1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8 
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13 
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *  Bacula low level File I/O routines.  This routine simulates
21  *    open(), read(), write(), and close(), but using native routines.
22  *    I.e. on Windows, we use Windows APIs.
23  *
24  *    Kern Sibbald, April MMIII
25  *
26  */
27 
28 #include "bacula.h"
29 #include "find.h"
30 
31 const int dbglvl = 200;
32 
33 int       (*plugin_bopen)(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode) = NULL;
34 int       (*plugin_bclose)(BFILE *bfd) = NULL;
35 ssize_t   (*plugin_bread)(BFILE *bfd, void *buf, size_t count) = NULL;
36 ssize_t   (*plugin_bwrite)(BFILE *bfd, void *buf, size_t count) = NULL;
37 boffset_t (*plugin_blseek)(BFILE *bfd, boffset_t offset, int whence) = NULL;
38 
39 
40 #ifdef HAVE_DARWIN_OS
41 #include <sys/paths.h>
42 #endif
43 
44 #if !defined(HAVE_FDATASYNC)
45 #define fdatasync(fd)
46 #endif
47 
48 #ifdef HAVE_WIN32
pause_msg(const char * file,const char * func,int line,const char * msg)49 void pause_msg(const char *file, const char *func, int line, const char *msg)
50 {
51    char buf[1000];
52    if (msg) {
53       bsnprintf(buf, sizeof(buf), "%s:%s:%d %s", file, func, line, msg);
54    } else {
55       bsnprintf(buf, sizeof(buf), "%s:%s:%d", file, func, line);
56    }
57    MessageBox(NULL, buf, "Pause", MB_OK);
58 }
59 #endif
60 
61 /* ===============================================================
62  *
63  *            U N I X   AND   W I N D O W S
64  *
65  * ===============================================================
66  */
67 
is_win32_stream(int stream)68 bool is_win32_stream(int stream)
69 {
70    switch (stream & STREAMMASK_TYPE) {
71    case STREAM_WIN32_DATA:
72    case STREAM_WIN32_GZIP_DATA:
73    case STREAM_WIN32_COMPRESSED_DATA:
74    case STREAM_ENCRYPTED_WIN32_DATA:
75    case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
76    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
77       return true;
78    }
79    return false;
80 }
81 
stream_to_ascii(int stream)82 const char *stream_to_ascii(int stream)
83 {
84    static char buf[20];
85 
86    switch (stream & STREAMMASK_TYPE) {
87       case STREAM_UNIX_ATTRIBUTES:
88          return _("Unix attributes");
89       case STREAM_FILE_DATA:
90          return _("File data");
91       case STREAM_MD5_DIGEST:
92          return _("MD5 digest");
93       case STREAM_GZIP_DATA:
94          return _("GZIP data");
95       case STREAM_COMPRESSED_DATA:
96          return _("Compressed data");
97       case STREAM_UNIX_ATTRIBUTES_EX:
98          return _("Extended attributes");
99       case STREAM_SPARSE_DATA:
100          return _("Sparse data");
101       case STREAM_SPARSE_GZIP_DATA:
102          return _("GZIP sparse data");
103       case STREAM_SPARSE_COMPRESSED_DATA:
104          return _("Compressed sparse data");
105       case STREAM_PROGRAM_NAMES:
106          return _("Program names");
107       case STREAM_PROGRAM_DATA:
108          return _("Program data");
109       case STREAM_SHA1_DIGEST:
110          return _("SHA1 digest");
111       case STREAM_WIN32_DATA:
112          return _("Win32 data");
113       case STREAM_WIN32_GZIP_DATA:
114          return _("Win32 GZIP data");
115       case STREAM_WIN32_COMPRESSED_DATA:
116          return _("Win32 compressed data");
117       case STREAM_MACOS_FORK_DATA:
118          return _("MacOS Fork data");
119       case STREAM_HFSPLUS_ATTRIBUTES:
120          return _("HFS+ attribs");
121       case STREAM_UNIX_ACCESS_ACL:
122          return _("Standard Unix ACL attribs");
123       case STREAM_UNIX_DEFAULT_ACL:
124          return _("Default Unix ACL attribs");
125       case STREAM_SHA256_DIGEST:
126          return _("SHA256 digest");
127       case STREAM_SHA512_DIGEST:
128          return _("SHA512 digest");
129       case STREAM_SIGNED_DIGEST:
130          return _("Signed digest");
131       case STREAM_ENCRYPTED_FILE_DATA:
132          return _("Encrypted File data");
133       case STREAM_ENCRYPTED_WIN32_DATA:
134          return _("Encrypted Win32 data");
135       case STREAM_ENCRYPTED_SESSION_DATA:
136          return _("Encrypted session data");
137       case STREAM_ENCRYPTED_FILE_GZIP_DATA:
138          return _("Encrypted GZIP data");
139       case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
140          return _("Encrypted compressed data");
141       case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
142          return _("Encrypted Win32 GZIP data");
143       case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
144          return _("Encrypted Win32 Compressed data");
145       case STREAM_ENCRYPTED_MACOS_FORK_DATA:
146          return _("Encrypted MacOS fork data");
147       case STREAM_PLUGIN_NAME:
148          return _("Plugin Name");
149       case STREAM_PLUGIN_DATA:
150          return _("Plugin Data");
151       case STREAM_RESTORE_OBJECT:
152          return _("Restore Object");
153       case STREAM_XACL_AIX_TEXT:
154          return _("AIX ACL attribs");
155       case STREAM_XACL_DARWIN_ACCESS:
156          return _("Darwin ACL attribs");
157       case STREAM_XACL_FREEBSD_DEFAULT:
158          return _("FreeBSD Default ACL attribs");
159       case STREAM_XACL_FREEBSD_ACCESS:
160          return _("FreeBSD Access ACL attribs");
161       case STREAM_XACL_HPUX_ACL_ENTRY:
162          return _("HPUX ACL attribs");
163       case STREAM_XACL_IRIX_DEFAULT:
164          return _("Irix Default ACL attribs");
165       case STREAM_XACL_IRIX_ACCESS:
166          return _("Irix Access ACL attribs");
167       case STREAM_XACL_LINUX_DEFAULT:
168          return _("Linux Default ACL attribs");
169       case STREAM_XACL_LINUX_ACCESS:
170          return _("Linux Access ACL attribs");
171       case STREAM_XACL_TRU64_DEFAULT:
172          return _("TRU64 Default ACL attribs");
173       case STREAM_XACL_TRU64_ACCESS:
174          return _("TRU64 Access ACL attribs");
175       case STREAM_XACL_SOLARIS_POSIX:
176          return _("Solaris POSIX ACL attribs");
177       case STREAM_XACL_SOLARIS_NFS4:
178          return _("Solaris NFSv4/ZFS ACL attribs");
179       case STREAM_XACL_AFS_TEXT:
180          return _("AFS ACL attribs");
181       case STREAM_XACL_AIX_AIXC:
182          return _("AIX POSIX ACL attribs");
183       case STREAM_XACL_AIX_NFS4:
184          return _("AIX NFSv4 ACL attribs");
185       case STREAM_XACL_FREEBSD_NFS4:
186          return _("FreeBSD NFSv4/ZFS ACL attribs");
187       case STREAM_XACL_HURD_DEFAULT:
188          return _("GNU Hurd Default ACL attribs");
189       case STREAM_XACL_HURD_ACCESS:
190          return _("GNU Hurd Access ACL attribs");
191       case STREAM_XACL_HURD_XATTR:
192          return _("GNU Hurd Extended attribs");
193       case STREAM_XACL_IRIX_XATTR:
194          return _("IRIX Extended attribs");
195       case STREAM_XACL_TRU64_XATTR:
196          return _("TRU64 Extended attribs");
197       case STREAM_XACL_AIX_XATTR:
198          return _("AIX Extended attribs");
199       case STREAM_XACL_OPENBSD_XATTR:
200          return _("OpenBSD Extended attribs");
201       case STREAM_XACL_SOLARIS_SYS_XATTR:
202          return _("Solaris Extensible attribs or System Extended attribs");
203       case STREAM_XACL_SOLARIS_XATTR:
204          return _("Solaris Extended attribs");
205       case STREAM_XACL_DARWIN_XATTR:
206          return _("Darwin Extended attribs");
207       case STREAM_XACL_FREEBSD_XATTR:
208          return _("FreeBSD Extended attribs");
209       case STREAM_XACL_LINUX_XATTR:
210          return _("Linux Extended attribs");
211       case STREAM_XACL_NETBSD_XATTR:
212          return _("NetBSD Extended attribs");
213       default:
214          sprintf(buf, "%d", stream);
215          return (const char *)buf;
216       }
217 }
218 
219 /**
220  *  Convert a 64 bit little endian to a big endian
221  */
int64_LE2BE(int64_t * pBE,const int64_t v)222 void int64_LE2BE(int64_t* pBE, const int64_t v)
223 {
224    /* convert little endian to big endian */
225    if (htonl(1) != 1L) { /* no work if on little endian machine */
226       memcpy(pBE, &v, sizeof(int64_t));
227    } else {
228       int i;
229       uint8_t rv[sizeof(int64_t)];
230       uint8_t *pv = (uint8_t *) &v;
231 
232       for (i = 0; i < 8; i++) {
233          rv[i] = pv[7 - i];
234       }
235       memcpy(pBE, &rv, sizeof(int64_t));
236    }
237 }
238 
239 /**
240  *  Convert a 32 bit little endian to a big endian
241  */
int32_LE2BE(int32_t * pBE,const int32_t v)242 void int32_LE2BE(int32_t* pBE, const int32_t v)
243 {
244    /* convert little endian to big endian */
245    if (htonl(1) != 1L) { /* no work if on little endian machine */
246       memcpy(pBE, &v, sizeof(int32_t));
247    } else {
248       int i;
249       uint8_t rv[sizeof(int32_t)];
250       uint8_t *pv = (uint8_t *) &v;
251 
252       for (i = 0; i < 4; i++) {
253          rv[i] = pv[3 - i];
254       }
255       memcpy(pBE, &rv, sizeof(int32_t));
256    }
257 }
258 
259 
260 /**
261  *  Read a BackupRead block and pull out the file data
262  */
processWin32BackupAPIBlock(BFILE * bfd,void * pBuffer,ssize_t dwSize)263 bool processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, ssize_t dwSize)
264 {
265    int64_t len = dwSize;
266    char *dat=(char *)pBuffer;
267    int64_t use_len;
268 
269    while (len>0 && bfd->win32filter.have_data(&dat, &len, &use_len)) {
270       if (bwrite(bfd, dat, use_len) != (ssize_t)use_len) {
271          return false;
272       }
273       dat+=use_len;
274    }
275    return true;
276 }
277 
278 /* ===============================================================
279  *
280  *            W I N D O W S
281  *
282  * ===============================================================
283  */
284 
285 #if defined(HAVE_WIN32)
286 
287 void unix_name_to_win32(POOLMEM **win32_name, const char *name);
288 extern "C" HANDLE get_osfhandle(int fd);
289 
290 
binit(BFILE * bfd)291 void binit(BFILE *bfd)
292 {
293    memset((void *)bfd, 0, sizeof(BFILE));
294    bfd->fid = -1;
295    bfd->mode = BF_CLOSED;
296    bfd->use_backup_api = have_win32_api();
297    bfd->cmd_plugin = false;
298 }
299 
300 /*
301  * Enables using the Backup API (win32_data).
302  *   Returns 1 if function worked
303  *   Returns 0 if failed (i.e. do not have Backup API on this machine)
304  */
set_win32_backup(BFILE * bfd)305 bool set_win32_backup(BFILE *bfd)
306 {
307    /* We enable if possible here */
308    bfd->use_backup_api = have_win32_api();
309    return bfd->use_backup_api;
310 }
311 
set_fattrs(BFILE * bfd,struct stat * statp)312 void set_fattrs(BFILE *bfd, struct stat *statp)
313 {
314    bfd->fattrs = statp->st_fattrs;
315    Dmsg1(200, "set_fattrs 0x%x\n", bfd->fattrs);
316 }
317 
set_portable_backup(BFILE * bfd)318 bool set_portable_backup(BFILE *bfd)
319 {
320    bfd->use_backup_api = false;
321    return true;
322 }
323 
set_cmd_plugin(BFILE * bfd,JCR * jcr)324 bool set_cmd_plugin(BFILE *bfd, JCR *jcr)
325 {
326    bfd->cmd_plugin = true;
327    bfd->jcr = jcr;
328    return true;
329 }
330 
331 /*
332  * Return 1 if we are NOT using Win32 BackupWrite()
333  * return 0 if are
334  */
is_portable_backup(BFILE * bfd)335 bool is_portable_backup(BFILE *bfd)
336 {
337    return !bfd->use_backup_api;
338 }
339 
is_plugin_data(BFILE * bfd)340 bool is_plugin_data(BFILE *bfd)
341 {
342    return bfd->cmd_plugin;
343 }
344 
have_win32_api()345 bool have_win32_api()
346 {
347    return p_BackupRead && p_BackupWrite;
348 }
349 
350 
351 /*
352  * Return true  if we support the stream
353  *        false if we do not support the stream
354  *
355  *  This code is running under Win32, so we
356  *    do not need #ifdef on MACOS ...
357  */
is_restore_stream_supported(int stream)358 bool is_restore_stream_supported(int stream)
359 {
360    switch (stream) {
361 
362 /* Streams known not to be supported */
363 #ifndef HAVE_LIBZ
364    case STREAM_GZIP_DATA:
365    case STREAM_SPARSE_GZIP_DATA:
366    case STREAM_WIN32_GZIP_DATA:
367 #endif
368 #ifndef HAVE_LZO
369    case STREAM_COMPRESSED_DATA:
370    case STREAM_SPARSE_COMPRESSED_DATA:
371    case STREAM_WIN32_COMPRESSED_DATA:
372    case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
373    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
374 #endif
375    case STREAM_MACOS_FORK_DATA:
376    case STREAM_HFSPLUS_ATTRIBUTES:
377    case STREAM_ENCRYPTED_MACOS_FORK_DATA:
378       return false;
379 
380    /* Known streams */
381 #ifdef HAVE_LIBZ
382    case STREAM_GZIP_DATA:
383    case STREAM_SPARSE_GZIP_DATA:
384    case STREAM_WIN32_GZIP_DATA:
385 #endif
386 #ifdef HAVE_LZO
387    case STREAM_COMPRESSED_DATA:
388    case STREAM_SPARSE_COMPRESSED_DATA:
389    case STREAM_WIN32_COMPRESSED_DATA:
390 #endif
391    case STREAM_WIN32_DATA:
392    case STREAM_UNIX_ATTRIBUTES:
393    case STREAM_FILE_DATA:
394    case STREAM_MD5_DIGEST:
395    case STREAM_UNIX_ATTRIBUTES_EX:
396    case STREAM_SPARSE_DATA:
397    case STREAM_PROGRAM_NAMES:
398    case STREAM_PROGRAM_DATA:
399    case STREAM_SHA1_DIGEST:
400 #ifdef HAVE_SHA2
401    case STREAM_SHA256_DIGEST:
402    case STREAM_SHA512_DIGEST:
403 #endif
404 #ifdef HAVE_CRYPTO
405    case STREAM_SIGNED_DIGEST:
406    case STREAM_ENCRYPTED_FILE_DATA:
407    case STREAM_ENCRYPTED_FILE_GZIP_DATA:
408    case STREAM_ENCRYPTED_WIN32_DATA:
409    case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
410 #ifdef HAVE_LZO
411    case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
412    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
413 #endif
414 #endif     /* !HAVE_CRYPTO */
415    case 0:                            /* compatibility with old tapes */
416       return true;
417    }
418    return false;
419 }
420 
bget_handle(BFILE * bfd)421 HANDLE bget_handle(BFILE *bfd)
422 {
423    return bfd->fh;
424 }
425 
426 /*
427  * The following code was contributed by Graham Keeling from his
428  *  burp project.  August 2014
429  */
encrypt_bopen(BFILE * bfd,const char * fname,uint64_t flags,mode_t mode)430 static int encrypt_bopen(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
431 {
432    ULONG ulFlags = 0;
433    POOLMEM *win32_fname;
434    POOLMEM *win32_fname_wchar;
435 
436    bfd->mode = BF_CLOSED;
437    bfd->fid = -1;
438 
439    if (!(p_OpenEncryptedFileRawA || p_OpenEncryptedFileRawW)) {
440       Dmsg0(50, "No OpenEncryptedFileRawA and no OpenEncryptedFileRawW APIs!!!\n");
441       return -1;
442    }
443 
444    /* Convert to Windows path format */
445    win32_fname = get_pool_memory(PM_FNAME);
446    win32_fname_wchar = get_pool_memory(PM_FNAME);
447 
448    unix_name_to_win32(&win32_fname, (char *)fname);
449 
450    if (p_CreateFileW && p_MultiByteToWideChar) {
451       make_win32_path_UTF8_2_wchar(&win32_fname_wchar, fname);
452    }
453 
454    if ((flags & O_CREAT) || (flags & O_WRONLY)) {
455       ulFlags = CREATE_FOR_IMPORT | OVERWRITE_HIDDEN;
456       if (bfd->fattrs & FILE_ATTRIBUTE_DIRECTORY) {
457          mkdir(fname, 0777);
458          ulFlags |= CREATE_FOR_DIR;
459       }
460       bfd->mode = BF_WRITE;
461       Dmsg0(200, "encrypt_bopen for write.\n");
462    } else {
463       /* Open existing for read */
464       ulFlags = CREATE_FOR_EXPORT;
465       bfd->mode = BF_READ;
466       Dmsg0(200, "encrypt_bopen for read.\n");
467    }
468 
469    if (p_OpenEncryptedFileRawW && p_MultiByteToWideChar) {
470       /* unicode open */
471       if (p_OpenEncryptedFileRawW((LPCWSTR)win32_fname_wchar,
472                    ulFlags, &(bfd->pvContext))) {
473          bfd->mode = BF_CLOSED;
474          errno = b_errno_win32;
475          bfd->berrno = b_errno_win32;
476       }
477    } else {
478       /* ascii open */
479       if (p_OpenEncryptedFileRawA(win32_fname, ulFlags, &(bfd->pvContext))) {
480          bfd->mode = BF_CLOSED;
481          errno = b_errno_win32;
482          bfd->berrno = b_errno_win32;
483       }
484    }
485    free_pool_memory(win32_fname_wchar);
486    free_pool_memory(win32_fname);
487    bfd->fid = (bfd->mode == BF_CLOSED) ? -1 : 0;
488    return bfd->mode==BF_CLOSED ? -1: 1;
489 }
490 
encrypt_bclose(BFILE * bfd)491 static int encrypt_bclose(BFILE *bfd)
492 {
493    Dmsg0(200, "encrypt_bclose\n");
494    if (p_CloseEncryptedFileRaw) {
495       p_CloseEncryptedFileRaw(bfd->pvContext);
496    }
497    bfd->pvContext = NULL;
498    bfd->mode = BF_CLOSED;
499    bfd->fattrs = 0;
500    bfd->fid = -1;
501    return 0;
502 }
503 
504 /* Windows */
bopen(BFILE * bfd,const char * fname,uint64_t flags,mode_t mode)505 int bopen(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
506 {
507    POOLMEM *win32_fname_wchar;
508 
509    DWORD dwaccess, dwflags, dwshare;
510 
511    if (bfd->fattrs & FILE_ATTRIBUTE_ENCRYPTED) {
512       return encrypt_bopen(bfd, fname, flags, mode);
513    }
514 
515    /* Convert to Windows path format */
516    win32_fname_wchar = get_pool_memory(PM_FNAME);
517 
518    if (bfd->cmd_plugin && plugin_bopen) {
519       int rtnstat;
520       Dmsg1(50, "call plugin_bopen fname=%s\n", fname);
521       rtnstat = plugin_bopen(bfd, fname, flags, mode);
522       Dmsg1(50, "return from plugin_bopen status=%d\n", rtnstat);
523       if (rtnstat >= 0) {
524          if (flags & O_CREAT || flags & O_WRONLY) {   /* Open existing for write */
525             Dmsg1(50, "plugin_open for write OK file=%s.\n", fname);
526             bfd->mode = BF_WRITE;
527          } else {
528             Dmsg1(50, "plugin_open for read OK file=%s.\n", fname);
529             bfd->mode = BF_READ;
530          }
531          bfd->fid = -1;         /* The file descriptor is invalid */
532       } else {
533          bfd->mode = BF_CLOSED;
534          bfd->fid = -1;
535          Dmsg1(10, "==== plugin_bopen returned bad status=%d\n", rtnstat);
536       }
537       free_pool_memory(win32_fname_wchar);
538       return bfd->mode == BF_CLOSED ? -1 : 1;
539    }
540    Dmsg0(100, "=== NO plugin\n");
541 
542    if (!(p_CreateFileA || p_CreateFileW)) {
543       Dmsg0(50, "No CreateFileA and no CreateFileW!!!!!\n");
544       return 0;
545    }
546 
547    if (p_CreateFileW && p_MultiByteToWideChar) {
548       make_win32_path_UTF8_2_wchar(&win32_fname_wchar, fname);
549    }
550 
551    if (flags & O_CREAT) {             /* Create */
552       if (bfd->use_backup_api) {
553          dwaccess = GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
554          dwflags = FILE_FLAG_BACKUP_SEMANTICS;
555       } else {
556          dwaccess = GENERIC_WRITE;
557          dwflags = 0;
558       }
559 
560       // unicode open for create write
561       Dmsg1(100, "Create CreateFileW=%ls\n", win32_fname_wchar);
562       bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
563              dwaccess,                /* Requested access */
564              0,                       /* Shared mode */
565              NULL,                    /* SecurityAttributes */
566              CREATE_ALWAYS,           /* CreationDisposition */
567              dwflags,                 /* Flags and attributes */
568              NULL);                   /* TemplateFile */
569 
570       bfd->mode = BF_WRITE;
571 
572    } else if (flags & O_WRONLY) {     /* Open existing for write */
573       if (bfd->use_backup_api) {
574          dwaccess = GENERIC_READ|GENERIC_WRITE|WRITE_OWNER|WRITE_DAC;
575 
576          if (bfd->fattrs & FILE_ATTRIBUTE_DIRECTORY) {
577             /* Avoid issues with directories
578              * ERR=The process cannot access the file because it is being used by another
579              */
580             dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
581          } else {
582             dwshare = 0;
583          }
584          /* If deduped, we do not want to open the reparse point */
585          if (bfd->fattrs & FILE_ATTRIBUTE_DEDUP) { /* Maybe check for bfd->reparse_point */
586             dwflags = FILE_FLAG_BACKUP_SEMANTICS;
587          } else {
588             dwflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT;
589          }
590       } else {
591          dwaccess = GENERIC_READ|GENERIC_WRITE;
592          dwflags = 0;
593          dwshare = 0;
594       }
595 
596       // unicode open for open existing write
597       Dmsg1(100, "Write only CreateFileW=%ls\n", win32_fname_wchar);
598       bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
599              dwaccess,                /* Requested access */
600              dwshare,                 /* Shared mode */
601              NULL,                    /* SecurityAttributes */
602              OPEN_EXISTING,           /* CreationDisposition */
603              dwflags,                 /* Flags and attributes */
604              NULL);                   /* TemplateFile */
605 
606       bfd->mode = BF_WRITE;
607 
608    } else {                           /* Read */
609       if (bfd->use_backup_api) {
610          dwaccess = GENERIC_READ|READ_CONTROL|ACCESS_SYSTEM_SECURITY;
611          dwflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_SEQUENTIAL_SCAN |
612                    FILE_FLAG_OPEN_REPARSE_POINT;
613          dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
614       } else {
615          dwaccess = GENERIC_READ;
616          dwflags = 0;
617          dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE;
618       }
619 
620       // unicode open for open existing read
621       Dmsg1(100, "Read CreateFileW=%ls\n", win32_fname_wchar);
622       bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
623              dwaccess,                /* Requested access */
624              dwshare,                 /* Share modes */
625              NULL,                    /* SecurityAttributes */
626              OPEN_EXISTING,           /* CreationDisposition */
627              dwflags,                 /* Flags and attributes */
628              NULL);                   /* TemplateFile */
629 
630       bfd->mode = BF_READ;
631    }
632 
633    if (bfd->fh == INVALID_HANDLE_VALUE) {
634       berrno be;
635       bfd->lerror = GetLastError();
636       bfd->berrno = b_errno_win32;
637       errno = b_errno_win32;
638       bfd->mode = BF_CLOSED;
639       Dmsg1(100, "Open failed: %s\n", be.bstrerror());
640    }
641    bfd->block = 0;
642    bfd->total_bytes = 0;
643    bfd->errmsg = NULL;
644    bfd->lpContext = NULL;
645    bfd->win32filter.init();
646    free_pool_memory(win32_fname_wchar);
647    bfd->fid = (bfd->mode == BF_CLOSED) ? -1 : 0;
648    return bfd->mode == BF_CLOSED ? -1 : 1;
649 }
650 
651 /*
652  * Returns  0 on success
653  *         -1 on error
654  */
655 /* Windows */
bclose(BFILE * bfd)656 int bclose(BFILE *bfd)
657 {
658    int stat = 0;
659 
660    if (bfd->mode == BF_CLOSED) {
661       Dmsg0(50, "=== BFD already closed.\n");
662       return 0;
663    }
664 
665    if (bfd->cmd_plugin && plugin_bclose) {
666       stat = plugin_bclose(bfd);
667       Dmsg0(50, "==== BFD closed!!!\n");
668       goto all_done;
669    }
670 
671    if (bfd->fattrs & FILE_ATTRIBUTE_ENCRYPTED) {
672       return encrypt_bclose(bfd);
673    }
674 
675    /*
676     * We need to tell the API to release the buffer it
677     *  allocated in lpContext.  We do so by calling the
678     *  API one more time, but with the Abort bit set.
679     */
680    if (bfd->use_backup_api && bfd->mode == BF_READ) {
681       BYTE buf[10];
682       if (bfd->lpContext && !p_BackupRead(bfd->fh,
683               buf,                    /* buffer */
684               (DWORD)0,               /* bytes to read */
685               &bfd->rw_bytes,         /* bytes read */
686               1,                      /* Abort */
687               1,                      /* ProcessSecurity */
688               &bfd->lpContext)) {     /* Read context */
689          errno = b_errno_win32;
690          stat = -1;
691       }
692    } else if (bfd->use_backup_api && bfd->mode == BF_WRITE) {
693       BYTE buf[10];
694       if (bfd->lpContext && !p_BackupWrite(bfd->fh,
695               buf,                    /* buffer */
696               (DWORD)0,               /* bytes to read */
697               &bfd->rw_bytes,         /* bytes written */
698               1,                      /* Abort */
699               1,                      /* ProcessSecurity */
700               &bfd->lpContext)) {     /* Write context */
701          errno = b_errno_win32;
702          stat = -1;
703       }
704    }
705    if (!CloseHandle(bfd->fh)) {
706       stat = -1;
707       errno = b_errno_win32;
708    }
709 
710 all_done:
711    if (bfd->errmsg) {
712       free_pool_memory(bfd->errmsg);
713       bfd->errmsg = NULL;
714    }
715    bfd->mode = BF_CLOSED;
716    bfd->fattrs = 0;
717    bfd->fid = -1;
718    bfd->lpContext = NULL;
719    bfd->cmd_plugin = false;
720    return stat;
721 }
722 
723 /* Returns: bytes read on success
724  *           0         on EOF
725  *          -1         on error
726  */
727 /* Windows */
bread(BFILE * bfd,void * buf,size_t count)728 ssize_t bread(BFILE *bfd, void *buf, size_t count)
729 {
730    bfd->rw_bytes = 0;
731 
732    if (bfd->cmd_plugin && plugin_bread) {
733       return plugin_bread(bfd, buf, count);
734    }
735 
736    if (bfd->use_backup_api) {
737       if (!p_BackupRead(bfd->fh,
738            (BYTE *)buf,
739            count,
740            &bfd->rw_bytes,
741            0,                           /* no Abort */
742            1,                           /* Process Security */
743            &bfd->lpContext)) {          /* Context */
744          berrno be;
745          bfd->lerror = GetLastError();
746          bfd->berrno = b_errno_win32;
747          errno = b_errno_win32;
748          Dmsg1(100, "Read failed: %s\n", be.bstrerror());
749          return -1;
750       }
751    } else {
752       if (!ReadFile(bfd->fh,
753            buf,
754            count,
755            &bfd->rw_bytes,
756            NULL)) {
757          bfd->lerror = GetLastError();
758          bfd->berrno = b_errno_win32;
759          errno = b_errno_win32;
760          return -1;
761       }
762    }
763    bfd->block++;
764    if (bfd->rw_bytes > 0) {
765       bfd->total_bytes += bfd->rw_bytes;
766    }
767    return (ssize_t)bfd->rw_bytes;
768 }
769 
770 /* Windows */
bwrite(BFILE * bfd,void * buf,size_t count)771 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
772 {
773    bfd->rw_bytes = 0;
774 
775    if (bfd->cmd_plugin && plugin_bwrite) {
776       return plugin_bwrite(bfd, buf, count);
777    }
778 
779    if (bfd->use_backup_api) {
780       if (!p_BackupWrite(bfd->fh,
781            (BYTE *)buf,
782            count,
783            &bfd->rw_bytes,
784            0,                           /* No abort */
785            1,                           /* Process Security */
786            &bfd->lpContext)) {          /* Context */
787          berrno be;
788          bfd->lerror = GetLastError();
789          bfd->berrno = b_errno_win32;
790          errno = b_errno_win32;
791          Dmsg1(100, "Write failed: %s\n", be.bstrerror());
792          return -1;
793       }
794    } else {
795       if (!WriteFile(bfd->fh,
796            buf,
797            count,
798            &bfd->rw_bytes,
799            NULL)) {
800          bfd->lerror = GetLastError();
801          bfd->berrno = b_errno_win32;
802          errno = b_errno_win32;
803          return -1;
804       }
805    }
806    bfd->block++;
807    if (bfd->rw_bytes > 0) {
808       bfd->total_bytes += bfd->rw_bytes;
809    }
810    return (ssize_t)bfd->rw_bytes;
811 }
812 
813 /* Windows */
is_bopen(BFILE * bfd)814 bool is_bopen(BFILE *bfd)
815 {
816    return bfd->mode != BF_CLOSED;
817 }
818 
819 /* Windows */
blseek(BFILE * bfd,boffset_t offset,int whence)820 boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
821 {
822    LONG  offset_low = (LONG)offset;
823    LONG  offset_high = (LONG)(offset >> 32);
824    DWORD dwResult;
825 
826    if (bfd->cmd_plugin && plugin_blseek) {
827       return plugin_blseek(bfd, offset, whence);
828    }
829 
830    dwResult = SetFilePointer(bfd->fh, offset_low, &offset_high, whence);
831 
832    if (dwResult == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
833       return (boffset_t)-1;
834    }
835 
836    return ((boffset_t)offset_high << 32) | dwResult;
837 }
838 
839 #else  /* Unix systems */
840 
841 /* ===============================================================
842  *
843  *            U N I X
844  *
845  * ===============================================================
846  */
847 /* Unix */
binit(BFILE * bfd)848 void binit(BFILE *bfd)
849 {
850    bmemset(bfd, 0, sizeof(BFILE));
851    bfd->fid = -1;
852 }
853 
854 /* Unix */
have_win32_api()855 bool have_win32_api()
856 {
857    return false;                       /* no can do */
858 }
859 
860 /*
861  * Enables using the Backup API (win32_data).
862  *   Returns true  if function worked
863  *   Returns false if failed (i.e. do not have Backup API on this machine)
864  */
865 /* Unix */
set_win32_backup(BFILE * bfd)866 bool set_win32_backup(BFILE *bfd)
867 {
868    return false;                       /* no can do */
869 }
870 
871 
872 /* Unix */
set_portable_backup(BFILE * bfd)873 bool set_portable_backup(BFILE *bfd)
874 {
875    return true;                        /* no problem */
876 }
877 
is_plugin_data(BFILE * bfd)878 bool is_plugin_data(BFILE *bfd)
879 {
880    return bfd->cmd_plugin;
881 }
882 
883 /*
884  * Return true  if we are writing in portable format
885  * return false if not
886  */
887 /* Unix */
is_portable_backup(BFILE * bfd)888 bool is_portable_backup(BFILE *bfd)
889 {
890    return true;                       /* portable by definition */
891 }
892 
893 /* Unix */
set_prog(BFILE * bfd,char * prog,JCR * jcr)894 bool set_prog(BFILE *bfd, char *prog, JCR *jcr)
895 {
896    return false;
897 }
898 
899 /* Unix */
set_cmd_plugin(BFILE * bfd,JCR * jcr)900 bool set_cmd_plugin(BFILE *bfd, JCR *jcr)
901 {
902    bfd->cmd_plugin = true;
903    bfd->jcr = jcr;
904    return true;
905 }
906 
907 /*
908  * This code is running on a non-Win32 machine
909  */
910 /* Unix */
is_restore_stream_supported(int stream)911 bool is_restore_stream_supported(int stream)
912 {
913    /* No Win32 backup on this machine */
914      switch (stream) {
915 #ifndef HAVE_LIBZ
916    case STREAM_GZIP_DATA:
917    case STREAM_SPARSE_GZIP_DATA:
918    case STREAM_WIN32_GZIP_DATA:
919 #endif
920 #ifndef HAVE_LZO
921    case STREAM_COMPRESSED_DATA:
922    case STREAM_SPARSE_COMPRESSED_DATA:
923    case STREAM_WIN32_COMPRESSED_DATA:
924    case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
925    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
926 #endif
927 #ifndef HAVE_DARWIN_OS
928    case STREAM_MACOS_FORK_DATA:
929    case STREAM_HFSPLUS_ATTRIBUTES:
930 #endif
931       return false;
932 
933    /* Known streams */
934 #ifdef HAVE_LIBZ
935    case STREAM_GZIP_DATA:
936    case STREAM_SPARSE_GZIP_DATA:
937    case STREAM_WIN32_GZIP_DATA:
938 #endif
939 #ifdef HAVE_LZO
940    case STREAM_COMPRESSED_DATA:
941    case STREAM_SPARSE_COMPRESSED_DATA:
942    case STREAM_WIN32_COMPRESSED_DATA:
943    case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
944    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
945 #endif
946    case STREAM_WIN32_DATA:
947    case STREAM_UNIX_ATTRIBUTES:
948    case STREAM_FILE_DATA:
949    case STREAM_MD5_DIGEST:
950    case STREAM_UNIX_ATTRIBUTES_EX:
951    case STREAM_SPARSE_DATA:
952    case STREAM_PROGRAM_NAMES:
953    case STREAM_PROGRAM_DATA:
954    case STREAM_SHA1_DIGEST:
955 #ifdef HAVE_SHA2
956    case STREAM_SHA256_DIGEST:
957    case STREAM_SHA512_DIGEST:
958 #endif
959 #ifdef HAVE_CRYPTO
960    case STREAM_SIGNED_DIGEST:
961    case STREAM_ENCRYPTED_FILE_DATA:
962    case STREAM_ENCRYPTED_FILE_GZIP_DATA:
963    case STREAM_ENCRYPTED_WIN32_DATA:
964    case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
965 #endif
966 #ifdef HAVE_DARWIN_OS
967    case STREAM_MACOS_FORK_DATA:
968    case STREAM_HFSPLUS_ATTRIBUTES:
969 #ifdef HAVE_CRYPTO
970    case STREAM_ENCRYPTED_MACOS_FORK_DATA:
971 #endif /* HAVE_CRYPTO */
972 #endif /* HAVE_DARWIN_OS */
973    case 0:   /* compatibility with old tapes */
974       return true;
975 
976    }
977    return false;
978 }
979 
980 /* Unix */
bopen(BFILE * bfd,const char * fname,uint64_t flags,mode_t mode)981 int bopen(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
982 {
983    if (bfd->cmd_plugin && plugin_bopen) {
984       Dmsg1(400, "call plugin_bopen fname=%s\n", fname);
985       bfd->fid = plugin_bopen(bfd, fname, flags, mode);
986       Dmsg2(400, "Plugin bopen fid=%d file=%s\n", bfd->fid, fname);
987       return bfd->fid;
988    }
989 
990    /* Normal file open */
991    Dmsg1(dbglvl, "open file %s\n", fname);
992 
993    /* We use fnctl to set O_NOATIME if requested to avoid open error */
994    bfd->fid = open(fname, (flags | O_CLOEXEC) & ~O_NOATIME, mode);
995 
996    /* Set O_NOATIME if possible */
997    if (bfd->fid != -1 && flags & O_NOATIME) {
998       int oldflags = fcntl(bfd->fid, F_GETFL, 0);
999       if (oldflags == -1) {
1000          bfd->berrno = errno;
1001          close(bfd->fid);
1002          bfd->fid = -1;
1003       } else {
1004          int ret = fcntl(bfd->fid, F_SETFL, oldflags | O_NOATIME);
1005         /* EPERM means setting O_NOATIME was not allowed  */
1006          if (ret == -1 && errno != EPERM) {
1007             bfd->berrno = errno;
1008             close(bfd->fid);
1009             bfd->fid = -1;
1010          }
1011       }
1012    }
1013    bfd->berrno = errno;
1014    bfd->m_flags = flags;
1015    bfd->block = 0;
1016    bfd->total_bytes = 0;
1017    Dmsg1(400, "Open file %d\n", bfd->fid);
1018    errno = bfd->berrno;
1019 
1020    bfd->win32filter.init();
1021 
1022 #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1023    /* If not RDWR or WRONLY must be Read Only */
1024    if (bfd->fid != -1 && !(flags & (O_RDWR|O_WRONLY))) {
1025       int stat = posix_fadvise(bfd->fid, 0, 0, POSIX_FADV_WILLNEED);
1026       Dmsg3(400, "Did posix_fadvise WILLNEED on %s fid=%d stat=%d\n", fname, bfd->fid, stat);
1027    }
1028 #endif
1029 
1030    return bfd->fid;
1031 }
1032 
1033 #ifdef HAVE_DARWIN_OS
1034 /* Open the resource fork of a file. */
bopen_rsrc(BFILE * bfd,const char * fname,uint64_t flags,mode_t mode)1035 int bopen_rsrc(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
1036 {
1037    POOLMEM *rsrc_fname;
1038 
1039    rsrc_fname = get_pool_memory(PM_FNAME);
1040    pm_strcpy(rsrc_fname, fname);
1041    pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
1042    bopen(bfd, rsrc_fname, flags, mode);
1043    free_pool_memory(rsrc_fname);
1044    return bfd->fid;
1045 }
1046 #else /* Unix */
1047 
1048 /* Unix */
bopen_rsrc(BFILE * bfd,const char * fname,uint64_t flags,mode_t mode)1049 int bopen_rsrc(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
1050     { return -1; }
1051 
1052 #endif
1053 
1054 
1055 /* Unix */
bclose(BFILE * bfd)1056 int bclose(BFILE *bfd)
1057 {
1058    int stat;
1059 
1060    Dmsg2(400, "Close bfd=%p file %d\n", bfd, bfd->fid);
1061 
1062    if (bfd->fid == -1) {
1063       return 0;
1064    }
1065    if (bfd->cmd_plugin && plugin_bclose) {
1066       stat = plugin_bclose(bfd);
1067       bfd->fid = -1;
1068       bfd->cmd_plugin = false;
1069    }
1070 
1071 #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
1072    /* If not RDWR or WRONLY must be Read Only */
1073    if (!(bfd->m_flags & (O_RDWR|O_WRONLY))) {
1074       fdatasync(bfd->fid);            /* sync the file */
1075       /* Tell OS we don't need it any more */
1076       posix_fadvise(bfd->fid, 0, 0, POSIX_FADV_DONTNEED);
1077       Dmsg1(400, "Did posix_fadvise DONTNEED on fid=%d\n", bfd->fid);
1078    }
1079 #endif
1080 
1081    /* Close normal file */
1082    stat = close(bfd->fid);
1083    bfd->berrno = errno;
1084    bfd->fid = -1;
1085    bfd->cmd_plugin = false;
1086    return stat;
1087 }
1088 
1089 /* Unix */
bread(BFILE * bfd,void * buf,size_t count)1090 ssize_t bread(BFILE *bfd, void *buf, size_t count)
1091 {
1092    ssize_t stat;
1093 
1094    if (bfd->cmd_plugin && plugin_bread) {
1095       return plugin_bread(bfd, buf, count);
1096    }
1097 
1098    stat = read(bfd->fid, buf, count);
1099    bfd->berrno = errno;
1100    bfd->block++;
1101    if (stat > 0) {
1102       bfd->total_bytes += stat;
1103    }
1104    return stat;
1105 }
1106 
1107 /* Unix */
bwrite(BFILE * bfd,void * buf,size_t count)1108 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
1109 {
1110    ssize_t stat;
1111 
1112    if (bfd->cmd_plugin && plugin_bwrite) {
1113       return plugin_bwrite(bfd, buf, count);
1114    }
1115    stat = write(bfd->fid, buf, count);
1116    bfd->berrno = errno;
1117    bfd->block++;
1118    if (stat > 0) {
1119       bfd->total_bytes += stat;
1120    }
1121    return stat;
1122 }
1123 
1124 /* Unix */
is_bopen(BFILE * bfd)1125 bool is_bopen(BFILE *bfd)
1126 {
1127    return bfd->fid >= 0;
1128 }
1129 
1130 /* Unix */
blseek(BFILE * bfd,boffset_t offset,int whence)1131 boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
1132 {
1133    boffset_t pos;
1134 
1135    if (bfd->cmd_plugin && plugin_bwrite) {
1136       return plugin_blseek(bfd, offset, whence);
1137    }
1138    pos = (boffset_t)lseek(bfd->fid, offset, whence);
1139    bfd->berrno = errno;
1140    return pos;
1141 }
1142 
1143 #endif
1144