~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/smbd/nttrans.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
   Unix SMB/CIFS implementation.
3
 
   SMB NT transaction handling
4
 
   Copyright (C) Jeremy Allison                 1994-1998
5
 
   Copyright (C) Stefan (metze) Metzmacher      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
 
 
24
 
extern int max_send;
25
 
extern enum protocol_types Protocol;
26
 
extern int smb_read_error;
27
 
extern struct current_user current_user;
28
 
 
29
 
static const char *known_nt_pipes[] = {
30
 
        "\\LANMAN",
31
 
        "\\srvsvc",
32
 
        "\\samr",
33
 
        "\\wkssvc",
34
 
        "\\NETLOGON",
35
 
        "\\ntlsa",
36
 
        "\\ntsvcs",
37
 
        "\\lsass",
38
 
        "\\lsarpc",
39
 
        "\\winreg",
40
 
        "\\spoolss",
41
 
        "\\netdfs",
42
 
        "\\rpcecho",
43
 
        "\\svcctl",
44
 
        "\\eventlog",
45
 
        "\\unixinfo",
46
 
        NULL
47
 
};
48
 
 
49
 
static char *nttrans_realloc(char **ptr, size_t size)
50
 
{
51
 
        if (ptr==NULL) {
52
 
                smb_panic("nttrans_realloc() called with NULL ptr\n");
53
 
        }
54
 
                
55
 
        *ptr = SMB_REALLOC(*ptr, size);
56
 
        if(*ptr == NULL) {
57
 
                return NULL;
58
 
        }
59
 
        memset(*ptr,'\0',size);
60
 
        return *ptr;
61
 
}
62
 
 
63
 
/****************************************************************************
64
 
 Send the required number of replies back.
65
 
 We assume all fields other than the data fields are
66
 
 set correctly for the type of call.
67
 
 HACK ! Always assumes smb_setup field is zero.
68
 
****************************************************************************/
69
 
 
70
 
static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_error, char *params,
71
 
                           int paramsize, char *pdata, int datasize)
72
 
{
73
 
        int data_to_send = datasize;
74
 
        int params_to_send = paramsize;
75
 
        int useable_space;
76
 
        char *pp = params;
77
 
        char *pd = pdata;
78
 
        int params_sent_thistime, data_sent_thistime, total_sent_thistime;
79
 
        int alignment_offset = 3;
80
 
        int data_alignment_offset = 0;
81
 
 
82
 
        /*
83
 
         * Initially set the wcnt area to be 18 - this is true for all
84
 
         * transNT replies.
85
 
         */
86
 
 
87
 
        set_message(outbuf,18,0,True);
88
 
 
89
 
        if (NT_STATUS_V(nt_error)) {
90
 
                ERROR_NT(nt_error);
91
 
        }
92
 
 
93
 
        /* 
94
 
         * If there genuinely are no parameters or data to send just send
95
 
         * the empty packet.
96
 
         */
97
 
 
98
 
        if(params_to_send == 0 && data_to_send == 0) {
99
 
                show_msg(outbuf);
100
 
                if (!send_smb(smbd_server_fd(),outbuf)) {
101
 
                        exit_server("send_nt_replies: send_smb failed.");
102
 
                }
103
 
                return 0;
104
 
        }
105
 
 
106
 
        /*
107
 
         * When sending params and data ensure that both are nicely aligned.
108
 
         * Only do this alignment when there is also data to send - else
109
 
         * can cause NT redirector problems.
110
 
         */
111
 
 
112
 
        if (((params_to_send % 4) != 0) && (data_to_send != 0)) {
113
 
                data_alignment_offset = 4 - (params_to_send % 4);
114
 
        }
115
 
 
116
 
        /* 
117
 
         * Space is bufsize minus Netbios over TCP header minus SMB header.
118
 
         * The alignment_offset is to align the param bytes on a four byte
119
 
         * boundary (2 bytes for data len, one byte pad). 
120
 
         * NT needs this to work correctly.
121
 
         */
122
 
 
123
 
        useable_space = bufsize - ((smb_buf(outbuf)+
124
 
                                alignment_offset+data_alignment_offset) -
125
 
                                outbuf);
126
 
 
127
 
        /*
128
 
         * useable_space can never be more than max_send minus the
129
 
         * alignment offset.
130
 
         */
131
 
 
132
 
        useable_space = MIN(useable_space,
133
 
                                max_send - (alignment_offset+data_alignment_offset));
134
 
 
135
 
 
136
 
        while (params_to_send || data_to_send) {
137
 
 
138
 
                /*
139
 
                 * Calculate whether we will totally or partially fill this packet.
140
 
                 */
141
 
 
142
 
                total_sent_thistime = params_to_send + data_to_send +
143
 
                                        alignment_offset + data_alignment_offset;
144
 
 
145
 
                /* 
146
 
                 * We can never send more than useable_space.
147
 
                 */
148
 
 
149
 
                total_sent_thistime = MIN(total_sent_thistime, useable_space);
150
 
 
151
 
                set_message(outbuf, 18, total_sent_thistime, True);
152
 
 
153
 
                /*
154
 
                 * Set total params and data to be sent.
155
 
                 */
156
 
 
157
 
                SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
158
 
                SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
159
 
 
160
 
                /* 
161
 
                 * Calculate how many parameters and data we can fit into
162
 
                 * this packet. Parameters get precedence.
163
 
                 */
164
 
 
165
 
                params_sent_thistime = MIN(params_to_send,useable_space);
166
 
                data_sent_thistime = useable_space - params_sent_thistime;
167
 
                data_sent_thistime = MIN(data_sent_thistime,data_to_send);
168
 
 
169
 
                SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
170
 
 
171
 
                if(params_sent_thistime == 0) {
172
 
                        SIVAL(outbuf,smb_ntr_ParameterOffset,0);
173
 
                        SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
174
 
                } else {
175
 
                        /*
176
 
                         * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
177
 
                         * parameter bytes, however the first 4 bytes of outbuf are
178
 
                         * the Netbios over TCP header. Thus use smb_base() to subtract
179
 
                         * them from the calculation.
180
 
                         */
181
 
 
182
 
                        SIVAL(outbuf,smb_ntr_ParameterOffset,
183
 
                                ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
184
 
                        /* 
185
 
                         * Absolute displacement of param bytes sent in this packet.
186
 
                         */
187
 
 
188
 
                        SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
189
 
                }
190
 
 
191
 
                /*
192
 
                 * Deal with the data portion.
193
 
                 */
194
 
 
195
 
                SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
196
 
 
197
 
                if(data_sent_thistime == 0) {
198
 
                        SIVAL(outbuf,smb_ntr_DataOffset,0);
199
 
                        SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
200
 
                } else {
201
 
                        /*
202
 
                         * The offset of the data bytes is the offset of the
203
 
                         * parameter bytes plus the number of parameters being sent this time.
204
 
                         */
205
 
 
206
 
                        SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
207
 
                                smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
208
 
                                SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
209
 
                }
210
 
 
211
 
                /* 
212
 
                 * Copy the param bytes into the packet.
213
 
                 */
214
 
 
215
 
                if(params_sent_thistime) {
216
 
                        memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
217
 
                }
218
 
 
219
 
                /*
220
 
                 * Copy in the data bytes
221
 
                 */
222
 
 
223
 
                if(data_sent_thistime) {
224
 
                        memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
225
 
                                data_alignment_offset,pd,data_sent_thistime);
226
 
                }
227
 
    
228
 
                DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
229
 
                        params_sent_thistime, data_sent_thistime, useable_space));
230
 
                DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
231
 
                        params_to_send, data_to_send, paramsize, datasize));
232
 
    
233
 
                /* Send the packet */
234
 
                show_msg(outbuf);
235
 
                if (!send_smb(smbd_server_fd(),outbuf)) {
236
 
                        exit_server("send_nt_replies: send_smb failed.");
237
 
                }
238
 
    
239
 
                pp += params_sent_thistime;
240
 
                pd += data_sent_thistime;
241
 
    
242
 
                params_to_send -= params_sent_thistime;
243
 
                data_to_send -= data_sent_thistime;
244
 
 
245
 
                /*
246
 
                 * Sanity check
247
 
                 */
248
 
 
249
 
                if(params_to_send < 0 || data_to_send < 0) {
250
 
                        DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
251
 
                                params_to_send, data_to_send));
252
 
                        return -1;
253
 
                }
254
 
        } 
255
 
 
256
 
        return 0;
257
 
}
258
 
 
259
 
/****************************************************************************
260
 
 Is it an NTFS stream name ?
261
 
****************************************************************************/
262
 
 
263
 
BOOL is_ntfs_stream_name(const char *fname)
264
 
{
265
 
        if (lp_posix_pathnames()) {
266
 
                return False;
267
 
        }
268
 
        return (strchr_m(fname, ':') != NULL) ? True : False;
269
 
}
270
 
 
271
 
/****************************************************************************
272
 
 Save case statics.
273
 
****************************************************************************/
274
 
 
275
 
static BOOL saved_case_sensitive;
276
 
static BOOL saved_case_preserve;
277
 
static BOOL saved_short_case_preserve;
278
 
 
279
 
/****************************************************************************
280
 
 Save case semantics.
281
 
****************************************************************************/
282
 
 
283
 
static void set_posix_case_semantics(connection_struct *conn, uint32 file_attributes)
284
 
{
285
 
        if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
286
 
                return;
287
 
        }
288
 
 
289
 
        saved_case_sensitive = conn->case_sensitive;
290
 
        saved_case_preserve = conn->case_preserve;
291
 
        saved_short_case_preserve = conn->short_case_preserve;
292
 
 
293
 
        /* Set to POSIX. */
294
 
        conn->case_sensitive = True;
295
 
        conn->case_preserve = True;
296
 
        conn->short_case_preserve = True;
297
 
}
298
 
 
299
 
/****************************************************************************
300
 
 Restore case semantics.
301
 
****************************************************************************/
302
 
 
303
 
static void restore_case_semantics(connection_struct *conn, uint32 file_attributes)
304
 
{
305
 
        if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
306
 
                return;
307
 
        }
308
 
 
309
 
        conn->case_sensitive = saved_case_sensitive;
310
 
        conn->case_preserve = saved_case_preserve;
311
 
        conn->short_case_preserve = saved_short_case_preserve;
312
 
}
313
 
 
314
 
/****************************************************************************
315
 
 Reply to an NT create and X call on a pipe.
316
 
****************************************************************************/
317
 
 
318
 
static int nt_open_pipe(char *fname, connection_struct *conn,
319
 
                        char *inbuf, char *outbuf, int *ppnum)
320
 
{
321
 
        smb_np_struct *p = NULL;
322
 
        uint16 vuid = SVAL(inbuf, smb_uid);
323
 
        int i;
324
 
 
325
 
        DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
326
 
    
327
 
        /* See if it is one we want to handle. */
328
 
 
329
 
        if (lp_disable_spoolss() && strequal(fname, "\\spoolss")) {
330
 
                return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
331
 
        }
332
 
 
333
 
        for( i = 0; known_nt_pipes[i]; i++ ) {
334
 
                if( strequal(fname,known_nt_pipes[i])) {
335
 
                        break;
336
 
                }
337
 
        }
338
 
    
339
 
        if ( known_nt_pipes[i] == NULL ) {
340
 
                return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
341
 
        }
342
 
    
343
 
        /* Strip \\ off the name. */
344
 
        fname++;
345
 
    
346
 
        DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
347
 
 
348
 
        p = open_rpc_pipe_p(fname, conn, vuid);
349
 
        if (!p) {
350
 
                return(ERROR_DOS(ERRSRV,ERRnofids));
351
 
        }
352
 
 
353
 
        /* TODO: Add pipe to db */
354
 
        
355
 
        if ( !store_pipe_opendb( p ) ) {
356
 
                DEBUG(3,("nt_open_pipe: failed to store %s pipe open.\n", fname));
357
 
        }
358
 
        
359
 
        *ppnum = p->pnum;
360
 
        return 0;
361
 
}
362
 
 
363
 
/****************************************************************************
364
 
 Reply to an NT create and X call for pipes.
365
 
****************************************************************************/
366
 
 
367
 
static int do_ntcreate_pipe_open(connection_struct *conn,
368
 
                         char *inbuf,char *outbuf,int length,int bufsize)
369
 
{
370
 
        pstring fname;
371
 
        int ret;
372
 
        int pnum = -1;
373
 
        char *p = NULL;
374
 
 
375
 
        srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
376
 
 
377
 
        if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) {
378
 
                return ret;
379
 
        }
380
 
 
381
 
        /*
382
 
         * Deal with pipe return.
383
 
         */  
384
 
 
385
 
        set_message(outbuf,34,0,True);
386
 
 
387
 
        p = outbuf + smb_vwv2;
388
 
        p++;
389
 
        SSVAL(p,0,pnum);
390
 
        p += 2;
391
 
        SIVAL(p,0,FILE_WAS_OPENED);
392
 
        p += 4;
393
 
        p += 32;
394
 
        SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
395
 
        p += 20;
396
 
        /* File type. */
397
 
        SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
398
 
        /* Device state. */
399
 
        SSVAL(p,2, 0x5FF); /* ? */
400
 
 
401
 
        DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
402
 
 
403
 
        return chain_reply(inbuf,outbuf,length,bufsize);
404
 
}
405
 
 
406
 
/****************************************************************************
407
 
 Reply to an NT create and X call for a quota file.
408
 
****************************************************************************/
409
 
 
410
 
int reply_ntcreate_and_X_quota(connection_struct *conn,
411
 
                                char *inbuf,
412
 
                                char *outbuf,
413
 
                                int length,
414
 
                                int bufsize,
415
 
                                enum FAKE_FILE_TYPE fake_file_type,
416
 
                                const char *fname)
417
 
{
418
 
        int result;
419
 
        char *p;
420
 
        uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
421
 
        files_struct *fsp;
422
 
        NTSTATUS status;
423
 
 
424
 
        status = open_fake_file(conn, fake_file_type, fname, desired_access,
425
 
                                &fsp);
426
 
 
427
 
        if (!NT_STATUS_IS_OK(status)) {
428
 
                return ERROR_NT(status);
429
 
        }
430
 
 
431
 
        set_message(outbuf,34,0,True);
432
 
        
433
 
        p = outbuf + smb_vwv2;
434
 
        
435
 
        /* SCVAL(p,0,NO_OPLOCK_RETURN); */
436
 
        p++;
437
 
        SSVAL(p,0,fsp->fnum);
438
 
#if 0
439
 
        p += 2;
440
 
        SIVAL(p,0,smb_action);
441
 
        p += 4;
442
 
        
443
 
        /* Create time. */  
444
 
        put_long_date(p,c_time);
445
 
        p += 8;
446
 
        put_long_date(p,sbuf.st_atime); /* access time */
447
 
        p += 8;
448
 
        put_long_date(p,sbuf.st_mtime); /* write time */
449
 
        p += 8;
450
 
        put_long_date(p,sbuf.st_mtime); /* change time */
451
 
        p += 8;
452
 
        SIVAL(p,0,fattr); /* File Attributes. */
453
 
        p += 4;
454
 
        SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
455
 
        p += 8;
456
 
        SOFF_T(p,0,file_len);
457
 
        p += 8;
458
 
        if (flags & EXTENDED_RESPONSE_REQUIRED)
459
 
                SSVAL(p,2,0x7);
460
 
        p += 4;
461
 
        SCVAL(p,0,fsp->is_directory ? 1 : 0);
462
 
#endif
463
 
 
464
 
        DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
465
 
 
466
 
        result = chain_reply(inbuf,outbuf,length,bufsize);
467
 
        return result;
468
 
}
469
 
 
470
 
