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