1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
5    Copyright (C) 2011-2012 Planets Communications B.V.
6    Copyright (C) 2013-2016 Bareos GmbH & Co. KG
7 
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    Affero General Public License for more details.
17 
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22 */
23 /*
24  * Kern Sibbald, November MM
25  */
26 /**
27  * @file
28  * Create a file, and reset the modes
29  */
30 
31 #include "include/bareos.h"
32 #include "include/jcr.h"
33 #include "find.h"
34 #include "findlib/makepath.h"
35 #include "findlib/create_file.h"
36 #include "lib/path_list.h"
37 #include "lib/btimers.h"
38 
39 #ifndef S_IRWXUGO
40 #define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
41 #endif
42 
43 #ifndef IS_CTG
44 #define IS_CTG(x) 0
45 #define O_CTG 0
46 #endif
47 
48 static int SeparatePathAndFile(JobControlRecord *jcr, char *fname, char *ofile);
49 static int PathAlreadySeen(JobControlRecord *jcr, char *path, int pnl);
50 
51 /**
52  * Create the file, or the directory
53  *
54  * fname is the original filename
55  * ofile is the output filename (may be in a different directory)
56  *
57  * Returns:  CF_SKIP     if file should be skipped
58  *           CF_ERROR    on error
59  *           CF_EXTRACT  file created and data to restore
60  *           CF_CREATED  file created no data to restore
61  *
62  * Note, we create the file here, except for special files,
63  * we do not set the attributes because we want to first
64  * write the file, then when the writing is done, set the
65  * attributes.
66  *
67  * So, we return with the file descriptor open for normal files.
68  */
CreateFile(JobControlRecord * jcr,Attributes * attr,BareosWinFilePacket * bfd,int replace)69 int CreateFile(JobControlRecord *jcr, Attributes *attr, BareosWinFilePacket *bfd, int replace)
70 {
71    mode_t new_mode, parent_mode;
72    int flags;
73    uid_t uid;
74    gid_t gid;
75    int pnl;
76    bool exists = false;
77    struct stat mstatp;
78 #ifndef HAVE_WIN32
79    bool isOnRoot;
80 #endif
81 
82    bfd->reparse_point = false;
83    if (is_win32_stream(attr->data_stream)) {
84       set_win32_backup(bfd);
85    } else {
86       SetPortableBackup(bfd);
87    }
88 
89    new_mode = attr->statp.st_mode;
90    Dmsg3(200, "type=%d newmode=%04o file=%s\n", attr->type, (new_mode & ~S_IFMT), attr->ofname);
91    parent_mode = S_IWUSR | S_IXUSR | new_mode;
92    gid = attr->statp.st_gid;
93    uid = attr->statp.st_uid;
94 
95 #ifdef HAVE_WIN32
96    if (!bfd->use_backup_api) {
97       /*
98        * Eliminate invalid windows filename characters from foreign filenames
99        */
100       char *ch = (char *)attr->ofname;
101       if (ch[0] != 0 && ch[1] != 0) {
102          ch += 2;
103          while (*ch) {
104             switch (*ch) {
105             case ':':
106             case '<':
107             case '>':
108             case '*':
109             case '?':
110             case '|':
111                *ch = '_';
112                 break;
113             }
114             ch++;
115          }
116       }
117    }
118 #endif
119 
120    Dmsg2(400, "Replace=%c %d\n", (char)replace, replace);
121    if (lstat(attr->ofname, &mstatp) == 0) {
122       exists = true;
123       switch (replace) {
124       case REPLACE_IFNEWER:
125          if (attr->statp.st_mtime <= mstatp.st_mtime) {
126             Qmsg(jcr, M_INFO, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
127             return CF_SKIP;
128          }
129          break;
130       case REPLACE_IFOLDER:
131          if (attr->statp.st_mtime >= mstatp.st_mtime) {
132             Qmsg(jcr, M_INFO, 0, _("File skipped. Not older: %s\n"), attr->ofname);
133             return CF_SKIP;
134          }
135          break;
136       case REPLACE_NEVER:
137          /*
138           * Set attributes if we created this directory
139           */
140          if (attr->type == FT_DIREND && PathListLookup(jcr->path_list, attr->ofname)) {
141             break;
142          }
143          Qmsg(jcr, M_INFO, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
144          return CF_SKIP;
145       case REPLACE_ALWAYS:
146          break;
147       }
148    }
149 
150    switch (attr->type) {
151    case FT_RAW:                       /* Raw device to be written */
152    case FT_FIFO:                      /* FIFO to be written to */
153    case FT_LNKSAVED:                  /* Hard linked, file already saved */
154    case FT_LNK:
155    case FT_SPEC:                      /* Fifo, ... to be backed up */
156    case FT_REGE:                      /* Empty file */
157    case FT_REG:                       /* Regular file */
158       /*
159        * Note, we do not delete FT_RAW because these are device files
160        * or FIFOs that should already exist. If we blow it away,
161        * we may blow away a FIFO that is being used to read the
162        * restore data, or we may blow away a partition definition.
163        */
164       if (exists && attr->type != FT_RAW && attr->type != FT_FIFO) {
165          /* Get rid of old copy */
166          Dmsg1(400, "unlink %s\n", attr->ofname);
167          if (SecureErase(jcr, attr->ofname) == -1) {
168             BErrNo be;
169 
170             Qmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"),
171                  attr->ofname, be.bstrerror());
172             /* Continue despite error */
173          }
174       }
175 
176       /*
177        * Here we do some preliminary work for all the above
178        *   types to create the path to the file if it does
179        *   not already exist.  Below, we will split to
180        *   do the file type specific work
181        */
182       pnl = SeparatePathAndFile(jcr, attr->fname, attr->ofname);
183       if (pnl < 0) {
184          return CF_ERROR;
185       }
186 
187       /*
188        * If path length is <= 0 we are making a file in the root
189        *  directory. Assume that the directory already exists.
190        */
191       if (pnl > 0) {
192          char savechr;
193          savechr = attr->ofname[pnl];
194          attr->ofname[pnl] = 0;                 /* Terminate path */
195 
196          if (!PathAlreadySeen(jcr, attr->ofname, pnl)) {
197             Dmsg1(400, "Make path %s\n", attr->ofname);
198             /*
199              * If we need to make the directory, ensure that it is with
200              * execute bit set (i.e. parent_mode), and preserve what already
201              * exists. Normally, this should do nothing.
202              */
203             if (!makepath(attr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) {
204                Dmsg1(10, "Could not make path. %s\n", attr->ofname);
205                attr->ofname[pnl] = savechr;     /* restore full name */
206                return CF_ERROR;
207             }
208          }
209          attr->ofname[pnl] = savechr;           /* restore full name */
210       }
211 
212       /*
213        * Now we do the specific work for each file type
214        */
215       switch(attr->type) {
216       case FT_REGE:
217       case FT_REG:
218          Dmsg1(100, "Create=%s\n", attr->ofname);
219          flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /*  O_NOFOLLOW; */
220          if (IS_CTG(attr->statp.st_mode)) {
221             flags |= O_CTG;              /* set contiguous bit if needed */
222          }
223 
224          if (IsBopen(bfd)) {
225             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
226             bclose(bfd);
227          }
228 
229          if (bopen(bfd, attr->ofname, flags, 0, attr->statp.st_rdev) < 0) {
230             BErrNo be;
231 
232             be.SetErrno(bfd->BErrNo);
233             Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), attr->ofname, be.bstrerror());
234             Dmsg2(100,"Could not create %s: ERR=%s\n", attr->ofname, be.bstrerror());
235 
236             return CF_ERROR;
237          }
238 
239          return CF_EXTRACT;
240 
241 #ifndef HAVE_WIN32 /* None of these exist in MS Windows */
242       case FT_RAW:                    /* Bareos raw device e.g. /dev/sda1 */
243       case FT_FIFO:                   /* Bareos fifo to save data */
244       case FT_SPEC:
245          flags = O_WRONLY | O_BINARY;
246 
247          isOnRoot = bstrcmp(attr->fname, attr->ofname) ? 1 : 0;
248          if (S_ISFIFO(attr->statp.st_mode)) {
249             Dmsg1(400, "Restore fifo: %s\n", attr->ofname);
250             if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) {
251                BErrNo be;
252                Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"),
253                      attr->ofname, be.bstrerror());
254                return CF_ERROR;
255             }
256          } else if (S_ISSOCK(attr->statp.st_mode)) {
257              Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname);
258 #ifdef S_IFDOOR /* Solaris high speed RPC mechanism */
259          } else if (S_ISDOOR(attr->statp.st_mode)) {
260              Dmsg1(200, "Skipping restore of door file: %s\n", attr->ofname);
261 #endif
262 #ifdef S_IFPORT /* Solaris event port for handling AIO */
263          } else if (S_ISPORT(attr->statp.st_mode)) {
264              Dmsg1(200, "Skipping restore of event port file: %s\n", attr->ofname);
265 #endif
266          } else if ((S_ISBLK(attr->statp.st_mode) || S_ISCHR(attr->statp.st_mode)) && !exists && isOnRoot) {
267              /*
268               * Fatal: Restoring a device on root-file system, but device node does not exist.
269               * Should not create a dump file.
270               */
271              Qmsg1(jcr, M_ERROR, 0, _("Device restore on root failed, device %s missing.\n"), attr->fname);
272              return CF_ERROR;
273          } else if (S_ISBLK(attr->statp.st_mode) || S_ISCHR(attr->statp.st_mode)) {
274              Dmsg1(400, "Restoring a device as a file: %s\n", attr->ofname);
275              flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;
276          } else {
277             Dmsg1(400, "Restore node: %s\n", attr->ofname);
278             if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) {
279                BErrNo be;
280                Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"),
281                      attr->ofname, be.bstrerror());
282                return CF_ERROR;
283             }
284          }
285 
286          /*
287           * Here we are going to attempt to restore to a FIFO, which
288           * means that the FIFO must already exist, AND there must
289           * be some process already attempting to read from the
290           * FIFO, so we open it write-only.
291           */
292          if (attr->type == FT_RAW || attr->type == FT_FIFO) {
293             btimer_t *tid;
294             Dmsg1(400, "FT_RAW|FT_FIFO %s\n", attr->ofname);
295             /*
296              * Timeout open() in 60 seconds
297              */
298             if (attr->type == FT_FIFO) {
299                Dmsg0(400, "Set FIFO timer\n");
300                tid = start_thread_timer(jcr, pthread_self(), 60);
301             } else {
302                tid = NULL;
303             }
304             if (IsBopen(bfd)) {
305                Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
306             }
307             Dmsg2(400, "open %s flags=%08o\n", attr->ofname, flags);
308             if ((bopen(bfd, attr->ofname, flags, 0, 0)) < 0) {
309                BErrNo be;
310                be.SetErrno(bfd->BErrNo);
311                Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
312                      attr->ofname, be.bstrerror());
313                Dmsg2(400, "Could not open %s: ERR=%s\n", attr->ofname, be.bstrerror());
314                StopThreadTimer(tid);
315                return CF_ERROR;
316             }
317             StopThreadTimer(tid);
318             return CF_EXTRACT;
319          }
320          Dmsg1(400, "FT_SPEC %s\n", attr->ofname);
321          return CF_CREATED;
322 
323       case FT_LNKSAVED:                  /* Hard linked, file already saved */
324          Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname);
325          if (link(attr->olname, attr->ofname) != 0) {
326             BErrNo be;
327 #ifdef HAVE_CHFLAGS
328             struct stat s;
329 
330             /*
331              * If using BSD user flags, maybe has a file flag preventing this.
332              * So attempt to disable, retry link, and reset flags.
333              * Note that BSD securelevel may prevent disabling flag.
334              */
335             if (stat(attr->olname, &s) == 0 && s.st_flags != 0) {
336                if (chflags(attr->olname, 0) == 0) {
337                   if (link(attr->olname, attr->ofname) != 0) {
338                      /*
339                       * Restore original file flags even when linking failed
340                       */
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 #endif /* HAVE_CHFLAGS */
346             Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
347                   attr->ofname, attr->olname, be.bstrerror());
348             Dmsg3(200, "Could not hard link %s -> %s: ERR=%s\n",
349                   attr->ofname, attr->olname, be.bstrerror());
350             return CF_ERROR;
351 #ifdef HAVE_CHFLAGS
352                   }
353                   /*
354                    * Finally restore original file flags
355                    */
356                   if (chflags(attr->olname, s.st_flags) < 0) {
357                      Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"),
358                             attr->olname, be.bstrerror());
359                   }
360                } else {
361                  Qmsg2(jcr, M_ERROR, 0, _("Could not reset file flags for file %s: ERR=%s\n"),
362                        attr->olname, be.bstrerror());
363                }
364             } else {
365               Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
366                     attr->ofname, attr->olname, be.bstrerror());
367               return CF_ERROR;
368             }
369 #endif /* HAVE_CHFLAGS */
370 
371          }
372          return CF_CREATED;
373 
374 #endif /* HAVE_WIN32 */
375 #ifdef HAVE_WIN32
376       case FT_LNK:
377          /*
378           * Handle Windows Symlink-Like Reparse Points
379           * - Directory Symlinks
380           * - File Symlinks
381           * - Volume Mount Points
382           * - Junctions
383           */
384          Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname);
385          if (attr->statp.st_rdev & FILE_ATTRIBUTE_VOLUME_MOUNT_POINT) {
386             /*
387              * We do not restore volume mount points
388              */
389             Dmsg0(130, "Skipping Volume Mount Point\n");
390             return CF_SKIP;
391          }
392          if (win32_symlink(attr->olname, attr->ofname, attr->statp.st_rdev) != 0 && errno != EEXIST) {
393             BErrNo be;
394             Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"),
395                   attr->ofname, attr->olname, be.bstrerror());
396             return CF_ERROR;
397          }
398          return CF_CREATED;
399 #else
400       case FT_LNK:
401          /*
402           * Unix/Linux symlink handling
403           */
404          Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname);
405          if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) {
406             BErrNo be;
407             Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"),
408                   attr->ofname, attr->olname, be.bstrerror());
409             return CF_ERROR;
410          }
411          return CF_CREATED;
412 #endif
413       } /* End inner switch */
414 
415    case FT_REPARSE:
416    case FT_JUNCTION:
417       bfd->reparse_point = true;
418       /*
419        * Fall through wanted
420        */
421    case FT_DIRBEGIN:
422    case FT_DIREND:
423       Dmsg2(200, "Make dir mode=%04o dir=%s\n", (new_mode & ~S_IFMT), attr->ofname);
424       if (!makepath(attr, attr->ofname, new_mode, parent_mode, uid, gid, 0)) {
425          return CF_ERROR;
426       }
427       /*
428        * If we are using the Win32 Backup API, we open the directory so
429        * that the security info will be read and saved.
430        */
431       if (!IsPortableBackup(bfd)) {
432          if (IsBopen(bfd)) {
433             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
434          }
435          if (bopen(bfd, attr->ofname, O_WRONLY | O_BINARY, 0, attr->statp.st_rdev) < 0) {
436             BErrNo be;
437             be.SetErrno(bfd->BErrNo);
438 #ifdef HAVE_WIN32
439             /*
440              * Check for trying to create a drive, if so, skip
441              */
442             if (attr->ofname[1] == ':' &&
443                 IsPathSeparator(attr->ofname[2]) &&
444                 attr->ofname[3] == '\0') {
445                return CF_SKIP;
446             }
447 #endif
448             Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
449                   attr->ofname, be.bstrerror());
450             return CF_ERROR;
451          }
452          return CF_EXTRACT;
453       } else {
454          return CF_CREATED;
455       }
456 
457    case FT_DELETED:
458       Qmsg2(jcr, M_INFO, 0, _("Original file %s have been deleted: type=%d\n"), attr->fname, attr->type);
459       break;
460    /*
461     * The following should not occur
462     */
463    case FT_NOACCESS:
464    case FT_NOFOLLOW:
465    case FT_NOSTAT:
466    case FT_DIRNOCHG:
467    case FT_NOCHG:
468    case FT_ISARCH:
469    case FT_NORECURSE:
470    case FT_NOFSCHG:
471    case FT_NOOPEN:
472       Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type);
473       break;
474    default:
475       Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname);
476       break;
477    }
478    return CF_ERROR;
479 }
480 
481 /**
482  *  Returns: > 0 index into path where last path char is.
483  *           0  no path
484  *           -1 filename is zero length
485  */
SeparatePathAndFile(JobControlRecord * jcr,char * fname,char * ofile)486 static int SeparatePathAndFile(JobControlRecord *jcr, char *fname, char *ofile)
487 {
488    char *f, *p, *q;
489    int fnl, pnl;
490 
491    /* Separate pathname and filename */
492    for (q=p=f=ofile; *p; p++) {
493 #ifdef HAVE_WIN32
494       if (IsPathSeparator(*p)) {
495          f = q;
496          if (IsPathSeparator(p[1])) {
497             p++;
498          }
499       }
500       *q++ = *p;                   /* copy data */
501 #else
502       if (IsPathSeparator(*p)) {
503          f = q;                    /* possible filename */
504       }
505       q++;
506 #endif
507    }
508 
509    if (IsPathSeparator(*f)) {
510       f++;
511    }
512    *q = 0;                         /* Terminate string */
513 
514    fnl = q - f;
515    if (fnl == 0) {
516       /* The filename length must not be zero here because we
517        *  are dealing with a file (i.e. FT_REGE or FT_REG).
518        */
519       Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
520       return -1;
521    }
522    pnl = f - ofile - 1;
523    return pnl;
524 }
525 
526 /**
527  * Primitive caching of path to prevent recreating a pathname
528  *   each time as long as we remain in the same directory.
529  */
PathAlreadySeen(JobControlRecord * jcr,char * path,int pnl)530 static int PathAlreadySeen(JobControlRecord *jcr, char *path, int pnl)
531 {
532    if (!jcr->cached_path) {
533       jcr->cached_path = GetPoolMemory(PM_FNAME);
534    }
535    if (jcr->cached_pnl == pnl && bstrcmp(path, jcr->cached_path)) {
536       return 1;
537    }
538    PmStrcpy(jcr->cached_path, path);
539    jcr->cached_pnl = pnl;
540    return 0;
541 }
542