Line data Source code
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 : #include "system/dir.h"
27 :
28 : /****************************************************************************
29 : Hard/Symlink a file (UNIX extensions).
30 : ****************************************************************************/
31 :
32 0 : static NTSTATUS smbcli_link_internal(struct smbcli_tree *tree,
33 : const char *fname_src,
34 : const char *fname_dst, bool hard_link)
35 : {
36 0 : union smb_setfileinfo parms;
37 0 : NTSTATUS status;
38 :
39 0 : if (hard_link) {
40 0 : parms.generic.level = RAW_SFILEINFO_UNIX_HLINK;
41 0 : parms.unix_hlink.in.file.path = fname_src;
42 0 : parms.unix_hlink.in.link_dest = fname_dst;
43 : } else {
44 0 : parms.generic.level = RAW_SFILEINFO_UNIX_LINK;
45 0 : parms.unix_link.in.file.path = fname_src;
46 0 : parms.unix_link.in.link_dest = fname_dst;
47 : }
48 :
49 0 : status = smb_raw_setpathinfo(tree, &parms);
50 :
51 0 : return status;
52 : }
53 :
54 : /****************************************************************************
55 : Symlink a file (UNIX extensions).
56 : ****************************************************************************/
57 0 : NTSTATUS smbcli_unix_symlink(struct smbcli_tree *tree, const char *fname_src,
58 : const char *fname_dst)
59 : {
60 0 : return smbcli_link_internal(tree, fname_src, fname_dst, false);
61 : }
62 :
63 : /****************************************************************************
64 : Hard a file (UNIX extensions).
65 : ****************************************************************************/
66 0 : NTSTATUS smbcli_unix_hardlink(struct smbcli_tree *tree, const char *fname_src,
67 : const char *fname_dst)
68 : {
69 0 : return smbcli_link_internal(tree, fname_src, fname_dst, true);
70 : }
71 :
72 :
73 : /****************************************************************************
74 : Chmod or chown a file internal (UNIX extensions).
75 : ****************************************************************************/
76 0 : static NTSTATUS smbcli_unix_chmod_chown_internal(struct smbcli_tree *tree,
77 : const char *fname,
78 : uint32_t mode, uint32_t uid,
79 : uint32_t gid)
80 : {
81 0 : union smb_setfileinfo parms;
82 0 : NTSTATUS status;
83 :
84 0 : parms.generic.level = SMB_SFILEINFO_UNIX_BASIC;
85 0 : parms.unix_basic.in.file.path = fname;
86 0 : parms.unix_basic.in.uid = uid;
87 0 : parms.unix_basic.in.gid = gid;
88 0 : parms.unix_basic.in.mode = mode;
89 :
90 0 : status = smb_raw_setpathinfo(tree, &parms);
91 :
92 0 : return status;
93 : }
94 :
95 : /****************************************************************************
96 : chmod a file (UNIX extensions).
97 : ****************************************************************************/
98 :
99 0 : NTSTATUS smbcli_unix_chmod(struct smbcli_tree *tree, const char *fname, mode_t mode)
100 : {
101 0 : return smbcli_unix_chmod_chown_internal(tree, fname,
102 : unix_perms_to_wire(mode),
103 : SMB_UID_NO_CHANGE,
104 : SMB_GID_NO_CHANGE);
105 : }
106 :
107 : /****************************************************************************
108 : chown a file (UNIX extensions).
109 : ****************************************************************************/
110 0 : NTSTATUS smbcli_unix_chown(struct smbcli_tree *tree, const char *fname, uid_t uid,
111 : gid_t gid)
112 : {
113 0 : return smbcli_unix_chmod_chown_internal(tree, fname, SMB_MODE_NO_CHANGE,
114 : (uint32_t)uid, (uint32_t)gid);
115 : }
116 :
117 :
118 : /****************************************************************************
119 : Rename a file.
120 : ****************************************************************************/
121 237 : NTSTATUS smbcli_rename(struct smbcli_tree *tree, const char *fname_src,
122 : const char *fname_dst)
123 : {
124 1 : union smb_rename parms;
125 :
126 237 : parms.generic.level = RAW_RENAME_RENAME;
127 237 : parms.rename.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY;
128 237 : parms.rename.in.pattern1 = fname_src;
129 237 : parms.rename.in.pattern2 = fname_dst;
130 :
131 237 : return smb_raw_rename(tree, &parms);
132 : }
133 :
134 :
135 : /****************************************************************************
136 : Delete a file.
137 : ****************************************************************************/
138 45693 : NTSTATUS smbcli_unlink(struct smbcli_tree *tree, const char *fname)
139 : {
140 378 : union smb_unlink parms;
141 :
142 45693 : parms.unlink.in.pattern = fname;
143 45693 : parms.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY;
144 :
145 45693 : return smb_raw_unlink(tree, &parms);
146 : }
147 :
148 : struct wcard_delete_state {
149 : struct smbcli_tree *tree;
150 : NTSTATUS status;
151 : char *error_name; /* To help debugging. */
152 : };
153 :
154 17148 : static void del_fn(struct clilist_file_info *finfo,
155 : const char *pattern,
156 : void *priv)
157 : {
158 33 : NTSTATUS status;
159 33 : union smb_unlink parms;
160 17148 : char *filename = NULL;
161 17148 : char *dirname = NULL;
162 17148 : char *p = NULL;
163 17148 : struct wcard_delete_state *state = (struct wcard_delete_state *)priv;
164 :
165 17148 : if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
166 0 : return;
167 : }
168 17148 : dirname = talloc_strdup(state, pattern);
169 17148 : if (dirname == NULL) {
170 0 : TALLOC_FREE(state->error_name);
171 0 : state->status = NT_STATUS_NO_MEMORY;
172 0 : return;
173 : }
174 17148 : p = strrchr_m(dirname, '\\');
175 17148 : if (p != NULL) {
176 : /* Remove the terminating '\' */
177 17148 : *p = '\0';
178 : }
179 17148 : if (dirname[0] != '\0') {
180 17148 : filename = talloc_asprintf(dirname,
181 : "%s\\%s",
182 : dirname,
183 : finfo->name);
184 : } else {
185 0 : filename = talloc_asprintf(dirname,
186 : "%s",
187 : finfo->name);
188 : }
189 17148 : if (filename == NULL) {
190 0 : TALLOC_FREE(dirname);
191 0 : TALLOC_FREE(state->error_name);
192 0 : state->status = NT_STATUS_NO_MEMORY;
193 0 : return;
194 : }
195 17148 : parms.unlink.in.pattern = filename;
196 17148 : parms.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM |
197 : FILE_ATTRIBUTE_HIDDEN;
198 17148 : status = smb_raw_unlink(state->tree, &parms);
199 17148 : if (NT_STATUS_IS_OK(state->status)) {
200 17148 : state->status = status;
201 17148 : if (!NT_STATUS_IS_OK(status)) {
202 : /*
203 : * Save off the name we failed to
204 : * delete to help debugging.
205 : */
206 20 : state->error_name = talloc_move(state, &filename);
207 : }
208 : }
209 17148 : TALLOC_FREE(dirname);
210 : }
211 :
212 : /****************************************************************************
213 : Delete a file, possibly with a wildcard pattern.
214 : ****************************************************************************/
215 1014 : NTSTATUS smbcli_unlink_wcard(struct smbcli_tree *tree, const char *pattern)
216 : {
217 42 : NTSTATUS status;
218 42 : int ret;
219 1014 : struct wcard_delete_state *state = NULL;
220 :
221 1014 : if (strchr(pattern, '*') == NULL) {
222 : /* No wildcard, just call smbcli_unlink(). */
223 0 : return smbcli_unlink(tree, pattern);
224 : }
225 1014 : state = talloc_zero(tree, struct wcard_delete_state);
226 1014 : if (state == NULL) {
227 0 : return NT_STATUS_NO_MEMORY;
228 : }
229 1014 : state->tree = tree;
230 1014 : ret = smbcli_list(tree,
231 : pattern,
232 : FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
233 : del_fn,
234 : state);
235 1014 : status = state->status;
236 1014 : TALLOC_FREE(state);
237 1014 : if (ret < 0) {
238 434 : return NT_STATUS_UNSUCCESSFUL;
239 : }
240 580 : return status;
241 : }
242 :
243 : /****************************************************************************
244 : Create a directory.
245 : ****************************************************************************/
246 8048 : NTSTATUS smbcli_mkdir(struct smbcli_tree *tree, const char *dname)
247 : {
248 48 : union smb_mkdir parms;
249 :
250 8048 : parms.mkdir.level = RAW_MKDIR_MKDIR;
251 8048 : parms.mkdir.in.path = dname;
252 :
253 8048 : return smb_raw_mkdir(tree, &parms);
254 : }
255 :
256 :
257 : /****************************************************************************
258 : Remove a directory.
259 : ****************************************************************************/
260 13231 : NTSTATUS smbcli_rmdir(struct smbcli_tree *tree, const char *dname)
261 : {
262 71 : struct smb_rmdir parms;
263 :
264 13231 : parms.in.path = dname;
265 :
266 13231 : return smb_raw_rmdir(tree, &parms);
267 : }
268 :
269 :
270 : /****************************************************************************
271 : Set or clear the delete on close flag.
272 : ****************************************************************************/
273 163 : NTSTATUS smbcli_nt_delete_on_close(struct smbcli_tree *tree, int fnum,
274 : bool flag)
275 : {
276 21 : union smb_setfileinfo parms;
277 21 : NTSTATUS status;
278 :
279 163 : parms.disposition_info.level = RAW_SFILEINFO_DISPOSITION_INFO;
280 163 : parms.disposition_info.in.file.fnum = fnum;
281 163 : parms.disposition_info.in.delete_on_close = flag;
282 :
283 163 : status = smb_raw_setfileinfo(tree, &parms);
284 :
285 163 : return status;
286 : }
287 :
288 :
289 : /****************************************************************************
290 : Create/open a file - exposing the full horror of the NT API :-).
291 : Used in CIFS-on-CIFS NTVFS.
292 : ****************************************************************************/
293 9804 : int smbcli_nt_create_full(struct smbcli_tree *tree, const char *fname,
294 : uint32_t CreatFlags, uint32_t DesiredAccess,
295 : uint32_t FileAttributes, uint32_t ShareAccess,
296 : uint32_t CreateDisposition, uint32_t CreateOptions,
297 : uint8_t SecurityFlags)
298 : {
299 429 : union smb_open open_parms;
300 429 : TALLOC_CTX *mem_ctx;
301 429 : NTSTATUS status;
302 :
303 9804 : mem_ctx = talloc_init("raw_open");
304 9804 : if (!mem_ctx) return -1;
305 :
306 9804 : open_parms.ntcreatex.level = RAW_OPEN_NTCREATEX;
307 9804 : open_parms.ntcreatex.in.flags = CreatFlags;
308 9804 : open_parms.ntcreatex.in.root_fid.fnum = 0;
309 9804 : open_parms.ntcreatex.in.access_mask = DesiredAccess;
310 9804 : open_parms.ntcreatex.in.file_attr = FileAttributes;
311 9804 : open_parms.ntcreatex.in.alloc_size = 0;
312 9804 : open_parms.ntcreatex.in.share_access = ShareAccess;
313 9804 : open_parms.ntcreatex.in.open_disposition = CreateDisposition;
314 9804 : open_parms.ntcreatex.in.create_options = CreateOptions;
315 9804 : open_parms.ntcreatex.in.impersonation = 0;
316 9804 : open_parms.ntcreatex.in.security_flags = SecurityFlags;
317 9804 : open_parms.ntcreatex.in.fname = fname;
318 :
319 9804 : status = smb_raw_open(tree, mem_ctx, &open_parms);
320 9804 : talloc_free(mem_ctx);
321 :
322 9804 : if (NT_STATUS_IS_OK(status)) {
323 8217 : return open_parms.ntcreatex.out.file.fnum;
324 : }
325 :
326 1297 : return -1;
327 : }
328 :
329 :
330 : /****************************************************************************
331 : Open a file (using SMBopenx)
332 : WARNING: if you open with O_WRONLY then getattrE won't work!
333 : ****************************************************************************/
334 27968 : int smbcli_open(struct smbcli_tree *tree, const char *fname, int flags,
335 : int share_mode)
336 : {
337 67 : union smb_open open_parms;
338 27968 : unsigned int openfn=0;
339 27968 : unsigned int accessmode=0;
340 67 : TALLOC_CTX *mem_ctx;
341 67 : NTSTATUS status;
342 :
343 27968 : mem_ctx = talloc_init("raw_open");
344 27968 : if (!mem_ctx) return -1;
345 :
346 27968 : if (flags & O_CREAT) {
347 17217 : openfn |= OPENX_OPEN_FUNC_CREATE;
348 : }
349 27968 : if (!(flags & O_EXCL)) {
350 27754 : if (flags & O_TRUNC) {
351 383 : openfn |= OPENX_OPEN_FUNC_TRUNC;
352 : } else {
353 27371 : openfn |= OPENX_OPEN_FUNC_OPEN;
354 : }
355 : }
356 :
357 27968 : accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
358 :
359 27968 : if ((flags & O_ACCMODE) == O_RDWR) {
360 20380 : accessmode |= OPENX_MODE_ACCESS_RDWR;
361 7588 : } else if ((flags & O_ACCMODE) == O_WRONLY) {
362 3486 : accessmode |= OPENX_MODE_ACCESS_WRITE;
363 : }
364 :
365 : #if defined(O_SYNC)
366 27968 : if ((flags & O_SYNC) == O_SYNC) {
367 0 : accessmode |= OPENX_MODE_WRITE_THRU;
368 : }
369 : #endif
370 :
371 27968 : if (share_mode == DENY_FCB) {
372 1728 : accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
373 : }
374 :
375 27968 : open_parms.openx.level = RAW_OPEN_OPENX;
376 27968 : open_parms.openx.in.flags = 0;
377 27968 : open_parms.openx.in.open_mode = accessmode;
378 27968 : open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
379 27968 : open_parms.openx.in.file_attrs = 0;
380 27968 : open_parms.openx.in.write_time = 0;
381 27968 : open_parms.openx.in.open_func = openfn;
382 27968 : open_parms.openx.in.size = 0;
383 27968 : open_parms.openx.in.timeout = 0;
384 27968 : open_parms.openx.in.fname = fname;
385 :
386 27968 : status = smb_raw_open(tree, mem_ctx, &open_parms);
387 27968 : talloc_free(mem_ctx);
388 :
389 27968 : if (NT_STATUS_IS_OK(status)) {
390 23532 : return open_parms.openx.out.file.fnum;
391 : }
392 :
393 4413 : return -1;
394 : }
395 :
396 :
397 : /****************************************************************************
398 : Close a file.
399 : ****************************************************************************/
400 93648 : NTSTATUS smbcli_close(struct smbcli_tree *tree, int fnum)
401 : {
402 351 : union smb_close close_parms;
403 351 : NTSTATUS status;
404 :
405 93648 : close_parms.close.level = RAW_CLOSE_CLOSE;
406 93648 : close_parms.close.in.file.fnum = fnum;
407 93648 : close_parms.close.in.write_time = 0;
408 93648 : status = smb_raw_close(tree, &close_parms);
409 93648 : return status;
410 : }
411 :
412 : /****************************************************************************
413 : send a lock with a specified locktype
414 : this is used for testing LOCKING_ANDX_CANCEL_LOCK
415 : ****************************************************************************/
416 8 : NTSTATUS smbcli_locktype(struct smbcli_tree *tree, int fnum,
417 : uint32_t offset, uint32_t len, int timeout,
418 : uint8_t locktype)
419 : {
420 0 : union smb_lock parms;
421 0 : struct smb_lock_entry lock[1];
422 0 : NTSTATUS status;
423 :
424 8 : parms.lockx.level = RAW_LOCK_LOCKX;
425 8 : parms.lockx.in.file.fnum = fnum;
426 8 : parms.lockx.in.mode = locktype;
427 8 : parms.lockx.in.timeout = timeout;
428 8 : parms.lockx.in.ulock_cnt = 0;
429 8 : parms.lockx.in.lock_cnt = 1;
430 8 : lock[0].pid = tree->session->pid;
431 8 : lock[0].offset = offset;
432 8 : lock[0].count = len;
433 8 : parms.lockx.in.locks = &lock[0];
434 :
435 8 : status = smb_raw_lock(tree, &parms);
436 :
437 8 : return status;
438 : }
439 :
440 :
441 : /****************************************************************************
442 : Lock a file.
443 : ****************************************************************************/
444 581 : NTSTATUS smbcli_lock(struct smbcli_tree *tree, int fnum,
445 : uint32_t offset, uint32_t len, int timeout,
446 : enum brl_type lock_type)
447 : {
448 8 : union smb_lock parms;
449 8 : struct smb_lock_entry lock[1];
450 8 : NTSTATUS status;
451 :
452 581 : parms.lockx.level = RAW_LOCK_LOCKX;
453 581 : parms.lockx.in.file.fnum = fnum;
454 581 : parms.lockx.in.mode = (lock_type == READ_LOCK? 1 : 0);
455 581 : parms.lockx.in.timeout = timeout;
456 581 : parms.lockx.in.ulock_cnt = 0;
457 581 : parms.lockx.in.lock_cnt = 1;
458 581 : lock[0].pid = tree->session->pid;
459 581 : lock[0].offset = offset;
460 581 : lock[0].count = len;
461 581 : parms.lockx.in.locks = &lock[0];
462 :
463 581 : status = smb_raw_lock(tree, &parms);
464 :
465 581 : return status;
466 : }
467 :
468 :
469 : /****************************************************************************
470 : Unlock a file.
471 : ****************************************************************************/
472 209 : NTSTATUS smbcli_unlock(struct smbcli_tree *tree, int fnum, uint32_t offset, uint32_t len)
473 : {
474 5 : union smb_lock parms;
475 5 : struct smb_lock_entry lock[1];
476 5 : NTSTATUS status;
477 :
478 209 : parms.lockx.level = RAW_LOCK_LOCKX;
479 209 : parms.lockx.in.file.fnum = fnum;
480 209 : parms.lockx.in.mode = 0;
481 209 : parms.lockx.in.timeout = 0;
482 209 : parms.lockx.in.ulock_cnt = 1;
483 209 : parms.lockx.in.lock_cnt = 0;
484 209 : lock[0].pid = tree->session->pid;
485 209 : lock[0].offset = offset;
486 209 : lock[0].count = len;
487 209 : parms.lockx.in.locks = &lock[0];
488 :
489 209 : status = smb_raw_lock(tree, &parms);
490 209 : return status;
491 : }
492 :
493 :
494 : /****************************************************************************
495 : Lock a file with 64 bit offsets.
496 : ****************************************************************************/
497 7 : NTSTATUS smbcli_lock64(struct smbcli_tree *tree, int fnum,
498 : off_t offset, off_t len, int timeout,
499 : enum brl_type lock_type)
500 : {
501 1 : union smb_lock parms;
502 1 : int ltype;
503 1 : struct smb_lock_entry lock[1];
504 1 : NTSTATUS status;
505 :
506 7 : if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
507 0 : return smbcli_lock(tree, fnum, offset, len, timeout, lock_type);
508 : }
509 :
510 7 : parms.lockx.level = RAW_LOCK_LOCKX;
511 7 : parms.lockx.in.file.fnum = fnum;
512 :
513 7 : ltype = (lock_type == READ_LOCK? 1 : 0);
514 7 : ltype |= LOCKING_ANDX_LARGE_FILES;
515 7 : parms.lockx.in.mode = ltype;
516 7 : parms.lockx.in.timeout = timeout;
517 7 : parms.lockx.in.ulock_cnt = 0;
518 7 : parms.lockx.in.lock_cnt = 1;
519 7 : lock[0].pid = tree->session->pid;
520 7 : lock[0].offset = offset;
521 7 : lock[0].count = len;
522 7 : parms.lockx.in.locks = &lock[0];
523 :
524 7 : status = smb_raw_lock(tree, &parms);
525 :
526 7 : return status;
527 : }
528 :
529 :
530 : /****************************************************************************
531 : Unlock a file with 64 bit offsets.
532 : ****************************************************************************/
533 0 : NTSTATUS smbcli_unlock64(struct smbcli_tree *tree, int fnum, off_t offset,
534 : off_t len)
535 : {
536 0 : union smb_lock parms;
537 0 : struct smb_lock_entry lock[1];
538 0 : NTSTATUS status;
539 :
540 0 : if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
541 0 : return smbcli_unlock(tree, fnum, offset, len);
542 : }
543 :
544 0 : parms.lockx.level = RAW_LOCK_LOCKX;
545 0 : parms.lockx.in.file.fnum = fnum;
546 0 : parms.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
547 0 : parms.lockx.in.timeout = 0;
548 0 : parms.lockx.in.ulock_cnt = 1;
549 0 : parms.lockx.in.lock_cnt = 0;
550 0 : lock[0].pid = tree->session->pid;
551 0 : lock[0].offset = offset;
552 0 : lock[0].count = len;
553 0 : parms.lockx.in.locks = &lock[0];
554 :
555 0 : status = smb_raw_lock(tree, &parms);
556 :
557 0 : return status;
558 : }
559 :
560 :
561 : /****************************************************************************
562 : Do a SMBgetattrE call.
563 : ****************************************************************************/
564 0 : NTSTATUS smbcli_getattrE(struct smbcli_tree *tree, int fnum,
565 : uint16_t *attr, size_t *size,
566 : time_t *c_time, time_t *a_time, time_t *m_time)
567 : {
568 0 : union smb_fileinfo parms;
569 0 : NTSTATUS status;
570 :
571 0 : parms.getattre.level = RAW_FILEINFO_GETATTRE;
572 0 : parms.getattre.in.file.fnum = fnum;
573 :
574 0 : status = smb_raw_fileinfo(tree, NULL, &parms);
575 :
576 0 : if (!NT_STATUS_IS_OK(status))
577 0 : return status;
578 :
579 0 : if (size) {
580 0 : *size = parms.getattre.out.size;
581 : }
582 :
583 0 : if (attr) {
584 0 : *attr = parms.getattre.out.attrib;
585 : }
586 :
587 0 : if (c_time) {
588 0 : *c_time = parms.getattre.out.create_time;
589 : }
590 :
591 0 : if (a_time) {
592 0 : *a_time = parms.getattre.out.access_time;
593 : }
594 :
595 0 : if (m_time) {
596 0 : *m_time = parms.getattre.out.write_time;
597 : }
598 :
599 0 : return status;
600 : }
601 :
602 : /****************************************************************************
603 : Do a SMBgetatr call
604 : ****************************************************************************/
605 901 : NTSTATUS smbcli_getatr(struct smbcli_tree *tree, const char *fname,
606 : uint16_t *attr, size_t *size, time_t *t)
607 : {
608 48 : union smb_fileinfo parms;
609 48 : NTSTATUS status;
610 :
611 901 : parms.getattr.level = RAW_FILEINFO_GETATTR;
612 901 : parms.getattr.in.file.path = fname;
613 :
614 901 : status = smb_raw_pathinfo(tree, NULL, &parms);
615 :
616 901 : if (!NT_STATUS_IS_OK(status)) {
617 147 : return status;
618 : }
619 :
620 754 : if (size) {
621 32 : *size = parms.getattr.out.size;
622 : }
623 :
624 754 : if (t) {
625 14 : *t = parms.getattr.out.write_time;
626 : }
627 :
628 754 : if (attr) {
629 642 : *attr = parms.getattr.out.attrib;
630 : }
631 :
632 754 : return status;
633 : }
634 :
635 :
636 : /****************************************************************************
637 : Do a SMBsetatr call.
638 : ****************************************************************************/
639 1195 : NTSTATUS smbcli_setatr(struct smbcli_tree *tree, const char *fname, uint16_t mode,
640 : time_t t)
641 : {
642 141 : union smb_setfileinfo parms;
643 :
644 1195 : parms.setattr.level = RAW_SFILEINFO_SETATTR;
645 1195 : parms.setattr.in.file.path = fname;
646 1195 : parms.setattr.in.attrib = mode;
647 1195 : parms.setattr.in.write_time = t;
648 :
649 1195 : return smb_raw_setpathinfo(tree, &parms);
650 : }
651 :
652 : /****************************************************************************
653 : Do a setfileinfo basic_info call.
654 : ****************************************************************************/
655 416 : NTSTATUS smbcli_fsetatr(struct smbcli_tree *tree, int fnum, uint16_t mode,
656 : NTTIME create_time, NTTIME access_time,
657 : NTTIME write_time, NTTIME change_time)
658 : {
659 0 : union smb_setfileinfo parms;
660 :
661 416 : parms.basic_info.level = RAW_SFILEINFO_BASIC_INFO;
662 416 : parms.basic_info.in.file.fnum = fnum;
663 416 : parms.basic_info.in.attrib = mode;
664 416 : parms.basic_info.in.create_time = create_time;
665 416 : parms.basic_info.in.access_time = access_time;
666 416 : parms.basic_info.in.write_time = write_time;
667 416 : parms.basic_info.in.change_time = change_time;
668 :
669 416 : return smb_raw_setfileinfo(tree, &parms);
670 : }
671 :
672 :
673 : /****************************************************************************
674 : truncate a file to a given size
675 : ****************************************************************************/
676 98 : NTSTATUS smbcli_ftruncate(struct smbcli_tree *tree, int fnum, uint64_t size)
677 : {
678 0 : union smb_setfileinfo parms;
679 :
680 98 : parms.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFO;
681 98 : parms.end_of_file_info.in.file.fnum = fnum;
682 98 : parms.end_of_file_info.in.size = size;
683 :
684 98 : return smb_raw_setfileinfo(tree, &parms);
685 : }
686 :
687 :
688 : /****************************************************************************
689 : Check for existence of a dir.
690 : ****************************************************************************/
691 244 : NTSTATUS smbcli_chkpath(struct smbcli_tree *tree, const char *path)
692 : {
693 5 : union smb_chkpath parms;
694 5 : char *path2;
695 5 : NTSTATUS status;
696 :
697 244 : path2 = strdup(path);
698 244 : trim_string(path2,NULL,"\\");
699 244 : if (!*path2) {
700 129 : free(path2);
701 129 : path2 = strdup("\\");
702 : }
703 :
704 244 : parms.chkpath.in.path = path2;
705 :
706 244 : status = smb_raw_chkpath(tree, &parms);
707 :
708 244 : free(path2);
709 :
710 244 : return status;
711 : }
712 :
713 :
714 : /****************************************************************************
715 : Query disk space.
716 : ****************************************************************************/
717 10 : NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, uint32_t *bsize,
718 : uint64_t *total, uint64_t *avail)
719 : {
720 0 : union smb_fsinfo fsinfo_parms;
721 0 : TALLOC_CTX *mem_ctx;
722 0 : NTSTATUS status;
723 :
724 10 : mem_ctx = talloc_init("smbcli_dskattr");
725 :
726 10 : fsinfo_parms.dskattr.level = RAW_QFS_SIZE_INFO;
727 10 : status = smb_raw_fsinfo(tree, mem_ctx, &fsinfo_parms);
728 10 : if (NT_STATUS_IS_OK(status)) {
729 10 : *bsize = fsinfo_parms.size_info.out.bytes_per_sector * fsinfo_parms.size_info.out.sectors_per_unit;
730 10 : *total = fsinfo_parms.size_info.out.total_alloc_units;
731 10 : *avail = fsinfo_parms.size_info.out.avail_alloc_units;
732 : }
733 :
734 10 : talloc_free(mem_ctx);
735 :
736 10 : return status;
737 : }
738 :
739 :
740 : /****************************************************************************
741 : Create and open a temporary file.
742 : ****************************************************************************/
743 7 : int smbcli_ctemp(struct smbcli_tree *tree, const char *path, char **tmp_path)
744 : {
745 1 : union smb_open open_parms;
746 1 : TALLOC_CTX *mem_ctx;
747 1 : NTSTATUS status;
748 7 : int ret = -1;
749 :
750 7 : mem_ctx = talloc_init("raw_open");
751 7 : if (!mem_ctx) return ret;
752 :
753 7 : open_parms.openx.level = RAW_OPEN_CTEMP;
754 7 : open_parms.ctemp.in.attrib = 0;
755 7 : open_parms.ctemp.in.directory = path;
756 7 : open_parms.ctemp.in.write_time = 0;
757 :
758 7 : status = smb_raw_open(tree, mem_ctx, &open_parms);
759 7 : if (NT_STATUS_IS_OK(status)) {
760 7 : if (tmp_path) {
761 7 : *tmp_path = strdup(open_parms.ctemp.out.name);
762 : }
763 7 : ret = open_parms.ctemp.out.file.fnum;
764 : }
765 7 : talloc_free(mem_ctx);
766 7 : return ret;
767 : }
|