/****************************************************************************
471
 
 Reply to an NT create and X call.
472
 
****************************************************************************/
473
 
 
474
 
int reply_ntcreate_and_X(connection_struct *conn,
475
 
                         char *inbuf,char *outbuf,int length,int bufsize)
476
 
{  
477
 
        int result;
478
 
        pstring fname;
479
 
        uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
480
 
        uint32 access_mask = IVAL(inbuf,smb_ntcreate_DesiredAccess);
481
 
        uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
482
 
        uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
483
 
        uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
484
 
        uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
485
 
        uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
486
 
        /* Breakout the oplock request bits so we can set the
487
 
           reply bits separately. */
488
 
        int oplock_request = 0;
489
 
        uint32 fattr=0;
490
 
        SMB_OFF_T file_len = 0;
491
 
        SMB_STRUCT_STAT sbuf;
492
 
        int info = 0;
493
 
        BOOL bad_path = False;
494
 
        files_struct *fsp=NULL;
495
 
        char *p = NULL;
496
 
        time_t c_time;
497
 
        BOOL extended_oplock_granted = False;
498
 
        NTSTATUS status;
499
 
 
500
 
        START_PROFILE(SMBntcreateX);
501
 
 
502
 
        DEBUG(10,("reply_ntcreateX: flags = 0x%x, access_mask = 0x%x \
503
 
file_attributes = 0x%x, share_access = 0x%x, create_disposition = 0x%x \
504
 
create_options = 0x%x root_dir_fid = 0x%x\n",
505
 
                        (unsigned int)flags,
506
 
                        (unsigned int)access_mask,
507
 
                        (unsigned int)file_attributes,
508
 
                        (unsigned int)share_access,
509
 
                        (unsigned int)create_disposition,
510
 
                        (unsigned int)create_options,
511
 
                        (unsigned int)root_dir_fid ));
512
 
 
513
 
        /* If it's an IPC, use the pipe handler. */
514
 
 
515
 
        if (IS_IPC(conn)) {
516
 
                if (lp_nt_pipe_support()) {
517
 
                        END_PROFILE(SMBntcreateX);
518
 
                        return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize);
519
 
                } else {
520
 
                        END_PROFILE(SMBntcreateX);
521
 
                        return(ERROR_DOS(ERRDOS,ERRnoaccess));
522
 
                }
523
 
        }
524
 
                        
525
 
        if (create_options & FILE_OPEN_BY_FILE_ID) {
526
 
                END_PROFILE(SMBntcreateX);
527
 
                return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
528
 
        }
529
 
 
530
 
        /*
531
 
         * Get the file name.
532
 
         */
533
 
 
534
 
        if(root_dir_fid != 0) {
535
 
                /*
536
 
                 * This filename is relative to a directory fid.
537
 
                 */
538
 
                pstring rel_fname;
539
 
                files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
540
 
                size_t dir_name_len;
541
 
 
542
 
                if(!dir_fsp) {
543
 
                        END_PROFILE(SMBntcreateX);
544
 
                        return(ERROR_DOS(ERRDOS,ERRbadfid));
545
 
                }
546
 
 
547
 
                if(!dir_fsp->is_directory) {
548
 
 
549
 
                        srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
550
 
                        if (!NT_STATUS_IS_OK(status)) {
551
 
                                END_PROFILE(SMBntcreateX);
552
 
                                return ERROR_NT(status);
553
 
                        }
554
 
 
555
 
                        /* 
556
 
                         * Check to see if this is a mac fork of some kind.
557
 
                         */
558
 
 
559
 
                        if( is_ntfs_stream_name(fname)) {
560
 
                                END_PROFILE(SMBntcreateX);
561
 
                                return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
562
 
                        }
563
 
 
564
 
                        /*
565
 
                          we need to handle the case when we get a
566
 
                          relative open relative to a file and the
567
 
                          pathname is blank - this is a reopen!
568
 
                          (hint from demyn plantenberg)
569
 
                        */
570
 
 
571
 
                        END_PROFILE(SMBntcreateX);
572
 
                        return(ERROR_DOS(ERRDOS,ERRbadfid));
573
 
                }
574
 
 
575
 
                /*
576
 
                 * Copy in the base directory name.
577
 
                 */
578
 
 
579
 
                pstrcpy( fname, dir_fsp->fsp_name );
580
 
                dir_name_len = strlen(fname);
581
 
 
582
 
                /*
583
 
                 * Ensure it ends in a '\'.
584
 
                 */
585
 
 
586
 
                if(fname[dir_name_len-1] != '\\' && fname[dir_name_len-1] != '/') {
587
 
                        pstrcat(fname, "/");
588
 
                        dir_name_len++;
589
 
                }
590
 
 
591
 
                srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status);
592
 
                if (!NT_STATUS_IS_OK(status)) {
593
 
                        END_PROFILE(SMBntcreateX);
594
 
                        return ERROR_NT(status);
595
 
                }
596
 
                pstrcat(fname, rel_fname);
597
 
        } else {
598
 
                srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
599
 
                if (!NT_STATUS_IS_OK(status)) {
600
 
                        END_PROFILE(SMBntcreateX);
601
 
                        return ERROR_NT(status);
602
 
                }
603
 
 
604
 
                /* 
605
 
                 * Check to see if this is a mac fork of some kind.
606
 
                 */
607
 
 
608
 
                if( is_ntfs_stream_name(fname)) {
609
 
                        enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname);
610
 
                        if (fake_file_type!=FAKE_FILE_TYPE_NONE) {
611
 
                                /*
612
 
                                 * Here we go! support for changing the disk quotas --metze
613
 
                                 *
614
 
                                 * We need to fake up to open this MAGIC QUOTA file 
615
 
                                 * and return a valid FID.
616
 
                                 *
617
 
                                 * w2k close this file directly after openening
618
 
                                 * xp also tries a QUERY_FILE_INFO on the file and then close it
619
 
                                 */
620
 
                                result = reply_ntcreate_and_X_quota(conn, inbuf, outbuf, length, bufsize,
621
 
                                                                fake_file_type, fname);
622
 
                                END_PROFILE(SMBntcreateX);
623
 
                                return result;
624
 
                        } else {
625
 
                                END_PROFILE(SMBntcreateX);
626
 
                                return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
627
 
                        }
628
 
                }
629
 
        }
630
 
        
631
 
        /*
632
 
         * Now contruct the smb_open_mode value from the filename, 
633
 
         * desired access and the share access.
634
 
         */
635
 
        RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
636
 
 
637
 
        oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
638
 
        if (oplock_request) {
639
 
                oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
640
 
        }
641
 
 
642
 
        /*
643
 
         * Ordinary file or directory.
644
 
         */
645
 
                
646
 
        /*
647
 
         * Check if POSIX semantics are wanted.
648
 
         */
649
 
                
650
 
        set_posix_case_semantics(conn, file_attributes);
651
 
                
652
 
        unix_convert(fname,conn,0,&bad_path,&sbuf);
653
 
 
654
 
        if (bad_path) {
655
 
                restore_case_semantics(conn, file_attributes);
656
 
                END_PROFILE(SMBntcreateX);
657
 
                return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
658
 
        }
659
 
        /* All file access must go through check_name() */
660
 
        if (!check_name(fname,conn)) {
661
 
                restore_case_semantics(conn, file_attributes);
662
 
                END_PROFILE(SMBntcreateX);
663
 
                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
664
 
        }
665
 
 
666
 
#if 0
667
 
        /* This is the correct thing to do (check every time) but can_delete is
668
 
           expensive (it may have to read the parent directory permissions). So
669
 
           for now we're not doing it unless we have a strong hint the client
670
 
           is really going to delete this file. */
671
 
        if (desired_access & DELETE_ACCESS) {
672
 
#else
673
 
        /* Setting FILE_SHARE_DELETE is the hint. */
674
 
        if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE)
675
 
                                && (access_mask & DELETE_ACCESS)) {
676
 
#endif
677
 
                status = can_delete(conn, fname, file_attributes, bad_path, True);
678
 
                /* We're only going to fail here if it's access denied, as that's the
679
 
                   only error we care about for "can we delete this ?" questions. */
680
 
                if (!NT_STATUS_IS_OK(status) && (NT_STATUS_EQUAL(status,NT_STATUS_ACCESS_DENIED) ||
681
 
                                                 NT_STATUS_EQUAL(status,NT_STATUS_CANNOT_DELETE))) {
682
 
                        restore_case_semantics(conn, file_attributes);
683
 
                        END_PROFILE(SMBntcreateX);
684
 
                        return ERROR_NT(NT_STATUS_ACCESS_DENIED);
685
 
                }
686
 
        }
687
 
 
688
 
        /* 
689
 
         * If it's a request for a directory open, deal with it separately.
690
 
         */
691
 
 
692
 
        if(create_options & FILE_DIRECTORY_FILE) {
693
 
                oplock_request = 0;
694
 
                
695
 
                /* Can't open a temp directory. IFS kit test. */
696
 
                if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
697
 
                        END_PROFILE(SMBntcreateX);
698
 
                        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
699
 
                }
700
 
 
701
 
                status = open_directory(conn, fname, &sbuf,
702
 
                                        access_mask,
703
 
                                        share_access,
704
 
                                        create_disposition,
705
 
                                        create_options,
706
 
                                        &info, &fsp);
707
 
 
708
 
                restore_case_semantics(conn, file_attributes);
709
 
 
710
 
                if(!NT_STATUS_IS_OK(status)) {
711
 
                        END_PROFILE(SMBntcreateX);
712
 
                        return ERROR_NT(status);
713
 
                }
714
 
        } else {
715
 
                /*
716
 
                 * Ordinary file case.
717
 
                 */
718
 
 
719
 
                /* NB. We have a potential bug here. If we
720
 
                 * cause an oplock break to ourselves, then we
721
 
                 * could end up processing filename related
722
 
                 * SMB requests whilst we await the oplock
723
 
                 * break response. As we may have changed the
724
 
                 * filename case semantics to be POSIX-like,
725
 
                 * this could mean a filename request could
726
 
                 * fail when it should succeed. This is a rare
727
 
                 * condition, but eventually we must arrange
728
 
                 * to restore the correct case semantics
729
 
                 * before issuing an oplock break request to
730
 
                 * our client. JRA.  */
731
 
 
732
 
                status = open_file_ntcreate(conn,fname,&sbuf,
733
 
                                        access_mask,
734
 
                                        share_access,
735
 
                                        create_disposition,
736
 
                                        create_options,
737
 
                                        file_attributes,
738
 
                                        oplock_request,
739
 
                                        &info, &fsp);
740
 
                if (!NT_STATUS_IS_OK(status)) { 
741
 
                        /* We cheat here. There are two cases we
742
 
                         * care about. One is a directory rename,
743
 
                         * where the NT client will attempt to
744
 
                         * open the source directory for
745
 
                         * DELETE access. Note that when the
746
 
                         * NT client does this it does *not*
747
 
                         * set the directory bit in the
748
 
                         * request packet. This is translated
749
 
                         * into a read/write open
750
 
                         * request. POSIX states that any open
751
 
                         * for write request on a directory
752
 
                         * will generate an EISDIR error, so
753
 
                         * we can catch this here and open a
754
 
                         * pseudo handle that is flagged as a
755
 
                         * directory. The second is an open
756
 
                         * for a permissions read only, which
757
 
                         * we handle in the open_file_stat case. JRA.
758
 
                         */
759
 
 
760
 
                        if (NT_STATUS_EQUAL(status,
761
 
                                            NT_STATUS_FILE_IS_A_DIRECTORY)) {
762
 
 
763
 
                                /*
764
 
                                 * Fail the open if it was explicitly a non-directory file.
765
 
                                 */
766
 
 
767
 
                                if (create_options & FILE_NON_DIRECTORY_FILE) {
768
 
                                        restore_case_semantics(conn, file_attributes);
769
 
                                        END_PROFILE(SMBntcreateX);
770
 
                                        return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
771
 
                                }
772
 
        
773
 
                                oplock_request = 0;
774
 
                                status = open_directory(conn, fname, &sbuf,
775
 
                                                        access_mask,
776
 
                                                        share_access,
777
 
                                                        create_disposition,
778
 
                                                        create_options,
779
 
                                                        &info, &fsp);
780
 
 
781
 
                                if(!NT_STATUS_IS_OK(status)) {
782
 
                                        restore_case_semantics(conn, file_attributes);
783
 
                                        END_PROFILE(SMBntcreateX);
784
 
                                        return ERROR_NT(status);
785
 
                                }
786
 
                        } else {
787
 
 
788
 
                                restore_case_semantics(conn, file_attributes);
789
 
                                END_PROFILE(SMBntcreateX);
790
 
                                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
791
 
                                        /* We have re-scheduled this call. */
792
 
                                        return -1;
793
 
                                }
794
 
                                return ERROR_NT(status);
795
 
                        }
796
 
                } 
797
 
        }
798
 
                
799
 
        restore_case_semantics(conn, file_attributes);
800
 
                
801
 
        file_len = sbuf.st_size;
802
 
        fattr = dos_mode(conn,fname,&sbuf);
803
 
        if(fattr == 0) {
804
 
                fattr = FILE_ATTRIBUTE_NORMAL;
805
 
        }
806
 
        if (!fsp->is_directory && (fattr & aDIR)) {
807
 
                close_file(fsp,ERROR_CLOSE);
808
 
                END_PROFILE(SMBntcreateX);
809
 
                return ERROR_DOS(ERRDOS,ERRnoaccess);
810
 
        } 
811
 
        
812
 
        /* Save the requested allocation size. */
813
 
        if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
814
 
                SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);
815
 
#ifdef LARGE_SMB_OFF_T
816
 
                allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
817
 
#endif
818
 
                if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
819
 
                        fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
820
 
                        if (fsp->is_directory) {
821
 
                                close_file(fsp,ERROR_CLOSE);
822
 
                                END_PROFILE(SMBntcreateX);
823
 
                                /* Can't set allocation size on a directory. */
824
 
                                return ERROR_NT(NT_STATUS_ACCESS_DENIED);
825
 
                        }
826
 
                        if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
827
 
                                close_file(fsp,ERROR_CLOSE);
828
 
                                END_PROFILE(SMBntcreateX);
829
 
                                return ERROR_NT(NT_STATUS_DISK_FULL);
830
 
                        }
831
 
                } else {
832
 
                        fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);
833
 
                }
834
 
        }
835
 
 
836
 
        /* 
837
 
         * If the caller set the extended oplock request bit
838
 
         * and we granted one (by whatever means) - set the
839
 
         * correct bit for extended oplock reply.
840
 
         */
841
 
        
842
 
        if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
843
 
                extended_oplock_granted = True;
844
 
        }
845
 
        
846
 
        if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
847
 
                extended_oplock_granted = True;
848
 
        }
849
 
 
850
 
#if 0
851
 
        /* W2K sends back 42 words here ! If we do the same it breaks offline sync. Go figure... ? JRA. */
852
 
        set_message(outbuf,42,0,True);
853
 
#else
854
 
        set_message(outbuf,34,0,True);
