]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/restore.c
18Jun08
[bacula/bacula] / bacula / src / filed / restore.c
index e71f2c134e8c472f8e057384ae96761d3561f4ec..299b78f9e2a5b33902fbe92add40c289f14028d2 100644 (file)
@@ -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 */
@@ -552,7 +570,7 @@ void do_restore(JCR *jcr)
             }
 
             if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags, 
-                             &rctx.rctxfork_cipher_ctx) < 0) {
+                             &rctx.fork_cipher_ctx) < 0) {
                extract = false;
                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;
 }