~ubuntu-branches/ubuntu/gutsy/samba/gutsy-updates

« back to all changes in this revision

Viewing changes to source/smbd/nttrans.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Mitchell
  • Date: 2006-11-28 20:14:37 UTC
  • mfrom: (0.10.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061128201437-a6x4lzlhempazocp
Tags: 3.0.23d-1ubuntu1
* Merge from debian unstable.
* Drop python2.4-samba, replace with python-samba. Added Conflicts/Replaces
  on python2.4-samba
* Drop track-connection-dos.patch, ubuntu-winbind-panic.patch, 
  ubuntu-fix-ldap.patch, ubuntu-setlocale.patch, ubuntu-setlocale-fixes.patch
* Remaining Ubuntu changes:
  - Revert Debian's installation of mount.cifs and umount.cifs as suid
  - Comment out the default [homes] shares and add more verbose comments to
    explain what they do and how they work (closes: launchpad.net/27608)
  - Add a "valid users = %S" stanza to the commented-out [homes] section, to
    show users how to restrict access to \\server\username to only username.
  - Change the (commented-out) "printer admin" example to use "@lpadmin"
    instead of "@ntadmin", since the lpadmin group is used for spool admin.
  - Alter the panic-action script to encourage users to report their
    bugs in Ubuntu packages to Ubuntu, rather than reporting to Debian.
    Modify text to more closely match the Debian script
  - Munge our init script to deal with the fact that our implementation
    (or lack thereof) of log_daemon_msg and log_progress_msg differs
    from Debian's implementation of the same (Ubuntu #19691)
  - Kept ubuntu-auxsrc.patch: some auxilliary sources (undocumented in 
    previous changelogs)
  - Set default workgroup to MSHOME

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
 
49
49
static char *nttrans_realloc(char **ptr, size_t size)
50
50
{
51
 
        char *tptr = NULL;
52
51
        if (ptr==NULL) {
53
52
                smb_panic("nttrans_realloc() called with NULL ptr\n");
54
53
        }
55
54
                
56
 
        tptr = SMB_REALLOC(*ptr, size);
57
 
        if(tptr == NULL) {
58
 
                *ptr = NULL;
 
55
        *ptr = SMB_REALLOC(*ptr, size);
 
56
        if(*ptr == NULL) {
59
57
                return NULL;
60
58
        }
61
 
        memset(tptr,'\0',size);
62
 
 
63
 
        *ptr = tptr;
64
 
 
65
 
        return tptr;
 
59
        memset(*ptr,'\0',size);
 
60
        return *ptr;
66
61
}
67
62
 
68
63
/****************************************************************************
798
793
                fattr = FILE_ATTRIBUTE_NORMAL;
799
794
        }
800
795
        if (!fsp->is_directory && (fattr & aDIR)) {
801
 
                close_file(fsp,False);
 
796
                close_file(fsp,ERROR_CLOSE);
802
797
                END_PROFILE(SMBntcreateX);
803
798
                return ERROR_DOS(ERRDOS,ERRnoaccess);
804
799
        } 
812
807
                if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
813
808
                        fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
814
809
                        if (fsp->is_directory) {
815
 
                                close_file(fsp,False);
 
810
                                close_file(fsp,ERROR_CLOSE);
816
811
                                END_PROFILE(SMBntcreateX);
817
812
                                /* Can't set allocation size on a directory. */
818
813
                                return ERROR_NT(NT_STATUS_ACCESS_DENIED);
819
814
                        }
820
815
                        if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
821
 
                                close_file(fsp,False);
 
816
                                close_file(fsp,ERROR_CLOSE);
822
817
                                END_PROFILE(SMBntcreateX);
823
818
                                return ERROR_NT(NT_STATUS_DISK_FULL);
824
819
                        }
919
914
****************************************************************************/
920
915
 
921
916
static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
922
 
                                  char **ppsetup, uint32 setup_count,
 
917
                                  uint16 **ppsetup, uint32 setup_count,
923
918
                                  char **ppparams, uint32 parameter_count,
924
919
                                  char **ppdata, uint32 data_count)
925
920
{
1068
1063
                struct ea_list *tmp;
1069
1064
                struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL);
1070
1065
 
 
1066
                if (!eal) {
 
1067
                        return NULL;
 
1068
                }
 
1069
 
1071
1070
                DLIST_ADD_END(ea_list_head, eal, tmp);
1072
1071
                if (next_offset == 0) {
1073
1072
                        break;
1083
1082
****************************************************************************/
1084
1083
 
1085
1084
static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1086
 
                                  char **ppsetup, uint32 setup_count,
 
1085
                                  uint16 **ppsetup, uint32 setup_count,
1087
1086
                                  char **ppparams, uint32 parameter_count,
1088
1087
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
1089
1088
{
1416
1415
                status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION);
1417
1416
                if (!NT_STATUS_IS_OK(status)) {
1418
1417
                        talloc_destroy(ctx);
1419
 
                        close_file(fsp,False);
 
1418
                        close_file(fsp,ERROR_CLOSE);
1420
1419
                        restore_case_semantics(conn, file_attributes);
1421
1420
                        return ERROR_NT(status);
1422
1421
                }
1427
1426
                status = set_ea(conn, fsp, fname, ea_list);
1428
1427
                talloc_destroy(ctx);
1429
1428
                if (!NT_STATUS_IS_OK(status)) {
1430
 
                        close_file(fsp,False);
 
1429
                        close_file(fsp,ERROR_CLOSE);
1431
1430
                        restore_case_semantics(conn, file_attributes);
1432
1431
                        return ERROR_NT(status);
1433
1432
                }
1441
1440
                fattr = FILE_ATTRIBUTE_NORMAL;
1442
1441
        }
1443
1442
        if (!fsp->is_directory && (fattr & aDIR)) {
1444
 
                close_file(fsp,False);
 
1443
                close_file(fsp,ERROR_CLOSE);
1445
1444
                return ERROR_DOS(ERRDOS,ERRnoaccess);
1446
1445
        } 
1447
1446
        