855
 
#endif
856
 
        
857
 
        p = outbuf + smb_vwv2;
858
 
        
859
 
        /*
860
 
         * Currently as we don't support level II oplocks we just report
861
 
         * exclusive & batch here.
862
 
         */
863
 
 
864
 
        if (extended_oplock_granted) {
865
 
                if (flags & REQUEST_BATCH_OPLOCK) {
866
 
                        SCVAL(p,0, BATCH_OPLOCK_RETURN);
867
 
                } else {
868
 
                        SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);
869
 
                }
870
 
        } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
871
 
                SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
872
 
        } else {
873
 
                SCVAL(p,0,NO_OPLOCK_RETURN);
874
 
        }
875
 
        
876
 
        p++;
877
 
        SSVAL(p,0,fsp->fnum);
878
 
        p += 2;
879
 
        if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) {
880
 
                SIVAL(p,0,FILE_WAS_SUPERSEDED);
881
 
        } else {
882
 
                SIVAL(p,0,info);
883
 
        }
884
 
        p += 4;
885
 
        
886
 
        /* Create time. */  
887
 
        c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
888
 
 
889
 
        if (lp_dos_filetime_resolution(SNUM(conn))) {
890
 
                c_time &= ~1;
891
 
                sbuf.st_atime &= ~1;
892
 
                sbuf.st_mtime &= ~1;
893
 
                sbuf.st_mtime &= ~1;
894
 
        }
895
 
 
896
 
        put_long_date(p,c_time);
897
 
        p += 8;
898
 
        put_long_date(p,sbuf.st_atime); /* access time */
899
 
        p += 8;
900
 
        put_long_date(p,sbuf.st_mtime); /* write time */
901
 
        p += 8;
902
 
        put_long_date(p,sbuf.st_mtime); /* change time */
903
 
        p += 8;
904
 
        SIVAL(p,0,fattr); /* File Attributes. */
905
 
        p += 4;
906
 
        SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
907
 
        p += 8;
908
 
        SOFF_T(p,0,file_len);
909
 
        p += 8;
910
 
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
911
 
                SSVAL(p,2,0x7);
912
 
        }
913
 
        p += 4;
914
 
        SCVAL(p,0,fsp->is_directory ? 1 : 0);
915
 
 
916
 
        DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
917
 
 
918
 
        result = chain_reply(inbuf,outbuf,length,bufsize);
919
 
        END_PROFILE(SMBntcreateX);
920
 
        return result;
921
 
}
922
 
 
923
 
/****************************************************************************
924
 
 Reply to a NT_TRANSACT_CREATE call to open a pipe.
925
 
****************************************************************************/
926
 
 
927
 
static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
928
 
                                  uint16 **ppsetup, uint32 setup_count,
929
 
                                  char **ppparams, uint32 parameter_count,
930
 
                                  char **ppdata, uint32 data_count)
931
 
{
932
 
        pstring fname;
933
 
        char *params = *ppparams;
934
 
        int ret;
935
 
        int pnum = -1;
936
 
        char *p = NULL;
937
 
        NTSTATUS status;
938
 
 
939
 
        /*
940
 
         * Ensure minimum number of parameters sent.
941
 
         */
942
 
 
943
 
        if(parameter_count < 54) {
944
 
                DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
945
 
                return ERROR_DOS(ERRDOS,ERRnoaccess);
946
 
        }
947
 
 
948
 
        srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
949
 
        if (!NT_STATUS_IS_OK(status)) {
950
 
                return ERROR_NT(status);
951
 
        }
952
 
 
953
 
        if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) {
954
 
                return ret;
955
 
        }
956
 
        
957
 
        /* Realloc the size of parameters and data we will return */
958
 
        params = nttrans_realloc(ppparams, 69);
959
 
        if(params == NULL) {
960
 
                return ERROR_DOS(ERRDOS,ERRnomem);
961
 
        }
962
 
        
963
 
        p = params;
964
 
        SCVAL(p,0,NO_OPLOCK_RETURN);
965
 
        
966
 
        p += 2;
967
 
        SSVAL(p,0,pnum);
968
 
        p += 2;
969
 
        SIVAL(p,0,FILE_WAS_OPENED);
970
 
        p += 8;
971
 
        
972
 
        p += 32;
973
 
        SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
974
 
        p += 20;
975
 
        /* File type. */
976
 
        SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
977
 
        /* Device state. */
978
 
        SSVAL(p,2, 0x5FF); /* ? */
979
 
        
980
 
        DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
981
 
        
982
 
        /* Send the required number of replies */
983
 
        send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 69, *ppdata, 0);
984
 
        
985
 
        return -1;
986
 
}
987
 
 
988
 
/****************************************************************************
989
 
 Internal fn to set security descriptors.
990
 
****************************************************************************/
991
 
 
992
 
static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 security_info_sent)
993
 
{
994
 
        prs_struct pd;
995
 
        SEC_DESC *psd = NULL;
996
 
        TALLOC_CTX *mem_ctx;
997
 
        BOOL ret;
998
 
        
999
 
        if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) {
1000
 
                return NT_STATUS_OK;
1001
 
        }
1002
 
 
1003
 
        /*
1004
 
         * Init the parse struct we will unmarshall from.
1005
 
         */
1006
 
 
1007
 
        if ((mem_ctx = talloc_init("set_sd")) == NULL) {
1008
 
                DEBUG(0,("set_sd: talloc_init failed.\n"));
1009
 
                return NT_STATUS_NO_MEMORY;
1010
 
        }
1011
 
 
1012
 
        prs_init(&pd, 0, mem_ctx, UNMARSHALL);
1013
 
 
1014
 
        /*
1015
 
         * Setup the prs_struct to point at the memory we just
1016
 
         * allocated.
1017
 
         */
1018
 
        
1019
 
        prs_give_memory( &pd, data, sd_len, False);
1020
 
 
1021
 
        /*
1022
 
         * Finally, unmarshall from the data buffer.
1023
 
         */
1024
 
 
1025
 
        if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
1026
 
                DEBUG(0,("set_sd: Error in unmarshalling security descriptor.\n"));
1027
 
                /*
1028
 
                 * Return access denied for want of a better error message..
1029
 
                 */ 
1030
 
                talloc_destroy(mem_ctx);
1031
 
                return NT_STATUS_NO_MEMORY;
1032
 
        }
1033
 
        
1034
 
        if (psd->off_owner_sid==0) {
1035
 
                security_info_sent &= ~OWNER_SECURITY_INFORMATION;
1036
 
        }
1037
 
        if (psd->off_grp_sid==0) {
1038
 
                security_info_sent &= ~GROUP_SECURITY_INFORMATION;
1039
 
        }
1040
 
        if (psd->off_sacl==0) {
1041
 
                security_info_sent &= ~SACL_SECURITY_INFORMATION;
1042
 
        }
1043
 
        if (psd->off_dacl==0) {
1044
 
                security_info_sent &= ~DACL_SECURITY_INFORMATION;
1045
 
        }
1046
 
        
1047
 
        ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd);
1048
 
        
1049
 
        if (!ret) {
1050
 
                talloc_destroy(mem_ctx);
1051
 
                return NT_STATUS_ACCESS_DENIED;
1052
 
        }
1053
 
        
1054
 
        talloc_destroy(mem_ctx);
1055
 
        
1056
 
        return NT_STATUS_OK;
1057
 
}
1058
 
 
1059
 
/****************************************************************************
1060
 
 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
1061
 
****************************************************************************/
1062
 
                                                                                                                             
1063
 
static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
1064
 
{
1065
 
        struct ea_list *ea_list_head = NULL;
1066
 
        size_t offset = 0;
1067
 
 
1068
 
        if (data_size < 4) {
1069
 
                return NULL;
1070
 
        }
1071
 
 
1072
 
        while (offset + 4 <= data_size) {
1073
 
                size_t next_offset = IVAL(pdata,offset);
1074
 
                struct ea_list *tmp;
1075
 
                struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL);
1076
 
 
1077
 
                if (!eal) {
1078
 
                        return NULL;
1079
 
                }
1080
 
 
1081
 
                DLIST_ADD_END(ea_list_head, eal, tmp);
1082
 
                if (next_offset == 0) {
1083
 
                        break;
1084
 
                }
1085
 
                offset += next_offset;
1086
 
        }
1087
 
                                                                                                                             
1088
 
        return ea_list_head;
1089
 
}
1090
 
 
1091
 
/****************************************************************************
1092
 
 Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
1093
 
****************************************************************************/
1094
 
 
1095
 
static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1096
 
                                  uint16 **ppsetup, uint32 setup_count,
1097
 
                                  char **ppparams, uint32 parameter_count,
1098
 
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
1099
 
{
1100
 
        pstring fname;
1101
 
        char *params = *ppparams;
1102
 
        char *data = *ppdata;
1103
 
        /* Breakout the oplock request bits so we can set the reply bits separately. */
1104
 
        int oplock_request = 0;
1105
 
        uint32 fattr=0;
1106
 
        SMB_OFF_T file_len = 0;
1107
 
        SMB_STRUCT_STAT sbuf;
1108
 
        int info = 0;
1109
 
        BOOL bad_path = False;
1110
 
        files_struct *fsp = NULL;
1111
 
        char *p = NULL;
1112
 
        BOOL extended_oplock_granted = False;
1113
 
        uint32 flags;
1114
 
        uint32 access_mask;
1115
 
        uint32 file_attributes;
1116
 
        uint32 share_access;
1117
 
        uint32 create_disposition;
1118
 
        uint32 create_options;
1119
 
        uint32 sd_len;
1120
 
        uint32 ea_len;
1121
 
        uint16 root_dir_fid;
1122
 
        time_t c_time;
1123
 
        struct ea_list *ea_list = NULL;
1124
 
        TALLOC_CTX *ctx = NULL;
1125
 
        char *pdata = NULL;
1126
 
        NTSTATUS status;
1127
 
 
1128
 
        DEBUG(5,("call_nt_transact_create\n"));
1129
 
 
1130
 
        /*
1131
 
         * If it's an IPC, use the pipe handler.
1132
 
         */
1133
 
 
1134
 
        if (IS_IPC(conn)) {
1135
 
                if (lp_nt_pipe_support()) {
1136
 
                        return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, 
1137
 
                                        bufsize,
1138
 
                                        ppsetup, setup_count,
1139
 
                                        ppparams, parameter_count,
1140
 
                                        ppdata, data_count);
1141
 
                } else {
1142
 
                        return ERROR_DOS(ERRDOS,ERRnoaccess);
1143
 
                }
1144
 
        }
1145
 
 
1146
 
        /*
1147
 
         * Ensure minimum number of parameters sent.
1148
 
         */
1149
 
 
1150
 
        if(parameter_count < 54) {
1151
 
                DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
1152
 
                return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1153
 
        }
1154
 
 
1155
 
        flags = IVAL(params,0);
1156
 
        access_mask = IVAL(params,8);
1157
 
        file_attributes = IVAL(params,20);
1158
 
        share_access = IVAL(params,24);
1159
 
        create_disposition = IVAL(params,28);
1160
 
        create_options = IVAL(params,32);
1161
 
        sd_len = IVAL(params,36);
1162
 
        ea_len = IVAL(params,40);
1163
 
        root_dir_fid = (uint16)IVAL(params,4);
1164
 
 
1165
 
        /* Ensure the data_len is correct for the sd and ea values given. */
1166
 
        if ((ea_len + sd_len > data_count) ||
1167
 
                        (ea_len > data_count) || (sd_len > data_count) ||
1168
 
                        (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
1169
 
                DEBUG(10,("call_nt_transact_create - ea_len = %u, sd_len = %u, data_count = %u\n",
1170
 
                        (unsigned int)ea_len, (unsigned int)sd_len, (unsigned int)data_count ));
1171
 
                return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1172
 
        }
1173
 
 
1174
 
        if (ea_len) {
1175
 
                if (!lp_ea_support(SNUM(conn))) {
1176
 
                        DEBUG(10,("call_nt_transact_create - ea_len = %u but EA's not supported.\n",
1177
 
                                (unsigned int)ea_len ));
1178
 
                        return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
1179
 
                }
1180
 
 
1181
 
                if (ea_len < 10) {
1182
 
                        DEBUG(10,("call_nt_transact_create - ea_len = %u - too small (should be more than 10)\n",
1183
 
                                (unsigned int)ea_len ));
1184
 
                        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1185
 
                }
1186
 
        }
1187
 
 
1188
 
        if (create_options & FILE_OPEN_BY_FILE_ID) {
1189
 
                return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
1190
 
        }
1191
 
 
1192
 
        /*
1193
 
         * Get the file name.
1194
 
         */
1195
 
 
1196
 
        if(root_dir_fid != 0) {
1197
 
                /*
1198
 
                 * This filename is relative to a directory fid.
1199
 
                 */
1200
 
                files_struct *dir_fsp = file_fsp(params,4);
1201
 
                size_t dir_name_len;
1202
 
 
1203
 
                if(!dir_fsp) {
1204
 
                        return ERROR_DOS(ERRDOS,ERRbadfid);
1205
 
                }
1206
 
 
1207
 
                if(!dir_fsp->is_directory) {
1208
 
                        srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
1209
 
                        if (!NT_STATUS_IS_OK(status)) {
1210
 
                                return ERROR_NT(status);
1211
 
                        }
1212
 
 
1213
 
                        /*
1214
 
                         * Check to see if this is a mac fork of some kind.
1215
 
                         */
1216
 
 
1217
 
                        if( is_ntfs_stream_name(fname)) {
1218
 
                                return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1219
 
                        }
1220
 
 
1221
 
                        return ERROR_DOS(ERRDOS,ERRbadfid);
1222
 
                }
1223
 
 
1224
 
                /*
1225
 
                 * Copy in the base directory name.
1226
 
                 */
1227
 
 
1228
 
                pstrcpy( fname, dir_fsp->fsp_name );
1229
 
                dir_name_len = strlen(fname);
1230
 
 
1231
 
                /*
1232
 
                 * Ensure it ends in a '\'.
1233
 
                 */
1234
 
 
1235
 
                if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
1236
 
                        pstrcat(fname, "/");
1237
 
                        dir_name_len++;
1238
 
                }
1239
 
 
1240
 
                {
1241
 
                        pstring tmpname;
1242
 
                        srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status);
1243
 
                        if (!NT_STATUS_IS_OK(status)) {
1244
 
                                return ERROR_NT(status);
1245
 
                        }
1246
 
                        pstrcat(fname, tmpname);
1247
 
                }
1248
 
        } else {
1249
 
                srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
1250
 
                if (!NT_STATUS_IS_OK(status)) {
1251
 
                        return ERROR_NT(status);
1252
 
                }
1253
 
 
1254
 
                /*
1255
 
                 * Check to see if this is a mac fork of some kind.
1256
 
                 */
1257
 
 
1258
 
                if( is_ntfs_stream_name(fname)) {
1259
 
                        return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1260
 
                }
1261
 
        }
1262
 
 
1263
 
        oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1264
 
        oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
1265
 
 
1266
 
        /*
1267
 
         * Check if POSIX semantics are wanted.
1268
 
         */
1269
 
 
1270
 
        set_posix_case_semantics(conn, file_attributes);
1271
 
    
1272
 
        RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1273
 
 
1274
 
        unix_convert(fname,conn,0,&bad_path,&sbuf);
