Add header files for secace and secacl.
[amitay/samba.git] / source4 / libcli / clifile.c
1 /* 
2    Unix SMB/CIFS implementation.
3    client file operations
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Jeremy Allison 2001-2002
6    Copyright (C) James Myers 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "libcli/libcli.h"
26
27 /****************************************************************************
28  Hard/Symlink a file (UNIX extensions).
29 ****************************************************************************/
30
31 static NTSTATUS smbcli_link_internal(struct smbcli_tree *tree, 
32                                   const char *fname_src, 
33                                   const char *fname_dst, bool hard_link)
34 {
35         union smb_setfileinfo parms;
36         NTSTATUS status;
37
38         if (hard_link) {
39                 parms.generic.level = RAW_SFILEINFO_UNIX_HLINK;
40                 parms.unix_hlink.in.file.path = fname_src;
41                 parms.unix_hlink.in.link_dest = fname_dst;
42         } else {
43                 parms.generic.level = RAW_SFILEINFO_UNIX_LINK;
44                 parms.unix_link.in.file.path = fname_src;
45                 parms.unix_link.in.link_dest = fname_dst;
46         }
47         
48         status = smb_raw_setpathinfo(tree, &parms);
49
50         return status;
51 }
52
53 /****************************************************************************
54  Map standard UNIX permissions onto wire representations.
55 ****************************************************************************/
56 uint32_t unix_perms_to_wire(mode_t perms)
57 {
58         uint_t ret = 0;
59
60         ret |= ((perms & S_IXOTH) ?  UNIX_X_OTH : 0);
61         ret |= ((perms & S_IWOTH) ?  UNIX_W_OTH : 0);
62         ret |= ((perms & S_IROTH) ?  UNIX_R_OTH : 0);
63         ret |= ((perms & S_IXGRP) ?  UNIX_X_GRP : 0);
64         ret |= ((perms & S_IWGRP) ?  UNIX_W_GRP : 0);
65         ret |= ((perms & S_IRGRP) ?  UNIX_R_GRP : 0);
66         ret |= ((perms & S_IXUSR) ?  UNIX_X_USR : 0);
67         ret |= ((perms & S_IWUSR) ?  UNIX_W_USR : 0);
68         ret |= ((perms & S_IRUSR) ?  UNIX_R_USR : 0);
69 #ifdef S_ISVTX
70         ret |= ((perms & S_ISVTX) ?  UNIX_STICKY : 0);
71 #endif
72 #ifdef S_ISGID
73         ret |= ((perms & S_ISGID) ?  UNIX_SET_GID : 0);
74 #endif
75 #ifdef S_ISUID
76         ret |= ((perms & S_ISUID) ?  UNIX_SET_UID : 0);
77 #endif
78         return ret;
79 }
80
81 /****************************************************************************
82  Symlink a file (UNIX extensions).
83 ****************************************************************************/
84 NTSTATUS smbcli_unix_symlink(struct smbcli_tree *tree, const char *fname_src, 
85                           const char *fname_dst)
86 {
87         return smbcli_link_internal(tree, fname_src, fname_dst, false);
88 }
89
90 /****************************************************************************
91  Hard a file (UNIX extensions).
92 ****************************************************************************/
93 NTSTATUS smbcli_unix_hardlink(struct smbcli_tree *tree, const char *fname_src, 
94                            const char *fname_dst)
95 {
96         return smbcli_link_internal(tree, fname_src, fname_dst, true);
97 }
98
99
100 /****************************************************************************
101  Chmod or chown a file internal (UNIX extensions).
102 ****************************************************************************/
103 static NTSTATUS smbcli_unix_chmod_chown_internal(struct smbcli_tree *tree, 
104                                               const char *fname, 
105                                               uint32_t mode, uint32_t uid, 
106                                               uint32_t gid)
107 {
108         union smb_setfileinfo parms;
109         NTSTATUS status;
110
111         parms.generic.level = SMB_SFILEINFO_UNIX_BASIC;
112         parms.unix_basic.in.file.path = fname;
113         parms.unix_basic.in.uid = uid;
114         parms.unix_basic.in.gid = gid;
115         parms.unix_basic.in.mode = mode;
116         
117         status = smb_raw_setpathinfo(tree, &parms);
118
119         return status;
120 }
121
122 /****************************************************************************
123  chmod a file (UNIX extensions).
124 ****************************************************************************/
125
126 NTSTATUS smbcli_unix_chmod(struct smbcli_tree *tree, const char *fname, mode_t mode)
127 {
128         return smbcli_unix_chmod_chown_internal(tree, fname, 
129                                              unix_perms_to_wire(mode), 
130                                              SMB_UID_NO_CHANGE, 
131                                              SMB_GID_NO_CHANGE);
132 }
133
134 /****************************************************************************
135  chown a file (UNIX extensions).
136 ****************************************************************************/
137 NTSTATUS smbcli_unix_chown(struct smbcli_tree *tree, const char *fname, uid_t uid, 
138                         gid_t gid)
139 {
140         return smbcli_unix_chmod_chown_internal(tree, fname, SMB_MODE_NO_CHANGE, 
141                                              (uint32_t)uid, (uint32_t)gid);
142 }
143
144
145 /****************************************************************************
146  Rename a file.
147 ****************************************************************************/
148 NTSTATUS smbcli_rename(struct smbcli_tree *tree, const char *fname_src, 
149                     const char *fname_dst)
150 {
151         union smb_rename parms;
152
153         parms.generic.level = RAW_RENAME_RENAME;
154         parms.rename.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY;
155         parms.rename.in.pattern1 = fname_src;
156         parms.rename.in.pattern2 = fname_dst;
157
158         return smb_raw_rename(tree, &parms);
159 }
160
161
162 /****************************************************************************
163  Delete a file.
164 ****************************************************************************/
165 NTSTATUS smbcli_unlink(struct smbcli_tree *tree, const char *fname)
166 {
167         union smb_unlink parms;
168
169         parms.unlink.in.pattern = fname;
170         if (strchr(fname, '*')) {
171                 parms.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
172         } else {
173                 parms.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY;
174         }
175
176         return smb_raw_unlink(tree, &parms);
177 }
178
179 /****************************************************************************
180  Create a directory.
181 ****************************************************************************/
182 NTSTATUS smbcli_mkdir(struct smbcli_tree *tree, const char *dname)
183 {
184         union smb_mkdir parms;
185
186         parms.mkdir.level = RAW_MKDIR_MKDIR;
187         parms.mkdir.in.path = dname;
188
189         return smb_raw_mkdir(tree, &parms);
190 }
191
192
193 /****************************************************************************
194  Remove a directory.
195 ****************************************************************************/
196 NTSTATUS smbcli_rmdir(struct smbcli_tree *tree, const char *dname)
197 {
198         struct smb_rmdir parms;
199
200         parms.in.path = dname;
201
202         return smb_raw_rmdir(tree, &parms);
203 }
204
205
206 /****************************************************************************
207  Set or clear the delete on close flag.
208 ****************************************************************************/
209 NTSTATUS smbcli_nt_delete_on_close(struct smbcli_tree *tree, int fnum, 
210                                    bool flag)
211 {
212         union smb_setfileinfo parms;
213         NTSTATUS status;
214
215         parms.disposition_info.level = RAW_SFILEINFO_DISPOSITION_INFO;
216         parms.disposition_info.in.file.fnum = fnum;
217         parms.disposition_info.in.delete_on_close = flag;
218         
219         status = smb_raw_setfileinfo(tree, &parms);
220
221         return status;
222 }
223
224
225 /****************************************************************************
226  Create/open a file - exposing the full horror of the NT API :-).
227  Used in CIFS-on-CIFS NTVFS.
228 ****************************************************************************/
229 int smbcli_nt_create_full(struct smbcli_tree *tree, const char *fname,
230                        uint32_t CreatFlags, uint32_t DesiredAccess,
231                        uint32_t FileAttributes, uint32_t ShareAccess,
232                        uint32_t CreateDisposition, uint32_t CreateOptions,
233                        uint8_t SecurityFlags)
234 {
235         union smb_open open_parms;
236         TALLOC_CTX *mem_ctx;
237         NTSTATUS status;
238
239         mem_ctx = talloc_init("raw_open");
240         if (!mem_ctx) return -1;
241
242         open_parms.ntcreatex.level = RAW_OPEN_NTCREATEX;
243         open_parms.ntcreatex.in.flags = CreatFlags;
244         open_parms.ntcreatex.in.root_fid = 0;
245         open_parms.ntcreatex.in.access_mask = DesiredAccess;
246         open_parms.ntcreatex.in.file_attr = FileAttributes;
247         open_parms.ntcreatex.in.alloc_size = 0;
248         open_parms.ntcreatex.in.share_access = ShareAccess;
249         open_parms.ntcreatex.in.open_disposition = CreateDisposition;
250         open_parms.ntcreatex.in.create_options = CreateOptions;
251         open_parms.ntcreatex.in.impersonation = 0;
252         open_parms.ntcreatex.in.security_flags = SecurityFlags;
253         open_parms.ntcreatex.in.fname = fname;
254
255         status = smb_raw_open(tree, mem_ctx, &open_parms);
256         talloc_free(mem_ctx);
257
258         if (NT_STATUS_IS_OK(status)) {
259                 return open_parms.ntcreatex.out.file.fnum;
260         }
261         
262         return -1;
263 }
264
265
266 /****************************************************************************
267  Open a file (using SMBopenx)
268  WARNING: if you open with O_WRONLY then getattrE won't work!
269 ****************************************************************************/
270 int smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, 
271              int share_mode)
272 {
273         union smb_open open_parms;
274         uint_t openfn=0;
275         uint_t accessmode=0;
276         TALLOC_CTX *mem_ctx;
277         NTSTATUS status;
278
279         mem_ctx = talloc_init("raw_open");
280         if (!mem_ctx) return -1;
281
282         if (flags & O_CREAT) {
283                 openfn |= OPENX_OPEN_FUNC_CREATE;
284         }
285         if (!(flags & O_EXCL)) {
286                 if (flags & O_TRUNC) {
287                         openfn |= OPENX_OPEN_FUNC_TRUNC;
288                 } else {
289                         openfn |= OPENX_OPEN_FUNC_OPEN;
290                 }
291         }
292
293         accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
294
295         if ((flags & O_ACCMODE) == O_RDWR) {
296                 accessmode |= OPENX_MODE_ACCESS_RDWR;
297         } else if ((flags & O_ACCMODE) == O_WRONLY) {
298                 accessmode |= OPENX_MODE_ACCESS_WRITE;
299         } 
300
301 #if defined(O_SYNC)
302         if ((flags & O_SYNC) == O_SYNC) {
303                 accessmode |= OPENX_MODE_WRITE_THRU;
304         }
305 #endif
306
307         if (share_mode == DENY_FCB) {
308                 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
309         }
310
311         open_parms.openx.level = RAW_OPEN_OPENX;
312         open_parms.openx.in.flags = 0;
313         open_parms.openx.in.open_mode = accessmode;
314         open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
315         open_parms.openx.in.file_attrs = 0;
316         open_parms.openx.in.write_time = 0;
317         open_parms.openx.in.open_func = openfn;
318         open_parms.openx.in.size = 0;
319         open_parms.openx.in.timeout = 0;
320         open_parms.openx.in.fname = fname;
321
322         status = smb_raw_open(tree, mem_ctx, &open_parms);
323         talloc_free(mem_ctx);
324
325         if (NT_STATUS_IS_OK(status)) {
326                 return open_parms.openx.out.file.fnum;
327         }
328
329         return -1;
330 }
331
332
333 /****************************************************************************
334  Close a file.
335 ****************************************************************************/
336 NTSTATUS smbcli_close(struct smbcli_tree *tree, int fnum)
337 {
338         union smb_close close_parms;
339         NTSTATUS status;
340
341         close_parms.close.level = RAW_CLOSE_CLOSE;
342         close_parms.close.in.file.fnum = fnum;
343         close_parms.close.in.write_time = 0;
344         status = smb_raw_close(tree, &close_parms);
345         return status;
346 }
347
348 /****************************************************************************
349  send a lock with a specified locktype 
350  this is used for testing LOCKING_ANDX_CANCEL_LOCK
351 ****************************************************************************/
352 NTSTATUS smbcli_locktype(struct smbcli_tree *tree, int fnum, 
353                       uint32_t offset, uint32_t len, int timeout, 
354                       uint8_t locktype)
355 {
356         union smb_lock parms;
357         struct smb_lock_entry lock[1];
358         NTSTATUS status;
359
360         parms.lockx.level = RAW_LOCK_LOCKX;
361         parms.lockx.in.file.fnum = fnum;
362         parms.lockx.in.mode = locktype;
363         parms.lockx.in.timeout = timeout;
364         parms.lockx.in.ulock_cnt = 0;
365         parms.lockx.in.lock_cnt = 1;
366         lock[0].pid = tree->session->pid;
367         lock[0].offset = offset;
368         lock[0].count = len;
369         parms.lockx.in.locks = &lock[0];
370
371         status = smb_raw_lock(tree, &parms);
372         
373         return status;
374 }
375
376
377 /****************************************************************************
378  Lock a file.
379 ****************************************************************************/
380 NTSTATUS smbcli_lock(struct smbcli_tree *tree, int fnum, 
381                   uint32_t offset, uint32_t len, int timeout, 
382                   enum brl_type lock_type)
383 {
384         union smb_lock parms;
385         struct smb_lock_entry lock[1];
386         NTSTATUS status;
387
388         parms.lockx.level = RAW_LOCK_LOCKX;
389         parms.lockx.in.file.fnum = fnum;
390         parms.lockx.in.mode = (lock_type == READ_LOCK? 1 : 0);
391         parms.lockx.in.timeout = timeout;
392         parms.lockx.in.ulock_cnt = 0;
393         parms.lockx.in.lock_cnt = 1;
394         lock[0].pid = tree->session->pid;
395         lock[0].offset = offset;
396         lock[0].count = len;
397         parms.lockx.in.locks = &lock[0];
398
399         status = smb_raw_lock(tree, &parms);
400
401         return status;
402 }
403
404
405 /****************************************************************************
406  Unlock a file.
407 ****************************************************************************/
408 NTSTATUS smbcli_unlock(struct smbcli_tree *tree, int fnum, uint32_t offset, uint32_t len)
409 {
410         union smb_lock parms;
411         struct smb_lock_entry lock[1];
412         NTSTATUS status;
413
414         parms.lockx.level = RAW_LOCK_LOCKX;
415         parms.lockx.in.file.fnum = fnum;
416         parms.lockx.in.mode = 0;
417         parms.lockx.in.timeout = 0;
418         parms.lockx.in.ulock_cnt = 1;
419         parms.lockx.in.lock_cnt = 0;
420         lock[0].pid = tree->session->pid;
421         lock[0].offset = offset;
422         lock[0].count = len;
423         parms.lockx.in.locks = &lock[0];
424         
425         status = smb_raw_lock(tree, &parms);
426         return status;
427 }
428         
429
430 /****************************************************************************
431  Lock a file with 64 bit offsets.
432 ****************************************************************************/
433 NTSTATUS smbcli_lock64(struct smbcli_tree *tree, int fnum, 
434                     off_t offset, off_t len, int timeout, 
435                     enum brl_type lock_type)
436 {
437         union smb_lock parms;
438         int ltype;
439         struct smb_lock_entry lock[1];
440         NTSTATUS status;
441
442         if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
443                 return smbcli_lock(tree, fnum, offset, len, timeout, lock_type);
444         }
445
446         parms.lockx.level = RAW_LOCK_LOCKX;
447         parms.lockx.in.file.fnum = fnum;
448         
449         ltype = (lock_type == READ_LOCK? 1 : 0);
450         ltype |= LOCKING_ANDX_LARGE_FILES;
451         parms.lockx.in.mode = ltype;
452         parms.lockx.in.timeout = timeout;
453         parms.lockx.in.ulock_cnt = 0;
454         parms.lockx.in.lock_cnt = 1;
455         lock[0].pid = tree->session->pid;
456         lock[0].offset = offset;
457         lock[0].count = len;
458         parms.lockx.in.locks = &lock[0];
459
460         status = smb_raw_lock(tree, &parms);
461         
462         return status;
463 }
464
465
466 /****************************************************************************
467  Unlock a file with 64 bit offsets.
468 ****************************************************************************/
469 NTSTATUS smbcli_unlock64(struct smbcli_tree *tree, int fnum, off_t offset, 
470                          off_t len)
471 {
472         union smb_lock parms;
473         struct smb_lock_entry lock[1];
474         NTSTATUS status;
475
476         if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
477                 return smbcli_unlock(tree, fnum, offset, len);
478         }
479
480         parms.lockx.level = RAW_LOCK_LOCKX;
481         parms.lockx.in.file.fnum = fnum;
482         parms.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
483         parms.lockx.in.timeout = 0;
484         parms.lockx.in.ulock_cnt = 1;
485         parms.lockx.in.lock_cnt = 0;
486         lock[0].pid = tree->session->pid;
487         lock[0].offset = offset;
488         lock[0].count = len;
489         parms.lockx.in.locks = &lock[0];
490
491         status = smb_raw_lock(tree, &parms);
492
493         return status;
494 }
495
496
497 /****************************************************************************
498  Do a SMBgetattrE call.
499 ****************************************************************************/
500 NTSTATUS smbcli_getattrE(struct smbcli_tree *tree, int fnum,
501                       uint16_t *attr, size_t *size,
502                       time_t *c_time, time_t *a_time, time_t *m_time)
503 {               
504         union smb_fileinfo parms;
505         NTSTATUS status;
506
507         parms.getattre.level = RAW_FILEINFO_GETATTRE;
508         parms.getattre.in.file.fnum = fnum;
509
510         status = smb_raw_fileinfo(tree, NULL, &parms);
511
512         if (!NT_STATUS_IS_OK(status))
513                 return status;
514
515         if (size) {
516                 *size = parms.getattre.out.size;
517         }
518
519         if (attr) {
520                 *attr = parms.getattre.out.attrib;
521         }
522
523         if (c_time) {
524                 *c_time = parms.getattre.out.create_time;
525         }
526
527         if (a_time) {
528                 *a_time = parms.getattre.out.access_time;
529         }
530
531         if (m_time) {
532                 *m_time = parms.getattre.out.write_time;
533         }
534
535         return status;
536 }
537
538 /****************************************************************************
539  Do a SMBgetatr call
540 ****************************************************************************/
541 NTSTATUS smbcli_getatr(struct smbcli_tree *tree, const char *fname, 
542                     uint16_t *attr, size_t *size, time_t *t)
543 {
544         union smb_fileinfo parms;
545         NTSTATUS status;
546
547         parms.getattr.level = RAW_FILEINFO_GETATTR;
548         parms.getattr.in.file.path = fname;
549
550         status = smb_raw_pathinfo(tree, NULL, &parms);
551         
552         if (!NT_STATUS_IS_OK(status)) {
553                 return status;
554         }
555
556         if (size) {
557                 *size = parms.getattr.out.size;
558         }
559
560         if (t) {
561                 *t = parms.getattr.out.write_time;
562         }
563
564         if (attr) {
565                 *attr = parms.getattr.out.attrib;
566         }
567
568         return status;
569 }
570
571
572 /****************************************************************************
573  Do a SMBsetatr call.
574 ****************************************************************************/
575 NTSTATUS smbcli_setatr(struct smbcli_tree *tree, const char *fname, uint16_t mode, 
576                     time_t t)
577 {
578         union smb_setfileinfo parms;
579
580         parms.setattr.level = RAW_SFILEINFO_SETATTR;
581         parms.setattr.in.file.path = fname;
582         parms.setattr.in.attrib = mode;
583         parms.setattr.in.write_time = t;
584         
585         return smb_raw_setpathinfo(tree, &parms);
586 }
587
588 /****************************************************************************
589  Do a setfileinfo basic_info call.
590 ****************************************************************************/
591 NTSTATUS smbcli_fsetatr(struct smbcli_tree *tree, int fnum, uint16_t mode, 
592                         NTTIME create_time, NTTIME access_time, 
593                         NTTIME write_time, NTTIME change_time)
594 {
595         union smb_setfileinfo parms;
596
597         parms.basic_info.level = RAW_SFILEINFO_BASIC_INFO;
598         parms.basic_info.in.file.fnum = fnum;
599         parms.basic_info.in.attrib = mode;
600         parms.basic_info.in.create_time = create_time;
601         parms.basic_info.in.access_time = access_time;
602         parms.basic_info.in.write_time = write_time;
603         parms.basic_info.in.change_time = change_time;
604         
605         return smb_raw_setfileinfo(tree, &parms);
606 }
607
608
609 /****************************************************************************
610  truncate a file to a given size
611 ****************************************************************************/
612 NTSTATUS smbcli_ftruncate(struct smbcli_tree *tree, int fnum, uint64_t size)
613 {
614         union smb_setfileinfo parms;
615
616         parms.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFO;
617         parms.end_of_file_info.in.file.fnum = fnum;
618         parms.end_of_file_info.in.size = size;
619         
620         return smb_raw_setfileinfo(tree, &parms);
621 }
622
623
624 /****************************************************************************
625  Check for existence of a dir.
626 ****************************************************************************/
627 NTSTATUS smbcli_chkpath(struct smbcli_tree *tree, const char *path)
628 {
629         union smb_chkpath parms;
630         char *path2;
631         NTSTATUS status;
632
633         path2 = strdup(path);
634         trim_string(path2,NULL,"\\");
635         if (!*path2) {
636                 free(path2);
637                 path2 = strdup("\\");
638         }
639
640         parms.chkpath.in.path = path2;
641
642         status = smb_raw_chkpath(tree, &parms);
643
644         free(path2);
645
646         return status;
647 }
648
649
650 /****************************************************************************
651  Query disk space.
652 ****************************************************************************/
653 NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, uint32_t *bsize, 
654                         uint64_t *total, uint64_t *avail)
655 {
656         union smb_fsinfo fsinfo_parms;
657         TALLOC_CTX *mem_ctx;
658         NTSTATUS status;
659
660         mem_ctx = talloc_init("smbcli_dskattr");
661
662         fsinfo_parms.dskattr.level = RAW_QFS_SIZE_INFO;
663         status = smb_raw_fsinfo(tree, mem_ctx, &fsinfo_parms);
664         if (NT_STATUS_IS_OK(status)) {
665                 *bsize = fsinfo_parms.size_info.out.bytes_per_sector * fsinfo_parms.size_info.out.sectors_per_unit;
666                 *total = fsinfo_parms.size_info.out.total_alloc_units;
667                 *avail = fsinfo_parms.size_info.out.avail_alloc_units;
668         }
669
670         talloc_free(mem_ctx);
671         
672         return status;
673 }
674
675
676 /****************************************************************************
677  Create and open a temporary file.
678 ****************************************************************************/
679 int smbcli_ctemp(struct smbcli_tree *tree, const char *path, char **tmp_path)
680 {
681         union smb_open open_parms;
682         TALLOC_CTX *mem_ctx;
683         NTSTATUS status;
684
685         mem_ctx = talloc_init("raw_open");
686         if (!mem_ctx) return -1;
687
688         open_parms.openx.level = RAW_OPEN_CTEMP;
689         open_parms.ctemp.in.attrib = 0;
690         open_parms.ctemp.in.directory = path;
691         open_parms.ctemp.in.write_time = 0;
692
693         status = smb_raw_open(tree, mem_ctx, &open_parms);
694         if (tmp_path) {
695                 *tmp_path = strdup(open_parms.ctemp.out.name);
696         }
697         talloc_free(mem_ctx);
698         if (NT_STATUS_IS_OK(status)) {
699                 return open_parms.ctemp.out.file.fnum;
700         }
701         return -1;
702 }