1454
1453
                if (allocation_size && (allocation_size > file_len)) {
1455
1454
                        fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1456
1455
                        if (fsp->is_directory) {
1457
 
                                close_file(fsp,False);
 
1456
                                close_file(fsp,ERROR_CLOSE);
1458
1457
                                /* Can't set allocation size on a directory. */
1459
1458
                                return ERROR_NT(NT_STATUS_ACCESS_DENIED);
1460
1459
                        }
1461
1460
                        if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1462
 
                                close_file(fsp,False);
 
1461
                                close_file(fsp,ERROR_CLOSE);
1463
1462
                                return ERROR_NT(NT_STATUS_DISK_FULL);
1464
1463
                        }
1465
1464
                } else {
1546
1545
 
1547
1546
/****************************************************************************
1548
1547
 Reply to a NT CANCEL request.
 
1548
 conn POINTER CAN BE NULL HERE !
1549
1549
****************************************************************************/
1550
1550
 
1551
1551
int reply_ntcancel(connection_struct *conn,
1657
1657
 
1658
1658
        fsp1 = open_file_ntcreate(conn,oldname,&sbuf1,
1659
1659
                        FILE_READ_DATA, /* Read-only. */
1660
 
                        0, /* No sharing. */
 
1660
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1661
1661
                        FILE_OPEN,
1662
1662
                        0, /* No create options. */
1663
1663
                        FILE_ATTRIBUTE_NORMAL,
1664
 
                        INTERNAL_OPEN_ONLY,
 
1664
                        NO_OPLOCK,
1665
1665
                        &info);
1666
1666
 
1667
1667
        if (!fsp1) {
1674
1674
        }
1675
1675
 
1676
1676
        fsp2 = open_file_ntcreate(conn,newname,&sbuf2,
1677
 
                        FILE_WRITE_DATA, /* Read-only. */
1678
 
                        0, /* No sharing. */
 
1677
                        FILE_WRITE_DATA, /* Write-only. */
 
1678
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1679
1679
                        FILE_CREATE,
1680
1680
                        0, /* No create options. */
1681
1681
                        fattr,
1682
 
                        INTERNAL_OPEN_ONLY,
 
1682
                        NO_OPLOCK,
1683
1683
                        &info);
1684
1684
 
1685
1685
        if (!fsp2) {
1688
1688
                        status = NT_STATUS_ACCESS_DENIED;
1689
1689
                }
1690
1690
                set_saved_ntstatus(NT_STATUS_OK);
1691
 
                close_file(fsp1,False);
 
1691
                close_file(fsp1,ERROR_CLOSE);
1692
1692
                return status;
1693
1693
        }
1694
1694
 
1702
1702
         * Thus we don't look at the error return from the
1703
1703
         * close of fsp1.
1704
1704
         */
1705
 
        close_file(fsp1,False);
 
1705
        close_file(fsp1,NORMAL_CLOSE);
1706
1706
 
1707
1707
        /* Ensure the modtime is set correctly on the destination file. */
1708
1708
        fsp_set_pending_modtime(fsp2, sbuf1.st_mtime);
1709
1709
 
1710
 
        close_ret = close_file(fsp2,False);
 
1710
        close_ret = close_file(fsp2,NORMAL_CLOSE);
1711
1711
 
1712
 
        /* Grrr. We have to do this as open_file_shared1 adds aARCH when it
1713
 
           creates the file. This isn't the correct thing to do in the copy case. JRA */
 
1712
        /* Grrr. We have to do this as open_file_ntcreate adds aARCH when it
 
1713
           creates the file. This isn't the correct thing to do in the copy
 
1714
           case. JRA */
1714
1715
        file_set_dosmode(conn, newname, fattr, &sbuf2, True);
1715
1716
 
1716
1717
        if (ret < (SMB_OFF_T)sbuf1.st_size) {
1810
1811
         * update after a rename..
1811
1812
         */     
1812
1813
        process_pending_change_notify_queue((time_t)0);
1813
 
        outsize = set_message(outbuf,0,0,True);
 
1814
        outsize = set_message(outbuf,0,0,False);
1814
1815
  
1815
1816
        END_PROFILE(SMBntrename);
1816
1817
        return(outsize);
1817
1818
}
1818
1819
 
1819
1820
/****************************************************************************
1820
 
 Reply to an unsolicited SMBNTtranss - just ignore it!
1821
 
****************************************************************************/
1822
 
 
1823
 
int reply_nttranss(connection_struct *conn,
1824
 
                   char *inbuf,char *outbuf,int length,int bufsize)
1825
 
{
1826
 
        START_PROFILE(SMBnttranss);
1827
 
        DEBUG(4,("Ignoring nttranss of length %d\n",length));
1828
 
        END_PROFILE(SMBnttranss);
1829
 
        return(-1);
1830
 
}
1831
 
 
1832
 
/****************************************************************************
1833
1821
 Reply to a notify change - queue the request and 
1834
1822
 don't allow a directory to be opened.
1835
1823
****************************************************************************/
1836
1824
 
1837
1825
static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
1838
 
                                  char **ppsetup, uint32 setup_count,
 
1826
                                  uint16 **ppsetup, uint32 setup_count,
1839
1827
                                  char **ppparams, uint32 parameter_count,
1840
1828
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
1841
1829
{
1842
 
        char *setup = *ppsetup;
 
1830
        uint16 *setup = *ppsetup;
1843
1831
        files_struct *fsp;
1844
1832
        uint32 flags;
1845
1833
 
1847
1835
                return ERROR_DOS(ERRDOS,ERRbadfunc);
1848
1836
        }
1849
1837
 
1850
 
        fsp = file_fsp(setup,4);
 
1838
        fsp = file_fsp((char *)setup,4);
1851
1839
        flags = IVAL(setup, 0);
1852
1840
 
1853
1841
        DEBUG(3,("call_nt_transact_notify_change\n"));
1875
1863
****************************************************************************/
1876
1864
 
1877
1865
static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1878
 
                                  char **ppsetup, uint32 setup_count,
 
1866
                                  uint16 **ppsetup, uint32 setup_count,
1879
1867
                                  char **ppparams, uint32 parameter_count,
1880
1868
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
1881
1869
{
1943
1931
****************************************************************************/
1944
1932
 
1945
1933
static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
1946
 
                                  char **ppsetup, uint32 setup_count,
 
1934
                                  uint16 **ppsetup, uint32 setup_count,
1947
1935
                                  char **ppparams, uint32 parameter_count,
1948
1936
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
1949
1937
{
2059
2047
****************************************************************************/
2060
2048
 
2061
2049
static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2062
 
                                  char **ppsetup, uint32 setup_count,
 
2050
                                  uint16 **ppsetup, uint32 setup_count,
2063
2051
                                  char **ppparams, uint32 parameter_count,
2064
2052
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
2065
2053
{
2105
2093
****************************************************************************/
2106
2094
 
2107
2095
static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
2108
 
                                  char **ppsetup, uint32 setup_count,
 
2096
                                  uint16 **ppsetup, uint32 setup_count,
2109
2097
                                  char **ppparams, uint32 parameter_count,
2110
2098
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
2111
2099
{
2130
2118
        DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", 
2131
2119
                 function, fidnum, isFSctl, compfilter));
2132
2120
 
2133
 
        fsp=file_fsp(*ppsetup, 4);
 
2121
        fsp=file_fsp((char *)*ppsetup, 4);
2134
2122
        /* this check is done in each implemented function case for now
2135
2123
           because I don't want to break anything... --metze
2136
2124
        FSP_BELONGS_CONN(fsp,conn);*/
2309
2297
                sid_parse(pdata+4,sid_len,&sid);
2310
2298
                DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
2311
2299
 
2312
 
                if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &uid))) {
 
2300
                if (!sid_to_uid(&sid, &uid)) {
2313
2301
                        DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
2314
2302
                                sid_string_static(&sid),(unsigned long)sid_len));