1275
 
        if (bad_path) {
1276
 
                restore_case_semantics(conn, file_attributes);
1277
 
                return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1278
 
        }
1279
 
        /* All file access must go through check_name() */
1280
 
        if (!check_name(fname,conn)) {
1281
 
                restore_case_semantics(conn, file_attributes);
1282
 
                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1283
 
        }
1284
 
    
1285
 
#if 0
1286
 
        /* This is the correct thing to do (check every time) but can_delete is
1287
 
           expensive (it may have to read the parent directory permissions). So
1288
 
           for now we're not doing it unless we have a strong hint the client
1289
 
           is really going to delete this file. */
1290
 
        if (desired_access & DELETE_ACCESS) {
1291
 
#else
1292
 
        /* Setting FILE_SHARE_DELETE is the hint. */
1293
 
        if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE) && (access_mask & DELETE_ACCESS)) {
1294
 
#endif
1295
 
                status = can_delete(conn, fname, file_attributes, bad_path, True);
1296
 
                /* We're only going to fail here if it's access denied, as that's the
1297
 
                   only error we care about for "can we delete this ?" questions. */
1298
 
                if (!NT_STATUS_IS_OK(status) && (NT_STATUS_EQUAL(status,NT_STATUS_ACCESS_DENIED) ||
1299
 
                                                 NT_STATUS_EQUAL(status,NT_STATUS_CANNOT_DELETE))) {
1300
 
                        restore_case_semantics(conn, file_attributes);
1301
 
                        return ERROR_NT(status);
1302
 
                }
1303
 
        }
1304
 
 
1305
 
        if (ea_len) {
1306
 
                ctx = talloc_init("NTTRANS_CREATE_EA");
1307
 
                if (!ctx) {
1308
 
                        talloc_destroy(ctx);
1309
 
                        restore_case_semantics(conn, file_attributes);
1310
 
                        return ERROR_NT(NT_STATUS_NO_MEMORY);
1311
 
                }
1312
 
 
1313
 
                pdata = data + sd_len;
1314
 
 
1315
 
                /* We have already checked that ea_len <= data_count here. */
1316
 
                ea_list = read_nttrans_ea_list(ctx, pdata, ea_len);
1317
 
                if (!ea_list ) {
1318
 
                        talloc_destroy(ctx);
1319
 
                        restore_case_semantics(conn, file_attributes);
1320
 
                        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1321
 
                }
1322
 
        }
1323
 
 
1324
 
        /*
1325
 
         * If it's a request for a directory open, deal with it separately.
1326
 
         */
1327
 
 
1328
 
        if(create_options & FILE_DIRECTORY_FILE) {
1329
 
 
1330
 
                /* Can't open a temp directory. IFS kit test. */
1331
 
                if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
1332
 
                        talloc_destroy(ctx);
1333
 
                        restore_case_semantics(conn, file_attributes);
1334
 
                        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1335
 
                }
1336
 
 
1337
 
                oplock_request = 0;
1338
 
 
1339
 
                /*
1340
 
                 * We will get a create directory here if the Win32
1341
 
                 * app specified a security descriptor in the 
1342
 
                 * CreateDirectory() call.
1343
 
                 */
1344
 
 
1345
 
                status = open_directory(conn, fname, &sbuf,
1346
 
                                        access_mask,
1347
 
                                        share_access,
1348
 
                                        create_disposition,
1349
 
                                        create_options,
1350
 
                                        &info, &fsp);
1351
 
                if(!NT_STATUS_IS_OK(status)) {
1352
 
                        talloc_destroy(ctx);
1353
 
                        restore_case_semantics(conn, file_attributes);
1354
 
                        return ERROR_NT(status);
1355
 
                }
1356
 
 
1357
 
        } else {
1358
 
 
1359
 
                /*
1360
 
                 * Ordinary file case.
1361
 
                 */
1362
 
 
1363
 
                status = open_file_ntcreate(conn,fname,&sbuf,
1364
 
                                        access_mask,
1365
 
                                        share_access,
1366
 
                                        create_disposition,
1367
 
                                        create_options,
1368
 
                                        file_attributes,
1369
 
                                        oplock_request,
1370
 
                                        &info, &fsp);
1371
 
 
1372
 
                if (!NT_STATUS_IS_OK(status)) { 
1373
 
                        if (NT_STATUS_EQUAL(status,
1374
 
                                            NT_STATUS_FILE_IS_A_DIRECTORY)) {
1375
 
 
1376
 
                                /*
1377
 
                                 * Fail the open if it was explicitly a non-directory file.
1378
 
                                 */
1379
 
 
1380
 
                                if (create_options & FILE_NON_DIRECTORY_FILE) {
1381
 
                                        restore_case_semantics(conn, file_attributes);
1382
 
                                        return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
1383
 
                                }
1384
 
        
1385
 
                                oplock_request = 0;
1386
 
                                status = open_directory(conn, fname, &sbuf,
1387
 
                                                        access_mask,
1388
 
                                                        share_access,
1389
 
                                                        create_disposition,
1390
 
                                                        create_options,
1391
 
                                                        &info, &fsp);
1392
 
                                if(!NT_STATUS_IS_OK(status)) {
1393
 
                                        talloc_destroy(ctx);
1394
 
                                        restore_case_semantics(conn, file_attributes);
1395
 
                                        return ERROR_NT(status);
1396
 
                                }
1397
 
                        } else {
1398
 
                                talloc_destroy(ctx);
1399
 
                                restore_case_semantics(conn, file_attributes);
1400
 
                                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1401
 
                                        /* We have re-scheduled this call. */
1402
 
                                        return -1;
1403
 
                                }
1404
 
                                return ERROR_NT(status);
1405
 
                        }
1406
 
                } 
1407
 
        }
1408
 
 
1409
 
        /*
1410
 
         * According to the MS documentation, the only time the security
1411
 
         * descriptor is applied to the opened file is iff we *created* the
1412
 
         * file; an existing file stays the same.
1413
 
         * 
1414
 
         * Also, it seems (from observation) that you can open the file with
1415
 
         * any access mask but you can still write the sd. We need to override
1416
 
         * the granted access before we call set_sd
1417
 
         * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
1418
 
         */
1419
 
 
1420
 
        if (lp_nt_acl_support(SNUM(conn)) && sd_len && info == FILE_WAS_CREATED) {
1421
 
                uint32 saved_access_mask = fsp->access_mask;
1422
 
 
1423
 
                /* We have already checked that sd_len <= data_count here. */
1424
 
 
1425
 
                fsp->access_mask = FILE_GENERIC_ALL;
1426
 
 
1427
 
                status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION);
1428
 
                if (!NT_STATUS_IS_OK(status)) {
1429
 
                        talloc_destroy(ctx);
1430
 
                        close_file(fsp,ERROR_CLOSE);
1431
 
                        restore_case_semantics(conn, file_attributes);
1432
 
                        return ERROR_NT(status);
1433
 
                }
1434
 
                fsp->access_mask = saved_access_mask;
1435
 
        }
1436
 
        
1437
 
        if (ea_len && (info == FILE_WAS_CREATED)) {
1438
 
                status = set_ea(conn, fsp, fname, ea_list);
1439
 
                talloc_destroy(ctx);
1440
 
                if (!NT_STATUS_IS_OK(status)) {
1441
 
                        close_file(fsp,ERROR_CLOSE);
1442
 
                        restore_case_semantics(conn, file_attributes);
1443
 
                        return ERROR_NT(status);
1444
 
                }
1445
 
        }
1446
 
 
1447
 
        restore_case_semantics(conn, file_attributes);
1448
 
 
1449
 
        file_len = sbuf.st_size;
1450
 
        fattr = dos_mode(conn,fname,&sbuf);
1451
 
        if(fattr == 0) {
1452
 
                fattr = FILE_ATTRIBUTE_NORMAL;
1453
 
        }
1454
 
        if (!fsp->is_directory && (fattr & aDIR)) {
1455
 
                close_file(fsp,ERROR_CLOSE);
1456
 
                return ERROR_DOS(ERRDOS,ERRnoaccess);
1457
 
        } 
1458
 
        
1459
 
        /* Save the requested allocation size. */
1460
 
        if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1461
 
                SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(params,12);
1462
 
#ifdef LARGE_SMB_OFF_T
1463
 
                allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
1464
 
#endif
1465
 
                if (allocation_size && (allocation_size > file_len)) {
1466
 
                        fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1467
 
                        if (fsp->is_directory) {
1468
 
                                close_file(fsp,ERROR_CLOSE);
1469
 
                                /* Can't set allocation size on a directory. */
1470
 
                                return ERROR_NT(NT_STATUS_ACCESS_DENIED);
1471
 
                        }
1472
 
                        if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1473
 
                                close_file(fsp,ERROR_CLOSE);
1474
 
                                return ERROR_NT(NT_STATUS_DISK_FULL);
1475
 
                        }
1476
 
                } else {
1477
 
                        fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len);
1478
 
                }
1479
 
        }
1480
 
 
1481
 
        /* 
1482
 
         * If the caller set the extended oplock request bit
1483
 
         * and we granted one (by whatever means) - set the
1484
 
         * correct bit for extended oplock reply.
1485
 
         */
1486
 
    
1487
 
        if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1488
 
                extended_oplock_granted = True;
1489
 
        }
1490
 
  
1491
 
        if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1492
 
                extended_oplock_granted = True;
1493
 
        }
1494
 
 
1495
 
        /* Realloc the size of parameters and data we will return */
1496
 
        params = nttrans_realloc(ppparams, 69);
1497
 
        if(params == NULL) {
1498
 
                return ERROR_DOS(ERRDOS,ERRnomem);
1499
 
        }
1500
 
 
1501
 
        p = params;
1502
 
        if (extended_oplock_granted) {
1503
 
                SCVAL(p,0, BATCH_OPLOCK_RETURN);
1504
 
        } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
1505
 
                SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
1506
 
        } else {
1507
 
                SCVAL(p,0,NO_OPLOCK_RETURN);
1508
 
        }
1509
 
        
1510
 
        p += 2;
1511
 
        SSVAL(p,0,fsp->fnum);
1512
 
        p += 2;
1513
 
        if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) {
1514
 
                SIVAL(p,0,FILE_WAS_SUPERSEDED);
1515
 
        } else {
1516
 
                SIVAL(p,0,info);
1517
 
        }
1518
 
        p += 8;
1519
 
 
1520
 
        /* Create time. */
1521
 
        c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1522
 
 
1523
 
        if (lp_dos_filetime_resolution(SNUM(conn))) {
1524
 
                c_time &= ~1;
1525
 
                sbuf.st_atime &= ~1;
1526
 
                sbuf.st_mtime &= ~1;
1527
 
                sbuf.st_mtime &= ~1;
1528
 
        }
1529
 
 
1530
 
        put_long_date(p,c_time);
1531
 
        p += 8;
1532
 
        put_long_date(p,sbuf.st_atime); /* access time */
1533
 
        p += 8;
1534
 
        put_long_date(p,sbuf.st_mtime); /* write time */
1535
 
        p += 8;
1536
 
        put_long_date(p,sbuf.st_mtime); /* change time */
1537
 
        p += 8;
1538
 
        SIVAL(p,0,fattr); /* File Attributes. */
1539
 
        p += 4;
1540
 
        SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
1541
 
        p += 8;
1542
 
        SOFF_T(p,0,file_len);
1543
 
        p += 8;
1544
 
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
1545
 
                SSVAL(p,2,0x7);
1546
 
        }
1547
 
        p += 4;
1548
 
        SCVAL(p,0,fsp->is_directory ? 1 : 0);
1549
 
 
1550
 
        DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
1551
 
 
1552
 
        /* Send the required number of replies */
1553
 
        send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 69, *ppdata, 0);
1554
 
 
1555
 
        return -1;
1556
 
}
1557
 
 
1558
 
/****************************************************************************
1559
 
 Reply to a NT CANCEL request.
1560
 
 conn POINTER CAN BE NULL HERE !
1561
 
****************************************************************************/
1562
 
 
1563
 
int reply_ntcancel(connection_struct *conn,
1564
 
                   char *inbuf,char *outbuf,int length,int bufsize)
1565
 
{
1566
 
        /*
1567
 
         * Go through and cancel any pending change notifies.
1568
 
         */
1569
 
        
1570
 
        int mid = SVAL(inbuf,smb_mid);
1571
 
        START_PROFILE(SMBntcancel);
1572
 
        remove_pending_change_notify_requests_by_mid(mid);
1573
 
        remove_pending_lock_requests_by_mid(mid);
1574
 
        srv_cancel_sign_response(mid);
1575
 
        
1576
 
        DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
1577
 
 
1578
 
        END_PROFILE(SMBntcancel);
1579
 
        return(-1);
1580
 
}
1581
 
 
1582
 
/****************************************************************************
1583
 
 Copy a file.
1584
 
****************************************************************************/
1585
 
 
1586
 
static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *newname, uint32 attrs)
1587
 
{
1588
 
        BOOL bad_path_oldname = False;
1589
 
        BOOL bad_path_newname = False;
1590
 
        SMB_STRUCT_STAT sbuf1, sbuf2;
1591
 
        pstring last_component_oldname;
1592
 
        pstring last_component_newname;
1593
 
        files_struct *fsp1,*fsp2;
1594
 
        uint32 fattr;
1595
 
        int info;
1596
 
        SMB_OFF_T ret=-1;
1597
 
        int close_ret;
1598
 
        NTSTATUS status = NT_STATUS_OK;
1599
 
 
1600
 
        ZERO_STRUCT(sbuf1);
1601
 
        ZERO_STRUCT(sbuf2);
1602
 
 
1603
 
        /* No wildcards. */
1604
 
        if (ms_has_wild(newname) || ms_has_wild(oldname)) {
1605
 
                return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
1606
 
        }
1607
 
 
1608
 
        if (!CAN_WRITE(conn))
1609
 
                return NT_STATUS_MEDIA_WRITE_PROTECTED;
1610
 
 
1611
 
        unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
1612
 
        if (bad_path_oldname) {
1613
 
                return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1614
 
        }
1615
 
 
1616
 
        /* Quick check for "." and ".." */
1617
 
        if (last_component_oldname[0] == '.') {
1618
 
                if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
1619
 
                        return NT_STATUS_OBJECT_NAME_INVALID;
1620
 
                }
1621
 
        }
1622
 
 
1623
 
        /* Source must already exist. */
1624
 
        if (!VALID_STAT(sbuf1)) {
1625
 
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1626
 
        }
1627
 
        if (!check_name(oldname,conn)) {
1628
 
                return NT_STATUS_ACCESS_DENIED;
1629
 
        }
1630
 
 
1631
 
        /* Ensure attributes match. */
1632
 
        fattr = dos_mode(conn,oldname,&sbuf1);
1633
 
        if ((fattr & ~attrs) & (aHIDDEN | aSYSTEM)) {
1634
 
                return NT_STATUS_NO_SUCH_FILE;
1635
 
        }
1636
 
 
1637
 
        unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
1638
 
        if (bad_path_newname) {
1639
 
                return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1640
 
        }
1641
 
 
1642
 
        /* Quick check for "." and ".." */
1643
 
        if (last_component_newname[0] == '.') {
1644
 
                if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
1645
 
                        return NT_STATUS_OBJECT_NAME_INVALID;
1646
 
                }
1647
 
        }
1648
 
 
1649
 
        /* Disallow if newname already exists. */
