2 * Bacula File Daemon restore.c Restorefiles.
4 * Kern Sibbald, November MM
10 Copyright (C) 2000-2005 Kern Sibbald
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 version 2 as amended with additional clauses defined in the
15 file LICENSE in the main source directory.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 the file LICENSE for additional details.
31 /* Data received from Storage Daemon */
32 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
34 /* Forward referenced functions */
36 static const char *zlib_strerror(int stat);
39 int verify_signature(JCR *jcr, SIGNATURE *sig);
40 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
41 uint64_t *addr, int flags);
43 #define RETRY 10 /* retry wait time */
46 * Close a bfd check that we are at the expected file offset.
47 * Makes some code in set_attributes().
49 int bclose_chksize(JCR *jcr, BFILE *bfd, off_t osize)
51 char ec1[50], ec2[50];
54 fsize = blseek(bfd, 0, SEEK_CUR);
55 bclose(bfd); /* first close file */
56 if (fsize > 0 && fsize != osize) {
57 Qmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"),
58 jcr->last_fname, edit_uint64(osize, ec1),
59 edit_uint64(fsize, ec2));
66 * Restore the requested files.
69 void do_restore(JCR *jcr)
74 uint32_t VolSessionId, VolSessionTime;
77 char ec1[50]; /* Buffer printing huge values */
79 BFILE bfd; /* File content */
80 uint64_t fileAddr = 0; /* file write address */
81 uint32_t size; /* Size of file */
82 BFILE altbfd; /* Alternative data stream */
83 uint64_t alt_addr = 0; /* Write address for alternative stream */
84 intmax_t alt_size = 0; /* Size of alternate stream */
85 SIGNATURE *sig = NULL; /* Cryptographic signature (if any) for file */
86 CRYPTO_SESSION *cs = NULL; /* Cryptographic session data (if any) for file */
87 int flags; /* Options for extract_data() */
91 /* The following variables keep track of "known unknowns" */
92 int non_support_data = 0;
93 int non_support_attr = 0;
94 int non_support_rsrc = 0;
95 int non_support_finfo = 0;
96 int non_support_acl = 0;
97 int non_support_progname = 0;
99 /* Finally, set up for special configurations */
100 #ifdef HAVE_DARWIN_OS
101 intmax_t rsrc_len = 0; /* Original length of resource fork */
102 struct attrlist attrList;
104 memset(&attrList, 0, sizeof(attrList));
105 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
106 attrList.commonattr = ATTR_CMN_FNDRINFO;
109 sd = jcr->store_bsock;
110 set_jcr_job_status(jcr, JS_Running);
113 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
117 buf_size = client->max_network_buffer_size;
119 buf_size = 0; /* use default */
121 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
122 set_jcr_job_status(jcr, JS_ErrorTerminated);
125 jcr->buf_size = sd->msglen;
128 uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
129 jcr->compress_buf = (char *)bmalloc(compress_buf_size);
130 jcr->compress_buf_size = compress_buf_size;
134 * Get a record from the Storage daemon. We are guaranteed to
135 * receive records in the following order:
136 * 1. Stream record header
138 * a. Attributes (Unix or Win32)
139 * b. Possibly stream encryption session data (e.g., symmetric session key)
140 * or c. File data for the file
141 * or d. Alternate data stream (e.g. Resource Fork)
144 * or g. Possibly a cryptographic signature
145 * or h. Possibly MD5 or SHA1 record
148 * NOTE: We keep track of two bacula file descriptors:
149 * 1. bfd for file data.
150 * This fd is opened for non empty files when an attribute stream is
151 * encountered and closed when we find the next attribute stream.
152 * 2. alt_bfd for alternate data streams
153 * This fd is opened every time we encounter a new alternate data
154 * stream for the current file. When we find any other stream, we
156 * The expected size of the stream, alt_len, should be set when
162 jcr->acl_text = get_pool_memory(PM_MESSAGE);
164 while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
165 /* Remember previous stream type */
166 prev_stream = stream;
168 /* First we expect a Stream Record Header */
169 if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
170 &stream, &size) != 5) {
171 Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
174 Dmsg2(30, "Got hdr: FilInx=%d Stream=%d.\n", file_index, stream);
176 /* * Now we expect the Stream Data */
177 if (bget_msg(sd) < 0) {
178 Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
181 if (size != (uint32_t)sd->msglen) {
182 Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
185 Dmsg1(30, "Got stream data, len=%d\n", sd->msglen);
187 /* If we change streams, close and reset alternate data streams */
188 if (prev_stream != stream) {
189 if (is_bopen(&altbfd)) {
190 bclose_chksize(jcr, &altbfd, alt_size);
192 alt_size = -1; /* Use an impossible value and set a proper one below */
196 /* File Attributes stream */
198 case STREAM_UNIX_ATTRIBUTES:
199 case STREAM_UNIX_ATTRIBUTES_EX:
200 Dmsg1(30, "Stream=Unix Attributes. extract=%d\n", extract);
202 * If extracting, it was from previous stream, so
203 * close the output file and validate the signature.
206 if (size > 0 && !is_bopen(&bfd)) {
207 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
209 set_attributes(jcr, attr, &bfd);
212 /* Verify the cryptographic signature, if any */
215 // Failure is reported in verify_signature() ...
216 verify_signature(jcr, sig);
218 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
224 crypto_sign_free(sig);
228 crypto_session_free(cs);
231 Dmsg0(30, "Stop extracting.\n");
232 } else if (is_bopen(&bfd)) {
233 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
238 * Unpack and do sanity check fo attributes.
240 if (!unpack_attributes_record(jcr, stream, sd->msg, attr)) {
243 if (file_index != attr->file_index) {
244 Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
245 file_index, attr->file_index);
246 Dmsg0(100, "File index error\n");
250 Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname,
251 attr->attr, attr->attrEx);
253 attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
255 if (!is_restore_stream_supported(attr->data_stream)) {
256 if (!non_support_data++) {
257 Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
258 stream_to_ascii(attr->data_stream));
263 build_attr_output_fnames(jcr, attr);
266 * Now determine if we are extracting or not.
268 jcr->num_files_examined++;
269 Dmsg1(30, "Outfile=%s\n", attr->ofname);
271 stat = create_file(jcr, attr, &bfd, jcr->replace);
276 case CF_EXTRACT: /* File created and we expect file data */
279 case CF_CREATED: /* File created, but there is no content */
281 pm_strcpy(jcr->last_fname, attr->ofname);
285 print_ls_output(jcr, attr);
286 #ifdef HAVE_DARWIN_OS
287 /* Only restore the resource fork for regular files */
288 from_base64(&rsrc_len, attr->attrEx);
289 if (attr->type == FT_REG && rsrc_len > 0) {
294 /* set attributes now because file will not be extracted */
295 set_attributes(jcr, attr, &bfd);
302 case STREAM_ENCRYPTED_SESSION_DATA:
303 crypto_error_t cryptoerr;
304 Dmsg1(30, "Stream=Encrypted Session Data, size: %d\n", sd->msglen);
306 /* Decode and save session keys. */
307 cryptoerr = crypto_session_decode(sd->msg, (size_t) sd->msglen, jcr->pki_recipients, &cs);
309 case CRYPTO_ERROR_NONE:
312 case CRYPTO_ERROR_NORECIPIENT:
313 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data."));
315 case CRYPTO_ERROR_DECRYPTION:
316 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed."));
319 /* Shouldn't happen */
320 Jmsg1(jcr, M_ERROR, 0, _("An error occured while decoding encrypted session data stream: %s"), crypto_strerror(cryptoerr));
326 case STREAM_FILE_DATA:
327 case STREAM_SPARSE_DATA:
328 case STREAM_WIN32_DATA:
329 case STREAM_GZIP_DATA:
330 case STREAM_SPARSE_GZIP_DATA:
331 case STREAM_WIN32_GZIP_DATA:
332 case STREAM_ENCRYPTED_FILE_DATA:
333 case STREAM_ENCRYPTED_WIN32_DATA:
334 case STREAM_ENCRYPTED_FILE_GZIP_DATA:
335 case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
336 /* Force an expected, consistent stream type here */
337 if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
338 || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
339 || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
342 if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
346 if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
347 || stream == STREAM_WIN32_GZIP_DATA || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
348 || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
352 if (is_win32_stream(stream) && !have_win32_api()) {
353 set_portable_backup(&bfd);
354 flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
357 if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags) < 0) {
365 /* Resource fork stream - only recorded after a file to be restored */
366 /* Silently ignore if we cannot write - we already reported that */
367 case STREAM_ENCRYPTED_MACOS_FORK_DATA:
368 case STREAM_MACOS_FORK_DATA:
369 #ifdef HAVE_DARWIN_OS
371 if (prev_stream != stream) {
372 if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
373 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
378 Dmsg0(30, "Restoring resource fork\n");
381 if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, flags) < 0) {
392 case STREAM_HFSPLUS_ATTRIBUTES:
393 #ifdef HAVE_DARWIN_OS
394 Dmsg0(30, "Restoring Finder Info\n");
395 if (sd->msglen != 32) {
396 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
399 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
400 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
407 case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
409 pm_strcpy(jcr->acl_text, sd->msg);
410 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
411 if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
412 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
419 case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
421 pm_strcpy(jcr->acl_text, sd->msg);
422 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
423 if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
424 Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
431 case STREAM_SIGNED_DIGEST:
432 /* Save signature. */
433 sig = crypto_sign_decode(sd->msg, (size_t) sd->msglen);
436 case STREAM_MD5_DIGEST:
437 case STREAM_SHA1_DIGEST:
438 case STREAM_SHA256_DIGEST:
439 case STREAM_SHA512_DIGEST:
442 case STREAM_PROGRAM_NAMES:
443 case STREAM_PROGRAM_DATA:
444 if (!non_support_progname) {
445 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
446 non_support_progname++;
451 /* If extracting, wierd stream (not 1 or 2), close output file anyway */
453 Dmsg1(30, "Found wierd stream %d\n", stream);
454 if (size > 0 && !is_bopen(&bfd)) {
455 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
457 set_attributes(jcr, attr, &bfd);
459 } else if (is_bopen(&bfd)) {
460 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
463 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
464 Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
466 } /* end switch(stream) */
468 } /* end while get_msg() */
470 /* If output file is still open, it was the last one in the
471 * archive since we just hit an end of file, so close the file.
473 if (is_bopen(&altbfd)) {
474 bclose_chksize(jcr, &altbfd, alt_size);
475 /* Verify the cryptographic signature on the last file, if any */
478 // Failure is reported in verify_signature() ...
479 verify_signature(jcr, sig);
481 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
486 set_attributes(jcr, attr, &bfd);
488 if (is_bopen(&bfd)) {
491 set_jcr_job_status(jcr, JS_Terminated);
495 set_jcr_job_status(jcr, JS_ErrorTerminated);
498 /* Free Signature & Crypto Session */
500 crypto_sign_free(sig);
504 crypto_session_free(cs);
507 if (jcr->compress_buf) {
508 free(jcr->compress_buf);
509 jcr->compress_buf = NULL;
510 jcr->compress_buf_size = 0;
515 free_pool_memory(jcr->acl_text);
516 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
517 edit_uint64(jcr->JobBytes, ec1));
518 if (non_support_data > 1 || non_support_attr > 1) {
519 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
520 non_support_data, non_support_attr);
522 if (non_support_rsrc) {
523 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
525 if (non_support_finfo) {
526 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
528 if (non_support_acl) {
529 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
536 * Convert ZLIB error code into an ASCII message
538 static const char *zlib_strerror(int stat)
545 return _("Zlib errno");
547 return _("Zlib stream error");
549 return _("Zlib data error");
551 return _("Zlib memory error");
553 return _("Zlib buffer error");
554 case Z_VERSION_ERROR:
555 return _("Zlib version error");
562 static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level) {
563 JCR *jcr = (JCR *) pkt;
564 return (digest_file(jcr, ff_pkt, jcr->digest));
568 * Verify the signature for the last restored file
569 * Return value is either true (signature correct)
570 * or false (signature could not be verified).
571 * TODO landonf: Better signature failure handling.
573 int verify_signature(JCR *jcr, SIGNATURE *sig)
575 X509_KEYPAIR *keypair;
576 DIGEST *digest = NULL;
579 /* Iterate through the trusted signers */
580 foreach_alist(keypair, jcr->pki_signers) {
581 err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
584 case CRYPTO_ERROR_NONE:
585 /* Signature found, digest allocated */
586 jcr->digest = digest;
588 /* Checksum the entire file */
589 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) {
590 Qmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname);
594 /* Verify the signature */
595 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
596 Dmsg1(100, "Bad signature on %s\n", jcr->last_fname);
597 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
598 crypto_digest_free(digest);
602 /* Valid signature */
603 Dmsg1(100, "Signature good on %s\n", jcr->last_fname);
604 crypto_digest_free(digest);
607 case CRYPTO_ERROR_NOSIGNER:
608 /* Signature not found, try again */
611 /* Something strange happened (that shouldn't happen!)... */
612 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
614 crypto_digest_free(digest);
621 Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
622 crypto_digest_free(digest);
627 * In the context of jcr, write data to bfd.
628 * We write buflen bytes in buf at addr. addr is updated in place.
629 * The flags specify whether to use sparse files or compression.
630 * Return value is the number of bytes written, or -1 on errors.
632 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
633 uint64_t *addr, int flags)
636 char *wbuf; /* write buffer */
637 uint32_t wsize; /* write size */
638 uint32_t rsize; /* read size */
639 char ec1[50]; /* Buffer printing huge values */
641 if (flags & FO_SPARSE) {
645 wbuf = buf + SPARSE_FADDR_SIZE;
646 rsize = buflen - SPARSE_FADDR_SIZE;
647 ser_begin(buf, SPARSE_FADDR_SIZE);
649 if (*addr != faddr) {
651 if (blseek(bfd, (off_t)*addr, SEEK_SET) < 0) {
653 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
654 edit_uint64(*addr, ec1), jcr->last_fname,
655 be.strerror(bfd->berrno));
665 if (flags & FO_GZIP) {
669 * NOTE! We only use uLong and Byte because they are
670 * needed by the zlib routines, they should not otherwise
673 compress_len = jcr->compress_buf_size;
674 Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, wsize);
675 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
676 (const Byte *)wbuf, (uLong)rsize)) != Z_OK) {
677 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
678 jcr->last_fname, zlib_strerror(stat));
681 wbuf = jcr->compress_buf;
682 wsize = compress_len;
683 Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
685 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
689 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
692 if (flags & FO_WIN32DECOMP) {
693 if (!processWin32BackupAPIBlock(bfd, wbuf, wsize)) {
695 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
696 jcr->last_fname, be.strerror(bfd->berrno));
699 } else if (bwrite(bfd, wbuf, wsize) != (ssize_t)wsize) {
701 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
702 jcr->last_fname, be.strerror(bfd->berrno));
706 jcr->JobBytes += wsize;
707 jcr->ReadBytes += rsize;