2315
2303
                        uid = (-1);
2355
2343
****************************************************************************/
2356
2344
 
2357
2345
static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
2358
 
                                  char **ppsetup, uint32 setup_count,
 
2346
                                  uint16 **ppsetup, uint32 setup_count,
2359
2347
                                  char **ppparams, uint32 parameter_count,
2360
2348
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
2361
2349
{
2379
2367
        ZERO_STRUCT(qt);
2380
2368
 
2381
2369
        /* access check */
2382
 
        if (current_user.uid != 0) {
 
2370
        if (current_user.ut.uid != 0) {
2383
2371
                DEBUG(1,("get_user_quota: access_denied service [%s] user [%s]\n",
2384
2372
                        lp_servicename(SNUM(conn)),conn->user));
2385
2373
                return ERROR_DOS(ERRDOS,ERRnoaccess);
2611
2599
****************************************************************************/
2612
2600
 
2613
2601
static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
2614
 
                                  char **ppsetup, uint32 setup_count,
 
2602
                                  uint16 **ppsetup, uint32 setup_count,
2615
2603
                                  char **ppparams, uint32 parameter_count,
2616
2604
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
2617
2605
{
2626
2614
        ZERO_STRUCT(qt);
2627
2615
 
2628
2616
        /* access check */
2629
 
        if (current_user.uid != 0) {
 
2617
        if (current_user.ut.uid != 0) {
2630
2618
                DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
2631
2619
                        lp_servicename(SNUM(conn)),conn->user));
2632
2620
                return ERROR_DOS(ERRDOS,ERRnoaccess);
2724
2712
}
2725
2713
#endif /* HAVE_SYS_QUOTAS */
2726
2714
 
2727
 
/****************************************************************************
2728
 
 Reply to a SMBNTtrans.
2729
 
****************************************************************************/
2730
 
 
2731
 
int reply_nttrans(connection_struct *conn,
2732
 
                        char *inbuf,char *outbuf,int length,int bufsize)
 
2715
static int handle_nttrans(connection_struct *conn,
 
2716
                          struct trans_state *state,
 
2717
                          char *inbuf, char *outbuf, int size, int bufsize)
2733
2718
{
2734
 
        int  outsize = 0;
2735
 
        uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
2736
 
#if 0 /* Not used. */
2737
 
        uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
2738
 
        uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
2739
 
#endif /* Not used. */
2740
 
        uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
2741
 
        uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
2742
 
        uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
2743
 
        uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
2744
 
        uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
2745
 
        uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
2746
 
        uint16 setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); /* setup count is in *words* */
2747
 
        uint16 function_code = SVAL( inbuf, smb_nt_Function);
2748
 
        char *params = NULL, *data = NULL, *setup = NULL;
2749
 
        uint32 num_params_sofar, num_data_sofar;
2750
 
        START_PROFILE(SMBnttrans);
2751
 
 
2752
 
        if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
2753
 
                END_PROFILE(SMBnttrans);
2754
 
                return ERROR_DOS(ERRSRV,ERRaccess);
2755
 
        }
2756
 
 
2757
 
        outsize = set_message(outbuf,0,0,True);
2758
 
 
2759
 
        /* 
2760
 
         * All nttrans messages we handle have smb_wct == 19 + setup_count.
2761
 
         * Ensure this is so as a sanity check.
2762
 
         */
2763
 
 
2764
 
        if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
2765
 
                DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
2766
 
                        CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
2767
 
                goto bad_param;
2768
 
        }
2769
 
 
2770
 
        /* Don't allow more than 128mb for each value. */
2771
 
        if ((total_parameter_count > (1024*1024*128)) || (total_data_count > (1024*1024*128))) {
2772
 
                END_PROFILE(SMBnttrans);
2773
 
                return ERROR_DOS(ERRDOS,ERRnomem);
2774
 
        }
2775
 
 
2776
 
        /* Allocate the space for the setup, the maximum needed parameters and data */
2777
 
 
2778
 
        if(setup_count > 0) {
2779
 
                setup = (char *)SMB_MALLOC(setup_count);
2780
 
        }
2781
 
        if (total_parameter_count > 0) {
2782
 
                params = (char *)SMB_MALLOC(total_parameter_count);
2783
 
        }
2784
 
        if (total_data_count > 0) {
2785
 
                data = (char *)SMB_MALLOC(total_data_count);
2786
 
        }
2787
 
 
2788
 
        if ((total_parameter_count && !params)  || (total_data_count && !data) ||
2789
 
                                (setup_count && !setup)) {
2790
 
                SAFE_FREE(setup);
2791
 
                SAFE_FREE(params);
2792
 
                SAFE_FREE(data);
2793
 
                DEBUG(0,("reply_nttrans : Out of memory\n"));
2794
 
                END_PROFILE(SMBnttrans);
2795
 
                return ERROR_DOS(ERRDOS,ERRnomem);
2796
 
        }
2797
 
 
2798
 
        /* Copy the param and data bytes sent with this request into the params buffer */
2799
 
        num_params_sofar = parameter_count;
2800
 
        num_data_sofar = data_count;
2801
 
 
2802
 
        if (parameter_count > total_parameter_count || data_count > total_data_count)
2803
 
                goto bad_param;
2804
 
 
2805
 
        if(setup) {
2806
 
                DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
2807
 
                if ((smb_nt_SetupStart + setup_count < smb_nt_SetupStart) ||
2808
 
                                (smb_nt_SetupStart + setup_count < setup_count)) {
2809
 
                        goto bad_param;
2810
 
                }
2811
 
                if (smb_nt_SetupStart + setup_count > length) {
2812
 
                        goto bad_param;
2813
 
                }
2814
 
 
2815
 
                memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
2816
 
                dump_data(10, setup, setup_count);
2817
 
        }
2818
 
        if(params) {
2819
 
                DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
2820
 
                if ((parameter_offset + parameter_count < parameter_offset) ||
2821
 
                                (parameter_offset + parameter_count < parameter_count)) {
2822
 
                        goto bad_param;
2823
 
                }
2824
 
                if ((smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)||
2825
 
                                (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf))) {
2826
 
                        goto bad_param;
2827
 
                }
2828
 
 
2829
 
                memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
2830
 
                dump_data(10, params, parameter_count);
2831
 
        }