1650
 
        if (VALID_STAT(sbuf2)) {
1651
 
                return NT_STATUS_OBJECT_NAME_COLLISION;
1652
 
        }
1653
 
 
1654
 
        if (!check_name(newname,conn)) {
1655
 
                return NT_STATUS_ACCESS_DENIED;
1656
 
        }
1657
 
 
1658
 
        /* No links from a directory. */
1659
 
        if (S_ISDIR(sbuf1.st_mode)) {
1660
 
                return NT_STATUS_FILE_IS_A_DIRECTORY;
1661
 
        }
1662
 
 
1663
 
        /* Ensure this is within the share. */
1664
 
        if (!reduce_name(conn, oldname) != 0) {
1665
 
                return NT_STATUS_ACCESS_DENIED;
1666
 
        }
1667
 
 
1668
 
        DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname));
1669
 
 
1670
 
        status = open_file_ntcreate(conn,oldname,&sbuf1,
1671
 
                        FILE_READ_DATA, /* Read-only. */
1672
 
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1673
 
                        FILE_OPEN,
1674
 
                        0, /* No create options. */
1675
 
                        FILE_ATTRIBUTE_NORMAL,
1676
 
                        NO_OPLOCK,
1677
 
                        &info, &fsp1);
1678
 
 
1679
 
        if (!NT_STATUS_IS_OK(status)) {
1680
 
                return status;
1681
 
        }
1682
 
 
1683
 
        status = open_file_ntcreate(conn,newname,&sbuf2,
1684
 
                        FILE_WRITE_DATA, /* Read-only. */
1685
 
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1686
 
                        FILE_CREATE,
1687
 
                        0, /* No create options. */
1688
 
                        fattr,
1689
 
                        NO_OPLOCK,
1690
 
                        &info, &fsp2);
1691
 
 
1692
 
        if (!NT_STATUS_IS_OK(status)) {
1693
 
                close_file(fsp1,ERROR_CLOSE);
1694
 
                return status;
1695
 
        }
1696
 
 
1697
 
        if (sbuf1.st_size) {
1698
 
                ret = vfs_transfer_file(fsp1, fsp2, sbuf1.st_size);
1699
 
        }
1700
 
 
1701
 
        /*
1702
 
         * As we are opening fsp1 read-only we only expect
1703
 
         * an error on close on fsp2 if we are out of space.
1704
 
         * Thus we don't look at the error return from the
1705
 
         * close of fsp1.
1706
 
         */
1707
 
        close_file(fsp1,NORMAL_CLOSE);
1708
 
 
1709
 
        /* Ensure the modtime is set correctly on the destination file. */
1710
 
        fsp_set_pending_modtime(fsp2, sbuf1.st_mtime);
1711
 
 
1712
 
        close_ret = close_file(fsp2,NORMAL_CLOSE);
1713
 
 
1714
 
        /* Grrr. We have to do this as open_file_ntcreate adds aARCH when it
1715
 
           creates the file. This isn't the correct thing to do in the copy
1716
 
           case. JRA */
1717
 
        file_set_dosmode(conn, newname, fattr, &sbuf2, True);
1718
 
 
1719
 
        if (ret < (SMB_OFF_T)sbuf1.st_size) {
1720
 
                return NT_STATUS_DISK_FULL;
1721
 
        }
1722
 
 
1723
 
        if (close_ret != 0) {
1724
 
                status = map_nt_error_from_unix(close_ret);
1725
 
                DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",
1726
 
                        nt_errstr(status), oldname, newname));
1727
 
        }
1728
 
        return status;
1729
 
}
1730
 
 
1731
 
/****************************************************************************
1732
 
 Reply to a NT rename request.
1733
 
****************************************************************************/
1734
 
 
1735
 
int reply_ntrename(connection_struct *conn,
1736
 
                   char *inbuf,char *outbuf,int length,int bufsize)
1737
 
{
1738
 
        int outsize = 0;
1739
 
        pstring oldname;
1740
 
        pstring newname;
1741
 
        char *p;
1742
 
        NTSTATUS status;
1743
 
        BOOL path_contains_wcard = False;
1744
 
        uint32 attrs = SVAL(inbuf,smb_vwv0);
1745
 
        uint16 rename_type = SVAL(inbuf,smb_vwv1);
1746
 
 
1747
 
        START_PROFILE(SMBntrename);
1748
 
 
1749
 
        p = smb_buf(inbuf) + 1;
1750
 
        p += srvstr_get_path_wcard(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, &path_contains_wcard);
1751
 
        if (!NT_STATUS_IS_OK(status)) {
1752
 
                END_PROFILE(SMBntrename);
1753
 
                return ERROR_NT(status);
1754
 
        }
1755
 
 
1756
 
        if( is_ntfs_stream_name(oldname)) {
1757
 
                /* Can't rename a stream. */
1758
 
                END_PROFILE(SMBntrename);
1759
 
                return ERROR_NT(NT_STATUS_ACCESS_DENIED);
1760
 
        }
1761
 
 
1762
 
        if (ms_has_wild(oldname)) {
1763
 
                END_PROFILE(SMBntrename);
1764
 
                return ERROR_NT(NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
1765
 
        }
1766
 
 
1767
 
        p++;
1768
 
        p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status);
1769
 
        if (!NT_STATUS_IS_OK(status)) {
1770
 
                END_PROFILE(SMBntrename);
1771
 
                return ERROR_NT(status);
1772
 
        }
1773
 
        
1774
 
        RESOLVE_DFSPATH(oldname, conn, inbuf, outbuf);
1775
 
        RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
1776
 
        
1777
 
        DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
1778
 
        
1779
 
        switch(rename_type) {
1780
 
                case RENAME_FLAG_RENAME:
1781
 
                        status = rename_internals(conn, oldname, newname, attrs, False, path_contains_wcard);
1782
 
                        break;
1783
 
                case RENAME_FLAG_HARD_LINK:
1784
 
                        status = hardlink_internals(conn, oldname, newname);
1785
 
                        break;
1786
 
                case RENAME_FLAG_COPY:
1787
 
                        if (path_contains_wcard) {
1788
 
                                /* No wildcards. */
1789
 
                                status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
1790
 
                        } else {
1791
 
                                status = copy_internals(conn, oldname, newname, attrs);
1792
 
                        }
1793
 
                        break;
1794
 
                case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
1795
 
                        status = NT_STATUS_INVALID_PARAMETER;
1796
 
                        break;
1797
 
                default:
1798
 
                        status = NT_STATUS_ACCESS_DENIED; /* Default error. */
1799
 
                        break;
1800
 
        }
1801
 
 
1802
 
        if (!NT_STATUS_IS_OK(status)) {
1803
 
                END_PROFILE(SMBntrename);
1804
 
                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1805
 
                        /* We have re-scheduled this call. */
1806
 
                        return -1;
1807
 
                }
1808
 
                return ERROR_NT(status);
1809
 
        }
1810
 
 
1811
 
        /*
1812
 
         * Win2k needs a changenotify request response before it will
1813
 
         * update after a rename..
1814
 
         */     
1815
 
        process_pending_change_notify_queue((time_t)0);
1816
 
        outsize = set_message(outbuf,0,0,False);
1817
 
  
1818
 
        END_PROFILE(SMBntrename);
1819
 
        return(outsize);
1820
 
}
1821
 
 
1822
 
/****************************************************************************
1823
 
 Reply to a notify change - queue the request and 
1824
 
 don't allow a directory to be opened.
1825
 
****************************************************************************/
1826
 
 
1827
 
static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
1828
 
                                  uint16 **ppsetup, uint32 setup_count,
1829
 
                                  char **ppparams, uint32 parameter_count,
1830
 
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
1831
 
{
1832
 
        uint16 *setup = *ppsetup;
1833
 
        files_struct *fsp;
1834
 
        uint32 flags;
1835
 
 
1836
 
        if(setup_count < 6) {
1837
 
                return ERROR_DOS(ERRDOS,ERRbadfunc);
1838
 
        }
1839
 
 
1840
 
        fsp = file_fsp((char *)setup,4);
1841
 
        flags = IVAL(setup, 0);
1842
 
 
1843
 
        DEBUG(3,("call_nt_transact_notify_change\n"));
1844
 
 
1845
 
        if(!fsp) {
1846
 
                return ERROR_DOS(ERRDOS,ERRbadfid);
1847
 
        }
1848
 
 
1849
 
        if((!fsp->is_directory) || (conn != fsp->conn)) {
1850
 
                return ERROR_DOS(ERRDOS,ERRbadfid);
1851
 
        }
1852
 
 
1853
 
        if (!change_notify_set(inbuf, fsp, conn, flags)) {
1854
 
                return(UNIXERROR(ERRDOS,ERRbadfid));
1855
 
        }
1856
 
 
1857
 
        DEBUG(3,("call_nt_transact_notify_change: notify change called on directory \
1858
 
name = %s\n", fsp->fsp_name ));
1859
 
 
1860
 
        return -1;
1861
 
}
1862
 
 
1863
 
/****************************************************************************
1864
 
 Reply to an NT transact rename command.
1865
 
****************************************************************************/
1866
 
 
1867
 
static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1868
 
                                  uint16 **ppsetup, uint32 setup_count,
1869
 
                                  char **ppparams, uint32 parameter_count,
1870
 
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
1871
 
{
1872
 
        char *params = *ppparams;
1873
 
        pstring new_name;
1874
 
        files_struct *fsp = NULL;
1875
 
        BOOL replace_if_exists = False;
1876
 
        BOOL path_contains_wcard = False;
1877
 
        NTSTATUS status;
1878
 
 
1879
 
        if(parameter_count < 4) {
1880
 
                return ERROR_DOS(ERRDOS,ERRbadfunc);
1881
 
        }
1882
 
 
1883
 
        fsp = file_fsp(params, 0);
1884
 
        replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
1885
 
        CHECK_FSP(fsp, conn);
1886
 
        srvstr_get_path_wcard(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE, &status, &path_contains_wcard);
1887
 
        if (!NT_STATUS_IS_OK(status)) {
1888
 
                return ERROR_NT(status);
1889
 
        }
1890
 
 
1891
 
        status = rename_internals(conn, fsp->fsp_name,
1892
 
                                  new_name, 0, replace_if_exists, path_contains_wcard);
1893
 
        if (!NT_STATUS_IS_OK(status))
1894
 
                return ERROR_NT(status);
1895
 
 
1896
 
        /*
1897
 
         * Rename was successful.
1898
 
         */
1899
 
        send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
1900
 
        
1901
 
        DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 
1902
 
                 fsp->fsp_name, new_name));
1903
 
        
1904
 
        /*
1905
 
         * Win2k needs a changenotify request response before it will
1906
 
         * update after a rename..
1907
 
         */
1908
 
        
1909
 
        process_pending_change_notify_queue((time_t)0);
1910
 
 
1911
 
        return -1;
1912
 
}
1913
 
 
1914
 
/******************************************************************************
1915
 
 Fake up a completely empty SD.
1916
 
*******************************************************************************/
1917
 
 
1918
 
static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
1919
 
{
1920
 
        size_t sd_size;
1921
 
 
1922
 
        *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
1923
 
        if(!*ppsd) {
1924
 
                DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));
1925
 
                sd_size = 0;
1926
 
        }
1927
 
 
1928
 
        return sd_size;
1929
 
}
1930
 
 
1931
 
/****************************************************************************
1932
 
 Reply to query a security descriptor.
1933
 
****************************************************************************/
1934
 
 
1935
 
static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
1936
 
                                  uint16 **ppsetup, uint32 setup_count,
1937
 
                                  char **ppparams, uint32 parameter_count,
1938
 
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
1939
 
{
1940
 
        char *params = *ppparams;
1941
 
        char *data = *ppdata;
1942
 
        prs_struct pd;
1943
 
        SEC_DESC *psd = NULL;
1944
 
        size_t sd_size;
1945
 
        uint32 security_info_wanted;
1946
 
        TALLOC_CTX *mem_ctx;
1947
 
        files_struct *fsp = NULL;
1948
 
 
1949
 
        if(parameter_count < 8) {
1950
 
                return ERROR_DOS(ERRDOS,ERRbadfunc);
1951
 
        }
1952
 
 
1953
 
        fsp = file_fsp(params,0);
1954
 
        if(!fsp) {
1955
 
                return ERROR_DOS(ERRDOS,ERRbadfid);
1956
 
        }
1957
 
 
1958
 
        security_info_wanted = IVAL(params,4);
1959
 
 
1960
 
        DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name,
1961
 
                        (unsigned int)security_info_wanted ));
1962
 
 
1963
 
        params = nttrans_realloc(ppparams, 4);
1964
 
        if(params == NULL) {
1965
 
                return ERROR_DOS(ERRDOS,ERRnomem);
1966
 
        }
1967
 
 
1968
 
        if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) {
1969
 
                DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
1970
 
                return ERROR_DOS(ERRDOS,ERRnomem);
1971
 
        }
1972
 
 
1973
 
        /*
1974
 
         * Get the permissions to return.
1975
 
         */
1976
 
 
1977
 
        if (!lp_nt_acl_support(SNUM(conn))) {
1978
 
                sd_size = get_null_nt_acl(mem_ctx, &psd);
1979
 
        } else {
1980
 
                sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, security_info_wanted, &psd);
1981
 
        }
1982
 
 
1983
 
        if (sd_size == 0) {
1984
 
                talloc_destroy(mem_ctx);
1985
 
                return(UNIXERROR(ERRDOS,ERRnoaccess));
1986
 
        }
1987
 
 
1988
 
        DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
1989
 
 
1990
 
        SIVAL(params,0,(uint32)sd_size);
1991
 
 
1992
 
        if(max_data_count < sd_size) {
1993
 
 
1994
 
                send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
1995
 
                        params, 4, *ppdata, 0);
1996
 
                talloc_destroy(mem_ctx);
1997
 
                return -1;
1998
 
        }
1999
 
 
2000
 
        /*
2001
 
         * Allocate the data we will point this at.
2002
 
         */
2003
 
 
2004
 
        data = nttrans_realloc(ppdata, sd_size);
2005
 
        if(data == NULL) {
2006
 
                talloc_destroy(mem_ctx);
2007
 
                return ERROR_DOS(ERRDOS,ERRnomem);
2008
 
        }
2009
 
 
2010
 
        /*
2011
 
         * Init the parse struct we will marshall into.
2012
 
         */
2013
 
 
2014
 
        prs_init(&pd, 0, mem_ctx, MARSHALL);
2015
 
 
2016
 
        /*
2017
 
         * Setup the prs_struct to point at the memory we just
2018
 
         * allocated.
2019
 
         */
2020
 
 
2021
 
        prs_give_memory( &pd, data, (uint32)sd_size, False);
2022
 
 
2023
 
        /*
2024
 
         * Finally, linearize into the outgoing buffer.
2025
 
         */
2026
 
 
2027
 
        if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
2028
 
                DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
2029
 
security descriptor.\n"));
2030
 
                /*
2031
 
                 * Return access denied for want of a better error message..
2032
 
                 */ 
2033
 
                talloc_destroy(mem_ctx);
2034
 
                return(UNIXERROR(ERRDOS,ERRnoaccess));
2035
 
        }
2036
 
 
2037
 
        /*
2038
 
         * Now we can delete the security descriptor.
2039
 
         */
