Changeset 746 for vendor/current/source3/smbd
- Timestamp:
- Nov 27, 2012, 4:56:06 PM (13 years ago)
- Location:
- vendor/current/source3/smbd
- Files:
-
- 48 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/aio.c
r740 r746 67 67 68 68 smbd_aio_complete_aio_ex(aio_ex); 69 TALLOC_FREE(aio_ex); 69 70 } 70 71 … … 895 896 return; 896 897 } 897 898 TALLOC_FREE(aio_ex);899 898 } 900 899 -
vendor/current/source3/smbd/blocking.c
r740 r746 327 327 *****************************************************************************/ 328 328 329 static void reply_lockingX_error(struct blocking_lock_record *blr, NTSTATUS status)329 static void undo_locks_obtained(struct blocking_lock_record *blr) 330 330 { 331 331 files_struct *fsp = blr->fsp; … … 371 371 WINDOWS_LOCK); 372 372 } 373 374 generic_blocking_lock_error(blr, status);375 373 } 376 374 … … 385 383 switch(blr->req->cmd) { 386 384 case SMBlockingX: 387 reply_lockingX_error(blr, status); 388 break; 385 /* 386 * This code can be called during the rundown of a 387 * file after it was already closed. In that case, 388 * blr->fsp==NULL and we do not need to undo any 389 * locks, they are already gone. 390 */ 391 if (blr->fsp != NULL) { 392 undo_locks_obtained(blr); 393 } 394 generic_blocking_lock_error(blr, status); 395 break; 389 396 case SMBtrans2: 390 397 case SMBtranss2: -
vendor/current/source3/smbd/close.c
r740 r746 202 202 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname) 203 203 { 204 struct stream_struct *stream_info ;204 struct stream_struct *stream_info = NULL; 205 205 int i; 206 unsigned int num_streams ;206 unsigned int num_streams = 0; 207 207 TALLOC_CTX *frame = talloc_stackframe(); 208 208 NTSTATUS status; 209 209 210 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),211 210 status = vfs_streaminfo(conn, NULL, fname, talloc_tos(), 211 &num_streams, &stream_info); 212 212 213 213 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { … … 218 218 219 219 if (!NT_STATUS_IS_OK(status)) { 220 DEBUG(10, (" SMB_VFS_STREAMINFOfailed: %s\n",220 DEBUG(10, ("vfs_streaminfo failed: %s\n", 221 221 nt_errstr(status))); 222 222 goto fail; … … 281 281 struct file_id id; 282 282 const struct security_unix_token *del_token = NULL; 283 const struct security_token *del_nt_token = NULL; 284 bool got_tokens = false; 283 285 284 286 /* Ensure any pending write time updates are done. */ … … 346 348 } 347 349 fsp->delete_on_close = true; 348 set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn)); 350 set_delete_on_close_lck(fsp, lck, True, 351 get_current_nttok(conn), 352 get_current_utok(conn)); 349 353 if (became_user) { 350 354 unbecome_user(); … … 399 403 fsp->update_write_time_on_close = false; 400 404 401 del_token = get_delete_on_close_token(lck, fsp->name_hash); 402 SMB_ASSERT(del_token != NULL); 405 got_tokens = get_delete_on_close_token(lck, fsp->name_hash, 406 &del_nt_token, &del_token); 407 SMB_ASSERT(got_tokens); 403 408 404 409 if (!unix_token_equal(del_token, get_current_utok(conn))) { … … 419 424 del_token->ngroups, 420 425 del_token->groups, 421 NULL);426 del_nt_token); 422 427 423 428 changed_user = true; … … 492 497 493 498 fsp->delete_on_close = false; 494 set_delete_on_close_lck(fsp, lck, false, NULL );499 set_delete_on_close_lck(fsp, lck, false, NULL, NULL); 495 500 496 501 done: … … 818 823 } 819 824 820 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {825 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(SNUM(conn))) { 821 826 /* 822 827 * Check to see if the only thing in this directory are … … 963 968 NTSTATUS status = NT_STATUS_OK; 964 969 NTSTATUS status1 = NT_STATUS_OK; 970 const struct security_token *del_nt_token = NULL; 965 971 const struct security_unix_token *del_token = NULL; 966 972 … … 999 1005 fsp->fsp_name->base_name); 1000 1006 set_delete_on_close_lck(fsp, lck, true, 1007 get_current_nttok(fsp->conn), 1001 1008 get_current_utok(fsp->conn)); 1002 1009 fsp->delete_on_close = true; … … 1006 1013 } 1007 1014 1008 del _token = get_delete_on_close_token(lck, fsp->name_hash);1009 delete_dir = (del_token != NULL);1015 delete_dir = get_delete_on_close_token(lck, fsp->name_hash, 1016 &del_nt_token, &del_token); 1010 1017 1011 1018 if (delete_dir) { … … 1039 1046 del_token->ngroups, 1040 1047 del_token->groups, 1041 NULL);1048 del_nt_token); 1042 1049 1043 1050 TALLOC_FREE(lck); 1051 1052 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS) 1053 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) { 1054 1055 status = delete_all_streams(fsp->conn, fsp->fsp_name->base_name); 1056 if (!NT_STATUS_IS_OK(status)) { 1057 DEBUG(5, ("delete_all_streams failed: %s\n", 1058 nt_errstr(status))); 1059 goto out; 1060 } 1061 } 1044 1062 1045 1063 status = rmdir_internals(talloc_tos(), fsp); -
vendor/current/source3/smbd/conn.c
r740 r746 68 68 if (ptcon->compat_conn && 69 69 ptcon->compat_conn->params && 70 (ptcon->compat_conn->params->service = snum)) {70 (ptcon->compat_conn->params->service == snum)) { 71 71 return true; 72 72 } -
vendor/current/source3/smbd/dir.c
r740 r746 261 261 } 262 262 263 if (sconn->using_smb2) { 264 goto done; 265 } 266 263 267 DLIST_REMOVE(sconn->searches.dirptrs, dptr); 264 268 … … 280 284 /* Lanman 2 specific code */ 281 285 SAFE_FREE(dptr->wcard); 282 string_set(&dptr->path,"");286 SAFE_FREE(dptr->path); 283 287 SAFE_FREE(dptr); 284 288 } … … 471 475 ZERO_STRUCTP(dptr); 472 476 477 dptr->path = SMB_STRDUP(path); 478 if (!dptr->path) { 479 SAFE_FREE(dptr); 480 TALLOC_FREE(dir_hnd); 481 return NT_STATUS_NO_MEMORY; 482 } 483 dptr->conn = conn; 484 dptr->dir_hnd = dir_hnd; 485 dptr->spid = spid; 486 dptr->expect_close = expect_close; 487 dptr->wcard = SMB_STRDUP(wcard); 488 if (!dptr->wcard) { 489 SAFE_FREE(dptr->path); 490 SAFE_FREE(dptr); 491 TALLOC_FREE(dir_hnd); 492 return NT_STATUS_NO_MEMORY; 493 } 494 if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) { 495 dptr->has_wild = True; 496 } else { 497 dptr->has_wild = wcard_has_wild; 498 } 499 500 dptr->attr = attr; 501 502 if (sconn->using_smb2) { 503 goto done; 504 } 505 473 506 if(old_handle) { 474 507 … … 494 527 if(dptr->dnum == -1 || dptr->dnum > 254) { 495 528 DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum)); 529 SAFE_FREE(dptr->path); 530 SAFE_FREE(dptr->wcard); 496 531 SAFE_FREE(dptr); 497 532 TALLOC_FREE(dir_hnd); … … 524 559 if(dptr->dnum == -1 || dptr->dnum < 255) { 525 560 DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum)); 561 SAFE_FREE(dptr->path); 562 SAFE_FREE(dptr->wcard); 526 563 SAFE_FREE(dptr); 527 564 TALLOC_FREE(dir_hnd); … … 535 572 dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */ 536 573 537 string_set(&dptr->path,path);538 dptr->conn = conn;539 dptr->dir_hnd = dir_hnd;540 dptr->spid = spid;541 dptr->expect_close = expect_close;542 dptr->wcard = SMB_STRDUP(wcard);543 if (!dptr->wcard) {544 bitmap_clear(sconn->searches.dptr_bmap, dptr->dnum - 1);545 SAFE_FREE(dptr);546 TALLOC_FREE(dir_hnd);547 return NT_STATUS_NO_MEMORY;548 }549 if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) {550 dptr->has_wild = True;551 } else {552 dptr->has_wild = wcard_has_wild;553 }554 555 dptr->attr = attr;556 557 574 DLIST_ADD(sconn->searches.dirptrs, dptr); 558 575 576 done: 559 577 DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n", 560 578 dptr->dnum,path,expect_close)); … … 1328 1346 SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); 1329 1347 } 1330 if (dirp->conn->sconn ) {1348 if (dirp->conn->sconn && !dirp->conn->sconn->using_smb2) { 1331 1349 dirp->conn->sconn->searches.dirhandles_open--; 1332 1350 } … … 1359 1377 } 1360 1378 1361 if (sconn ) {1379 if (sconn && !sconn->using_smb2) { 1362 1380 sconn->searches.dirhandles_open++; 1363 1381 } … … 1403 1421 } 1404 1422 1405 if (sconn ) {1423 if (sconn && !sconn->using_smb2) { 1406 1424 sconn->searches.dirhandles_open++; 1407 1425 } -
vendor/current/source3/smbd/file_access.c
r740 r746 42 42 if (get_current_uid(conn) == (uid_t)0) { 43 43 /* I'm sorry sir, I didn't know you were root... */ 44 return true; 45 } 46 47 if (access_mask == DELETE_ACCESS && 48 VALID_STAT(smb_fname->st) && 49 S_ISLNK(smb_fname->st.st_ex_mode)) { 50 /* We can always delete a symlink. */ 44 51 return true; 45 52 } … … 81 88 82 89 bool can_delete_file_in_directory(connection_struct *conn, 83 struct smb_filename *smb_fname)90 const struct smb_filename *smb_fname) 84 91 { 85 92 TALLOC_CTX *ctx = talloc_tos(); … … 131 138 * by owner of directory. */ 132 139 if (smb_fname_parent->st.st_ex_mode & S_ISVTX) { 133 if(SMB_VFS_STAT(conn, smb_fname) != 0) { 134 if (errno == ENOENT) { 135 /* If the file doesn't already exist then 136 * yes we'll be able to delete it. */ 137 ret = true; 138 goto out; 139 } 140 DEBUG(10,("can_delete_file_in_directory: can't " 141 "stat file %s (%s)", 142 smb_fname_str_dbg(smb_fname), 143 strerror(errno) )); 144 ret = false; 140 if (!VALID_STAT(smb_fname->st)) { 141 /* If the file doesn't already exist then 142 * yes we'll be able to delete it. */ 143 ret = true; 145 144 goto out; 146 145 } … … 263 262 SECINFO_DACL, &secdesc); 264 263 265 if (!NT_STATUS_IS_OK(status) || secdesc == NULL) { 264 if (!NT_STATUS_IS_OK(status) || 265 secdesc == NULL || 266 secdesc->dacl == NULL) { 267 TALLOC_FREE(secdesc); 266 268 return false; 267 269 } -
vendor/current/source3/smbd/filename.c
r740 r746 384 384 if((!conn->case_sensitive || !(conn->fs_capabilities & 385 385 FILE_CASE_SENSITIVE_SEARCH)) && 386 stat_cache_lookup(conn, &smb_fname->base_name, &dirpath, &start,386 stat_cache_lookup(conn, posix_pathnames, &smb_fname->base_name, &dirpath, &start, 387 387 &smb_fname->st)) { 388 388 goto done; … … 978 978 979 979 /**************************************************************************** 980 Ensure a path is not vetod. 981 ****************************************************************************/ 982 983 NTSTATUS check_veto_path(connection_struct *conn, const char *name) 984 { 985 if (IS_VETO_PATH(conn, name)) { 986 /* Is it not dot or dot dot. */ 987 if (!(ISDOT(name) || ISDOTDOT(name))) { 988 DEBUG(5,("check_veto_path: file path name %s vetoed\n", 989 name)); 990 return map_nt_error_from_unix(ENOENT); 991 } 992 } 993 return NT_STATUS_OK; 994 } 995 996 /**************************************************************************** 980 997 Check a filename - possibly calling check_reduced_name. 981 998 This is called by every routine before it allows an operation on a filename. … … 986 1003 NTSTATUS check_name(connection_struct *conn, const char *name) 987 1004 { 988 if (IS_VETO_PATH(conn, name)) { 989 /* Is it not dot or dot dot. */ 990 if (!((name[0] == '.') && (!name[1] || 991 (name[1] == '.' && !name[2])))) { 992 DEBUG(5,("check_name: file path name %s vetoed\n", 993 name)); 994 return map_nt_error_from_unix(ENOENT); 995 } 1005 NTSTATUS status = check_veto_path(conn, name); 1006 1007 if (!NT_STATUS_IS_OK(status)) { 1008 return status; 996 1009 } 997 1010 998 1011 if (!lp_widelinks(SNUM(conn)) || !lp_symlinks(SNUM(conn))) { 999 NTSTATUSstatus = check_reduced_name(conn,name);1012 status = check_reduced_name(conn,name); 1000 1013 if (!NT_STATUS_IS_OK(status)) { 1001 1014 DEBUG(5,("check_name: name %s failed with %s\n",name, … … 1171 1184 { 1172 1185 NTSTATUS status; 1173 unsigned int i, num_streams ;1186 unsigned int i, num_streams = 0; 1174 1187 struct stream_struct *streams = NULL; 1175 1188 … … 1186 1199 1187 1200 /* Fall back to a case-insensitive scan of all streams on the file. */ 1188 status = SMB_VFS_STREAMINFO(conn, NULL, smb_fname->base_name, mem_ctx,1189 1201 status = vfs_streaminfo(conn, NULL, smb_fname->base_name, mem_ctx, 1202 &num_streams, &streams); 1190 1203 1191 1204 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { … … 1315 1328 } 1316 1329 1330 if ((ucf_flags & UCF_UNIX_NAME_LOOKUP) && 1331 VALID_STAT((*pp_smb_fname)->st) && 1332 S_ISLNK((*pp_smb_fname)->st.st_ex_mode)) { 1333 return check_veto_path(conn, (*pp_smb_fname)->base_name); 1334 } 1335 1317 1336 status = check_name(conn, (*pp_smb_fname)->base_name); 1318 1337 if (!NT_STATUS_IS_OK(status)) { -
vendor/current/source3/smbd/files.c
r740 r746 29 29 30 30 /**************************************************************************** 31 Return a unique number identifying this fsp over the life of this pid. 31 Return a unique number identifying this fsp over the life of this pid, 32 and try to make it as globally unique as possible. 33 See bug #8995 for the details. 32 34 ****************************************************************************/ 33 35 34 36 static unsigned long get_gen_count(struct smbd_server_connection *sconn) 35 37 { 38 /* 39 * While fsp->fh->gen_id is 'unsigned long' currently 40 * (which might by 8 bytes), 41 * there's some oplock code which truncates it to 42 * uint32_t(using IVAL()). 43 */ 44 if (sconn->file_gen_counter == 0) { 45 sconn->file_gen_counter = generate_random(); 46 } 36 47 sconn->file_gen_counter += 1; 48 if (sconn->file_gen_counter >= UINT32_MAX) { 49 sconn->file_gen_counter = 0; 50 } 37 51 if (sconn->file_gen_counter == 0) { 38 52 sconn->file_gen_counter += 1; … … 284 298 int count=0; 285 299 files_struct *fsp; 300 301 if (gen_id == 0) { 302 return NULL; 303 } 286 304 287 305 for (fsp=sconn->files; fsp; fsp=fsp->next,count++) { … … 549 567 } 550 568 569 uint64_t fsp_persistent_id(const struct files_struct *fsp) 570 { 571 uint64_t persistent_id; 572 573 /* 574 * This calculates a number that is most likely 575 * globally unique. In future we will have a database 576 * to make it completely unique. 577 * 578 * 32-bit random gen_id 579 * 16-bit truncated open_time 580 * 16-bit fnum (valatile_id) 581 */ 582 persistent_id = fsp->fh->gen_id & UINT32_MAX; 583 persistent_id <<= 16; 584 persistent_id &= 0x0000FFFFFFFF0000LLU; 585 persistent_id |= fsp->open_time.tv_usec & UINT16_MAX; 586 persistent_id <<= 16; 587 persistent_id &= 0xFFFFFFFFFFFF0000LLU; 588 persistent_id |= fsp->fnum & UINT16_MAX; 589 590 return persistent_id; 591 } 592 593 struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req, 594 uint64_t persistent_id, 595 uint64_t volatile_id) 596 { 597 struct files_struct *fsp; 598 uint64_t fsp_persistent; 599 600 if (smb2req->compat_chain_fsp != NULL) { 601 return smb2req->compat_chain_fsp; 602 } 603 604 if (volatile_id > UINT16_MAX) { 605 return NULL; 606 } 607 608 fsp = file_fnum(smb2req->sconn, (uint16_t)volatile_id); 609 if (fsp == NULL) { 610 return NULL; 611 } 612 fsp_persistent = fsp_persistent_id(fsp); 613 614 if (persistent_id != fsp_persistent) { 615 return NULL; 616 } 617 618 if (smb2req->tcon == NULL) { 619 return NULL; 620 } 621 622 if (smb2req->tcon->compat_conn != fsp->conn) { 623 return NULL; 624 } 625 626 if (smb2req->session == NULL) { 627 return NULL; 628 } 629 630 if (smb2req->session->vuid != fsp->vuid) { 631 return NULL; 632 } 633 634 smb2req->compat_chain_fsp = fsp; 635 return fsp; 636 } 637 551 638 /**************************************************************************** 552 639 Duplicate the file handle part for a DOS or FCB open. -
vendor/current/source3/smbd/globals.h
r740 r746 278 278 struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req); 279 279 void remove_smb2_chained_fsp(files_struct *fsp); 280 281 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req, 282 size_t expected_body_size); 280 283 281 284 NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req); … … 351 354 /* the session the request operates on, maybe NULL */ 352 355 struct smbd_smb2_session *session; 356 uint64_t last_session_id; 353 357 354 358 /* the tcon the request operates on, maybe NULL */ 355 359 struct smbd_smb2_tcon *tcon; 360 uint32_t last_tid; 356 361 357 362 int current_idx; … … 359 364 bool async; 360 365 bool cancelled; 366 bool compound_related; 361 367 362 368 /* fake smb1 request. */ 363 369 struct smb_request *smb1req; 364 370 struct files_struct *compat_chain_fsp; 365 366 NTSTATUS next_status;367 371 368 372 /* … … 598 602 } locks; 599 603 struct smbd_smb2_request *requests; 604 /* 605 * seqnum_low is the lowest sequence number 606 * we will accept. 607 */ 600 608 uint64_t seqnum_low; 601 uint32_t credits_granted; 602 uint32_t max_credits; 609 /* 610 * seqnum_range is the range of credits we have 611 * granted from the sequence windows starting 612 * at seqnum_low. 613 * 614 * This gets incremented when new credits are 615 * granted and gets decremented when the 616 * lowest sequence number is consumed 617 * (when seqnum_low gets incremented). 618 */ 619 uint16_t seqnum_range; 620 /* 621 * credits_grantedThe number of credits we have currently granted 622 * to the client. 623 * 624 * This gets incremented when new credits are 625 * granted and gets decremented when any credit 626 * is comsumed. 627 * 628 * Note: the decrementing is different compared 629 * to seqnum_range. 630 */ 631 uint16_t credits_granted; 632 /* 633 * The maximum number of credits we will ever 634 * grant to the client. 635 * 636 * Typically we will only grant 1/16th of 637 * max_credits. 638 * 639 * This is the "server max credits" parameter. 640 */ 641 uint16_t max_credits; 642 /* 643 * a bitmap of size max_credits 644 */ 603 645 struct bitmap *credits_bitmap; 646 uint32_t max_trans; 647 uint32_t max_read; 648 uint32_t max_write; 649 bool compound_related_in_progress; 604 650 } smb2; 605 651 }; -
vendor/current/source3/smbd/lanman.c
r740 r746 3525 3525 NULL, 3526 3526 devmode_ctr, 3527 SEC_FLAG_MAXIMUM_ALLOWED,3527 PRINTER_ACCESS_ADMINISTER, 3528 3528 &handle, 3529 3529 &werr); … … 4982 4982 NULL, 4983 4983 devmode_ctr, 4984 SEC_FLAG_MAXIMUM_ALLOWED,4984 PRINTER_ACCESS_USE, 4985 4985 &handle, 4986 4986 &werr); … … 5182 5182 NULL, 5183 5183 devmode_ctr, 5184 SEC_FLAG_MAXIMUM_ALLOWED,5184 PRINTER_ACCESS_USE, 5185 5185 &handle, 5186 5186 &werr); -
vendor/current/source3/smbd/msdfs.c
r740 r746 576 576 577 577 /* 578 * Note the unix path conversion here we're doing we can 578 * Note the unix path conversion here we're doing we 579 579 * throw away. We're looking for a symlink for a dfs 580 580 * resolution, if we don't find it we'll do another 581 581 * unix_convert later in the codepath. 582 * If we needed to remember what we'd resolved in583 * dp->reqpath (as the original code did) we'd584 * copy (localhost, dp->reqpath) on any code585 * path below that returns True - but I don't586 * think this is needed. JRA.587 582 */ 588 583 … … 595 590 return status; 596 591 } 597 598 /* Create an smb_fname to use below. */ 599 status = create_synthetic_smb_fname(ctx, pdp->reqpath, NULL, 600 NULL, &smb_fname); 601 if (!NT_STATUS_IS_OK(status)) { 592 if (smb_fname == NULL || smb_fname->base_name == NULL) { 602 593 return status; 603 594 } -
vendor/current/source3/smbd/negprot.c
r740 r746 717 717 718 718 TALLOC_FREE(cliprotos); 719 720 if (lp_async_smb_echo_handler() && (get_Protocol() < PROTOCOL_SMB2) && 721 !fork_echo_handler(sconn)) { 722 exit_server("Failed to fork echo handler"); 723 } 724 719 725 END_PROFILE(SMBnegprot); 720 726 return; -
vendor/current/source3/smbd/notify.c
r740 r746 346 346 } 347 347 348 static void notify_parent_dir(connection_struct *conn, 349 uint32 action, uint32 filter, 350 const char *path) 351 { 352 struct smb_filename smb_fname_parent; 353 char *parent; 354 const char *name; 355 char *oldwd; 356 357 if (!parent_dirname(talloc_tos(), path, &parent, &name)) { 358 return; 359 } 360 361 ZERO_STRUCT(smb_fname_parent); 362 smb_fname_parent.base_name = parent; 363 364 oldwd = vfs_GetWd(parent, conn); 365 if (oldwd == NULL) { 366 goto done; 367 } 368 if (vfs_ChDir(conn, conn->connectpath) == -1) { 369 goto done; 370 } 371 372 if (SMB_VFS_STAT(conn, &smb_fname_parent) == -1) { 373 goto chdir_done; 374 } 375 376 notify_onelevel(conn->notify_ctx, action, filter, 377 SMB_VFS_FILE_ID_CREATE(conn, &smb_fname_parent.st), 378 name); 379 chdir_done: 380 vfs_ChDir(conn, oldwd); 381 done: 382 TALLOC_FREE(parent); 383 } 384 348 385 void notify_fname(connection_struct *conn, uint32 action, uint32 filter, 349 386 const char *path) 350 387 { 351 388 char *fullpath; 352 char *parent;353 const char *name;354 389 355 390 if (path[0] == '.' && path[1] == '/') { 356 391 path += 2; 357 392 } 358 if (parent_dirname(talloc_tos(), path, &parent, &name)) { 359 struct smb_filename smb_fname_parent; 360 361 ZERO_STRUCT(smb_fname_parent); 362 smb_fname_parent.base_name = parent; 363 364 if (SMB_VFS_STAT(conn, &smb_fname_parent) != -1) { 365 notify_onelevel(conn->notify_ctx, action, filter, 366 SMB_VFS_FILE_ID_CREATE(conn, &smb_fname_parent.st), 367 name); 368 } 369 } 393 notify_parent_dir(conn, action, filter, path); 370 394 371 395 fullpath = talloc_asprintf(talloc_tos(), "%s/%s", conn->connectpath, -
vendor/current/source3/smbd/nttrans.c
r740 r746 143 143 total_sent_thistime + alignment_offset 144 144 + data_alignment_offset); 145 146 /*147 * We might have had SMBnttranss in req->inbuf, fix that.148 */149 SCVAL(req->outbuf, smb_com, SMBnttrans);150 145 151 146 /* … … 694 689 uint16_t file_status = (NO_EAS|NO_SUBSTREAMS|NO_REPARSETAG); 695 690 size_t num_names = 0; 696 unsigned int num_streams ;691 unsigned int num_streams = 0; 697 692 struct stream_struct *streams = NULL; 698 693 … … 703 698 file_status &= ~NO_EAS; 704 699 } 705 status = SMB_VFS_STREAMINFO(conn, NULL, smb_fname->base_name, ctx,700 status = vfs_streaminfo(conn, NULL, smb_fname->base_name, ctx, 706 701 &num_streams, &streams); 707 702 /* There is always one stream, ::$DATA. */ … … 832 827 } 833 828 829 /********************************************************************* 830 Windows seems to do canonicalization of inheritance bits. Do the 831 same. 832 *********************************************************************/ 833 834 static void canonicalize_inheritance_bits(struct security_descriptor *psd) 835 { 836 bool set_auto_inherited = false; 837 838 /* 839 * We need to filter out the 840 * SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_AUTO_INHERIT_REQ 841 * bits. If both are set we store SEC_DESC_DACL_AUTO_INHERITED 842 * as this alters whether SEC_ACE_FLAG_INHERITED_ACE is set 843 * when an ACE is inherited. Otherwise we zero these bits out. 844 * See: 845 * 846 * http://social.msdn.microsoft.com/Forums/eu/os_fileservices/thread/11f77b68-731e-407d-b1b3-064750716531 847 * 848 * for details. 849 */ 850 851 if ((psd->type & (SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_AUTO_INHERIT_REQ)) 852 == (SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_AUTO_INHERIT_REQ)) { 853 set_auto_inherited = true; 854 } 855 856 psd->type &= ~(SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_AUTO_INHERIT_REQ); 857 if (set_auto_inherited) { 858 psd->type |= SEC_DESC_DACL_AUTO_INHERITED; 859 } 860 } 861 834 862 /**************************************************************************** 835 863 Internal fn to set security descriptors. 836 864 ****************************************************************************/ 837 865 838 NTSTATUS set_sd(files_struct *fsp, uint8_t *data, uint32_t sd_len, 866 NTSTATUS set_sd(files_struct *fsp, struct security_descriptor *psd, 867 uint32_t security_info_sent) 868 { 869 NTSTATUS status; 870 871 if (!CAN_WRITE(fsp->conn)) { 872 return NT_STATUS_ACCESS_DENIED; 873 } 874 875 if (!lp_nt_acl_support(SNUM(fsp->conn))) { 876 return NT_STATUS_OK; 877 } 878 879 if (psd->owner_sid == NULL) { 880 security_info_sent &= ~SECINFO_OWNER; 881 } 882 if (psd->group_sid == NULL) { 883 security_info_sent &= ~SECINFO_GROUP; 884 } 885 886 /* Ensure we have at least one thing set. */ 887 if ((security_info_sent & (SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL)) == 0) { 888 if (security_info_sent & SECINFO_LABEL) { 889 /* Only consider SECINFO_LABEL if no other 890 bits are set. Just like W2K3 we don't 891 store this. */ 892 return NT_STATUS_OK; 893 } 894 return NT_STATUS_INVALID_PARAMETER; 895 } 896 897 /* Ensure we have the rights to do this. */ 898 if (security_info_sent & SECINFO_OWNER) { 899 if (!(fsp->access_mask & SEC_STD_WRITE_OWNER)) { 900 return NT_STATUS_ACCESS_DENIED; 901 } 902 } 903 904 if (security_info_sent & SECINFO_GROUP) { 905 if (!(fsp->access_mask & SEC_STD_WRITE_OWNER)) { 906 return NT_STATUS_ACCESS_DENIED; 907 } 908 } 909 910 if (security_info_sent & SECINFO_DACL) { 911 if (!(fsp->access_mask & SEC_STD_WRITE_DAC)) { 912 return NT_STATUS_ACCESS_DENIED; 913 } 914 /* Convert all the generic bits. */ 915 if (psd->dacl) { 916 security_acl_map_generic(psd->dacl, &file_generic_mapping); 917 } 918 } 919 920 if (security_info_sent & SECINFO_SACL) { 921 if (!(fsp->access_mask & SEC_FLAG_SYSTEM_SECURITY)) { 922 return NT_STATUS_ACCESS_DENIED; 923 } 924 /* Convert all the generic bits. */ 925 if (psd->sacl) { 926 security_acl_map_generic(psd->sacl, &file_generic_mapping); 927 } 928 } 929 930 canonicalize_inheritance_bits(psd); 931 932 if (DEBUGLEVEL >= 10) { 933 DEBUG(10,("set_sd for file %s\n", fsp_str_dbg(fsp))); 934 NDR_PRINT_DEBUG(security_descriptor, psd); 935 } 936 937 status = SMB_VFS_FSET_NT_ACL(fsp, security_info_sent, psd); 938 939 TALLOC_FREE(psd); 940 941 return status; 942 } 943 944 /**************************************************************************** 945 Internal fn to set security descriptors from a data blob. 946 ****************************************************************************/ 947 948 NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len, 839 949 uint32_t security_info_sent) 840 950 { … … 846 956 } 847 957 848 if (!CAN_WRITE(fsp->conn)) {849 return NT_STATUS_ACCESS_DENIED;850 }851 852 if (!lp_nt_acl_support(SNUM(fsp->conn))) {853 return NT_STATUS_OK;854 }855 856 958 status = unmarshall_sec_desc(talloc_tos(), data, sd_len, &psd); 857 959 … … 860 962 } 861 963 862 if (psd->owner_sid == NULL) { 863 security_info_sent &= ~SECINFO_OWNER; 864 } 865 if (psd->group_sid == NULL) { 866 security_info_sent &= ~SECINFO_GROUP; 867 } 868 869 /* Ensure we have at least one thing set. */ 870 if ((security_info_sent & (SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL)) == 0) { 871 return NT_STATUS_INVALID_PARAMETER; 872 } 873 874 /* Ensure we have the rights to do this. */ 875 if (security_info_sent & SECINFO_OWNER) { 876 if (!(fsp->access_mask & SEC_STD_WRITE_OWNER)) { 877 return NT_STATUS_ACCESS_DENIED; 878 } 879 } 880 881 if (security_info_sent & SECINFO_GROUP) { 882 if (!(fsp->access_mask & SEC_STD_WRITE_OWNER)) { 883 return NT_STATUS_ACCESS_DENIED; 884 } 885 } 886 887 if (security_info_sent & SECINFO_DACL) { 888 if (!(fsp->access_mask & SEC_STD_WRITE_DAC)) { 889 return NT_STATUS_ACCESS_DENIED; 890 } 891 /* Convert all the generic bits. */ 892 if (psd->dacl) { 893 security_acl_map_generic(psd->dacl, &file_generic_mapping); 894 } 895 } 896 897 if (security_info_sent & SECINFO_SACL) { 898 if (!(fsp->access_mask & SEC_FLAG_SYSTEM_SECURITY)) { 899 return NT_STATUS_ACCESS_DENIED; 900 } 901 /* Convert all the generic bits. */ 902 if (psd->sacl) { 903 security_acl_map_generic(psd->sacl, &file_generic_mapping); 904 } 905 } 906 907 if (DEBUGLEVEL >= 10) { 908 DEBUG(10,("set_sd for file %s\n", fsp_str_dbg(fsp))); 909 NDR_PRINT_DEBUG(security_descriptor, psd); 910 } 911 912 status = SMB_VFS_FSET_NT_ACL(fsp, security_info_sent, psd); 913 914 TALLOC_FREE(psd); 915 916 return status; 964 return set_sd(fsp, psd, security_info_sent); 917 965 } 918 966 … … 1269 1317 uint16_t file_status = (NO_EAS|NO_SUBSTREAMS|NO_REPARSETAG); 1270 1318 size_t num_names = 0; 1271 unsigned int num_streams ;1319 unsigned int num_streams = 0; 1272 1320 struct stream_struct *streams = NULL; 1273 1321 … … 1278 1326 file_status &= ~NO_EAS; 1279 1327 } 1280 status = SMB_VFS_STREAMINFO(conn, NULL, smb_fname->base_name, ctx,1328 status = vfs_streaminfo(conn, NULL, smb_fname->base_name, ctx, 1281 1329 &num_streams, &streams); 1282 1330 /* There is always one stream, ::$DATA. */ … … 1869 1917 } 1870 1918 1919 if (security_info_wanted & (SECINFO_DACL|SECINFO_OWNER| 1920 SECINFO_GROUP|SECINFO_SACL)) { 1921 /* Don't return SECINFO_LABEL if anything else was 1922 requested. See bug #8458. */ 1923 security_info_wanted &= ~SECINFO_LABEL; 1924 } 1925 1871 1926 if (!lp_nt_acl_support(SNUM(conn))) { 1927 status = get_null_nt_acl(mem_ctx, &psd); 1928 } else if (security_info_wanted & SECINFO_LABEL) { 1929 /* Like W2K3 return a null object. */ 1872 1930 status = get_null_nt_acl(mem_ctx, &psd); 1873 1931 } else { … … 1886 1944 } 1887 1945 if (!(security_info_wanted & SECINFO_DACL)) { 1946 psd->type &= ~SEC_DESC_DACL_PRESENT; 1888 1947 psd->dacl = NULL; 1889 1948 } 1890 1949 if (!(security_info_wanted & SECINFO_SACL)) { 1950 psd->type &= ~SEC_DESC_SACL_PRESENT; 1891 1951 psd->sacl = NULL; 1892 1952 } … … 1900 1960 security_info_wanted & SECINFO_DACL) 1901 1961 psd->type |= SEC_DESC_DACL_PRESENT; 1962 1963 if (security_info_wanted & SECINFO_LABEL) { 1964 /* Like W2K3 return a null object. */ 1965 psd->owner_sid = NULL; 1966 psd->group_sid = NULL; 1967 psd->dacl = NULL; 1968 psd->sacl = NULL; 1969 psd->type &= ~(SEC_DESC_DACL_PRESENT|SEC_DESC_SACL_PRESENT); 1970 } 1902 1971 1903 1972 *psd_size = ndr_size_security_descriptor(psd, 0); … … 2074 2143 } 2075 2144 2076 status = set_sd (fsp, (uint8 *)data, data_count, security_info_sent);2145 status = set_sd_blob(fsp, (uint8 *)data, data_count, security_info_sent); 2077 2146 2078 2147 if (!NT_STATUS_IS_OK(status)) { … … 2086 2155 } 2087 2156 2088 /**************************************************************************** 2089 Reply to NT IOCTL 2090 ****************************************************************************/ 2091 2092 static void call_nt_transact_ioctl(connection_struct *conn, 2093 struct smb_request *req, 2094 uint16 **ppsetup, uint32 setup_count, 2095 char **ppparams, uint32 parameter_count, 2096 char **ppdata, uint32 data_count, 2097 uint32 max_data_count) 2157 /* 2158 * Implement the default fsctl operation. 2159 */ 2160 2161 static bool vfswrap_logged_ioctl_message = false; 2162 2163 /* 2164 * In 3.6 we do not have a SMB_VFS_FSCTL() function 2165 * it's just faked to make it more look like 2166 * master (4.0) 2167 */ 2168 NTSTATUS smb_fsctl(struct files_struct *fsp, 2169 TALLOC_CTX *ctx, 2170 uint32_t function, 2171 uint16_t req_flags, /* Needed for UNICODE ... */ 2172 const uint8_t *_in_data, 2173 uint32_t in_len, 2174 uint8_t **_out_data, 2175 uint32_t max_out_len, 2176 uint32_t *out_len) 2098 2177 { 2099 uint32 function; 2100 uint16 fidnum; 2101 files_struct *fsp; 2102 uint8 isFSctl; 2103 uint8 compfilter; 2104 char *pdata = *ppdata; 2105 2106 if (setup_count != 8) { 2107 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count)); 2108 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 2109 return; 2110 } 2111 2112 function = IVAL(*ppsetup, 0); 2113 fidnum = SVAL(*ppsetup, 4); 2114 isFSctl = CVAL(*ppsetup, 6); 2115 compfilter = CVAL(*ppsetup, 7); 2116 2117 DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", 2118 function, fidnum, isFSctl, compfilter)); 2119 2120 fsp=file_fsp(req, fidnum); 2121 /* this check is done in each implemented function case for now 2122 because I don't want to break anything... --metze 2123 FSP_BELONGS_CONN(fsp,conn);*/ 2124 2125 SMB_PERFCOUNT_SET_IOCTL(&req->pcd, function); 2178 const char *in_data = (const char *)_in_data; 2179 char **out_data = (char **)_out_data; 2126 2180 2127 2181 switch (function) { … … 2131 2185 NTSTATUS status; 2132 2186 2133 if ( data_count >= 1 && pdata[0] == 0) {2187 if (in_len >= 1 && in_data[0] == 0) { 2134 2188 set_sparse = false; 2135 2189 } 2136 2190 2137 DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X]set[%u]\n", 2138 fidnum, set_sparse)); 2139 2140 if (!check_fsp_open(conn, req, fsp)) { 2141 return; 2142 } 2143 2144 status = file_set_sparse(conn, fsp, set_sparse); 2145 if (!NT_STATUS_IS_OK(status)) { 2146 DEBUG(9,("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n", 2147 smb_fname_str_dbg(fsp->fsp_name), set_sparse, nt_errstr(status))); 2148 reply_nterror(req, status); 2149 return; 2150 } 2151 2152 DEBUG(10,("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n", 2153 smb_fname_str_dbg(fsp->fsp_name), set_sparse, nt_errstr(status))); 2154 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0); 2155 return; 2156 } 2191 status = file_set_sparse(fsp->conn, fsp, set_sparse); 2192 2193 DEBUG(NT_STATUS_IS_OK(status) ? 10 : 9, 2194 ("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n", 2195 smb_fname_str_dbg(fsp->fsp_name), set_sparse, 2196 nt_errstr(status))); 2197 2198 return status; 2199 } 2200 2157 2201 case FSCTL_CREATE_OR_GET_OBJECT_ID: 2158 2202 { 2159 2203 unsigned char objid[16]; 2204 char *return_data = NULL; 2160 2205 2161 2206 /* This should return the object-id on this file. … … 2163 2208 */ 2164 2209 2165 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on FID[0x%04X]\n",fidnum)); 2166 2167 if (!check_fsp_open(conn, req, fsp)) { 2168 return; 2169 } 2170 2171 data_count = 64; 2172 pdata = nttrans_realloc(ppdata, data_count); 2173 if (pdata == NULL) { 2174 reply_nterror(req, NT_STATUS_NO_MEMORY); 2175 return; 2210 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on FID[0x%04X]\n",fsp->fnum)); 2211 2212 *out_len = (max_out_len >= 64) ? 64 : max_out_len; 2213 /* Hmmm, will this cause problems if less data asked for? */ 2214 return_data = talloc_array(ctx, char, 64); 2215 if (return_data == NULL) { 2216 return NT_STATUS_NO_MEMORY; 2176 2217 } 2177 2218 2178 2219 /* For backwards compatibility only store the dev/inode. */ 2179 push_file_id_16(pdata, &fsp->file_id); 2180 memcpy(pdata+16,create_volume_objectid(conn,objid),16); 2181 push_file_id_16(pdata+32, &fsp->file_id); 2182 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, 2183 pdata, data_count); 2184 return; 2220 push_file_id_16(return_data, &fsp->file_id); 2221 memcpy(return_data+16,create_volume_objectid(fsp->conn,objid),16); 2222 push_file_id_16(return_data+32, &fsp->file_id); 2223 *out_data = return_data; 2224 return NT_STATUS_OK; 2185 2225 } 2186 2226 2187 2227 case FSCTL_GET_REPARSE_POINT: 2188 /* pretend this fail - my winXP does it like this 2189 * --metze 2190 */ 2191 2192 DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum)); 2193 reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT); 2194 return; 2228 { 2229 /* Fail it with STATUS_NOT_A_REPARSE_POINT */ 2230 DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X] Status: NOT_IMPLEMENTED\n", fsp->fnum)); 2231 return NT_STATUS_NOT_A_REPARSE_POINT; 2232 } 2195 2233 2196 2234 case FSCTL_SET_REPARSE_POINT: 2197 /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case. 2198 * --metze 2199 */ 2200 2201 DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum)); 2202 reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT); 2203 return; 2204 2205 case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/ 2235 { 2236 /* Fail it with STATUS_NOT_A_REPARSE_POINT */ 2237 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X] Status: NOT_IMPLEMENTED\n", fsp->fnum)); 2238 return NT_STATUS_NOT_A_REPARSE_POINT; 2239 } 2240 2241 case FSCTL_GET_SHADOW_COPY_DATA: 2206 2242 { 2207 2243 /* … … 2219 2255 uint32 labels_data_count = 0; 2220 2256 uint32 i; 2221 char *cur_pdata; 2222 2223 if (!check_fsp_open(conn, req, fsp)) { 2224 return; 2225 } 2226 2227 if (max_data_count < 16) { 2257 char *cur_pdata = NULL; 2258 2259 if (max_out_len < 16) { 2228 2260 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n", 2229 max_data_count)); 2230 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 2231 return; 2232 } 2233 2234 if (max_data_count > 16) { 2261 max_out_len)); 2262 return NT_STATUS_INVALID_PARAMETER; 2263 } 2264 2265 if (max_out_len > 16) { 2235 2266 labels = True; 2236 2267 } 2237 2268 2238 shadow_data = TALLOC_ZERO_P(talloc_tos(), 2239 struct shadow_copy_data); 2269 shadow_data = talloc_zero(ctx, struct shadow_copy_data); 2240 2270 if (shadow_data == NULL) { 2241 2271 DEBUG(0,("TALLOC_ZERO() failed!\n")); 2242 reply_nterror(req, NT_STATUS_NO_MEMORY); 2243 return; 2272 return NT_STATUS_NO_MEMORY; 2244 2273 } 2245 2274 … … 2251 2280 if (errno == ENOSYS) { 2252 2281 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", 2253 conn->connectpath)); 2254 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 2255 return; 2282 fsp->conn->connectpath)); 2283 return NT_STATUS_NOT_SUPPORTED; 2256 2284 } else { 2257 2285 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n", 2258 conn->connectpath)); 2259 reply_nterror(req, NT_STATUS_UNSUCCESSFUL); 2260 return; 2286 fsp->conn->connectpath)); 2287 return NT_STATUS_UNSUCCESSFUL; 2261 2288 } 2262 2289 } 2263 2290 2264 labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2; 2291 labels_data_count = (shadow_data->num_volumes * 2 * 2292 sizeof(SHADOW_COPY_LABEL)) + 2; 2265 2293 2266 2294 if (!labels) { 2267 data_count= 16;2295 *out_len = 16; 2268 2296 } else { 2269 data_count = 12+labels_data_count+4;2270 } 2271 2272 if (max_ data_count<data_count) {2297 *out_len = 12 + labels_data_count + 4; 2298 } 2299 2300 if (max_out_len < *out_len) { 2273 2301 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n", 2274 max_ data_count,data_count));2302 max_out_len, *out_len)); 2275 2303 TALLOC_FREE(shadow_data); 2276 reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); 2277 return; 2278 } 2279 2280 pdata = nttrans_realloc(ppdata, data_count); 2281 if (pdata == NULL) { 2304 return NT_STATUS_BUFFER_TOO_SMALL; 2305 } 2306 2307 cur_pdata = talloc_array(ctx, char, *out_len); 2308 if (cur_pdata == NULL) { 2282 2309 TALLOC_FREE(shadow_data); 2283 reply_nterror(req, NT_STATUS_NO_MEMORY); 2284 return; 2285 } 2286 2287 cur_pdata = pdata; 2310 return NT_STATUS_NO_MEMORY; 2311 } 2312 2313 *out_data = cur_pdata; 2288 2314 2289 2315 /* num_volumes 4 bytes */ 2290 SIVAL( pdata,0,shadow_data->num_volumes);2316 SIVAL(cur_pdata, 0, shadow_data->num_volumes); 2291 2317 2292 2318 if (labels) { 2293 2319 /* num_labels 4 bytes */ 2294 SIVAL( pdata,4,shadow_data->num_volumes);2320 SIVAL(cur_pdata, 4, shadow_data->num_volumes); 2295 2321 } 2296 2322 2297 2323 /* needed_data_count 4 bytes */ 2298 SIVAL( pdata, 8, labels_data_count+4);2299 2300 cur_pdata +=12;2324 SIVAL(cur_pdata, 8, labels_data_count + 4); 2325 2326 cur_pdata += 12; 2301 2327 2302 2328 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n", 2303 2329 shadow_data->num_volumes, fsp_str_dbg(fsp))); 2304 2330 if (labels && shadow_data->labels) { 2305 for (i=0; i<shadow_data->num_volumes;i++) {2306 srvstr_push( pdata, req->flags2,2331 for (i=0; i<shadow_data->num_volumes; i++) { 2332 srvstr_push(cur_pdata, req_flags, 2307 2333 cur_pdata, shadow_data->labels[i], 2308 2 *sizeof(SHADOW_COPY_LABEL),2334 2 * sizeof(SHADOW_COPY_LABEL), 2309 2335 STR_UNICODE|STR_TERMINATE); 2310 cur_pdata +=2*sizeof(SHADOW_COPY_LABEL);2336 cur_pdata += 2 * sizeof(SHADOW_COPY_LABEL); 2311 2337 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i])); 2312 2338 } … … 2315 2341 TALLOC_FREE(shadow_data); 2316 2342 2317 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, 2318 pdata, data_count); 2319 2320 return; 2321 } 2322 2323 case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */ 2343 return NT_STATUS_OK; 2344 } 2345 2346 case FSCTL_FIND_FILES_BY_SID: 2324 2347 { 2325 2348 /* pretend this succeeded - … … 2333 2356 size_t sid_len; 2334 2357 2335 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum)); 2336 2337 if (!check_fsp_open(conn, req, fsp)) { 2338 return; 2339 } 2340 2341 if (data_count < 8) { 2342 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 2343 return; 2344 } 2345 2346 sid_len = MIN(data_count-4,SID_MAX_SIZE); 2358 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n", fsp->fnum)); 2359 2360 if (in_len < 8) { 2361 /* NT_STATUS_BUFFER_TOO_SMALL maybe? */ 2362 return NT_STATUS_INVALID_PARAMETER; 2363 } 2364 2365 sid_len = MIN(in_len - 4,SID_MAX_SIZE); 2347 2366 2348 2367 /* unknown 4 bytes: this is not the length of the sid :-( */ 2349 2368 /*unknown = IVAL(pdata,0);*/ 2350 2369 2351 if (!sid_parse(pdata+4,sid_len,&sid)) { 2352 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 2353 return; 2370 if (!sid_parse(in_data + 4, sid_len, &sid)) { 2371 return NT_STATUS_INVALID_PARAMETER; 2354 2372 } 2355 2373 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid))); … … 2373 2391 * (maybe we can hang the result anywhere in the fsp struct) 2374 2392 * 2393 * but I don't know how to deal with the paged results 2394 * (maybe we can hang the result anywhere in the fsp struct) 2395 * 2375 2396 * we don't send all files at once 2376 2397 * and at the next we should *not* start from the beginning, … … 2381 2402 2382 2403 /* this works for now... */ 2383 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);2384 return;2385 } 2404 return NT_STATUS_OK; 2405 } 2406 2386 2407 case FSCTL_QUERY_ALLOCATED_RANGES: 2387 2408 { … … 2394 2415 NTSTATUS status; 2395 2416 uint64_t offset, length; 2396 2397 if (!check_fsp_open(conn, req, fsp)) { 2398 return; 2399 } 2400 2401 if (data_count != 16) { 2417 char *out_data_tmp = NULL; 2418 2419 if (in_len != 16) { 2402 2420 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n", 2403 data_count)); 2404 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 2405 return; 2406 } 2407 2408 if (max_data_count < 16) { 2409 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_data_count(%u) < 16 is invalid!\n", 2410 max_data_count)); 2411 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 2412 return; 2413 } 2414 2415 offset = BVAL(pdata,0); 2416 length = BVAL(pdata,8); 2421 in_len)); 2422 return NT_STATUS_INVALID_PARAMETER; 2423 } 2424 2425 if (max_out_len < 16) { 2426 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n", 2427 max_out_len)); 2428 return NT_STATUS_INVALID_PARAMETER; 2429 } 2430 2431 offset = BVAL(in_data,0); 2432 length = BVAL(in_data,8); 2417 2433 2418 2434 if (offset + length < offset) { 2419 2435 /* No 64-bit integer wrap. */ 2420 re ply_nterror(req, NT_STATUS_INVALID_PARAMETER);2421 return;2422 } 2423 2436 return NT_STATUS_INVALID_PARAMETER; 2437 } 2438 2439 /* Shouldn't this be SMB_VFS_STAT ... ? */ 2424 2440 status = vfs_stat_fsp(fsp); 2425 2441 if (!NT_STATUS_IS_OK(status)) { 2426 reply_nterror(req, status); 2427 return; 2442 return status; 2443 } 2444 2445 *out_len = 16; 2446 out_data_tmp = talloc_array(ctx, char, *out_len); 2447 if (out_data_tmp == NULL) { 2448 DEBUG(10, ("unable to allocate memory for response\n")); 2449 return NT_STATUS_NO_MEMORY; 2428 2450 } 2429 2451 … … 2431 2453 fsp->fsp_name->st.st_ex_size == 0 || 2432 2454 length == 0) { 2433 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);2455 memset(out_data_tmp, 0, *out_len); 2434 2456 } else { 2435 2457 uint64_t end = offset + length; 2436 2458 end = MIN(end, fsp->fsp_name->st.st_ex_size); 2437 SBVAL(pdata,0,0); 2438 SBVAL(pdata,8,end); 2439 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, 2440 pdata, 16); 2441 } 2442 return; 2443 } 2459 SBVAL(out_data_tmp, 0, 0); 2460 SBVAL(out_data_tmp, 8, end); 2461 } 2462 2463 *out_data = out_data_tmp; 2464 2465 return NT_STATUS_OK; 2466 } 2467 2444 2468 case FSCTL_IS_VOLUME_DIRTY: 2469 { 2445 2470 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on FID[0x%04X] " 2446 "(but not implemented)\n", (int)fidnum));2471 "(but not implemented)\n", fsp->fnum)); 2447 2472 /* 2448 2473 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx 2449 2474 * says we have to respond with NT_STATUS_INVALID_PARAMETER 2450 2475 */ 2451 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 2452 return; 2476 return NT_STATUS_INVALID_PARAMETER; 2477 } 2478 2453 2479 default: 2454 /* Only print this once... */ 2455 if (!logged_ioctl_message) { 2456 logged_ioctl_message = true; 2457 DEBUG(2,("call_nt_transact_ioctl(0x%x): " 2458 "Currently not implemented.\n", 2459 function)); 2460 } 2461 } 2462 2463 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 2480 /* 2481 * Only print once ... unfortunately there could be lots of 2482 * different FSCTLs that are called. 2483 */ 2484 if (!vfswrap_logged_ioctl_message) { 2485 vfswrap_logged_ioctl_message = true; 2486 DEBUG(2, ("%s (0x%x): Currently not implemented.\n", 2487 __FUNCTION__, function)); 2488 } 2489 } 2490 2491 return NT_STATUS_NOT_SUPPORTED; 2492 } 2493 2494 /**************************************************************************** 2495 Reply to NT IOCTL 2496 ****************************************************************************/ 2497 2498 static void call_nt_transact_ioctl(connection_struct *conn, 2499 struct smb_request *req, 2500 uint16 **ppsetup, uint32 setup_count, 2501 char **ppparams, uint32 parameter_count, 2502 char **ppdata, uint32 data_count, 2503 uint32 max_data_count) 2504 { 2505 NTSTATUS status; 2506 uint32 function; 2507 uint16 fidnum; 2508 files_struct *fsp; 2509 uint8 isFSctl; 2510 uint8 compfilter; 2511 char *out_data = NULL; 2512 uint32 out_data_len = 0; 2513 char *pdata = *ppdata; 2514 TALLOC_CTX *ctx = talloc_tos(); 2515 2516 if (setup_count != 8) { 2517 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count)); 2518 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 2519 return; 2520 } 2521 2522 function = IVAL(*ppsetup, 0); 2523 fidnum = SVAL(*ppsetup, 4); 2524 isFSctl = CVAL(*ppsetup, 6); 2525 compfilter = CVAL(*ppsetup, 7); 2526 2527 DEBUG(10, ("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", 2528 function, fidnum, isFSctl, compfilter)); 2529 2530 fsp=file_fsp(req, fidnum); 2531 2532 /* 2533 * We don't really implement IOCTLs, especially on files. 2534 */ 2535 if (!isFSctl) { 2536 DEBUG(10, ("isFSctl: 0x%02X indicates IOCTL, not FSCTL!\n", 2537 isFSctl)); 2538 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 2539 return; 2540 } 2541 2542 /* Has to be for an open file! */ 2543 if (!check_fsp_open(conn, req, fsp)) { 2544 return; 2545 } 2546 2547 /* 2548 * out_data might be allocated by the VFS module, but talloc should be 2549 * used, and should be cleaned up when the request ends. 2550 */ 2551 status = smb_fsctl(fsp, 2552 ctx, 2553 function, 2554 req->flags2, 2555 (uint8_t *)pdata, 2556 data_count, 2557 (uint8_t **)&out_data, 2558 max_data_count, 2559 &out_data_len); 2560 if (!NT_STATUS_IS_OK(status)) { 2561 reply_nterror(req, status); 2562 } else { 2563 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, out_data, out_data_len); 2564 } 2464 2565 } 2465 2566 … … 3197 3298 show_msg((char *)req->inbuf); 3198 3299 3300 /* Windows clients expect all replies to 3301 an NT transact secondary (SMBnttranss 0xA1) 3302 to have a command code of NT transact 3303 (SMBnttrans 0xA0). See bug #8989 for details. */ 3304 req->cmd = SMBnttrans; 3305 3199 3306 if (req->wct < 18) { 3200 3307 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); -
vendor/current/source3/smbd/open.c
r740 r746 93 93 smb_fname_str_dbg(smb_fname), 94 94 (unsigned int)*access_granted )); 95 return NT_STATUS_OK; 96 } 97 98 if (access_mask == DELETE_ACCESS && 99 VALID_STAT(smb_fname->st) && 100 S_ISLNK(smb_fname->st.st_ex_mode)) { 101 /* We can always delete a symlink. */ 102 DEBUG(10,("smbd_check_open_rights: not checking ACL " 103 "on DELETE_ACCESS on symlink %s.\n", 104 smb_fname_str_dbg(smb_fname) )); 95 105 return NT_STATUS_OK; 96 106 } … … 698 708 } 699 709 700 /*******************************************************************701 Return True if the filename is one of the special executable types.702 ********************************************************************/703 704 bool is_executable(const char *fname)705 {706 if ((fname = strrchr_m(fname,'.'))) {707 if (strequal(fname,".com") ||708 strequal(fname,".dll") ||709 strequal(fname,".exe") ||710 strequal(fname,".sym")) {711 return True;712 }713 }714 return False;715 }716 717 710 /**************************************************************************** 718 711 Check if we can open a file with a share mode. … … 942 935 } 943 936 944 static bool is_delete_request(files_struct *fsp) {945 return ((fsp->access_mask == DELETE_ACCESS) &&946 (fsp->oplock_type == NO_OPLOCK));947 }948 949 937 /* 950 938 * Send a break message to the oplock holder and delay the open for … … 1091 1079 1092 1080 if (ex_entry != NULL) { 1093 /* Found an exclusive or batch oplock */ 1094 bool delay_it = is_delete_request(fsp) ? 1095 BATCH_OPLOCK_TYPE(ex_entry->op_type) : true; 1096 if (delay_it) { 1097 send_break_message(fsp, ex_entry, mid, oplock_request); 1098 return true; 1099 } 1081 send_break_message(fsp, ex_entry, mid, oplock_request); 1082 return true; 1100 1083 } 1101 1084 return false; … … 1335 1318 } 1336 1319 1337 /****************************************************************************1338 Open a file with a share mode - old openX method - map into NTCreate.1339 ****************************************************************************/1340 1341 bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,1342 int deny_mode, int open_func,1343 uint32 *paccess_mask,1344 uint32 *pshare_mode,1345 uint32 *pcreate_disposition,1346 uint32 *pcreate_options,1347 uint32_t *pprivate_flags)1348 {1349 uint32 access_mask;1350 uint32 share_mode;1351 uint32 create_disposition;1352 uint32 create_options = FILE_NON_DIRECTORY_FILE;1353 uint32_t private_flags = 0;1354 1355 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "1356 "open_func = 0x%x\n",1357 smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,1358 (unsigned int)open_func ));1359 1360 /* Create the NT compatible access_mask. */1361 switch (GET_OPENX_MODE(deny_mode)) {1362 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */1363 case DOS_OPEN_RDONLY:1364 access_mask = FILE_GENERIC_READ;1365 break;1366 case DOS_OPEN_WRONLY:1367 access_mask = FILE_GENERIC_WRITE;1368 break;1369 case DOS_OPEN_RDWR:1370 case DOS_OPEN_FCB:1371 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;1372 break;1373 default:1374 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",1375 (unsigned int)GET_OPENX_MODE(deny_mode)));1376 return False;1377 }1378 1379 /* Create the NT compatible create_disposition. */1380 switch (open_func) {1381 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:1382 create_disposition = FILE_CREATE;1383 break;1384 1385 case OPENX_FILE_EXISTS_OPEN:1386 create_disposition = FILE_OPEN;1387 break;1388 1389 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:1390 create_disposition = FILE_OPEN_IF;1391 break;1392 1393 case OPENX_FILE_EXISTS_TRUNCATE:1394 create_disposition = FILE_OVERWRITE;1395 break;1396 1397 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:1398 create_disposition = FILE_OVERWRITE_IF;1399 break;1400 1401 default:1402 /* From samba4 - to be confirmed. */1403 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {1404 create_disposition = FILE_CREATE;1405 break;1406 }1407 DEBUG(10,("map_open_params_to_ntcreate: bad "1408 "open_func 0x%x\n", (unsigned int)open_func));1409 return False;1410 }1411 1412 /* Create the NT compatible share modes. */1413 switch (GET_DENY_MODE(deny_mode)) {1414 case DENY_ALL:1415 share_mode = FILE_SHARE_NONE;1416 break;1417 1418 case DENY_WRITE:1419 share_mode = FILE_SHARE_READ;1420 break;1421 1422 case DENY_READ:1423 share_mode = FILE_SHARE_WRITE;1424 break;1425 1426 case DENY_NONE:1427 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;1428 break;1429 1430 case DENY_DOS:1431 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;1432 if (is_executable(smb_fname->base_name)) {1433 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;1434 } else {1435 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {1436 share_mode = FILE_SHARE_READ;1437 } else {1438 share_mode = FILE_SHARE_NONE;1439 }1440 }1441 break;1442 1443 case DENY_FCB:1444 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;1445 share_mode = FILE_SHARE_NONE;1446 break;1447 1448 default:1449 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",1450 (unsigned int)GET_DENY_MODE(deny_mode) ));1451 return False;1452 }1453 1454 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "1455 "share_mode = 0x%x, create_disposition = 0x%x, "1456 "create_options = 0x%x private_flags = 0x%x\n",1457 smb_fname_str_dbg(smb_fname),1458 (unsigned int)access_mask,1459 (unsigned int)share_mode,1460 (unsigned int)create_disposition,1461 (unsigned int)create_options,1462 (unsigned int)private_flags));1463 1464 if (paccess_mask) {1465 *paccess_mask = access_mask;1466 }1467 if (pshare_mode) {1468 *pshare_mode = share_mode;1469 }1470 if (pcreate_disposition) {1471 *pcreate_disposition = create_disposition;1472 }1473 if (pcreate_options) {1474 *pcreate_options = create_options;1475 }1476 if (pprivate_flags) {1477 *pprivate_flags = private_flags;1478 }1479 1480 return True;1481 1482 }1483 1484 1320 static void schedule_defer_open(struct share_mode_lock *lck, 1485 1321 struct timeval request_time, … … 1573 1409 smb_fname_str_dbg(smb_fname))); 1574 1410 return NT_STATUS_ACCESS_DENIED; 1411 } 1412 1413 if (!(access_granted & DELETE_ACCESS)) { 1414 if (can_delete_file_in_directory(conn, smb_fname)) { 1415 access_granted |= DELETE_ACCESS; 1416 } 1575 1417 } 1576 1418 … … 1705 1547 ZERO_STRUCT(id); 1706 1548 1707 /* Windows allows a new file to be created and1708 silently removes a FILE_ATTRIBUTE_DIRECTORY1709 sent by the client. Do the same. */1710 1711 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;1712 1713 1549 if (conn->printer) { 1714 1550 /* … … 1744 1580 new_dos_attributes = 0; 1745 1581 } else { 1582 /* Windows allows a new file to be created and 1583 silently removes a FILE_ATTRIBUTE_DIRECTORY 1584 sent by the client. Do the same. */ 1585 1586 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY; 1587 1746 1588 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is 1747 1589 * created new. */ … … 1787 1629 remove_deferred_open_message_smb(req->mid); 1788 1630 } 1789 }1790 1791 status = check_name(conn, smb_fname->base_name);1792 if (!NT_STATUS_IS_OK(status)) {1793 return status;1794 1631 } 1795 1632 … … 2743 2580 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname)); 2744 2581 2745 /* Ensure we have a directory attribute. */ 2746 file_attributes |= FILE_ATTRIBUTE_DIRECTORY; 2582 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) { 2583 /* Ensure we have a directory attribute. */ 2584 file_attributes |= FILE_ATTRIBUTE_DIRECTORY; 2585 } 2747 2586 2748 2587 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, " … … 2900 2739 fsp->share_access = share_access; 2901 2740 fsp->fh->private_options = 0; 2902 /*2903 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,2904 */2905 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;2906 2741 fsp->print_file = NULL; 2907 2742 fsp->modified = False; … … 2918 2753 mtimespec = smb_dname->st.st_ex_mtime; 2919 2754 2755 /* Temporary access mask used to open the directory fd. */ 2756 fsp->access_mask = FILE_READ_DATA | FILE_READ_ATTRIBUTES; 2920 2757 #ifdef O_DIRECTORY 2921 2758 status = fd_open(conn, fsp, O_RDONLY|O_DIRECTORY, 0); … … 2932 2769 return status; 2933 2770 } 2771 2772 /* 2773 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted, 2774 * Set the real access mask for later access (possibly delete). 2775 */ 2776 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES; 2934 2777 2935 2778 status = vfs_stat_fsp(fsp); … … 3132 2975 const char *fname) 3133 2976 { 3134 struct stream_struct *stream_info ;3135 files_struct **streams ;2977 struct stream_struct *stream_info = NULL; 2978 files_struct **streams = NULL; 3136 2979 int i; 3137 unsigned int num_streams ;2980 unsigned int num_streams = 0; 3138 2981 TALLOC_CTX *frame = talloc_stackframe(); 3139 2982 NTSTATUS status; 3140 2983 3141 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),3142 2984 status = vfs_streaminfo(conn, NULL, fname, talloc_tos(), 2985 &num_streams, &stream_info); 3143 2986 3144 2987 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED) … … 3150 2993 3151 2994 if (!NT_STATUS_IS_OK(status)) { 3152 DEBUG(10, (" SMB_VFS_STREAMINFOfailed: %s\n",2995 DEBUG(10, ("vfs_streaminfo failed: %s\n", 3153 2996 nt_errstr(status))); 3154 2997 goto fail; … … 3517 3360 fsp->access_mask = FILE_GENERIC_ALL; 3518 3361 3519 /* Convert all the generic bits. */3520 security_acl_map_generic(sd->dacl, &file_generic_mapping);3521 security_acl_map_generic(sd->sacl, &file_generic_mapping);3522 3523 3362 if (sec_info_sent & (SECINFO_OWNER| 3524 3363 SECINFO_GROUP| 3525 3364 SECINFO_DACL| 3526 3365 SECINFO_SACL)) { 3527 status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);3366 status = set_sd(fsp, sd, sec_info_sent); 3528 3367 } 3529 3368 … … 3814 3653 } 3815 3654 3816 /* All file access must go through check_name() */3817 3818 status = check_name(conn, smb_fname->base_name);3819 if (!NT_STATUS_IS_OK(status)) {3820 goto fail;3821 }3822 3823 3655 if (stream_name && is_ntfs_default_stream_smb_fname(smb_fname)) { 3824 3656 int ret; -
vendor/current/source3/smbd/oplock_linux.c
r740 r746 77 77 int ret; 78 78 79 /* First set the signal handler. */ 80 if (linux_set_lease_sighandler(fd) == -1) { 81 return -1; 82 } 79 83 ret = fcntl(fd, F_SETLEASE, leasetype); 80 84 if (ret == -1 && errno == EACCES) { 81 85 set_effective_capability(LEASE_CAPABILITY); 86 /* 87 * Bug 8974 - work around Linux kernel bug 88 * https://bugzilla.kernel.org/show_bug.cgi?id=43336. 89 * "fcntl(F_SETLEASE) resets signal number when 90 * called multiple times" 91 */ 92 if (linux_set_lease_sighandler(fd) == -1) { 93 return -1; 94 } 82 95 ret = fcntl(fd, F_SETLEASE, leasetype); 83 96 } -
vendor/current/source3/smbd/password.c
r740 r746 295 295 DEBUG(3, ("register_existing_vuid: User name: %s\t" 296 296 "Real name: %s\n", vuser->session_info->unix_name, 297 vuser->session_info->info3->base.full_name.string)); 297 vuser->session_info->info3->base.full_name.string ? 298 vuser->session_info->info3->base.full_name.string : "")); 298 299 299 300 if (!vuser->session_info->security_token) { -
vendor/current/source3/smbd/posix_acls.c
r740 r746 1131 1131 ****************************************************************************/ 1132 1132 1133 #define FILE_SPECIFIC_READ_BITS (FILE_READ_DATA|FILE_READ_EA |FILE_READ_ATTRIBUTES)1134 #define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA |FILE_WRITE_ATTRIBUTES)1133 #define FILE_SPECIFIC_READ_BITS (FILE_READ_DATA|FILE_READ_EA) 1134 #define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA) 1135 1135 #define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE) 1136 1136 … … 1354 1354 ****************************************************************************/ 1355 1355 1356 static bool ensure_canon_entry_valid(connection_struct *conn, canon_ace **pp_ace, 1357 const struct share_params *params, 1358 const bool is_directory, 1359 const struct dom_sid *pfile_owner_sid, 1360 const struct dom_sid *pfile_grp_sid, 1361 const SMB_STRUCT_STAT *pst, 1362 bool setting_acl) 1356 static bool ensure_canon_entry_valid(connection_struct *conn, 1357 canon_ace **pp_ace, 1358 bool is_default_acl, 1359 const struct share_params *params, 1360 const bool is_directory, 1361 const struct dom_sid *pfile_owner_sid, 1362 const struct dom_sid *pfile_grp_sid, 1363 const SMB_STRUCT_STAT *pst, 1364 bool setting_acl) 1363 1365 { 1364 1366 canon_ace *pace; … … 1371 1373 if (pace->type == SMB_ACL_USER_OBJ) { 1372 1374 1373 if (setting_acl )1375 if (setting_acl && !is_default_acl) { 1374 1376 apply_default_perms(params, is_directory, pace, S_IRUSR); 1377 } 1375 1378 got_user = True; 1376 1379 … … 1381 1384 */ 1382 1385 1383 if (setting_acl )1386 if (setting_acl && !is_default_acl) { 1384 1387 apply_default_perms(params, is_directory, pace, S_IRGRP); 1388 } 1385 1389 got_grp = True; 1386 1390 … … 1391 1395 */ 1392 1396 1393 if (setting_acl )1397 if (setting_acl && !is_default_acl) { 1394 1398 apply_default_perms(params, is_directory, pace, S_IROTH); 1399 } 1395 1400 got_other = True; 1396 1401 pace_other = pace; 1402 1403 } else if (pace->type == SMB_ACL_USER || pace->type == SMB_ACL_GROUP) { 1404 1405 /* 1406 * Ensure create mask/force create mode is respected on set. 1407 */ 1408 1409 if (setting_acl && !is_default_acl) { 1410 apply_default_perms(params, is_directory, pace, S_IRGRP); 1411 } 1397 1412 } 1398 1413 } … … 1410 1425 pace->trustee = *pfile_owner_sid; 1411 1426 pace->attr = ALLOW_ACE; 1427 /* Start with existing permissions, principle of least 1428 surprises for the user. */ 1429 pace->perms = pst->st_ex_mode; 1412 1430 1413 1431 if (setting_acl) { 1414 1432 /* See if the owning user is in any of the other groups in 1415 the ACE . If so, OR in the permissions from that group. */1416 1417 bool group_matched = False; 1433 the ACE, or if there's a matching user entry. 1434 If so, OR in the permissions from that entry. */ 1435 1418 1436 canon_ace *pace_iter; 1419 1437 1420 1438 for (pace_iter = *pp_ace; pace_iter; pace_iter = pace_iter->next) { 1421 if (pace_iter->type == SMB_ACL_GROUP_OBJ || pace_iter->type == SMB_ACL_GROUP) { 1439 if (pace_iter->type == SMB_ACL_USER && 1440 pace_iter->unix_ug.uid == pace->unix_ug.uid) { 1441 pace->perms |= pace_iter->perms; 1442 } else if (pace_iter->type == SMB_ACL_GROUP_OBJ || pace_iter->type == SMB_ACL_GROUP) { 1422 1443 if (uid_entry_in_group(conn, pace, pace_iter)) { 1423 1444 pace->perms |= pace_iter->perms; 1424 group_matched = True;1425 1445 } 1426 1446 } 1427 1447 } 1428 1448 1429 /* If we only got an "everyone" perm, just use that. */1430 if (!group_matched) {1449 if (pace->perms == 0) { 1450 /* If we only got an "everyone" perm, just use that. */ 1431 1451 if (got_other) 1432 1452 pace->perms = pace_other->perms; 1433 else1434 pace->perms = 0; 1435 }1436 1437 apply_default_perms(params, is_directory, pace, S_IRUSR);1453 } 1454 1455 if (!is_default_acl) { 1456 apply_default_perms(params, is_directory, pace, S_IRUSR); 1457 } 1438 1458 } else { 1439 1459 pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR); … … 1461 1481 else 1462 1482 pace->perms = 0; 1463 apply_default_perms(params, is_directory, pace, S_IRGRP); 1483 if (!is_default_acl) { 1484 apply_default_perms(params, is_directory, pace, S_IRGRP); 1485 } 1464 1486 } else { 1465 1487 pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRGRP, S_IWGRP, S_IXGRP); … … 1483 1505 if (setting_acl) { 1484 1506 pace->perms = 0; 1485 apply_default_perms(params, is_directory, pace, S_IROTH); 1507 if (!is_default_acl) { 1508 apply_default_perms(params, is_directory, pace, S_IROTH); 1509 } 1486 1510 } else 1487 1511 pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IROTH, S_IWOTH, S_IXOTH); … … 1497 1521 If it does not have them, check if there are any entries where the trustee is the 1498 1522 file owner or the owning group, and map these to SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ. 1523 Note we must not do this to default directory ACLs. 1499 1524 ****************************************************************************/ 1500 1525 … … 1536 1561 if (!got_group_obj) 1537 1562 DEBUG(10,("check_owning_objs: ACL is missing an owning group entry.\n")); 1538 }1539 1540 /****************************************************************************1541 If an ACE entry is SMB_ACL_USER_OBJ and not CREATOR_OWNER, map to SMB_ACL_USER.1542 If an ACE entry is SMB_ACL_GROUP_OBJ and not CREATOR_GROUP, map to SMB_ACL_GROUP1543 ****************************************************************************/1544 1545 static bool dup_owning_ace(canon_ace *dir_ace, canon_ace *ace)1546 {1547 /* dir ace must be followings.1548 SMB_ACL_USER_OBJ : trustee(CREATOR_OWNER) -> Posix ACL d:u::perm1549 SMB_ACL_USER : not trustee -> Posix ACL u:user:perm1550 SMB_ACL_USER_OBJ : trustee -> convert to SMB_ACL_USER : trustee1551 Posix ACL u:trustee:perm1552 1553 SMB_ACL_GROUP_OBJ: trustee(CREATOR_GROUP) -> Posix ACL d:g::perm1554 SMB_ACL_GROUP : not trustee -> Posix ACL g:group:perm1555 SMB_ACL_GROUP_OBJ: trustee -> convert to SMB_ACL_GROUP : trustee1556 Posix ACL g:trustee:perm1557 */1558 1559 if (ace->type == SMB_ACL_USER_OBJ &&1560 !(dom_sid_equal(&ace->trustee, &global_sid_Creator_Owner))) {1561 canon_ace *dup_ace = dup_canon_ace(ace);1562 1563 if (dup_ace == NULL) {1564 return false;1565 }1566 dup_ace->type = SMB_ACL_USER;1567 DLIST_ADD_END(dir_ace, dup_ace, canon_ace *);1568 }1569 1570 if (ace->type == SMB_ACL_GROUP_OBJ &&1571 !(dom_sid_equal(&ace->trustee, &global_sid_Creator_Group))) {1572 canon_ace *dup_ace = dup_canon_ace(ace);1573 1574 if (dup_ace == NULL) {1575 return false;1576 }1577 dup_ace->type = SMB_ACL_GROUP;1578 DLIST_ADD_END(dir_ace, dup_ace, canon_ace *);1579 }1580 1581 return true;1582 1563 } 1583 1564 … … 1805 1786 (SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT)) { 1806 1787 1788 canon_ace *current_dir_ace = current_ace; 1807 1789 DLIST_ADD_END(dir_ace, current_ace, canon_ace *); 1808 1790 … … 1830 1812 dbgtext("create_canon_ace_lists: adding dir ACL:\n"); 1831 1813 print_canon_ace( current_ace, 0); 1832 }1833 1834 /*1835 * We have a lossy mapping: directory ACE entries1836 * CREATOR_OWNER ------\1837 * (map to) +---> SMB_ACL_USER_OBJ1838 * owning sid ------/1839 *1840 * CREATOR_GROUP ------\1841 * (map to) +---> SMB_ACL_GROUP_OBJ1842 * primary group sid --/1843 *1844 * on set. And on read of a directory ACL1845 *1846 * SMB_ACL_USER_OBJ ----> CREATOR_OWNER1847 * SMB_ACL_GROUP_OBJ ---> CREATOR_GROUP.1848 *1849 * Deal with this on set by duplicating1850 * owning sid and primary group sid ACE1851 * entries into the directory ACL.1852 * Fix from Tsukasa Hamano <hamano@osstech.co.jp>.1853 */1854 1855 if (!dup_owning_ace(dir_ace, current_ace)) {1856 DEBUG(0,("create_canon_ace_lists: malloc fail !\n"));1857 free_canon_ace_list(file_ace);1858 free_canon_ace_list(dir_ace);1859 return false;1860 1814 } 1861 1815 … … 1894 1848 current_ace = NULL; 1895 1849 } 1850 1851 /* 1852 * current_ace is now either owned by file_ace 1853 * or is NULL. We can safely operate on current_dir_ace 1854 * to treat mapping for default acl entries differently 1855 * than access acl entries. 1856 */ 1857 1858 if (current_dir_ace->owner_type == UID_ACE) { 1859 /* 1860 * We already decided above this is a uid, 1861 * for default acls ace's only CREATOR_OWNER 1862 * maps to ACL_USER_OBJ. All other uid 1863 * ace's are ACL_USER. 1864 */ 1865 if (dom_sid_equal(¤t_dir_ace->trustee, 1866 &global_sid_Creator_Owner)) { 1867 current_dir_ace->type = SMB_ACL_USER_OBJ; 1868 } else { 1869 current_dir_ace->type = SMB_ACL_USER; 1870 } 1871 } 1872 1873 if (current_dir_ace->owner_type == GID_ACE) { 1874 /* 1875 * We already decided above this is a gid, 1876 * for default acls ace's only CREATOR_GROUP 1877 * maps to ACL_GROUP_OBJ. All other uid 1878 * ace's are ACL_GROUP. 1879 */ 1880 if (dom_sid_equal(¤t_dir_ace->trustee, 1881 &global_sid_Creator_Group)) { 1882 current_dir_ace->type = SMB_ACL_GROUP_OBJ; 1883 } else { 1884 current_dir_ace->type = SMB_ACL_GROUP; 1885 } 1886 } 1896 1887 } 1897 1888 } … … 1955 1946 } else { 1956 1947 /* 1957 * Check if we have SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ entries in each 1958 * ACL. If we don't have them, check if any SMB_ACL_USER/SMB_ACL_GROUP 1959 * entries can be converted to *_OBJ. Usually we will already have these 1960 * entries in the Default ACL, and the Access ACL will not have them. 1948 * Check if we have SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ entries in 1949 * the file ACL. If we don't have them, check if any SMB_ACL_USER/SMB_ACL_GROUP 1950 * entries can be converted to *_OBJ. Don't do this for the default 1951 * ACL, we will create them separately for this if needed inside 1952 * ensure_canon_entry_valid(). 1961 1953 */ 1962 1954 if (file_ace) { 1963 1955 check_owning_objs(file_ace, pfile_owner_sid, pfile_grp_sid); 1964 }1965 if (dir_ace) {1966 check_owning_objs(dir_ace, pfile_owner_sid, pfile_grp_sid);1967 1956 } 1968 1957 } … … 2287 2276 2288 2277 /**************************************************************************** 2289 Create a default mode that will be used if a security descriptor entry has2290 no user/group/world entries.2291 ****************************************************************************/2292 2293 static mode_t create_default_mode(files_struct *fsp, bool interitable_mode)2294 {2295 int snum = SNUM(fsp->conn);2296 mode_t and_bits = (mode_t)0;2297 mode_t or_bits = (mode_t)0;2298 mode_t mode;2299 2300 if (interitable_mode) {2301 mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE,2302 fsp->fsp_name, NULL);2303 } else {2304 mode = S_IRUSR;2305 }2306 2307 if (fsp->is_directory)2308 mode |= (S_IWUSR|S_IXUSR);2309 2310 /*2311 * Now AND with the create mode/directory mode bits then OR with the2312 * force create mode/force directory mode bits.2313 */2314 2315 if (fsp->is_directory) {2316 and_bits = lp_dir_security_mask(snum);2317 or_bits = lp_force_dir_security_mode(snum);2318 } else {2319 and_bits = lp_security_mask(snum);2320 or_bits = lp_force_security_mode(snum);2321 }2322 2323 return ((mode & and_bits)|or_bits);2324 }2325 2326 /****************************************************************************2327 2278 Unpack a struct security_descriptor into two canonical ace lists. We don't depend on this 2328 2279 succeeding. … … 2338 2289 const struct security_descriptor *psd) 2339 2290 { 2340 SMB_STRUCT_STAT st;2341 2291 canon_ace *file_ace = NULL; 2342 2292 canon_ace *dir_ace = NULL; … … 2402 2352 print_canon_ace_list( "file ace - before valid", file_ace); 2403 2353 2404 st = *pst; 2405 2406 /* 2407 * A default 3 element mode entry for a file should be r-- --- ---. 2408 * A default 3 element mode entry for a directory should be rwx --- ---. 2409 */ 2410 2411 st.st_ex_mode = create_default_mode(fsp, False); 2412 2413 if (!ensure_canon_entry_valid(fsp->conn, &file_ace, fsp->conn->params, 2414 fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) { 2354 if (!ensure_canon_entry_valid(fsp->conn, &file_ace, false, fsp->conn->params, 2355 fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) { 2415 2356 free_canon_ace_list(file_ace); 2416 2357 free_canon_ace_list(dir_ace); … … 2420 2361 print_canon_ace_list( "dir ace - before valid", dir_ace); 2421 2362 2422 /* 2423 * A default inheritable 3 element mode entry for a directory should be the 2424 * mode Samba will use to create a file within. Ensure user rwx bits are set if 2425 * it's a directory. 2426 */ 2427 2428 st.st_ex_mode = create_default_mode(fsp, True); 2429 2430 if (dir_ace && !ensure_canon_entry_valid(fsp->conn, &dir_ace, fsp->conn->params, 2431 fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) { 2363 if (dir_ace && !ensure_canon_entry_valid(fsp->conn, &dir_ace, true, fsp->conn->params, 2364 fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) { 2432 2365 free_canon_ace_list(file_ace); 2433 2366 free_canon_ace_list(dir_ace); … … 2517 2450 canon_ace *next_ace = NULL; 2518 2451 int entry_id = SMB_ACL_FIRST_ENTRY; 2452 bool is_default_acl = (the_acl_type == SMB_ACL_TYPE_DEFAULT); 2519 2453 SMB_ACL_ENTRY_T entry; 2520 2454 size_t ace_count; … … 2604 2538 ace->unix_ug = unix_ug; 2605 2539 ace->owner_type = owner_type; 2606 ace->ace_flags = get_pai_flags(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT));2540 ace->ace_flags = get_pai_flags(pal, ace, is_default_acl); 2607 2541 2608 2542 DLIST_ADD(l_head, ace); … … 2613 2547 */ 2614 2548 2615 if (!ensure_canon_entry_valid(conn, &l_head, conn->params,2549 if (!ensure_canon_entry_valid(conn, &l_head, is_default_acl, conn->params, 2616 2550 S_ISDIR(psbuf->st_ex_mode), powner, pgroup, 2617 2551 psbuf, False)) … … 2623 2557 */ 2624 2558 2625 DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", the_acl_type == SMB_ACL_TYPE_ACCESS ? "Access" : "Default"));2559 DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", is_default_acl ? "Default" : "Access")); 2626 2560 2627 2561 for ( ace_count = 0, ace = l_head; ace; ace = next_ace, ace_count++) { -
vendor/current/source3/smbd/process.c
r740 r746 452 452 p_unread, &len); 453 453 if (!NT_STATUS_IS_OK(status)) { 454 DEBUG(1, ("read_smb_length_return_keepalive failed for " 455 "client %s read error = %s.\n", 456 sconn->client_id.addr, nt_errstr(status))); 454 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1, 455 ("receive_smb_raw_talloc failed for client %s " 456 "read error = %s.\n", 457 sconn->client_id.addr, nt_errstr(status))); 457 458 return status; 458 459 } … … 1442 1443 /* Make sure this is an SMB packet. smb_size contains NetBIOS header 1443 1444 * so subtract 4 from it. */ 1444 if ( !valid_smb_header(req->inbuf)1445 || (size < (smb_size - 4))) {1445 if ((size < (smb_size - 4)) || 1446 !valid_smb_header(req->inbuf)) { 1446 1447 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n", 1447 1448 smb_len(req->inbuf))); … … 2089 2090 2090 2091 /* 2091 * Check if the client tries to fool us. The request so far uses the 2092 * space to the end of the byte buffer in the request just 2093 * processed. The chain_offset can't point into that area. If that was 2094 * the case, we could end up with an endless processing of the chain, 2095 * we would always handle the same request. 2092 * Check if the client tries to fool us. The chain offset 2093 * needs to point beyond the current request in the chain, it 2094 * needs to strictly grow. Otherwise we might be tricked into 2095 * an endless loop always processing the same request over and 2096 * over again. We used to assume that vwv and the byte buffer 2097 * array in a chain are always attached, but OS/2 the 2098 * Write&X/Read&X chain puts the Read&X vwv array right behind 2099 * the Write&X vwv chain. The Write&X bcc array is put behind 2100 * the Read&X vwv array. So now we check whether the chain 2101 * offset points strictly behind the previous vwv 2102 * array. req->buf points right after the vwv array of the 2103 * previous request. See 2104 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more 2105 * information. 2096 2106 */ 2097 2107 2098 already_used = PTR_DIFF(req->buf +req->buflen, smb_base(req->inbuf));2099 if (chain_offset < already_used) {2108 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf)); 2109 if (chain_offset <= already_used) { 2100 2110 goto error; 2101 2111 } … … 2798 2808 * Handle SMBecho requests in a forked child process 2799 2809 */ 2800 staticbool fork_echo_handler(struct smbd_server_connection *sconn)2810 bool fork_echo_handler(struct smbd_server_connection *sconn) 2801 2811 { 2802 2812 int listener_pipe[2]; … … 2912 2922 int ret; 2913 2923 2914 if (lp_maxprotocol() == PROTOCOL_SMB2 && 2915 !lp_async_smb_echo_handler()) { 2924 if (lp_maxprotocol() == PROTOCOL_SMB2) { 2916 2925 /* 2917 2926 * We're not making the decision here, … … 3034 3043 } 3035 3044 3036 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {3037 exit_server("Failed to fork echo handler");3038 }3039 3040 3045 /* Setup oplocks */ 3041 3046 if (!init_oplocks(sconn->msg_ctx)) -
vendor/current/source3/smbd/proto.h
r740 r746 302 302 uint32_t access_mask); 303 303 bool can_delete_file_in_directory(connection_struct *conn, 304 struct smb_filename *smb_fname);304 const struct smb_filename *smb_fname); 305 305 bool can_access_file_data(connection_struct *conn, 306 306 const struct smb_filename *smb_fname, … … 337 337 struct smb_filename **smb_fname, 338 338 uint32_t ucf_flags); 339 NTSTATUS check_veto_path(connection_struct *conn, const char *name); 339 340 NTSTATUS check_name(connection_struct *conn, const char *name); 340 341 int get_real_filename(connection_struct *conn, const char *path, … … 373 374 void file_free(struct smb_request *req, files_struct *fsp); 374 375 files_struct *file_fsp(struct smb_request *req, uint16 fid); 376 uint64_t fsp_persistent_id(const struct files_struct *fsp); 377 struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req, 378 uint64_t persistent_id, 379 uint64_t volatile_id); 375 380 NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from, 376 381 uint32 access_mask, uint32 share_access, … … 557 562 char *pdata, int datasize); 558 563 void reply_ntcreate_and_X(struct smb_request *req); 559 NTSTATUS set_sd(files_struct *fsp, uint8_t *data, uint32_t sd_len,564 NTSTATUS set_sd(files_struct *fsp, struct security_descriptor *psd, 560 565 uint32_t security_info_sent); 566 NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len, 567 uint32_t security_info_sent); 568 NTSTATUS smb_fsctl(struct files_struct *fsp, 569 TALLOC_CTX *ctx, 570 uint32_t function, 571 uint16_t req_flags, /* Needed for UNICODE ... */ 572 const uint8_t *_in_data, 573 uint32_t in_len, 574 uint8_t **_out_data, 575 uint32_t max_out_len, 576 uint32_t *out_len); 561 577 struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size); 562 578 void reply_ntcancel(struct smb_request *req); … … 587 603 const char *fname, 588 604 SMB_STRUCT_STAT *psbuf); 589 bool is_executable(const char *fname);590 605 bool is_stat_open(uint32 access_mask); 591 606 bool request_timed_out(struct timeval request_time, … … 607 622 uint32 share_access, 608 623 uint32 create_options); 609 bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,610 int deny_mode, int open_func,611 uint32 *paccess_mask,612 uint32 *pshare_mode,613 uint32 *pcreate_disposition,614 uint32 *pcreate_options,615 uint32_t *pprivate_flags);616 624 void remove_deferred_open_entry(struct file_id id, uint64_t mid, 617 625 struct server_id pid); … … 802 810 bool req_is_in_chain(struct smb_request *req); 803 811 void smbd_process(struct smbd_server_connection *sconn); 812 bool fork_echo_handler(struct smbd_server_connection *sconn); 804 813 805 814 /* The following definitions come from smbd/quotas.c */ … … 960 969 bool unix_token_equal(const struct security_unix_token *t1, const struct security_unix_token *t2); 961 970 bool push_sec_ctx(void); 962 void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, struct security_token *token);971 void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, const struct security_token *token); 963 972 void set_root_sec_ctx(void); 964 973 bool pop_sec_ctx(void); … … 988 997 int add_home_service(const char *service, const char *username, const char *homedir); 989 998 int find_service(TALLOC_CTX *ctx, const char *service, char **p_service_out); 990 connection_struct *make_connection_snum(struct smbd_server_connection *sconn, 991 int snum, user_struct *vuser, 999 struct smbd_smb2_tcon; 1000 connection_struct *make_connection_smb2(struct smbd_server_connection *sconn, 1001 struct smbd_smb2_tcon *tcon, 1002 user_struct *vuser, 992 1003 DATA_BLOB password, 993 1004 const char *pdev, … … 1045 1056 bool case_sensitive); 1046 1057 bool stat_cache_lookup(connection_struct *conn, 1058 bool posix_paths, 1047 1059 char **pp_name, 1048 1060 char **pp_dirpath, … … 1175 1187 NTSTATUS vfs_stat_fsp(files_struct *fsp); 1176 1188 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid); 1189 NTSTATUS vfs_streaminfo(connection_struct *conn, 1190 struct files_struct *fsp, 1191 const char *fname, 1192 TALLOC_CTX *mem_ctx, 1193 unsigned int *num_streams, 1194 struct stream_struct **streams); 1177 1195 1178 1196 /* The following definitions come from smbd/avahi_register.c */ -
vendor/current/source3/smbd/quotas.c
r740 r746 746 746 *bsize = gqr.getquota_rslt_u.gqr_rquota.rq_bsize; 747 747 *dsize = D.dqb_bsoftlimit; 748 749 if (D.dqb_curblocks == 1)750 *bsize = 512;751 748 752 749 if (D.dqb_curblocks > D.dqb_bsoftlimit) { -
vendor/current/source3/smbd/reply.c
r740 r746 1767 1767 } 1768 1768 1769 if (!map_open_params_to_ntcreate(smb_fname , deny_mode,1769 if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode, 1770 1770 OPENX_FILE_EXISTS_OPEN, &access_mask, 1771 1771 &share_mode, &create_disposition, … … 1942 1942 } 1943 1943 1944 if (!map_open_params_to_ntcreate(smb_fname, deny_mode, smb_ofun, 1944 if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode, 1945 smb_ofun, 1945 1946 &access_mask, &share_mode, 1946 1947 &create_disposition, … … 2541 2542 2542 2543 /* The set is across all open files on this dev/inode pair. */ 2543 if (!set_delete_on_close(fsp, True, &conn->session_info->utok)) { 2544 if (!set_delete_on_close(fsp, true, 2545 conn->session_info->security_token, 2546 &conn->session_info->utok)) { 2544 2547 close_file(req, fsp, NORMAL_CLOSE); 2545 2548 return NT_STATUS_ACCESS_DENIED; … … 4630 4633 SSVAL(req->outbuf,smb_vwv4,nwritten>>16); 4631 4634 4632 if (nwritten < (ssize_t)numtowrite) {4633 SCVAL(req->outbuf,smb_rcls,ERRHRD);4634 SSVAL(req->outbuf,smb_err,ERRdiskfull);4635 }4636 4637 4635 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n", 4638 4636 fsp->fnum, (int)numtowrite, (int)nwritten)); … … 5655 5653 } 5656 5654 5657 if (!set_delete_on_close(fsp, true, &conn->session_info->utok)) { 5655 if (!set_delete_on_close(fsp, true, 5656 conn->session_info->security_token, 5657 &conn->session_info->utok)) { 5658 5658 close_file(req, fsp, ERROR_CLOSE); 5659 5659 reply_nterror(req, NT_STATUS_ACCESS_DENIED); … … 5936 5936 5937 5937 /**************************************************************************** 5938 Returns an error if the parent directory for a filename is open in an 5939 incompatible way. 5940 ****************************************************************************/ 5941 5942 static NTSTATUS parent_dirname_compatible_open(connection_struct *conn, 5943 const struct smb_filename *smb_fname_dst_in) 5944 { 5945 char *parent_dir = NULL; 5946 struct smb_filename smb_fname_parent; 5947 struct file_id id; 5948 files_struct *fsp = NULL; 5949 int ret; 5950 5951 if (!parent_dirname(talloc_tos(), smb_fname_dst_in->base_name, 5952 &parent_dir, NULL)) { 5953 return NT_STATUS_NO_MEMORY; 5954 } 5955 ZERO_STRUCT(smb_fname_parent); 5956 smb_fname_parent.base_name = parent_dir; 5957 5958 ret = SMB_VFS_LSTAT(conn, &smb_fname_parent); 5959 if (ret == -1) { 5960 return map_nt_error_from_unix(errno); 5961 } 5962 5963 /* 5964 * We're only checking on this smbd here, mostly good 5965 * enough.. and will pass tests. 5966 */ 5967 5968 id = vfs_file_id_from_sbuf(conn, &smb_fname_parent.st); 5969 for (fsp = file_find_di_first(conn->sconn, id); fsp; 5970 fsp = file_find_di_next(fsp)) { 5971 if (fsp->access_mask & DELETE_ACCESS) { 5972 return NT_STATUS_SHARING_VIOLATION; 5973 } 5974 } 5975 return NT_STATUS_OK; 5976 } 5977 5978 /**************************************************************************** 5938 5979 Rename an open file - given an fsp. 5939 5980 ****************************************************************************/ … … 5952 5993 5953 5994 status = check_name(conn, smb_fname_dst_in->base_name); 5995 if (!NT_STATUS_IS_OK(status)) { 5996 return status; 5997 } 5998 5999 status = parent_dirname_compatible_open(conn, smb_fname_dst_in); 5954 6000 if (!NT_STATUS_IS_OK(status)) { 5955 6001 return status; … … 6562 6608 struct smb_filename *smb_fname_src = NULL; 6563 6609 struct smb_filename *smb_fname_dst = NULL; 6610 uint32_t src_ucf_flags = lp_posix_pathnames() ? UCF_UNIX_NAME_LOOKUP : UCF_COND_ALLOW_WCARD_LCOMP; 6611 uint32_t dst_ucf_flags = UCF_SAVE_LCOMP | (lp_posix_pathnames() ? 0 : UCF_COND_ALLOW_WCARD_LCOMP); 6564 6612 bool stream_rename = false; 6565 6613 … … 6604 6652 req->flags2 & FLAGS2_DFS_PATHNAMES, 6605 6653 name, 6606 UCF_COND_ALLOW_WCARD_LCOMP,6654 src_ucf_flags, 6607 6655 &src_has_wcard, 6608 6656 &smb_fname_src); … … 6622 6670 req->flags2 & FLAGS2_DFS_PATHNAMES, 6623 6671 newname, 6624 UCF_COND_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP,6672 dst_ucf_flags, 6625 6673 &dest_has_wcard, 6626 6674 &smb_fname_dst); … … 6733 6781 new_create_disposition = FILE_OPEN; 6734 6782 } else { 6735 if (!map_open_params_to_ntcreate(smb_fname_dst_tmp, 0, ofun, 6783 if (!map_open_params_to_ntcreate(smb_fname_dst_tmp->base_name, 6784 0, ofun, 6736 6785 NULL, NULL, 6737 6786 &new_create_disposition, -
vendor/current/source3/smbd/sec_ctx.c
r740 r746 305 305 ****************************************************************************/ 306 306 307 void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, struct security_token *token)307 void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, const struct security_token *token) 308 308 { 309 309 struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx]; -
vendor/current/source3/smbd/server.c
r740 r746 65 65 */ 66 66 67 if (sconn->client_id.name != NULL && 68 sconn->client_id.name != sconn->client_id.addr) { 69 talloc_free(discard_const_p(char, sconn->client_id.name)); 70 sconn->client_id.name = NULL; 71 } 72 67 73 client_addr(fd, sconn->client_id.addr, sizeof(sconn->client_id.addr)); 68 74 … … 277 283 static struct timed_event *cleanup_te; 278 284 struct server_id child_id; 285 286 child_id = procid_self(); /* Just initialize pid and potentially vnn */ 287 child_id.pid = pid; 288 289 for (child = children; child != NULL; child = child->next) { 290 if (child->pid == pid) { 291 struct child_pid *tmp = child; 292 DLIST_REMOVE(children, child); 293 SAFE_FREE(tmp); 294 num_children -= 1; 295 break; 296 } 297 } 298 299 if (child == NULL) { 300 /* not all forked child processes are added to the children list */ 301 DEBUG(2, ("Could not find child %d -- ignoring\n", (int)pid)); 302 return; 303 } 279 304 280 305 if (unclean_shutdown) { … … 296 321 } 297 322 298 child_id = procid_self(); /* Just initialize pid and potentially vnn */299 child_id.pid = pid;300 301 323 if (!serverid_deregister(child_id)) { 302 324 DEBUG(1, ("Could not remove pid %d from serverid.tdb\n", 303 325 (int)pid)); 304 326 } 305 306 for (child = children; child != NULL; child = child->next) {307 if (child->pid == pid) {308 struct child_pid *tmp = child;309 DLIST_REMOVE(children, child);310 SAFE_FREE(tmp);311 num_children -= 1;312 return;313 }314 }315 316 /* not all forked child processes are added to the children list */317 DEBUG(1, ("Could not find child %d -- ignoring\n", (int)pid));318 327 } 319 328 … … 442 451 * the global random state in the parent. 443 452 */ 444 generate_random_buffer((uint8_t *)&unique_id, sizeof(unique_id));453 unique_id = serverid_get_random_unique_id(); 445 454 446 455 pid = sys_fork(); … … 611 620 } 612 621 613 static bool smbd_parent_housekeeping(const struct timeval *now, void *private_data)614 {615 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();616 time_t t = time_mono(NULL);617 618 DEBUG(5, ("parent housekeeping\n"));619 620 /* if periodic printcap rescan is enabled, see if it's time to reload */621 if ((printcap_cache_time != 0)622 && (t >= (last_printer_reload_time + printcap_cache_time))) {623 DEBUG( 3,( "Printcap cache time expired.\n"));624 pcap_cache_reload(server_event_context(),625 smbd_messaging_context(),626 &reload_pcap_change_notify);627 last_printer_reload_time = t;628 }629 630 return true;631 }632 633 622 /**************************************************************************** 634 623 Open the socket communication. … … 642 631 int i; 643 632 char *ports; 633 char *tok; 634 const char *ptr; 644 635 unsigned dns_port = 0; 645 636 … … 663 654 } 664 655 656 for (ptr = ports; 657 next_token_talloc(talloc_tos(),&ptr, &tok, " \t,");) { 658 unsigned port = atoi(tok); 659 660 if (port == 0 || port > 0xffff) { 661 exit_server_cleanly("Invalid port in the config or on " 662 "the commandline specified!"); 663 } 664 } 665 665 666 if (lp_interfaces() && lp_bind_interfaces_only()) { 666 667 /* We have been given an interfaces line, and been … … 674 675 const struct sockaddr_storage *ifss = 675 676 iface_n_sockaddr_storage(i); 676 char *tok;677 const char *ptr;678 677 679 678 if (ifss == NULL) { … … 687 686 next_token_talloc(talloc_tos(),&ptr, &tok, " \t,");) { 688 687 unsigned port = atoi(tok); 689 if (port == 0 || port > 0xffff) {690 continue;691 }692 688 693 689 /* Keep the first port for mDNS service … … 707 703 from anywhere. */ 708 704 709 char *tok;710 const char *ptr;711 705 const char *sock_addr = lp_socket_address(); 712 706 char *sock_tok; … … 726 720 for (ptr=ports; next_token_talloc(talloc_tos(), &ptr, &tok, " \t,"); ) { 727 721 struct sockaddr_storage ss; 728 729 722 unsigned port = atoi(tok); 730 if (port == 0 || port > 0xffff) {731 continue;732 }733 723 734 724 /* Keep the first port for mDNS service … … 769 759 DEBUG(0, ("open_sockets_smbd: Failed to register " 770 760 "myself in serverid.tdb\n")); 771 return false;772 }773 774 if (!(event_add_idle(smbd_event_context(), NULL,775 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),776 "parent_housekeeping", smbd_parent_housekeeping,777 NULL))) {778 DEBUG(0, ("Could not add parent_housekeeping event\n"));779 761 return false; 780 762 } … … 915 897 TALLOC_CTX *frame; 916 898 NTSTATUS status; 917 uint64_t unique_id;918 899 919 900 /* … … 1114 1095 } 1115 1096 1116 generate_random_buffer((uint8_t *)&unique_id, sizeof(unique_id)); 1117 set_my_unique_id(unique_id); 1097 set_my_unique_id(serverid_get_random_unique_id()); 1118 1098 1119 1099 #if HAVE_SETPGID … … 1206 1186 exit(1); 1207 1187 1208 if (!print_backend_init(smbd_messaging_context()))1209 exit(1);1210 1211 1188 /* Open the share_info.tdb here, so we don't have to open 1212 1189 after the fork on every single connection. This is a small … … 1250 1227 exit(1); 1251 1228 } 1229 1230 /* 1231 * The print backend init also migrates the printing tdb's, 1232 * this requires a winreg pipe. 1233 */ 1234 if (!print_backend_init(smbd_messaging_context())) 1235 exit(1); 1252 1236 1253 1237 /* Publish nt printers, this requires a working winreg pipe */ -
vendor/current/source3/smbd/server_exit.c
r740 r746 84 84 const char *const reason) 85 85 { 86 bool had_open_conn = false;87 86 struct smbd_server_connection *sconn = smbd_server_conn; 88 87 … … 102 101 files_forall(sconn, log_writeable_file_fn, &found); 103 102 } 104 had_open_conn =conn_close_all(sconn);103 (void)conn_close_all(sconn); 105 104 invalidate_all_vuids(sconn); 106 105 } … … 176 175 dump_core(); 177 176 177 /* Notreached. */ 178 exit(1); 178 179 } else { 179 180 DEBUG(3,("Server exit (%s)\n", … … 185 186 } 186 187 187 /* if we had any open SMB connections when we exited then we 188 need to tell the parent smbd so that it can trigger a retry 189 of any locks we may have been holding or open files we were 190 blocking */ 191 if (had_open_conn) { 192 exit(1); 193 } else { 194 exit(0); 195 } 188 exit(0); 196 189 } 197 190 -
vendor/current/source3/smbd/server_reload.c
r740 r746 39 39 struct auth_serversupplied_info *session_info = NULL; 40 40 struct spoolss_PrinterInfo2 *pinfo2 = NULL; 41 int n_services; 42 int pnum; 41 43 int snum; 42 int n_services = lp_numservices();43 int pnum = lp_servicenumber(PRINTERS_NAME);44 44 const char *pname; 45 const char *sname; 45 46 NTSTATUS status; 46 bool skip = false;47 47 48 SMB_ASSERT(pcap_cache_loaded()); 48 load_printers(ev, msg_ctx); 49 50 n_services = lp_numservices(); 51 pnum = lp_servicenumber(PRINTERS_NAME); 52 49 53 DEBUG(10, ("reloading printer services from pcap cache\n")); 50 54 … … 55 59 /* can't remove stale printers before we 56 60 * are fully initilized */ 57 skip = true;61 return; 58 62 } 59 63 60 /* remove stale printers */ 61 for (snum = 0; skip == false && snum < n_services; snum++) { 62 /* avoid removing PRINTERS_NAME or non-autoloaded printers */ 63 if (snum == pnum || !(lp_snum_ok(snum) && lp_print_ok(snum) && 64 lp_autoloaded(snum))) 64 /* 65 * Add default config for printers added to smb.conf file and remove 66 * stale printers 67 */ 68 for (snum = 0; snum < n_services; snum++) { 69 /* avoid removing PRINTERS_NAME */ 70 if (snum == pnum) { 65 71 continue; 72 } 66 73 74 /* skip no-printer services */ 75 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) { 76 continue; 77 } 78 79 sname = lp_const_servicename(snum); 67 80 pname = lp_printername(snum); 68 if (!pcap_printername_ok(pname)) { 81 82 /* check printer, but avoid removing non-autoloaded printers */ 83 if (lp_autoloaded(snum) && !pcap_printername_ok(pname)) { 69 84 DEBUG(3, ("removing stale printer %s\n", pname)); 70 85 … … 83 98 pname); 84 99 lp_killservice(snum); 100 } else { 101 DEBUG(8, ("Adding default registry entry for printer " 102 "[%s], if it doesn't exist.\n", sname)); 103 nt_printer_add(session_info, session_info, msg_ctx, 104 sname); 85 105 } 86 106 } 87 107 108 /* Make sure deleted printers are gone */ 88 109 load_printers(ev, msg_ctx); 89 110 … … 107 128 test = False; 108 129 } 130 TALLOC_FREE(fname); 109 131 } 110 132 … … 146 168 struct messaging_context *msg_ctx) 147 169 { 170 /* 171 * Reload the printers first in the background process so that 172 * newly added printers get default values created in the registry. 173 * 174 * This will block the process for some time (~1 sec per printer), but 175 * it doesn't block smbd's servering clients. 176 */ 177 reload_printers(ev, msg_ctx); 178 148 179 message_send_all(msg_ctx, MSG_PRINTER_PCAP, NULL, 0, NULL); 149 180 } -
vendor/current/source3/smbd/service.c
r740 r746 697 697 } 698 698 699 /* We don't want to replace the original sanitized_username 700 as it is the original user given in the connect attempt. 701 This is used in '%U' substitutions. */ 702 TALLOC_FREE(forced_serverinfo->sanitized_username); 703 forced_serverinfo->sanitized_username = 704 talloc_move(forced_serverinfo, 705 &conn->session_info->sanitized_username); 706 699 707 TALLOC_FREE(conn->session_info); 700 708 conn->session_info = forced_serverinfo; … … 733 741 734 742 /**************************************************************************** 743 Setup the share access mask for a connection. 744 ****************************************************************************/ 745 746 static void create_share_access_mask(connection_struct *conn, int snum) 747 { 748 const struct security_token *token = conn->session_info->security_token; 749 750 share_access_check(token, 751 lp_servicename(snum), 752 MAXIMUM_ALLOWED_ACCESS, 753 &conn->share_access); 754 755 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) { 756 conn->share_access |= SEC_FLAG_SYSTEM_SECURITY; 757 } 758 if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) { 759 conn->share_access |= (SEC_RIGHTS_PRIV_RESTORE); 760 } 761 if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) { 762 conn->share_access |= (SEC_RIGHTS_PRIV_BACKUP); 763 } 764 if (security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) { 765 conn->share_access |= (SEC_STD_WRITE_OWNER); 766 } 767 } 768 769 /**************************************************************************** 735 770 Make a connection, given the snum to connect to, and the vuser of the 736 771 connecting user if appropriate. 737 772 ****************************************************************************/ 738 773 739 connection_struct *make_connection_snum(struct smbd_server_connection *sconn, 774 static connection_struct *make_connection_snum(struct smbd_server_connection *sconn, 775 connection_struct *conn, 740 776 int snum, user_struct *vuser, 741 777 DATA_BLOB password, … … 743 779 NTSTATUS *pstatus) 744 780 { 745 connection_struct *conn = NULL;746 781 struct smb_filename *smb_fname_cpath = NULL; 747 782 fstring dev; … … 760 795 } 761 796 762 conn = conn_new(sconn);763 if (!conn) {764 DEBUG(0,("Couldn't find free connection.\n"));765 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;766 goto err_root_exit;767 }768 769 797 conn->params->service = snum; 770 798 … … 816 844 status = set_conn_force_user_group(conn, snum); 817 845 if (!NT_STATUS_IS_OK(status)) { 818 conn_free(conn);819 846 *pstatus = status; 820 847 return NULL; … … 854 881 */ 855 882 856 share_access_check(conn->session_info->security_token, 857 lp_servicename(snum), MAXIMUM_ALLOWED_ACCESS, 858 &conn->share_access); 883 create_share_access_mask(conn, snum); 859 884 860 885 if ((conn->share_access & FILE_WRITE_DATA) == 0) { … … 1113 1138 yield_connection(conn, lp_servicename(snum)); 1114 1139 } 1115 if (conn) { 1140 return NULL; 1141 } 1142 1143 /**************************************************************************** 1144 Make a connection to a service from SMB1. Internal interface. 1145 ****************************************************************************/ 1146 1147 static connection_struct *make_connection_smb1(struct smbd_server_connection *sconn, 1148 int snum, user_struct *vuser, 1149 DATA_BLOB password, 1150 const char *pdev, 1151 NTSTATUS *pstatus) 1152 { 1153 connection_struct *ret_conn = NULL; 1154 connection_struct *conn = conn_new(sconn); 1155 if (!conn) { 1156 DEBUG(0,("make_connection_smb1: Couldn't find free connection.\n")); 1157 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES; 1158 return NULL; 1159 } 1160 ret_conn = make_connection_snum(sconn, 1161 conn, 1162 snum, 1163 vuser, 1164 password, 1165 pdev, 1166 pstatus); 1167 if (ret_conn != conn) { 1116 1168 conn_free(conn); 1117 } 1118 return NULL; 1169 return NULL; 1170 } 1171 return conn; 1119 1172 } 1120 1173 1121 1174 /**************************************************************************** 1122 Make a connection to a service. 1175 Make a connection to a service from SMB2. External SMB2 interface. 1176 We must set cnum before claiming connection. 1177 ****************************************************************************/ 1178 1179 connection_struct *make_connection_smb2(struct smbd_server_connection *sconn, 1180 struct smbd_smb2_tcon *tcon, 1181 user_struct *vuser, 1182 DATA_BLOB password, 1183 const char *pdev, 1184 NTSTATUS *pstatus) 1185 { 1186 connection_struct *ret_conn = NULL; 1187 connection_struct *conn = conn_new(sconn); 1188 if (!conn) { 1189 DEBUG(0,("make_connection_smb2: Couldn't find free connection.\n")); 1190 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES; 1191 return NULL; 1192 } 1193 conn->cnum = tcon->tid; 1194 ret_conn = make_connection_snum(sconn, 1195 conn, 1196 tcon->snum, 1197 vuser, 1198 password, 1199 pdev, 1200 pstatus); 1201 if (ret_conn != conn) { 1202 conn_free(conn); 1203 return NULL; 1204 } 1205 return conn; 1206 } 1207 1208 /**************************************************************************** 1209 Make a connection to a service. External SMB1 interface. 1123 1210 * 1124 1211 * @param service … … 1183 1270 DEBUG(5, ("making a connection to [homes] service " 1184 1271 "created at session setup time\n")); 1185 return make_connection_s num(sconn,1272 return make_connection_smb1(sconn, 1186 1273 vuser->homes_snum, 1187 1274 vuser, no_pw, … … 1207 1294 "service %s based on " 1208 1295 "security=share\n", service_in)); 1209 return make_connection_s num(sconn,1296 return make_connection_smb1(sconn, 1210 1297 snum, NULL, 1211 1298 password, … … 1219 1306 DEBUG(5, ("making a connection to 'homes' service [%s] " 1220 1307 "created at session setup time\n", service_in)); 1221 return make_connection_s num(sconn,1308 return make_connection_smb1(sconn, 1222 1309 vuser->homes_snum, 1223 1310 vuser, no_pw, … … 1267 1354 DEBUG(5, ("making a connection to 'normal' service %s\n", service)); 1268 1355 1269 return make_connection_s num(sconn, snum, vuser,1356 return make_connection_smb1(sconn, snum, vuser, 1270 1357 password, 1271 1358 dev, status); -
vendor/current/source3/smbd/sesssetup.c
r740 r746 736 736 } 737 737 738 if (auth. data[0] == ASN1_APPLICATION(0)) {738 if (auth.length > 0 && auth.data[0] == ASN1_APPLICATION(0)) { 739 739 /* Might be a second negTokenTarg packet */ 740 740 char *kerb_mech = NULL; -
vendor/current/source3/smbd/smb2_break.c
r740 r746 29 29 struct tevent_context *ev, 30 30 struct smbd_smb2_request *smb2req, 31 uint8_t in_oplock_level,32 uint 64_t in_file_id_volatile);31 struct files_struct *in_fsp, 32 uint8_t in_oplock_level); 33 33 static NTSTATUS smbd_smb2_oplock_break_recv(struct tevent_req *req, 34 34 uint8_t *out_oplock_level); … … 37 37 NTSTATUS smbd_smb2_request_process_break(struct smbd_smb2_request *req) 38 38 { 39 const uint8_t *inhdr;39 NTSTATUS status; 40 40 const uint8_t *inbody; 41 41 int i = req->current_idx; 42 size_t expected_body_size = 0x18;43 size_t body_size;44 42 uint8_t in_oplock_level; 45 43 uint64_t in_file_id_persistent; 46 44 uint64_t in_file_id_volatile; 45 struct files_struct *in_fsp; 47 46 struct tevent_req *subreq; 48 47 49 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 50 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 51 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 52 } 53 48 status = smbd_smb2_request_verify_sizes(req, 0x18); 49 if (!NT_STATUS_IS_OK(status)) { 50 return smbd_smb2_request_error(req, status); 51 } 54 52 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 55 56 body_size = SVAL(inbody, 0x00);57 if (body_size != expected_body_size) {58 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);59 }60 53 61 54 in_oplock_level = CVAL(inbody, 0x02); … … 71 64 in_file_id_volatile = BVAL(inbody, 0x10); 72 65 73 if (req->compat_chain_fsp) { 74 /* skip check */ 75 } else if (in_file_id_persistent != in_file_id_volatile) { 66 in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); 67 if (in_fsp == NULL) { 76 68 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 77 69 } 78 70 79 subreq = smbd_smb2_oplock_break_send(req, 80 req->sconn->smb2.event_ctx, 81 req, 82 in_oplock_level, 83 in_file_id_volatile); 71 subreq = smbd_smb2_oplock_break_send(req, req->sconn->smb2.event_ctx, 72 req, in_fsp, in_oplock_level); 84 73 if (subreq == NULL) { 85 74 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); … … 157 146 struct tevent_context *ev, 158 147 struct smbd_smb2_request *smb2req, 159 uint8_t in_oplock_level,160 uint 64_t in_file_id_volatile)148 struct files_struct *fsp, 149 uint8_t in_oplock_level) 161 150 { 162 151 struct tevent_req *req; 163 152 struct smbd_smb2_oplock_break_state *state; 164 153 struct smb_request *smbreq; 165 connection_struct *conn = smb2req->tcon->compat_conn;166 files_struct *fsp = NULL;167 154 int oplocklevel = map_smb2_oplock_levels_to_samba(in_oplock_level); 168 155 bool break_to_none = (oplocklevel == NO_OPLOCK); … … 177 164 state->out_oplock_level = SMB2_OPLOCK_LEVEL_NONE; 178 165 179 DEBUG(10,("smbd_smb2_oplock_break_send: file_id[0x%016llX] "180 "samba level %d\n",181 (unsigned long long)in_file_id_volatile,182 oplocklevel));166 DEBUG(10,("smbd_smb2_oplock_break_send: %s - fnum[%d] " 167 "samba level %d\n", 168 fsp_str_dbg(fsp), fsp->fnum, 169 oplocklevel)); 183 170 184 171 smbreq = smbd_smb2_fake_smb_request(smb2req); 185 172 if (tevent_req_nomem(smbreq, req)) { 186 return tevent_req_post(req, ev);187 }188 189 fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);190 if (fsp == NULL) {191 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);192 return tevent_req_post(req, ev);193 }194 if (conn != fsp->conn) {195 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);196 return tevent_req_post(req, ev);197 }198 if (smb2req->session->vuid != fsp->vuid) {199 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);200 173 return tevent_req_post(req, ev); 201 174 } … … 265 238 SMB2_OPLOCK_LEVEL_NONE; 266 239 NTSTATUS status; 240 uint64_t fsp_persistent = fsp_persistent_id(fsp); 267 241 268 242 DEBUG(10,("send_break_message_smb2: sending oplock break " … … 273 247 274 248 status = smbd_smb2_send_oplock_break(fsp->conn->sconn, 275 (uint64_t)fsp->fnum,249 fsp_persistent, 276 250 (uint64_t)fsp->fnum, 277 251 smb2_oplock_level); -
vendor/current/source3/smbd/smb2_close.c
r740 r746 25 25 26 26 static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, 27 struct files_struct *fsp, 27 28 uint16_t in_flags, 28 uint64_t in_file_id_volatile,29 29 DATA_BLOB *outbody); 30 30 31 31 NTSTATUS smbd_smb2_request_process_close(struct smbd_smb2_request *req) 32 32 { 33 const uint8_t *inhdr;34 33 const uint8_t *inbody; 35 34 int i = req->current_idx; 36 35 uint8_t *outhdr; 37 36 DATA_BLOB outbody; 38 size_t expected_body_size = 0x18;39 size_t body_size;40 37 uint16_t in_flags; 41 38 uint64_t in_file_id_persistent; 42 39 uint64_t in_file_id_volatile; 40 struct files_struct *in_fsp; 43 41 NTSTATUS status; 44 42 45 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;46 if ( req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {47 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);43 status = smbd_smb2_request_verify_sizes(req, 0x18); 44 if (!NT_STATUS_IS_OK(status)) { 45 return smbd_smb2_request_error(req, status); 48 46 } 49 50 47 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 51 52 body_size = SVAL(inbody, 0x00);53 if (body_size != expected_body_size) {54 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);55 }56 48 57 49 outbody = data_blob_talloc(req->out.vector, NULL, 0x3C); … … 64 56 in_file_id_volatile = BVAL(inbody, 0x10); 65 57 66 if (req->compat_chain_fsp) { 67 /* skip check */ 68 } else if (in_file_id_persistent != in_file_id_volatile) { 58 in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); 59 if (in_fsp == NULL) { 69 60 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 70 61 } 71 62 72 63 status = smbd_smb2_close(req, 64 in_fsp, 73 65 in_flags, 74 in_file_id_volatile,75 66 &outbody); 76 67 if (!NT_STATUS_IS_OK(status)) { … … 83 74 84 75 static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, 76 struct files_struct *fsp, 85 77 uint16_t in_flags, 86 uint64_t in_file_id_volatile,87 78 DATA_BLOB *outbody) 88 79 { … … 90 81 struct smb_request *smbreq; 91 82 connection_struct *conn = req->tcon->compat_conn; 92 files_struct *fsp;93 83 struct smb_filename *smb_fname = NULL; 94 84 struct timespec mdate_ts, adate_ts, cdate_ts, create_date_ts; … … 104 94 ZERO_STRUCT(cdate_ts); 105 95 106 DEBUG(10,("smbd_smb2_close: file_id[0x%016llX]\n",107 (unsigned long long)in_file_id_volatile));96 DEBUG(10,("smbd_smb2_close: %s - fnum[%d]\n", 97 fsp_str_dbg(fsp), fsp->fnum)); 108 98 109 99 smbreq = smbd_smb2_fake_smb_request(req); 110 100 if (smbreq == NULL) { 111 101 return NT_STATUS_NO_MEMORY; 112 }113 114 fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);115 if (fsp == NULL) {116 return NT_STATUS_FILE_CLOSED;117 }118 if (conn != fsp->conn) {119 return NT_STATUS_FILE_CLOSED;120 }121 if (req->session->vuid != fsp->vuid) {122 return NT_STATUS_FILE_CLOSED;123 102 } 124 103 -
vendor/current/source3/smbd/smb2_create.c
r740 r746 101 101 const uint8_t *inbody; 102 102 int i = smb2req->current_idx; 103 size_t expected_body_size = 0x39;104 size_t body_size;105 103 uint8_t in_oplock_level; 106 104 uint32_t in_impersonation_level; … … 128 126 struct tevent_req *tsubreq; 129 127 130 if (smb2req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {131 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);132 }133 128 status = smbd_smb2_request_verify_sizes(smb2req, 0x39); 129 if (!NT_STATUS_IS_OK(status)) { 130 return smbd_smb2_request_error(smb2req, status); 131 } 134 132 inbody = (const uint8_t *)smb2req->in.vector[i+1].iov_base; 135 136 body_size = SVAL(inbody, 0x00);137 if (body_size != expected_body_size) {138 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);139 }140 133 141 134 in_oplock_level = CVAL(inbody, 0x03); … … 159 152 */ 160 153 161 dyn_offset = SMB2_HDR_BODY + (body_size & 0xFFFFFFFE);154 dyn_offset = SMB2_HDR_BODY + smb2req->in.vector[i+1].iov_len; 162 155 163 156 if (in_name_offset == 0 && in_name_length == 0) { … … 218 211 if (!ok) { 219 212 return smbd_smb2_request_error(smb2req, NT_STATUS_ILLEGAL_CHARACTER); 213 } 214 215 if (in_name_buffer.length == 0) { 216 in_name_string_size = 0; 217 } 218 219 if (strlen(in_name_string) != in_name_string_size) { 220 return smbd_smb2_request_error(smb2req, NT_STATUS_OBJECT_NAME_INVALID); 220 221 } 221 222 … … 386 387 struct smbd_smb2_request *smb2req; 387 388 struct smb_request *smb1req; 389 bool open_was_deferred; 388 390 struct timed_event *te; 389 391 struct tevent_immediate *im; … … 538 540 if (exta) { 539 541 if (dhnc) { 540 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);542 tevent_req_nterror(req,NT_STATUS_OBJECT_NAME_NOT_FOUND); 541 543 return tevent_req_post(req, ev); 542 544 } … … 553 555 if (mxac) { 554 556 if (dhnc) { 555 tevent_req_nterror(req, NT_STATUS_ INVALID_PARAMETER);557 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); 556 558 return tevent_req_post(req, ev); 557 559 } … … 571 573 572 574 if (dhnc) { 573 tevent_req_nterror(req, NT_STATUS_ INVALID_PARAMETER);575 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); 574 576 return tevent_req_post(req, ev); 575 577 } … … 593 595 if (dhnq) { 594 596 if (dhnc) { 595 tevent_req_nterror(req, NT_STATUS_ INVALID_PARAMETER);597 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); 596 598 return tevent_req_post(req, ev); 597 599 } … … 619 621 if (alsi) { 620 622 if (dhnc) { 621 tevent_req_nterror(req, NT_STATUS_ INVALID_PARAMETER);623 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); 622 624 return tevent_req_post(req, ev); 623 625 } … … 636 638 637 639 if (dhnc) { 638 tevent_req_nterror(req, NT_STATUS_ INVALID_PARAMETER);640 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); 639 641 return tevent_req_post(req, ev); 640 642 } … … 821 823 result->fsp_name)); 822 824 state->out_allocation_size = 823 result->fsp_name->st.st_ex_blksize *824 result->fsp_name->st.st_ex_blocks;825 SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result, 826 &(result->fsp_name->st)); 825 827 state->out_end_of_file = result->fsp_name->st.st_ex_size; 826 828 if (state->out_file_attributes == 0) { 827 829 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL; 828 830 } 829 state->out_file_id_persistent = result->fnum;831 state->out_file_id_persistent = fsp_persistent_id(result); 830 832 state->out_file_id_volatile = result->fnum; 831 833 state->out_context_blobs = out_context_blobs; … … 964 966 } 965 967 /* It's not in progress if there's no timeout event. */ 966 if (!state-> te) {968 if (!state->open_was_deferred) { 967 969 return false; 968 970 } … … 995 997 (unsigned long long)mid )); 996 998 999 state->open_was_deferred = false; 997 1000 /* Ensure we don't have any outstanding timer event. */ 998 1001 TALLOC_FREE(state->te); … … 1238 1241 true) )); 1239 1242 1243 state->open_was_deferred = true; 1240 1244 state->te = event_add_timed(smb2req->sconn->smb2.event_ctx, 1241 1245 state, -
vendor/current/source3/smbd/smb2_find.c
r740 r746 29 29 struct tevent_context *ev, 30 30 struct smbd_smb2_request *smb2req, 31 struct files_struct *in_fsp, 31 32 uint8_t in_file_info_class, 32 33 uint8_t in_flags, 33 34 uint32_t in_file_index, 34 uint64_t in_file_id_volatile,35 35 uint32_t in_output_buffer_length, 36 36 const char *in_file_name); … … 42 42 NTSTATUS smbd_smb2_request_process_find(struct smbd_smb2_request *req) 43 43 { 44 const uint8_t *inhdr;44 NTSTATUS status; 45 45 const uint8_t *inbody; 46 46 int i = req->current_idx; 47 size_t expected_body_size = 0x21;48 size_t body_size;49 47 uint8_t in_file_info_class; 50 48 uint8_t in_flags; … … 52 50 uint64_t in_file_id_persistent; 53 51 uint64_t in_file_id_volatile; 52 struct files_struct *in_fsp; 54 53 uint16_t in_file_name_offset; 55 54 uint16_t in_file_name_length; … … 61 60 bool ok; 62 61 63 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 64 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 65 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 66 } 67 62 status = smbd_smb2_request_verify_sizes(req, 0x21); 63 if (!NT_STATUS_IS_OK(status)) { 64 return smbd_smb2_request_error(req, status); 65 } 68 66 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 69 70 body_size = SVAL(inbody, 0x00);71 if (body_size != expected_body_size) {72 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);73 }74 67 75 68 in_file_info_class = CVAL(inbody, 0x02); … … 85 78 /* This is ok */ 86 79 } else if (in_file_name_offset != 87 (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {80 (SMB2_HDR_BODY + req->in.vector[i+1].iov_len)) { 88 81 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 89 82 } … … 116 109 } 117 110 118 if (req->compat_chain_fsp) { 119 /* skip check */ 120 } else if (in_file_id_persistent != in_file_id_volatile) { 111 if (in_file_name_buffer.length == 0) { 112 in_file_name_string_size = 0; 113 } 114 115 if (strlen(in_file_name_string) != in_file_name_string_size) { 116 return smbd_smb2_request_error(req, NT_STATUS_OBJECT_NAME_INVALID); 117 } 118 119 in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); 120 if (in_fsp == NULL) { 121 121 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 122 122 } 123 123 124 subreq = smbd_smb2_find_send(req, 125 req->sconn->smb2.event_ctx, 126 req, 124 subreq = smbd_smb2_find_send(req, req->sconn->smb2.event_ctx, 125 req, in_fsp, 127 126 in_file_info_class, 128 127 in_flags, 129 128 in_file_index, 130 in_file_id_volatile,131 129 in_output_buffer_length, 132 130 in_file_name_string); … … 208 206 struct tevent_context *ev, 209 207 struct smbd_smb2_request *smb2req, 208 struct files_struct *fsp, 210 209 uint8_t in_file_info_class, 211 210 uint8_t in_flags, 212 211 uint32_t in_file_index, 213 uint64_t in_file_id_volatile,214 212 uint32_t in_output_buffer_length, 215 213 const char *in_file_name) … … 219 217 struct smb_request *smbreq; 220 218 connection_struct *conn = smb2req->tcon->compat_conn; 221 files_struct *fsp;222 219 NTSTATUS status; 223 220 NTSTATUS empty_status; … … 242 239 state->out_output_buffer = data_blob_null; 243 240 244 DEBUG(10,("smbd_smb2_find_send: file_id[0x%016llX]\n",245 (unsigned long long)in_file_id_volatile));241 DEBUG(10,("smbd_smb2_find_send: %s - fnum[%d]\n", 242 fsp_str_dbg(fsp), fsp->fnum)); 246 243 247 244 smbreq = smbd_smb2_fake_smb_request(smb2req); … … 250 247 } 251 248 252 fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);253 if (fsp == NULL) {254 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);255 return tevent_req_post(req, ev);256 }257 if (conn != fsp->conn) {258 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);259 return tevent_req_post(req, ev);260 }261 if (smb2req->session->vuid != fsp->vuid) {262 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);263 return tevent_req_post(req, ev);264 }265 266 249 if (!fsp->is_directory) { 267 250 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); … … 282 265 } 283 266 284 if (in_output_buffer_length > 0x10000) {267 if (in_output_buffer_length > smb2req->sconn->smb2.max_trans) { 285 268 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 286 269 return tevent_req_post(req, ev); -
vendor/current/source3/smbd/smb2_flush.c
r740 r746 28 28 struct tevent_context *ev, 29 29 struct smbd_smb2_request *smb2req, 30 uint64_t in_file_id_volatile);30 struct files_struct *fsp); 31 31 static NTSTATUS smbd_smb2_flush_recv(struct tevent_req *req); 32 32 … … 34 34 NTSTATUS smbd_smb2_request_process_flush(struct smbd_smb2_request *req) 35 35 { 36 const uint8_t *inhdr;36 NTSTATUS status; 37 37 const uint8_t *inbody; 38 38 int i = req->current_idx; 39 size_t expected_body_size = 0x18;40 size_t body_size;41 39 uint64_t in_file_id_persistent; 42 40 uint64_t in_file_id_volatile; 41 struct files_struct *in_fsp; 43 42 struct tevent_req *subreq; 44 43 45 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;46 if ( req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {47 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);44 status = smbd_smb2_request_verify_sizes(req, 0x18); 45 if (!NT_STATUS_IS_OK(status)) { 46 return smbd_smb2_request_error(req, status); 48 47 } 49 50 48 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 51 52 body_size = SVAL(inbody, 0x00);53 if (body_size != expected_body_size) {54 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);55 }56 49 57 50 in_file_id_persistent = BVAL(inbody, 0x08); 58 51 in_file_id_volatile = BVAL(inbody, 0x10); 59 52 60 if (req->compat_chain_fsp) { 61 /* skip check */ 62 } else if (in_file_id_persistent != in_file_id_volatile) { 53 in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); 54 if (in_fsp == NULL) { 63 55 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 64 56 } 65 57 66 subreq = smbd_smb2_flush_send(req, 67 req->sconn->smb2.event_ctx, 68 req, 69 in_file_id_volatile); 58 subreq = smbd_smb2_flush_send(req, req->sconn->smb2.event_ctx, 59 req, in_fsp); 70 60 if (subreq == NULL) { 71 61 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); … … 96 86 } 97 87 98 outbody = data_blob_talloc(req->out.vector, NULL, 0x 10);88 outbody = data_blob_talloc(req->out.vector, NULL, 0x04); 99 89 if (outbody.data == NULL) { 100 90 error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); … … 125 115 struct tevent_context *ev, 126 116 struct smbd_smb2_request *smb2req, 127 uint64_t in_file_id_volatile)117 struct files_struct *fsp) 128 118 { 129 119 struct tevent_req *req; … … 131 121 NTSTATUS status; 132 122 struct smb_request *smbreq; 133 files_struct *fsp;134 123 135 124 req = tevent_req_create(mem_ctx, &state, … … 140 129 state->smb2req = smb2req; 141 130 142 DEBUG(10,("smbd_smb2_flush: file_id[0x%016llX]\n",143 (unsigned long long)in_file_id_volatile));131 DEBUG(10,("smbd_smb2_flush: %s - fnum[%d]\n", 132 fsp_str_dbg(fsp), fsp->fnum)); 144 133 145 134 smbreq = smbd_smb2_fake_smb_request(smb2req); … … 150 139 if (IS_IPC(smbreq->conn)) { 151 140 tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); 152 return tevent_req_post(req, ev);153 }154 155 fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);156 if (fsp == NULL) {157 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);158 return tevent_req_post(req, ev);159 }160 if (smbreq->conn != fsp->conn) {161 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);162 return tevent_req_post(req, ev);163 }164 if (smb2req->session->vuid != fsp->vuid) {165 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);166 141 return tevent_req_post(req, ev); 167 142 } -
vendor/current/source3/smbd/smb2_getinfo.c
r740 r746 30 30 struct tevent_context *ev, 31 31 struct smbd_smb2_request *smb2req, 32 struct files_struct *in_fsp, 32 33 uint8_t in_info_type, 33 34 uint8_t in_file_info_class, … … 35 36 DATA_BLOB in_input_buffer, 36 37 uint32_t in_additional_information, 37 uint32_t in_flags, 38 uint64_t in_file_id_volatile); 38 uint32_t in_flags); 39 39 static NTSTATUS smbd_smb2_getinfo_recv(struct tevent_req *req, 40 40 TALLOC_CTX *mem_ctx, … … 45 45 NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req) 46 46 { 47 const uint8_t *inhdr;47 NTSTATUS status; 48 48 const uint8_t *inbody; 49 49 int i = req->current_idx; 50 size_t expected_body_size = 0x29;51 size_t body_size;52 50 uint8_t in_info_type; 53 51 uint8_t in_file_info_class; … … 60 58 uint64_t in_file_id_persistent; 61 59 uint64_t in_file_id_volatile; 60 struct files_struct *in_fsp; 62 61 struct tevent_req *subreq; 63 62 64 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 65 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 66 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 67 } 68 63 status = smbd_smb2_request_verify_sizes(req, 0x29); 64 if (!NT_STATUS_IS_OK(status)) { 65 return smbd_smb2_request_error(req, status); 66 } 69 67 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 70 71 body_size = SVAL(inbody, 0x00);72 if (body_size != expected_body_size) {73 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);74 }75 68 76 69 in_info_type = CVAL(inbody, 0x02); … … 88 81 /* This is ok */ 89 82 } else if (in_input_buffer_offset != 90 (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {83 (SMB2_HDR_BODY + req->in.vector[i+1].iov_len)) { 91 84 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 92 85 } … … 99 92 in_input_buffer.length = in_input_buffer_length; 100 93 101 if (req->compat_chain_fsp) { 102 /* skip check */ 103 } else if (in_file_id_persistent != in_file_id_volatile) { 94 if (in_input_buffer.length > req->sconn->smb2.max_trans) { 95 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 96 } 97 if (in_output_buffer_length > req->sconn->smb2.max_trans) { 98 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 99 } 100 101 in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); 102 if (in_fsp == NULL) { 104 103 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 105 104 } 106 105 107 subreq = smbd_smb2_getinfo_send(req, 108 req->sconn->smb2.event_ctx, 109 req, 106 subreq = smbd_smb2_getinfo_send(req, req->sconn->smb2.event_ctx, 107 req, in_fsp, 110 108 in_info_type, 111 109 in_file_info_class, … … 113 111 in_input_buffer, 114 112 in_additional_information, 115 in_flags, 116 in_file_id_volatile); 113 in_flags); 117 114 if (subreq == NULL) { 118 115 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); … … 236 233 struct tevent_context *ev, 237 234 struct smbd_smb2_request *smb2req, 235 struct files_struct *fsp, 238 236 uint8_t in_info_type, 239 237 uint8_t in_file_info_class, … … 241 239 DATA_BLOB in_input_buffer, 242 240 uint32_t in_additional_information, 243 uint32_t in_flags, 244 uint64_t in_file_id_volatile) 241 uint32_t in_flags) 245 242 { 246 243 struct tevent_req *req; … … 248 245 struct smb_request *smbreq; 249 246 connection_struct *conn = smb2req->tcon->compat_conn; 250 files_struct *fsp;251 247 NTSTATUS status; 252 248 … … 260 256 state->out_output_buffer = data_blob_null; 261 257 262 DEBUG(10,("smbd_smb2_getinfo_send: file_id[0x%016llX]\n",263 (unsigned long long)in_file_id_volatile));258 DEBUG(10,("smbd_smb2_getinfo_send: %s - fnum[%d]\n", 259 fsp_str_dbg(fsp), fsp->fnum)); 264 260 265 261 smbreq = smbd_smb2_fake_smb_request(smb2req); 266 262 if (tevent_req_nomem(smbreq, req)) { 267 return tevent_req_post(req, ev);268 }269 270 fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);271 if (fsp == NULL) {272 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);273 return tevent_req_post(req, ev);274 }275 if (conn != fsp->conn) {276 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);277 return tevent_req_post(req, ev);278 }279 if (smb2req->session->vuid != fsp->vuid) {280 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);281 263 return tevent_req_post(req, ev); 282 264 } -
vendor/current/source3/smbd/smb2_ioctl.c
r740 r746 30 30 struct tevent_context *ev, 31 31 struct smbd_smb2_request *smb2req, 32 struct files_struct *in_fsp, 32 33 uint32_t in_ctl_code, 33 uint64_t in_file_id_volatile,34 34 DATA_BLOB in_input, 35 35 uint32_t in_max_output, … … 42 42 NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req) 43 43 { 44 const uint8_t *inhdr;44 NTSTATUS status; 45 45 const uint8_t *inbody; 46 46 int i = req->current_idx; 47 size_t expected_body_size = 0x39;48 size_t body_size;49 47 uint32_t in_ctl_code; 50 48 uint64_t in_file_id_persistent; 51 49 uint64_t in_file_id_volatile; 50 struct files_struct *in_fsp = NULL; 52 51 uint32_t in_input_offset; 53 52 uint32_t in_input_length; … … 57 56 struct tevent_req *subreq; 58 57 59 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 60 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 61 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 62 } 63 58 status = smbd_smb2_request_verify_sizes(req, 0x39); 59 if (!NT_STATUS_IS_OK(status)) { 60 return smbd_smb2_request_error(req, status); 61 } 64 62 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 65 66 body_size = SVAL(inbody, 0x00);67 if (body_size != expected_body_size) {68 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);69 }70 63 71 64 in_ctl_code = IVAL(inbody, 0x04); … … 77 70 in_flags = IVAL(inbody, 0x30); 78 71 79 if (in_input_offset != (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) { 72 /* 73 * InputOffset (4 bytes): The offset, in bytes, from the beginning of 74 * the SMB2 header to the input data buffer. If no input data is 75 * required for the FSCTL/IOCTL command being issued, the client SHOULD 76 * set this value to 0.<49> 77 * <49> If no input data is required for the FSCTL/IOCTL command being 78 * issued, Windows-based clients set this field to any value. 79 */ 80 if ((in_input_length > 0) 81 && (in_input_offset != (SMB2_HDR_BODY + req->in.vector[i+1].iov_len))) { 80 82 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 81 83 } … … 88 90 in_input_buffer.length = in_input_length; 89 91 90 if (req->compat_chain_fsp) { 91 /* skip check */ 92 } else if (in_file_id_persistent == UINT64_MAX && 93 in_file_id_volatile == UINT64_MAX) { 94 /* without a handle */ 95 } else if (in_file_id_persistent != in_file_id_volatile) { 96 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 92 switch (in_ctl_code) { 93 case FSCTL_DFS_GET_REFERRALS: 94 case FSCTL_DFS_GET_REFERRALS_EX: 95 case FSCTL_PIPE_WAIT: 96 case FSCTL_VALIDATE_NEGOTIATE_INFO_224: 97 case FSCTL_VALIDATE_NEGOTIATE_INFO: 98 case FSCTL_QUERY_NETWORK_INTERFACE_INFO: 99 /* 100 * Some SMB2 specific CtlCodes like FSCTL_DFS_GET_REFERRALS or 101 * FSCTL_PIPE_WAIT does not take a file handle. 102 * 103 * If FileId in the SMB2 Header of the request is not 104 * 0xFFFFFFFFFFFFFFFF, then the server MUST fail the request 105 * with STATUS_INVALID_PARAMETER. 106 */ 107 if (in_file_id_persistent != UINT64_MAX || 108 in_file_id_volatile != UINT64_MAX) { 109 return smbd_smb2_request_error(req, 110 NT_STATUS_INVALID_PARAMETER); 111 } 112 break; 113 default: 114 in_fsp = file_fsp_smb2(req, in_file_id_persistent, 115 in_file_id_volatile); 116 if (in_fsp == NULL) { 117 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 118 } 119 break; 97 120 } 98 121 99 122 subreq = smbd_smb2_ioctl_send(req, 100 123 req->sconn->smb2.event_ctx, 101 req, 124 req, in_fsp, 102 125 in_ctl_code, 103 in_file_id_volatile,104 126 in_input_buffer, 105 127 in_max_output_length, … … 222 244 struct tevent_context *ev, 223 245 struct smbd_smb2_request *smb2req, 246 struct files_struct *fsp, 224 247 uint32_t in_ctl_code, 225 uint64_t in_file_id_volatile,226 248 DATA_BLOB in_input, 227 249 uint32_t in_max_output, … … 231 253 struct smbd_smb2_ioctl_state *state; 232 254 struct smb_request *smbreq; 233 files_struct *fsp = NULL;234 255 struct tevent_req *subreq; 235 256 … … 241 262 state->smb2req = smb2req; 242 263 state->smbreq = NULL; 243 state->fsp = NULL;264 state->fsp = fsp; 244 265 state->in_input = in_input; 245 266 state->in_max_output = in_max_output; 246 267 state->out_output = data_blob_null; 247 268 248 DEBUG(10,("smbd_smb2_ioctl: file_id[0x%016llX]\n", 249 (unsigned long long)in_file_id_volatile)); 269 DEBUG(10, ("smbd_smb2_ioctl: ctl_code[0x%08x] %s fnum[%d]\n", 270 (unsigned)in_ctl_code, 271 fsp ? fsp_str_dbg(fsp) : "<no handle>", 272 fsp ? fsp->fnum : -1)); 250 273 251 274 smbreq = smbd_smb2_fake_smb_request(smb2req); … … 254 277 } 255 278 state->smbreq = smbreq; 256 257 if (in_file_id_volatile != UINT64_MAX) {258 fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);259 if (fsp == NULL) {260 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);261 return tevent_req_post(req, ev);262 }263 if (smbreq->conn != fsp->conn) {264 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);265 return tevent_req_post(req, ev);266 }267 if (smb2req->session->vuid != fsp->vuid) {268 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);269 return tevent_req_post(req, ev);270 }271 state->fsp = fsp;272 }273 279 274 280 switch (in_ctl_code) { … … 379 385 return req; 380 386 381 case 0x00144064: /* FSCTL_SRV_ENUMERATE_SNAPSHOTS */ 382 { 383 /* 384 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots) 385 * and return their volume names. If max_data_count is 16, then it is just 386 * asking for the number of volumes and length of the combined names. 387 * 388 * pdata is the data allocated by our caller, but that uses 389 * total_data_count (which is 0 in our case) rather than max_data_count. 390 * Allocate the correct amount and return the pointer to let 391 * it be deallocated when we return. 392 */ 393 struct shadow_copy_data *shadow_data = NULL; 394 bool labels = False; 395 uint32_t labels_data_count = 0; 396 uint32_t data_count; 397 uint32_t i; 398 char *pdata; 387 default: { 388 uint8_t *out_data = NULL; 389 uint32_t out_data_len = 0; 399 390 NTSTATUS status; 400 391 … … 404 395 } 405 396 406 if (in_max_output < 16) { 407 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: " 408 "in_max_output(%u) < 16 is invalid!\n", 409 in_max_output)); 410 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 411 return tevent_req_post(req, ev); 412 } 413 414 if (in_max_output > 16) { 415 labels = True; 416 } 417 418 shadow_data = TALLOC_ZERO_P(talloc_tos(), 419 struct shadow_copy_data); 420 if (tevent_req_nomem(shadow_data, req)) { 421 DEBUG(0,("TALLOC_ZERO() failed!\n")); 422 return tevent_req_post(req, ev); 423 } 424 425 /* 426 * Call the VFS routine to actually do the work. 427 */ 428 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels) 429 != 0) { 430 if (errno == ENOSYS) { 431 DEBUG(5, ("FSCTL_GET_SHADOW_COPY_DATA: " 432 "connectpath %s, not supported.\n", 433 smbreq->conn->connectpath)); 434 status = NT_STATUS_NOT_SUPPORTED; 397 status = smb_fsctl(fsp, 398 state, 399 in_ctl_code, 400 smbreq->flags2, 401 in_input.data, 402 in_input.length, 403 &out_data, 404 in_max_output, 405 &out_data_len); 406 state->out_output = data_blob_const(out_data, out_data_len); 407 if (NT_STATUS_IS_OK(status)) { 408 tevent_req_done(req); 409 return tevent_req_post(req, ev); 410 } 411 412 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { 413 if (IS_IPC(smbreq->conn)) { 414 status = NT_STATUS_FS_DRIVER_REQUIRED; 435 415 } else { 436 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: " 437 "connectpath %s, failed.\n", 438 smbreq->conn->connectpath)); 439 status = map_nt_error_from_unix(errno); 416 status = NT_STATUS_INVALID_DEVICE_REQUEST; 440 417 } 441 TALLOC_FREE(shadow_data); 442 tevent_req_nterror(req, status); 443 return tevent_req_post(req, ev); 444 } 445 446 labels_data_count = 447 (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL)) 448 + 2; 449 450 if (labels) { 451 data_count = 12+labels_data_count+4; 452 } else { 453 data_count = 16; 454 } 455 456 if (labels && (in_max_output < data_count)) { 457 DEBUG(0, ("FSCTL_GET_SHADOW_COPY_DATA: " 458 "in_max_output(%u) too small (%u) bytes " 459 "needed!\n", in_max_output, data_count)); 460 TALLOC_FREE(shadow_data); 461 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); 462 return tevent_req_post(req, ev); 463 } 464 465 state->out_output = data_blob_talloc(state, NULL, data_count); 466 if (tevent_req_nomem(state->out_output.data, req)) { 467 return tevent_req_post(req, ev); 468 } 469 470 pdata = (char *)state->out_output.data; 471 472 /* num_volumes 4 bytes */ 473 SIVAL(pdata, 0, shadow_data->num_volumes); 474 475 if (labels) { 476 /* num_labels 4 bytes */ 477 SIVAL(pdata, 4, shadow_data->num_volumes); 478 } 479 480 /* needed_data_count 4 bytes */ 481 SIVAL(pdata, 8, labels_data_count+4); 482 483 pdata += 12; 484 485 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for " 486 "path[%s].\n", 487 shadow_data->num_volumes, fsp_str_dbg(fsp))); 488 if (labels && shadow_data->labels) { 489 for (i=0; i<shadow_data->num_volumes; i++) { 490 srvstr_push(pdata, smbreq->flags2, 491 pdata, shadow_data->labels[i], 492 2*sizeof(SHADOW_COPY_LABEL), 493 STR_UNICODE|STR_TERMINATE); 494 pdata += 2*sizeof(SHADOW_COPY_LABEL); 495 DEBUGADD(10, ("Label[%u]: '%s'\n", i, 496 shadow_data->labels[i])); 497 } 498 } 499 500 TALLOC_FREE(shadow_data); 501 502 tevent_req_done(req); 418 } 419 420 tevent_req_nterror(req, status); 503 421 return tevent_req_post(req, ev); 504 } 505 506 default: 507 if (IS_IPC(smbreq->conn)) { 508 tevent_req_nterror(req, NT_STATUS_FS_DRIVER_REQUIRED); 509 return tevent_req_post(req, ev); 510 } 511 tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST); 512 return tevent_req_post(req, ev); 422 } 513 423 } 514 424 -
vendor/current/source3/smbd/smb2_keepalive.c
r740 r746 26 26 NTSTATUS smbd_smb2_request_process_keepalive(struct smbd_smb2_request *req) 27 27 { 28 const uint8_t *inbody;29 int i = req->current_idx;30 28 DATA_BLOB outbody; 31 size_t expected_body_size = 0x04; 32 size_t body_size; 29 NTSTATUS status; 33 30 34 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 35 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 36 } 37 38 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 39 40 body_size = SVAL(inbody, 0x00); 41 if (body_size != expected_body_size) { 42 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 31 status = smbd_smb2_request_verify_sizes(req, 0x04); 32 if (!NT_STATUS_IS_OK(status)) { 33 return smbd_smb2_request_error(req, status); 43 34 } 44 35 -
vendor/current/source3/smbd/smb2_lock.c
r740 r746 47 47 struct tevent_context *ev, 48 48 struct smbd_smb2_request *smb2req, 49 struct files_struct *in_fsp, 49 50 uint32_t in_smbpid, 50 uint64_t in_file_id_volatile,51 51 uint16_t in_lock_count, 52 52 struct smbd_smb2_lock_element *in_locks); … … 59 59 const uint8_t *inbody; 60 60 const int i = req->current_idx; 61 size_t expected_body_size = 0x30;62 size_t body_size;63 61 uint32_t in_smbpid; 64 62 uint16_t in_lock_count; 65 63 uint64_t in_file_id_persistent; 66 64 uint64_t in_file_id_volatile; 65 struct files_struct *in_fsp; 67 66 struct smbd_smb2_lock_element *in_locks; 68 67 struct tevent_req *subreq; 69 68 const uint8_t *lock_buffer; 70 69 uint16_t l; 71 70 NTSTATUS status; 71 72 status = smbd_smb2_request_verify_sizes(req, 0x30); 73 if (!NT_STATUS_IS_OK(status)) { 74 return smbd_smb2_request_error(req, status); 75 } 72 76 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 73 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {74 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);75 }76 77 77 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 78 79 body_size = SVAL(inbody, 0x00);80 if (body_size != expected_body_size) {81 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);82 }83 78 84 79 in_smbpid = IVAL(inhdr, SMB2_HDR_PID); … … 95 90 if (((in_lock_count - 1) * 0x18) > req->in.vector[i+2].iov_len) { 96 91 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 97 }98 99 if (req->compat_chain_fsp) {100 /* skip check */101 } else if (in_file_id_persistent != in_file_id_volatile) {102 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);103 92 } 104 93 … … 128 117 } 129 118 130 subreq = smbd_smb2_lock_send(req, 131 req->sconn->smb2.event_ctx, 132 req, 119 in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); 120 if (in_fsp == NULL) { 121 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 122 } 123 124 subreq = smbd_smb2_lock_send(req, req->sconn->smb2.event_ctx, 125 req, in_fsp, 133 126 in_smbpid, 134 in_file_id_volatile,135 127 in_lock_count, 136 128 in_locks); … … 214 206 struct tevent_context *ev, 215 207 struct smbd_smb2_request *smb2req, 208 struct files_struct *fsp, 216 209 uint32_t in_smbpid, 217 uint64_t in_file_id_volatile,218 210 uint16_t in_lock_count, 219 211 struct smbd_smb2_lock_element *in_locks) … … 222 214 struct smbd_smb2_lock_state *state; 223 215 struct smb_request *smb1req; 224 connection_struct *conn = smb2req->tcon->compat_conn;225 files_struct *fsp;226 216 int32_t timeout = -1; 227 217 bool isunlock = false; … … 245 235 state->smb1req = smb1req; 246 236 247 DEBUG(10,("smbd_smb2_lock_send: file_id[0x%016llX]\n", 248 (unsigned long long)in_file_id_volatile)); 249 250 fsp = file_fsp(smb1req, (uint16_t)in_file_id_volatile); 251 if (fsp == NULL) { 252 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED); 253 return tevent_req_post(req, ev); 254 } 255 if (conn != fsp->conn) { 256 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED); 257 return tevent_req_post(req, ev); 258 } 259 if (smb2req->session->vuid != fsp->vuid) { 260 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED); 261 return tevent_req_post(req, ev); 262 } 237 DEBUG(10,("smbd_smb2_lock_send: %s - fnum[%d]\n", 238 fsp_str_dbg(fsp), fsp->fnum)); 263 239 264 240 locks = talloc_array(state, struct smbd_lock_element, in_lock_count); … … 342 318 } 343 319 344 locks[i].smblctx = in_file_id_volatile;320 locks[i].smblctx = fsp->fnum; 345 321 locks[i].offset = in_locks[i].offset; 346 322 locks[i].count = in_locks[i].length; … … 873 849 files_struct *fsp_curr = NULL; 874 850 int i = smb2req->current_idx; 875 uint64_t in_file_id_volatile;876 851 struct blocking_lock_record *blr = NULL; 877 852 const uint8_t *inhdr; 878 const uint8_t *inbody;879 853 880 854 nextreq = smb2req->next; … … 894 868 continue; 895 869 } 896 897 inbody = (const uint8_t *)smb2req->in.vector[i+1].iov_base;898 in_file_id_volatile = BVAL(inbody, 0x10);899 870 900 871 state = tevent_req_data(smb2req->subreq, … … 905 876 } 906 877 907 fsp_curr = file_fsp(state->smb1req, (uint16_t)in_file_id_volatile);878 fsp_curr = smb2req->compat_chain_fsp; 908 879 if (fsp_curr == NULL) { 909 880 /* Strange - is this even possible ? */ -
vendor/current/source3/smbd/smb2_negprot.c
r740 r746 62 62 NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) 63 63 { 64 NTSTATUS status; 64 65 const uint8_t *inbody; 65 66 const uint8_t *indyn = NULL; … … 70 71 uint16_t security_offset; 71 72 DATA_BLOB security_buffer; 72 size_t expected_body_size = 0x24;73 size_t body_size;74 73 size_t expected_dyn_size = 0; 75 74 size_t c; … … 78 77 uint16_t dialect = 0; 79 78 uint32_t capabilities; 79 uint32_t max_limit; 80 uint32_t max_trans = lp_smb2_max_trans(); 81 uint32_t max_read = lp_smb2_max_read(); 82 uint32_t max_write = lp_smb2_max_write(); 80 83 81 /* TODO: drop the connection with INVALID_PARAMETER */ 82 83 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 84 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 84 status = smbd_smb2_request_verify_sizes(req, 0x24); 85 if (!NT_STATUS_IS_OK(status)) { 86 return smbd_smb2_request_error(req, status); 85 87 } 86 87 88 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 88 89 body_size = SVAL(inbody, 0x00);90 if (body_size != expected_body_size) {91 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);92 }93 89 94 90 dialect_count = SVAL(inbody, 0x02); … … 140 136 } 141 137 138 /* 139 * Unless we implement SMB2_CAP_LARGE_MTU, 140 * 0x10000 (65536) is the maximum allowed message size 141 */ 142 max_limit = 0x10000; 143 144 max_trans = MIN(max_limit, max_trans); 145 max_read = MIN(max_limit, max_read); 146 max_write = MIN(max_limit, max_write); 147 142 148 security_offset = SMB2_HDR_BODY + 0x40; 143 149 … … 165 171 SIVAL(outbody.data, 0x18, 166 172 capabilities); /* capabilities */ 167 SIVAL(outbody.data, 0x1C, lp_smb2_max_trans()); /* max transact size */168 SIVAL(outbody.data, 0x20, lp_smb2_max_read()); /* max read size */169 SIVAL(outbody.data, 0x24, lp_smb2_max_write()); /* max write size */173 SIVAL(outbody.data, 0x1C, max_trans); /* max transact size */ 174 SIVAL(outbody.data, 0x20, max_trans); /* max read size */ 175 SIVAL(outbody.data, 0x24, max_trans); /* max write size */ 170 176 SBVAL(outbody.data, 0x28, 0); /* system time */ 171 177 SBVAL(outbody.data, 0x30, 0); /* server start time */ … … 179 185 180 186 req->sconn->using_smb2 = true; 187 req->sconn->smb2.max_trans = max_trans; 188 req->sconn->smb2.max_read = max_read; 189 req->sconn->smb2.max_write = max_write; 181 190 182 191 return smbd_smb2_request_done(req, outbody, &outdyn); -
vendor/current/source3/smbd/smb2_notify.c
r740 r746 37 37 struct tevent_context *ev, 38 38 struct smbd_smb2_request *smb2req, 39 struct files_struct *in_fsp, 39 40 uint16_t in_flags, 40 41 uint32_t in_output_buffer_length, 41 uint64_t in_file_id_volatile,42 42 uint64_t in_completion_filter); 43 43 static NTSTATUS smbd_smb2_notify_recv(struct tevent_req *req, … … 48 48 NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req) 49 49 { 50 const uint8_t *inhdr;50 NTSTATUS status; 51 51 const uint8_t *inbody; 52 52 int i = req->current_idx; 53 size_t expected_body_size = 0x20;54 size_t body_size;55 53 uint16_t in_flags; 56 54 uint32_t in_output_buffer_length; 57 55 uint64_t in_file_id_persistent; 58 56 uint64_t in_file_id_volatile; 57 struct files_struct *in_fsp; 59 58 uint64_t in_completion_filter; 60 59 struct tevent_req *subreq; 61 60 62 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 63 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 64 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 65 } 66 61 status = smbd_smb2_request_verify_sizes(req, 0x20); 62 if (!NT_STATUS_IS_OK(status)) { 63 return smbd_smb2_request_error(req, status); 64 } 67 65 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 68 69 body_size = SVAL(inbody, 0x00);70 if (body_size != expected_body_size) {71 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);72 }73 66 74 67 in_flags = SVAL(inbody, 0x02); … … 82 75 * Windows 2008 uses 0x00080000 83 76 */ 84 if (in_output_buffer_length > lp_smb2_max_trans()) {77 if (in_output_buffer_length > req->sconn->smb2.max_trans) { 85 78 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 86 79 } 87 80 88 if (req->compat_chain_fsp) { 89 /* skip check */ 90 } else if (in_file_id_persistent != in_file_id_volatile) { 81 in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); 82 if (in_fsp == NULL) { 91 83 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 92 84 } 93 85 94 subreq = smbd_smb2_notify_send(req, 95 req->sconn->smb2.event_ctx, 96 req, 86 subreq = smbd_smb2_notify_send(req, req->sconn->smb2.event_ctx, 87 req, in_fsp, 97 88 in_flags, 98 89 in_output_buffer_length, 99 in_file_id_volatile,100 90 in_completion_filter); 101 91 if (subreq == NULL) { … … 194 184 struct tevent_context *ev, 195 185 struct smbd_smb2_request *smb2req, 186 struct files_struct *fsp, 196 187 uint16_t in_flags, 197 188 uint32_t in_output_buffer_length, 198 uint64_t in_file_id_volatile,199 189 uint64_t in_completion_filter) 200 190 { … … 203 193 struct smb_request *smbreq; 204 194 connection_struct *conn = smb2req->tcon->compat_conn; 205 files_struct *fsp;206 195 bool recursive = (in_flags & 0x0001) ? true : false; 207 196 NTSTATUS status; … … 217 206 state->im = NULL; 218 207 219 DEBUG(10,("smbd_smb2_notify_send: file_id[0x%016llX]\n",220 (unsigned long long)in_file_id_volatile));208 DEBUG(10,("smbd_smb2_notify_send: %s - fnum[%d]\n", 209 fsp_str_dbg(fsp), fsp->fnum)); 221 210 222 211 smbreq = smbd_smb2_fake_smb_request(smb2req); … … 227 216 state->smbreq = smbreq; 228 217 smbreq->async_priv = (void *)req; 229 230 fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);231 if (fsp == NULL) {232 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);233 return tevent_req_post(req, ev);234 }235 if (conn != fsp->conn) {236 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);237 return tevent_req_post(req, ev);238 }239 if (smb2req->session->vuid != fsp->vuid) {240 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);241 return tevent_req_post(req, ev);242 }243 218 244 219 { … … 383 358 struct smbd_smb2_notify_state); 384 359 360 state->smb2req->cancelled = true; 385 361 smbd_notify_cancel_by_smbreq(state->smbreq); 386 362 387 state->smb2req->cancelled = true;388 tevent_req_done(req);389 363 return true; 390 364 } -
vendor/current/source3/smbd/smb2_read.c
r740 r746 31 31 struct tevent_context *ev, 32 32 struct smbd_smb2_request *smb2req, 33 struct files_struct *in_fsp, 33 34 uint32_t in_smbpid, 34 uint64_t in_file_id_volatile,35 35 uint32_t in_length, 36 36 uint64_t in_offset, … … 45 45 NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req) 46 46 { 47 NTSTATUS status; 47 48 const uint8_t *inhdr; 48 49 const uint8_t *inbody; 49 50 int i = req->current_idx; 50 size_t expected_body_size = 0x31;51 size_t body_size;52 51 uint32_t in_smbpid; 53 52 uint32_t in_length; … … 55 54 uint64_t in_file_id_persistent; 56 55 uint64_t in_file_id_volatile; 56 struct files_struct *in_fsp; 57 57 uint32_t in_minimum_count; 58 58 uint32_t in_remaining_bytes; 59 59 struct tevent_req *subreq; 60 60 61 status = smbd_smb2_request_verify_sizes(req, 0x31); 62 if (!NT_STATUS_IS_OK(status)) { 63 return smbd_smb2_request_error(req, status); 64 } 61 65 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 62 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {63 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);64 }65 66 66 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 67 68 body_size = SVAL(inbody, 0x00);69 if (body_size != expected_body_size) {70 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);71 }72 67 73 68 in_smbpid = IVAL(inhdr, SMB2_HDR_PID); … … 81 76 82 77 /* check the max read size */ 83 if (in_length > lp_smb2_max_read()) {78 if (in_length > req->sconn->smb2.max_read) { 84 79 DEBUG(0,("here:%s: 0x%08X: 0x%08X\n", 85 __location__, in_length, lp_smb2_max_read()));80 __location__, in_length, req->sconn->smb2.max_read)); 86 81 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 87 82 } 88 83 89 if (req->compat_chain_fsp) { 90 /* skip check */ 91 } else if (in_file_id_persistent != in_file_id_volatile) { 84 in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); 85 if (in_fsp == NULL) { 92 86 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 93 87 } 94 88 95 subreq = smbd_smb2_read_send(req, 96 req->sconn->smb2.event_ctx, 97 req, 89 subreq = smbd_smb2_read_send(req, req->sconn->smb2.event_ctx, 90 req, in_fsp, 98 91 in_smbpid, 99 in_file_id_volatile,100 92 in_length, 101 93 in_offset, … … 177 169 struct smbd_smb2_request *smb2req; 178 170 files_struct *fsp; 179 uint64_t in_file_id_volatile;180 171 uint32_t in_length; 181 172 uint64_t in_offset; … … 259 250 260 251 init_strict_lock_struct(fsp, 261 state->in_file_id_volatile,252 fsp->fnum, 262 253 in_offset, 263 254 in_length, … … 374 365 struct tevent_context *ev, 375 366 struct smbd_smb2_request *smb2req, 367 struct files_struct *fsp, 376 368 uint32_t in_smbpid, 377 uint64_t in_file_id_volatile,378 369 uint32_t in_length, 379 370 uint64_t in_offset, … … 386 377 struct smb_request *smbreq = NULL; 387 378 connection_struct *conn = smb2req->tcon->compat_conn; 388 files_struct *fsp = NULL;389 379 ssize_t nread = -1; 390 380 struct lock_struct lock; … … 403 393 state->out_remaining = 0; 404 394 405 DEBUG(10,("smbd_smb2_read: file_id[0x%016llX]\n",406 (unsigned long long)in_file_id_volatile));395 DEBUG(10,("smbd_smb2_read: %s - fnum[%d]\n", 396 fsp_str_dbg(fsp), fsp->fnum)); 407 397 408 398 smbreq = smbd_smb2_fake_smb_request(smb2req); … … 411 401 } 412 402 413 fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);414 if (fsp == NULL) {415 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);416 return tevent_req_post(req, ev);417 }418 if (conn != fsp->conn) {419 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);420 return tevent_req_post(req, ev);421 }422 if (smb2req->session->vuid != fsp->vuid) {423 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);424 return tevent_req_post(req, ev);425 }426 403 if (fsp->is_directory) { 427 404 tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST); … … 430 407 431 408 state->fsp = fsp; 432 state->in_file_id_volatile = in_file_id_volatile;433 409 434 410 if (IS_IPC(smbreq->conn)) { … … 493 469 494 470 init_strict_lock_struct(fsp, 495 in_file_id_volatile,471 fsp->fnum, 496 472 in_offset, 497 473 in_length, … … 533 509 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); 534 510 535 DEBUG(10,("smbd_smb2_read: file %s handle [0x%016llX] offset=%llu "511 DEBUG(10,("smbd_smb2_read: file %s fnum[%d] offset=%llu " 536 512 "len=%llu returned %lld\n", 537 513 fsp_str_dbg(fsp), 538 (unsigned long long)in_file_id_volatile,514 fsp->fnum, 539 515 (unsigned long long)in_offset, 540 516 (unsigned long long)in_length, -
vendor/current/source3/smbd/smb2_server.c
r740 r746 115 115 sconn->smb2.sessions.list = NULL; 116 116 sconn->smb2.seqnum_low = 0; 117 sconn->smb2.credits_granted = 0; 117 sconn->smb2.seqnum_range = 1; 118 sconn->smb2.credits_granted = 1; 118 119 sconn->smb2.max_credits = lp_smb2_max_credits(); 119 120 sconn->smb2.credits_bitmap = bitmap_talloc(sconn, 120 DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR*sconn->smb2.max_credits);121 sconn->smb2.max_credits); 121 122 if (sconn->smb2.credits_bitmap == NULL) { 122 123 return NT_STATUS_NO_MEMORY; … … 207 208 req->parent = parent; 208 209 210 req->last_session_id = UINT64_MAX; 211 req->last_tid = UINT32_MAX; 212 209 213 talloc_set_destructor(parent, smbd_smb2_request_parent_destructor); 210 214 talloc_set_destructor(req, smbd_smb2_request_destructor); … … 296 300 } 297 301 302 static bool smb2_validate_sequence_number(struct smbd_server_connection *sconn, 303 uint64_t message_id, uint64_t seq_id) 304 { 305 struct bitmap *credits_bm = sconn->smb2.credits_bitmap; 306 unsigned int offset; 307 308 if (seq_id < sconn->smb2.seqnum_low) { 309 DEBUG(0,("smb2_validate_sequence_number: bad message_id " 310 "%llu (sequence id %llu) " 311 "(granted = %u, low = %llu, range = %u)\n", 312 (unsigned long long)message_id, 313 (unsigned long long)seq_id, 314 (unsigned int)sconn->smb2.credits_granted, 315 (unsigned long long)sconn->smb2.seqnum_low, 316 (unsigned int)sconn->smb2.seqnum_range)); 317 return false; 318 } 319 320 if (seq_id >= sconn->smb2.seqnum_low + sconn->smb2.seqnum_range) { 321 DEBUG(0,("smb2_validate_sequence_number: bad message_id " 322 "%llu (sequence id %llu) " 323 "(granted = %u, low = %llu, range = %u)\n", 324 (unsigned long long)message_id, 325 (unsigned long long)seq_id, 326 (unsigned int)sconn->smb2.credits_granted, 327 (unsigned long long)sconn->smb2.seqnum_low, 328 (unsigned int)sconn->smb2.seqnum_range)); 329 return false; 330 } 331 332 offset = seq_id % sconn->smb2.max_credits; 333 334 if (bitmap_query(credits_bm, offset)) { 335 DEBUG(0,("smb2_validate_sequence_number: duplicate message_id " 336 "%llu (sequence id %llu) " 337 "(granted = %u, low = %llu, range = %u) " 338 "(bm offset %u)\n", 339 (unsigned long long)message_id, 340 (unsigned long long)seq_id, 341 (unsigned int)sconn->smb2.credits_granted, 342 (unsigned long long)sconn->smb2.seqnum_low, 343 (unsigned int)sconn->smb2.seqnum_range, 344 offset)); 345 return false; 346 } 347 348 /* Mark the message_ids as seen in the bitmap. */ 349 bitmap_set(credits_bm, offset); 350 351 if (seq_id != sconn->smb2.seqnum_low) { 352 return true; 353 } 354 355 /* 356 * Move the window forward by all the message_id's 357 * already seen. 358 */ 359 while (bitmap_query(credits_bm, offset)) { 360 DEBUG(10,("smb2_validate_sequence_number: clearing " 361 "id %llu (position %u) from bitmap\n", 362 (unsigned long long)(sconn->smb2.seqnum_low), 363 offset)); 364 bitmap_clear(credits_bm, offset); 365 366 sconn->smb2.seqnum_low += 1; 367 sconn->smb2.seqnum_range -= 1; 368 offset = sconn->smb2.seqnum_low % sconn->smb2.max_credits; 369 } 370 371 return true; 372 } 373 298 374 static bool smb2_validate_message_id(struct smbd_server_connection *sconn, 299 375 const uint8_t *inhdr) 300 376 { 301 377 uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID); 302 struct bitmap *credits_bm = sconn->smb2.credits_bitmap;303 378 uint16_t opcode = IVAL(inhdr, SMB2_HDR_OPCODE); 304 unsigned int bitmap_offset;379 bool ok; 305 380 306 381 if (opcode == SMB2_OP_CANCEL) { … … 309 384 } 310 385 311 if (message_id < sconn->smb2.seqnum_low || 312 message_id > (sconn->smb2.seqnum_low + 313 (sconn->smb2.max_credits * DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR))) { 314 DEBUG(0,("smb2_validate_message_id: bad message_id " 315 "%llu (low = %llu, max = %lu)\n", 316 (unsigned long long)message_id, 317 (unsigned long long)sconn->smb2.seqnum_low, 318 (unsigned long)sconn->smb2.max_credits )); 386 DEBUG(11, ("smb2_validate_message_id: mid %llu, credits_granted %llu, " 387 "seqnum low/range: %llu/%llu\n", 388 (unsigned long long) message_id, 389 (unsigned long long) sconn->smb2.credits_granted, 390 (unsigned long long) sconn->smb2.seqnum_low, 391 (unsigned long long) sconn->smb2.seqnum_range)); 392 393 if (sconn->smb2.credits_granted < 1) { 394 DEBUG(0, ("smb2_validate_message_id: client used more " 395 "credits than granted, mid %llu, credits_granted %llu, " 396 "seqnum low/range: %llu/%llu\n", 397 (unsigned long long) message_id, 398 (unsigned long long) sconn->smb2.credits_granted, 399 (unsigned long long) sconn->smb2.seqnum_low, 400 (unsigned long long) sconn->smb2.seqnum_range)); 319 401 return false; 320 402 } 321 403 322 /* client just used a credit. */ 323 SMB_ASSERT(sconn->smb2.credits_granted > 0); 404 ok = smb2_validate_sequence_number(sconn, message_id, message_id); 405 if (!ok) { 406 return false; 407 } 408 409 /* substract used credits */ 324 410 sconn->smb2.credits_granted -= 1; 325 326 /* Mark the message_id as seen in the bitmap. */327 bitmap_offset = (unsigned int)(message_id %328 (uint64_t)(sconn->smb2.max_credits * DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR));329 if (bitmap_query(credits_bm, bitmap_offset)) {330 DEBUG(0,("smb2_validate_message_id: duplicate message_id "331 "%llu (bm offset %u)\n",332 (unsigned long long)message_id,333 bitmap_offset));334 return false;335 }336 bitmap_set(credits_bm, bitmap_offset);337 338 if (message_id == sconn->smb2.seqnum_low + 1) {339 /* Move the window forward by all the message_id's340 already seen. */341 while (bitmap_query(credits_bm, bitmap_offset)) {342 DEBUG(10,("smb2_validate_message_id: clearing "343 "id %llu (position %u) from bitmap\n",344 (unsigned long long)(sconn->smb2.seqnum_low + 1),345 bitmap_offset ));346 bitmap_clear(credits_bm, bitmap_offset);347 sconn->smb2.seqnum_low += 1;348 bitmap_offset = (bitmap_offset + 1) %349 (sconn->smb2.max_credits * DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR);350 }351 }352 411 353 412 return true; … … 358 417 int count; 359 418 int idx; 360 bool compound_related = false;361 419 362 420 count = req->in.vector_count; … … 369 427 for (idx=1; idx < count; idx += 3) { 370 428 const uint8_t *inhdr = NULL; 371 uint32_t flags;372 429 373 430 if (req->in.vector[idx].iov_len != SMB2_HDR_BODY) { … … 388 445 if (!smb2_validate_message_id(req->sconn, inhdr)) { 389 446 return NT_STATUS_INVALID_PARAMETER; 390 }391 392 flags = IVAL(inhdr, SMB2_HDR_FLAGS);393 if (idx == 1) {394 /*395 * the 1st request should never have the396 * SMB2_HDR_FLAG_CHAINED flag set397 */398 if (flags & SMB2_HDR_FLAG_CHAINED) {399 req->next_status = NT_STATUS_INVALID_PARAMETER;400 return NT_STATUS_OK;401 }402 } else if (idx == 4) {403 /*404 * the 2nd request triggers related vs. unrelated405 * compounded requests406 */407 if (flags & SMB2_HDR_FLAG_CHAINED) {408 compound_related = true;409 }410 } else if (idx > 4) {411 #if 0412 /*413 * It seems the this tests are wrong414 * see the SMB2-COMPOUND test415 */416 417 /*418 * all other requests should match the 2nd one419 */420 if (flags & SMB2_HDR_FLAG_CHAINED) {421 if (!compound_related) {422 req->next_status =423 NT_STATUS_INVALID_PARAMETER;424 return NT_STATUS_OK;425 }426 } else {427 if (compound_related) {428 req->next_status =429 NT_STATUS_INVALID_PARAMETER;430 return NT_STATUS_OK;431 }432 }433 #endif434 447 } 435 448 } … … 446 459 uint16_t credits_requested; 447 460 uint32_t out_flags; 461 uint16_t cmd; 462 NTSTATUS out_status; 448 463 uint16_t credits_granted = 0; 449 464 uint64_t credits_possible; 465 uint16_t current_max_credits; 466 467 /* 468 * first we grant only 1/16th of the max range. 469 * 470 * Windows also starts with the 1/16th and then grants 471 * more later. I was only able to trigger higher 472 * values, when using a verify high credit charge. 473 * 474 * TODO: scale up depending one load, free memory 475 * or other stuff. 476 * Maybe also on the relationship between number 477 * of requests and the used sequence number. 478 * Which means we would grant more credits 479 * for client which use multi credit requests. 480 */ 481 current_max_credits = sconn->smb2.max_credits / 16; 482 current_max_credits = MAX(current_max_credits, 1); 483 484 cmd = SVAL(inhdr, SMB2_HDR_OPCODE); 450 485 credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT); 451 486 out_flags = IVAL(outhdr, SMB2_HDR_FLAGS); 487 out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS)); 452 488 453 489 SMB_ASSERT(sconn->smb2.max_credits >= sconn->smb2.credits_granted); … … 459 495 * credits on the final response. 460 496 */ 461 credits_requested = 0; 462 } 463 464 if (credits_requested) { 465 uint16_t modified_credits_requested; 466 uint32_t multiplier; 467 468 /* 469 * Split up max_credits into 1/16ths, and then scale 470 * the requested credits by how many 16ths have been 471 * currently granted. Less than 1/16th == grant all 472 * requested (100%), scale down as more have been 473 * granted. Never ask for less than 1 as the client 474 * asked for at least 1. JRA. 475 */ 476 477 multiplier = 16 - (((sconn->smb2.credits_granted * 16) / sconn->smb2.max_credits) % 16); 478 479 modified_credits_requested = (multiplier * credits_requested) / 16; 480 if (modified_credits_requested == 0) { 481 modified_credits_requested = 1; 482 } 483 484 /* Remember what we gave out. */ 485 credits_granted = MIN(modified_credits_requested, 486 (sconn->smb2.max_credits - sconn->smb2.credits_granted)); 487 } 488 489 if (credits_granted == 0 && sconn->smb2.credits_granted == 0) { 490 /* First negprot packet, or ensure the client credits can 491 never drop to zero. */ 497 credits_granted = 0; 498 } else if (credits_requested > 0) { 499 uint16_t additional_max = 0; 500 uint16_t additional_credits = credits_requested - 1; 501 502 switch (cmd) { 503 case SMB2_OP_NEGPROT: 504 break; 505 case SMB2_OP_SESSSETUP: 506 /* 507 * Windows 2012 RC1 starts to grant 508 * additional credits 509 * with a successful session setup 510 */ 511 if (NT_STATUS_IS_OK(out_status)) { 512 additional_max = 32; 513 } 514 break; 515 default: 516 /* 517 * We match windows and only grant additional credits 518 * in chunks of 32. 519 */ 520 additional_max = 32; 521 break; 522 } 523 524 additional_credits = MIN(additional_credits, additional_max); 525 526 credits_granted = 1 + additional_credits; 527 } else if (sconn->smb2.credits_granted == 0) { 528 /* 529 * Make sure the client has always at least one credit 530 */ 492 531 credits_granted = 1; 493 532 } 533 534 /* 535 * sequence numbers should not wrap 536 * 537 * 1. calculate the possible credits until 538 * the sequence numbers start to wrap on 64-bit. 539 * 540 * 2. UINT64_MAX is used for Break Notifications. 541 * 542 * 2. truncate the possible credits to the maximum 543 * credits we want to grant to the client in total. 544 * 545 * 3. remove the range we'll already granted to the client 546 * this makes sure the client consumes the lowest sequence 547 * number, before we can grant additional credits. 548 */ 549 credits_possible = UINT64_MAX - sconn->smb2.seqnum_low; 550 if (credits_possible > 0) { 551 /* remove UINT64_MAX */ 552 credits_possible -= 1; 553 } 554 credits_possible = MIN(credits_possible, current_max_credits); 555 credits_possible -= sconn->smb2.seqnum_range; 556 557 credits_granted = MIN(credits_granted, credits_possible); 494 558 495 559 SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted); 496 560 sconn->smb2.credits_granted += credits_granted; 561 sconn->smb2.seqnum_range += credits_granted; 497 562 498 563 DEBUG(10,("smb2_set_operation_credit: requested %u, " 499 "granted %u, total granted %u\n", 564 "granted %u, current possible/max %u/%u, " 565 "total granted/max/low/range %u/%u/%llu/%u\n", 500 566 (unsigned int)credits_requested, 501 567 (unsigned int)credits_granted, 502 (unsigned int)sconn->smb2.credits_granted )); 568 (unsigned int)credits_possible, 569 (unsigned int)current_max_credits, 570 (unsigned int)sconn->smb2.credits_granted, 571 (unsigned int)sconn->smb2.max_credits, 572 (unsigned long long)sconn->smb2.seqnum_low, 573 (unsigned int)sconn->smb2.seqnum_range)); 503 574 } 504 575 … … 507 578 { 508 579 int count, idx; 580 uint16_t total_credits = 0; 509 581 510 582 count = outreq->out.vector_count; 511 583 512 584 for (idx=1; idx < count; idx += 3) { 585 uint8_t *outhdr = (uint8_t *)outreq->out.vector[idx].iov_base; 513 586 smb2_set_operation_credit(outreq->sconn, 514 587 &inreq->in.vector[idx], 515 588 &outreq->out.vector[idx]); 589 /* To match Windows, count up what we 590 just granted. */ 591 total_credits += SVAL(outhdr, SMB2_HDR_CREDIT); 592 /* Set to zero in all but the last reply. */ 593 if (idx + 3 < count) { 594 SSVAL(outhdr, SMB2_HDR_CREDIT, 0); 595 } else { 596 SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits); 597 } 516 598 } 517 599 } … … 570 652 SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC); 571 653 SSVAL(outhdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); 572 SSVAL(outhdr, SMB2_HDR_EPOCH, 0); 654 SSVAL(outhdr, SMB2_HDR_CREDIT_CHARGE, 655 SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE)); 573 656 SIVAL(outhdr, SMB2_HDR_STATUS, 574 657 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR)); … … 586 669 SBVAL(outhdr, SMB2_HDR_SESSION_ID, 587 670 BVAL(inhdr, SMB2_HDR_SESSION_ID)); 588 memset(outhdr + SMB2_HDR_SIGNATURE, 0, 16); 671 memcpy(outhdr + SMB2_HDR_SIGNATURE, 672 inhdr + SMB2_HDR_SIGNATURE, 16); 589 673 590 674 /* setup error body header */ … … 864 948 * Cancel the outstanding request. 865 949 */ 866 tevent_req_cancel(req->subreq); 950 bool ok = tevent_req_cancel(req->subreq); 951 if (ok) { 952 return NT_STATUS_OK; 953 } 954 TALLOC_FREE(req->subreq); 867 955 return smbd_smb2_request_error(req, 868 NT_STATUS_IN SUFFICIENT_RESOURCES);956 NT_STATUS_INTERNAL_ERROR); 869 957 } 870 958 … … 885 973 return status; 886 974 } 975 976 /* 977 * We're splitting off the last SMB2 978 * request in a compound set, and the 979 * smb2_send_async_interim_response() 980 * call above just sent all the replies 981 * for the previous SMB2 requests in 982 * this compound set. So we're no longer 983 * in the "compound_related_in_progress" 984 * state, and this is no longer a compound 985 * request. 986 */ 987 req->compound_related = false; 988 req->sconn->smb2.compound_related_in_progress = false; 887 989 } 888 990 889 991 /* Don't return an intermediate packet on a pipe read/write. */ 890 992 if (req->tcon && req->tcon->compat_conn && IS_IPC(req->tcon->compat_conn)) { 891 return NT_STATUS_OK;993 goto ipc_out; 892 994 } 893 995 … … 929 1031 SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(reqhdr, SMB2_HDR_OPCODE)); 930 1032 931 SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);1033 SIVAL(hdr, SMB2_HDR_FLAGS, flags); 932 1034 SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0); 933 1035 SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id); … … 952 1054 &state->vector[1]); 953 1055 1056 SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC); 1057 954 1058 if (req->do_signing) { 955 1059 status = smb2_signing_sign_pdu(req->session->session_key, … … 977 1081 /* Note we're going async with this request. */ 978 1082 req->async = true; 1083 1084 ipc_out: 979 1085 980 1086 /* … … 1025 1131 req->out.vector_count); 1026 1132 1027 /* Ensure our final reply matches the interim one. */ 1028 reqhdr = (uint8_t *)req->out.vector[1].iov_base; 1029 SIVAL(reqhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC); 1030 SBVAL(reqhdr, SMB2_HDR_PID, async_id); 1031 1032 { 1033 const uint8_t *inhdr = 1034 (const uint8_t *)req->in.vector[1].iov_base; 1035 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu " 1036 "going async\n", 1037 smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)), 1038 (unsigned long long)async_id )); 1039 } 1133 if (req->async) { 1134 /* Ensure our final reply matches the interim one. */ 1135 reqhdr = (uint8_t *)req->out.vector[1].iov_base; 1136 SIVAL(reqhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC); 1137 SBVAL(reqhdr, SMB2_HDR_PID, async_id); 1138 1139 { 1140 const uint8_t *inhdr = 1141 (const uint8_t *)req->in.vector[1].iov_base; 1142 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu " 1143 "going async\n", 1144 smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)), 1145 (unsigned long long)async_id )); 1146 } 1147 } 1148 1040 1149 return NT_STATUS_OK; 1041 1150 } … … 1102 1211 } 1103 1212 1213 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req, 1214 size_t expected_body_size) 1215 { 1216 const uint8_t *inhdr; 1217 uint16_t opcode; 1218 const uint8_t *inbody; 1219 int i = req->current_idx; 1220 size_t body_size; 1221 size_t min_dyn_size = expected_body_size & 0x00000001; 1222 1223 /* 1224 * The following should be checked already. 1225 */ 1226 if ((i+2) > req->in.vector_count) { 1227 return NT_STATUS_INTERNAL_ERROR; 1228 } 1229 if (req->in.vector[i+0].iov_len != SMB2_HDR_BODY) { 1230 return NT_STATUS_INTERNAL_ERROR; 1231 } 1232 if (req->in.vector[i+1].iov_len < 2) { 1233 return NT_STATUS_INTERNAL_ERROR; 1234 } 1235 1236 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 1237 opcode = SVAL(inhdr, SMB2_HDR_OPCODE); 1238 1239 switch (opcode) { 1240 case SMB2_OP_IOCTL: 1241 case SMB2_OP_GETINFO: 1242 min_dyn_size = 0; 1243 break; 1244 } 1245 1246 /* 1247 * Now check the expected body size, 1248 * where the last byte might be in the 1249 * dynnamic section.. 1250 */ 1251 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 1252 return NT_STATUS_INVALID_PARAMETER; 1253 } 1254 if (req->in.vector[i+2].iov_len < min_dyn_size) { 1255 return NT_STATUS_INVALID_PARAMETER; 1256 } 1257 1258 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 1259 1260 body_size = SVAL(inbody, 0x00); 1261 if (body_size != expected_body_size) { 1262 return NT_STATUS_INVALID_PARAMETER; 1263 } 1264 1265 return NT_STATUS_OK; 1266 } 1267 1104 1268 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) 1105 1269 { … … 1125 1289 (unsigned long long)mid)); 1126 1290 1291 if (get_Protocol() >= PROTOCOL_SMB2) { 1292 /* 1293 * once the protocol is negotiated 1294 * SMB2_OP_NEGPROT is not allowed anymore 1295 */ 1296 if (opcode == SMB2_OP_NEGPROT) { 1297 /* drop the connection */ 1298 return NT_STATUS_INVALID_PARAMETER; 1299 } 1300 } else { 1301 /* 1302 * if the protocol is not negotiated yet 1303 * only SMB2_OP_NEGPROT is allowed. 1304 */ 1305 if (opcode != SMB2_OP_NEGPROT) { 1306 /* drop the connection */ 1307 return NT_STATUS_INVALID_PARAMETER; 1308 } 1309 } 1310 1127 1311 allowed_flags = SMB2_HDR_FLAG_CHAINED | 1128 1312 SMB2_HDR_FLAG_SIGNED | … … 1145 1329 session_status = smbd_smb2_request_check_session(req); 1146 1330 1331 if (flags & SMB2_HDR_FLAG_CHAINED) { 1332 /* 1333 * This check is mostly for giving the correct error code 1334 * for compounded requests. 1335 */ 1336 if (!NT_STATUS_IS_OK(session_status)) { 1337 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 1338 } 1339 } else { 1340 req->compat_chain_fsp = NULL; 1341 } 1342 1147 1343 req->do_signing = false; 1148 1344 if (flags & SMB2_HDR_FLAG_SIGNED) { … … 1157 1353 return smbd_smb2_request_error(req, status); 1158 1354 } 1355 } else if (opcode == SMB2_OP_CANCEL) { 1356 /* Cancel requests are allowed to skip the signing */ 1159 1357 } else if (req->session && req->session->do_signing) { 1160 1358 return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED); … … 1162 1360 1163 1361 if (flags & SMB2_HDR_FLAG_CHAINED) { 1164 /* 1165 * This check is mostly for giving the correct error code 1166 * for compounded requests. 1167 * 1168 * TODO: we may need to move this after the session 1169 * and tcon checks. 1170 */ 1171 if (!NT_STATUS_IS_OK(req->next_status)) { 1172 return smbd_smb2_request_error(req, req->next_status); 1173 } 1174 } else { 1175 req->compat_chain_fsp = NULL; 1362 req->compound_related = true; 1363 req->sconn->smb2.compound_related_in_progress = true; 1176 1364 } 1177 1365 … … 1622 1810 } 1623 1811 1812 if (req->compound_related) { 1813 req->compound_related = false; 1814 req->sconn->smb2.compound_related_in_progress = false; 1815 } 1816 1624 1817 smb2_setup_nbt_length(req->out.vector, req->out.vector_count); 1625 1818 1626 /* Set credit for th is operation(zero credits if this1819 /* Set credit for these operations (zero credits if this 1627 1820 is a final reply for an async operation). */ 1628 smb2_set_operation_credit(req->sconn, 1629 &req->in.vector[i], 1630 &req->out.vector[i]); 1821 smb2_calculate_credits(req, req); 1631 1822 1632 1823 if (req->do_signing) { … … 1672 1863 } 1673 1864 1865 static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn); 1866 1674 1867 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx, 1675 1868 struct tevent_immediate *im, … … 1690 1883 1691 1884 status = smbd_smb2_request_dispatch(req); 1885 if (!NT_STATUS_IS_OK(status)) { 1886 smbd_server_connection_terminate(sconn, nt_errstr(status)); 1887 return; 1888 } 1889 1890 status = smbd_smb2_request_next_incoming(sconn); 1692 1891 if (!NT_STATUS_IS_OK(status)) { 1693 1892 smbd_server_connection_terminate(sconn, nt_errstr(status)); … … 1703 1902 int ret; 1704 1903 int sys_errno; 1904 NTSTATUS status; 1705 1905 1706 1906 ret = tstream_writev_queue_recv(subreq, &sys_errno); … … 1708 1908 TALLOC_FREE(req); 1709 1909 if (ret == -1) { 1710 NTSTATUSstatus = map_nt_error_from_unix(sys_errno);1910 status = map_nt_error_from_unix(sys_errno); 1711 1911 DEBUG(2,("smbd_smb2_request_writev_done: client write error %s\n", 1712 1912 nt_errstr(status))); 1913 smbd_server_connection_terminate(sconn, nt_errstr(status)); 1914 return; 1915 } 1916 1917 status = smbd_smb2_request_next_incoming(sconn); 1918 if (!NT_STATUS_IS_OK(status)) { 1713 1919 smbd_server_connection_terminate(sconn, nt_errstr(status)); 1714 1920 return; … … 1853 2059 1854 2060 /* 1855 * if a request fails, all other remaining1856 * compounded requests should fail too2061 * Note: Even if there is an error, continue to process the request. 2062 * per MS-SMB2. 1857 2063 */ 1858 req->next_status = NT_STATUS_INVALID_PARAMETER;1859 2064 1860 2065 return smbd_smb2_request_done_ex(req, status, body, info, __location__); … … 2318 2523 static void smbd_smb2_request_incoming(struct tevent_req *subreq); 2319 2524 2525 static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn) 2526 { 2527 size_t max_send_queue_len; 2528 size_t cur_send_queue_len; 2529 struct tevent_req *subreq; 2530 2531 if (sconn->smb2.compound_related_in_progress) { 2532 /* 2533 * Can't read another until the related 2534 * compound is done. 2535 */ 2536 return NT_STATUS_OK; 2537 } 2538 2539 if (tevent_queue_length(sconn->smb2.recv_queue) > 0) { 2540 /* 2541 * if there is already a smbd_smb2_request_read 2542 * pending, we are done. 2543 */ 2544 return NT_STATUS_OK; 2545 } 2546 2547 max_send_queue_len = MAX(1, sconn->smb2.max_credits/16); 2548 cur_send_queue_len = tevent_queue_length(sconn->smb2.send_queue); 2549 2550 if (cur_send_queue_len > max_send_queue_len) { 2551 /* 2552 * if we have a lot of requests to send, 2553 * we wait until they are on the wire until we 2554 * ask for the next request. 2555 */ 2556 return NT_STATUS_OK; 2557 } 2558 2559 /* ask for the next request */ 2560 subreq = smbd_smb2_request_read_send(sconn, sconn->smb2.event_ctx, sconn); 2561 if (subreq == NULL) { 2562 return NT_STATUS_NO_MEMORY; 2563 } 2564 tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn); 2565 2566 return NT_STATUS_OK; 2567 } 2568 2320 2569 void smbd_smb2_first_negprot(struct smbd_server_connection *sconn, 2321 2570 const uint8_t *inbuf, size_t size) … … 2323 2572 NTSTATUS status; 2324 2573 struct smbd_smb2_request *req = NULL; 2325 struct tevent_req *subreq;2326 2574 2327 2575 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n", … … 2340 2588 } 2341 2589 2590 status = smbd_smb2_request_validate(req); 2591 if (!NT_STATUS_IS_OK(status)) { 2592 smbd_server_connection_terminate(sconn, nt_errstr(status)); 2593 return; 2594 } 2595 2342 2596 status = smbd_smb2_request_setup_out(req); 2343 2597 if (!NT_STATUS_IS_OK(status)) { … … 2352 2606 } 2353 2607 2354 /* ask for the next request */ 2355 subreq = smbd_smb2_request_read_send(sconn, sconn->smb2.event_ctx, sconn); 2356 if (subreq == NULL) { 2357 smbd_server_connection_terminate(sconn, "no memory for reading"); 2608 status = smbd_smb2_request_next_incoming(sconn); 2609 if (!NT_STATUS_IS_OK(status)) { 2610 smbd_server_connection_terminate(sconn, nt_errstr(status)); 2358 2611 return; 2359 2612 } 2360 tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);2361 2613 2362 2614 sconn->num_requests++; … … 2410 2662 2411 2663 next: 2412 /* ask for the next request (this constructs the main loop) */ 2413 subreq = smbd_smb2_request_read_send(sconn, sconn->smb2.event_ctx, sconn); 2414 if (subreq == NULL) { 2415 smbd_server_connection_terminate(sconn, "no memory for reading"); 2664 status = smbd_smb2_request_next_incoming(sconn); 2665 if (!NT_STATUS_IS_OK(status)) { 2666 smbd_server_connection_terminate(sconn, nt_errstr(status)); 2416 2667 return; 2417 2668 } 2418 tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);2419 2669 2420 2670 sconn->num_requests++; -
vendor/current/source3/smbd/smb2_sesssetup.c
r740 r746 48 48 DATA_BLOB outbody; 49 49 DATA_BLOB outdyn; 50 size_t expected_body_size = 0x19;51 size_t body_size;52 50 uint64_t in_session_id; 53 51 uint8_t in_security_mode; … … 58 56 uint64_t out_session_id; 59 57 uint16_t out_security_offset; 60 DATA_BLOB out_security_buffer ;58 DATA_BLOB out_security_buffer = data_blob_null; 61 59 NTSTATUS status; 62 60 61 status = smbd_smb2_request_verify_sizes(smb2req, 0x19); 62 if (!NT_STATUS_IS_OK(status)) { 63 return smbd_smb2_request_error(smb2req, status); 64 } 63 65 inhdr = (const uint8_t *)smb2req->in.vector[i+0].iov_base; 64 65 if (smb2req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {66 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);67 }68 69 66 inbody = (const uint8_t *)smb2req->in.vector[i+1].iov_base; 70 71 body_size = SVAL(inbody, 0x00);72 if (body_size != expected_body_size) {73 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);74 }75 67 76 68 in_security_offset = SVAL(inbody, 0x0C); 77 69 in_security_length = SVAL(inbody, 0x0E); 78 70 79 if (in_security_offset != (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {71 if (in_security_offset != (SMB2_HDR_BODY + smb2req->in.vector[i+1].iov_len)) { 80 72 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER); 81 73 } … … 196 188 bool username_was_mapped = false; 197 189 bool map_domainuser_to_guest = false; 190 bool guest = false; 198 191 199 192 if (!spnego_parse_krb5_wrap(talloc_tos(), *secblob, &ticket, tok_id)) { … … 272 265 /* force no signing */ 273 266 session->do_signing = false; 267 guest = true; 274 268 } 275 269 … … 324 318 */ 325 319 smb2req->session = session; 326 if ( session->do_signing) {320 if (!guest) { 327 321 smb2req->do_signing = true; 328 322 } … … 478 472 { 479 473 fstring tmp; 474 bool guest = false; 480 475 481 476 if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) || … … 490 485 /* force no signing */ 491 486 session->do_signing = false; 487 guest = true; 492 488 } 493 489 … … 537 533 */ 538 534 smb2req->session = session; 539 if ( session->do_signing) {535 if (!guest) { 540 536 smb2req->do_signing = true; 541 537 } … … 565 561 } 566 562 567 if (auth. data[0] == ASN1_APPLICATION(0)) {563 if (auth.length > 0 && auth.data[0] == ASN1_APPLICATION(0)) { 568 564 /* Might be a second negTokenTarg packet */ 569 565 DATA_BLOB secblob_in = data_blob_null; … … 679 675 NTSTATUS status; 680 676 DATA_BLOB secblob_out = data_blob_null; 677 678 *out_security_buffer = data_blob_null; 681 679 682 680 if (session->auth_ntlmssp_state == NULL) { … … 820 818 { 821 819 const uint8_t *inhdr; 822 const uint8_t *outhdr;823 820 int i = req->current_idx; 821 uint32_t in_flags; 824 822 uint64_t in_session_id; 825 823 void *p; 826 824 struct smbd_smb2_session *session; 827 bool chained_fixup = false; 825 826 req->session = NULL; 827 req->tcon = NULL; 828 828 829 829 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 830 830 831 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS); 831 832 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID); 832 833 833 if (in_session_id == (0xFFFFFFFFFFFFFFFFLL)) { 834 if (req->async) { 835 /* 836 * async request - fill in session_id from 837 * already setup request out.vector[].iov_base. 838 */ 839 outhdr = (const uint8_t *)req->out.vector[i].iov_base; 840 in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID); 841 } else if (i > 2) { 842 /* 843 * Chained request - fill in session_id from 844 * the previous request out.vector[].iov_base. 845 */ 846 outhdr = (const uint8_t *)req->out.vector[i-3].iov_base; 847 in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID); 848 chained_fixup = true; 849 } 850 } 834 if (in_flags & SMB2_HDR_FLAG_CHAINED) { 835 in_session_id = req->last_session_id; 836 } 837 838 req->last_session_id = UINT64_MAX; 851 839 852 840 /* lookup an existing session */ … … 866 854 867 855 req->session = session; 868 869 if (chained_fixup) { 870 /* Fix up our own outhdr. */ 871 outhdr = (const uint8_t *)req->out.vector[i].iov_base; 872 SBVAL(outhdr, SMB2_HDR_SESSION_ID, in_session_id); 873 } 856 req->last_session_id = in_session_id; 857 874 858 return NT_STATUS_OK; 875 859 } … … 877 861 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req) 878 862 { 879 const uint8_t *inbody; 880 int i = req->current_idx; 863 NTSTATUS status; 881 864 DATA_BLOB outbody; 882 size_t expected_body_size = 0x04; 883 size_t body_size; 884 885 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 886 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 887 } 888 889 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 890 891 body_size = SVAL(inbody, 0x00); 892 if (body_size != expected_body_size) { 893 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 865 866 status = smbd_smb2_request_verify_sizes(req, 0x04); 867 if (!NT_STATUS_IS_OK(status)) { 868 return smbd_smb2_request_error(req, status); 894 869 } 895 870 -
vendor/current/source3/smbd/smb2_setinfo.c
r740 r746 30 30 struct tevent_context *ev, 31 31 struct smbd_smb2_request *smb2req, 32 struct files_struct *in_fsp, 32 33 uint8_t in_info_type, 33 34 uint8_t in_file_info_class, 34 35 DATA_BLOB in_input_buffer, 35 uint32_t in_additional_information, 36 uint64_t in_file_id_volatile); 36 uint32_t in_additional_information); 37 37 static NTSTATUS smbd_smb2_setinfo_recv(struct tevent_req *req); 38 38 … … 40 40 NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req) 41 41 { 42 const uint8_t *inhdr;42 NTSTATUS status; 43 43 const uint8_t *inbody; 44 44 int i = req->current_idx; 45 size_t expected_body_size = 0x21;46 size_t body_size;47 45 uint8_t in_info_type; 48 46 uint8_t in_file_info_class; … … 53 51 uint64_t in_file_id_persistent; 54 52 uint64_t in_file_id_volatile; 53 struct files_struct *in_fsp; 55 54 struct tevent_req *subreq; 56 55 57 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 58 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 59 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 60 } 61 56 status = smbd_smb2_request_verify_sizes(req, 0x21); 57 if (!NT_STATUS_IS_OK(status)) { 58 return smbd_smb2_request_error(req, status); 59 } 62 60 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 63 64 body_size = SVAL(inbody, 0x00);65 if (body_size != expected_body_size) {66 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);67 }68 61 69 62 in_info_type = CVAL(inbody, 0x02); … … 79 72 /* This is ok */ 80 73 } else if (in_input_buffer_offset != 81 (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {74 (SMB2_HDR_BODY + req->in.vector[i+1].iov_len)) { 82 75 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 83 76 } … … 90 83 in_input_buffer.length = in_input_buffer_length; 91 84 92 if (req->compat_chain_fsp) { 93 /* skip check */ 94 } else if (in_file_id_persistent != in_file_id_volatile) { 85 if (in_input_buffer.length > req->sconn->smb2.max_trans) { 86 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 87 } 88 89 in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); 90 if (in_fsp == NULL) { 95 91 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 96 92 } 97 93 98 subreq = smbd_smb2_setinfo_send(req, 99 req->sconn->smb2.event_ctx, 100 req, 94 subreq = smbd_smb2_setinfo_send(req, req->sconn->smb2.event_ctx, 95 req, in_fsp, 101 96 in_info_type, 102 97 in_file_info_class, 103 98 in_input_buffer, 104 in_additional_information, 105 in_file_id_volatile); 99 in_additional_information); 106 100 if (subreq == NULL) { 107 101 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); … … 160 154 struct tevent_context *ev, 161 155 struct smbd_smb2_request *smb2req, 156 struct files_struct *fsp, 162 157 uint8_t in_info_type, 163 158 uint8_t in_file_info_class, 164 159 DATA_BLOB in_input_buffer, 165 uint32_t in_additional_information, 166 uint64_t in_file_id_volatile) 160 uint32_t in_additional_information) 167 161 { 168 162 struct tevent_req *req = NULL; … … 170 164 struct smb_request *smbreq = NULL; 171 165 connection_struct *conn = smb2req->tcon->compat_conn; 172 files_struct *fsp = NULL;173 166 NTSTATUS status; 174 167 … … 180 173 state->smb2req = smb2req; 181 174 182 DEBUG(10,("smbd_smb2_setinfo_send: file_id[0x%016llX]\n",183 (unsigned long long)in_file_id_volatile));175 DEBUG(10,("smbd_smb2_setinfo_send: %s - fnum[%d]\n", 176 fsp_str_dbg(fsp), fsp->fnum)); 184 177 185 178 smbreq = smbd_smb2_fake_smb_request(smb2req); 186 179 if (tevent_req_nomem(smbreq, req)) { 187 return tevent_req_post(req, ev);188 }189 190 fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);191 if (fsp == NULL) {192 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);193 return tevent_req_post(req, ev);194 }195 if (conn != fsp->conn) {196 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);197 return tevent_req_post(req, ev);198 }199 if (smb2req->session->vuid != fsp->vuid) {200 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);201 180 return tevent_req_post(req, ev); 202 181 } … … 220 199 /* SMB2_FILE_RENAME_INFORMATION_INTERNAL == 0xFF00 + in_file_info_class */ 221 200 file_info_level = SMB2_FILE_RENAME_INFORMATION_INTERNAL; 222 if (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK &&223 fsp->oplock_type != NO_OPLOCK) {224 /* No break, but error. */225 tevent_req_nterror(req, NT_STATUS_SHARING_VIOLATION);226 return tevent_req_post(req, ev);227 }228 201 } 229 202 … … 326 299 } 327 300 328 status = set_sd (fsp,301 status = set_sd_blob(fsp, 329 302 in_input_buffer.data, 330 303 in_input_buffer.length, -
vendor/current/source3/smbd/smb2_tcon.c
r740 r746 40 40 uint8_t *outhdr; 41 41 DATA_BLOB outbody; 42 size_t expected_body_size = 0x09;43 size_t body_size;44 42 uint16_t in_path_offset; 45 43 uint16_t in_path_length; … … 55 53 bool ok; 56 54 57 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {58 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);59 }60 55 status = smbd_smb2_request_verify_sizes(req, 0x09); 56 if (!NT_STATUS_IS_OK(status)) { 57 return smbd_smb2_request_error(req, status); 58 } 61 59 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 62 63 body_size = SVAL(inbody, 0x00);64 if (body_size != expected_body_size) {65 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);66 }67 60 68 61 in_path_offset = SVAL(inbody, 0x04); 69 62 in_path_length = SVAL(inbody, 0x06); 70 63 71 if (in_path_offset != (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {64 if (in_path_offset != (SMB2_HDR_BODY + req->in.vector[i+1].iov_len)) { 72 65 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 73 66 } … … 87 80 if (!ok) { 88 81 return smbd_smb2_request_error(req, NT_STATUS_ILLEGAL_CHARACTER); 82 } 83 84 if (in_path_buffer.length == 0) { 85 in_path_string_size = 0; 86 } 87 88 if (strlen(in_path_string) != in_path_string_size) { 89 return smbd_smb2_request_error(req, NT_STATUS_BAD_NETWORK_NAME); 89 90 } 90 91 … … 228 229 talloc_set_destructor(tcon, smbd_smb2_tcon_destructor); 229 230 230 compat_conn = make_connection_snum(req->sconn, 231 snum, req->session->compat_vuser, 231 compat_conn = make_connection_smb2(req->sconn, 232 tcon, 233 req->session->compat_vuser, 232 234 data_blob_null, "???", 233 235 &status); … … 237 239 } 238 240 tcon->compat_conn = talloc_move(tcon, &compat_conn); 239 tcon->compat_conn->cnum = tcon->tid;240 241 241 242 if (IS_PRINT(tcon->compat_conn)) { … … 281 282 { 282 283 const uint8_t *inhdr; 283 const uint8_t *outhdr;284 284 int i = req->current_idx; 285 uint32_t in_flags; 285 286 uint32_t in_tid; 286 287 void *p; 287 288 struct smbd_smb2_tcon *tcon; 288 bool chained_fixup = false; 289 290 req->tcon = NULL; 289 291 290 292 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 291 293 294 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS); 292 295 in_tid = IVAL(inhdr, SMB2_HDR_TID); 293 296 294 if (in_tid == (0xFFFFFFFF)) { 295 if (req->async) { 296 /* 297 * async request - fill in tid from 298 * already setup out.vector[].iov_base. 299 */ 300 outhdr = (const uint8_t *)req->out.vector[i].iov_base; 301 in_tid = IVAL(outhdr, SMB2_HDR_TID); 302 } else if (i > 2) { 303 /* 304 * Chained request - fill in tid from 305 * the previous request out.vector[].iov_base. 306 */ 307 outhdr = (const uint8_t *)req->out.vector[i-3].iov_base; 308 in_tid = IVAL(outhdr, SMB2_HDR_TID); 309 chained_fixup = true; 310 } 311 } 297 if (in_flags & SMB2_HDR_FLAG_CHAINED) { 298 in_tid = req->last_tid; 299 } 300 301 req->last_tid = UINT32_MAX; 312 302 313 303 /* lookup an existing session */ … … 328 318 329 319 req->tcon = tcon; 330 331 if (chained_fixup) { 332 /* Fix up our own outhdr. */ 333 outhdr = (const uint8_t *)req->out.vector[i].iov_base; 334 SIVAL(outhdr, SMB2_HDR_TID, in_tid); 335 } 320 req->last_tid = in_tid; 336 321 337 322 return NT_STATUS_OK; … … 340 325 NTSTATUS smbd_smb2_request_process_tdis(struct smbd_smb2_request *req) 341 326 { 342 const uint8_t *inbody; 343 int i = req->current_idx; 327 NTSTATUS status; 344 328 DATA_BLOB outbody; 345 size_t expected_body_size = 0x04; 346 size_t body_size; 347 348 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 349 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 350 } 351 352 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 353 354 body_size = SVAL(inbody, 0x00); 355 if (body_size != expected_body_size) { 356 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 329 330 status = smbd_smb2_request_verify_sizes(req, 0x04); 331 if (!NT_STATUS_IS_OK(status)) { 332 return smbd_smb2_request_error(req, status); 357 333 } 358 334 -
vendor/current/source3/smbd/smb2_write.c
r740 r746 29 29 struct tevent_context *ev, 30 30 struct smbd_smb2_request *smb2req, 31 struct files_struct *in_fsp, 31 32 uint32_t in_smbpid, 32 uint64_t in_file_id_volatile,33 33 DATA_BLOB in_data, 34 34 uint64_t in_offset, … … 40 40 NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req) 41 41 { 42 NTSTATUS status; 42 43 const uint8_t *inhdr; 43 44 const uint8_t *inbody; 44 45 int i = req->current_idx; 45 size_t expected_body_size = 0x31;46 size_t body_size;47 46 uint32_t in_smbpid; 48 47 uint16_t in_data_offset; … … 52 51 uint64_t in_file_id_persistent; 53 52 uint64_t in_file_id_volatile; 53 struct files_struct *in_fsp; 54 54 uint32_t in_flags; 55 55 struct tevent_req *subreq; 56 56 57 status = smbd_smb2_request_verify_sizes(req, 0x31); 58 if (!NT_STATUS_IS_OK(status)) { 59 return smbd_smb2_request_error(req, status); 60 } 57 61 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 58 if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {59 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);60 }61 62 62 inbody = (const uint8_t *)req->in.vector[i+1].iov_base; 63 64 body_size = SVAL(inbody, 0x00);65 if (body_size != expected_body_size) {66 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);67 }68 63 69 64 in_smbpid = IVAL(inhdr, SMB2_HDR_PID); … … 76 71 in_flags = IVAL(inbody, 0x2C); 77 72 78 if (in_data_offset != (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {73 if (in_data_offset != (SMB2_HDR_BODY + req->in.vector[i+1].iov_len)) { 79 74 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 80 75 } … … 85 80 86 81 /* check the max write size */ 87 if (in_data_length > lp_smb2_max_write()) { 88 /* This is a warning. */ 82 if (in_data_length > req->sconn->smb2.max_write) { 89 83 DEBUG(2,("smbd_smb2_request_process_write : " 90 84 "client ignored max write :%s: 0x%08X: 0x%08X\n", 91 __location__, in_data_length, lp_smb2_max_write())); 92 #if 0 85 __location__, in_data_length, req->sconn->smb2.max_write)); 93 86 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); 94 #endif95 87 } 96 88 … … 98 90 in_data_buffer.length = in_data_length; 99 91 100 if (req->compat_chain_fsp) { 101 /* skip check */ 102 } else if (in_file_id_persistent != in_file_id_volatile) { 92 in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); 93 if (in_fsp == NULL) { 103 94 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 104 95 } 105 96 106 subreq = smbd_smb2_write_send(req, 107 req->sconn->smb2.event_ctx, 108 req, 97 subreq = smbd_smb2_write_send(req, req->sconn->smb2.event_ctx, 98 req, in_fsp, 109 99 in_smbpid, 110 in_file_id_volatile,111 100 in_data_buffer, 112 101 in_offset, … … 225 214 struct tevent_context *ev, 226 215 struct smbd_smb2_request *smb2req, 216 struct files_struct *fsp, 227 217 uint32_t in_smbpid, 228 uint64_t in_file_id_volatile,229 218 DATA_BLOB in_data, 230 219 uint64_t in_offset, … … 236 225 struct smb_request *smbreq = NULL; 237 226 connection_struct *conn = smb2req->tcon->compat_conn; 238 files_struct *fsp = NULL;239 227 ssize_t nwritten; 240 228 struct lock_struct lock; … … 252 240 state->out_count = 0; 253 241 254 DEBUG(10,("smbd_smb2_write: file_id[0x%016llX]\n",255 (unsigned long long)in_file_id_volatile));242 DEBUG(10,("smbd_smb2_write: %s - fnum[%d]\n", 243 fsp_str_dbg(fsp), fsp->fnum)); 256 244 257 245 smbreq = smbd_smb2_fake_smb_request(smb2req); 258 246 if (tevent_req_nomem(smbreq, req)) { 259 return tevent_req_post(req, ev);260 }261 262 fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);263 if (fsp == NULL) {264 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);265 return tevent_req_post(req, ev);266 }267 if (conn != fsp->conn) {268 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);269 return tevent_req_post(req, ev);270 }271 if (smb2req->session->vuid != fsp->vuid) {272 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);273 247 return tevent_req_post(req, ev); 274 248 } … … 325 299 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) { 326 300 /* Real error in setting up aio. Fail. */ 327 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);301 tevent_req_nterror(req, status); 328 302 return tevent_req_post(req, ev); 329 303 } … … 331 305 /* Fallback to synchronous. */ 332 306 init_strict_lock_struct(fsp, 333 in_file_id_volatile,307 fsp->fnum, 334 308 in_offset, 335 309 in_data.length, -
vendor/current/source3/smbd/statcache.c
r740 r746 151 151 * 152 152 * @param conn A connection struct to do the stat() with. 153 * @param posix_paths Whether to lookup using stat() or lstat() 153 154 * @param name The path we are attempting to cache, modified by this routine 154 155 * to be correct as far as the cache can tell us. We assume that … … 167 168 168 169 bool stat_cache_lookup(connection_struct *conn, 170 bool posix_paths, 169 171 char **pp_name, 170 172 char **pp_dirpath, … … 182 184 TALLOC_CTX *ctx = talloc_tos(); 183 185 struct smb_filename smb_fname; 186 int ret; 184 187 185 188 *pp_dirpath = NULL; … … 284 287 smb_fname.base_name = translated_path; 285 288 286 if (SMB_VFS_STAT(conn, &smb_fname) != 0) { 289 if (posix_paths) { 290 ret = SMB_VFS_LSTAT(conn, &smb_fname); 291 } else { 292 ret = SMB_VFS_STAT(conn, &smb_fname); 293 } 294 295 if (ret != 0) { 287 296 /* Discard this entry - it doesn't exist in the filesystem. */ 288 297 memcache_delete(smbd_memcache(), STAT_CACHE, -
vendor/current/source3/smbd/trans2.c
r740 r746 863 863 reply_outbuf(req, 10, total_sent_thistime + alignment_offset 864 864 + data_alignment_offset); 865 866 /*867 * We might have SMBtrans2s in req which was transferred to868 * the outbuf, fix that.869 */870 SCVAL(req->outbuf, smb_com, SMBtrans2);871 865 872 866 /* Set total params and data to be sent */ … … 1084 1078 } 1085 1079 1086 if (!map_open_params_to_ntcreate(smb_fname, deny_mode, open_ofun, 1080 if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode, 1081 open_ofun, 1087 1082 &access_mask, &share_mode, 1088 1083 &create_disposition, … … 2271 2266 struct dptr_struct *dirptr = NULL; 2272 2267 struct smbd_server_connection *sconn = req->sconn; 2268 uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP); 2273 2269 2274 2270 if (total_params < 13) { … … 2314 2310 goto out; 2315 2311 } 2312 ucf_flags |= UCF_UNIX_NAME_LOOKUP; 2316 2313 break; 2317 2314 default: … … 2331 2328 req->flags2 & FLAGS2_DFS_PATHNAMES, 2332 2329 directory, 2333 (UCF_SAVE_LCOMP | 2334 UCF_ALWAYS_ALLOW_WCARD_LCOMP), 2330 ucf_flags, 2335 2331 &mask_contains_wcard, 2336 2332 &smb_dname); … … 4673 4669 case SMB_QUERY_FILE_STREAM_INFO: 4674 4670 case SMB_FILE_STREAM_INFORMATION: { 4675 unsigned int num_streams ;4676 struct stream_struct *streams ;4671 unsigned int num_streams = 0; 4672 struct stream_struct *streams = NULL; 4677 4673 4678 4674 DEBUG(10,("smbd_do_qfilepathinfo: " … … 4683 4679 } 4684 4680 4685 status = SMB_VFS_STREAMINFO( 4686 conn, fsp, smb_fname->base_name, talloc_tos(), 4687 &num_streams, &streams); 4681 status = vfs_streaminfo(conn, fsp, smb_fname->base_name, 4682 talloc_tos(), &num_streams, &streams); 4688 4683 4689 4684 if (!NT_STATUS_IS_OK(status)) { … … 5104 5099 uint32_t name_hash; 5105 5100 char *fname = NULL; 5101 uint32_t ucf_flags = 0; 5106 5102 5107 5103 /* qpathinfo */ … … 5115 5111 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level)); 5116 5112 5117 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { 5118 reply_nterror(req, NT_STATUS_INVALID_LEVEL); 5119 return; 5113 if (INFO_LEVEL_IS_UNIX(info_level)) { 5114 if (!lp_unix_extensions()) { 5115 reply_nterror(req, NT_STATUS_INVALID_LEVEL); 5116 return; 5117 } 5118 if (info_level == SMB_QUERY_FILE_UNIX_BASIC || 5119 info_level == SMB_QUERY_FILE_UNIX_INFO2 || 5120 info_level == SMB_QUERY_FILE_UNIX_LINK) { 5121 ucf_flags |= UCF_UNIX_NAME_LOOKUP; 5122 } 5120 5123 } 5121 5124 … … 5132 5135 req->flags2 & FLAGS2_DFS_PATHNAMES, 5133 5136 fname, 5134 0,5137 ucf_flags, 5135 5138 NULL, 5136 5139 &smb_fname); … … 5819 5822 /* The set is across all open files on this dev/inode pair. */ 5820 5823 if (!set_delete_on_close(fsp, delete_on_close, 5824 conn->session_info->security_token, 5821 5825 &conn->session_info->utok)) { 5822 5826 return NT_STATUS_ACCESS_DENIED; … … 7976 7980 } else { 7977 7981 char *fname = NULL; 7982 uint32_t ucf_flags = 0; 7978 7983 7979 7984 /* set path info */ … … 7992 7997 } 7993 7998 7999 if (info_level == SMB_SET_FILE_UNIX_BASIC || 8000 info_level == SMB_SET_FILE_UNIX_INFO2 || 8001 info_level == SMB_FILE_RENAME_INFORMATION || 8002 info_level == SMB_POSIX_PATH_UNLINK) { 8003 ucf_flags |= UCF_UNIX_NAME_LOOKUP; 8004 } 8005 7994 8006 status = filename_convert(req, conn, 7995 8007 req->flags2 & FLAGS2_DFS_PATHNAMES, 7996 8008 fname, 7997 0,8009 ucf_flags, 7998 8010 NULL, 7999 8011 &smb_fname); … … 8822 8834 show_msg((char *)req->inbuf); 8823 8835 8836 /* Windows clients expect all replies to 8837 a transact secondary (SMBtranss2 0x33) 8838 to have a command code of transact 8839 (SMBtrans2 0x32). See bug #8989 8840 and also [MS-CIFS] section 2.2.4.47.2 8841 for details. 8842 */ 8843 req->cmd = SMBtrans2; 8844 8824 8845 if (req->wct < 8) { 8825 8846 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); -
vendor/current/source3/smbd/vfs.c
r740 r746 1126 1126 } 1127 1127 1128 /** 1129 * Initialize num_streams and streams, then call VFS op streaminfo 1130 */ 1131 NTSTATUS vfs_streaminfo(connection_struct *conn, 1132 struct files_struct *fsp, 1133 const char *fname, 1134 TALLOC_CTX *mem_ctx, 1135 unsigned int *num_streams, 1136 struct stream_struct **streams) 1137 { 1138 *num_streams = 0; 1139 *streams = NULL; 1140 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams); 1141 } 1142 1128 1143 /* 1129 1144 generate a file_id from a stat structure … … 1501 1516 1502 1517 /* cd into the parent dir to pin it. */ 1503 ret = SMB_VFS_CHDIR(fsp->conn, parent_dir);1518 ret = vfs_ChDir(fsp->conn, parent_dir); 1504 1519 if (ret == -1) { 1505 1520 return map_nt_error_from_unix(errno); … … 1512 1527 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname); 1513 1528 if (ret == -1) { 1514 return map_nt_error_from_unix(errno); 1529 status = map_nt_error_from_unix(errno); 1530 goto out; 1515 1531 } 1516 1532 1517 1533 /* Ensure it matches the fsp stat. */ 1518 1534 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) { 1519 return NT_STATUS_ACCESS_DENIED; 1535 status = NT_STATUS_ACCESS_DENIED; 1536 goto out; 1520 1537 } 1521 1538 path = final_component; … … 1540 1557 } 1541 1558 1559 out: 1560 1542 1561 if (as_root) { 1543 1562 vfs_ChDir(fsp->conn,saved_dir);
Note:
See TracChangeset
for help on using the changeset viewer.