2832
 
        if(data) {
2833
 
                DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
2834
 
                if ((data_offset + data_count < data_offset) || (data_offset + data_count < data_count)) {
2835
 
                        goto bad_param;
2836
 
                }
2837
 
                if ((smb_base(inbuf) + data_offset + data_count > inbuf + length) ||
2838
 
                                (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf))) {
2839
 
                        goto bad_param;
2840
 
                }
2841
 
 
2842
 
                memcpy( data, smb_base(inbuf) + data_offset, data_count);
2843
 
                dump_data(10, data, data_count);
2844
 
        }
2845
 
 
2846
 
        srv_signing_trans_start(SVAL(inbuf,smb_mid));
2847
 
 
2848
 
        if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
2849
 
                /* We need to send an interim response then receive the rest
2850
 
                        of the parameter/data bytes */
2851
 
                outsize = set_message(outbuf,0,0,True);
2852
 
                srv_signing_trans_stop();
2853
 
                show_msg(outbuf);
2854
 
                if (!send_smb(smbd_server_fd(),outbuf)) {
2855
 
                        exit_server("reply_nttrans: send_smb failed.");
2856
 
                }
2857
 
 
2858
 
                while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
2859
 
                        BOOL ret;
2860
 
                        uint32 parameter_displacement;
2861
 
                        uint32 data_displacement;
2862
 
 
2863
 
                        ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2864
 
 
2865
 
                        /* We need to re-calcuate the new length after we've read the secondary packet. */
2866
 
                        length = smb_len(inbuf) + 4;
2867
 
 
2868
 
                        /*
2869
 
                         * The sequence number for the trans reply is always
2870
 
                         * based on the last secondary received.
2871
 
                         */
2872
 
 
2873
 
                        srv_signing_trans_start(SVAL(inbuf,smb_mid));
2874
 
 
2875
 
                        if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
2876
 
                                outsize = set_message(outbuf,0,0,True);
2877
 
                                if(ret) {
2878
 
                                        DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
2879
 
                                } else {
2880
 
                                        DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
2881
 
                                                (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2882
 
                                }
2883
 
                                goto bad_param;
2884
 
                        }
2885
 
      
2886
 
                        /* Revise total_params and total_data in case they have changed downwards */
2887
 
                        if (IVAL(inbuf, smb_nts_TotalParameterCount) < total_parameter_count) {
2888
 
                                total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
2889
 
                        }
2890
 
                        if (IVAL(inbuf, smb_nts_TotalDataCount) < total_data_count) {
2891
 
                                total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
2892
 
                        }
2893
 
 
2894
 
                        parameter_count = IVAL(inbuf,smb_nts_ParameterCount);
2895
 
                        parameter_offset = IVAL(inbuf, smb_nts_ParameterOffset);
2896
 
                        parameter_displacement = IVAL(inbuf, smb_nts_ParameterDisplacement);
2897
 
                        num_params_sofar += parameter_count;
2898
 
 
2899
 
                        data_count = IVAL(inbuf, smb_nts_DataCount);
2900
 
                        data_displacement = IVAL(inbuf, smb_nts_DataDisplacement);
2901
 
                        data_offset = IVAL(inbuf, smb_nts_DataOffset);
2902
 
                        num_data_sofar += data_count;
2903
 
 
2904
 
                        if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count) {
2905
 
                                DEBUG(0,("reply_nttrans2: data overflow in secondary nttrans packet"));
2906
 
                                goto bad_param;
2907
 
                        }
2908
 
 
2909
 
                        if (parameter_count) {
2910
 
                                if (parameter_displacement + parameter_count > total_parameter_count) {
2911
 
                                        goto bad_param;
2912
 
                                }
2913
 
                                if ((parameter_displacement + parameter_count < parameter_displacement) ||
2914
 
                                                (parameter_displacement + parameter_count < parameter_count)) {
2915
 
                                        goto bad_param;
2916
 
                                }
2917
 
                                if (parameter_displacement > total_parameter_count) {
2918
 
                                        goto bad_param;
2919
 
                                }
2920
 
                                if ((smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length) ||
2921
 
                                                (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf))) {
2922
 
                                        goto bad_param;
2923
 
                                }