2040
 
 
2041
 
        talloc_destroy(mem_ctx);
2042
 
 
2043
 
        send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 4, data, (int)sd_size);
2044
 
        return -1;
2045
 
}
2046
 
 
2047
 
/****************************************************************************
2048
 
 Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
2049
 
****************************************************************************/
2050
 
 
2051
 
static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2052
 
                                  uint16 **ppsetup, uint32 setup_count,
2053
 
                                  char **ppparams, uint32 parameter_count,
2054
 
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
2055
 
{
2056
 
        char *params= *ppparams;
2057
 
        char *data = *ppdata;
2058
 
        files_struct *fsp = NULL;
2059
 
        uint32 security_info_sent = 0;
2060
 
        NTSTATUS nt_status;
2061
 
 
2062
 
        if(parameter_count < 8) {
2063
 
                return ERROR_DOS(ERRDOS,ERRbadfunc);
2064
 
        }
2065
 
 
2066
 
        if((fsp = file_fsp(params,0)) == NULL) {
2067
 
                return ERROR_DOS(ERRDOS,ERRbadfid);
2068
 
        }
2069
 
 
2070
 
        if(!lp_nt_acl_support(SNUM(conn))) {
2071
 
                goto done;
2072
 
        }
2073
 
 
2074
 
        security_info_sent = IVAL(params,4);
2075
 
 
2076
 
        DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
2077
 
                (unsigned int)security_info_sent ));
2078
 
 
2079
 
        if (data_count == 0) {
2080
 
                return ERROR_DOS(ERRDOS, ERRnoaccess);
2081
 
        }
2082
 
 
2083
 
        if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) {
2084
 
                return ERROR_NT(nt_status);
2085
 
        }
2086
 
 
2087
 
  done:
2088
 
 
2089
 
        send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
2090
 
        return -1;
2091
 
}
2092
 
   
2093
 
/****************************************************************************
2094
 
 Reply to NT IOCTL
2095
 
****************************************************************************/
2096
 
 
2097
 
static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
2098
 
                                  uint16 **ppsetup, uint32 setup_count,
2099
 
                                  char **ppparams, uint32 parameter_count,
2100
 
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
2101
 
{
2102
 
        uint32 function;
2103
 
        uint16 fidnum;
2104
 
        files_struct *fsp;
2105
 
        uint8 isFSctl;
2106
 
        uint8 compfilter;
2107
 
        static BOOL logged_message;
2108
 
        char *pdata = *ppdata;
2109
 
 
2110
 
        if (setup_count != 8) {
2111
 
                DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
2112
 
                return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
2113
 
        }
2114
 
 
2115
 
        function = IVAL(*ppsetup, 0);
2116
 
        fidnum = SVAL(*ppsetup, 4);
2117
 
        isFSctl = CVAL(*ppsetup, 6);
2118
 
        compfilter = CVAL(*ppsetup, 7);
2119
 
 
2120
 
        DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", 
2121
 
                 function, fidnum, isFSctl, compfilter));
2122
 
 
2123
 
        fsp=file_fsp((char *)*ppsetup, 4);
2124
 
        /* this check is done in each implemented function case for now
2125
 
           because I don't want to break anything... --metze
2126
 
        FSP_BELONGS_CONN(fsp,conn);*/
2127
 
 
2128
 
        switch (function) {
2129
 
        case FSCTL_SET_SPARSE:
2130
 
                /* pretend this succeeded - tho strictly we should
2131
 
                   mark the file sparse (if the local fs supports it)
2132
 
                   so we can know if we need to pre-allocate or not */
2133
 
 
2134
 
                DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
2135
 
                send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
2136
 
                return -1;
2137
 
        
2138
 
        case FSCTL_0x000900C0:
2139
 
                /* pretend this succeeded - don't know what this really is
2140
 
                   but works ok like this --metze
2141
 
                 */
2142
 
 
2143
 
                DEBUG(10,("FSCTL_0x000900C0: called on FID[0x%04X](but not implemented)\n",fidnum));
2144
 
                send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
2145
 
                return -1;
2146
 
 
2147
 
        case FSCTL_GET_REPARSE_POINT:
2148
 
                /* pretend this fail - my winXP does it like this
2149
 
                 * --metze
2150
 
                 */
2151
 
 
2152
 
                DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
2153
 
                send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
2154
 
                return -1;
2155
 
 
2156
 
        case FSCTL_SET_REPARSE_POINT:
2157
 
                /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case.
2158
 
                 * --metze
2159
 
                 */
2160
 
 
2161
 
                DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
2162
 
                send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
2163
 
                return -1;
2164
 
                        
2165
 
        case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/
2166
 
        {
2167
 
                /*
2168
 
                 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
2169
 
                 * and return their volume names.  If max_data_count is 16, then it is just
2170
 
                 * asking for the number of volumes and length of the combined names.
2171
 
                 *
2172
 
                 * pdata is the data allocated by our caller, but that uses
2173
 
                 * total_data_count (which is 0 in our case) rather than max_data_count.
2174
 
                 * Allocate the correct amount and return the pointer to let
2175
 
                 * it be deallocated when we return.
2176
 
                 */
2177
 
                SHADOW_COPY_DATA *shadow_data = NULL;
2178
 
                TALLOC_CTX *shadow_mem_ctx = NULL;
2179
 
                BOOL labels = False;
2180
 
                uint32 labels_data_count = 0;
2181
 
                uint32 i;
2182
 
                char *cur_pdata;
2183
 
 
2184
 
                FSP_BELONGS_CONN(fsp,conn);
2185
 
 
2186
 
                if (max_data_count < 16) {
2187
 
                        DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
2188
 
                                max_data_count));
2189
 
                        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2190
 
                }
2191
 
 
2192
 
                if (max_data_count > 16) {
2193
 
                        labels = True;
2194
 
                }
2195
 
 
2196
 
                shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
2197
 
                if (shadow_mem_ctx == NULL) {
2198
 
                        DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
2199
 
                        return ERROR_NT(NT_STATUS_NO_MEMORY);
2200
 
                }
2201
 
 
2202
 
                shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA);
2203
 
                if (shadow_data == NULL) {
2204
 
                        DEBUG(0,("talloc_zero() failed!\n"));
2205
 
                        talloc_destroy(shadow_mem_ctx);
2206
 
                        return ERROR_NT(NT_STATUS_NO_MEMORY);
2207
 
                }
2208
 
                
2209
 
                shadow_data->mem_ctx = shadow_mem_ctx;
2210
 
                
2211
 
                /*
2212
 
                 * Call the VFS routine to actually do the work.
2213
 
                 */
2214
 
                if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
2215
 
                        talloc_destroy(shadow_data->mem_ctx);
2216
 
                        if (errno == ENOSYS) {
2217
 
                                DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", 
2218
 
                                        conn->connectpath));
2219
 
                                return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
2220
 
                        } else {
2221
 
                                DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n", 
2222
 
                                        conn->connectpath));
2223
 
                                return ERROR_NT(NT_STATUS_UNSUCCESSFUL);                        
2224
 
                        }
2225
 
                }
2226
 
 
2227
 
                labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2;
2228
 
 
2229
 
                if (!labels) {
2230
 
                        data_count = 16;
2231
 
                } else {
2232
 
                        data_count = 12+labels_data_count+4;
2233
 
                }
2234
 
 
2235
 
                if (max_data_count<data_count) {
2236
 
                        DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
2237
 
                                max_data_count,data_count));
2238
 
                        talloc_destroy(shadow_data->mem_ctx);
2239
 
                        return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
2240
 
                }
2241
 
 
2242
 
                pdata = nttrans_realloc(ppdata, data_count);
2243
 
                if (pdata == NULL) {
2244
 
                        talloc_destroy(shadow_data->mem_ctx);
2245
 
                        return ERROR_NT(NT_STATUS_NO_MEMORY);
2246
 
                }               
2247
 
 
2248
 
                cur_pdata = pdata;
2249
 
 
2250
 
                /* num_volumes 4 bytes */
2251
 
                SIVAL(pdata,0,shadow_data->num_volumes);
2252
 
 
2253
 
                if (labels) {
2254
 
                        /* num_labels 4 bytes */
2255
 
                        SIVAL(pdata,4,shadow_data->num_volumes);
2256
 
                }
2257
 
 
2258
 
                /* needed_data_count 4 bytes */
2259
 
                SIVAL(pdata,8,labels_data_count);
2260
 
 
2261
 
                cur_pdata+=12;
2262
 
 
2263
 
                DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
2264
 
                        shadow_data->num_volumes,fsp->fsp_name));
2265
 
                if (labels && shadow_data->labels) {
2266
 
                        for (i=0;i<shadow_data->num_volumes;i++) {
2267
 
                                srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE);
2268
 
                                cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
2269
 
                                DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
2270
 
                        }
2271
 
                }
2272
 
 
2273
 
                talloc_destroy(shadow_data->mem_ctx);
2274
 
 
2275
 
                send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, pdata, data_count);
2276
 
 
2277
 
                return -1;
2278
 
        }
2279
 
        
2280
 
        case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
2281
 
        {
2282
 
                /* pretend this succeeded - 
2283
 
                 * 
2284
 
                 * we have to send back a list with all files owned by this SID
2285
 
                 *
2286
 
                 * but I have to check that --metze
2287
 
                 */
2288
 
                DOM_SID sid;
2289
 
                uid_t uid;
2290
 
                size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
2291
 
                
2292
 
                DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
2293
 
 
2294
 
                FSP_BELONGS_CONN(fsp,conn);
2295
 
 
2296
 
                /* unknown 4 bytes: this is not the length of the sid :-(  */
2297
 
                /*unknown = IVAL(pdata,0);*/
2298
 
                
2299
 
                sid_parse(pdata+4,sid_len,&sid);
2300
 
                DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
2301
 
 
2302
 
                if (!sid_to_uid(&sid, &uid)) {
2303
 
                        DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
2304
 
                                sid_string_static(&sid),(unsigned long)sid_len));
2305
 
                        uid = (-1);
2306
 
                }
2307
 
                
2308
 
                /* we can take a look at the find source :-)
2309
 
                 *
2310
 
                 * find ./ -uid $uid  -name '*'   is what we need here
2311
 
                 *
2312
 
                 *
2313
 
                 * and send 4bytes len and then NULL terminated unicode strings
2314
 
                 * for each file
2315
 
                 *
2316
 
                 * but I don't know how to deal with the paged results
2317
 
                 * (maybe we can hang the result anywhere in the fsp struct)
2318
 
                 *
2319
 
                 * we don't send all files at once
2320
 
                 * and at the next we should *not* start from the beginning, 
2321
 
                 * so we have to cache the result 
2322
 
                 *
2323
 
                 * --metze
2324
 
                 */
2325
 
                
2326
 
                /* this works for now... */
2327
 
                send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
2328
 
                return -1;      
2329
 
        }       
2330
 
        default:
2331
 
                if (!logged_message) {
2332
 
                        logged_message = True; /* Only print this once... */
2333
 
                        DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
2334
 
                                 function));
2335
 
                }
2336
 
        }
2337
 
 
2338
 
        return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
2339
 
}
2340
 
 
2341
 
 
2342
 
#ifdef HAVE_SYS_QUOTAS
2343
 
/****************************************************************************
2344
 
 Reply to get user quota 
2345
 
****************************************************************************/
2346
 
 
2347
 
static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
2348
 
                                  uint16 **ppsetup, uint32 setup_count,
2349
 
                                  char **ppparams, uint32 parameter_count,
2350
 
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
2351
 
{
2352
 
        NTSTATUS nt_status = NT_STATUS_OK;
2353
 
        char *params = *ppparams;
2354
 
        char *pdata = *ppdata;
2355
 
        char *entry;
2356
 
        int data_len=0,param_len=0;
2357
 
        int qt_len=0;
2358
 
        int entry_len = 0;
2359
 
        files_struct *fsp = NULL;
2360
 
        uint16 level = 0;
2361
 
        size_t sid_len;
2362
 
        DOM_SID sid;
2363
 
        BOOL start_enum = True;
2364
 
        SMB_NTQUOTA_STRUCT qt;
2365
 
        SMB_NTQUOTA_LIST *tmp_list;
2366
 
        SMB_NTQUOTA_HANDLE *qt_handle = NULL;
2367
 
        extern struct current_user current_user;
2368
 
 
2369
 
        ZERO_STRUCT(qt);
2370
 
 
2371
 
        /* access check */
2372
 
        if (current_user.ut.uid != 0) {
2373
 
                DEBUG(1,("get_user_quota: access_denied service [%s] user [%s]\n",
2374
 
                        lp_servicename(SNUM(conn)),conn->user));
2375
 
                return ERROR_DOS(ERRDOS,ERRnoaccess);
2376
 
        }
2377
 
 
2378
 
        /*
2379
 
         * Ensure minimum number of parameters sent.
2380
 
         */
2381
 
 
2382
 
        if (parameter_count < 4) {
2383
 
                DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
2384
 
                return ERROR_DOS(ERRDOS,ERRinvalidparam);
2385
 
        }
2386
 
        
2387
 
        /* maybe we can check the quota_fnum */
2388
 
        fsp = file_fsp(params,0);
2389
 
        if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2390
 
                DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2391
 
                return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2392
 
        }
2393
 
 
2394
 
        /* the NULL pointer checking for fsp->fake_file_handle->pd
2395
 
         * is done by CHECK_NTQUOTA_HANDLE_OK()
2396
 
         */
2397
 
        qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd;
2398
 
 
2399
 
        level = SVAL(params,2);
2400
 
        
2401
 
        /* unknown 12 bytes leading in params */ 
2402
 
        
2403
 
        switch (level) {
2404
 
                case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
2405
 
                        /* seems that we should continue with the enum here --metze */
2406
 
 
2407
 
                        if (qt_handle->quota_list!=NULL && 
2408
 
                            qt_handle->tmp_list==NULL) {
2409
 
                
2410
 
                                /* free the list */
2411
 
                                free_ntquota_list(&(qt_handle->quota_list));
2412
 
 
2413
 
                                /* Realloc the size of parameters and data we will return */
2414
 
                                param_len = 4;
2415
 
                                params = nttrans_realloc(ppparams, param_len);
2416
 
                                if(params == NULL) {
2417
 
                                        return ERROR_DOS(ERRDOS,ERRnomem);
2418
 
                                }
2419
 
 
2420
 
                                data_len = 0;
2421
 
                                SIVAL(params,0,data_len);
2422
 
 
2423
 
                                break;
2424
 
                        }
2425
 
 
2426
 
                        start_enum = False;
2427
 
 
2428
 
                case TRANSACT_GET_USER_QUOTA_LIST_START:
2429
 
 
2430
 
                        if (qt_handle->quota_list==NULL &&
2431
 
                                qt_handle->tmp_list==NULL) {
2432
 
                                start_enum = True;
2433
 
                        }
2434
 
 
2435
 
                        if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0)
2436
 
                                return ERROR_DOS(ERRSRV,ERRerror);
2437
 
 
2438
 
                        /* Realloc the size of parameters and data we will return */
2439
 
                        param_len = 4;
2440
 
                        params = nttrans_realloc(ppparams, param_len);
2441
 
                        if(params == NULL) {
2442
 
                                return ERROR_DOS(ERRDOS,ERRnomem);
2443
 
                        }
2444
 
 
2445
 
                        /* we should not trust the value in max_data_count*/
