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 Dmsg1(30, "Stream=Encrypted Session Data, size: %d\n", sd->msglen);
304 /* Save session keys . */
305 switch(crypto_session_decode(sd->msg, (size_t) sd->msglen, jcr->pki_recipients, &cs)) {
306 case CRYPTO_ERROR_NONE:
309 case CRYPTO_ERROR_NORECIPIENT:
310 Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data."));
312 case CRYPTO_ERROR_DECRYPTION:
313 Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed."));
316 /* Shouldn't happen */
317 Jmsg(jcr, M_ERROR, 0, _("An error occured while decoding encrypted session data stream."));
323 case STREAM_FILE_DATA:
324 case STREAM_SPARSE_DATA:
325 case STREAM_WIN32_DATA:
326 case STREAM_GZIP_DATA:
327 case STREAM_SPARSE_GZIP_DATA:
328 case STREAM_WIN32_GZIP_DATA:
329 /* Force an expected, consistent stream type here */
330 if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
331 || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
332 || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
334 if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
337 if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
338 || stream == STREAM_WIN32_GZIP_DATA) {
342 if (is_win32_stream(stream) && !have_win32_api()) {
343 set_portable_backup(&bfd);
344 flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
347 if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags) < 0) {
355 /* Resource fork stream - only recorded after a file to be restored */
356 /* Silently ignore if we cannot write - we already reported that */
357 case STREAM_MACOS_FORK_DATA:
358 #ifdef HAVE_DARWIN_OS
360 if (prev_stream != stream) {
361 if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
362 Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname);
367 Dmsg0(30, "Restoring resource fork\n");
370 if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, flags) < 0) {
381 case STREAM_HFSPLUS_ATTRIBUTES:
382 #ifdef HAVE_DARWIN_OS
383 Dmsg0(30, "Restoring Finder Info\n");
384 if (sd->msglen != 32) {
385 Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen);
388 if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) {
389 Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname);
396 case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
398 pm_strcpy(jcr->acl_text, sd->msg);
399 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
400 if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
401 Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
408 case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
410 pm_strcpy(jcr->acl_text, sd->msg);
411 Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
412 if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
413 Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
420 case STREAM_SIGNED_DIGEST:
421 /* Save signature. */
422 sig = crypto_sign_decode(sd->msg, (size_t) sd->msglen);
425 case STREAM_MD5_DIGEST:
426 case STREAM_SHA1_DIGEST:
427 case STREAM_SHA256_DIGEST:
428 case STREAM_SHA512_DIGEST:
431 case STREAM_PROGRAM_NAMES:
432 case STREAM_PROGRAM_DATA:
433 if (!non_support_progname) {
434 Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
435 non_support_progname++;
440 /* If extracting, wierd stream (not 1 or 2), close output file anyway */
442 Dmsg1(30, "Found wierd stream %d\n", stream);
443 if (size > 0 && !is_bopen(&bfd)) {
444 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
446 set_attributes(jcr, attr, &bfd);
448 } else if (is_bopen(&bfd)) {
449 Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
452 Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
453 Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
455 } /* end switch(stream) */
457 } /* end while get_msg() */
459 /* If output file is still open, it was the last one in the
460 * archive since we just hit an end of file, so close the file.
462 if (is_bopen(&altbfd)) {
463 bclose_chksize(jcr, &altbfd, alt_size);
464 /* Verify the cryptographic signature on the last file, if any */
467 // Failure is reported in verify_signature() ...
468 verify_signature(jcr, sig);
470 Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname);
475 set_attributes(jcr, attr, &bfd);
477 if (is_bopen(&bfd)) {
480 set_jcr_job_status(jcr, JS_Terminated);
484 set_jcr_job_status(jcr, JS_ErrorTerminated);
487 /* Free Signature & Crypto Session */
489 crypto_sign_free(sig);
493 crypto_session_free(cs);
496 if (jcr->compress_buf) {
497 free(jcr->compress_buf);
498 jcr->compress_buf = NULL;
499 jcr->compress_buf_size = 0;
504 free_pool_memory(jcr->acl_text);
505 Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
506 edit_uint64(jcr->JobBytes, ec1));
507 if (non_support_data > 1 || non_support_attr > 1) {
508 Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
509 non_support_data, non_support_attr);
511 if (non_support_rsrc) {
512 Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc);
514 if (non_support_finfo) {
515 Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_rsrc);
517 if (non_support_acl) {
518 Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
525 * Convert ZLIB error code into an ASCII message
527 static const char *zlib_strerror(int stat)
534 return _("Zlib errno");
536 return _("Zlib stream error");
538 return _("Zlib data error");
540 return _("Zlib memory error");
542 return _("Zlib buffer error");
543 case Z_VERSION_ERROR:
544 return _("Zlib version error");
551 static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level) {
552 JCR *jcr = (JCR *) pkt;
553 return (digest_file(jcr, ff_pkt, jcr->digest));
557 * Verify the signature for the last restored file
558 * Return value is either true (signature correct)
559 * or false (signature could not be verified).
560 * TODO landonf: Better signature failure handling.
562 int verify_signature(JCR *jcr, SIGNATURE *sig)
564 X509_KEYPAIR *keypair;
565 DIGEST *digest = NULL;
568 /* Iterate through the trusted signers */
569 foreach_alist(keypair, jcr->pki_signers) {
570 err = crypto_sign_get_digest(sig, jcr->pki_keypair, &digest);
573 case CRYPTO_ERROR_NONE:
574 /* Signature found, digest allocated */
575 jcr->digest = digest;
577 /* Checksum the entire file */
578 if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) {
579 Qmsg(jcr, M_ERROR, 0, _("Signature validation failed for %s: \n"), jcr->last_fname);
583 /* Verify the signature */
584 if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) {
585 Dmsg1(100, "Bad signature on %s\n", jcr->last_fname);
586 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
587 crypto_digest_free(digest);
591 /* Valid signature */
592 Dmsg1(100, "Signature good on %s\n", jcr->last_fname);
593 crypto_digest_free(digest);
596 case CRYPTO_ERROR_NOSIGNER:
597 /* Signature not found, try again */
600 /* Something strange happened (that shouldn't happen!)... */
601 Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err));
603 crypto_digest_free(digest);
610 Dmsg1(100, "Could not find a valid public key for signature on %s\n", jcr->last_fname);
611 crypto_digest_free(digest);
616 * In the context of jcr, write data to bfd.
617 * We write buflen bytes in buf at addr. addr is updated in place.
618 * The flags specify whether to use sparse files or compression.
619 * Return value is the number of bytes written, or -1 on errors.
621 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
622 uint64_t *addr, int flags)
625 char *wbuf; /* write buffer */
626 uint32_t wsize; /* write size */
627 uint32_t rsize; /* read size */
628 char ec1[50]; /* Buffer printing huge values */
630 if (flags & FO_SPARSE) {
634 wbuf = buf + SPARSE_FADDR_SIZE;
635 rsize = buflen - SPARSE_FADDR_SIZE;
636 ser_begin(buf, SPARSE_FADDR_SIZE);
638 if (*addr != faddr) {
640 if (blseek(bfd, (off_t)*addr, SEEK_SET) < 0) {
642 Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
643 edit_uint64(*addr, ec1), jcr->last_fname,
644 be.strerror(bfd->berrno));
654 if (flags & FO_GZIP) {
658 * NOTE! We only use uLong and Byte because they are
659 * needed by the zlib routines, they should not otherwise
662 compress_len = jcr->compress_buf_size;
663 Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, wsize);
664 if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
665 (const Byte *)wbuf, (uLong)rsize)) != Z_OK) {
666 Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
667 jcr->last_fname, zlib_strerror(stat));
670 wbuf = jcr->compress_buf;
671 wsize = compress_len;
672 Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
674 Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
678 Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
681 if (flags & FO_WIN32DECOMP) {
682 if (!processWin32BackupAPIBlock(bfd, wbuf, wsize)) {
684 Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
685 jcr->last_fname, be.strerror(bfd->berrno));
688 } else if (bwrite(bfd, wbuf, wsize) != (ssize_t)wsize) {
690 Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
691 jcr->last_fname, be.strerror(bfd->berrno));
695 jcr->JobBytes += wsize;
696 jcr->ReadBytes += rsize;