2924
 
                                if (parameter_displacement + params < params) {
2925
 
                                        goto bad_param;
2926
 
                                }
2927
 
 
2928
 
                                memcpy( &params[parameter_displacement], smb_base(inbuf) + parameter_offset, parameter_count);
2929
 
                        }
2930
 
 
2931
 
                        if (data_count) {
2932
 
                                if (data_displacement + data_count > total_data_count) {
2933
 
                                        goto bad_param;
2934
 
                                }
2935
 
                                if ((data_displacement + data_count < data_displacement) ||
2936
 
                                                (data_displacement + data_count < data_count)) {
2937
 
                                        goto bad_param;
2938
 
                                }
2939
 
                                if (data_displacement > total_data_count) {
2940
 
                                        goto bad_param;
2941
 
                                }
2942
 
                                if ((smb_base(inbuf) + data_offset + data_count > inbuf + length) ||
2943
 
                                                (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf))) {
2944
 
                                        goto bad_param;
2945
 
                                }
2946
 
                                if (data_displacement + data < data) {
2947
 
                                        goto bad_param;
2948
 
                                }
2949
 
 
2950
 
                                memcpy( &data[data_displacement], smb_base(inbuf)+ data_offset, data_count);
2951
 
                        }
2952
 
                }
2953
 
        }
 
2719
        int outsize;
2954
2720
 
2955
2721
        if (Protocol >= PROTOCOL_NT1) {
2956
 
                SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_IS_LONG_NAME);
 
2722
                SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2957
2723
        }
2958
2724
 
2959
2725
        /* Now we must call the relevant NT_TRANS function */
2960
 
        switch(function_code) {
 
2726
        switch(state->call) {
2961
2727
                case NT_TRANSACT_CREATE:
 
2728
                {
2962
2729
                        START_PROFILE_NESTED(NT_transact_create);
2963
2730
                        outsize = call_nt_transact_create(conn, inbuf, outbuf,
2964
 
                                                        length, bufsize, 
2965
 
                                                        &setup, setup_count,
2966
 
                                                        &params, total_parameter_count, 
2967
 
                                                        &data, total_data_count, max_data_count);
 
2731
                                                          size, bufsize, 
 
2732
                                                        &state->setup, state->setup_count,
 
2733
                                                        &state->param, state->total_param, 
 
2734
                                                        &state->data, state->total_data,
 
2735
                                                          state->max_data_return);
2968
2736
                        END_PROFILE_NESTED(NT_transact_create);
2969
2737
                        break;
 
2738
                }
 
2739
 
2970
2740
                case NT_TRANSACT_IOCTL:
 
2741
                {
2971
2742
                        START_PROFILE_NESTED(NT_transact_ioctl);
2972
2743
                        outsize = call_nt_transact_ioctl(conn, inbuf, outbuf,
2973
 
                                                         length, bufsize, 
2974
 
                                                         &setup, setup_count,
2975
 
                                                         &params, total_parameter_count, 
2976
 
                                                         &data, total_data_count, max_data_count);
 
2744
                                                         size, bufsize, 
 
2745
                                                         &state->setup, state->setup_count,
 
2746
                                                         &state->param, state->total_param, 
 
2747
                                                         &state->data, state->total_data, state->max_data_return);
2977
2748
                        END_PROFILE_NESTED(NT_transact_ioctl);
2978
2749
                        break;
 
2750
                }
 
2751
 
2979
2752
                case NT_TRANSACT_SET_SECURITY_DESC:
 
2753
                {
2980
2754
                        START_PROFILE_NESTED(NT_transact_set_security_desc);
2981
2755
                        outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, 
2982
 
                                                         length, bufsize, 
2983
 
                                                         &setup, setup_count,
2984
 
                                                         &params, total_parameter_count, 
2985
 
                                                         &data, total_data_count, max_data_count);
 
2756
                                                         size, bufsize, 
 
2757
                                                         &state->setup, state->setup_count,
 
2758
                                                         &state->param, state->total_param, 
 
2759
                                                         &state->data, state->total_data, state->max_data_return);
2986
2760
                        END_PROFILE_NESTED(NT_transact_set_security_desc);
2987
2761
                        break;
 
2762
                }
 
2763
 
2988
2764
                case NT_TRANSACT_NOTIFY_CHANGE:
 
2765
                {
2989
2766
                        START_PROFILE_NESTED(NT_transact_notify_change);
2990
2767
                        outsize = call_nt_transact_notify_change(conn, inbuf, outbuf, 
2991
 
                                                         length, bufsize, 
2992
 
                                                         &setup, setup_count,
2993
 
                                                         &params, total_parameter_count, 
2994
 
                                                         &data, total_data_count, max_data_count);
 
2768
                                                         size, bufsize, 
 
2769
                                                         &state->setup, state->setup_count,
 
2770
                                                         &state->param, state->total_param, 
 
2771
                                                         &state->data, state->total_data, state->max_data_return);
2995
2772
                        END_PROFILE_NESTED(NT_transact_notify_change);
2996
2773
                        break;
 
2774
                }
 
2775
 
2997
2776
                case NT_TRANSACT_RENAME:
 
2777
                {
2998
2778
                        START_PROFILE_NESTED(NT_transact_rename);
2999
2779
                        outsize = call_nt_transact_rename(conn, inbuf, outbuf,
3000
 
                                                         length, bufsize, 
3001
 
                                                         &setup, setup_count,
3002
 
                                                         &params, total_parameter_count, 
3003
 
                                                         &data, total_data_count, max_data_count);
 
2780
                                                         size, bufsize, 
 
2781
                                                         &state->setup, state->setup_count,
 
2782
                                                         &state->param, state->total_param, 
 
2783
                                                         &state->data, state->total_data, state->max_data_return);