2446
 
                        max_data_count = MIN(max_data_count,2048);
2447
 
                        
2448
 
                        pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/
2449
 
                        if(pdata == NULL) {
2450
 
                                return ERROR_DOS(ERRDOS,ERRnomem);
2451
 
                        }
2452
 
 
2453
 
                        entry = pdata;
2454
 
 
2455
 
                        /* set params Size of returned Quota Data 4 bytes*/
2456
 
                        /* but set it later when we know it */
2457
 
                
2458
 
                        /* for each entry push the data */
2459
 
 
2460
 
                        if (start_enum) {
2461
 
                                qt_handle->tmp_list = qt_handle->quota_list;
2462
 
                        }
2463
 
 
2464
 
                        tmp_list = qt_handle->tmp_list;
2465
 
 
2466
 
                        for (;((tmp_list!=NULL)&&((qt_len +40+SID_MAX_SIZE)<max_data_count));
2467
 
                                tmp_list=tmp_list->next,entry+=entry_len,qt_len+=entry_len) {
2468
 
 
2469
 
                                sid_len = sid_size(&tmp_list->quotas->sid);
2470
 
                                entry_len = 40 + sid_len;
2471
 
 
2472
 
                                /* nextoffset entry 4 bytes */
2473
 
                                SIVAL(entry,0,entry_len);
2474
 
                
2475
 
                                /* then the len of the SID 4 bytes */
2476
 
                                SIVAL(entry,4,sid_len);
2477
 
                                
2478
 
                                /* unknown data 8 bytes SMB_BIG_UINT */
2479
 
                                SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/
2480
 
                                
2481
 
                                /* the used disk space 8 bytes SMB_BIG_UINT */
2482
 
                                SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
2483
 
                                
2484
 
                                /* the soft quotas 8 bytes SMB_BIG_UINT */
2485
 
                                SBIG_UINT(entry,24,tmp_list->quotas->softlim);
2486
 
                                
2487
 
                                /* the hard quotas 8 bytes SMB_BIG_UINT */
2488
 
                                SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
2489
 
                                
2490
 
                                /* and now the SID */
2491
 
                                sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
2492
 
                        }
2493
 
                        
2494
 
                        qt_handle->tmp_list = tmp_list;
2495
 
                        
2496
 
                        /* overwrite the offset of the last entry */
2497
 
                        SIVAL(entry-entry_len,0,0);
2498
 
 
2499
 
                        data_len = 4+qt_len;
2500
 
                        /* overwrite the params quota_data_len */
2501
 
                        SIVAL(params,0,data_len);
2502
 
 
2503
 
                        break;
2504
 
 
2505
 
                case TRANSACT_GET_USER_QUOTA_FOR_SID:
2506
 
                        
2507
 
                        /* unknown 4 bytes IVAL(pdata,0) */     
2508
 
                        
2509
 
                        if (data_count < 8) {
2510
 
                                DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
2511
 
                                return ERROR_DOS(ERRDOS,ERRunknownlevel);                               
2512
 
                        }
2513
 
 
2514
 
                        sid_len = IVAL(pdata,4);
2515
 
                        /* Ensure this is less than 1mb. */
2516
 
                        if (sid_len > (1024*1024)) {
2517
 
                                return ERROR_DOS(ERRDOS,ERRnomem);
2518
 
                        }
2519
 
 
2520
 
                        if (data_count < 8+sid_len) {
2521
 
                                DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len)));
2522
 
                                return ERROR_DOS(ERRDOS,ERRunknownlevel);                               
2523
 
                        }
2524
 
 
2525
 
                        data_len = 4+40+sid_len;
2526
 
 
2527
 
                        if (max_data_count < data_len) {
2528
 
                                DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: max_data_count(%d) < data_len(%d)\n",
2529
 
                                        max_data_count, data_len));
2530
 
                                param_len = 4;
2531
 
                                SIVAL(params,0,data_len);
2532
 
                                data_len = 0;
2533
 
                                nt_status = NT_STATUS_BUFFER_TOO_SMALL;
2534
 
                                break;
2535
 
                        }
2536
 
 
2537
 
                        sid_parse(pdata+8,sid_len,&sid);
2538
 
                
2539
 
                        if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2540
 
                                ZERO_STRUCT(qt);
2541
 
                                /* 
2542
 
                                 * we have to return zero's in all fields 
2543
 
                                 * instead of returning an error here
2544
 
                                 * --metze
2545
 
                                 */
2546
 
                        }
2547
 
 
2548
 
                        /* Realloc the size of parameters and data we will return */
2549
 
                        param_len = 4;
2550
 
                        params = nttrans_realloc(ppparams, param_len);
2551
 
                        if(params == NULL) {
2552
 
                                return ERROR_DOS(ERRDOS,ERRnomem);
2553
 
                        }
2554
 
 
2555
 
                        pdata = nttrans_realloc(ppdata, data_len);
2556
 
                        if(pdata == NULL) {
2557
 
                                return ERROR_DOS(ERRDOS,ERRnomem);
2558
 
                        }
2559
 
 
2560
 
                        entry = pdata;
2561
 
 
2562
 
                        /* set params Size of returned Quota Data 4 bytes*/
2563
 
                        SIVAL(params,0,data_len);
2564
 
        
2565
 
                        /* nextoffset entry 4 bytes */
2566
 
                        SIVAL(entry,0,0);
2567
 
        
2568
 
                        /* then the len of the SID 4 bytes */
2569
 
                        SIVAL(entry,4,sid_len);
2570
 
                        
2571
 
                        /* unknown data 8 bytes SMB_BIG_UINT */
2572
 
                        SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/
2573
 
                        
2574
 
                        /* the used disk space 8 bytes SMB_BIG_UINT */
2575
 
                        SBIG_UINT(entry,16,qt.usedspace);
2576
 
                        
2577
 
                        /* the soft quotas 8 bytes SMB_BIG_UINT */
2578
 
                        SBIG_UINT(entry,24,qt.softlim);
2579
 
                        
2580
 
                        /* the hard quotas 8 bytes SMB_BIG_UINT */
2581
 
                        SBIG_UINT(entry,32,qt.hardlim);
2582
 
                        
2583
 
                        /* and now the SID */
2584
 
                        sid_linearize(entry+40, sid_len, &sid);
2585
 
 
2586
 
                        break;
2587
 
 
2588
 
                default:
2589
 
                        DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level));
2590
 
                        return ERROR_DOS(ERRSRV,ERRerror);
2591
 
                        break;
2592
 
        }
2593
 
 
2594
 
        send_nt_replies(inbuf, outbuf, bufsize, nt_status, params, param_len, pdata, data_len);
2595
 
 
2596
 
        return -1;
2597
 
}
2598
 
 
2599
 
/****************************************************************************
2600
 
 Reply to set user quota
2601
 
****************************************************************************/
2602
 
 
2603
 
static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
2604
 
                                  uint16 **ppsetup, uint32 setup_count,
2605
 
                                  char **ppparams, uint32 parameter_count,
2606
 
                                  char **ppdata, uint32 data_count, uint32 max_data_count)
2607
 
{
2608
 
        char *params = *ppparams;
2609
 
        char *pdata = *ppdata;
2610
 
        int data_len=0,param_len=0;
2611
 
        SMB_NTQUOTA_STRUCT qt;
2612
 
        size_t sid_len;
2613
 
        DOM_SID sid;
2614
 
        files_struct *fsp = NULL;
2615
 
 
2616
 
        ZERO_STRUCT(qt);
2617
 
 
2618
 
        /* access check */
2619
 
        if (current_user.ut.uid != 0) {
2620
 
                DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
2621
 
                        lp_servicename(SNUM(conn)),conn->user));
2622
 
                return ERROR_DOS(ERRDOS,ERRnoaccess);
2623
 
        }
2624
 
 
2625
 
        /*
2626
 
         * Ensure minimum number of parameters sent.
2627
 
         */
2628
 
 
2629
 
        if (parameter_count < 2) {
2630
 
                DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
2631
 
                return ERROR_DOS(ERRDOS,ERRinvalidparam);
2632
 
        }
2633
 
        
2634
 
        /* maybe we can check the quota_fnum */
2635
 
        fsp = file_fsp(params,0);
2636
 
        if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2637
 
                DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2638
 
                return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2639
 
        }
2640
 
 
2641
 
        if (data_count < 40) {
2642
 
                DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40));
2643
 
                return ERROR_DOS(ERRDOS,ERRunknownlevel);               
2644
 
        }
2645
 
 
2646
 
        /* offset to next quota record.
2647
 
         * 4 bytes IVAL(pdata,0)
2648
 
         * unused here...
2649
 
         */
2650
 
 
2651
 
        /* sid len */
2652
 
        sid_len = IVAL(pdata,4);
2653
 
 
2654
 
        if (data_count < 40+sid_len) {
2655
 
                DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len));
2656
 
                return ERROR_DOS(ERRDOS,ERRunknownlevel);               
2657
 
        }
2658
 
 
2659
 
        /* unknown 8 bytes in pdata 
2660
 
         * maybe its the change time in NTTIME
2661
 
         */
2662
 
 
2663
 
        /* the used space 8 bytes (SMB_BIG_UINT)*/
2664
 
        qt.usedspace = (SMB_BIG_UINT)IVAL(pdata,16);
2665
 
#ifdef LARGE_SMB_OFF_T
2666
 
        qt.usedspace |= (((SMB_BIG_UINT)IVAL(pdata,20)) << 32);
2667
 
#else /* LARGE_SMB_OFF_T */
2668
 
        if ((IVAL(pdata,20) != 0)&&
2669
 
                ((qt.usedspace != 0xFFFFFFFF)||
2670
 
                (IVAL(pdata,20)!=0xFFFFFFFF))) {
2671
 
                /* more than 32 bits? */
2672
 
                return ERROR_DOS(ERRDOS,ERRunknownlevel);
2673
 
        }
2674
 
#endif /* LARGE_SMB_OFF_T */
2675
 
 
2676
 
        /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2677
 
        qt.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2678
 
#ifdef LARGE_SMB_OFF_T
2679
 
        qt.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2680
 
#else /* LARGE_SMB_OFF_T */
2681
 
        if ((IVAL(pdata,28) != 0)&&
2682
 
                ((qt.softlim != 0xFFFFFFFF)||
2683
 
                (IVAL(pdata,28)!=0xFFFFFFFF))) {
2684
 
                /* more than 32 bits? */
2685
 
                return ERROR_DOS(ERRDOS,ERRunknownlevel);
2686
 
        }
2687
 
#endif /* LARGE_SMB_OFF_T */
2688
 
 
2689
 
        /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2690
 
        qt.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2691
 
#ifdef LARGE_SMB_OFF_T
2692
 
        qt.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2693
 
#else /* LARGE_SMB_OFF_T */
2694
 
        if ((IVAL(pdata,36) != 0)&&
2695
 
                ((qt.hardlim != 0xFFFFFFFF)||
2696
 
                (IVAL(pdata,36)!=0xFFFFFFFF))) {
2697
 
                /* more than 32 bits? */
2698
 
                return ERROR_DOS(ERRDOS,ERRunknownlevel);
2699
 
        }
2700
 
#endif /* LARGE_SMB_OFF_T */
2701
 
        
2702
 
        sid_parse(pdata+40,sid_len,&sid);
2703
 
        DEBUGADD(8,("SID: %s\n",sid_string_static(&sid)));
2704
 
 
2705
 
        /* 44 unknown bytes left... */
2706
 
 
2707
 
        if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2708
 
                return ERROR_DOS(ERRSRV,ERRerror);      
2709
 
        }
2710
 
 
2711
 
        send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, param_len, pdata, data_len);
2712
 
 
2713
 
        return -1;
2714
 
}
2715
 
#endif /* HAVE_SYS_QUOTAS */
2716
 
 
2717
 
static int handle_nttrans(connection_struct *conn,
2718
 
                          struct trans_state *state,
2719
 
                          char *inbuf, char *outbuf, int size, int bufsize)
2720
 
{
2721
 
        int outsize;
2722
 
 
2723
 
        if (Protocol >= PROTOCOL_NT1) {
2724
 
                SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2725
 
        }
2726
 
 
2727
 
        /* Now we must call the relevant NT_TRANS function */
2728
 
        switch(state->call) {
2729
 
                case NT_TRANSACT_CREATE:
2730
 
                {
2731
 
                        START_PROFILE_NESTED(NT_transact_create);
2732
 
                        outsize = call_nt_transact_create(conn, inbuf, outbuf,
2733
 
                                                          size, bufsize, 
2734
 
                                                        &state->setup, state->setup_count,
2735
 
                                                        &state->param, state->total_param, 
2736
 
                                                        &state->data, state->total_data,
2737
 
                                                          state->max_data_return);
2738
 
                        END_PROFILE_NESTED(NT_transact_create);
2739
 
                        break;
2740
 
                }
2741
 
 
2742
 
                case NT_TRANSACT_IOCTL:
2743
 
                {
2744
 
                        START_PROFILE_NESTED(NT_transact_ioctl);
2745
 
                        outsize = call_nt_transact_ioctl(conn, inbuf, outbuf,
2746
 
                                                         size, bufsize, 
2747
 
                                                         &state->setup, state->setup_count,
2748
 
                                                         &state->param, state->total_param, 
2749
 
                                                         &state->data, state->total_data, state->max_data_return);
2750
 
                        END_PROFILE_NESTED(NT_transact_ioctl);
2751
 
                        break;
2752
 
                }
2753
 
 
2754
 
                case NT_TRANSACT_SET_SECURITY_DESC:
2755
 
                {
2756
 
                        START_PROFILE_NESTED(NT_transact_set_security_desc);
2757
 
                        outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, 
2758
 
                                                         size, bufsize, 
2759
 
                                                         &state->setup, state->setup_count,
2760
 
                                                         &state->param, state->total_param, 
2761
 
                                                         &state->data, state->total_data, state->max_data_return);
2762
 
                        END_PROFILE_NESTED(NT_transact_set_security_desc);
2763
 
                        break;
2764
 
                }
2765
 
 
2766
 
                case NT_TRANSACT_NOTIFY_CHANGE:
2767
 
                {
2768
 
                        START_PROFILE_NESTED(NT_transact_notify_change);
2769
 
                        outsize = call_nt_transact_notify_change(conn, inbuf, outbuf, 
2770
 
                                                         size, bufsize, 
2771
 
                                                         &state->setup, state->setup_count,
2772
 
                                                         &state->param, state->total_param, 
2773
 
                                                         &state->data, state->total_data, state->max_data_return);
2774
 
                        END_PROFILE_NESTED(NT_transact_notify_change);
2775
 
                        break;
2776
 
                }
2777
 
 
2778
 
                case NT_TRANSACT_RENAME:
2779
 
                {
2780
 
                        START_PROFILE_NESTED(NT_transact_rename);
2781
 
                        outsize = call_nt_transact_rename(conn, inbuf, outbuf,
2782
 
                                                         size, bufsize, 
2783
 
                                                         &state->setup, state->setup_count,
2784
 
                                                         &state->param, state->total_param, 
2785
 
                                                         &state->data, state->total_data, state->max_data_return);
2786
 
                        END_PROFILE_NESTED(NT_transact_rename);
2787
 
                        break;
2788
 
                }
2789
 
 
2790
 
                case NT_TRANSACT_QUERY_SECURITY_DESC:
2791
 
                {
2792
 
                        START_PROFILE_NESTED(NT_transact_query_security_desc);
2793
 
                        outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, 
2794
 
                                                         size, bufsize, 
2795
 
                                                         &state->setup, state->setup_count,
2796
 
                                                         &state->param, state->total_param, 
2797
 
                                                         &state->data, state->total_data, state->max_data_return);
2798
 
                        END_PROFILE_NESTED(NT_transact_query_security_desc);
2799
 
                        break;
2800
 
                }
