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  *  Create a file, and reset the modes
21  *
22  *    Kern Sibbald, November MM
23  *
24  */
25 
26 #include "bacula.h"
27 #include "find.h"
28 
29 #ifndef S_IRWXUGO
30 #define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
31 #endif
32 
33 #ifndef IS_CTG
34 #define IS_CTG(x) 0
35 #define O_CTG 0
36 #endif
37 
38 #ifndef O_EXCL
39 #define O_EXCL 0
40 #endif
41 #ifndef O_NOFOLLOW
42 #define O_NOFOLLOW 0
43 #endif
44 
45 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile);
46 static int path_already_seen(JCR *jcr, char *path, int pnl);
47 
48 
49 /*
50  * Create the file, or the directory
51  *
52  *  fname is the original filename
53  *  ofile is the output filename (may be in a different directory)
54  *
55  * Returns:  CF_SKIP     if file should be skipped
56  *           CF_ERROR    on error
57  *           CF_EXTRACT  file created and data to restore
58  *           CF_CREATED  file created no data to restore
59  *
60  *   Note, we create the file here, except for special files,
61  *     we do not set the attributes because we want to first
62  *     write the file, then when the writing is done, set the
63  *     attributes.
64  *   So, we return with the file descriptor open for normal
65  *     files.
66  *
67  */
create_file(JCR * jcr,ATTR * attr,BFILE * bfd,int replace)68 int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
69 {
70    mode_t new_mode, parent_mode;
71    int flags;
72    uid_t uid;
73    gid_t gid;
74    int pnl;
75    bool exists = false;
76    struct stat mstatp;
77 
78    bfd->reparse_point = false;
79    if (is_win32_stream(attr->data_stream)) {
80       set_win32_backup(bfd);
81    } else {
82       set_portable_backup(bfd);
83    }
84 
85    new_mode = attr->statp.st_mode;
86    Dmsg3(200, "type=%d newmode=%x file=%s\n", attr->type, new_mode, attr->ofname);
87    parent_mode = S_IWUSR | S_IXUSR | new_mode;
88    gid = attr->statp.st_gid;
89    uid = attr->statp.st_uid;
90 
91 #ifdef HAVE_WIN32
92    if (!bfd->use_backup_api) {
93       // eliminate invalid windows filename characters from foreign filenames
94       char *ch = (char *)attr->ofname;
95       if (ch[0] != 0 && ch[1] != 0) {
96          ch += 2;
97          while (*ch) {
98             switch (*ch) {
99             case ':':
100             case '<':
101             case '>':
102             case '*':
103             case '?':
104             case '|':
105                *ch = '_';
106                 break;
107             }
108             ch++;
109          }
110       }
111    }
112 #endif
113 
114    Dmsg2(400, "Replace=%c %d\n", (char)replace, replace);
115    if (lstat(attr->ofname, &mstatp) == 0) {
116       exists = true;
117       switch (replace) {
118       case REPLACE_IFNEWER:
119          /* Set attributes if we created this directory */
120          if (attr->type == FT_DIREND && path_list_lookup(jcr, attr->ofname)) {
121             break;
122          }
123 
124          if (attr->statp.st_mtime <= mstatp.st_mtime) {
125             Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
126             return CF_SKIP;
127          }
128          break;
129 
130       case REPLACE_IFOLDER:
131          if (attr->statp.st_mtime >= mstatp.st_mtime) {
132             Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname);
133             return CF_SKIP;
134          }
135          break;
136 
137       case REPLACE_NEVER:
138          /* Set attributes if we created this directory */
139          if (attr->type == FT_DIREND && path_list_lookup(jcr, attr->ofname)) {
140             break;
141          }
142          Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
143          return CF_SKIP;
144 
145       case REPLACE_ALWAYS:
146          break;
147       }
148    }
149    switch (attr->type) {
150    case FT_RAW:                       /* raw device to be written */
151    case FT_FIFO:                      /* FIFO to be written to */
152    case FT_LNKSAVED:                  /* Hard linked, file already saved */
153    case FT_LNK:
154    case FT_SPEC:                      /* fifo, ... to be backed up */
155    case FT_REGE:                      /* empty file */
156    case FT_REG:                       /* regular file */
157       /*
158        * Note, we do not delete FT_RAW because these are device files
159        *  or FIFOs that should already exist. If we blow it away,
160        *  we may blow away a FIFO that is being used to read the
161        *  restore data, or we may blow away a partition definition.
162        */
163       if (exists && attr->type != FT_RAW && attr->type != FT_FIFO) {
164          /* Get rid of old copy */
165          Dmsg1(400, "unlink %s\n", attr->ofname);
166          if (unlink(attr->ofname) == -1) {
167             berrno be;
168             Qmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"),
169                attr->ofname, be.bstrerror());
170             return CF_ERROR;
171          }
172       }
173       /*
174        * Here we do some preliminary work for all the above
175        *   types to create the path to the file if it does
176        *   not already exist.  Below, we will split to
177        *   do the file type specific work
178        */
179       pnl = separate_path_and_file(jcr, attr->fname, attr->ofname);
180       if (pnl < 0) {
181          return CF_ERROR;
182       }
183 
184       /*
185        * If path length is <= 0 we are making a file in the root
186        *  directory. Assume that the directory already exists.
187        */
188       if (pnl > 0) {
189          char savechr;
190          savechr = attr->ofname[pnl];
191          attr->ofname[pnl] = 0;                 /* terminate path */
192 
193          if (!path_already_seen(jcr, attr->ofname, pnl)) {
194             Dmsg1(400, "Make path %s\n", attr->ofname);
195             /*
196              * If we need to make the directory, ensure that it is with
197              * execute bit set (i.e. parent_mode), and preserve what already
198              * exists. Normally, this should do nothing.
199              */
200             if (!makepath(attr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) {
201                Dmsg1(10, "Could not make path. %s\n", attr->ofname);
202                attr->ofname[pnl] = savechr;     /* restore full name */
203                return CF_ERROR;
204             }
205          }
206          attr->ofname[pnl] = savechr;           /* restore full name */
207       }
208 
209       /* Now we do the specific work for each file type */
210       switch(attr->type) {
211       case FT_REGE:
212       case FT_REG:
213          Dmsg1(100, "Create=%s\n", attr->ofname);
214          flags =  O_WRONLY | O_CREAT | O_BINARY | O_EXCL;
215          if (IS_CTG(attr->statp.st_mode)) {
216             flags |= O_CTG;              /* set contiguous bit if needed */
217          }
218          if (is_bopen(bfd)) {
219             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
220             bclose(bfd);
221          }
222 
223          set_fattrs(bfd, &attr->statp);
224          if ((bopen(bfd, attr->ofname, flags, S_IRUSR | S_IWUSR)) < 0) {
225             berrno be;
226             be.set_errno(bfd->berrno);
227             Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"),
228                   attr->ofname, be.bstrerror());
229             Dmsg2(100,"Could not create %s: ERR=%s\n", attr->ofname, be.bstrerror());
230             return CF_ERROR;
231          }
232          return CF_EXTRACT;
233 
234 #ifndef HAVE_WIN32  // none of these exist in MS Windows
235       case FT_RAW:                    /* Bacula raw device e.g. /dev/sda1 */
236       case FT_FIFO:                   /* Bacula fifo to save data */
237       case FT_SPEC:
238          if (S_ISFIFO(attr->statp.st_mode)) {
239             Dmsg1(400, "Restore fifo: %s\n", attr->ofname);
240             if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) {
241                berrno be;
242                Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"),
243                      attr->ofname, be.bstrerror());
244                return CF_ERROR;
245             }
246          } else if (S_ISSOCK(attr->statp.st_mode)) {
247              Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname);
248 #ifdef S_IFDOOR     // Solaris high speed RPC mechanism
249          } else if (S_ISDOOR(attr->statp.st_mode)) {
250              Dmsg1(200, "Skipping restore of door file: %s\n", attr->ofname);
251 #endif
252 #ifdef S_IFPORT     // Solaris event port for handling AIO
253          } else if (S_ISPORT(attr->statp.st_mode)) {
254              Dmsg1(200, "Skipping restore of event port file: %s\n", attr->ofname);
255 #endif
256          } else {
257             Dmsg1(400, "Restore node: %s\n", attr->ofname);
258             if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) {
259                berrno be;
260                Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"),
261                      attr->ofname, be.bstrerror());
262                return CF_ERROR;
263             }
264          }
265          /*
266           * Here we are going to attempt to restore to a FIFO, which
267           *   means that the FIFO must already exist, AND there must
268           *   be some process already attempting to read from the
269           *   FIFO, so we open it write-only.
270           */
271          if (attr->type == FT_RAW || attr->type == FT_FIFO) {
272             btimer_t *tid;
273             Dmsg1(400, "FT_RAW|FT_FIFO %s\n", attr->ofname);
274             flags =  O_WRONLY | O_BINARY;
275             /* Timeout open() in 60 seconds */
276             if (attr->type == FT_FIFO) {
277                Dmsg0(400, "Set FIFO timer\n");
278                tid = start_thread_timer(jcr, pthread_self(), 60);
279             } else {
280                tid = NULL;
281             }
282             if (is_bopen(bfd)) {
283                Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
284             }
285             Dmsg2(400, "open %s flags=0x%x\n", attr->ofname, flags);
286             set_fattrs(bfd, &attr->statp);
287             if ((bopen(bfd, attr->ofname, flags, 0)) < 0) {
288                berrno be;
289                be.set_errno(bfd->berrno);
290                Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
291                      attr->ofname, be.bstrerror());
292                Dmsg2(400, "Could not open %s: ERR=%s\n", attr->ofname, be.bstrerror());
293                stop_thread_timer(tid);
294                return CF_ERROR;
295             }
296             stop_thread_timer(tid);
297             return CF_EXTRACT;
298          }
299          Dmsg1(400, "FT_SPEC %s\n", attr->ofname);
300          return CF_CREATED;
301 
302       case FT_LNK:
303          Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname);
304          if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) {
305             berrno be;
306             Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"),
307                   attr->ofname, attr->olname, be.bstrerror());
308             return CF_ERROR;
309          }
310          return CF_CREATED;
311 
312       case FT_LNKSAVED:                  /* Hard linked, file already saved */
313          Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname);
314          if (link(attr->olname, attr->ofname) != 0) {
315             berrno be;
316 #ifdef HAVE_CHFLAGS
317             struct stat s;
318            /*
319             * If using BSD user flags, maybe has a file flag
320             * preventing this. So attempt to disable, retry link,
321             * and reset flags.
322             * Note that BSD securelevel may prevent disabling flag.
323             */
324             if (stat(attr->olname, &s) == 0 && s.st_flags != 0) {
325                if (chflags(attr->olname, 0) == 0) {
326                   if (link(attr->olname, attr->ofname) != 0) {
327                      /* restore original file flags even when linking failed */
328                      if (chflags(attr->olname, s.st_flags) < 0) {
329                         Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"),
330                               attr->olname, be.bstrerror());
331                      }
332 #endif /* HAVE_CHFLAGS */
333             Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
334                   attr->ofname, attr->olname, be.bstrerror());
335             Dmsg3(200, "Could not hard link %s -> %s: ERR=%s\n",
336                   attr->ofname, attr->olname, be.bstrerror());
337             return CF_ERROR;
338 #ifdef HAVE_CHFLAGS
339                   }
340                   /* finally restore original file flags */
341                   if (chflags(attr->olname, s.st_flags) < 0) {
342                      Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"),
343                             attr->olname, be.bstrerror());
344                   }
345                } else {
346                  Qmsg2(jcr, M_ERROR, 0, _("Could not reset file flags for file %s: ERR=%s\n"),
347                        attr->olname, be.bstrerror());
348                }
349             } else {
350               Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
351                     attr->ofname, attr->olname, be.bstrerror());
352               return CF_ERROR;
353             }
354 #endif /* HAVE_CHFLAGS */
355 
356          }
357          return CF_CREATED;
358 #endif
359       } /* End inner switch */
360 
361    case FT_REPARSE:
362    case FT_JUNCTION:
363       bfd->reparse_point = true;
364       /* Fall through wanted */
365    case FT_DIRBEGIN:
366    case FT_DIREND:
367       Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
368       if (is_win32_stream(attr->data_stream) && attr->statp.st_rdev == WIN32_ROOT_POINT) {
369          /* this is a root directory like C:\ or C:\anymountpoint,
370           * don't restore HIDDEN and SYSTEM attributes
371           */
372          new_mode &= ~S_ISVTX; // remove FILE_ATTRIBUTE_HIDDEN
373          new_mode |= S_IRWXO;  // remove FILE_ATTRIBUTE_SYSTEM
374       }
375       if (!makepath(attr, attr->ofname, new_mode, parent_mode, uid, gid, 0)) {
376          return CF_ERROR;
377       }
378       /*
379        * If we are using the Win32 Backup API, we open the
380        *   directory so that the security info will be read
381        *   and saved.
382        */
383       if (!is_portable_backup(bfd)) {
384          if (is_bopen(bfd)) {
385             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
386          }
387          set_fattrs(bfd, &attr->statp);
388          if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
389             berrno be;
390             be.set_errno(bfd->berrno);
391 #ifdef HAVE_WIN32
392             /* Check for trying to create a drive, if so, skip */
393             if (attr->ofname[1] == ':' &&
394                 IsPathSeparator(attr->ofname[2]) &&
395                 attr->ofname[3] == '\0') {
396                return CF_SKIP;
397             }
398 #endif
399             Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
400                   attr->ofname, be.bstrerror());
401             return CF_ERROR;
402          }
403          return CF_EXTRACT;
404       } else {
405          return CF_CREATED;
406       }
407 
408    case FT_DELETED:
409       Qmsg2(jcr, M_INFO, 0, _("Original file %s have been deleted: type=%d\n"), attr->fname, attr->type);
410       break;
411    /* The following should not occur */
412    case FT_NOACCESS:
413    case FT_NOFOLLOW:
414    case FT_NOSTAT:
415    case FT_DIRNOCHG:
416    case FT_NOCHG:
417    case FT_ISARCH:
418    case FT_NORECURSE:
419    case FT_NOFSCHG:
420    case FT_NOOPEN:
421       Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type);
422       break;
423    default:
424       Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname);
425       Pmsg2(000, "Unknown file type %d; not restored: %s\n", attr->type, attr->fname);
426       break;
427    }
428    return CF_ERROR;
429 }
430 
431 /*
432  *  Returns: > 0 index into path where last path char is.
433  *           0  no path
434  *           -1 filename is zero length
435  */
separate_path_and_file(JCR * jcr,char * fname,char * ofile)436 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile)
437 {
438    char *f, *p, *q;
439    int fnl, pnl;
440 
441    /* Separate pathname and filename */
442    for (q=p=f=ofile; *p; p++) {
443 #ifdef HAVE_WIN32
444       if (IsPathSeparator(*p)) {
445          f = q;
446          if (IsPathSeparator(p[1])) {
447             p++;
448          }
449       }
450       *q++ = *p;                   /* copy data */
451 #else
452       if (IsPathSeparator(*p)) {
453          f = q;                    /* possible filename */
454       }
455       q++;
456 #endif
457    }
458 
459    if (IsPathSeparator(*f)) {
460       f++;
461    }
462    *q = 0;                         /* terminate string */
463 
464    fnl = q - f;
465    if (fnl == 0) {
466       /* The filename length must not be zero here because we
467        *  are dealing with a file (i.e. FT_REGE or FT_REG).
468        */
469       Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
470       return -1;
471    }
472    pnl = f - ofile - 1;
473    return pnl;
474 }
475 
476 /*
477  * Primitive caching of path to prevent recreating a pathname
478  *   each time as long as we remain in the same directory.
479  */
path_already_seen(JCR * jcr,char * path,int pnl)480 static int path_already_seen(JCR *jcr, char *path, int pnl)
481 {
482    if (!jcr->cached_path) {
483       jcr->cached_path = get_pool_memory(PM_FNAME);
484    }
485    if (jcr->cached_pnl == pnl && strcmp(path, jcr->cached_path) == 0) {
486       return 1;
487    }
488    pm_strcpy(jcr->cached_path, path);
489    jcr->cached_pnl = pnl;
490    return 0;
491 }
492