3004
2784
                        END_PROFILE_NESTED(NT_transact_rename);
3005
2785
                        break;
 
2786
                }
3006
2787
 
3007
2788
                case NT_TRANSACT_QUERY_SECURITY_DESC:
 
2789
                {
3008
2790
                        START_PROFILE_NESTED(NT_transact_query_security_desc);
3009
2791
                        outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, 
3010
 
                                                         length, bufsize, 
3011
 
                                                         &setup, setup_count,
3012
 
                                                         &params, total_parameter_count, 
3013
 
                                                         &data, total_data_count, max_data_count);
 
2792
                                                         size, bufsize, 
 
2793
                                                         &state->setup, state->setup_count,
 
2794
                                                         &state->param, state->total_param, 
 
2795
                                                         &state->data, state->total_data, state->max_data_return);
3014
2796
                        END_PROFILE_NESTED(NT_transact_query_security_desc);
3015
2797
                        break;
 
2798
                }
 
2799
 
3016
2800
#ifdef HAVE_SYS_QUOTAS
3017
2801
                case NT_TRANSACT_GET_USER_QUOTA:
 
2802
                {
3018
2803
                        START_PROFILE_NESTED(NT_transact_get_user_quota);
3019
2804
                        outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf, 
3020
 
                                                         length, bufsize, 
3021
 
                                                         &setup, setup_count,
3022
 
                                                         &params, total_parameter_count, 
3023
 
                                                         &data, total_data_count, max_data_count);
 
2805
                                                         size, bufsize, 
 
2806
                                                         &state->setup, state->setup_count,
 
2807
                                                         &state->param, state->total_param, 
 
2808
                                                         &state->data, state->total_data, state->max_data_return);
3024
2809
                        END_PROFILE_NESTED(NT_transact_get_user_quota);
3025
2810
                        break;
 
2811
                }
 
2812
 
3026
2813
                case NT_TRANSACT_SET_USER_QUOTA:
 
2814
                {
3027
2815
                        START_PROFILE_NESTED(NT_transact_set_user_quota);
3028
2816
                        outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf, 
3029
 
                                                         length, bufsize, 
3030
 
                                                         &setup, setup_count,
3031
 
                                                         &params, total_parameter_count, 
3032
 
                                                         &data, total_data_count, max_data_count);
 
2817
                                                         size, bufsize, 
 
2818
                                                         &state->setup, state->setup_count,
 
2819
                                                         &state->param, state->total_param, 
 
2820
                                                         &state->data, state->total_data, state->max_data_return);
3033
2821
                        END_PROFILE_NESTED(NT_transact_set_user_quota);
3034
2822
                        break;                                  
 
2823
                }
3035
2824
#endif /* HAVE_SYS_QUOTAS */
 
2825
 
3036
2826
                default:
3037
2827
                        /* Error in request */
3038
 
                        DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
3039
 
                        SAFE_FREE(setup);
3040
 
                        SAFE_FREE(params);
3041
 
                        SAFE_FREE(data);
3042
 
                        END_PROFILE(SMBnttrans);
3043
 
                        srv_signing_trans_stop();
 
2828
                        DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n",
 
2829
                                 state->call));
3044
2830
                        return ERROR_DOS(ERRSRV,ERRerror);
3045
2831
        }
3046
 
 
3047
 
        /* As we do not know how many data packets will need to be
3048
 
                returned here the various call_nt_transact_xxxx calls
3049
 
                must send their own. Thus a call_nt_transact_xxxx routine only
3050
 
                returns a value other than -1 when it wants to send
3051
 
                an error packet. 
3052
 
        */
3053
 
 
3054
 
        srv_signing_trans_stop();
3055
 
 
3056
 
        SAFE_FREE(setup);
3057
 
        SAFE_FREE(params);
3058
 
        SAFE_FREE(data);
3059
 
        END_PROFILE(SMBnttrans);
3060
 
        return outsize; /* If a correct response was needed the call_nt_transact_xxxx 
3061
 
                                calls have already sent it. If outsize != -1 then it is
3062
 
                                returning an error packet. */
3063
 
 
3064
 
 bad_param:
3065
 
 
3066
 
        srv_signing_trans_stop();
3067
 
        SAFE_FREE(params);
3068
 
        SAFE_FREE(data);
3069
 
        SAFE_FREE(setup);
3070
 
        END_PROFILE(SMBnttrans);
 
2832
        return outsize;
 
2833
}
 
2834
 
 
2835
/****************************************************************************
 
2836
 Reply to a SMBNTtrans.
 
2837
****************************************************************************/
 
2838
 
 
2839
int reply_nttrans(connection_struct *conn,
 
2840
                        char *inbuf,char *outbuf,int size,int bufsize)
 
2841
{
 
2842
        int  outsize = 0;
 
2843
        uint32 pscnt = IVAL(inbuf,smb_nt_ParameterCount);
 
2844
        uint32 psoff = IVAL(inbuf,smb_nt_ParameterOffset);
 
2845
        uint32 dscnt = IVAL(inbuf,smb_nt_DataCount);
 
2846
        uint32 dsoff = IVAL(inbuf,smb_nt_DataOffset);
 
2847
        
 
2848
        uint16 function_code = SVAL( inbuf, smb_nt_Function);
 
2849
        NTSTATUS result;
 
2850
        struct trans_state *state;
 
2851
 
 
2852
        START_PROFILE(SMBnttrans);
 
2853
 
 
2854
        if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
 
2855
                END_PROFILE(SMBnttrans);
 
2856
                return ERROR_DOS(ERRSRV,ERRaccess);
 
2857
        }
 
2858
 
 
2859
        result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid));
 
2860
        if (!NT_STATUS_IS_OK(result)) {
 
2861
                DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result)));
 
2862
                END_PROFILE(SMBnttrans);
 
2863
                return ERROR_NT(result);
 
2864
        }
 