2801
 
 
2802
 
#ifdef HAVE_SYS_QUOTAS
2803
 
                case NT_TRANSACT_GET_USER_QUOTA:
2804
 
                {
2805
 
                        START_PROFILE_NESTED(NT_transact_get_user_quota);
2806
 
                        outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf, 
2807
 
                                                         size, bufsize, 
2808
 
                                                         &state->setup, state->setup_count,
2809
 
                                                         &state->param, state->total_param, 
2810
 
                                                         &state->data, state->total_data, state->max_data_return);
2811
 
                        END_PROFILE_NESTED(NT_transact_get_user_quota);
2812
 
                        break;
2813
 
                }
2814
 
 
2815
 
                case NT_TRANSACT_SET_USER_QUOTA:
2816
 
                {
2817
 
                        START_PROFILE_NESTED(NT_transact_set_user_quota);
2818
 
                        outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf, 
2819
 
                                                         size, bufsize, 
2820
 
                                                         &state->setup, state->setup_count,
2821
 
                                                         &state->param, state->total_param, 
2822
 
                                                         &state->data, state->total_data, state->max_data_return);
2823
 
                        END_PROFILE_NESTED(NT_transact_set_user_quota);
2824
 
                        break;                                  
2825
 
                }
2826
 
#endif /* HAVE_SYS_QUOTAS */
2827
 
 
2828
 
                default:
2829
 
                        /* Error in request */
2830
 
                        DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n",
2831
 
                                 state->call));
2832
 
                        return ERROR_DOS(ERRSRV,ERRerror);
2833
 
        }
2834
 
        return outsize;
2835
 
}
2836
 
 
2837
 
/****************************************************************************
2838
 
 Reply to a SMBNTtrans.
2839
 
****************************************************************************/
2840
 
 
2841
 
int reply_nttrans(connection_struct *conn,
2842
 
                        char *inbuf,char *outbuf,int size,int bufsize)
2843
 
{
2844
 
        int  outsize = 0;
2845
 
        uint32 pscnt = IVAL(inbuf,smb_nt_ParameterCount);
2846
 
        uint32 psoff = IVAL(inbuf,smb_nt_ParameterOffset);
2847
 
        uint32 dscnt = IVAL(inbuf,smb_nt_DataCount);
2848
 
        uint32 dsoff = IVAL(inbuf,smb_nt_DataOffset);
2849
 
        
2850
 
        uint16 function_code = SVAL( inbuf, smb_nt_Function);
2851
 
        NTSTATUS result;
2852
 
        struct trans_state *state;
2853
 
 
2854
 
        START_PROFILE(SMBnttrans);
2855
 
 
2856
 
        if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
2857
 
                END_PROFILE(SMBnttrans);
2858
 
                return ERROR_DOS(ERRSRV,ERRaccess);
2859
 
        }
2860
 
 
2861
 
        result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid));
2862
 
        if (!NT_STATUS_IS_OK(result)) {
2863
 
                DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result)));
2864
 
                END_PROFILE(SMBnttrans);
2865
 
                return ERROR_NT(result);
2866
 
        }
2867
 
 
2868
 
        if ((state = TALLOC_P(NULL, struct trans_state)) == NULL) {
2869
 
                END_PROFILE(SMBnttrans);
2870
 
                return ERROR_DOS(ERRSRV,ERRaccess);
2871
 
        }
2872
 
 
2873
 
        state->cmd = SMBnttrans;
2874
 
 
2875
 
        state->mid = SVAL(inbuf,smb_mid);
2876
 
        state->vuid = SVAL(inbuf,smb_uid);
2877
 
        state->total_data = IVAL(inbuf, smb_nt_TotalDataCount);
2878
 
        state->data = NULL;
2879
 
        state->total_param = IVAL(inbuf, smb_nt_TotalParameterCount);
2880
 
        state->param = NULL;
2881
 
        state->max_data_return = IVAL(inbuf,smb_nt_MaxDataCount);       
2882
 
 
2883
 
        /* setup count is in *words* */
2884
 
        state->setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); 
2885
 
        state->call = function_code;
2886
 
 
2887
 
        /* 
2888
 
         * All nttrans messages we handle have smb_wct == 19 +
2889
 
         * state->setup_count.  Ensure this is so as a sanity check.
2890
 
         */
2891
 
 
2892
 
        if(CVAL(inbuf, smb_wct) != 19 + (state->setup_count/2)) {
2893
 
                DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
2894
 
                        CVAL(inbuf, smb_wct), 19 + (state->setup_count/2)));
2895
 
                goto bad_param;
2896
 
        }
2897
 
 
2898
 
        /* Don't allow more than 128mb for each value. */
2899
 
        if ((state->total_data > (1024*1024*128)) ||
2900
 
            (state->total_param > (1024*1024*128))) {
2901
 
                END_PROFILE(SMBnttrans);
2902
 
                return ERROR_DOS(ERRDOS,ERRnomem);
2903
 
        }
2904
 
 
2905
 
        if ((dscnt > state->total_data) || (pscnt > state->total_param))
2906
 
                goto bad_param;
2907
 
 
2908
 
        if (state->total_data)  {
2909
 
                /* Can't use talloc here, the core routines do realloc on the
2910
 
                 * params and data. */
2911
 
                if ((state->data = SMB_MALLOC(state->total_data)) == NULL) {
2912
 
                        DEBUG(0,("reply_nttrans: data malloc fail for %u "
2913
 
                                 "bytes !\n", (unsigned int)state->total_data));
2914
 
                        TALLOC_FREE(state);
2915
 
                        END_PROFILE(SMBnttrans);
2916
 
                        return(ERROR_DOS(ERRDOS,ERRnomem));
2917
 
                } 
2918
 
                if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
2919
 
                        goto bad_param;
2920
 
                if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) ||
2921
 
                    (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf)))
2922
 
                        goto bad_param;
2923
 
 
2924
 
                memcpy(state->data,smb_base(inbuf)+dsoff,dscnt);
2925
 
        }
2926
 
 
2927
 
        if (state->total_param) {
2928
 
                /* Can't use talloc here, the core routines do realloc on the
2929
 
                 * params and data. */
2930
 
                if ((state->param = SMB_MALLOC(state->total_param)) == NULL) {
2931
 
                        DEBUG(0,("reply_nttrans: param malloc fail for %u "
2932
 
                                 "bytes !\n", (unsigned int)state->total_param));
2933
 
                        SAFE_FREE(state->data);
2934
 
                        TALLOC_FREE(state);
2935
 
                        END_PROFILE(SMBnttrans);
2936
 
                        return(ERROR_DOS(ERRDOS,ERRnomem));
2937
 
                } 
2938
 
                if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
2939
 
                        goto bad_param;
2940
 
                if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) ||
2941
 
                    (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf)))
2942
 
                        goto bad_param;
2943
 
 
2944
 
                memcpy(state->param,smb_base(inbuf)+psoff,pscnt);
2945
 
        }
2946
 
 
2947
 
        state->received_data  = dscnt;
2948
 
        state->received_param = pscnt;
2949
 
 
2950
 
        if(state->setup_count > 0) {
2951
 
                DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
2952
 
                          state->setup_count));
2953
 
                state->setup = TALLOC(state, state->setup_count);
2954
 
                if (state->setup == NULL) {
2955
 
                        DEBUG(0,("reply_nttrans : Out of memory\n"));
2956
 
                        SAFE_FREE(state->data);
2957
 
                        SAFE_FREE(state->param);
2958
 
                        TALLOC_FREE(state);
2959
 
                        END_PROFILE(SMBnttrans);
2960
 
                        return ERROR_DOS(ERRDOS,ERRnomem);
2961
 
                }
2962
 
 
2963
 
                if ((smb_nt_SetupStart + state->setup_count < smb_nt_SetupStart) ||
2964
 
                    (smb_nt_SetupStart + state->setup_count < state->setup_count)) {
2965
 
                        goto bad_param;
2966
 
                }
2967
 
                if (smb_nt_SetupStart + state->setup_count > size) {
2968
 
                        goto bad_param;
2969
 
                }
2970
 
 
2971
 
                memcpy( state->setup, &inbuf[smb_nt_SetupStart], state->setup_count);
2972
 
                dump_data(10, (char *)state->setup, state->setup_count);
2973
 
        }
2974
 
 
2975
 
        if ((state->received_data == state->total_data) &&
2976
 
            (state->received_param == state->total_param)) {
2977
 
                outsize = handle_nttrans(conn, state, inbuf, outbuf,
2978
 
                                         size, bufsize);
2979
 
                SAFE_FREE(state->param);
2980
 
                SAFE_FREE(state->data);
2981
 
                TALLOC_FREE(state);
2982
 
                END_PROFILE(SMBnttrans);
2983
 
                return outsize;
2984
 
        }
2985
 
 
2986
 
        DLIST_ADD(conn->pending_trans, state);
2987
 
 
2988
 
        /* We need to send an interim response then receive the rest
2989
 
           of the parameter/data bytes */
2990
 
        outsize = set_message(outbuf,0,0,False);
2991
 
        show_msg(outbuf);
2992
 
        END_PROFILE(SMBnttrans);
2993
 
        return outsize;
2994
 
 
2995
 
  bad_param:
2996
 
 
2997
 
        DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
2998
 
        SAFE_FREE(state->data);
2999
 
        SAFE_FREE(state->param);
3000
 
        TALLOC_FREE(state);
3001
 
        END_PROFILE(SMBnttrans);
3002
 
        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3003
 
}
3004
 
        
3005
 
/****************************************************************************
3006
 
 Reply to a SMBnttranss
3007
 
 ****************************************************************************/
3008
 
 
3009
 
int reply_nttranss(connection_struct *conn,  char *inbuf,char *outbuf,
3010
 
                   int size,int bufsize)
3011
 
{
3012
 
        int outsize = 0;
3013
 
        unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
3014
 
        struct trans_state *state;
3015
 
 
3016
 
        START_PROFILE(SMBnttranss);
3017
 
 
3018
 
        show_msg(inbuf);
3019
 
 
3020
 
        for (state = conn->pending_trans; state != NULL;
3021
 
             state = state->next) {
3022
 
                if (state->mid == SVAL(inbuf,smb_mid)) {
3023
 
                        break;
3024
 
                }
3025
 
        }
3026
 
 
3027
 
        if ((state == NULL) || (state->cmd != SMBnttrans)) {
3028
 
                END_PROFILE(SMBnttranss);
3029
 
                return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3030
 
        }
3031
 
 
3032
 
        /* Revise state->total_param and state->total_data in case they have
3033
 
           changed downwards */
3034
 
        if (IVAL(inbuf, smb_nts_TotalParameterCount) < state->total_param) {
3035
 
                state->total_param = IVAL(inbuf, smb_nts_TotalParameterCount);
3036
 
        }
3037
 
        if (IVAL(inbuf, smb_nts_TotalDataCount) < state->total_data) {
3038
 
                state->total_data = IVAL(inbuf, smb_nts_TotalDataCount);
3039
 
        }
3040
 
 
3041
 
        pcnt = IVAL(inbuf,smb_nts_ParameterCount);
3042
 
        poff = IVAL(inbuf, smb_nts_ParameterOffset);
3043
 
        pdisp = IVAL(inbuf, smb_nts_ParameterDisplacement);
3044
 
 
3045
 
        dcnt = IVAL(inbuf, smb_nts_DataCount);
3046
 
        ddisp = IVAL(inbuf, smb_nts_DataDisplacement);
3047
 
        doff = IVAL(inbuf, smb_nts_DataOffset);
3048
 
 
3049
 
        state->received_param += pcnt;
3050
 
        state->received_data += dcnt;
3051
 
                
3052
 
        if ((state->received_data > state->total_data) ||
3053
 
            (state->received_param > state->total_param))
3054
 
                goto bad_param;
3055
 
 
3056
 
        if (pcnt) {
3057
 
                if (pdisp+pcnt > state->total_param)
3058
 
                        goto bad_param;
3059
 
                if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
3060
 
                        goto bad_param;
3061
 
                if (pdisp > state->total_param)
3062
 
                        goto bad_param;
3063
 
                if ((smb_base(inbuf) + poff + pcnt > inbuf + size) ||
3064
 
                    (smb_base(inbuf) + poff + pcnt < smb_base(inbuf)))
3065
 
                        goto bad_param;
3066
 
                if (state->param + pdisp < state->param)
3067
 
                        goto bad_param;
3068
 
 
3069
 
                memcpy(state->param+pdisp,smb_base(inbuf)+poff,
3070
 
                       pcnt);
3071
 
        }
3072
 
 
3073
 
        if (dcnt) {
3074
 
                if (ddisp+dcnt > state->total_data)
3075
 
                        goto bad_param;
3076
 
                if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
3077
 
                        goto bad_param;
3078
 
                if (ddisp > state->total_data)
3079
 
                        goto bad_param;
3080
 
                if ((smb_base(inbuf) + doff + dcnt > inbuf + size) ||
3081
 
                    (smb_base(inbuf) + doff + dcnt < smb_base(inbuf)))
3082
 
                        goto bad_param;
3083
 
                if (state->data + ddisp < state->data)
3084
 
                        goto bad_param;
3085
 
 
3086
 
                memcpy(state->data+ddisp, smb_base(inbuf)+doff,
3087
 
                       dcnt);      
3088
 
        }
3089
 
 
3090
 
        if ((state->received_param < state->total_param) ||
3091
 
            (state->received_data < state->total_data)) {
3092
 
                END_PROFILE(SMBnttranss);
3093
 
                return -1;
3094
 
        }
3095
 
 
3096
 
        /* construct_reply_common has done us the favor to pre-fill the
3097
 
         * command field with SMBnttranss which is wrong :-)
3098
 
         */
3099
 
        SCVAL(outbuf,smb_com,SMBnttrans);
3100
 
 
3101
 
        outsize = handle_nttrans(conn, state, inbuf, outbuf,
3102
 
                                 size, bufsize);
3103
 
 
3104
 
        DLIST_REMOVE(conn->pending_trans, state);
3105
 
        SAFE_FREE(state->data);
3106
 
        SAFE_FREE(state->param);
3107
 
        TALLOC_FREE(state);
3108
 
 
3109
 
        if (outsize == 0) {
3110
 
                END_PROFILE(SMBnttranss);
3111
 
                return(ERROR_DOS(ERRSRV,ERRnosupport));
3112
 
        }
3113
 
        
3114
 
        END_PROFILE(SMBnttranss);
3115
 
        return(outsize);
3116
 
 
3117
 
  bad_param:
3118
 
 
3119
 
        DEBUG(0,("reply_nttranss: invalid trans parameters\n"));
3120
 
        DLIST_REMOVE(conn->pending_trans, state);
3121
 
        SAFE_FREE(state->data);
3122
 
        SAFE_FREE(state->param);
3123
 
        TALLOC_FREE(state);
3124
 
        END_PROFILE(SMBnttranss);
3125
 
        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3126
 
}