root/source4/libcli/raw/rawfileinfo.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smbcli_parse_stream_info
  2. smb_raw_fileinfo_passthru_parse
  3. smb_raw_info_backend
  4. smb_raw_fileinfo_blob_send
  5. smb_raw_fileinfo_blob_recv
  6. smb_raw_pathinfo_blob_send
  7. smb_raw_getattr_send
  8. smb_raw_getattr_recv
  9. smb_raw_getattrE_send
  10. smb_raw_getattrE_recv
  11. smb_raw_fileinfo_send
  12. smb_raw_fileinfo_recv
  13. smb_raw_fileinfo
  14. smb_raw_pathinfo_send
  15. smb_raw_pathinfo_recv
  16. smb_raw_pathinfo

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    client trans2 operations
   4    Copyright (C) James Myers 2003
   5    Copyright (C) Andrew Tridgell 2003
   6    Copyright (C) James Peach 2007
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "libcli/raw/libcliraw.h"
  24 #include "libcli/raw/raw_proto.h"
  25 #include "librpc/gen_ndr/ndr_security.h"
  26 
  27 /* local macros to make the code more readable */
  28 #define FINFO_CHECK_MIN_SIZE(size) if (blob->length < (size)) { \
  29       DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected min of %d\n", \
  30                (int)blob->length, parms->generic.level, (size))); \
  31       return NT_STATUS_INFO_LENGTH_MISMATCH; \
  32 }
  33 #define FINFO_CHECK_SIZE(size) if (blob->length != (size)) { \
  34       DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected %d\n", \
  35                (int)blob->length, parms->generic.level, (size))); \
  36       return NT_STATUS_INFO_LENGTH_MISMATCH; \
  37 }
  38 
  39 /*
  40   parse a stream information structure
  41 */
  42 NTSTATUS smbcli_parse_stream_info(DATA_BLOB blob, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  43                                   struct stream_information *io)
  44 {
  45         uint32_t ofs = 0;
  46         io->num_streams = 0;
  47         io->streams = NULL;
  48 
  49         while (blob.length - ofs >= 24) {
  50                 uint_t n = io->num_streams;
  51                 uint32_t nlen, len;
  52                 bool ret;
  53                 void *vstr;
  54                 io->streams = 
  55                         talloc_realloc(mem_ctx, io->streams, struct stream_struct, n+1);
  56                 if (!io->streams) {
  57                         return NT_STATUS_NO_MEMORY;
  58                 }
  59                 nlen                      = IVAL(blob.data, ofs + 0x04);
  60                 io->streams[n].size       = BVAL(blob.data, ofs + 0x08);
  61                 io->streams[n].alloc_size = BVAL(blob.data, ofs + 0x10);
  62                 if (nlen > blob.length - (ofs + 24)) {
  63                         return NT_STATUS_INFO_LENGTH_MISMATCH;
  64                 }
  65                 ret = convert_string_talloc(io->streams, 
  66                                              CH_UTF16, CH_UNIX,
  67                                              blob.data+ofs+24, nlen, &vstr, NULL, false);
  68                 if (!ret) {
  69                         return NT_STATUS_ILLEGAL_CHARACTER;
  70                 }
  71                 io->streams[n].stream_name.s = (const char *)vstr;
  72                 io->streams[n].stream_name.private_length = nlen;
  73                 io->num_streams++;
  74                 len = IVAL(blob.data, ofs);
  75                 if (len > blob.length - ofs) {
  76                         return NT_STATUS_INFO_LENGTH_MISMATCH;
  77                 }
  78                 if (len == 0) break;
  79                 ofs += len;
  80         }
  81 
  82         return NT_STATUS_OK;
  83 }
  84 
  85 /*
  86   parse the fsinfo 'passthru' level replies
  87 */
  88 NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
  89                                          enum smb_fileinfo_level level,
  90                                          union smb_fileinfo *parms)
  91 {       
  92         switch (level) {
  93         case RAW_FILEINFO_BASIC_INFORMATION:
  94                 /* some servers return 40 bytes and some 36. w2k3 return 40, so thats
  95                    what we should do, but we need to accept 36 */
  96                 if (blob->length != 36) {
  97                         FINFO_CHECK_SIZE(40);
  98                 }
  99                 parms->basic_info.out.create_time = smbcli_pull_nttime(blob->data, 0);
 100                 parms->basic_info.out.access_time = smbcli_pull_nttime(blob->data, 8);
 101                 parms->basic_info.out.write_time  = smbcli_pull_nttime(blob->data, 16);
 102                 parms->basic_info.out.change_time = smbcli_pull_nttime(blob->data, 24);
 103                 parms->basic_info.out.attrib      = IVAL(blob->data, 32);
 104                 return NT_STATUS_OK;
 105 
 106         case RAW_FILEINFO_STANDARD_INFORMATION:
 107                 FINFO_CHECK_SIZE(24);
 108                 parms->standard_info.out.alloc_size =     BVAL(blob->data, 0);
 109                 parms->standard_info.out.size =           BVAL(blob->data, 8);
 110                 parms->standard_info.out.nlink =          IVAL(blob->data, 16);
 111                 parms->standard_info.out.delete_pending = CVAL(blob->data, 20);
 112                 parms->standard_info.out.directory =      CVAL(blob->data, 21);
 113                 return NT_STATUS_OK;
 114 
 115         case RAW_FILEINFO_EA_INFORMATION:
 116                 FINFO_CHECK_SIZE(4);
 117                 parms->ea_info.out.ea_size = IVAL(blob->data, 0);
 118                 return NT_STATUS_OK;
 119 
 120         case RAW_FILEINFO_NAME_INFORMATION:
 121                 FINFO_CHECK_MIN_SIZE(4);
 122                 smbcli_blob_pull_string(NULL, mem_ctx, blob, 
 123                                         &parms->name_info.out.fname, 0, 4, STR_UNICODE);
 124                 return NT_STATUS_OK;
 125 
 126         case RAW_FILEINFO_ALL_INFORMATION:
 127                 FINFO_CHECK_MIN_SIZE(72);
 128                 parms->all_info.out.create_time =           smbcli_pull_nttime(blob->data, 0);
 129                 parms->all_info.out.access_time =           smbcli_pull_nttime(blob->data, 8);
 130                 parms->all_info.out.write_time =            smbcli_pull_nttime(blob->data, 16);
 131                 parms->all_info.out.change_time =           smbcli_pull_nttime(blob->data, 24);
 132                 parms->all_info.out.attrib =                IVAL(blob->data, 32);
 133                 parms->all_info.out.alloc_size =            BVAL(blob->data, 40);
 134                 parms->all_info.out.size =                  BVAL(blob->data, 48);
 135                 parms->all_info.out.nlink =                 IVAL(blob->data, 56);
 136                 parms->all_info.out.delete_pending =        CVAL(blob->data, 60);
 137                 parms->all_info.out.directory =             CVAL(blob->data, 61);
 138 #if 1
 139                 parms->all_info.out.ea_size =               IVAL(blob->data, 64);
 140                 smbcli_blob_pull_string(NULL, mem_ctx, blob,
 141                                         &parms->all_info.out.fname, 68, 72, STR_UNICODE);
 142 #else
 143                 /* this is what the CIFS spec says - and its totally
 144                    wrong, but its useful having it here so we can
 145                    quickly adapt to broken servers when running
 146                    tests */
 147                 parms->all_info.out.ea_size =               IVAL(blob->data, 72);
 148                 /* access flags 4 bytes at 76
 149                    current_position 8 bytes at 80
 150                    mode 4 bytes at 88
 151                    alignment 4 bytes at 92
 152                 */
 153                 smbcli_blob_pull_string(NULL, mem_ctx, blob,
 154                                         &parms->all_info.out.fname, 96, 100, STR_UNICODE);
 155 #endif
 156                 return NT_STATUS_OK;
 157 
 158         case RAW_FILEINFO_ALT_NAME_INFORMATION:
 159                 FINFO_CHECK_MIN_SIZE(4);
 160                 smbcli_blob_pull_string(NULL, mem_ctx, blob, 
 161                                         &parms->alt_name_info.out.fname, 0, 4, STR_UNICODE);
 162                 return NT_STATUS_OK;
 163 
 164         case RAW_FILEINFO_STREAM_INFORMATION:
 165                 return smbcli_parse_stream_info(*blob, mem_ctx, &parms->stream_info.out);
 166 
 167         case RAW_FILEINFO_INTERNAL_INFORMATION:
 168                 FINFO_CHECK_SIZE(8);
 169                 parms->internal_information.out.file_id = BVAL(blob->data, 0);
 170                 return NT_STATUS_OK;
 171 
 172         case RAW_FILEINFO_ACCESS_INFORMATION:
 173                 FINFO_CHECK_SIZE(4);
 174                 parms->access_information.out.access_flags = IVAL(blob->data, 0);
 175                 return NT_STATUS_OK;
 176 
 177         case RAW_FILEINFO_POSITION_INFORMATION:
 178                 FINFO_CHECK_SIZE(8);
 179                 parms->position_information.out.position = BVAL(blob->data, 0);
 180                 return NT_STATUS_OK;
 181 
 182         case RAW_FILEINFO_MODE_INFORMATION:
 183                 FINFO_CHECK_SIZE(4);
 184                 parms->mode_information.out.mode = IVAL(blob->data, 0);
 185                 return NT_STATUS_OK;
 186 
 187         case RAW_FILEINFO_ALIGNMENT_INFORMATION:
 188                 FINFO_CHECK_SIZE(4);
 189                 parms->alignment_information.out.alignment_requirement 
 190                         = IVAL(blob->data, 0);
 191                 return NT_STATUS_OK;
 192 
 193         case RAW_FILEINFO_COMPRESSION_INFORMATION:
 194                 FINFO_CHECK_SIZE(16);
 195                 parms->compression_info.out.compressed_size = BVAL(blob->data,  0);
 196                 parms->compression_info.out.format          = SVAL(blob->data,  8);
 197                 parms->compression_info.out.unit_shift      = CVAL(blob->data, 10);
 198                 parms->compression_info.out.chunk_shift     = CVAL(blob->data, 11);
 199                 parms->compression_info.out.cluster_shift   = CVAL(blob->data, 12);
 200                 /* 3 bytes of padding */
 201                 return NT_STATUS_OK;
 202 
 203         case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:             
 204                 FINFO_CHECK_SIZE(56);
 205                 parms->network_open_information.out.create_time = smbcli_pull_nttime(blob->data,  0);
 206                 parms->network_open_information.out.access_time = smbcli_pull_nttime(blob->data,  8);
 207                 parms->network_open_information.out.write_time =  smbcli_pull_nttime(blob->data, 16);
 208                 parms->network_open_information.out.change_time = smbcli_pull_nttime(blob->data, 24);
 209                 parms->network_open_information.out.alloc_size =             BVAL(blob->data, 32);
 210                 parms->network_open_information.out.size =                   BVAL(blob->data, 40);
 211                 parms->network_open_information.out.attrib =                 IVAL(blob->data, 48);
 212                 return NT_STATUS_OK;
 213 
 214         case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
 215                 FINFO_CHECK_SIZE(8);
 216                 parms->attribute_tag_information.out.attrib =      IVAL(blob->data, 0);
 217                 parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4);
 218                 return NT_STATUS_OK;
 219 
 220         case RAW_FILEINFO_SMB2_ALL_EAS:
 221                 FINFO_CHECK_MIN_SIZE(4);
 222                 return ea_pull_list_chained(blob, mem_ctx, 
 223                                             &parms->all_eas.out.num_eas,
 224                                             &parms->all_eas.out.eas);
 225 
 226         case RAW_FILEINFO_SMB2_ALL_INFORMATION:
 227                 FINFO_CHECK_MIN_SIZE(0x64);
 228                 parms->all_info2.out.create_time    = smbcli_pull_nttime(blob->data, 0x00);
 229                 parms->all_info2.out.access_time    = smbcli_pull_nttime(blob->data, 0x08);
 230                 parms->all_info2.out.write_time     = smbcli_pull_nttime(blob->data, 0x10);
 231                 parms->all_info2.out.change_time    = smbcli_pull_nttime(blob->data, 0x18);
 232                 parms->all_info2.out.attrib         = IVAL(blob->data, 0x20);
 233                 parms->all_info2.out.unknown1       = IVAL(blob->data, 0x24);
 234                 parms->all_info2.out.alloc_size     = BVAL(blob->data, 0x28);
 235                 parms->all_info2.out.size           = BVAL(blob->data, 0x30);
 236                 parms->all_info2.out.nlink          = IVAL(blob->data, 0x38);
 237                 parms->all_info2.out.delete_pending = CVAL(blob->data, 0x3C);
 238                 parms->all_info2.out.directory      = CVAL(blob->data, 0x3D);
 239                 /* 0x3E-0x3F padding */
 240                 parms->all_info2.out.file_id        = BVAL(blob->data, 0x40);
 241                 parms->all_info2.out.ea_size        = IVAL(blob->data, 0x48);
 242                 parms->all_info2.out.access_mask    = IVAL(blob->data, 0x4C);
 243                 parms->all_info2.out.position       = BVAL(blob->data, 0x50);
 244                 parms->all_info2.out.mode           = IVAL(blob->data, 0x58);
 245                 parms->all_info2.out.alignment_requirement = IVAL(blob->data, 0x5C);
 246                 smbcli_blob_pull_string(NULL, mem_ctx, blob,
 247                                         &parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE);
 248                 return NT_STATUS_OK;
 249 
 250         case RAW_FILEINFO_SEC_DESC: {
 251                 enum ndr_err_code ndr_err;
 252 
 253                 parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor);
 254                 NT_STATUS_HAVE_NO_MEMORY(parms->query_secdesc.out.sd);
 255 
 256                 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, NULL, 
 257                                                parms->query_secdesc.out.sd,
 258                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
 259                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 260                         return ndr_map_error2ntstatus(ndr_err);
 261                 }
 262 
 263                 return NT_STATUS_OK;
 264         }
 265 
 266         default:
 267                 break;
 268         }
 269 
 270         return NT_STATUS_INVALID_LEVEL;
 271 }
 272 
 273 
 274 /****************************************************************************
 275  Handle qfileinfo/qpathinfo trans2 backend.
 276 ****************************************************************************/
 277 static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
     /* [<][>][^][v][top][bottom][index][help] */
 278                                      TALLOC_CTX *mem_ctx,
 279                                      union smb_fileinfo *parms, 
 280                                      DATA_BLOB *blob)
 281 {       
 282         switch (parms->generic.level) {
 283         case RAW_FILEINFO_GENERIC:
 284         case RAW_FILEINFO_GETATTR:
 285         case RAW_FILEINFO_GETATTRE:
 286         case RAW_FILEINFO_SEC_DESC:
 287                 /* not handled here */
 288                 return NT_STATUS_INVALID_LEVEL;
 289 
 290         case RAW_FILEINFO_STANDARD:
 291                 FINFO_CHECK_SIZE(22);
 292                 parms->standard.out.create_time = raw_pull_dos_date2(session->transport,
 293                                                                      blob->data +  0);
 294                 parms->standard.out.access_time = raw_pull_dos_date2(session->transport,
 295                                                                      blob->data +  4);
 296                 parms->standard.out.write_time =  raw_pull_dos_date2(session->transport,
 297                                                                      blob->data +  8);
 298                 parms->standard.out.size =        IVAL(blob->data,             12);
 299                 parms->standard.out.alloc_size =  IVAL(blob->data,             16);
 300                 parms->standard.out.attrib =      SVAL(blob->data,             20);
 301                 return NT_STATUS_OK;
 302 
 303         case RAW_FILEINFO_EA_SIZE:
 304                 FINFO_CHECK_SIZE(26);
 305                 parms->ea_size.out.create_time = raw_pull_dos_date2(session->transport,
 306                                                                     blob->data +  0);
 307                 parms->ea_size.out.access_time = raw_pull_dos_date2(session->transport,
 308                                                                     blob->data +  4);
 309                 parms->ea_size.out.write_time =  raw_pull_dos_date2(session->transport,
 310                                                                     blob->data +  8);
 311                 parms->ea_size.out.size =        IVAL(blob->data,             12);
 312                 parms->ea_size.out.alloc_size =  IVAL(blob->data,             16);
 313                 parms->ea_size.out.attrib =      SVAL(blob->data,             20);
 314                 parms->ea_size.out.ea_size =     IVAL(blob->data,             22);
 315                 return NT_STATUS_OK;
 316 
 317         case RAW_FILEINFO_EA_LIST:
 318                 FINFO_CHECK_MIN_SIZE(4);
 319                 return ea_pull_list(blob, mem_ctx, 
 320                                     &parms->ea_list.out.num_eas,
 321                                     &parms->ea_list.out.eas);
 322 
 323         case RAW_FILEINFO_ALL_EAS:
 324                 FINFO_CHECK_MIN_SIZE(4);
 325                 return ea_pull_list(blob, mem_ctx, 
 326                                     &parms->all_eas.out.num_eas,
 327                                     &parms->all_eas.out.eas);
 328 
 329         case RAW_FILEINFO_IS_NAME_VALID:
 330                 /* no data! */
 331                 FINFO_CHECK_SIZE(0);
 332                 return NT_STATUS_OK;
 333 
 334         case RAW_FILEINFO_BASIC_INFO:
 335         case RAW_FILEINFO_BASIC_INFORMATION:
 336                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 337                                                        RAW_FILEINFO_BASIC_INFORMATION, parms);
 338 
 339         case RAW_FILEINFO_STANDARD_INFO:
 340         case RAW_FILEINFO_STANDARD_INFORMATION:
 341                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 342                                                        RAW_FILEINFO_STANDARD_INFORMATION, parms);
 343 
 344         case RAW_FILEINFO_EA_INFO:
 345         case RAW_FILEINFO_EA_INFORMATION:
 346                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 347                                                        RAW_FILEINFO_EA_INFORMATION, parms);
 348 
 349         case RAW_FILEINFO_NAME_INFO:
 350         case RAW_FILEINFO_NAME_INFORMATION:
 351                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 352                                                        RAW_FILEINFO_NAME_INFORMATION, parms);
 353 
 354         case RAW_FILEINFO_ALL_INFO:
 355         case RAW_FILEINFO_ALL_INFORMATION:
 356                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 357                                                        RAW_FILEINFO_ALL_INFORMATION, parms);
 358 
 359         case RAW_FILEINFO_ALT_NAME_INFO:
 360         case RAW_FILEINFO_ALT_NAME_INFORMATION:
 361                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 362                                                        RAW_FILEINFO_ALT_NAME_INFORMATION, parms);
 363 
 364         case RAW_FILEINFO_STREAM_INFO:
 365         case RAW_FILEINFO_STREAM_INFORMATION:
 366                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 367                                                        RAW_FILEINFO_STREAM_INFORMATION, parms);
 368 
 369         case RAW_FILEINFO_INTERNAL_INFORMATION:
 370                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 371                                                        RAW_FILEINFO_INTERNAL_INFORMATION, parms);
 372 
 373         case RAW_FILEINFO_ACCESS_INFORMATION:
 374                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 375                                                        RAW_FILEINFO_ACCESS_INFORMATION, parms);
 376 
 377         case RAW_FILEINFO_POSITION_INFORMATION:
 378                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 379                                                        RAW_FILEINFO_POSITION_INFORMATION, parms);
 380 
 381         case RAW_FILEINFO_MODE_INFORMATION:
 382                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 383                                                        RAW_FILEINFO_MODE_INFORMATION, parms);
 384 
 385         case RAW_FILEINFO_ALIGNMENT_INFORMATION:
 386                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 387                                                        RAW_FILEINFO_ALIGNMENT_INFORMATION, parms);
 388 
 389         case RAW_FILEINFO_COMPRESSION_INFO:
 390         case RAW_FILEINFO_COMPRESSION_INFORMATION:
 391                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 392                                                        RAW_FILEINFO_COMPRESSION_INFORMATION, parms);
 393 
 394         case RAW_FILEINFO_UNIX_BASIC:
 395                 FINFO_CHECK_SIZE(100);
 396                 parms->unix_basic_info.out.end_of_file        =            BVAL(blob->data,  0);
 397                 parms->unix_basic_info.out.num_bytes          =            BVAL(blob->data,  8);
 398                 parms->unix_basic_info.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
 399                 parms->unix_basic_info.out.access_time        = smbcli_pull_nttime(blob->data, 24);
 400                 parms->unix_basic_info.out.change_time        = smbcli_pull_nttime(blob->data, 32);
 401                 parms->unix_basic_info.out.uid                =            BVAL(blob->data, 40);
 402                 parms->unix_basic_info.out.gid                =            BVAL(blob->data, 48);
 403                 parms->unix_basic_info.out.file_type          =            IVAL(blob->data, 52);
 404                 parms->unix_basic_info.out.dev_major          =            BVAL(blob->data, 60);
 405                 parms->unix_basic_info.out.dev_minor          =            BVAL(blob->data, 68);
 406                 parms->unix_basic_info.out.unique_id          =            BVAL(blob->data, 76);
 407                 parms->unix_basic_info.out.permissions        =            BVAL(blob->data, 84);
 408                 parms->unix_basic_info.out.nlink              =            BVAL(blob->data, 92);
 409                 return NT_STATUS_OK;
 410 
 411         case RAW_FILEINFO_UNIX_INFO2:
 412                 FINFO_CHECK_SIZE(116);
 413                 parms->unix_info2.out.end_of_file       = BVAL(blob->data,  0);
 414                 parms->unix_info2.out.num_bytes         = BVAL(blob->data,  8);
 415                 parms->unix_info2.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
 416                 parms->unix_info2.out.access_time       = smbcli_pull_nttime(blob->data, 24);
 417                 parms->unix_info2.out.change_time       = smbcli_pull_nttime(blob->data, 32);
 418                 parms->unix_info2.out.uid               = BVAL(blob->data, 40);
 419                 parms->unix_info2.out.gid               = BVAL(blob->data, 48);
 420                 parms->unix_info2.out.file_type         = IVAL(blob->data, 52);
 421                 parms->unix_info2.out.dev_major         = BVAL(blob->data, 60);
 422                 parms->unix_info2.out.dev_minor         = BVAL(blob->data, 68);
 423                 parms->unix_info2.out.unique_id         = BVAL(blob->data, 76);
 424                 parms->unix_info2.out.permissions       = BVAL(blob->data, 84);
 425                 parms->unix_info2.out.nlink             = BVAL(blob->data, 92);
 426                 parms->unix_info2.out.create_time       = smbcli_pull_nttime(blob->data, 100);
 427                 parms->unix_info2.out.file_flags        = IVAL(blob->data, 108);
 428                 parms->unix_info2.out.flags_mask        = IVAL(blob->data, 112);
 429                 return NT_STATUS_OK;
 430 
 431         case RAW_FILEINFO_UNIX_LINK:
 432                 smbcli_blob_pull_string(session, mem_ctx, blob, 
 433                                      &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE);
 434                 return NT_STATUS_OK;
 435                 
 436         case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:             
 437                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 438                                                        RAW_FILEINFO_NETWORK_OPEN_INFORMATION, parms);
 439 
 440         case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
 441                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 442                                                        RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, parms);
 443 
 444         case RAW_FILEINFO_SMB2_ALL_INFORMATION:
 445                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 446                                                        RAW_FILEINFO_SMB2_ALL_INFORMATION, parms);
 447 
 448         case RAW_FILEINFO_SMB2_ALL_EAS:
 449                 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
 450                                                        RAW_FILEINFO_SMB2_ALL_EAS, parms);
 451 
 452         }
 453 
 454         return NT_STATUS_INVALID_LEVEL;
 455 }
 456 
 457 
 458 /****************************************************************************
 459  Very raw query file info - returns param/data blobs - (async send)
 460 ****************************************************************************/
 461 static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 462                                                          uint16_t fnum, 
 463                                                          uint16_t info_level,
 464                                                          DATA_BLOB data)
 465 {
 466         struct smb_trans2 tp;
 467         uint16_t setup = TRANSACT2_QFILEINFO;
 468         struct smbcli_request *req;
 469         TALLOC_CTX *mem_ctx = talloc_init("raw_fileinfo");
 470         
 471         tp.in.max_setup = 0;
 472         tp.in.flags = 0; 
 473         tp.in.timeout = 0;
 474         tp.in.setup_count = 1;
 475         tp.in.data = data;
 476         tp.in.max_param = 2;
 477         tp.in.max_data = 0xFFFF;
 478         tp.in.setup = &setup;
 479         
 480         tp.in.params = data_blob_talloc(mem_ctx, NULL, 4);
 481         if (!tp.in.params.data) {
 482                 talloc_free(mem_ctx);
 483                 return NULL;
 484         }
 485 
 486         SSVAL(tp.in.params.data, 0, fnum);
 487         SSVAL(tp.in.params.data, 2, info_level);
 488 
 489         req = smb_raw_trans2_send(tree, &tp);
 490 
 491         talloc_free(mem_ctx);
 492 
 493         return req;
 494 }
 495 
 496 
 497 /****************************************************************************
 498  Very raw query file info - returns param/data blobs - (async recv)
 499 ****************************************************************************/
 500 static NTSTATUS smb_raw_fileinfo_blob_recv(struct smbcli_request *req,
     /* [<][>][^][v][top][bottom][index][help] */
 501                                            TALLOC_CTX *mem_ctx,
 502                                            DATA_BLOB *blob)
 503 {
 504         struct smb_trans2 tp;
 505         NTSTATUS status = smb_raw_trans2_recv(req, mem_ctx, &tp);
 506         if (NT_STATUS_IS_OK(status)) {
 507                 *blob = tp.out.data;
 508         }
 509         return status;
 510 }
 511 
 512 /****************************************************************************
 513  Very raw query path info - returns param/data blobs (async send)
 514 ****************************************************************************/
 515 static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 516                                                          const char *fname,
 517                                                          uint16_t info_level,
 518                                                          DATA_BLOB data)
 519 {
 520         struct smb_trans2 tp;
 521         uint16_t setup = TRANSACT2_QPATHINFO;
 522         struct smbcli_request *req;
 523         TALLOC_CTX *mem_ctx = talloc_init("raw_pathinfo");
 524 
 525         tp.in.max_setup = 0;
 526         tp.in.flags = 0; 
 527         tp.in.timeout = 0;
 528         tp.in.setup_count = 1;
 529         tp.in.data = data;
 530         tp.in.max_param = 2;
 531         tp.in.max_data = 0xFFFF;
 532         tp.in.setup = &setup;
 533         
 534         tp.in.params = data_blob_talloc(mem_ctx, NULL, 6);
 535         if (!tp.in.params.data) {
 536                 talloc_free(mem_ctx);
 537                 return NULL;
 538         }
 539 
 540         SSVAL(tp.in.params.data, 0, info_level);
 541         SIVAL(tp.in.params.data, 2, 0);
 542         smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params,
 543                                fname, STR_TERMINATE);
 544         
 545         req = smb_raw_trans2_send(tree, &tp);
 546 
 547         talloc_free(mem_ctx);
 548 
 549         return req;
 550 }
 551 
 552 /****************************************************************************
 553  send a SMBgetatr (async send)
 554 ****************************************************************************/
 555 static struct smbcli_request *smb_raw_getattr_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 556                                                 union smb_fileinfo *parms)
 557 {
 558         struct smbcli_request *req;
 559         
 560         req = smbcli_request_setup(tree, SMBgetatr, 0, 0);
 561         if (!req) return NULL;
 562 
 563         smbcli_req_append_ascii4(req, parms->getattr.in.file.path, STR_TERMINATE);
 564         
 565         if (!smbcli_request_send(req)) {
 566                 smbcli_request_destroy(req);
 567                 return NULL;
 568         }
 569 
 570         return req;
 571 }
 572 
 573 /****************************************************************************
 574  send a SMBgetatr (async recv)
 575 ****************************************************************************/
 576 static NTSTATUS smb_raw_getattr_recv(struct smbcli_request *req,
     /* [<][>][^][v][top][bottom][index][help] */
 577                                      union smb_fileinfo *parms)
 578 {
 579         if (!smbcli_request_receive(req) ||
 580             smbcli_request_is_error(req)) {
 581                 return smbcli_request_destroy(req);
 582         }
 583 
 584         SMBCLI_CHECK_WCT(req, 10);
 585         parms->getattr.out.attrib =     SVAL(req->in.vwv, VWV(0));
 586         parms->getattr.out.write_time = raw_pull_dos_date3(req->transport,
 587                                                            req->in.vwv + VWV(1));
 588         parms->getattr.out.size =       IVAL(req->in.vwv, VWV(3));
 589 
 590 failed:
 591         return smbcli_request_destroy(req);
 592 }
 593 
 594 
 595 /****************************************************************************
 596  Handle SMBgetattrE (async send)
 597 ****************************************************************************/
 598 static struct smbcli_request *smb_raw_getattrE_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 599                                                  union smb_fileinfo *parms)
 600 {
 601         struct smbcli_request *req;
 602         
 603         req = smbcli_request_setup(tree, SMBgetattrE, 1, 0);
 604         if (!req) return NULL;
 605         
 606         SSVAL(req->out.vwv, VWV(0), parms->getattre.in.file.fnum);
 607         if (!smbcli_request_send(req)) {
 608                 smbcli_request_destroy(req);
 609                 return NULL;
 610         }
 611 
 612         return req;
 613 }
 614 
 615 /****************************************************************************
 616  Handle SMBgetattrE (async send)
 617 ****************************************************************************/
 618 static NTSTATUS smb_raw_getattrE_recv(struct smbcli_request *req,
     /* [<][>][^][v][top][bottom][index][help] */
 619                                       union smb_fileinfo *parms)
 620 {
 621         if (!smbcli_request_receive(req) ||
 622             smbcli_request_is_error(req)) {
 623                 return smbcli_request_destroy(req);
 624         }
 625         
 626         SMBCLI_CHECK_WCT(req, 11);
 627         parms->getattre.out.create_time =   raw_pull_dos_date2(req->transport,
 628                                                                req->in.vwv + VWV(0));
 629         parms->getattre.out.access_time =   raw_pull_dos_date2(req->transport,
 630                                                                req->in.vwv + VWV(2));
 631         parms->getattre.out.write_time  =   raw_pull_dos_date2(req->transport,
 632                                                                req->in.vwv + VWV(4));
 633         parms->getattre.out.size =          IVAL(req->in.vwv,             VWV(6));
 634         parms->getattre.out.alloc_size =    IVAL(req->in.vwv,             VWV(8));
 635         parms->getattre.out.attrib =        SVAL(req->in.vwv,             VWV(10));
 636 
 637 failed:
 638         return smbcli_request_destroy(req);
 639 }
 640 
 641 
 642 /****************************************************************************
 643  Query file info (async send)
 644 ****************************************************************************/
 645 struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 646                                              union smb_fileinfo *parms)
 647 {
 648         DATA_BLOB data;
 649         struct smbcli_request *req;
 650 
 651         /* pass off the non-trans2 level to specialised functions */
 652         if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
 653                 return smb_raw_getattrE_send(tree, parms);
 654         }
 655         if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
 656                 return smb_raw_query_secdesc_send(tree, parms);
 657         }
 658         if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
 659                 return NULL;
 660         }
 661 
 662         data = data_blob(NULL, 0);
 663 
 664         if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
 665                 if (!ea_push_name_list(tree, 
 666                                        &data,
 667                                        parms->ea_list.in.num_names,
 668                                        parms->ea_list.in.ea_names)) {
 669                         return NULL;
 670                 }
 671         }
 672 
 673         req = smb_raw_fileinfo_blob_send(tree, 
 674                                          parms->generic.in.file.fnum,
 675                                          parms->generic.level, data);
 676 
 677         data_blob_free(&data);
 678 
 679         return req;
 680 }
 681 
 682 /****************************************************************************
 683  Query file info (async recv)
 684 ****************************************************************************/
 685 NTSTATUS smb_raw_fileinfo_recv(struct smbcli_request *req,
     /* [<][>][^][v][top][bottom][index][help] */
 686                                TALLOC_CTX *mem_ctx,
 687                                union smb_fileinfo *parms)
 688 {
 689         DATA_BLOB blob;
 690         NTSTATUS status;
 691         struct smbcli_session *session = req?req->session:NULL;
 692 
 693         if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
 694                 return smb_raw_getattrE_recv(req, parms);
 695         }
 696         if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
 697                 return smb_raw_query_secdesc_recv(req, mem_ctx, parms);
 698         }
 699         if (parms->generic.level == RAW_FILEINFO_GETATTR) {
 700                 return smb_raw_getattr_recv(req, parms);
 701         }
 702 
 703         status = smb_raw_fileinfo_blob_recv(req, mem_ctx, &blob);
 704         if (!NT_STATUS_IS_OK(status)) {
 705                 return status;
 706         }
 707 
 708         return smb_raw_info_backend(session, mem_ctx, parms, &blob);
 709 }
 710 
 711 /****************************************************************************
 712  Query file info (sync interface)
 713 ****************************************************************************/
 714 _PUBLIC_ NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 715                           TALLOC_CTX *mem_ctx,
 716                           union smb_fileinfo *parms)
 717 {
 718         struct smbcli_request *req = smb_raw_fileinfo_send(tree, parms);
 719         return smb_raw_fileinfo_recv(req, mem_ctx, parms);
 720 }
 721 
 722 /****************************************************************************
 723  Query path info (async send)
 724 ****************************************************************************/
 725 _PUBLIC_ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 726                                              union smb_fileinfo *parms)
 727 {
 728         DATA_BLOB data;
 729         struct smbcli_request *req;
 730 
 731         if (parms->generic.level == RAW_FILEINFO_GETATTR) {
 732                 return smb_raw_getattr_send(tree, parms);
 733         }
 734         if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
 735                 return NULL;
 736         }
 737         
 738         data = data_blob(NULL, 0);
 739 
 740         if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
 741                 if (!ea_push_name_list(tree, 
 742                                        &data,
 743                                        parms->ea_list.in.num_names,
 744                                        parms->ea_list.in.ea_names)) {
 745                         return NULL;
 746                 }
 747         }
 748 
 749         req = smb_raw_pathinfo_blob_send(tree, parms->generic.in.file.path,
 750                                          parms->generic.level, data);
 751         data_blob_free(&data);
 752 
 753         return req;
 754 }
 755 
 756 /****************************************************************************
 757  Query path info (async recv)
 758 ****************************************************************************/
 759 _PUBLIC_ NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req,
     /* [<][>][^][v][top][bottom][index][help] */
 760                                TALLOC_CTX *mem_ctx,
 761                                union smb_fileinfo *parms)
 762 {
 763         /* recv is idential to fileinfo */
 764         return smb_raw_fileinfo_recv(req, mem_ctx, parms);
 765 }
 766 
 767 /****************************************************************************
 768  Query path info (sync interface)
 769 ****************************************************************************/
 770 _PUBLIC_ NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 771                           TALLOC_CTX *mem_ctx,
 772                           union smb_fileinfo *parms)
 773 {
 774         struct smbcli_request *req = smb_raw_pathinfo_send(tree, parms);
 775         return smb_raw_pathinfo_recv(req, mem_ctx, parms);
 776 }

/* [<][>][^][v][top][bottom][index][help] */