2865
 
 
2866
        if ((state = TALLOC_P(NULL, struct trans_state)) == NULL) {
 
2867
                END_PROFILE(SMBnttrans);
 
2868
                return ERROR_DOS(ERRSRV,ERRaccess);
 
2869
        }
 
2870
 
 
2871
        state->cmd = SMBnttrans;
 
2872
 
 
2873
        state->mid = SVAL(inbuf,smb_mid);
 
2874
        state->vuid = SVAL(inbuf,smb_uid);
 
2875
        state->total_data = IVAL(inbuf, smb_nt_TotalDataCount);
 
2876
        state->data = NULL;
 
2877
        state->total_param = IVAL(inbuf, smb_nt_TotalParameterCount);
 
2878
        state->param = NULL;
 
2879
        state->max_data_return = IVAL(inbuf,smb_nt_MaxDataCount);       
 
2880
 
 
2881
        /* setup count is in *words* */
 
2882
        state->setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); 
 
2883
        state->call = function_code;
 
2884
 
 
2885
        /* 
 
2886
         * All nttrans messages we handle have smb_wct == 19 +
 
2887
         * state->setup_count.  Ensure this is so as a sanity check.
 
2888
         */
 
2889
 
 
2890
        if(CVAL(inbuf, smb_wct) != 19 + (state->setup_count/2)) {
 
2891
                DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
 
2892
                        CVAL(inbuf, smb_wct), 19 + (state->setup_count/2)));
 
2893
                goto bad_param;
 
2894
        }
 
2895
 
 
2896
        /* Don't allow more than 128mb for each value. */
 
2897
        if ((state->total_data > (1024*1024*128)) ||
 
2898
            (state->total_param > (1024*1024*128))) {
 
2899
                END_PROFILE(SMBnttrans);
 
2900
                return ERROR_DOS(ERRDOS,ERRnomem);
 
2901
        }
 
2902
 
 
2903
        if ((dscnt > state->total_data) || (pscnt > state->total_param))
 
2904
                goto bad_param;
 
2905
 
 
2906
        if (state->total_data)  {
 
2907
                /* Can't use talloc here, the core routines do realloc on the
 
2908
                 * params and data. */
 
2909
                if ((state->data = SMB_MALLOC(state->total_data)) == NULL) {
 
2910
                        DEBUG(0,("reply_nttrans: data malloc fail for %u "
 
2911
                                 "bytes !\n", (unsigned int)state->total_data));
 
2912
                        TALLOC_FREE(state);
 
2913
                        END_PROFILE(SMBnttrans);
 
2914
                        return(ERROR_DOS(ERRDOS,ERRnomem));
 
2915
                } 
 
2916
                if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
 
2917
                        goto bad_param;
 
2918
                if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) ||
 
2919
                    (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf)))
 
2920
                        goto bad_param;
 
2921
 
 
2922
                memcpy(state->data,smb_base(inbuf)+dsoff,dscnt);
 
2923
        }
 
2924
 
 
2925
        if (state->total_param) {
 
2926
                /* Can't use talloc here, the core routines do realloc on the
 
2927
                 * params and data. */
 
2928
                if ((state->param = SMB_MALLOC(state->total_param)) == NULL) {
 
2929
                        DEBUG(0,("reply_nttrans: param malloc fail for %u "
 
2930
                                 "bytes !\n", (unsigned int)state->total_param));
 
2931
                        SAFE_FREE(state->data);
 
2932
                        TALLOC_FREE(state);
 
2933
                        END_PROFILE(SMBnttrans);
 
2934
                        return(ERROR_DOS(ERRDOS,ERRnomem));
 
2935
                } 
 
2936
                if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
 
2937
                        goto bad_param;
 
2938
                if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) ||
 
2939
                    (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf)))
 
2940
                        goto bad_param;
 
2941
 
 
2942
                memcpy(state->param,smb_base(inbuf)+psoff,pscnt);
 
2943
        }
 
2944
 
 
2945
        state->received_data  = dscnt;
 
2946
        state->received_param = pscnt;
 
2947
 
 
2948
        if(state->setup_count > 0) {
 
2949
                DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
 
2950
                          state->setup_count));
 
2951
                state->setup = TALLOC(state, state->setup_count);
 
2952
                if (state->setup == NULL) {
 
2953
                        DEBUG(0,("reply_nttrans : Out of memory\n"));
 
2954
                        SAFE_FREE(state->data);
 
2955
                        SAFE_FREE(state->param);
 
2956
                        TALLOC_FREE(state);
 
2957
                        END_PROFILE(SMBnttrans);
 
2958
                        return ERROR_DOS(ERRDOS,ERRnomem);
 
2959
                }
 
2960
 
 
2961
                if ((smb_nt_SetupStart + state->setup_count < smb_nt_SetupStart) ||
 
2962
                    (smb_nt_SetupStart + state->setup_count < state->setup_count)) {
 
2963
                        goto bad_param;
 
2964
                }
 
2965
                if (smb_nt_SetupStart + state->setup_count > size) {
 
2966
                        goto bad_param;
 
2967
                }
 
2968
 
 
2969
                memcpy( state->setup, &inbuf[smb_nt_SetupStart], state->setup_count);
 
2970
                dump_data(10, (char *)state->setup, state->setup_count);
 
2971
        }
 
2972
 
 
2973
        if ((state->received_data == state->total_data) &&
 
2974
            (state->received_param == state->total_param)) {
 
2975
                outsize = handle_nttrans(conn, state, inbuf, outbuf,
 
2976
                                         size, bufsize);
 
2977
                SAFE_FREE(state->param);
 
2978
                SAFE_FREE(state->data);
 
2979
                TALLOC_FREE(state);
 
2980
                END_PROFILE(SMBnttrans);
 
2981
                return outsize;
 
2982
        }
 
2983
 
 
2984
        DLIST_ADD(conn->pending_trans, state);
 
2985
 
 
2986
        /* We need to send an interim response then receive the rest
 
2987
           of the parameter/data bytes */
 
2988
        outsize = set_message(outbuf,0,0,False);
 
2989
        show_msg(outbuf);
 
