X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Ffiled%2Frestore.c;h=299b78f9e2a5b33902fbe92add40c289f14028d2;hb=f5571f4e4916261503020df01b6f9d30d17ae194;hp=d6d6fe7590e1917e90b6ec7923b58941a149ae3e;hpb=ca084e1c760ac981558d32244e357aa8ecff4d8c;p=bacula%2Fbacula diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index d6d6fe7590..299b78f9e2 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2007 Free Software Foundation Europe e.V. + Copyright (C) 2000-2008 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -120,9 +120,9 @@ bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, /* * Close a bfd check that we are at the expected file offset. - * Makes some code in set_attributes(). + * Makes use of some code from set_attributes(). */ -int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize) +static int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize) { char ec1[50], ec2[50]; boffset_t fsize; @@ -240,7 +240,7 @@ void do_restore(JCR *jcr) */ binit(&rctx.bfd); binit(&rctx.forkbfd); - attr = new_attr(); + attr = new_attr(jcr); jcr->acl_text = get_pool_memory(PM_MESSAGE); @@ -299,7 +299,11 @@ void do_restore(JCR *jcr) deallocate_fork_cipher(rctx); } - set_attributes(jcr, attr, &rctx.bfd); + if (jcr->plugin) { + plugin_set_attributes(jcr, attr, &rctx.bfd); + } else { + set_attributes(jcr, attr, &rctx.bfd); + } extract = false; /* Verify the cryptographic signature, if any */ @@ -316,6 +320,11 @@ void do_restore(JCR *jcr) bclose(&rctx.bfd); } + /* TODO: manage deleted files */ + if (rctx.type == FT_DELETED) { /* deleted file */ + continue; + } + /* * Unpack attributes and do sanity check them */ @@ -345,11 +354,16 @@ void do_restore(JCR *jcr) build_attr_output_fnames(jcr, attr); /* - * Now determine if we are extracting or not. + * Try to actually create the file, which returns a status telling + * us if we need to extract or not. */ jcr->num_files_examined++; extract = false; - stat = create_file(jcr, attr, &rctx.bfd, jcr->replace); + if (jcr->plugin) { + stat = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace); + } else { + stat = create_file(jcr, attr, &rctx.bfd, jcr->replace); + } Dmsg2(30, "Outfile=%s create_file stat=%d\n", attr->ofname, stat); switch (stat) { case CF_ERROR: @@ -376,7 +390,11 @@ void do_restore(JCR *jcr) } if (!extract) { /* set attributes now because file will not be extracted */ - set_attributes(jcr, attr, &rctx.bfd); + if (jcr->plugin) { + plugin_set_attributes(jcr, attr, &rctx.bfd); + } else { + set_attributes(jcr, attr, &rctx.bfd); + } } break; } @@ -395,18 +413,18 @@ void do_restore(JCR *jcr) } /* Do we have any keys at all? */ - if (!jcr->pki_recipients) { + if (!jcr->crypto.pki_recipients) { Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n")); extract = false; bclose(&rctx.bfd); break; } - if (jcr->digest) { - crypto_digest_free(jcr->digest); + if (jcr->crypto.digest) { + crypto_digest_free(jcr->crypto.digest); } - jcr->digest = crypto_digest_new(jcr, signing_algorithm); - if (!jcr->digest) { + jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm); + if (!jcr->crypto.digest) { Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n")); extract = false; bclose(&rctx.bfd); @@ -415,7 +433,7 @@ void do_restore(JCR *jcr) /* Decode and save session keys. */ cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, - jcr->pki_recipients, &rctx.cs); + jcr->crypto.pki_recipients, &rctx.cs); switch(cryptoerr) { case CRYPTO_ERROR_NONE: /* Success */ @@ -514,22 +532,22 @@ void do_restore(JCR *jcr) case STREAM_ENCRYPTED_MACOS_FORK_DATA: case STREAM_MACOS_FORK_DATA: #ifdef HAVE_DARWIN_OS - fork_flags = 0; + rctx.fork_flags = 0; jcr->ff->flags |= FO_HFSPLUS; - if (stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) { - fork_flags |= FO_ENCRYPT; + if (rctx.stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) { + rctx.fork_flags |= FO_ENCRYPT; /* Set up a decryption context */ if (extract && !rctx.fork_cipher_ctx.cipher) { - if (!cs) { + if (!rctx.cs) { Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname); extract = false; bclose(&rctx.bfd); continue; } - if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) { + if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, &rctx.fork_cipher_ctx.block_size)) == NULL) { Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname); free_session(rctx); extract = false; @@ -540,21 +558,21 @@ void do_restore(JCR *jcr) } if (extract) { - if (prev_stream != stream) { - if (bopen_rsrc(&forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) { + if (rctx.prev_stream != rctx.stream) { + if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) { Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s.\n"), jcr->last_fname); extract = false; continue; } - fork_size = rsrc_len; + rctx.fork_size = rsrc_len; Dmsg0(30, "Restoring resource fork\n"); } - if (extract_data(jcr, &forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, fork_flags, - &rctxfork_cipher_ctx) < 0) { + if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags, + &rctx.fork_cipher_ctx) < 0) { extract = false; - bclose(&forkbfd); + bclose(&rctx.forkbfd); continue; } } @@ -580,7 +598,7 @@ void do_restore(JCR *jcr) #endif break; - case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL: + case STREAM_UNIX_ACCESS_ACL: if (have_acl) { pm_strcpy(jcr->acl_text, sd->msg); Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text); @@ -592,7 +610,7 @@ void do_restore(JCR *jcr) } break; - case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL: + case STREAM_UNIX_DEFAULT_ACL: if (have_acl) { pm_strcpy(jcr->acl_text, sd->msg); Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text); @@ -631,6 +649,11 @@ void do_restore(JCR *jcr) } break; + case STREAM_PLUGIN_NAME: + Dmsg1(000, "restore stream_plugin_name=%s\n", sd->msg); + plugin_name_stream(jcr, sd->msg); + break; + default: /* If extracting, wierd stream (not 1 or 2), close output file anyway */ if (extract) { @@ -642,7 +665,11 @@ void do_restore(JCR *jcr) deallocate_cipher(rctx); deallocate_fork_cipher(rctx); - set_attributes(jcr, attr, &rctx.bfd); + if (jcr->plugin) { + plugin_set_attributes(jcr, attr, &rctx.bfd); + } else { + set_attributes(jcr, attr, &rctx.bfd); + } /* Verify the cryptographic signature if any */ rctx.type = attr->type; @@ -654,7 +681,7 @@ void do_restore(JCR *jcr) } Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), rctx.stream); - Dmsg2(0, "None of above!!! stream=%d data=%s\n", rctx.stream,sd->msg); + Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg); break; } /* end switch(stream) */ @@ -671,7 +698,11 @@ void do_restore(JCR *jcr) deallocate_cipher(rctx); deallocate_fork_cipher(rctx); - set_attributes(jcr, attr, &rctx.bfd); + if (jcr->plugin) { + plugin_set_attributes(jcr, attr, &rctx.bfd); + } else { + set_attributes(jcr, attr, &rctx.bfd); + } /* Verify the cryptographic signature on the last file, if any */ rctx.type = attr->type; @@ -692,9 +723,9 @@ ok_out: /* Free Signature & Crypto Data */ free_signature(rctx); free_session(rctx); - if (jcr->digest) { - crypto_digest_free(jcr->digest); - jcr->digest = NULL; + if (jcr->crypto.digest) { + crypto_digest_free(jcr->crypto.digest); + jcr->crypto.digest = NULL; } /* Free file cipher restore context */ @@ -775,11 +806,10 @@ static const char *zlib_strerror(int stat) } #endif -static int do_file_digest(FF_PKT *ff_pkt, void *pkt, bool top_level) +static int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { - JCR *jcr = (JCR *)pkt; Dmsg1(50, "do_file_digest jcr=%p\n", jcr); - return (digest_file(jcr, ff_pkt, jcr->digest)); + return (digest_file(jcr, ff_pkt, jcr->crypto.digest)); } /* @@ -801,7 +831,7 @@ static bool verify_signature(JCR *jcr, r_ctx &rctx) SIGNATURE *sig = rctx.sig; - if (!jcr->pki_sign) { + if (!jcr->crypto.pki_sign) { return true; /* no signature OK */ } if (!sig) { @@ -814,26 +844,26 @@ static bool verify_signature(JCR *jcr, r_ctx &rctx) } /* Iterate through the trusted signers */ - foreach_alist(keypair, jcr->pki_signers) { - err = crypto_sign_get_digest(sig, jcr->pki_keypair, algorithm, &digest); + foreach_alist(keypair, jcr->crypto.pki_signers) { + err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest); switch (err) { case CRYPTO_ERROR_NONE: Dmsg0(50, "== Got digest\n"); /* - * We computed jcr->digest using signing_algorithm while writing + * We computed jcr->crypto.digest using signing_algorithm while writing * the file. If it is not the same as the algorithm used for * this file, punt by releasing the computed algorithm and * computing by re-reading the file. */ if (algorithm != signing_algorithm) { - if (jcr->digest) { - crypto_digest_free(jcr->digest); - jcr->digest = NULL; + if (jcr->crypto.digest) { + crypto_digest_free(jcr->crypto.digest); + jcr->crypto.digest = NULL; } } - if (jcr->digest) { + if (jcr->crypto.digest) { /* Use digest computed while writing the file to verify the signature */ - if ((err = crypto_sign_verify(sig, keypair, jcr->digest)) != CRYPTO_ERROR_NONE) { + if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) { Dmsg1(50, "Bad signature on %s\n", jcr->last_fname); Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"), jcr->last_fname, crypto_strerror(err)); @@ -843,12 +873,12 @@ static bool verify_signature(JCR *jcr, r_ctx &rctx) /* Signature found, digest allocated. Old method, * re-read the file and compute the digest */ - jcr->digest = digest; + jcr->crypto.digest = digest; /* Checksum the entire file */ /* Make sure we don't modify JobBytes by saving and restoring it */ saved_bytes = jcr->JobBytes; - if (find_one_file(jcr, jcr->ff, do_file_digest, jcr, jcr->last_fname, (dev_t)-1, 1) != 0) { + if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) { Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"), jcr->last_fname); jcr->JobBytes = saved_bytes; @@ -863,7 +893,7 @@ static bool verify_signature(JCR *jcr, r_ctx &rctx) jcr->last_fname, crypto_strerror(err)); goto bail_out; } - jcr->digest = NULL; + jcr->crypto.digest = NULL; } /* Valid signature */ @@ -959,8 +989,8 @@ static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx) bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp) { - if (jcr->digest) { - crypto_digest_update(jcr->digest, (uint8_t *)data, length); + if (jcr->crypto.digest) { + crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length); } if (win32_decomp) { if (!processWin32BackupAPIBlock(bfd, data, length)) { @@ -1084,7 +1114,6 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, * packet length may be re-read by unser_crypto_packet_len() */ cipher_ctx->packet_len = 0; } - return wsize; }