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