2990
        END_PROFILE(SMBnttrans);
 
2991
        return outsize;
 
2992
 
 
2993
  bad_param:
 
2994
 
 
2995
        DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
 
2996
        SAFE_FREE(state->data);
 
2997
        SAFE_FREE(state->param);
 
2998
        TALLOC_FREE(state);
 
2999
        END_PROFILE(SMBnttrans);
 
3000
        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 
3001
}
 
3002
        
 
3003
/****************************************************************************
 
3004
 Reply to a SMBnttranss
 
3005
 ****************************************************************************/
 
3006
 
 
3007
int reply_nttranss(connection_struct *conn,  char *inbuf,char *outbuf,
 
3008
                   int size,int bufsize)
 
3009
{
 
3010
        int outsize = 0;
 
3011
        unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
 
3012
        struct trans_state *state;
 
3013
 
 
3014
        START_PROFILE(SMBnttranss);
 
3015
 
 
3016
        show_msg(inbuf);
 
3017
 
 
3018
        for (state = conn->pending_trans; state != NULL;
 
3019
             state = state->next) {
 
3020
                if (state->mid == SVAL(inbuf,smb_mid)) {
 
3021
                        break;
 
3022
                }
 
3023
        }
 
3024
 
 
3025
        if ((state == NULL) || (state->cmd != SMBnttrans)) {
 
3026
                END_PROFILE(SMBnttranss);
 
3027
                return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 
3028
        }
 
3029
 
 
3030
        /* Revise state->total_param and state->total_data in case they have
 
3031
           changed downwards */
 
3032
        if (IVAL(inbuf, smb_nts_TotalParameterCount) < state->total_param) {
 
3033
                state->total_param = IVAL(inbuf, smb_nts_TotalParameterCount);
 
3034
        }
 
3035
        if (IVAL(inbuf, smb_nts_TotalDataCount) < state->total_data) {
 
3036
                state->total_data = IVAL(inbuf, smb_nts_TotalDataCount);
 
3037
        }
 
3038
 
 
3039
        pcnt = IVAL(inbuf,smb_nts_ParameterCount);
 
3040
        poff = IVAL(inbuf, smb_nts_ParameterOffset);
 
3041
        pdisp = IVAL(inbuf, smb_nts_ParameterDisplacement);
 
3042
 
 
3043
        dcnt = IVAL(inbuf, smb_nts_DataCount);
 
3044
        ddisp = IVAL(inbuf, smb_nts_DataDisplacement);
 
3045
        doff = IVAL(inbuf, smb_nts_DataOffset);
 
3046
 
 
3047
        state->received_param += pcnt;
 
3048
        state->received_data += dcnt;
 
3049
                
 
3050
        if ((state->received_data > state->total_data) ||
 
3051
            (state->received_param > state->total_param))
 
3052
                goto bad_param;
 
3053
 
 
3054
        if (pcnt) {
 
3055
                if (pdisp+pcnt > state->total_param)
 
3056
                        goto bad_param;
 
3057
                if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
 
3058
                        goto bad_param;
 
3059
                if (pdisp > state->total_param)
 
3060
                        goto bad_param;
 
3061
                if ((smb_base(inbuf) + poff + pcnt > inbuf + size) ||
 
3062
                    (smb_base(inbuf) + poff + pcnt < smb_base(inbuf)))
 
3063
                        goto bad_param;
 
3064
                if (state->param + pdisp < state->param)
 
3065
                        goto bad_param;
 
3066
 
 
3067
                memcpy(state->param+pdisp,smb_base(inbuf)+poff,
 
3068
                       pcnt);
 
3069
        }
 
3070
 
 
3071
        if (dcnt) {
 
3072
                if (ddisp+dcnt > state->total_data)
 
3073
                        goto bad_param;
 
3074
                if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
 
3075
                        goto bad_param;
 
3076
                if (ddisp > state->total_data)
 
3077
                        goto bad_param;
 
3078
                if ((smb_base(inbuf) + doff + dcnt > inbuf + size) ||
 
3079
                    (smb_base(inbuf) + doff + dcnt < smb_base(inbuf)))
 
3080
                        goto bad_param;
 
3081
                if (state->data + ddisp < state->data)
 
3082
                        goto bad_param;
 
3083
 
 
3084
                memcpy(state->data+ddisp, smb_base(inbuf)+doff,
 
3085
                       dcnt);      
 
3086
        }
 
3087
 
 
3088
        if ((state->received_param < state->total_param) ||
 
3089
            (state->received_data < state->total_data)) {
 
3090
                END_PROFILE(SMBnttranss);
 
3091
                return -1;
 
3092
        }
 
3093
 
 
3094
        /* construct_reply_common has done us the favor to pre-fill the
 
3095
         * command field with SMBnttranss which is wrong :-)
 
3096
         */
 
3097
        SCVAL(outbuf,smb_com,SMBnttrans);
 
3098
 
 
3099
        outsize = handle_nttrans(conn, state, inbuf, outbuf,
 
3100
                                 size, bufsize);
 
3101
 
 
3102
        DLIST_REMOVE(conn->pending_trans, state);
 
3103
        SAFE_FREE(state->data);
 
3104
        SAFE_FREE(state->param);
 
3105
        TALLOC_FREE(state);
 
3106
 
 
3107
        if (outsize == 0) {
 
3108
                END_PROFILE(SMBnttranss);
 
3109
                return(ERROR_DOS(ERRSRV,ERRnosupport));
 
3110
        }
 
3111
        
 
3112
        END_PROFILE(SMBnttranss);
 
3113
        return(outsize);
 
3114
 
 
3115
  bad_param:
 
3116
 
 
3117
        DEBUG(0,("reply_nttranss: invalid trans parameters\n"));
 
3118
        DLIST_REMOVE(conn->pending_trans, state);
 
3119
        SAFE_FREE(state->data);
 
3120
        SAFE_FREE(state->param);
 
3121
        TALLOC_FREE(state);
 
3122
        END_PROFILE(SMBnttranss);
3071
3123
        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3072
3124
}