~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/libcli/raw/rawfileinfo.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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,
 
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, 
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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
}