6f875f51a7717874d5ca332bf4aacf2cc709303e
[samba.git] / source4 / libcli / raw / rawfileinfo.c
1 /* 
2    Unix SMB/CIFS implementation.
3    client trans2 operations
4    Copyright (C) James Myers 2003
5    Copyright (C) Andrew Tridgell 2003
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "libcli/raw/libcliraw.h"
24
25 /* local macros to make the code more readable */
26 #define FINFO_CHECK_MIN_SIZE(size) if (blob->length < (size)) { \
27       DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected min of %d\n", \
28                blob->length, parms->generic.level, (size))); \
29       return NT_STATUS_INFO_LENGTH_MISMATCH; \
30 }
31 #define FINFO_CHECK_SIZE(size) if (blob->length != (size)) { \
32       DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected %d\n", \
33                blob->length, parms->generic.level, (size))); \
34       return NT_STATUS_INFO_LENGTH_MISMATCH; \
35 }
36
37 /****************************************************************************
38  Handle qfileinfo/qpathinfo trans2 backend.
39 ****************************************************************************/
40 static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
41                                      TALLOC_CTX *mem_ctx,
42                                      union smb_fileinfo *parms, 
43                                      DATA_BLOB *blob)
44 {       
45         uint_t len, ofs;
46
47         switch (parms->generic.level) {
48         case RAW_FILEINFO_GENERIC:
49         case RAW_FILEINFO_GETATTR:
50         case RAW_FILEINFO_GETATTRE:
51         case RAW_FILEINFO_SEC_DESC:
52                 /* not handled here */
53                 return NT_STATUS_INVALID_LEVEL;
54
55         case RAW_FILEINFO_STANDARD:
56                 FINFO_CHECK_SIZE(22);
57                 parms->standard.out.create_time = raw_pull_dos_date2(session->transport,
58                                                                      blob->data +  0);
59                 parms->standard.out.access_time = raw_pull_dos_date2(session->transport,
60                                                                      blob->data +  4);
61                 parms->standard.out.write_time =  raw_pull_dos_date2(session->transport,
62                                                                      blob->data +  8);
63                 parms->standard.out.size =        IVAL(blob->data,             12);
64                 parms->standard.out.alloc_size =  IVAL(blob->data,             16);
65                 parms->standard.out.attrib =      SVAL(blob->data,             20);
66                 return NT_STATUS_OK;
67
68         case RAW_FILEINFO_EA_SIZE:
69                 FINFO_CHECK_SIZE(26);
70                 parms->ea_size.out.create_time = raw_pull_dos_date2(session->transport,
71                                                                     blob->data +  0);
72                 parms->ea_size.out.access_time = raw_pull_dos_date2(session->transport,
73                                                                     blob->data +  4);
74                 parms->ea_size.out.write_time =  raw_pull_dos_date2(session->transport,
75                                                                     blob->data +  8);
76                 parms->ea_size.out.size =        IVAL(blob->data,             12);
77                 parms->ea_size.out.alloc_size =  IVAL(blob->data,             16);
78                 parms->ea_size.out.attrib =      SVAL(blob->data,             20);
79                 parms->ea_size.out.ea_size =     IVAL(blob->data,             22);
80                 return NT_STATUS_OK;
81
82         case RAW_FILEINFO_ALL_EAS:
83                 FINFO_CHECK_MIN_SIZE(4);
84                 return ea_pull_list(blob, mem_ctx, 
85                                     &parms->all_eas.out.num_eas,
86                                     &parms->all_eas.out.eas);
87
88         case RAW_FILEINFO_IS_NAME_VALID:
89                 /* no data! */
90                 FINFO_CHECK_SIZE(0);
91                 return NT_STATUS_OK;
92
93         case RAW_FILEINFO_BASIC_INFO:
94         case RAW_FILEINFO_BASIC_INFORMATION:
95                 /* some servers return 40 bytes and some 36. w2k3 return 40, so thats
96                    what we should do, but we need to accept 36 */
97                 if (blob->length != 36) {
98                         FINFO_CHECK_SIZE(40);
99                 }
100                 parms->basic_info.out.create_time = smbcli_pull_nttime(blob->data, 0);
101                 parms->basic_info.out.access_time = smbcli_pull_nttime(blob->data, 8);
102                 parms->basic_info.out.write_time =  smbcli_pull_nttime(blob->data, 16);
103                 parms->basic_info.out.change_time = smbcli_pull_nttime(blob->data, 24);
104                 parms->basic_info.out.attrib =                 IVAL(blob->data, 32);
105                 return NT_STATUS_OK;
106
107         case RAW_FILEINFO_STANDARD_INFO:
108         case RAW_FILEINFO_STANDARD_INFORMATION:
109                 FINFO_CHECK_SIZE(24);
110                 parms->standard_info.out.alloc_size =     BVAL(blob->data, 0);
111                 parms->standard_info.out.size =           BVAL(blob->data, 8);
112                 parms->standard_info.out.nlink =          IVAL(blob->data, 16);
113                 parms->standard_info.out.delete_pending = CVAL(blob->data, 20);
114                 parms->standard_info.out.directory =      CVAL(blob->data, 21);
115                 return NT_STATUS_OK;
116
117         case RAW_FILEINFO_EA_INFO:
118         case RAW_FILEINFO_EA_INFORMATION:
119                 FINFO_CHECK_SIZE(4);
120                 parms->ea_info.out.ea_size = IVAL(blob->data, 0);
121                 return NT_STATUS_OK;
122
123         case RAW_FILEINFO_NAME_INFO:
124         case RAW_FILEINFO_NAME_INFORMATION:
125                 FINFO_CHECK_MIN_SIZE(4);
126                 smbcli_blob_pull_string(session, mem_ctx, blob, 
127                                      &parms->name_info.out.fname, 0, 4, STR_UNICODE);
128                 return NT_STATUS_OK;
129
130         case RAW_FILEINFO_ALL_INFO:
131         case RAW_FILEINFO_ALL_INFORMATION:
132                 FINFO_CHECK_MIN_SIZE(72);
133                 parms->all_info.out.create_time =           smbcli_pull_nttime(blob->data, 0);
134                 parms->all_info.out.access_time =           smbcli_pull_nttime(blob->data, 8);
135                 parms->all_info.out.write_time =            smbcli_pull_nttime(blob->data, 16);
136                 parms->all_info.out.change_time =           smbcli_pull_nttime(blob->data, 24);
137                 parms->all_info.out.attrib =                IVAL(blob->data, 32);
138                 parms->all_info.out.alloc_size =            BVAL(blob->data, 40);
139                 parms->all_info.out.size =                  BVAL(blob->data, 48);
140                 parms->all_info.out.nlink =                 IVAL(blob->data, 56);
141                 parms->all_info.out.delete_pending =        CVAL(blob->data, 60);
142                 parms->all_info.out.directory =             CVAL(blob->data, 61);
143 #if 1
144                 parms->all_info.out.ea_size =               IVAL(blob->data, 64);
145                 smbcli_blob_pull_string(session, mem_ctx, blob,
146                                      &parms->all_info.out.fname, 68, 72, STR_UNICODE);
147 #else
148                 /* this is what the CIFS spec says - and its totally
149                    wrong, but its useful having it here so we can
150                    quickly adapt to broken servers when running
151                    tests */
152                 parms->all_info.out.ea_size =               IVAL(blob->data, 72);
153                 /* access flags 4 bytes at 76
154                    current_position 8 bytes at 80
155                    mode 4 bytes at 88
156                    alignment 4 bytes at 92
157                 */
158                 smbcli_blob_pull_string(session, mem_ctx, blob,
159                                         &parms->all_info.out.fname, 96, 100, STR_UNICODE);
160 #endif
161                 return NT_STATUS_OK;
162
163         case RAW_FILEINFO_ALT_NAME_INFO:
164         case RAW_FILEINFO_ALT_NAME_INFORMATION:
165                 FINFO_CHECK_MIN_SIZE(4);
166                 smbcli_blob_pull_string(session, mem_ctx, blob, 
167                                      &parms->alt_name_info.out.fname, 0, 4, STR_UNICODE);
168                 return NT_STATUS_OK;
169
170         case RAW_FILEINFO_STREAM_INFO:
171         case RAW_FILEINFO_STREAM_INFORMATION:
172                 ofs = 0;
173                 parms->stream_info.out.num_streams = 0;
174                 parms->stream_info.out.streams = NULL;
175
176                 while (blob->length - ofs >= 24) {
177                         uint_t n = parms->stream_info.out.num_streams;
178                         parms->stream_info.out.streams = 
179                                 talloc_realloc_p(mem_ctx,
180                                                  parms->stream_info.out.streams,
181                                                  struct stream_struct,
182                                                  n+1);
183                         if (!parms->stream_info.out.streams) {
184                                 return NT_STATUS_NO_MEMORY;
185                         }
186                         parms->stream_info.out.streams[n].size =       BVAL(blob->data, ofs +  8);
187                         parms->stream_info.out.streams[n].alloc_size = BVAL(blob->data, ofs + 16);
188                         smbcli_blob_pull_string(session, mem_ctx, blob, 
189                                              &parms->stream_info.out.streams[n].stream_name, 
190                                              ofs+4, ofs+24, STR_UNICODE);
191                         parms->stream_info.out.num_streams++;
192                         len = IVAL(blob->data, ofs);
193                         if (len > blob->length - ofs) return NT_STATUS_INFO_LENGTH_MISMATCH;
194                         if (len == 0) break;
195                         ofs += len;
196                 }
197                 return NT_STATUS_OK;
198
199         case RAW_FILEINFO_INTERNAL_INFORMATION:
200                 FINFO_CHECK_SIZE(8);
201                 parms->internal_information.out.file_id = BVAL(blob->data, 0);
202                 return NT_STATUS_OK;
203
204         case RAW_FILEINFO_ACCESS_INFORMATION:
205                 FINFO_CHECK_SIZE(4);
206                 parms->access_information.out.access_flags = IVAL(blob->data, 0);
207                 return NT_STATUS_OK;
208
209         case RAW_FILEINFO_POSITION_INFORMATION:
210                 FINFO_CHECK_SIZE(8);
211                 parms->position_information.out.position = BVAL(blob->data, 0);
212                 return NT_STATUS_OK;
213
214         case RAW_FILEINFO_MODE_INFORMATION:
215                 FINFO_CHECK_SIZE(4);
216                 parms->mode_information.out.mode = IVAL(blob->data, 0);
217                 return NT_STATUS_OK;
218
219         case RAW_FILEINFO_ALIGNMENT_INFORMATION:
220                 FINFO_CHECK_SIZE(4);
221                 parms->alignment_information.out.alignment_requirement 
222                         = IVAL(blob->data, 0);
223                 return NT_STATUS_OK;
224
225         case RAW_FILEINFO_COMPRESSION_INFO:
226         case RAW_FILEINFO_COMPRESSION_INFORMATION:
227                 FINFO_CHECK_SIZE(16);
228                 parms->compression_info.out.compressed_size = BVAL(blob->data,  0);
229                 parms->compression_info.out.format          = SVAL(blob->data,  8);
230                 parms->compression_info.out.unit_shift      = CVAL(blob->data, 10);
231                 parms->compression_info.out.chunk_shift     = CVAL(blob->data, 11);
232                 parms->compression_info.out.cluster_shift   = CVAL(blob->data, 12);
233                 /* 3 bytes of padding */
234                 return NT_STATUS_OK;
235
236         case RAW_FILEINFO_UNIX_BASIC:
237                 FINFO_CHECK_SIZE(100);
238                 parms->unix_basic_info.out.end_of_file        =            BVAL(blob->data,  0);
239                 parms->unix_basic_info.out.num_bytes          =            BVAL(blob->data,  8);
240                 parms->unix_basic_info.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
241                 parms->unix_basic_info.out.access_time        = smbcli_pull_nttime(blob->data, 24);
242                 parms->unix_basic_info.out.change_time        = smbcli_pull_nttime(blob->data, 32);
243                 parms->unix_basic_info.out.uid                =            BVAL(blob->data, 40);
244                 parms->unix_basic_info.out.gid                =            BVAL(blob->data, 48);
245                 parms->unix_basic_info.out.file_type          =            IVAL(blob->data, 52);
246                 parms->unix_basic_info.out.dev_major          =            BVAL(blob->data, 60);
247                 parms->unix_basic_info.out.dev_minor          =            BVAL(blob->data, 68);
248                 parms->unix_basic_info.out.unique_id          =            BVAL(blob->data, 76);
249                 parms->unix_basic_info.out.permissions        =            BVAL(blob->data, 84);
250                 parms->unix_basic_info.out.nlink              =            BVAL(blob->data, 92);
251                 return NT_STATUS_OK;
252
253         case RAW_FILEINFO_UNIX_LINK:
254                 smbcli_blob_pull_string(session, mem_ctx, blob, 
255                                      &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE);
256                 return NT_STATUS_OK;
257                 
258         case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:             
259                 FINFO_CHECK_SIZE(56);
260                 parms->network_open_information.out.create_time = smbcli_pull_nttime(blob->data,  0);
261                 parms->network_open_information.out.access_time = smbcli_pull_nttime(blob->data,  8);
262                 parms->network_open_information.out.write_time =  smbcli_pull_nttime(blob->data, 16);
263                 parms->network_open_information.out.change_time = smbcli_pull_nttime(blob->data, 24);
264                 parms->network_open_information.out.alloc_size =             BVAL(blob->data, 32);
265                 parms->network_open_information.out.size =                   BVAL(blob->data, 40);
266                 parms->network_open_information.out.attrib =                 IVAL(blob->data, 48);
267                 return NT_STATUS_OK;
268
269         case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
270                 FINFO_CHECK_SIZE(8);
271                 parms->attribute_tag_information.out.attrib =      IVAL(blob->data, 0);
272                 parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4);
273                 return NT_STATUS_OK;
274         }
275
276         return NT_STATUS_INVALID_LEVEL;
277 }
278
279 /****************************************************************************
280  Very raw query file info - returns param/data blobs - (async send)
281 ****************************************************************************/
282 static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tree,
283                                                       uint16_t fnum, uint16_t info_level)
284 {
285         struct smb_trans2 tp;
286         uint16_t setup = TRANSACT2_QFILEINFO;
287         struct smbcli_request *req;
288         TALLOC_CTX *mem_ctx = talloc_init("raw_fileinfo");
289         
290         tp.in.max_setup = 0;
291         tp.in.flags = 0; 
292         tp.in.timeout = 0;
293         tp.in.setup_count = 1;
294         tp.in.data = data_blob(NULL, 0);
295         tp.in.max_param = 2;
296         tp.in.max_data = smb_raw_max_trans_data(tree, 2);
297         tp.in.setup = &setup;
298         
299         tp.in.params = data_blob_talloc(mem_ctx, NULL, 4);
300         if (!tp.in.params.data) {
301                 talloc_destroy(mem_ctx);
302                 return NULL;
303         }
304
305         SIVAL(tp.in.params.data, 0, fnum);
306         SSVAL(tp.in.params.data, 2, info_level);
307
308         req = smb_raw_trans2_send(tree, &tp);
309
310         talloc_destroy(mem_ctx);
311
312         return req;
313 }
314
315
316 /****************************************************************************
317  Very raw query file info - returns param/data blobs - (async recv)
318 ****************************************************************************/
319 static NTSTATUS smb_raw_fileinfo_blob_recv(struct smbcli_request *req,
320                                            TALLOC_CTX *mem_ctx,
321                                            DATA_BLOB *blob)
322 {
323         struct smb_trans2 tp;
324         NTSTATUS status = smb_raw_trans2_recv(req, mem_ctx, &tp);
325         if (NT_STATUS_IS_OK(status)) {
326                 *blob = tp.out.data;
327         }
328         return status;
329 }
330
331 /****************************************************************************
332  Very raw query path info - returns param/data blobs (async send)
333 ****************************************************************************/
334 static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tree,
335                                                       const char *fname,
336                                                       uint16_t info_level)
337 {
338         struct smb_trans2 tp;
339         uint16_t setup = TRANSACT2_QPATHINFO;
340         struct smbcli_request *req;
341         TALLOC_CTX *mem_ctx = talloc_init("raw_pathinfo");
342
343         tp.in.max_setup = 0;
344         tp.in.flags = 0; 
345         tp.in.timeout = 0;
346         tp.in.setup_count = 1;
347         tp.in.data = data_blob(NULL, 0);
348         tp.in.max_param = 2;
349         tp.in.max_data = smb_raw_max_trans_data(tree, 2);
350         tp.in.setup = &setup;
351         
352         tp.in.params = data_blob_talloc(mem_ctx, NULL, 6);
353         if (!tp.in.params.data) {
354                 talloc_destroy(mem_ctx);
355                 return NULL;
356         }
357
358         SSVAL(tp.in.params.data, 0, info_level);
359         SIVAL(tp.in.params.data, 2, 0);
360         smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params,
361                                fname, STR_TERMINATE);
362         
363         req = smb_raw_trans2_send(tree, &tp);
364
365         talloc_destroy(mem_ctx);
366
367         return req;
368 }
369
370 /****************************************************************************
371  send a SMBgetatr (async send)
372 ****************************************************************************/
373 static struct smbcli_request *smb_raw_getattr_send(struct smbcli_tree *tree,
374                                                 union smb_fileinfo *parms)
375 {
376         struct smbcli_request *req;
377         
378         req = smbcli_request_setup(tree, SMBgetatr, 0, 0);
379         if (!req) return NULL;
380
381         smbcli_req_append_ascii4(req, parms->getattr.in.fname, STR_TERMINATE);
382         
383         if (!smbcli_request_send(req)) {
384                 smbcli_request_destroy(req);
385                 return NULL;
386         }
387
388         return req;
389 }
390
391 /****************************************************************************
392  send a SMBgetatr (async recv)
393 ****************************************************************************/
394 static NTSTATUS smb_raw_getattr_recv(struct smbcli_request *req,
395                                      union smb_fileinfo *parms)
396 {
397         if (!smbcli_request_receive(req) ||
398             smbcli_request_is_error(req)) {
399                 return smbcli_request_destroy(req);
400         }
401
402         SMBCLI_CHECK_WCT(req, 10);
403         parms->getattr.out.attrib =     SVAL(req->in.vwv, VWV(0));
404         parms->getattr.out.write_time = raw_pull_dos_date3(req->transport,
405                                                            req->in.vwv + VWV(1));
406         parms->getattr.out.size =       IVAL(req->in.vwv, VWV(3));
407
408 failed:
409         return smbcli_request_destroy(req);
410 }
411
412
413 /****************************************************************************
414  Handle SMBgetattrE (async send)
415 ****************************************************************************/
416 static struct smbcli_request *smb_raw_getattrE_send(struct smbcli_tree *tree,
417                                                  union smb_fileinfo *parms)
418 {
419         struct smbcli_request *req;
420         
421         req = smbcli_request_setup(tree, SMBgetattrE, 1, 0);
422         if (!req) return NULL;
423         
424         SSVAL(req->out.vwv, VWV(0), parms->getattre.in.fnum);
425         if (!smbcli_request_send(req)) {
426                 smbcli_request_destroy(req);
427                 return NULL;
428         }
429
430         return req;
431 }
432
433 /****************************************************************************
434  Handle SMBgetattrE (async send)
435 ****************************************************************************/
436 static NTSTATUS smb_raw_getattrE_recv(struct smbcli_request *req,
437                                       union smb_fileinfo *parms)
438 {
439         if (!smbcli_request_receive(req) ||
440             smbcli_request_is_error(req)) {
441                 return smbcli_request_destroy(req);
442         }
443         
444         SMBCLI_CHECK_WCT(req, 11);
445         parms->getattre.out.create_time =   raw_pull_dos_date2(req->transport,
446                                                                req->in.vwv + VWV(0));
447         parms->getattre.out.access_time =   raw_pull_dos_date2(req->transport,
448                                                                req->in.vwv + VWV(2));
449         parms->getattre.out.write_time  =   raw_pull_dos_date2(req->transport,
450                                                                req->in.vwv + VWV(4));
451         parms->getattre.out.size =          IVAL(req->in.vwv,             VWV(6));
452         parms->getattre.out.alloc_size =    IVAL(req->in.vwv,             VWV(8));
453         parms->getattre.out.attrib =        SVAL(req->in.vwv,             VWV(10));
454
455 failed:
456         return smbcli_request_destroy(req);
457 }
458
459
460 /****************************************************************************
461  Query file info (async send)
462 ****************************************************************************/
463 struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree,
464                                              union smb_fileinfo *parms)
465 {
466         /* pass off the non-trans2 level to specialised functions */
467         if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
468                 return smb_raw_getattrE_send(tree, parms);
469         }
470         if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
471                 return smb_raw_query_secdesc_send(tree, parms);
472         }
473         if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
474                 return NULL;
475         }
476
477         return smb_raw_fileinfo_blob_send(tree, 
478                                           parms->generic.in.fnum,
479                                           parms->generic.level);
480 }
481
482 /****************************************************************************
483  Query file info (async recv)
484 ****************************************************************************/
485 NTSTATUS smb_raw_fileinfo_recv(struct smbcli_request *req,
486                                TALLOC_CTX *mem_ctx,
487                                union smb_fileinfo *parms)
488 {
489         DATA_BLOB blob;
490         NTSTATUS status;
491         struct smbcli_session *session = req?req->session:NULL;
492
493         if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
494                 return smb_raw_getattrE_recv(req, parms);
495         }
496         if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
497                 return smb_raw_query_secdesc_recv(req, mem_ctx, parms);
498         }
499         if (parms->generic.level == RAW_FILEINFO_GETATTR) {
500                 return smb_raw_getattr_recv(req, parms);
501         }
502
503         status = smb_raw_fileinfo_blob_recv(req, mem_ctx, &blob);
504         if (!NT_STATUS_IS_OK(status)) {
505                 return status;
506         }
507
508         return smb_raw_info_backend(session, mem_ctx, parms, &blob);
509 }
510
511 /****************************************************************************
512  Query file info (sync interface)
513 ****************************************************************************/
514 NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree,
515                           TALLOC_CTX *mem_ctx,
516                           union smb_fileinfo *parms)
517 {
518         struct smbcli_request *req = smb_raw_fileinfo_send(tree, parms);
519         return smb_raw_fileinfo_recv(req, mem_ctx, parms);
520 }
521
522 /****************************************************************************
523  Query path info (async send)
524 ****************************************************************************/
525 struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree,
526                                           union smb_fileinfo *parms)
527 {
528         if (parms->generic.level == RAW_FILEINFO_GETATTR) {
529                 return smb_raw_getattr_send(tree, parms);
530         }
531         if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
532                 return NULL;
533         }
534         
535         return smb_raw_pathinfo_blob_send(tree, parms->generic.in.fname,
536                                           parms->generic.level);
537 }
538
539 /****************************************************************************
540  Query path info (async recv)
541 ****************************************************************************/
542 NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req,
543                                TALLOC_CTX *mem_ctx,
544                                union smb_fileinfo *parms)
545 {
546         /* recv is idential to fileinfo */
547         return smb_raw_fileinfo_recv(req, mem_ctx, parms);
548 }
549
550 /****************************************************************************
551  Query path info (sync interface)
552 ****************************************************************************/
553 NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree,
554                           TALLOC_CTX *mem_ctx,
555                           union smb_fileinfo *parms)
556 {
557         struct smbcli_request *req = smb_raw_pathinfo_send(tree, parms);
558         return smb_raw_pathinfo_recv(req, mem_ctx, parms);
559 }