Ignore:
Timestamp:
Nov 27, 2012, 4:56:06 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated vendor to 3.6.9

Location:
vendor/current/source3/smbd
Files:
48 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/smbd/aio.c

    r740 r746  
    6767
    6868        smbd_aio_complete_aio_ex(aio_ex);
     69        TALLOC_FREE(aio_ex);
    6970}
    7071
     
    895896                return;
    896897        }
    897 
    898         TALLOC_FREE(aio_ex);
    899898}
    900899
  • vendor/current/source3/smbd/blocking.c

    r740 r746  
    327327*****************************************************************************/
    328328
    329 static void reply_lockingX_error(struct blocking_lock_record *blr, NTSTATUS status)
     329static void undo_locks_obtained(struct blocking_lock_record *blr)
    330330{
    331331        files_struct *fsp = blr->fsp;
     
    371371                        WINDOWS_LOCK);
    372372        }
    373 
    374         generic_blocking_lock_error(blr, status);
    375373}
    376374
     
    385383        switch(blr->req->cmd) {
    386384        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;
    389396        case SMBtrans2:
    390397        case SMBtranss2:
  • vendor/current/source3/smbd/close.c

    r740 r746  
    202202NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
    203203{
    204         struct stream_struct *stream_info;
     204        struct stream_struct *stream_info = NULL;
    205205        int i;
    206         unsigned int num_streams;
     206        unsigned int num_streams = 0;
    207207        TALLOC_CTX *frame = talloc_stackframe();
    208208        NTSTATUS status;
    209209
    210         status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
    211                                     &num_streams, &stream_info);
     210        status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
     211                                &num_streams, &stream_info);
    212212
    213213        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
     
    218218
    219219        if (!NT_STATUS_IS_OK(status)) {
    220                 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
     220                DEBUG(10, ("vfs_streaminfo failed: %s\n",
    221221                           nt_errstr(status)));
    222222                goto fail;
     
    281281        struct file_id id;
    282282        const struct security_unix_token *del_token = NULL;
     283        const struct security_token *del_nt_token = NULL;
     284        bool got_tokens = false;
    283285
    284286        /* Ensure any pending write time updates are done. */
     
    346348                }
    347349                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));
    349353                if (became_user) {
    350354                        unbecome_user();
     
    399403        fsp->update_write_time_on_close = false;
    400404
    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);
    403408
    404409        if (!unix_token_equal(del_token, get_current_utok(conn))) {
     
    419424                            del_token->ngroups,
    420425                            del_token->groups,
    421                             NULL);
     426                            del_nt_token);
    422427
    423428                changed_user = true;
     
    492497
    493498        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);
    495500
    496501 done:
     
    818823        }
    819824
    820         if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
     825        if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(SNUM(conn))) {
    821826                /*
    822827                 * Check to see if the only thing in this directory are
     
    963968        NTSTATUS status = NT_STATUS_OK;
    964969        NTSTATUS status1 = NT_STATUS_OK;
     970        const struct security_token *del_nt_token = NULL;
    965971        const struct security_unix_token *del_token = NULL;
    966972
     
    9991005                                               fsp->fsp_name->base_name);
    10001006                set_delete_on_close_lck(fsp, lck, true,
     1007                                get_current_nttok(fsp->conn),
    10011008                                get_current_utok(fsp->conn));
    10021009                fsp->delete_on_close = true;
     
    10061013        }
    10071014
    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);
    10101017
    10111018        if (delete_dir) {
     
    10391046                                del_token->ngroups,
    10401047                                del_token->groups,
    1041                                 NULL);
     1048                                del_nt_token);
    10421049
    10431050                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                }
    10441062
    10451063                status = rmdir_internals(talloc_tos(), fsp);
  • vendor/current/source3/smbd/conn.c

    r740 r746  
    6868                                if (ptcon->compat_conn &&
    6969                                                ptcon->compat_conn->params &&
    70                                                 (ptcon->compat_conn->params->service = snum)) {
     70                                                (ptcon->compat_conn->params->service == snum)) {
    7171                                        return true;
    7272                                }
  • vendor/current/source3/smbd/dir.c

    r740 r746  
    261261        }
    262262
     263        if (sconn->using_smb2) {
     264                goto done;
     265        }
     266
    263267        DLIST_REMOVE(sconn->searches.dirptrs, dptr);
    264268
     
    280284        /* Lanman 2 specific code */
    281285        SAFE_FREE(dptr->wcard);
    282         string_set(&dptr->path,"");
     286        SAFE_FREE(dptr->path);
    283287        SAFE_FREE(dptr);
    284288}
     
    471475        ZERO_STRUCTP(dptr);
    472476
     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
    473506        if(old_handle) {
    474507
     
    494527                        if(dptr->dnum == -1 || dptr->dnum > 254) {
    495528                                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);
    496531                                SAFE_FREE(dptr);
    497532                                TALLOC_FREE(dir_hnd);
     
    524559                        if(dptr->dnum == -1 || dptr->dnum < 255) {
    525560                                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);
    526563                                SAFE_FREE(dptr);
    527564                                TALLOC_FREE(dir_hnd);
     
    535572        dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
    536573
    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 
    557574        DLIST_ADD(sconn->searches.dirptrs, dptr);
    558575
     576done:
    559577        DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
    560578                dptr->dnum,path,expect_close)); 
     
    13281346                SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir);
    13291347        }
    1330         if (dirp->conn->sconn) {
     1348        if (dirp->conn->sconn && !dirp->conn->sconn->using_smb2) {
    13311349                dirp->conn->sconn->searches.dirhandles_open--;
    13321350        }
     
    13591377        }
    13601378
    1361         if (sconn) {
     1379        if (sconn && !sconn->using_smb2) {
    13621380                sconn->searches.dirhandles_open++;
    13631381        }
     
    14031421        }
    14041422
    1405         if (sconn) {
     1423        if (sconn && !sconn->using_smb2) {
    14061424                sconn->searches.dirhandles_open++;
    14071425        }
  • vendor/current/source3/smbd/file_access.c

    r740 r746  
    4242        if (get_current_uid(conn) == (uid_t)0) {
    4343                /* 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. */
    4451                return true;
    4552        }
     
    8188
    8289bool can_delete_file_in_directory(connection_struct *conn,
    83                                   struct smb_filename *smb_fname)
     90                                  const struct smb_filename *smb_fname)
    8491{
    8592        TALLOC_CTX *ctx = talloc_tos();
     
    131138         * by owner of directory. */
    132139        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;
    145144                        goto out;
    146145                }
     
    263262                                SECINFO_DACL, &secdesc);
    264263
    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);
    266268                return false;
    267269        }
  • vendor/current/source3/smbd/filename.c

    r740 r746  
    384384        if((!conn->case_sensitive || !(conn->fs_capabilities &
    385385                                       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,
    387387                              &smb_fname->st)) {
    388388                goto done;
     
    978978
    979979/****************************************************************************
     980 Ensure a path is not vetod.
     981****************************************************************************/
     982
     983NTSTATUS 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/****************************************************************************
    980997 Check a filename - possibly calling check_reduced_name.
    981998 This is called by every routine before it allows an operation on a filename.
     
    9861003NTSTATUS check_name(connection_struct *conn, const char *name)
    9871004{
    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;
    9961009        }
    9971010
    9981011        if (!lp_widelinks(SNUM(conn)) || !lp_symlinks(SNUM(conn))) {
    999                 NTSTATUS status = check_reduced_name(conn,name);
     1012                status = check_reduced_name(conn,name);
    10001013                if (!NT_STATUS_IS_OK(status)) {
    10011014                        DEBUG(5,("check_name: name %s failed with %s\n",name,
     
    11711184{
    11721185        NTSTATUS status;
    1173         unsigned int i, num_streams;
     1186        unsigned int i, num_streams = 0;
    11741187        struct stream_struct *streams = NULL;
    11751188
     
    11861199
    11871200        /* 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                                     &num_streams, &streams);
     1201        status = vfs_streaminfo(conn, NULL, smb_fname->base_name, mem_ctx,
     1202                                &num_streams, &streams);
    11901203
    11911204        if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     
    13151328        }
    13161329
     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
    13171336        status = check_name(conn, (*pp_smb_fname)->base_name);
    13181337        if (!NT_STATUS_IS_OK(status)) {
  • vendor/current/source3/smbd/files.c

    r740 r746  
    2929
    3030/****************************************************************************
    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.
    3234****************************************************************************/
    3335
    3436static unsigned long get_gen_count(struct smbd_server_connection *sconn)
    3537{
     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        }
    3647        sconn->file_gen_counter += 1;
     48        if (sconn->file_gen_counter >= UINT32_MAX) {
     49                sconn->file_gen_counter = 0;
     50        }
    3751        if (sconn->file_gen_counter == 0) {
    3852                sconn->file_gen_counter += 1;
     
    284298        int count=0;
    285299        files_struct *fsp;
     300
     301        if (gen_id == 0) {
     302                return NULL;
     303        }
    286304
    287305        for (fsp=sconn->files; fsp; fsp=fsp->next,count++) {
     
    549567}
    550568
     569uint64_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
     593struct 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
    551638/****************************************************************************
    552639 Duplicate the file handle part for a DOS or FCB open.
  • vendor/current/source3/smbd/globals.h

    r740 r746  
    278278struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req);
    279279void remove_smb2_chained_fsp(files_struct *fsp);
     280
     281NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
     282                                        size_t expected_body_size);
    280283
    281284NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req);
     
    351354        /* the session the request operates on, maybe NULL */
    352355        struct smbd_smb2_session *session;
     356        uint64_t last_session_id;
    353357
    354358        /* the tcon the request operates on, maybe NULL */
    355359        struct smbd_smb2_tcon *tcon;
     360        uint32_t last_tid;
    356361
    357362        int current_idx;
     
    359364        bool async;
    360365        bool cancelled;
     366        bool compound_related;
    361367
    362368        /* fake smb1 request. */
    363369        struct smb_request *smb1req;
    364370        struct files_struct *compat_chain_fsp;
    365 
    366         NTSTATUS next_status;
    367371
    368372        /*
     
    598602                } locks;
    599603                struct smbd_smb2_request *requests;
     604                /*
     605                 * seqnum_low is the lowest sequence number
     606                 * we will accept.
     607                 */
    600608                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                 */
    603645                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;
    604650        } smb2;
    605651};
  • vendor/current/source3/smbd/lanman.c

    r740 r746  
    35253525                                            NULL,
    35263526                                            devmode_ctr,
    3527                                             SEC_FLAG_MAXIMUM_ALLOWED,
     3527                                            PRINTER_ACCESS_ADMINISTER,
    35283528                                            &handle,
    35293529                                            &werr);
     
    49824982                                            NULL,
    49834983                                            devmode_ctr,
    4984                                             SEC_FLAG_MAXIMUM_ALLOWED,
     4984                                            PRINTER_ACCESS_USE,
    49854985                                            &handle,
    49864986                                            &werr);
     
    51825182                                            NULL,
    51835183                                            devmode_ctr,
    5184                                             SEC_FLAG_MAXIMUM_ALLOWED,
     5184                                            PRINTER_ACCESS_USE,
    51855185                                            &handle,
    51865186                                            &werr);
  • vendor/current/source3/smbd/msdfs.c

    r740 r746  
    576576
    577577        /*
    578          * Note the unix path conversion here we're doing we can
     578         * Note the unix path conversion here we're doing we
    579579         * throw away. We're looking for a symlink for a dfs
    580580         * resolution, if we don't find it we'll do another
    581581         * unix_convert later in the codepath.
    582          * If we needed to remember what we'd resolved in
    583          * dp->reqpath (as the original code did) we'd
    584          * copy (localhost, dp->reqpath) on any code
    585          * path below that returns True - but I don't
    586          * think this is needed. JRA.
    587582         */
    588583
     
    595590                        return status;
    596591                }
    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) {
    602593                        return status;
    603594                }
  • vendor/current/source3/smbd/negprot.c

    r740 r746  
    717717
    718718        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
    719725        END_PROFILE(SMBnegprot);
    720726        return;
  • vendor/current/source3/smbd/notify.c

    r740 r746  
    346346}
    347347
     348static 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);
     379chdir_done:
     380        vfs_ChDir(conn, oldwd);
     381done:
     382        TALLOC_FREE(parent);
     383}
     384
    348385void notify_fname(connection_struct *conn, uint32 action, uint32 filter,
    349386                  const char *path)
    350387{
    351388        char *fullpath;
    352         char *parent;
    353         const char *name;
    354389
    355390        if (path[0] == '.' && path[1] == '/') {
    356391                path += 2;
    357392        }
    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);
    370394
    371395        fullpath = talloc_asprintf(talloc_tos(), "%s/%s", conn->connectpath,
  • vendor/current/source3/smbd/nttrans.c

    r740 r746  
    143143                             total_sent_thistime + alignment_offset
    144144                             + data_alignment_offset);
    145 
    146                 /*
    147                  * We might have had SMBnttranss in req->inbuf, fix that.
    148                  */
    149                 SCVAL(req->outbuf, smb_com, SMBnttrans);
    150145
    151146                /*
     
    694689                uint16_t file_status = (NO_EAS|NO_SUBSTREAMS|NO_REPARSETAG);
    695690                size_t num_names = 0;
    696                 unsigned int num_streams;
     691                unsigned int num_streams = 0;
    697692                struct stream_struct *streams = NULL;
    698693
     
    703698                        file_status &= ~NO_EAS;
    704699                }
    705                 status = SMB_VFS_STREAMINFO(conn, NULL, smb_fname->base_name, ctx,
     700                status = vfs_streaminfo(conn, NULL, smb_fname->base_name, ctx,
    706701                        &num_streams, &streams);
    707702                /* There is always one stream, ::$DATA. */
     
    832827}
    833828
     829/*********************************************************************
     830 Windows seems to do canonicalization of inheritance bits. Do the
     831 same.
     832*********************************************************************/
     833
     834static 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
    834862/****************************************************************************
    835863 Internal fn to set security descriptors.
    836864****************************************************************************/
    837865
    838 NTSTATUS set_sd(files_struct *fsp, uint8_t *data, uint32_t sd_len,
     866NTSTATUS 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
     948NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len,
    839949                       uint32_t security_info_sent)
    840950{
     
    846956        }
    847957
    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 
    856958        status = unmarshall_sec_desc(talloc_tos(), data, sd_len, &psd);
    857959
     
    860962        }
    861963
    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);
    917965}
    918966
     
    12691317                uint16_t file_status = (NO_EAS|NO_SUBSTREAMS|NO_REPARSETAG);
    12701318                size_t num_names = 0;
    1271                 unsigned int num_streams;
     1319                unsigned int num_streams = 0;
    12721320                struct stream_struct *streams = NULL;
    12731321
     
    12781326                        file_status &= ~NO_EAS;
    12791327                }
    1280                 status = SMB_VFS_STREAMINFO(conn, NULL, smb_fname->base_name, ctx,
     1328                status = vfs_streaminfo(conn, NULL, smb_fname->base_name, ctx,
    12811329                        &num_streams, &streams);
    12821330                /* There is always one stream, ::$DATA. */
     
    18691917        }
    18701918
     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
    18711926        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. */
    18721930                status = get_null_nt_acl(mem_ctx, &psd);
    18731931        } else {
     
    18861944        }
    18871945        if (!(security_info_wanted & SECINFO_DACL)) {
     1946                psd->type &= ~SEC_DESC_DACL_PRESENT;
    18881947                psd->dacl = NULL;
    18891948        }
    18901949        if (!(security_info_wanted & SECINFO_SACL)) {
     1950                psd->type &= ~SEC_DESC_SACL_PRESENT;
    18911951                psd->sacl = NULL;
    18921952        }
     
    19001960            security_info_wanted & SECINFO_DACL)
    19011961                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        }
    19021971
    19031972        *psd_size = ndr_size_security_descriptor(psd, 0);
     
    20742143        }
    20752144
    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);
    20772146
    20782147        if (!NT_STATUS_IS_OK(status)) {
     
    20862155}
    20872156
    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
     2161static 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 */
     2168NTSTATUS 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)
    20982177{
    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;
    21262180
    21272181        switch (function) {
     
    21312185                NTSTATUS status;
    21322186
    2133                 if (data_count >= 1 && pdata[0] == 0) {
     2187                if (in_len >= 1 && in_data[0] == 0) {
    21342188                        set_sparse = false;
    21352189                }
    21362190
    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
    21572201        case FSCTL_CREATE_OR_GET_OBJECT_ID:
    21582202        {
    21592203                unsigned char objid[16];
     2204                char *return_data = NULL;
    21602205
    21612206                /* This should return the object-id on this file.
     
    21632208                 */
    21642209
    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;
    21762217                }
    21772218
    21782219                /* 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;
    21852225        }
    21862226
    21872227        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        }
    21952233
    21962234        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:
    22062242        {
    22072243                /*
     
    22192255                uint32 labels_data_count = 0;
    22202256                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) {
    22282260                        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) {
    22352266                        labels = True;
    22362267                }
    22372268
    2238                 shadow_data = TALLOC_ZERO_P(talloc_tos(),
    2239                                             struct shadow_copy_data);
     2269                shadow_data = talloc_zero(ctx, struct shadow_copy_data);
    22402270                if (shadow_data == NULL) {
    22412271                        DEBUG(0,("TALLOC_ZERO() failed!\n"));
    2242                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    2243                         return;
     2272                        return NT_STATUS_NO_MEMORY;
    22442273                }
    22452274
     
    22512280                        if (errno == ENOSYS) {
    22522281                                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;
    22562284                        } else {
    22572285                                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;
    22612288                        }
    22622289                }
    22632290
    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;
    22652293
    22662294                if (!labels) {
    2267                         data_count = 16;
     2295                        *out_len = 16;
    22682296                } 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) {
    22732301                        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));
    22752303                        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) {
    22822309                        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;
    22882314
    22892315                /* num_volumes 4 bytes */
    2290                 SIVAL(pdata,0,shadow_data->num_volumes);
     2316                SIVAL(cur_pdata, 0, shadow_data->num_volumes);
    22912317
    22922318                if (labels) {
    22932319                        /* num_labels 4 bytes */
    2294                         SIVAL(pdata,4,shadow_data->num_volumes);
     2320                        SIVAL(cur_pdata, 4, shadow_data->num_volumes);
    22952321                }
    22962322
    22972323                /* 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;
    23012327
    23022328                DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
    23032329                          shadow_data->num_volumes, fsp_str_dbg(fsp)));
    23042330                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,
    23072333                                            cur_pdata, shadow_data->labels[i],
    2308                                             2*sizeof(SHADOW_COPY_LABEL),
     2334                                            2 * sizeof(SHADOW_COPY_LABEL),
    23092335                                            STR_UNICODE|STR_TERMINATE);
    2310                                 cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
     2336                                cur_pdata += 2 * sizeof(SHADOW_COPY_LABEL);
    23112337                                DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
    23122338                        }
     
    23152341                TALLOC_FREE(shadow_data);
    23162342
    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:
    23242347        {
    23252348                /* pretend this succeeded -
     
    23332356                size_t sid_len;
    23342357
    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);
    23472366
    23482367                /* unknown 4 bytes: this is not the length of the sid :-(  */
    23492368                /*unknown = IVAL(pdata,0);*/
    23502369
    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;
    23542372                }
    23552373                DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid)));
     
    23732391                 * (maybe we can hang the result anywhere in the fsp struct)
    23742392                 *
     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                 *
    23752396                 * we don't send all files at once
    23762397                 * and at the next we should *not* start from the beginning,
     
    23812402
    23822403                /* 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
    23862407        case FSCTL_QUERY_ALLOCATED_RANGES:
    23872408        {
     
    23942415                NTSTATUS status;
    23952416                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) {
    24022420                        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);
    24172433
    24182434                if (offset + length < offset) {
    24192435                        /* No 64-bit integer wrap. */
    2420                         reply_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 ... ? */
    24242440                status = vfs_stat_fsp(fsp);
    24252441                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;
    24282450                }
    24292451
     
    24312453                                fsp->fsp_name->st.st_ex_size == 0 ||
    24322454                                length == 0) {
    2433                         send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
     2455                        memset(out_data_tmp, 0, *out_len);
    24342456                } else {
    24352457                        uint64_t end = offset + length;
    24362458                        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
    24442468        case FSCTL_IS_VOLUME_DIRTY:
     2469        {
    24452470                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));
    24472472                /*
    24482473                 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
    24492474                 * says we have to respond with NT_STATUS_INVALID_PARAMETER
    24502475                 */
    2451                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2452                 return;
     2476                return NT_STATUS_INVALID_PARAMETER;
     2477        }
     2478
    24532479        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
     2498static 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        }
    24642565}
    24652566
     
    31973298        show_msg((char *)req->inbuf);
    31983299
     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
    31993306        if (req->wct < 18) {
    32003307                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  • vendor/current/source3/smbd/open.c

    r740 r746  
    9393                        smb_fname_str_dbg(smb_fname),
    9494                        (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) ));
    95105                return NT_STATUS_OK;
    96106        }
     
    698708}
    699709
    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 
    717710/****************************************************************************
    718711 Check if we can open a file with a share mode.
     
    942935}
    943936
    944 static bool is_delete_request(files_struct *fsp) {
    945         return ((fsp->access_mask == DELETE_ACCESS) &&
    946                 (fsp->oplock_type == NO_OPLOCK));
    947 }
    948 
    949937/*
    950938 * Send a break message to the oplock holder and delay the open for
     
    10911079
    10921080        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;
    11001083        }
    11011084        return false;
     
    13351318}
    13361319
    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 
    14841320static void schedule_defer_open(struct share_mode_lock *lck,
    14851321                                struct timeval request_time,
     
    15731409                                        smb_fname_str_dbg(smb_fname)));
    15741410                                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                                }
    15751417                        }
    15761418
     
    17051547        ZERO_STRUCT(id);
    17061548
    1707         /* Windows allows a new file to be created and
    1708            silently removes a FILE_ATTRIBUTE_DIRECTORY
    1709            sent by the client. Do the same. */
    1710 
    1711         new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
    1712 
    17131549        if (conn->printer) {
    17141550                /*
     
    17441580                new_dos_attributes = 0;
    17451581        } 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
    17461588                /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
    17471589                 * created new. */
     
    17871629                        remove_deferred_open_message_smb(req->mid);
    17881630                }
    1789         }
    1790 
    1791         status = check_name(conn, smb_fname->base_name);
    1792         if (!NT_STATUS_IS_OK(status)) {
    1793                 return status;
    17941631        }
    17951632
     
    27432580        SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
    27442581
    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        }
    27472586
    27482587        DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
     
    29002739        fsp->share_access = share_access;
    29012740        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;
    29062741        fsp->print_file = NULL;
    29072742        fsp->modified = False;
     
    29182753        mtimespec = smb_dname->st.st_ex_mtime;
    29192754
     2755        /* Temporary access mask used to open the directory fd. */
     2756        fsp->access_mask = FILE_READ_DATA | FILE_READ_ATTRIBUTES;
    29202757#ifdef O_DIRECTORY
    29212758        status = fd_open(conn, fsp, O_RDONLY|O_DIRECTORY, 0);
     
    29322769                return status;
    29332770        }
     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;
    29342777
    29352778        status = vfs_stat_fsp(fsp);
     
    31322975                                        const char *fname)
    31332976{
    3134         struct stream_struct *stream_info;
    3135         files_struct **streams;
     2977        struct stream_struct *stream_info = NULL;
     2978        files_struct **streams = NULL;
    31362979        int i;
    3137         unsigned int num_streams;
     2980        unsigned int num_streams = 0;
    31382981        TALLOC_CTX *frame = talloc_stackframe();
    31392982        NTSTATUS status;
    31402983
    3141         status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
    3142                                     &num_streams, &stream_info);
     2984        status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
     2985                                &num_streams, &stream_info);
    31432986
    31442987        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
     
    31502993
    31512994        if (!NT_STATUS_IS_OK(status)) {
    3152                 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
     2995                DEBUG(10, ("vfs_streaminfo failed: %s\n",
    31532996                           nt_errstr(status)));
    31542997                goto fail;
     
    35173360                fsp->access_mask = FILE_GENERIC_ALL;
    35183361
    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 
    35233362                if (sec_info_sent & (SECINFO_OWNER|
    35243363                                        SECINFO_GROUP|
    35253364                                        SECINFO_DACL|
    35263365                                        SECINFO_SACL)) {
    3527                         status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
     3366                        status = set_sd(fsp, sd, sec_info_sent);
    35283367                }
    35293368
     
    38143653        }
    38153654
    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 
    38233655        if (stream_name && is_ntfs_default_stream_smb_fname(smb_fname)) {
    38243656                int ret;
  • vendor/current/source3/smbd/oplock_linux.c

    r740 r746  
    7777        int ret;
    7878
     79        /* First set the signal handler. */
     80        if (linux_set_lease_sighandler(fd) == -1) {
     81                return -1;
     82        }
    7983        ret = fcntl(fd, F_SETLEASE, leasetype);
    8084        if (ret == -1 && errno == EACCES) {
    8185                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                }
    8295                ret = fcntl(fd, F_SETLEASE, leasetype);
    8396        }
  • vendor/current/source3/smbd/password.c

    r740 r746  
    295295        DEBUG(3, ("register_existing_vuid: User name: %s\t"
    296296                  "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 : ""));
    298299
    299300        if (!vuser->session_info->security_token) {
  • vendor/current/source3/smbd/posix_acls.c

    r740 r746  
    11311131****************************************************************************/
    11321132
    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)
    11351135#define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE)
    11361136
     
    13541354****************************************************************************/
    13551355
    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)
     1356static 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)
    13631365{
    13641366        canon_ace *pace;
     
    13711373                if (pace->type == SMB_ACL_USER_OBJ) {
    13721374
    1373                         if (setting_acl)
     1375                        if (setting_acl && !is_default_acl) {
    13741376                                apply_default_perms(params, is_directory, pace, S_IRUSR);
     1377                        }
    13751378                        got_user = True;
    13761379
     
    13811384                         */
    13821385
    1383                         if (setting_acl)
     1386                        if (setting_acl && !is_default_acl) {
    13841387                                apply_default_perms(params, is_directory, pace, S_IRGRP);
     1388                        }
    13851389                        got_grp = True;
    13861390
     
    13911395                         */
    13921396
    1393                         if (setting_acl)
     1397                        if (setting_acl && !is_default_acl) {
    13941398                                apply_default_perms(params, is_directory, pace, S_IROTH);
     1399                        }
    13951400                        got_other = True;
    13961401                        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                        }
    13971412                }
    13981413        }
     
    14101425                pace->trustee = *pfile_owner_sid;
    14111426                pace->attr = ALLOW_ACE;
     1427                /* Start with existing permissions, principle of least
     1428                   surprises for the user. */
     1429                pace->perms = pst->st_ex_mode;
    14121430
    14131431                if (setting_acl) {
    14141432                        /* 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
    14181436                        canon_ace *pace_iter;
    14191437
    14201438                        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) {
    14221443                                        if (uid_entry_in_group(conn, pace, pace_iter)) {
    14231444                                                pace->perms |= pace_iter->perms;
    1424                                                 group_matched = True;
    14251445                                        }
    14261446                                }
    14271447                        }
    14281448
    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. */
    14311451                                if (got_other)
    14321452                                        pace->perms = pace_other->perms;
    1433                                 else
    1434                                         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                        }
    14381458                } else {
    14391459                        pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR);
     
    14611481                        else
    14621482                                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                        }
    14641486                } else {
    14651487                        pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRGRP, S_IWGRP, S_IXGRP);
     
    14831505                if (setting_acl) {
    14841506                        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                        }
    14861510                } else
    14871511                        pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IROTH, S_IWOTH, S_IXOTH);
     
    14971521 If it does not have them, check if there are any entries where the trustee is the
    14981522 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.
    14991524****************************************************************************/
    15001525
     
    15361561        if (!got_group_obj)
    15371562                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_GROUP
    1543 ****************************************************************************/
    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::perm
    1549            SMB_ACL_USER     : not trustee    -> Posix ACL u:user:perm
    1550            SMB_ACL_USER_OBJ : trustee -> convert to SMB_ACL_USER : trustee
    1551            Posix ACL u:trustee:perm
    1552 
    1553            SMB_ACL_GROUP_OBJ: trustee(CREATOR_GROUP) -> Posix ACL d:g::perm
    1554            SMB_ACL_GROUP    : not trustee   -> Posix ACL g:group:perm
    1555            SMB_ACL_GROUP_OBJ: trustee -> convert to SMB_ACL_GROUP : trustee
    1556            Posix ACL g:trustee:perm
    1557         */
    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;
    15821563}
    15831564
     
    18051786                                (SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT)) {
    18061787
     1788                                canon_ace *current_dir_ace = current_ace;
    18071789                                DLIST_ADD_END(dir_ace, current_ace, canon_ace *);
    18081790
     
    18301812                                        dbgtext("create_canon_ace_lists: adding dir ACL:\n");
    18311813                                        print_canon_ace( current_ace, 0);
    1832                                 }
    1833 
    1834                                 /*
    1835                                  * We have a lossy mapping: directory ACE entries
    1836                                  * CREATOR_OWNER ------\
    1837                                  *     (map to)         +---> SMB_ACL_USER_OBJ
    1838                                  * owning sid    ------/
    1839                                  *
    1840                                  * CREATOR_GROUP ------\
    1841                                  *     (map to)         +---> SMB_ACL_GROUP_OBJ
    1842                                  * primary group sid --/
    1843                                  *
    1844                                  * on set. And on read of a directory ACL
    1845                                  *
    1846                                  * SMB_ACL_USER_OBJ ----> CREATOR_OWNER
    1847                                  * SMB_ACL_GROUP_OBJ ---> CREATOR_GROUP.
    1848                                  *
    1849                                  * Deal with this on set by duplicating
    1850                                  * owning sid and primary group sid ACE
    1851                                  * 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;
    18601814                                }
    18611815
     
    18941848                                        current_ace = NULL;
    18951849                                }
     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(&current_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(&current_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                                }
    18961887                        }
    18971888                }
     
    19551946        } else {
    19561947                /*
    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().
    19611953                 */
    19621954                if (file_ace) {
    19631955                        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);
    19671956                }
    19681957        }
     
    22872276
    22882277/****************************************************************************
    2289  Create a default mode that will be used if a security descriptor entry has
    2290  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 the
    2312          * 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 /****************************************************************************
    23272278 Unpack a struct security_descriptor into two canonical ace lists. We don't depend on this
    23282279 succeeding.
     
    23382289                                const struct security_descriptor *psd)
    23392290{
    2340         SMB_STRUCT_STAT st;
    23412291        canon_ace *file_ace = NULL;
    23422292        canon_ace *dir_ace = NULL;
     
    24022352        print_canon_ace_list( "file ace - before valid", file_ace);
    24032353
    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)) {
    24152356                free_canon_ace_list(file_ace);
    24162357                free_canon_ace_list(dir_ace);
     
    24202361        print_canon_ace_list( "dir ace - before valid", dir_ace);
    24212362
    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)) {
    24322365                free_canon_ace_list(file_ace);
    24332366                free_canon_ace_list(dir_ace);
     
    25172450        canon_ace *next_ace = NULL;
    25182451        int entry_id = SMB_ACL_FIRST_ENTRY;
     2452        bool is_default_acl = (the_acl_type == SMB_ACL_TYPE_DEFAULT);
    25192453        SMB_ACL_ENTRY_T entry;
    25202454        size_t ace_count;
     
    26042538                ace->unix_ug = unix_ug;
    26052539                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);
    26072541
    26082542                DLIST_ADD(l_head, ace);
     
    26132547         */
    26142548
    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,
    26162550                                      S_ISDIR(psbuf->st_ex_mode), powner, pgroup,
    26172551                                      psbuf, False))
     
    26232557         */
    26242558
    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"));
    26262560
    26272561        for ( ace_count = 0, ace = l_head; ace; ace = next_ace, ace_count++) {
  • vendor/current/source3/smbd/process.c

    r740 r746  
    452452                                        p_unread, &len);
    453453        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)));
    457458                return status;
    458459        }
     
    14421443        /* Make sure this is an SMB packet. smb_size contains NetBIOS header
    14431444         * 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)) {
    14461447                DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
    14471448                         smb_len(req->inbuf)));
     
    20892090
    20902091        /*
    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.
    20962106         */
    20972107
    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) {
    21002110                goto error;
    21012111        }
     
    27982808 * Handle SMBecho requests in a forked child process
    27992809 */
    2800 static bool fork_echo_handler(struct smbd_server_connection *sconn)
     2810bool fork_echo_handler(struct smbd_server_connection *sconn)
    28012811{
    28022812        int listener_pipe[2];
     
    29122922        int ret;
    29132923
    2914         if (lp_maxprotocol() == PROTOCOL_SMB2 &&
    2915             !lp_async_smb_echo_handler()) {
     2924        if (lp_maxprotocol() == PROTOCOL_SMB2) {
    29162925                /*
    29172926                 * We're not making the decision here,
     
    30343043        }
    30353044
    3036         if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
    3037                 exit_server("Failed to fork echo handler");
    3038         }
    3039 
    30403045        /* Setup oplocks */
    30413046        if (!init_oplocks(sconn->msg_ctx))
  • vendor/current/source3/smbd/proto.h

    r740 r746  
    302302                         uint32_t access_mask);
    303303bool can_delete_file_in_directory(connection_struct *conn,
    304                                   struct smb_filename *smb_fname);
     304                                  const struct smb_filename *smb_fname);
    305305bool can_access_file_data(connection_struct *conn,
    306306                          const struct smb_filename *smb_fname,
     
    337337                      struct smb_filename **smb_fname,
    338338                      uint32_t ucf_flags);
     339NTSTATUS check_veto_path(connection_struct *conn, const char *name);
    339340NTSTATUS check_name(connection_struct *conn, const char *name);
    340341int get_real_filename(connection_struct *conn, const char *path,
     
    373374void file_free(struct smb_request *req, files_struct *fsp);
    374375files_struct *file_fsp(struct smb_request *req, uint16 fid);
     376uint64_t fsp_persistent_id(const struct files_struct *fsp);
     377struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
     378                                   uint64_t persistent_id,
     379                                   uint64_t volatile_id);
    375380NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
    376381                      uint32 access_mask, uint32 share_access,
     
    557562                     char *pdata, int datasize);
    558563void reply_ntcreate_and_X(struct smb_request *req);
    559 NTSTATUS set_sd(files_struct *fsp, uint8_t *data, uint32_t sd_len,
     564NTSTATUS set_sd(files_struct *fsp, struct security_descriptor *psd,
    560565                       uint32_t security_info_sent);
     566NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len,
     567                       uint32_t security_info_sent);
     568NTSTATUS 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);
    561577struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size);
    562578void reply_ntcancel(struct smb_request *req);
     
    587603                                    const char *fname,
    588604                                    SMB_STRUCT_STAT *psbuf);
    589 bool is_executable(const char *fname);
    590605bool is_stat_open(uint32 access_mask);
    591606bool request_timed_out(struct timeval request_time,
     
    607622                         uint32 share_access,
    608623                         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);
    616624void remove_deferred_open_entry(struct file_id id, uint64_t mid,
    617625                                struct server_id pid);
     
    802810bool req_is_in_chain(struct smb_request *req);
    803811void smbd_process(struct smbd_server_connection *sconn);
     812bool fork_echo_handler(struct smbd_server_connection *sconn);
    804813
    805814/* The following definitions come from smbd/quotas.c  */
     
    960969bool unix_token_equal(const struct security_unix_token *t1, const struct security_unix_token *t2);
    961970bool push_sec_ctx(void);
    962 void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, struct security_token *token);
     971void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, const struct security_token *token);
    963972void set_root_sec_ctx(void);
    964973bool pop_sec_ctx(void);
     
    988997int add_home_service(const char *service, const char *username, const char *homedir);
    989998int 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,
     999struct smbd_smb2_tcon;
     1000connection_struct *make_connection_smb2(struct smbd_server_connection *sconn,
     1001                                        struct smbd_smb2_tcon *tcon,
     1002                                        user_struct *vuser,
    9921003                                        DATA_BLOB password,
    9931004                                        const char *pdev,
     
    10451056                bool case_sensitive);
    10461057bool stat_cache_lookup(connection_struct *conn,
     1058                        bool posix_paths,
    10471059                        char **pp_name,
    10481060                        char **pp_dirpath,
     
    11751187NTSTATUS vfs_stat_fsp(files_struct *fsp);
    11761188NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid);
     1189NTSTATUS 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);
    11771195
    11781196/* The following definitions come from smbd/avahi_register.c */
  • vendor/current/source3/smbd/quotas.c

    r740 r746  
    746746        *bsize = gqr.getquota_rslt_u.gqr_rquota.rq_bsize;
    747747        *dsize = D.dqb_bsoftlimit;
    748 
    749         if (D.dqb_curblocks == 1)
    750                 *bsize = 512;
    751748
    752749        if (D.dqb_curblocks > D.dqb_bsoftlimit) {
  • vendor/current/source3/smbd/reply.c

    r740 r746  
    17671767        }
    17681768
    1769         if (!map_open_params_to_ntcreate(smb_fname, deny_mode,
     1769        if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
    17701770                                         OPENX_FILE_EXISTS_OPEN, &access_mask,
    17711771                                         &share_mode, &create_disposition,
     
    19421942        }
    19431943
    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,
    19451946                                         &access_mask, &share_mode,
    19461947                                         &create_disposition,
     
    25412542
    25422543        /* 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)) {
    25442547                close_file(req, fsp, NORMAL_CLOSE);
    25452548                return NT_STATUS_ACCESS_DENIED;
     
    46304633        SSVAL(req->outbuf,smb_vwv4,nwritten>>16);
    46314634
    4632         if (nwritten < (ssize_t)numtowrite) {
    4633                 SCVAL(req->outbuf,smb_rcls,ERRHRD);
    4634                 SSVAL(req->outbuf,smb_err,ERRdiskfull);
    4635         }
    4636 
    46374635        DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
    46384636                fsp->fnum, (int)numtowrite, (int)nwritten));
     
    56555653        }
    56565654
    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)) {
    56585658                close_file(req, fsp, ERROR_CLOSE);
    56595659                reply_nterror(req, NT_STATUS_ACCESS_DENIED);
     
    59365936
    59375937/****************************************************************************
     5938 Returns an error if the parent directory for a filename is open in an
     5939 incompatible way.
     5940****************************************************************************/
     5941
     5942static 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/****************************************************************************
    59385979 Rename an open file - given an fsp.
    59395980****************************************************************************/
     
    59525993
    59535994        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);
    59546000        if (!NT_STATUS_IS_OK(status)) {
    59556001                return status;
     
    65626608        struct smb_filename *smb_fname_src = NULL;
    65636609        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);
    65646612        bool stream_rename = false;
    65656613
     
    66046652                                  req->flags2 & FLAGS2_DFS_PATHNAMES,
    66056653                                  name,
    6606                                   UCF_COND_ALLOW_WCARD_LCOMP,
     6654                                  src_ucf_flags,
    66076655                                  &src_has_wcard,
    66086656                                  &smb_fname_src);
     
    66226670                                  req->flags2 & FLAGS2_DFS_PATHNAMES,
    66236671                                  newname,
    6624                                   UCF_COND_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP,
     6672                                  dst_ucf_flags,
    66256673                                  &dest_has_wcard,
    66266674                                  &smb_fname_dst);
     
    67336781                new_create_disposition = FILE_OPEN;
    67346782        } 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,
    67366785                                                 NULL, NULL,
    67376786                                                 &new_create_disposition,
  • vendor/current/source3/smbd/sec_ctx.c

    r740 r746  
    305305****************************************************************************/
    306306
    307 void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, struct security_token *token)
     307void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, const struct security_token *token)
    308308{
    309309        struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
  • vendor/current/source3/smbd/server.c

    r740 r746  
    6565         */
    6666
     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
    6773        client_addr(fd, sconn->client_id.addr, sizeof(sconn->client_id.addr));
    6874
     
    277283        static struct timed_event *cleanup_te;
    278284        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        }
    279304
    280305        if (unclean_shutdown) {
     
    296321        }
    297322
    298         child_id = procid_self(); /* Just initialize pid and potentially vnn */
    299         child_id.pid = pid;
    300 
    301323        if (!serverid_deregister(child_id)) {
    302324                DEBUG(1, ("Could not remove pid %d from serverid.tdb\n",
    303325                          (int)pid));
    304326        }
    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));
    318327}
    319328
     
    442451         * the global random state in the parent.
    443452         */
    444         generate_random_buffer((uint8_t *)&unique_id, sizeof(unique_id));
     453        unique_id = serverid_get_random_unique_id();
    445454
    446455        pid = sys_fork();
     
    611620}
    612621
    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 
    633622/****************************************************************************
    634623 Open the socket communication.
     
    642631        int i;
    643632        char *ports;
     633        char *tok;
     634        const char *ptr;
    644635        unsigned dns_port = 0;
    645636
     
    663654        }
    664655
     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
    665666        if (lp_interfaces() && lp_bind_interfaces_only()) {
    666667                /* We have been given an interfaces line, and been
     
    674675                        const struct sockaddr_storage *ifss =
    675676                                        iface_n_sockaddr_storage(i);
    676                         char *tok;
    677                         const char *ptr;
    678677
    679678                        if (ifss == NULL) {
     
    687686                             next_token_talloc(talloc_tos(),&ptr, &tok, " \t,");) {
    688687                                unsigned port = atoi(tok);
    689                                 if (port == 0 || port > 0xffff) {
    690                                         continue;
    691                                 }
    692688
    693689                                /* Keep the first port for mDNS service
     
    707703                   from anywhere. */
    708704
    709                 char *tok;
    710                 const char *ptr;
    711705                const char *sock_addr = lp_socket_address();
    712706                char *sock_tok;
     
    726720                        for (ptr=ports; next_token_talloc(talloc_tos(), &ptr, &tok, " \t,"); ) {
    727721                                struct sockaddr_storage ss;
    728 
    729722                                unsigned port = atoi(tok);
    730                                 if (port == 0 || port > 0xffff) {
    731                                         continue;
    732                                 }
    733723
    734724                                /* Keep the first port for mDNS service
     
    769759                DEBUG(0, ("open_sockets_smbd: Failed to register "
    770760                          "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"));
    779761                return false;
    780762        }
     
    915897        TALLOC_CTX *frame;
    916898        NTSTATUS status;
    917         uint64_t unique_id;
    918899
    919900        /*
     
    11141095        }
    11151096
    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());
    11181098
    11191099#if HAVE_SETPGID
     
    12061186                exit(1);
    12071187
    1208         if (!print_backend_init(smbd_messaging_context()))
    1209                 exit(1);
    1210 
    12111188        /* Open the share_info.tdb here, so we don't have to open
    12121189           after the fork on every single connection.  This is a small
     
    12501227                exit(1);
    12511228        }
     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);
    12521236
    12531237        /* Publish nt printers, this requires a working winreg pipe */
  • vendor/current/source3/smbd/server_exit.c

    r740 r746  
    8484        const char *const reason)
    8585{
    86         bool had_open_conn = false;
    8786        struct smbd_server_connection *sconn = smbd_server_conn;
    8887
     
    102101                        files_forall(sconn, log_writeable_file_fn, &found);
    103102                }
    104                 had_open_conn = conn_close_all(sconn);
     103                (void)conn_close_all(sconn);
    105104                invalidate_all_vuids(sconn);
    106105        }
     
    176175                dump_core();
    177176
     177                /* Notreached. */
     178                exit(1);
    178179        } else {
    179180                DEBUG(3,("Server exit (%s)\n",
     
    185186        }
    186187
    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);
    196189}
    197190
  • vendor/current/source3/smbd/server_reload.c

    r740 r746  
    3939        struct auth_serversupplied_info *session_info = NULL;
    4040        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
     41        int n_services;
     42        int pnum;
    4143        int snum;
    42         int n_services = lp_numservices();
    43         int pnum = lp_servicenumber(PRINTERS_NAME);
    4444        const char *pname;
     45        const char *sname;
    4546        NTSTATUS status;
    46         bool skip = false;
    4747
    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
    4953        DEBUG(10, ("reloading printer services from pcap cache\n"));
    5054
     
    5559                /* can't remove stale printers before we
    5660                 * are fully initilized */
    57                 skip = true;
     61                return;
    5862        }
    5963
    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) {
    6571                        continue;
     72                }
    6673
     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);
    6780                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)) {
    6984                        DEBUG(3, ("removing stale printer %s\n", pname));
    7085
     
    8398                                          pname);
    8499                        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);
    85105                }
    86106        }
    87107
     108        /* Make sure deleted printers are gone */
    88109        load_printers(ev, msg_ctx);
    89110
     
    107128                        test = False;
    108129                }
     130                TALLOC_FREE(fname);
    109131        }
    110132
     
    146168                               struct messaging_context *msg_ctx)
    147169{
     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
    148179        message_send_all(msg_ctx, MSG_PRINTER_PCAP, NULL, 0, NULL);
    149180}
  • vendor/current/source3/smbd/service.c

    r740 r746  
    697697                }
    698698
     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
    699707                TALLOC_FREE(conn->session_info);
    700708                conn->session_info = forced_serverinfo;
     
    733741
    734742/****************************************************************************
     743  Setup the share access mask for a connection.
     744****************************************************************************/
     745
     746static 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/****************************************************************************
    735770  Make a connection, given the snum to connect to, and the vuser of the
    736771  connecting user if appropriate.
    737772****************************************************************************/
    738773
    739 connection_struct *make_connection_snum(struct smbd_server_connection *sconn,
     774static connection_struct *make_connection_snum(struct smbd_server_connection *sconn,
     775                                        connection_struct *conn,
    740776                                        int snum, user_struct *vuser,
    741777                                        DATA_BLOB password,
     
    743779                                        NTSTATUS *pstatus)
    744780{
    745         connection_struct *conn = NULL;
    746781        struct smb_filename *smb_fname_cpath = NULL;
    747782        fstring dev;
     
    760795        }
    761796
    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 
    769797        conn->params->service = snum;
    770798
     
    816844        status = set_conn_force_user_group(conn, snum);
    817845        if (!NT_STATUS_IS_OK(status)) {
    818                 conn_free(conn);
    819846                *pstatus = status;
    820847                return NULL;
     
    854881         */
    855882
    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);
    859884
    860885        if ((conn->share_access & FILE_WRITE_DATA) == 0) {
     
    11131138                yield_connection(conn, lp_servicename(snum));
    11141139        }
    1115         if (conn) {
     1140        return NULL;
     1141}
     1142
     1143/****************************************************************************
     1144 Make a connection to a service from SMB1. Internal interface.
     1145****************************************************************************/
     1146
     1147static 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) {
    11161168                conn_free(conn);
    1117         }
    1118         return NULL;
     1169                return NULL;
     1170        }
     1171        return conn;
    11191172}
    11201173
    11211174/****************************************************************************
    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
     1179connection_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.
    11231210 *
    11241211 * @param service
     
    11831270                        DEBUG(5, ("making a connection to [homes] service "
    11841271                                  "created at session setup time\n"));
    1185                         return make_connection_snum(sconn,
     1272                        return make_connection_smb1(sconn,
    11861273                                                    vuser->homes_snum,
    11871274                                                    vuser, no_pw,
     
    12071294                                          "service %s based on "
    12081295                                          "security=share\n", service_in));
    1209                                 return make_connection_snum(sconn,
     1296                                return make_connection_smb1(sconn,
    12101297                                                            snum, NULL,
    12111298                                                            password,
     
    12191306                DEBUG(5, ("making a connection to 'homes' service [%s] "
    12201307                          "created at session setup time\n", service_in));
    1221                 return make_connection_snum(sconn,
     1308                return make_connection_smb1(sconn,
    12221309                                            vuser->homes_snum,
    12231310                                            vuser, no_pw,
     
    12671354        DEBUG(5, ("making a connection to 'normal' service %s\n", service));
    12681355
    1269         return make_connection_snum(sconn, snum, vuser,
     1356        return make_connection_smb1(sconn, snum, vuser,
    12701357                                    password,
    12711358                                    dev, status);
  • vendor/current/source3/smbd/sesssetup.c

    r740 r746  
    736736        }
    737737
    738         if (auth.data[0] == ASN1_APPLICATION(0)) {
     738        if (auth.length > 0 && auth.data[0] == ASN1_APPLICATION(0)) {
    739739                /* Might be a second negTokenTarg packet */
    740740                char *kerb_mech = NULL;
  • vendor/current/source3/smbd/smb2_break.c

    r740 r746  
    2929                                                      struct tevent_context *ev,
    3030                                                      struct smbd_smb2_request *smb2req,
    31                                                       uint8_t in_oplock_level,
    32                                                       uint64_t in_file_id_volatile);
     31                                                      struct files_struct *in_fsp,
     32                                                      uint8_t in_oplock_level);
    3333static NTSTATUS smbd_smb2_oplock_break_recv(struct tevent_req *req,
    3434                                            uint8_t *out_oplock_level);
     
    3737NTSTATUS smbd_smb2_request_process_break(struct smbd_smb2_request *req)
    3838{
    39         const uint8_t *inhdr;
     39        NTSTATUS status;
    4040        const uint8_t *inbody;
    4141        int i = req->current_idx;
    42         size_t expected_body_size = 0x18;
    43         size_t body_size;
    4442        uint8_t in_oplock_level;
    4543        uint64_t in_file_id_persistent;
    4644        uint64_t in_file_id_volatile;
     45        struct files_struct *in_fsp;
    4746        struct tevent_req *subreq;
    4847
    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        }
    5452        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         }
    6053
    6154        in_oplock_level         = CVAL(inbody, 0x02);
     
    7164        in_file_id_volatile             = BVAL(inbody, 0x10);
    7265
    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) {
    7668                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    7769        }
    7870
    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);
    8473        if (subreq == NULL) {
    8574                return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     
    157146                                                      struct tevent_context *ev,
    158147                                                      struct smbd_smb2_request *smb2req,
    159                                                       uint8_t in_oplock_level,
    160                                                       uint64_t in_file_id_volatile)
     148                                                      struct files_struct *fsp,
     149                                                      uint8_t in_oplock_level)
    161150{
    162151        struct tevent_req *req;
    163152        struct smbd_smb2_oplock_break_state *state;
    164153        struct smb_request *smbreq;
    165         connection_struct *conn = smb2req->tcon->compat_conn;
    166         files_struct *fsp = NULL;
    167154        int oplocklevel = map_smb2_oplock_levels_to_samba(in_oplock_level);
    168155        bool break_to_none = (oplocklevel == NO_OPLOCK);
     
    177164        state->out_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
    178165
    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));
    183170
    184171        smbreq = smbd_smb2_fake_smb_request(smb2req);
    185172        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);
    200173                return tevent_req_post(req, ev);
    201174        }
     
    265238                                SMB2_OPLOCK_LEVEL_NONE;
    266239        NTSTATUS status;
     240        uint64_t fsp_persistent = fsp_persistent_id(fsp);
    267241
    268242        DEBUG(10,("send_break_message_smb2: sending oplock break "
     
    273247
    274248        status = smbd_smb2_send_oplock_break(fsp->conn->sconn,
    275                                         (uint64_t)fsp->fnum,
     249                                        fsp_persistent,
    276250                                        (uint64_t)fsp->fnum,
    277251                                        smb2_oplock_level);
  • vendor/current/source3/smbd/smb2_close.c

    r740 r746  
    2525
    2626static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
     27                                struct files_struct *fsp,
    2728                                uint16_t in_flags,
    28                                 uint64_t in_file_id_volatile,
    2929                                DATA_BLOB *outbody);
    3030
    3131NTSTATUS smbd_smb2_request_process_close(struct smbd_smb2_request *req)
    3232{
    33         const uint8_t *inhdr;
    3433        const uint8_t *inbody;
    3534        int i = req->current_idx;
    3635        uint8_t *outhdr;
    3736        DATA_BLOB outbody;
    38         size_t expected_body_size = 0x18;
    39         size_t body_size;
    4037        uint16_t in_flags;
    4138        uint64_t in_file_id_persistent;
    4239        uint64_t in_file_id_volatile;
     40        struct files_struct *in_fsp;
    4341        NTSTATUS status;
    4442
    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);
    4846        }
    49 
    5047        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         }
    5648
    5749        outbody = data_blob_talloc(req->out.vector, NULL, 0x3C);
     
    6456        in_file_id_volatile     = BVAL(inbody, 0x10);
    6557
    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) {
    6960                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    7061        }
    7162
    7263        status = smbd_smb2_close(req,
     64                                in_fsp,
    7365                                in_flags,
    74                                 in_file_id_volatile,
    7566                                &outbody);
    7667        if (!NT_STATUS_IS_OK(status)) {
     
    8374
    8475static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
     76                                struct files_struct *fsp,
    8577                                uint16_t in_flags,
    86                                 uint64_t in_file_id_volatile,
    8778                                DATA_BLOB *outbody)
    8879{
     
    9081        struct smb_request *smbreq;
    9182        connection_struct *conn = req->tcon->compat_conn;
    92         files_struct *fsp;
    9383        struct smb_filename *smb_fname = NULL;
    9484        struct timespec mdate_ts, adate_ts, cdate_ts, create_date_ts;
     
    10494        ZERO_STRUCT(cdate_ts);
    10595
    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));
    10898
    10999        smbreq = smbd_smb2_fake_smb_request(req);
    110100        if (smbreq == NULL) {
    111101                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;
    123102        }
    124103
  • vendor/current/source3/smbd/smb2_create.c

    r740 r746  
    101101        const uint8_t *inbody;
    102102        int i = smb2req->current_idx;
    103         size_t expected_body_size = 0x39;
    104         size_t body_size;
    105103        uint8_t in_oplock_level;
    106104        uint32_t in_impersonation_level;
     
    128126        struct tevent_req *tsubreq;
    129127
    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        }
    134132        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         }
    140133
    141134        in_oplock_level         = CVAL(inbody, 0x03);
     
    159152         */
    160153
    161         dyn_offset = SMB2_HDR_BODY + (body_size & 0xFFFFFFFE);
     154        dyn_offset = SMB2_HDR_BODY + smb2req->in.vector[i+1].iov_len;
    162155
    163156        if (in_name_offset == 0 && in_name_length == 0) {
     
    218211        if (!ok) {
    219212                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);
    220221        }
    221222
     
    386387        struct smbd_smb2_request *smb2req;
    387388        struct smb_request *smb1req;
     389        bool open_was_deferred;
    388390        struct timed_event *te;
    389391        struct tevent_immediate *im;
     
    538540                if (exta) {
    539541                        if (dhnc) {
    540                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     542                                tevent_req_nterror(req,NT_STATUS_OBJECT_NAME_NOT_FOUND);
    541543                                return tevent_req_post(req, ev);
    542544                        }
     
    553555                if (mxac) {
    554556                        if (dhnc) {
    555                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     557                                tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    556558                                return tevent_req_post(req, ev);
    557559                        }
     
    571573
    572574                        if (dhnc) {
    573                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     575                                tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    574576                                return tevent_req_post(req, ev);
    575577                        }
     
    593595                if (dhnq) {
    594596                        if (dhnc) {
    595                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     597                                tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    596598                                return tevent_req_post(req, ev);
    597599                        }
     
    619621                if (alsi) {
    620622                        if (dhnc) {
    621                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     623                                tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    622624                                return tevent_req_post(req, ev);
    623625                        }
     
    636638
    637639                        if (dhnc) {
    638                                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     640                                tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    639641                                return tevent_req_post(req, ev);
    640642                        }
     
    821823                                        result->fsp_name));
    822824        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));
    825827        state->out_end_of_file = result->fsp_name->st.st_ex_size;
    826828        if (state->out_file_attributes == 0) {
    827829                state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
    828830        }
    829         state->out_file_id_persistent = result->fnum;
     831        state->out_file_id_persistent = fsp_persistent_id(result);
    830832        state->out_file_id_volatile = result->fnum;
    831833        state->out_context_blobs = out_context_blobs;
     
    964966        }
    965967        /* It's not in progress if there's no timeout event. */
    966         if (!state->te) {
     968        if (!state->open_was_deferred) {
    967969                return false;
    968970        }
     
    995997                (unsigned long long)mid ));
    996998
     999        state->open_was_deferred = false;
    9971000        /* Ensure we don't have any outstanding timer event. */
    9981001        TALLOC_FREE(state->te);
     
    12381241                                true) ));
    12391242
     1243        state->open_was_deferred = true;
    12401244        state->te = event_add_timed(smb2req->sconn->smb2.event_ctx,
    12411245                                state,
  • vendor/current/source3/smbd/smb2_find.c

    r740 r746  
    2929                                              struct tevent_context *ev,
    3030                                              struct smbd_smb2_request *smb2req,
     31                                              struct files_struct *in_fsp,
    3132                                              uint8_t in_file_info_class,
    3233                                              uint8_t in_flags,
    3334                                              uint32_t in_file_index,
    34                                               uint64_t in_file_id_volatile,
    3535                                              uint32_t in_output_buffer_length,
    3636                                              const char *in_file_name);
     
    4242NTSTATUS smbd_smb2_request_process_find(struct smbd_smb2_request *req)
    4343{
    44         const uint8_t *inhdr;
     44        NTSTATUS status;
    4545        const uint8_t *inbody;
    4646        int i = req->current_idx;
    47         size_t expected_body_size = 0x21;
    48         size_t body_size;
    4947        uint8_t in_file_info_class;
    5048        uint8_t in_flags;
     
    5250        uint64_t in_file_id_persistent;
    5351        uint64_t in_file_id_volatile;
     52        struct files_struct *in_fsp;
    5453        uint16_t in_file_name_offset;
    5554        uint16_t in_file_name_length;
     
    6160        bool ok;
    6261
    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        }
    6866        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         }
    7467
    7568        in_file_info_class              = CVAL(inbody, 0x02);
     
    8578                /* This is ok */
    8679        } else if (in_file_name_offset !=
    87                    (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {
     80                   (SMB2_HDR_BODY + req->in.vector[i+1].iov_len)) {
    8881                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
    8982        }
     
    116109        }
    117110
    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) {
    121121                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    122122        }
    123123
    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,
    127126                                     in_file_info_class,
    128127                                     in_flags,
    129128                                     in_file_index,
    130                                      in_file_id_volatile,
    131129                                     in_output_buffer_length,
    132130                                     in_file_name_string);
     
    208206                                              struct tevent_context *ev,
    209207                                              struct smbd_smb2_request *smb2req,
     208                                              struct files_struct *fsp,
    210209                                              uint8_t in_file_info_class,
    211210                                              uint8_t in_flags,
    212211                                              uint32_t in_file_index,
    213                                               uint64_t in_file_id_volatile,
    214212                                              uint32_t in_output_buffer_length,
    215213                                              const char *in_file_name)
     
    219217        struct smb_request *smbreq;
    220218        connection_struct *conn = smb2req->tcon->compat_conn;
    221         files_struct *fsp;
    222219        NTSTATUS status;
    223220        NTSTATUS empty_status;
     
    242239        state->out_output_buffer = data_blob_null;
    243240
    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));
    246243
    247244        smbreq = smbd_smb2_fake_smb_request(smb2req);
     
    250247        }
    251248
    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 
    266249        if (!fsp->is_directory) {
    267250                tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
     
    282265        }
    283266
    284         if (in_output_buffer_length > 0x10000) {
     267        if (in_output_buffer_length > smb2req->sconn->smb2.max_trans) {
    285268                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    286269                return tevent_req_post(req, ev);
  • vendor/current/source3/smbd/smb2_flush.c

    r740 r746  
    2828                                               struct tevent_context *ev,
    2929                                               struct smbd_smb2_request *smb2req,
    30                                                uint64_t in_file_id_volatile);
     30                                               struct files_struct *fsp);
    3131static NTSTATUS smbd_smb2_flush_recv(struct tevent_req *req);
    3232
     
    3434NTSTATUS smbd_smb2_request_process_flush(struct smbd_smb2_request *req)
    3535{
    36         const uint8_t *inhdr;
     36        NTSTATUS status;
    3737        const uint8_t *inbody;
    3838        int i = req->current_idx;
    39         size_t expected_body_size = 0x18;
    40         size_t body_size;
    4139        uint64_t in_file_id_persistent;
    4240        uint64_t in_file_id_volatile;
     41        struct files_struct *in_fsp;
    4342        struct tevent_req *subreq;
    4443
    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);
    4847        }
    49 
    5048        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         }
    5649
    5750        in_file_id_persistent   = BVAL(inbody, 0x08);
    5851        in_file_id_volatile     = BVAL(inbody, 0x10);
    5952
    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) {
    6355                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    6456        }
    6557
    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);
    7060        if (subreq == NULL) {
    7161                return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     
    9686        }
    9787
    98         outbody = data_blob_talloc(req->out.vector, NULL, 0x10);
     88        outbody = data_blob_talloc(req->out.vector, NULL, 0x04);
    9989        if (outbody.data == NULL) {
    10090                error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     
    125115                                               struct tevent_context *ev,
    126116                                               struct smbd_smb2_request *smb2req,
    127                                                uint64_t in_file_id_volatile)
     117                                               struct files_struct *fsp)
    128118{
    129119        struct tevent_req *req;
     
    131121        NTSTATUS status;
    132122        struct smb_request *smbreq;
    133         files_struct *fsp;
    134123
    135124        req = tevent_req_create(mem_ctx, &state,
     
    140129        state->smb2req = smb2req;
    141130
    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));
    144133
    145134        smbreq = smbd_smb2_fake_smb_request(smb2req);
     
    150139        if (IS_IPC(smbreq->conn)) {
    151140                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);
    166141                return tevent_req_post(req, ev);
    167142        }
  • vendor/current/source3/smbd/smb2_getinfo.c

    r740 r746  
    3030                                                 struct tevent_context *ev,
    3131                                                 struct smbd_smb2_request *smb2req,
     32                                                 struct files_struct *in_fsp,
    3233                                                 uint8_t in_info_type,
    3334                                                 uint8_t in_file_info_class,
     
    3536                                                 DATA_BLOB in_input_buffer,
    3637                                                 uint32_t in_additional_information,
    37                                                  uint32_t in_flags,
    38                                                  uint64_t in_file_id_volatile);
     38                                                 uint32_t in_flags);
    3939static NTSTATUS smbd_smb2_getinfo_recv(struct tevent_req *req,
    4040                                       TALLOC_CTX *mem_ctx,
     
    4545NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req)
    4646{
    47         const uint8_t *inhdr;
     47        NTSTATUS status;
    4848        const uint8_t *inbody;
    4949        int i = req->current_idx;
    50         size_t expected_body_size = 0x29;
    51         size_t body_size;
    5250        uint8_t in_info_type;
    5351        uint8_t in_file_info_class;
     
    6058        uint64_t in_file_id_persistent;
    6159        uint64_t in_file_id_volatile;
     60        struct files_struct *in_fsp;
    6261        struct tevent_req *subreq;
    6362
    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        }
    6967        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         }
    7568
    7669        in_info_type                    = CVAL(inbody, 0x02);
     
    8881                /* This is ok */
    8982        } else if (in_input_buffer_offset !=
    90                    (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {
     83                   (SMB2_HDR_BODY + req->in.vector[i+1].iov_len)) {
    9184                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
    9285        }
     
    9992        in_input_buffer.length = in_input_buffer_length;
    10093
    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) {
    104103                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    105104        }
    106105
    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,
    110108                                        in_info_type,
    111109                                        in_file_info_class,
     
    113111                                        in_input_buffer,
    114112                                        in_additional_information,
    115                                         in_flags,
    116                                         in_file_id_volatile);
     113                                        in_flags);
    117114        if (subreq == NULL) {
    118115                return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     
    236233                                                 struct tevent_context *ev,
    237234                                                 struct smbd_smb2_request *smb2req,
     235                                                 struct files_struct *fsp,
    238236                                                 uint8_t in_info_type,
    239237                                                 uint8_t in_file_info_class,
     
    241239                                                 DATA_BLOB in_input_buffer,
    242240                                                 uint32_t in_additional_information,
    243                                                  uint32_t in_flags,
    244                                                  uint64_t in_file_id_volatile)
     241                                                 uint32_t in_flags)
    245242{
    246243        struct tevent_req *req;
     
    248245        struct smb_request *smbreq;
    249246        connection_struct *conn = smb2req->tcon->compat_conn;
    250         files_struct *fsp;
    251247        NTSTATUS status;
    252248
     
    260256        state->out_output_buffer = data_blob_null;
    261257
    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));
    264260
    265261        smbreq = smbd_smb2_fake_smb_request(smb2req);
    266262        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);
    281263                return tevent_req_post(req, ev);
    282264        }
  • vendor/current/source3/smbd/smb2_ioctl.c

    r740 r746  
    3030                                               struct tevent_context *ev,
    3131                                               struct smbd_smb2_request *smb2req,
     32                                               struct files_struct *in_fsp,
    3233                                               uint32_t in_ctl_code,
    33                                                uint64_t in_file_id_volatile,
    3434                                               DATA_BLOB in_input,
    3535                                               uint32_t in_max_output,
     
    4242NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
    4343{
    44         const uint8_t *inhdr;
     44        NTSTATUS status;
    4545        const uint8_t *inbody;
    4646        int i = req->current_idx;
    47         size_t expected_body_size = 0x39;
    48         size_t body_size;
    4947        uint32_t in_ctl_code;
    5048        uint64_t in_file_id_persistent;
    5149        uint64_t in_file_id_volatile;
     50        struct files_struct *in_fsp = NULL;
    5251        uint32_t in_input_offset;
    5352        uint32_t in_input_length;
     
    5756        struct tevent_req *subreq;
    5857
    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        }
    6462        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         }
    7063
    7164        in_ctl_code             = IVAL(inbody, 0x04);
     
    7770        in_flags                = IVAL(inbody, 0x30);
    7871
    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))) {
    8082                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
    8183        }
     
    8890        in_input_buffer.length = in_input_length;
    8991
    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;
    97120        }
    98121
    99122        subreq = smbd_smb2_ioctl_send(req,
    100123                                      req->sconn->smb2.event_ctx,
    101                                       req,
     124                                      req, in_fsp,
    102125                                      in_ctl_code,
    103                                       in_file_id_volatile,
    104126                                      in_input_buffer,
    105127                                      in_max_output_length,
     
    222244                                               struct tevent_context *ev,
    223245                                               struct smbd_smb2_request *smb2req,
     246                                               struct files_struct *fsp,
    224247                                               uint32_t in_ctl_code,
    225                                                uint64_t in_file_id_volatile,
    226248                                               DATA_BLOB in_input,
    227249                                               uint32_t in_max_output,
     
    231253        struct smbd_smb2_ioctl_state *state;
    232254        struct smb_request *smbreq;
    233         files_struct *fsp = NULL;
    234255        struct tevent_req *subreq;
    235256
     
    241262        state->smb2req = smb2req;
    242263        state->smbreq = NULL;
    243         state->fsp = NULL;
     264        state->fsp = fsp;
    244265        state->in_input = in_input;
    245266        state->in_max_output = in_max_output;
    246267        state->out_output = data_blob_null;
    247268
    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));
    250273
    251274        smbreq = smbd_smb2_fake_smb_request(smb2req);
     
    254277        }
    255278        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         }
    273279
    274280        switch (in_ctl_code) {
     
    379385                return req;
    380386
    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;
    399390                NTSTATUS status;
    400391
     
    404395                }
    405396
    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;
    435415                        } 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;
    440417                        }
    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);
    503421                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        }
    513423        }
    514424
  • vendor/current/source3/smbd/smb2_keepalive.c

    r740 r746  
    2626NTSTATUS smbd_smb2_request_process_keepalive(struct smbd_smb2_request *req)
    2727{
    28         const uint8_t *inbody;
    29         int i = req->current_idx;
    3028        DATA_BLOB outbody;
    31         size_t expected_body_size = 0x04;
    32         size_t body_size;
     29        NTSTATUS status;
    3330
    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);
    4334        }
    4435
  • vendor/current/source3/smbd/smb2_lock.c

    r740 r746  
    4747                                                 struct tevent_context *ev,
    4848                                                 struct smbd_smb2_request *smb2req,
     49                                                 struct files_struct *in_fsp,
    4950                                                 uint32_t in_smbpid,
    50                                                  uint64_t in_file_id_volatile,
    5151                                                 uint16_t in_lock_count,
    5252                                                 struct smbd_smb2_lock_element *in_locks);
     
    5959        const uint8_t *inbody;
    6060        const int i = req->current_idx;
    61         size_t expected_body_size = 0x30;
    62         size_t body_size;
    6361        uint32_t in_smbpid;
    6462        uint16_t in_lock_count;
    6563        uint64_t in_file_id_persistent;
    6664        uint64_t in_file_id_volatile;
     65        struct files_struct *in_fsp;
    6766        struct smbd_smb2_lock_element *in_locks;
    6867        struct tevent_req *subreq;
    6968        const uint8_t *lock_buffer;
    7069        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        }
    7276        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 
    7777        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         }
    8378
    8479        in_smbpid                       = IVAL(inhdr, SMB2_HDR_PID);
     
    9590        if (((in_lock_count - 1) * 0x18) > req->in.vector[i+2].iov_len) {
    9691                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);
    10392        }
    10493
     
    128117        }
    129118
    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,
    133126                                     in_smbpid,
    134                                      in_file_id_volatile,
    135127                                     in_lock_count,
    136128                                     in_locks);
     
    214206                                                 struct tevent_context *ev,
    215207                                                 struct smbd_smb2_request *smb2req,
     208                                                 struct files_struct *fsp,
    216209                                                 uint32_t in_smbpid,
    217                                                  uint64_t in_file_id_volatile,
    218210                                                 uint16_t in_lock_count,
    219211                                                 struct smbd_smb2_lock_element *in_locks)
     
    222214        struct smbd_smb2_lock_state *state;
    223215        struct smb_request *smb1req;
    224         connection_struct *conn = smb2req->tcon->compat_conn;
    225         files_struct *fsp;
    226216        int32_t timeout = -1;
    227217        bool isunlock = false;
     
    245235        state->smb1req = smb1req;
    246236
    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));
    263239
    264240        locks = talloc_array(state, struct smbd_lock_element, in_lock_count);
     
    342318                }
    343319
    344                 locks[i].smblctx = in_file_id_volatile;
     320                locks[i].smblctx = fsp->fnum;
    345321                locks[i].offset = in_locks[i].offset;
    346322                locks[i].count  = in_locks[i].length;
     
    873849                files_struct *fsp_curr = NULL;
    874850                int i = smb2req->current_idx;
    875                 uint64_t in_file_id_volatile;
    876851                struct blocking_lock_record *blr = NULL;
    877852                const uint8_t *inhdr;
    878                 const uint8_t *inbody;
    879853
    880854                nextreq = smb2req->next;
     
    894868                        continue;
    895869                }
    896 
    897                 inbody = (const uint8_t *)smb2req->in.vector[i+1].iov_base;
    898                 in_file_id_volatile = BVAL(inbody, 0x10);
    899870
    900871                state = tevent_req_data(smb2req->subreq,
     
    905876                }
    906877
    907                 fsp_curr = file_fsp(state->smb1req, (uint16_t)in_file_id_volatile);
     878                fsp_curr = smb2req->compat_chain_fsp;
    908879                if (fsp_curr == NULL) {
    909880                        /* Strange - is this even possible ? */
  • vendor/current/source3/smbd/smb2_negprot.c

    r740 r746  
    6262NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
    6363{
     64        NTSTATUS status;
    6465        const uint8_t *inbody;
    6566        const uint8_t *indyn = NULL;
     
    7071        uint16_t security_offset;
    7172        DATA_BLOB security_buffer;
    72         size_t expected_body_size = 0x24;
    73         size_t body_size;
    7473        size_t expected_dyn_size = 0;
    7574        size_t c;
     
    7877        uint16_t dialect = 0;
    7978        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();
    8083
    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);
    8587        }
    86 
    8788        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         }
    9389
    9490        dialect_count = SVAL(inbody, 0x02);
     
    140136        }
    141137
     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
    142148        security_offset = SMB2_HDR_BODY + 0x40;
    143149
     
    165171        SIVAL(outbody.data, 0x18,
    166172              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 */
    170176        SBVAL(outbody.data, 0x28, 0);           /* system time */
    171177        SBVAL(outbody.data, 0x30, 0);           /* server start time */
     
    179185
    180186        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;
    181190
    182191        return smbd_smb2_request_done(req, outbody, &outdyn);
  • vendor/current/source3/smbd/smb2_notify.c

    r740 r746  
    3737                                                struct tevent_context *ev,
    3838                                                struct smbd_smb2_request *smb2req,
     39                                                struct files_struct *in_fsp,
    3940                                                uint16_t in_flags,
    4041                                                uint32_t in_output_buffer_length,
    41                                                 uint64_t in_file_id_volatile,
    4242                                                uint64_t in_completion_filter);
    4343static NTSTATUS smbd_smb2_notify_recv(struct tevent_req *req,
     
    4848NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req)
    4949{
    50         const uint8_t *inhdr;
     50        NTSTATUS status;
    5151        const uint8_t *inbody;
    5252        int i = req->current_idx;
    53         size_t expected_body_size = 0x20;
    54         size_t body_size;
    5553        uint16_t in_flags;
    5654        uint32_t in_output_buffer_length;
    5755        uint64_t in_file_id_persistent;
    5856        uint64_t in_file_id_volatile;
     57        struct files_struct *in_fsp;
    5958        uint64_t in_completion_filter;
    6059        struct tevent_req *subreq;
    6160
    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        }
    6765        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         }
    7366
    7467        in_flags                = SVAL(inbody, 0x02);
     
    8275         * Windows 2008 uses 0x00080000
    8376         */
    84         if (in_output_buffer_length > lp_smb2_max_trans()) {
     77        if (in_output_buffer_length > req->sconn->smb2.max_trans) {
    8578                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
    8679        }
    8780
    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) {
    9183                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    9284        }
    9385
    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,
    9788                                       in_flags,
    9889                                       in_output_buffer_length,
    99                                        in_file_id_volatile,
    10090                                       in_completion_filter);
    10191        if (subreq == NULL) {
     
    194184                                                struct tevent_context *ev,
    195185                                                struct smbd_smb2_request *smb2req,
     186                                                struct files_struct *fsp,
    196187                                                uint16_t in_flags,
    197188                                                uint32_t in_output_buffer_length,
    198                                                 uint64_t in_file_id_volatile,
    199189                                                uint64_t in_completion_filter)
    200190{
     
    203193        struct smb_request *smbreq;
    204194        connection_struct *conn = smb2req->tcon->compat_conn;
    205         files_struct *fsp;
    206195        bool recursive = (in_flags & 0x0001) ? true : false;
    207196        NTSTATUS status;
     
    217206        state->im = NULL;
    218207
    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));
    221210
    222211        smbreq = smbd_smb2_fake_smb_request(smb2req);
     
    227216        state->smbreq = smbreq;
    228217        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         }
    243218
    244219        {
     
    383358                                               struct smbd_smb2_notify_state);
    384359
     360        state->smb2req->cancelled = true;
    385361        smbd_notify_cancel_by_smbreq(state->smbreq);
    386362
    387         state->smb2req->cancelled = true;
    388         tevent_req_done(req);
    389363        return true;
    390364}
  • vendor/current/source3/smbd/smb2_read.c

    r740 r746  
    3131                                              struct tevent_context *ev,
    3232                                              struct smbd_smb2_request *smb2req,
     33                                              struct files_struct *in_fsp,
    3334                                              uint32_t in_smbpid,
    34                                               uint64_t in_file_id_volatile,
    3535                                              uint32_t in_length,
    3636                                              uint64_t in_offset,
     
    4545NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req)
    4646{
     47        NTSTATUS status;
    4748        const uint8_t *inhdr;
    4849        const uint8_t *inbody;
    4950        int i = req->current_idx;
    50         size_t expected_body_size = 0x31;
    51         size_t body_size;
    5251        uint32_t in_smbpid;
    5352        uint32_t in_length;
     
    5554        uint64_t in_file_id_persistent;
    5655        uint64_t in_file_id_volatile;
     56        struct files_struct *in_fsp;
    5757        uint32_t in_minimum_count;
    5858        uint32_t in_remaining_bytes;
    5959        struct tevent_req *subreq;
    6060
     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        }
    6165        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 
    6666        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         }
    7267
    7368        in_smbpid = IVAL(inhdr, SMB2_HDR_PID);
     
    8176
    8277        /* check the max read size */
    83         if (in_length > lp_smb2_max_read()) {
     78        if (in_length > req->sconn->smb2.max_read) {
    8479                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));
    8681                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
    8782        }
    8883
    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) {
    9286                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    9387        }
    9488
    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,
    9891                                     in_smbpid,
    99                                      in_file_id_volatile,
    10092                                     in_length,
    10193                                     in_offset,
     
    177169        struct smbd_smb2_request *smb2req;
    178170        files_struct *fsp;
    179         uint64_t in_file_id_volatile;
    180171        uint32_t in_length;
    181172        uint64_t in_offset;
     
    259250
    260251        init_strict_lock_struct(fsp,
    261                                 state->in_file_id_volatile,
     252                                fsp->fnum,
    262253                                in_offset,
    263254                                in_length,
     
    374365                                              struct tevent_context *ev,
    375366                                              struct smbd_smb2_request *smb2req,
     367                                              struct files_struct *fsp,
    376368                                              uint32_t in_smbpid,
    377                                               uint64_t in_file_id_volatile,
    378369                                              uint32_t in_length,
    379370                                              uint64_t in_offset,
     
    386377        struct smb_request *smbreq = NULL;
    387378        connection_struct *conn = smb2req->tcon->compat_conn;
    388         files_struct *fsp = NULL;
    389379        ssize_t nread = -1;
    390380        struct lock_struct lock;
     
    403393        state->out_remaining = 0;
    404394
    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));
    407397
    408398        smbreq = smbd_smb2_fake_smb_request(smb2req);
     
    411401        }
    412402
    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         }
    426403        if (fsp->is_directory) {
    427404                tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
     
    430407
    431408        state->fsp = fsp;
    432         state->in_file_id_volatile = in_file_id_volatile;
    433409
    434410        if (IS_IPC(smbreq->conn)) {
     
    493469
    494470        init_strict_lock_struct(fsp,
    495                                 in_file_id_volatile,
     471                                fsp->fnum,
    496472                                in_offset,
    497473                                in_length,
     
    533509        SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
    534510
    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 "
    536512                "len=%llu returned %lld\n",
    537513                fsp_str_dbg(fsp),
    538                 (unsigned long long)in_file_id_volatile,
     514                fsp->fnum,
    539515                (unsigned long long)in_offset,
    540516                (unsigned long long)in_length,
  • vendor/current/source3/smbd/smb2_server.c

    r740 r746  
    115115        sconn->smb2.sessions.list = NULL;
    116116        sconn->smb2.seqnum_low = 0;
    117         sconn->smb2.credits_granted = 0;
     117        sconn->smb2.seqnum_range = 1;
     118        sconn->smb2.credits_granted = 1;
    118119        sconn->smb2.max_credits = lp_smb2_max_credits();
    119120        sconn->smb2.credits_bitmap = bitmap_talloc(sconn,
    120                         DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR*sconn->smb2.max_credits);
     121                                                   sconn->smb2.max_credits);
    121122        if (sconn->smb2.credits_bitmap == NULL) {
    122123                return NT_STATUS_NO_MEMORY;
     
    207208        req->parent     = parent;
    208209
     210        req->last_session_id = UINT64_MAX;
     211        req->last_tid = UINT32_MAX;
     212
    209213        talloc_set_destructor(parent, smbd_smb2_request_parent_destructor);
    210214        talloc_set_destructor(req, smbd_smb2_request_destructor);
     
    296300}
    297301
     302static 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
    298374static bool smb2_validate_message_id(struct smbd_server_connection *sconn,
    299375                                const uint8_t *inhdr)
    300376{
    301377        uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
    302         struct bitmap *credits_bm = sconn->smb2.credits_bitmap;
    303378        uint16_t opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
    304         unsigned int bitmap_offset;
     379        bool ok;
    305380
    306381        if (opcode == SMB2_OP_CANCEL) {
     
    309384        }
    310385
    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));
    319401                return false;
    320402        }
    321403
    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 */
    324410        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's
    340                    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         }
    352411
    353412        return true;
     
    358417        int count;
    359418        int idx;
    360         bool compound_related = false;
    361419
    362420        count = req->in.vector_count;
     
    369427        for (idx=1; idx < count; idx += 3) {
    370428                const uint8_t *inhdr = NULL;
    371                 uint32_t flags;
    372429
    373430                if (req->in.vector[idx].iov_len != SMB2_HDR_BODY) {
     
    388445                if (!smb2_validate_message_id(req->sconn, inhdr)) {
    389446                        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 the
    396                          * SMB2_HDR_FLAG_CHAINED flag set
    397                          */
    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. unrelated
    405                          * compounded requests
    406                          */
    407                         if (flags & SMB2_HDR_FLAG_CHAINED) {
    408                                 compound_related = true;
    409                         }
    410                 } else if (idx > 4) {
    411 #if 0
    412                         /*
    413                          * It seems the this tests are wrong
    414                          * see the SMB2-COMPOUND test
    415                          */
    416 
    417                         /*
    418                          * all other requests should match the 2nd one
    419                          */
    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 #endif
    434447                }
    435448        }
     
    446459        uint16_t credits_requested;
    447460        uint32_t out_flags;
     461        uint16_t cmd;
     462        NTSTATUS out_status;
    448463        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);
    450485        credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
    451486        out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
     487        out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
    452488
    453489        SMB_ASSERT(sconn->smb2.max_credits >= sconn->smb2.credits_granted);
     
    459495                 * credits on the final response.
    460496                 */
    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                 */
    492531                credits_granted = 1;
    493532        }
     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);
    494558
    495559        SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
    496560        sconn->smb2.credits_granted += credits_granted;
     561        sconn->smb2.seqnum_range += credits_granted;
    497562
    498563        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",
    500566                (unsigned int)credits_requested,
    501567                (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));
    503574}
    504575
     
    507578{
    508579        int count, idx;
     580        uint16_t total_credits = 0;
    509581
    510582        count = outreq->out.vector_count;
    511583
    512584        for (idx=1; idx < count; idx += 3) {
     585                uint8_t *outhdr = (uint8_t *)outreq->out.vector[idx].iov_base;
    513586                smb2_set_operation_credit(outreq->sconn,
    514587                        &inreq->in.vector[idx],
    515588                        &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                }
    516598        }
    517599}
     
    570652                SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID,     SMB2_MAGIC);
    571653                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));
    573656                SIVAL(outhdr, SMB2_HDR_STATUS,
    574657                      NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
     
    586669                SBVAL(outhdr, SMB2_HDR_SESSION_ID,
    587670                      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);
    589673
    590674                /* setup error body header */
     
    864948                 * Cancel the outstanding request.
    865949                 */
    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);
    867955                return smbd_smb2_request_error(req,
    868                         NT_STATUS_INSUFFICIENT_RESOURCES);
     956                        NT_STATUS_INTERNAL_ERROR);
    869957        }
    870958
     
    885973                        return status;
    886974                }
     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;
    887989        }
    888990
    889991        /* Don't return an intermediate packet on a pipe read/write. */
    890992        if (req->tcon && req->tcon->compat_conn && IS_IPC(req->tcon->compat_conn)) {
    891                 return NT_STATUS_OK;
     993                goto ipc_out;
    892994        }
    893995
     
    9291031        SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(reqhdr, SMB2_HDR_OPCODE));
    9301032
    931         SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
     1033        SIVAL(hdr, SMB2_HDR_FLAGS, flags);
    9321034        SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
    9331035        SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
     
    9521054                        &state->vector[1]);
    9531055
     1056        SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
     1057
    9541058        if (req->do_signing) {
    9551059                status = smb2_signing_sign_pdu(req->session->session_key,
     
    9771081        /* Note we're going async with this request. */
    9781082        req->async = true;
     1083
     1084  ipc_out:
    9791085
    9801086        /*
     
    10251131                req->out.vector_count);
    10261132
    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
    10401149        return NT_STATUS_OK;
    10411150}
     
    11021211}
    11031212
     1213NTSTATUS 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
    11041268NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
    11051269{
     
    11251289                (unsigned long long)mid));
    11261290
     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
    11271311        allowed_flags = SMB2_HDR_FLAG_CHAINED |
    11281312                        SMB2_HDR_FLAG_SIGNED |
     
    11451329        session_status = smbd_smb2_request_check_session(req);
    11461330
     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
    11471343        req->do_signing = false;
    11481344        if (flags & SMB2_HDR_FLAG_SIGNED) {
     
    11571353                        return smbd_smb2_request_error(req, status);
    11581354                }
     1355        } else if (opcode == SMB2_OP_CANCEL) {
     1356                /* Cancel requests are allowed to skip the signing */
    11591357        } else if (req->session && req->session->do_signing) {
    11601358                return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
     
    11621360
    11631361        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;
    11761364        }
    11771365
     
    16221810        }
    16231811
     1812        if (req->compound_related) {
     1813                req->compound_related = false;
     1814                req->sconn->smb2.compound_related_in_progress = false;
     1815        }
     1816
    16241817        smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
    16251818
    1626         /* Set credit for this operation (zero credits if this
     1819        /* Set credit for these operations (zero credits if this
    16271820           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);
    16311822
    16321823        if (req->do_signing) {
     
    16721863}
    16731864
     1865static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn);
     1866
    16741867void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
    16751868                                        struct tevent_immediate *im,
     
    16901883
    16911884        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);
    16921891        if (!NT_STATUS_IS_OK(status)) {
    16931892                smbd_server_connection_terminate(sconn, nt_errstr(status));
     
    17031902        int ret;
    17041903        int sys_errno;
     1904        NTSTATUS status;
    17051905
    17061906        ret = tstream_writev_queue_recv(subreq, &sys_errno);
     
    17081908        TALLOC_FREE(req);
    17091909        if (ret == -1) {
    1710                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
     1910                status = map_nt_error_from_unix(sys_errno);
    17111911                DEBUG(2,("smbd_smb2_request_writev_done: client write error %s\n",
    17121912                        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)) {
    17131919                smbd_server_connection_terminate(sconn, nt_errstr(status));
    17141920                return;
     
    18532059
    18542060        /*
    1855          * if a request fails, all other remaining
    1856          * compounded requests should fail too
     2061         * Note: Even if there is an error, continue to process the request.
     2062         * per MS-SMB2.
    18572063         */
    1858         req->next_status = NT_STATUS_INVALID_PARAMETER;
    18592064
    18602065        return smbd_smb2_request_done_ex(req, status, body, info, __location__);
     
    23182523static void smbd_smb2_request_incoming(struct tevent_req *subreq);
    23192524
     2525static 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
    23202569void smbd_smb2_first_negprot(struct smbd_server_connection *sconn,
    23212570                             const uint8_t *inbuf, size_t size)
     
    23232572        NTSTATUS status;
    23242573        struct smbd_smb2_request *req = NULL;
    2325         struct tevent_req *subreq;
    23262574
    23272575        DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
     
    23402588        }
    23412589
     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
    23422596        status = smbd_smb2_request_setup_out(req);
    23432597        if (!NT_STATUS_IS_OK(status)) {
     
    23522606        }
    23532607
    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));
    23582611                return;
    23592612        }
    2360         tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
    23612613
    23622614        sconn->num_requests++;
     
    24102662
    24112663next:
    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));
    24162667                return;
    24172668        }
    2418         tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
    24192669
    24202670        sconn->num_requests++;
  • vendor/current/source3/smbd/smb2_sesssetup.c

    r740 r746  
    4848        DATA_BLOB outbody;
    4949        DATA_BLOB outdyn;
    50         size_t expected_body_size = 0x19;
    51         size_t body_size;
    5250        uint64_t in_session_id;
    5351        uint8_t in_security_mode;
     
    5856        uint64_t out_session_id;
    5957        uint16_t out_security_offset;
    60         DATA_BLOB out_security_buffer;
     58        DATA_BLOB out_security_buffer = data_blob_null;
    6159        NTSTATUS status;
    6260
     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        }
    6365        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 
    6966        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         }
    7567
    7668        in_security_offset = SVAL(inbody, 0x0C);
    7769        in_security_length = SVAL(inbody, 0x0E);
    7870
    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)) {
    8072                return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
    8173        }
     
    196188        bool username_was_mapped = false;
    197189        bool map_domainuser_to_guest = false;
     190        bool guest = false;
    198191
    199192        if (!spnego_parse_krb5_wrap(talloc_tos(), *secblob, &ticket, tok_id)) {
     
    272265                /* force no signing */
    273266                session->do_signing = false;
     267                guest = true;
    274268        }
    275269
     
    324318         */
    325319        smb2req->session = session;
    326         if (session->do_signing) {
     320        if (!guest) {
    327321                smb2req->do_signing = true;
    328322        }
     
    478472{
    479473        fstring tmp;
     474        bool guest = false;
    480475
    481476        if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
     
    490485                /* force no signing */
    491486                session->do_signing = false;
     487                guest = true;
    492488        }
    493489
     
    537533         */
    538534        smb2req->session = session;
    539         if (session->do_signing) {
     535        if (!guest) {
    540536                smb2req->do_signing = true;
    541537        }
     
    565561        }
    566562
    567         if (auth.data[0] == ASN1_APPLICATION(0)) {
     563        if (auth.length > 0 && auth.data[0] == ASN1_APPLICATION(0)) {
    568564                /* Might be a second negTokenTarg packet */
    569565                DATA_BLOB secblob_in = data_blob_null;
     
    679675        NTSTATUS status;
    680676        DATA_BLOB secblob_out = data_blob_null;
     677
     678        *out_security_buffer = data_blob_null;
    681679
    682680        if (session->auth_ntlmssp_state == NULL) {
     
    820818{
    821819        const uint8_t *inhdr;
    822         const uint8_t *outhdr;
    823820        int i = req->current_idx;
     821        uint32_t in_flags;
    824822        uint64_t in_session_id;
    825823        void *p;
    826824        struct smbd_smb2_session *session;
    827         bool chained_fixup = false;
     825
     826        req->session = NULL;
     827        req->tcon = NULL;
    828828
    829829        inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
    830830
     831        in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
    831832        in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
    832833
    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;
    851839
    852840        /* lookup an existing session */
     
    866854
    867855        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
    874858        return NT_STATUS_OK;
    875859}
     
    877861NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
    878862{
    879         const uint8_t *inbody;
    880         int i = req->current_idx;
     863        NTSTATUS status;
    881864        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);
    894869        }
    895870
  • vendor/current/source3/smbd/smb2_setinfo.c

    r740 r746  
    3030                                                 struct tevent_context *ev,
    3131                                                 struct smbd_smb2_request *smb2req,
     32                                                 struct files_struct *in_fsp,
    3233                                                 uint8_t in_info_type,
    3334                                                 uint8_t in_file_info_class,
    3435                                                 DATA_BLOB in_input_buffer,
    35                                                  uint32_t in_additional_information,
    36                                                  uint64_t in_file_id_volatile);
     36                                                 uint32_t in_additional_information);
    3737static NTSTATUS smbd_smb2_setinfo_recv(struct tevent_req *req);
    3838
     
    4040NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req)
    4141{
    42         const uint8_t *inhdr;
     42        NTSTATUS status;
    4343        const uint8_t *inbody;
    4444        int i = req->current_idx;
    45         size_t expected_body_size = 0x21;
    46         size_t body_size;
    4745        uint8_t in_info_type;
    4846        uint8_t in_file_info_class;
     
    5351        uint64_t in_file_id_persistent;
    5452        uint64_t in_file_id_volatile;
     53        struct files_struct *in_fsp;
    5554        struct tevent_req *subreq;
    5655
    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        }
    6260        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         }
    6861
    6962        in_info_type                    = CVAL(inbody, 0x02);
     
    7972                /* This is ok */
    8073        } else if (in_input_buffer_offset !=
    81                    (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {
     74                   (SMB2_HDR_BODY + req->in.vector[i+1].iov_len)) {
    8275                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
    8376        }
     
    9083        in_input_buffer.length = in_input_buffer_length;
    9184
    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) {
    9591                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    9692        }
    9793
    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,
    10196                                        in_info_type,
    10297                                        in_file_info_class,
    10398                                        in_input_buffer,
    104                                         in_additional_information,
    105                                         in_file_id_volatile);
     99                                        in_additional_information);
    106100        if (subreq == NULL) {
    107101                return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     
    160154                                                 struct tevent_context *ev,
    161155                                                 struct smbd_smb2_request *smb2req,
     156                                                 struct files_struct *fsp,
    162157                                                 uint8_t in_info_type,
    163158                                                 uint8_t in_file_info_class,
    164159                                                 DATA_BLOB in_input_buffer,
    165                                                  uint32_t in_additional_information,
    166                                                  uint64_t in_file_id_volatile)
     160                                                 uint32_t in_additional_information)
    167161{
    168162        struct tevent_req *req = NULL;
     
    170164        struct smb_request *smbreq = NULL;
    171165        connection_struct *conn = smb2req->tcon->compat_conn;
    172         files_struct *fsp = NULL;
    173166        NTSTATUS status;
    174167
     
    180173        state->smb2req = smb2req;
    181174
    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));
    184177
    185178        smbreq = smbd_smb2_fake_smb_request(smb2req);
    186179        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);
    201180                return tevent_req_post(req, ev);
    202181        }
     
    220199                        /* SMB2_FILE_RENAME_INFORMATION_INTERNAL == 0xFF00 + in_file_info_class */
    221200                        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                         }
    228201                }
    229202
     
    326299                }
    327300
    328                 status = set_sd(fsp,
     301                status = set_sd_blob(fsp,
    329302                                in_input_buffer.data,
    330303                                in_input_buffer.length,
  • vendor/current/source3/smbd/smb2_tcon.c

    r740 r746  
    4040        uint8_t *outhdr;
    4141        DATA_BLOB outbody;
    42         size_t expected_body_size = 0x09;
    43         size_t body_size;
    4442        uint16_t in_path_offset;
    4543        uint16_t in_path_length;
     
    5553        bool ok;
    5654
    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        }
    6159        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         }
    6760
    6861        in_path_offset = SVAL(inbody, 0x04);
    6962        in_path_length = SVAL(inbody, 0x06);
    7063
    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)) {
    7265                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
    7366        }
     
    8780        if (!ok) {
    8881                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);
    8990        }
    9091
     
    228229        talloc_set_destructor(tcon, smbd_smb2_tcon_destructor);
    229230
    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,
    232234                                        data_blob_null, "???",
    233235                                        &status);
     
    237239        }
    238240        tcon->compat_conn = talloc_move(tcon, &compat_conn);
    239         tcon->compat_conn->cnum = tcon->tid;
    240241
    241242        if (IS_PRINT(tcon->compat_conn)) {
     
    281282{
    282283        const uint8_t *inhdr;
    283         const uint8_t *outhdr;
    284284        int i = req->current_idx;
     285        uint32_t in_flags;
    285286        uint32_t in_tid;
    286287        void *p;
    287288        struct smbd_smb2_tcon *tcon;
    288         bool chained_fixup = false;
     289
     290        req->tcon = NULL;
    289291
    290292        inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
    291293
     294        in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
    292295        in_tid = IVAL(inhdr, SMB2_HDR_TID);
    293296
    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;
    312302
    313303        /* lookup an existing session */
     
    328318
    329319        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;
    336321
    337322        return NT_STATUS_OK;
     
    340325NTSTATUS smbd_smb2_request_process_tdis(struct smbd_smb2_request *req)
    341326{
    342         const uint8_t *inbody;
    343         int i = req->current_idx;
     327        NTSTATUS status;
    344328        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);
    357333        }
    358334
  • vendor/current/source3/smbd/smb2_write.c

    r740 r746  
    2929                                               struct tevent_context *ev,
    3030                                               struct smbd_smb2_request *smb2req,
     31                                               struct files_struct *in_fsp,
    3132                                               uint32_t in_smbpid,
    32                                                uint64_t in_file_id_volatile,
    3333                                               DATA_BLOB in_data,
    3434                                               uint64_t in_offset,
     
    4040NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req)
    4141{
     42        NTSTATUS status;
    4243        const uint8_t *inhdr;
    4344        const uint8_t *inbody;
    4445        int i = req->current_idx;
    45         size_t expected_body_size = 0x31;
    46         size_t body_size;
    4746        uint32_t in_smbpid;
    4847        uint16_t in_data_offset;
     
    5251        uint64_t in_file_id_persistent;
    5352        uint64_t in_file_id_volatile;
     53        struct files_struct *in_fsp;
    5454        uint32_t in_flags;
    5555        struct tevent_req *subreq;
    5656
     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        }
    5761        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 
    6262        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         }
    6863
    6964        in_smbpid = IVAL(inhdr, SMB2_HDR_PID);
     
    7671        in_flags                = IVAL(inbody, 0x2C);
    7772
    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)) {
    7974                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
    8075        }
     
    8580
    8681        /* 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) {
    8983                DEBUG(2,("smbd_smb2_request_process_write : "
    9084                        "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));
    9386                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
    94 #endif
    9587        }
    9688
     
    9890        in_data_buffer.length = in_data_length;
    9991
    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) {
    10394                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    10495        }
    10596
    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,
    10999                                      in_smbpid,
    110                                       in_file_id_volatile,
    111100                                      in_data_buffer,
    112101                                      in_offset,
     
    225214                                               struct tevent_context *ev,
    226215                                               struct smbd_smb2_request *smb2req,
     216                                               struct files_struct *fsp,
    227217                                               uint32_t in_smbpid,
    228                                                uint64_t in_file_id_volatile,
    229218                                               DATA_BLOB in_data,
    230219                                               uint64_t in_offset,
     
    236225        struct smb_request *smbreq = NULL;
    237226        connection_struct *conn = smb2req->tcon->compat_conn;
    238         files_struct *fsp = NULL;
    239227        ssize_t nwritten;
    240228        struct lock_struct lock;
     
    252240        state->out_count = 0;
    253241
    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));
    256244
    257245        smbreq = smbd_smb2_fake_smb_request(smb2req);
    258246        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);
    273247                return tevent_req_post(req, ev);
    274248        }
     
    325299        if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
    326300                /* Real error in setting up aio. Fail. */
    327                 tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
     301                tevent_req_nterror(req, status);
    328302                return tevent_req_post(req, ev);
    329303        }
     
    331305        /* Fallback to synchronous. */
    332306        init_strict_lock_struct(fsp,
    333                                 in_file_id_volatile,
     307                                fsp->fnum,
    334308                                in_offset,
    335309                                in_data.length,
  • vendor/current/source3/smbd/statcache.c

    r740 r746  
    151151 *
    152152 * @param conn    A connection struct to do the stat() with.
     153 * @param posix_paths Whether to lookup using stat() or lstat()
    153154 * @param name    The path we are attempting to cache, modified by this routine
    154155 *                to be correct as far as the cache can tell us. We assume that
     
    167168
    168169bool stat_cache_lookup(connection_struct *conn,
     170                        bool posix_paths,
    169171                        char **pp_name,
    170172                        char **pp_dirpath,
     
    182184        TALLOC_CTX *ctx = talloc_tos();
    183185        struct smb_filename smb_fname;
     186        int ret;
    184187
    185188        *pp_dirpath = NULL;
     
    284287        smb_fname.base_name = translated_path;
    285288
    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) {
    287296                /* Discard this entry - it doesn't exist in the filesystem. */
    288297                memcache_delete(smbd_memcache(), STAT_CACHE,
  • vendor/current/source3/smbd/trans2.c

    r740 r746  
    863863                reply_outbuf(req, 10, total_sent_thistime + alignment_offset
    864864                             + data_alignment_offset);
    865 
    866                 /*
    867                  * We might have SMBtrans2s in req which was transferred to
    868                  * the outbuf, fix that.
    869                  */
    870                 SCVAL(req->outbuf, smb_com, SMBtrans2);
    871865
    872866                /* Set total params and data to be sent */
     
    10841078        }
    10851079
    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,
    10871082                                         &access_mask, &share_mode,
    10881083                                         &create_disposition,
     
    22712266        struct dptr_struct *dirptr = NULL;
    22722267        struct smbd_server_connection *sconn = req->sconn;
     2268        uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP);
    22732269
    22742270        if (total_params < 13) {
     
    23142310                                goto out;
    23152311                        }
     2312                        ucf_flags |= UCF_UNIX_NAME_LOOKUP;
    23162313                        break;
    23172314                default:
     
    23312328                                    req->flags2 & FLAGS2_DFS_PATHNAMES,
    23322329                                    directory,
    2333                                     (UCF_SAVE_LCOMP |
    2334                                         UCF_ALWAYS_ALLOW_WCARD_LCOMP),
     2330                                    ucf_flags,
    23352331                                    &mask_contains_wcard,
    23362332                                    &smb_dname);
     
    46734669                case SMB_QUERY_FILE_STREAM_INFO:
    46744670                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;
    46774673
    46784674                        DEBUG(10,("smbd_do_qfilepathinfo: "
     
    46834679                        }
    46844680
    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);
    46884683
    46894684                        if (!NT_STATUS_IS_OK(status)) {
     
    51045099                uint32_t name_hash;
    51055100                char *fname = NULL;
     5101                uint32_t ucf_flags = 0;
    51065102
    51075103                /* qpathinfo */
     
    51155111                DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
    51165112
    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                        }
    51205123                }
    51215124
     
    51325135                                        req->flags2 & FLAGS2_DFS_PATHNAMES,
    51335136                                        fname,
    5134                                         0,
     5137                                        ucf_flags,
    51355138                                        NULL,
    51365139                                        &smb_fname);
     
    58195822        /* The set is across all open files on this dev/inode pair. */
    58205823        if (!set_delete_on_close(fsp, delete_on_close,
     5824                                 conn->session_info->security_token,
    58215825                                 &conn->session_info->utok)) {
    58225826                return NT_STATUS_ACCESS_DENIED;
     
    79767980        } else {
    79777981                char *fname = NULL;
     7982                uint32_t ucf_flags = 0;
    79787983
    79797984                /* set path info */
     
    79927997                }
    79937998
     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
    79948006                status = filename_convert(req, conn,
    79958007                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
    79968008                                         fname,
    7997                                          0,
     8009                                         ucf_flags,
    79988010                                         NULL,
    79998011                                         &smb_fname);
     
    88228834        show_msg((char *)req->inbuf);
    88238835
     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
    88248845        if (req->wct < 8) {
    88258846                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  • vendor/current/source3/smbd/vfs.c

    r740 r746  
    11261126}
    11271127
     1128/**
     1129 * Initialize num_streams and streams, then call VFS op streaminfo
     1130 */
     1131NTSTATUS 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
    11281143/*
    11291144  generate a file_id from a stat structure
     
    15011516
    15021517                /* 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);
    15041519                if (ret == -1) {
    15051520                        return map_nt_error_from_unix(errno);
     
    15121527                ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
    15131528                if (ret == -1) {
    1514                         return map_nt_error_from_unix(errno);
     1529                        status = map_nt_error_from_unix(errno);
     1530                        goto out;
    15151531                }
    15161532
    15171533                /* Ensure it matches the fsp stat. */
    15181534                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;
    15201537                }
    15211538                path = final_component;
     
    15401557        }
    15411558
     1559  out:
     1560
    15421561        if (as_root) {
    15431562                vfs_ChDir(fsp->conn,saved_dir);
Note: See TracChangeset for help on using the changeset viewer.