]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Minor refactoring of restore decryption code.
authorKern Sibbald <kern@sibbald.com>
Mon, 28 May 2007 18:03:50 +0000 (18:03 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 28 May 2007 18:03:50 +0000 (18:03 +0000)
kes  Add code to smartall.c to detect double free of a buffer.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4926 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/scripts/bacula-ctl-dir.in
bacula/scripts/devel_bacula.in
bacula/src/filed/acl.c
bacula/src/filed/restore.c
bacula/src/lib/address_conf.c
bacula/src/lib/bsys.c
bacula/src/lib/btime.c
bacula/src/lib/signal.c
bacula/src/lib/smartall.c
bacula/src/version.h
bacula/technotes-2.1

index 37d22aff86c52e189545d9528fa53b0ca7ea8bd4..fdebdfbe216d7a901293de90bc38a34a52db2e2a 100644 (file)
@@ -208,7 +208,11 @@ case "$1" in
            OPTIONS="${OPTIONS} -g ${DIR_GROUP}"
         fi
 
-        ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/bacula-dir.conf
+        if [ "${VALGRIND}" != '' ]; then
+           valgrind --leak-check=full ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/bacula-dir.conf
+        else
+           ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/bacula-dir.conf
+        fi
       }
       ;;
 
index bddb7705eeb7525130651ce6ba3776d062fb4064..4a68501db282d2e69e4b27ba7c3290ba46241006 100755 (executable)
@@ -230,8 +230,11 @@ case "$1" in
             OPTIONS="${OPTIONS} -g ${DIR_GROUP}"
          fi
 
-#        valgrind --leak-check=full ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/dird.conf
-         ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/dird.conf
+         if [ "${VALGRIND}" != '' ]; then
+            valgrind --leak-check=full ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/dird.conf
+         else
+            ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/dird.conf
+         fi
        }
        ;;
 
index 5ee3e034e88fc9433c833b07f42edf207bb5878e..bd4124aaeb18e99e0d80eef495817ce6e7487a50 100644 (file)
@@ -1,3 +1,30 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2004-2007 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.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version two of the GNU General Public
+   License as published by the Free Software Foundation plus additions
+   that are listed in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of John Walker.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
 /*
  * Functions to handle ACL for bacula.
  *
  *
  *   Version $Id$
  */
-/*
-   Bacula® - The Network Backup Solution
-
-   Copyright (C) 2004-2006 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.
-   This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
-   License as published by the Free Software Foundation plus additions
-   that are listed in the file LICENSE.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-   Bacula® is a registered trademark of John Walker.
-   The licensor of Bacula is the Free Software Foundation Europe
-   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
-   Switzerland, email:ftf@fsfeurope.org.
-*/
 
 
 #ifndef TEST_PROGRAM
@@ -71,8 +71,8 @@
  */
 #if !defined(HAVE_ACL)              /* ACL support is required, of course */ \
    || !( defined(HAVE_AIX_OS)       /* man page -- may need flags         */ \
-      || defined(HAVE_FREEBSD_OS)   /* tested   -- compile wihtout flags  */ \
-      || defined(HAVE_DARWIN_OS)    /* tested   -- compile wihtout flags  */ \
+      || defined(HAVE_FREEBSD_OS)   /* tested   -- compile without flags  */ \
+      || defined(HAVE_DARWIN_OS)    /* tested   -- compile without flags  */ \
       || defined(HAVE_IRIX_OS)      /* man page -- compile without flags  */ \
       || defined(HAVE_OSF1_OS)      /* man page -- may need -lpacl        */ \
       || defined(HAVE_LINUX_OS)     /* tested   -- compile with -lacl     */ \
@@ -88,6 +88,7 @@
  *    with what we have and give all ACL streams a new number/type.
  */
 #endif
+
 #if !defined(HAVE_ACL) \
    || !( defined(HAVE_LINUX_OS) \
       || defined(HAVE_FREEBSD_OS) \
index 6f5cf607c7eca2caa14cfd31776635634ef9f3f3..2a197a51168d736063dd3b93552dd9f3b566e098 100644 (file)
@@ -39,6 +39,9 @@
 
 #ifdef HAVE_DARWIN_OS
 #include <sys/attr.h>
+const bool have_darwin_os = true;
+#else
+const bool have_darwin_os = false;
 #endif
 
 #if defined(HAVE_CRYPTO)
@@ -47,9 +50,44 @@ const bool have_crypto = true;
 const bool have_crypto = false;
 #endif
 
+#if defined(HAVE_ACL)
+const bool have_acl = true;
+#else
+const bool have_acl = false;
+#endif
+
 /* Data received from Storage Daemon */
 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
 
+typedef struct restore_cipher_ctx {
+   CIPHER_CONTEXT *cipher;
+   uint32_t block_size;
+
+   POOLMEM *buf;       /* Pointer to descryption buffer */
+   int32_t buf_len;    /* Count of bytes currently in buf */ 
+   int32_t packet_len; /* Total bytes in packet */
+} RESTORE_CIPHER_CTX;
+
+struct r_ctx {
+   JCR *jcr;
+   int32_t stream;
+   int32_t prev_stream;
+   BFILE bfd;                          /* File content */
+   uint64_t fileAddr;                  /* file write address */
+   uint32_t size;                      /* Size of file */
+   int flags;                          /* Options for extract_data() */
+   BFILE forkbfd;                       /* Alternative data stream */
+   uint64_t fork_addr;                  /* Write address for alternative stream */
+   intmax_t fork_size;                  /* Size of alternate stream */
+   int fork_flags;                      /* Options for extract_data() */
+
+   SIGNATURE *sig;                     /* Cryptographic signature (if any) for file */
+   CRYPTO_SESSION *cs;                 /* Cryptographic session data (if any) for file */
+   RESTORE_CIPHER_CTX cipher_ctx;     /* Cryptographic restore context (if any) for file */
+   RESTORE_CIPHER_CTX fork_cipher_ctx; /* Cryptographic restore context (if any) for alternative stream */
+};
+
+
 /* Forward referenced functions */
 #if   defined(HAVE_LIBZ)
 static const char *zlib_strerror(int stat);
@@ -58,21 +96,19 @@ const bool have_libz = true;
 const bool have_libz = false;
 #endif
 
-typedef struct restore_cipher_ctx {
-   CIPHER_CONTEXT *cipher;
-   uint32_t block_size;
+static void deallocate_cipher(r_ctx &rctx);
+static void deallocate_fork_cipher(r_ctx &rctx);
+static void free_signature(r_ctx &rctx);
+static void free_session(r_ctx &rctx);
+
 
-   POOLMEM *buf;       /* Pointer to descryption buffer */
-   int32_t buf_len;    /* Count of bytes currently in buf */ 
-   int32_t packet_len; /* Total bytes in packet */
-} RESTORE_CIPHER_CTX;
 
 static bool verify_signature(JCR *jcr, SIGNATURE *sig);
 int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
-      uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
-bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
+                     uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
+bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags, 
+                  RESTORE_CIPHER_CTX *cipher_ctx);
 
-#define RETRY 10                      /* retry wait time */
 
 /*
  * Close a bfd check that we are at the expected file offset.
@@ -94,6 +130,7 @@ int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
    return 0;
 }
 
+
 /*
  * Restore the requested files.
  *
@@ -101,26 +138,18 @@ int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
 void do_restore(JCR *jcr)
 {
    BSOCK *sd;
-   int32_t stream = 0;
-   int32_t prev_stream;
    uint32_t VolSessionId, VolSessionTime;
    bool extract = false;
    int32_t file_index;
    char ec1[50];                       /* Buffer printing huge values */
-   BFILE bfd;                          /* File content */
-   uint64_t fileAddr = 0;              /* file write address */
-   uint32_t size;                      /* Size of file */
-   BFILE altbfd;                       /* Alternative data stream */
-   uint64_t alt_addr = 0;              /* Write address for alternative stream */
-   intmax_t alt_size = 0;              /* Size of alternate stream */
-   SIGNATURE *sig = NULL;              /* Cryptographic signature (if any) for file */
-   CRYPTO_SESSION *cs = NULL;          /* Cryptographic session data (if any) for file */
-   RESTORE_CIPHER_CTX cipher_ctx;     /* Cryptographic restore context (if any) for file */
-   RESTORE_CIPHER_CTX alt_cipher_ctx; /* Cryptographic restore context (if any) for alternative stream */
-   int flags = 0;                      /* Options for extract_data() */
-   int alt_flags = 0;                  /* Options for extract_data() */
+   uint32_t buf_size;                  /* client buffer size */
    int stat;
    ATTR *attr;
+   intmax_t rsrc_len = 0;             /* Original length of resource fork */
+   r_ctx rctx;
+
+   memset(&rctx, 0, sizeof(rctx));
+   rctx.jcr = jcr;
 
    /* The following variables keep track of "known unknowns" */
    int non_support_data = 0;
@@ -129,24 +158,22 @@ void do_restore(JCR *jcr)
    int non_support_finfo = 0;
    int non_support_acl = 0;
    int non_support_progname = 0;
+   int non_support_crypto = 0;
 
-   /* Finally, set up for special configurations */
 #ifdef HAVE_DARWIN_OS
-   intmax_t rsrc_len = 0;             /* Original length of resource fork */
    struct attrlist attrList;
-
    memset(&attrList, 0, sizeof(attrList));
    attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
    attrList.commonattr = ATTR_CMN_FNDRINFO;
 #endif
 
+
    sd = jcr->store_bsock;
    set_jcr_job_status(jcr, JS_Running);
 
    LockRes();
    CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
    UnlockRes();
-   uint32_t buf_size;
    if (client) {
       buf_size = client->max_network_buffer_size;
    } else {
@@ -158,29 +185,7 @@ void do_restore(JCR *jcr)
    }
    jcr->buf_size = sd->msglen;
 
-#ifdef stbernard_implemented
-/  #if defined(HAVE_WIN32)
-   bool        bResumeOfmOnExit = FALSE;
-   if (isOpenFileManagerRunning()) {
-       if ( pauseOpenFileManager() ) {
-          Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
-          bResumeOfmOnExit = TRUE;
-       }
-       else {
-          Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
-       }
-   }
-   {
-       char username[UNLEN+1];
-       DWORD usize = sizeof(username);
-       int privs = enable_backup_privileges(NULL, 1);
-       if (GetUserName(username, &usize)) {
-          Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
-       } else {
-          Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));
-       }
-   }
-#endif
+   /* St Bernard code goes here if implemented */
 
    if (have_libz) {
       uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
@@ -188,19 +193,11 @@ void do_restore(JCR *jcr)
       jcr->compress_buf_size = compress_buf_size;
    }
 
-   cipher_ctx.cipher = NULL;
-   alt_cipher_ctx.cipher = NULL;
    if (have_crypto) {
-      cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
-      cipher_ctx.buf_len = 0;
-      cipher_ctx.packet_len = 0;
-
-      alt_cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
-      alt_cipher_ctx.buf_len = 0;
-      alt_cipher_ctx.packet_len = 0;
-   } else {
-      cipher_ctx.buf = NULL;
-      alt_cipher_ctx.buf = NULL;
+      rctx.cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
+      if (have_darwin_os) {
+         rctx.fork_cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
+      }
    }
    
    /*
@@ -222,59 +219,56 @@ void do_restore(JCR *jcr)
     *   1. bfd for file data.
     *      This fd is opened for non empty files when an attribute stream is
     *      encountered and closed when we find the next attribute stream.
-    *   2. alt_bfd for alternate data streams
+    *   2. fork_bfd for alternate data streams
     *      This fd is opened every time we encounter a new alternate data
     *      stream for the current file. When we find any other stream, we
     *      close it again.
-    *      The expected size of the stream, alt_len, should be set when
+    *      The expected size of the stream, fork_len, should be set when
     *      opening the fd.
     */
-   binit(&bfd);
-   binit(&altbfd);
+   binit(&rctx.bfd);
+   binit(&rctx.forkbfd);
    attr = new_attr();
    jcr->acl_text = get_pool_memory(PM_MESSAGE);
 
    while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
       /* Remember previous stream type */
-      prev_stream = stream;
+      rctx.prev_stream = rctx.stream;
 
       /* First we expect a Stream Record Header */
       if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
-          &stream, &size) != 5) {
+          &rctx.stream, &rctx.size) != 5) {
          Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
          goto bail_out;
       }
       Dmsg4(30, "Got hdr: Files=%d FilInx=%d Stream=%d, %s.\n", 
-            jcr->JobFiles, file_index, stream, stream_to_ascii(stream));
+            jcr->JobFiles, file_index, rctx.stream, stream_to_ascii(rctx.stream));
 
       /* * Now we expect the Stream Data */
       if (bget_msg(sd) < 0) {
          Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
          goto bail_out;
       }
-      if (size != (uint32_t)sd->msglen) {
-         Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
+      if (rctx.size != (uint32_t)sd->msglen) {
+         Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), 
+               sd->msglen, rctx.size);
          goto bail_out;
       }
-      Dmsg3(30, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(stream), 
+      Dmsg3(30, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(rctx.stream), 
             sd->msglen, extract);
 
       /* If we change streams, close and reset alternate data streams */
-      if (prev_stream != stream) {
-         if (is_bopen(&altbfd)) {
-            if (alt_cipher_ctx.cipher) {
-               flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
-               crypto_cipher_free(alt_cipher_ctx.cipher);
-               alt_cipher_ctx.cipher = NULL;
-            }
-            bclose_chksize(jcr, &altbfd, alt_size);
+      if (rctx.prev_stream != rctx.stream) {
+         if (is_bopen(&rctx.forkbfd)) {
+            deallocate_fork_cipher(rctx);
+            bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
          }
-         alt_size = -1; /* Use an impossible value and set a proper one below */
-         alt_addr = 0;
+         rctx.fork_size = -1; /* Use an impossible value and set a proper one below */
+         rctx.fork_addr = 0;
       }
 
       /* File Attributes stream */
-      switch (stream) {
+      switch (rctx.stream) {
       case STREAM_UNIX_ATTRIBUTES:
       case STREAM_UNIX_ATTRIBUTES_EX:
          /*
@@ -282,48 +276,35 @@ void do_restore(JCR *jcr)
           * close the output file and validate the signature.
           */
          if (extract) {
-            if (size > 0 && !is_bopen(&bfd)) {
+            if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
                Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
             }
-            /* Flush and deallocate previous stream's cipher context */
-            if (cipher_ctx.cipher && prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
-               flush_cipher(jcr, &bfd, &fileAddr, flags, &cipher_ctx);
-               crypto_cipher_free(cipher_ctx.cipher);
-               cipher_ctx.cipher = NULL;
-            }
 
-            /* Flush and deallocate previous stream's alt cipher context */
-            if (alt_cipher_ctx.cipher && prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
-               flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
-               crypto_cipher_free(alt_cipher_ctx.cipher);
-               alt_cipher_ctx.cipher = NULL;
+            if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) {
+               deallocate_cipher(rctx);
+               deallocate_fork_cipher(rctx);
             }
-            set_attributes(jcr, attr, &bfd);
+
+            set_attributes(jcr, attr, &rctx.bfd);
             extract = false;
 
             /* Verify the cryptographic signature, if any */
-            verify_signature(jcr, sig);
+            verify_signature(jcr, rctx.sig);
 
             /* Free Signature */
-            if (sig) {
-               crypto_sign_free(sig);
-               sig = NULL;
-            }
-            if (cs) {
-               crypto_session_free(cs);
-               cs = NULL;
-            }
+            free_signature(rctx);
+            free_session(rctx);
             jcr->ff->flags = 0;
             Dmsg0(30, "Stop extracting.\n");
-         } else if (is_bopen(&bfd)) {
+         } else if (is_bopen(&rctx.bfd)) {
             Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
-            bclose(&bfd);
+            bclose(&rctx.bfd);
          }
 
          /*
-          * Unpack and do sanity check fo attributes.
+          * Unpack attributes and do sanity check them
           */
-         if (!unpack_attributes_record(jcr, stream, sd->msg, attr)) {
+         if (!unpack_attributes_record(jcr, rctx.stream, sd->msg, attr)) {
             goto bail_out;
          }
          if (file_index != attr->file_index) {
@@ -353,7 +334,7 @@ void do_restore(JCR *jcr)
           */
          jcr->num_files_examined++;
          extract = false;
-         stat = create_file(jcr, attr, &bfd, jcr->replace);
+         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:
@@ -368,19 +349,19 @@ void do_restore(JCR *jcr)
             jcr->last_type = attr->type;
             jcr->JobFiles++;
             jcr->unlock();
-            fileAddr = 0;
+            rctx.fileAddr = 0;
             print_ls_output(jcr, attr);
 
-#ifdef HAVE_DARWIN_OS
-            /* Only restore the resource fork for regular files */
-            from_base64(&rsrc_len, attr->attrEx);
-            if (attr->type == FT_REG && rsrc_len > 0) {
-               extract = true;
+            if (have_darwin_os) {
+               /* Only restore the resource fork for regular files */
+               from_base64(&rsrc_len, attr->attrEx);
+               if (attr->type == FT_REG && rsrc_len > 0) {
+                  extract = true;
+               }
             }
-#endif
             if (!extract) {
                /* set attributes now because file will not be extracted */
-               set_attributes(jcr, attr, &bfd);
+               set_attributes(jcr, attr, &rctx.bfd);
             }
             break;
          }
@@ -391,10 +372,10 @@ void do_restore(JCR *jcr)
          crypto_error_t cryptoerr;
 
          /* Is this an unexpected session data entry? */
-         if (cs) {
+         if (rctx.cs) {
             Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n"));
             extract = false;
-            bclose(&bfd);
+            bclose(&rctx.bfd);
             continue;
          }
 
@@ -402,12 +383,13 @@ void do_restore(JCR *jcr)
          if (!jcr->pki_recipients) {
             Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n"));
             extract = false;
-            bclose(&bfd);
+            bclose(&rctx.bfd);
             break;
          }
 
          /* Decode and save session keys. */
-         cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, jcr->pki_recipients, &cs);
+         cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, 
+                        jcr->pki_recipients, &rctx.cs);
          switch(cryptoerr) {
          case CRYPTO_ERROR_NONE:
             /* Success */
@@ -426,7 +408,7 @@ void do_restore(JCR *jcr)
 
          if (cryptoerr != CRYPTO_ERROR_NONE) {
             extract = false;
-            bclose(&bfd);
+            bclose(&rctx.bfd);
             continue;
          }
 
@@ -443,55 +425,59 @@ void do_restore(JCR *jcr)
       case STREAM_ENCRYPTED_FILE_GZIP_DATA:
       case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
          /* Force an expected, consistent stream type here */
-         if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES
-                  || prev_stream == STREAM_UNIX_ATTRIBUTES_EX
-                  || prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
-            flags = 0;
-
-            if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) {
-               flags |= FO_SPARSE;
+         if (extract && (rctx.prev_stream == rctx.stream 
+                         || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES
+                         || rctx.prev_stream == STREAM_UNIX_ATTRIBUTES_EX
+                         || rctx.prev_stream == STREAM_ENCRYPTED_SESSION_DATA)) {
+            rctx.flags = 0;
+
+            if (rctx.stream == STREAM_SPARSE_DATA || 
+                rctx.stream == STREAM_SPARSE_GZIP_DATA) {
+               rctx.flags |= FO_SPARSE;
             }
 
-            if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA
-                  || stream == STREAM_WIN32_GZIP_DATA || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
-                  || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
-               flags |= FO_GZIP;
+            if (rctx.stream == STREAM_GZIP_DATA 
+                  || rctx.stream == STREAM_SPARSE_GZIP_DATA
+                  || rctx.stream == STREAM_WIN32_GZIP_DATA
+                  || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
+                  || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {
+               rctx.flags |= FO_GZIP;
             }
 
-            if (stream == STREAM_ENCRYPTED_FILE_DATA
-                  || stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
-                  || stream == STREAM_ENCRYPTED_WIN32_DATA
-                  || stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {               
+            if (rctx.stream == STREAM_ENCRYPTED_FILE_DATA
+                  || rctx.stream == STREAM_ENCRYPTED_FILE_GZIP_DATA
+                  || rctx.stream == STREAM_ENCRYPTED_WIN32_DATA
+                  || rctx.stream == STREAM_ENCRYPTED_WIN32_GZIP_DATA) {               
                /* Set up a decryption context */
-               if (!cipher_ctx.cipher) {
-                  if (!cs) {
+               if (!rctx.cipher_ctx.cipher) {
+                  if (!rctx.cs) {
                      Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
                      extract = false;
-                     bclose(&bfd);
+                     bclose(&rctx.bfd);
                      continue;
                   }
 
-                  if ((cipher_ctx.cipher = crypto_cipher_new(cs, false, &cipher_ctx.block_size)) == NULL) {
+                  if ((rctx.cipher_ctx.cipher = crypto_cipher_new(rctx.cs, false, 
+                           &rctx.cipher_ctx.block_size)) == NULL) {
                      Jmsg1(jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), jcr->last_fname);
-                     crypto_session_free(cs);
-                     cs = NULL;
+                     free_session(rctx);
                      extract = false;
-                     bclose(&bfd);
+                     bclose(&rctx.bfd);
                      continue;
                   }
                }
-               flags |= FO_ENCRYPT;
+               rctx.flags |= FO_ENCRYPT;
             }
 
-            if (is_win32_stream(stream) && !have_win32_api()) {
-               set_portable_backup(&bfd);
-               flags |= FO_WIN32DECOMP;    /* "decompose" BackupWrite data */
+            if (is_win32_stream(rctx.stream) && !have_win32_api()) {
+               set_portable_backup(&rctx.bfd);
+               rctx.flags |= FO_WIN32DECOMP;    /* "decompose" BackupWrite data */
             }
 
-            if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags,
-                             &cipher_ctx) < 0) {
+            if (extract_data(jcr, &rctx.bfd, sd->msg, sd->msglen, &rctx.fileAddr, 
+                             rctx.flags, &rctx.cipher_ctx) < 0) {
                extract = false;
-               bclose(&bfd);
+               bclose(&rctx.bfd);
                continue;
             }
          }
@@ -502,27 +488,26 @@ void do_restore(JCR *jcr)
       case STREAM_ENCRYPTED_MACOS_FORK_DATA:
       case STREAM_MACOS_FORK_DATA:
 #ifdef HAVE_DARWIN_OS
-         alt_flags = 0;
+         fork_flags = 0;
          jcr->ff->flags |= FO_HFSPLUS;
 
          if (stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) {
-            alt_flags |= FO_ENCRYPT;
+            fork_flags |= FO_ENCRYPT;
 
             /* Set up a decryption context */
-            if (extract && !alt_cipher_ctx.cipher) {
+            if (extract && !rctx.fork_cipher_ctx.cipher) {
                if (!cs) {
                   Jmsg1(jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), jcr->last_fname);
                   extract = false;
-                  bclose(&bfd);
+                  bclose(&rctx.bfd);
                   continue;
                }
 
-               if ((alt_cipher_ctx.cipher = crypto_cipher_new(cs, false, &alt_cipher_ctx.block_size)) == NULL) {
+               if ((rctx.fork_cipher_ctx.cipher = crypto_cipher_new(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);
-                  crypto_session_free(cs);
-                  cs = NULL;
+                  free_session(rctx);
                   extract = false;
-                  bclose(&bfd);
+                  bclose(&rctx.bfd);
                   continue;
                }
             }
@@ -530,20 +515,20 @@ void do_restore(JCR *jcr)
 
          if (extract) {
             if (prev_stream != stream) {
-               if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) {
+               if (bopen_rsrc(&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;
                }
 
-               alt_size = rsrc_len;
+               fork_size = rsrc_len;
                Dmsg0(30, "Restoring resource fork\n");
             }
 
-            if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, alt_flags, 
-                             &alt_cipher_ctx) < 0) {
+            if (extract_data(jcr, &forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, fork_flags, 
+                             &rctxfork_cipher_ctx) < 0) {
                extract = false;
-               bclose(&altbfd);
+               bclose(&forkbfd);
                continue;
             }
          }
@@ -570,41 +555,38 @@ void do_restore(JCR *jcr)
          break;
 
       case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:
-#ifdef HAVE_ACL
-         pm_strcpy(jcr->acl_text, sd->msg);
-         Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
-         if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
+         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);
+            if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
                Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
+            }
+         } else {
+            non_support_acl++;
          }
-#else 
-         non_support_acl++;
-#endif
          break;
 
       case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:
-#ifdef HAVE_ACL
-         pm_strcpy(jcr->acl_text, sd->msg);
-         Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
-         if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
+         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);
+            if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
                Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
+            }
+         } else {
+            non_support_acl++;
          }
-#else 
-         non_support_acl++;
-#endif
          break;
 
       case STREAM_SIGNED_DIGEST:
-
          /* Is this an unexpected signature? */
-         if (sig) {
+         if (rctx.sig) {
             Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n"));
-            crypto_sign_free(sig);
-            sig = NULL;
+            free_signature(rctx);
             continue;
          }
-
          /* Save signature. */
-         if (extract && (sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
+         if (extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) {
             Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname);
          }
          break;
@@ -626,35 +608,26 @@ void do_restore(JCR *jcr)
       default:
          /* If extracting, wierd stream (not 1 or 2), close output file anyway */
          if (extract) {
-            Dmsg1(30, "Found wierd stream %d\n", stream);
-            if (size > 0 && !is_bopen(&bfd)) {
+            Dmsg1(30, "Found wierd stream %d\n", rctx.stream);
+            if (rctx.size > 0 && !is_bopen(&rctx.bfd)) {
                Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n"));
             }
             /* Flush and deallocate cipher context */
-            if (cipher_ctx.cipher) {
-               flush_cipher(jcr, &bfd, &fileAddr, flags, &cipher_ctx);
-               crypto_cipher_free(cipher_ctx.cipher);
-               cipher_ctx.cipher = NULL;
-            }
-
-            /* Flush and deallocate alt cipher context */
-            if (alt_cipher_ctx.cipher) {
-               flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
-               crypto_cipher_free(alt_cipher_ctx.cipher);
-               alt_cipher_ctx.cipher = NULL;
-            }
+            deallocate_cipher(rctx);
+            deallocate_fork_cipher(rctx);
 
-            set_attributes(jcr, attr, &bfd);
+            set_attributes(jcr, attr, &rctx.bfd);
 
             /* Verify the cryptographic signature if any */
-            verify_signature(jcr, sig);
+            verify_signature(jcr, rctx.sig);
             extract = false;
-         } else if (is_bopen(&bfd)) {
+         } else if (is_bopen(&rctx.bfd)) {
             Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n"));
-            bclose(&bfd);
+            bclose(&rctx.bfd);
          }
-         Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
-         Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
+         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);
          break;
       } /* end switch(stream) */
 
@@ -663,32 +636,22 @@ void do_restore(JCR *jcr)
    /* If output file is still open, it was the last one in the
     * archive since we just hit an end of file, so close the file.
     */
-   if (is_bopen(&altbfd)) {
-      bclose_chksize(jcr, &altbfd, alt_size);
+   if (is_bopen(&rctx.forkbfd)) {
+      bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size);
    }
    if (extract) {
       /* Flush and deallocate cipher context */
-      if (cipher_ctx.cipher) {
-         flush_cipher(jcr, &bfd, &fileAddr, flags, &cipher_ctx);
-         crypto_cipher_free(cipher_ctx.cipher);
-         cipher_ctx.cipher = NULL;
-      }
-
-      /* Flush and deallocate alt cipher context */
-      if (alt_cipher_ctx.cipher) {
-         flush_cipher(jcr, &altbfd, &alt_addr, alt_flags, &alt_cipher_ctx);
-         crypto_cipher_free(alt_cipher_ctx.cipher);
-         alt_cipher_ctx.cipher = NULL;
-      }
+      deallocate_cipher(rctx);
+      deallocate_fork_cipher(rctx);
 
-      set_attributes(jcr, attr, &bfd);
+      set_attributes(jcr, attr, &rctx.bfd);
 
       /* Verify the cryptographic signature on the last file, if any */
-      verify_signature(jcr, sig);
+      verify_signature(jcr, rctx.sig);
    }
 
-   if (is_bopen(&bfd)) {
-      bclose(&bfd);
+   if (is_bopen(&rctx.bfd)) {
+      bclose(&rctx.bfd);
    }
 
    set_jcr_job_status(jcr, JS_Terminated);
@@ -699,33 +662,27 @@ bail_out:
 
 ok_out:
    /* Free Signature & Crypto Data */
-   if (sig) {
-      crypto_sign_free(sig);
-      sig = NULL;
-   }
-   if (cs) {
-      crypto_session_free(cs);
-      cs = NULL;
-   }
+   free_signature(rctx);
+   free_session(rctx);
 
    /* Free file cipher restore context */
-   if (cipher_ctx.cipher) {
-      crypto_cipher_free(cipher_ctx.cipher);
-      cipher_ctx.cipher = NULL;
+   if (rctx.cipher_ctx.cipher) {
+      crypto_cipher_free(rctx.cipher_ctx.cipher);
+      rctx.cipher_ctx.cipher = NULL;
    }
-   if (cipher_ctx.buf) {
-      free_pool_memory(cipher_ctx.buf);
-      cipher_ctx.buf = NULL;
+   if (rctx.cipher_ctx.buf) {
+      free_pool_memory(rctx.cipher_ctx.buf);
+      rctx.cipher_ctx.buf = NULL;
    }
 
    /* Free alternate stream cipher restore context */
-   if (alt_cipher_ctx.cipher) {
-      crypto_cipher_free(alt_cipher_ctx.cipher);
-      alt_cipher_ctx.cipher = NULL;
+   if (rctx.fork_cipher_ctx.cipher) {
+      crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
+      rctx.fork_cipher_ctx.cipher = NULL;
    }
-   if (alt_cipher_ctx.buf) {
-      free_pool_memory(alt_cipher_ctx.buf);
-      alt_cipher_ctx.buf = NULL;
+   if (rctx.fork_cipher_ctx.buf) {
+      free_pool_memory(rctx.fork_cipher_ctx.buf);
+      rctx.fork_cipher_ctx.buf = NULL;
    }
 
    if (jcr->compress_buf) {
@@ -733,8 +690,8 @@ ok_out:
       jcr->compress_buf = NULL;
       jcr->compress_buf_size = 0;
    }
-   bclose(&altbfd);
-   bclose(&bfd);
+   bclose(&rctx.forkbfd);
+   bclose(&rctx.bfd);
    free_attr(attr);
    free_pool_memory(jcr->acl_text);
    Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
@@ -752,6 +709,9 @@ ok_out:
    if (non_support_acl) {
       Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
    }
+   if (non_support_crypto) {
+      Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
+   }
 
 }
 
@@ -1142,3 +1102,66 @@ again:
 
    return true;
 }
+
+static void deallocate_cipher(r_ctx &rctx)
+{
+   /* Flush and deallocate previous stream's cipher context */
+   if (rctx.cipher_ctx.cipher) {
+      flush_cipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, &rctx.cipher_ctx);
+      crypto_cipher_free(rctx.cipher_ctx.cipher);
+      rctx.cipher_ctx.cipher = NULL;
+   }
+}
+
+static void deallocate_fork_cipher(r_ctx &rctx)
+{
+
+   /* Flush and deallocate previous stream's fork cipher context */
+   if (rctx.fork_cipher_ctx.cipher) {
+      flush_cipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, &rctx.fork_cipher_ctx);
+      crypto_cipher_free(rctx.fork_cipher_ctx.cipher);
+      rctx.fork_cipher_ctx.cipher = NULL;
+   }
+}
+
+static void free_signature(r_ctx &rctx)
+{
+   if (rctx.sig) {
+      crypto_sign_free(rctx.sig);
+      rctx.sig = NULL;
+   }
+}
+
+static void free_session(r_ctx &rctx)
+{
+   if (rctx.cs) {
+      crypto_session_free(rctx.cs);
+      rctx.cs = NULL;
+   }
+}
+
+
+/* This code if implemented goes above */
+#ifdef stbernard_implemented
+/  #if defined(HAVE_WIN32)
+   bool        bResumeOfmOnExit = FALSE;
+   if (isOpenFileManagerRunning()) {
+       if ( pauseOpenFileManager() ) {
+          Jmsg(jcr, M_INFO, 0, _("Open File Manager paused\n") );
+          bResumeOfmOnExit = TRUE;
+       }
+       else {
+          Jmsg(jcr, M_ERROR, 0, _("FAILED to pause Open File Manager\n") );
+       }
+   }
+   {
+       char username[UNLEN+1];
+       DWORD usize = sizeof(username);
+       int privs = enable_backup_privileges(NULL, 1);
+       if (GetUserName(username, &usize)) {
+          Jmsg2(jcr, M_INFO, 0, _("Running as '%s'. Privmask=%#08x\n"), username,
+       } else {
+          Jmsg(jcr, M_WARNING, 0, _("Failed to retrieve current UserName\n"));
+       }
+   }
+#endif
index b79ae3b487d2361daf2d2e913ff68bb8aa14f286..678056c6982aea79ff7c7955ced743bde04bbc8d 100644 (file)
@@ -1,14 +1,7 @@
-/*
- *   Configuration file parser for IP-Addresse ipv4 and ipv6
- *
- *     Written by Meno Abels, June MMIV
- *
- *     Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2004-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2004-2007 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.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *   Configuration file parser for IP-Addresse ipv4 and ipv6
+ *
+ *     Written by Meno Abels, June MMIV
+ *
+ *     Version $Id$
+ */
 
 
 #include "bacula.h"
@@ -43,7 +43,7 @@
 #endif
 
 static int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultport, int family,
-                const char *hostname_str, const char *port_str, char **errstr);
+                const char *hostname_str, const char *port_str, char *buf, int buflen);
 
 
 IPADDR::IPADDR(const IPADDR &src) : type(src.type)
@@ -233,12 +233,12 @@ const char *build_addresses_str(dlist *addrs, char *buf, int blen)
    return buf;
 }
 
-const char *get_first_address(dlist * addrs, char *outputbuf, int outlen)
+const char *get_first_address(dlist *addrs, char *outputbuf, int outlen)
 {
    return ((IPADDR *)(addrs->first()))->get_address(outputbuf, outlen);
 }
 
-int get_first_port_net_order(dlist * addrs)
+int get_first_port_net_order(dlist *addrs)
 {
    if (!addrs) {
       return 0;
@@ -247,7 +247,7 @@ int get_first_port_net_order(dlist * addrs)
    }
 }
 
-int get_first_port_host_order(dlist * addrs)
+int get_first_port_host_order(dlist *addrs)
 {
    if (!addrs) {
       return 0;
@@ -258,16 +258,15 @@ int get_first_port_host_order(dlist * addrs)
 
 void init_default_addresses(dlist **out, int port)
 {
-   char *errstr;
+   char buf[1024];
    unsigned short sport = port;
-   if (!add_address(out, IPADDR::R_DEFAULT, htons(sport), AF_INET, 0, 0, &errstr)) {
-      Emsg1(M_ERROR_TERM, 0, _("Can't add default address (%s)\n"), errstr);
-      free(errstr);
+   if (!add_address(out, IPADDR::R_DEFAULT, htons(sport), AF_INET, 0, 0, buf, sizeof(buf))) {
+      Emsg1(M_ERROR_TERM, 0, _("Can't add default address (%s)\n"), buf);
    }
 }
 
 static int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultport, int family,
-                const char *hostname_str, const char *port_str, char **errstr)
+                const char *hostname_str, const char *port_str, char *buf, int buflen)
 {
    IPADDR *iaddr;
    IPADDR *jaddr;
@@ -275,6 +274,7 @@ static int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultp
    unsigned short port;
    IPADDR::i_type intype = type;
 
+   buf[0] = 0;
    dlist *addrs = (dlist *)(*(out));
    if (!addrs) {
       IPADDR *tmp = 0;
@@ -289,8 +289,7 @@ static int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultp
          if (iaddr->get_type() == IPADDR::R_DEFAULT) {
             def = iaddr;
          } else if (iaddr->get_type() != type) {
-            *errstr = (char *)malloc(1024);
-            bsnprintf(*errstr, 1023,
+            bsnprintf(buf, buflen,
                       _("the old style addresses cannot be mixed with new style"));
             return 0;
          }
@@ -301,7 +300,6 @@ static int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultp
       }
    }
 
-
    if (!port_str || port_str[0] == '\0') {
       port = defaultport;
    } else {
@@ -313,8 +311,7 @@ static int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultp
          if (s) {
             port = s->s_port;
          } else {
-            *errstr = (char *)malloc(1024);
-            bsnprintf(*errstr, 1023, _("can't resolve service(%s)"), port_str);
+            bsnprintf(buf, buflen, _("can't resolve service(%s)"), port_str);
             return 0;
          }
       }
@@ -323,8 +320,7 @@ static int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultp
    const char *myerrstr;
    hostaddrs = bnet_host2ipaddrs(hostname_str, family, &myerrstr);
    if (!hostaddrs) {
-      *errstr = (char *)malloc(1024);
-      bsnprintf(*errstr, 1023, _("can't resolve hostname(%s) %s"), hostname_str,
+      bsnprintf(buf, buflen, _("can't resolve hostname(%s) %s"), hostname_str,
                 myerrstr);
       return 0;
    }
@@ -344,7 +340,7 @@ static int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultp
          addr->set_port_net(port);
       }
       if (intype == IPADDR::R_SINGLE_ADDR) {
-         addr->copy_addr((IPADDR *) (hostaddrs->first()));
+         addr->copy_addr((IPADDR *)(hostaddrs->first()));
       }
    } else {
       foreach_dlist(iaddr, hostaddrs) {
@@ -409,6 +405,7 @@ void store_addresses(LEX * lc, RES_ITEM * item, int index, int pass)
    char hostname_str[1024];
    char port_str[128];
    int family = 0;
+   char errmsg[1024];
 
 
    token = lex_get_token(lc, T_SKIP_EOL);
@@ -499,12 +496,11 @@ void store_addresses(LEX * lc, RES_ITEM * item, int index, int pass)
          scan_err1(lc, _("Expected a end of block }, got: %s"), lc->str);
       }
 
-      char *errstr;
       if (pass == 1 && !add_address((dlist **)(item->value), IPADDR::R_MULTIPLE,
-               htons(item->default_value), family, hostname_str, port_str, &errstr)) {
+               htons(item->default_value), family, hostname_str, port_str, 
+               errmsg, sizeof(errmsg))) {
            scan_err3(lc, _("Can't add hostname(%s) and port(%s) to addrlist (%s)"),
-                   hostname_str, port_str, errstr);
-           free(errstr);
+                   hostname_str, port_str, errmsg);
         }
       token = scan_to_next_not_eol(lc);
    } while ((token == T_IDENTIFIER || token == T_UNQUOTED_STRING));
@@ -515,30 +511,29 @@ void store_addresses(LEX * lc, RES_ITEM * item, int index, int pass)
 
 void store_addresses_address(LEX * lc, RES_ITEM * item, int index, int pass)
 {
-
+   char errmsg[1024];
    int token = lex_get_token(lc, T_SKIP_EOL);
    if (!(token == T_UNQUOTED_STRING || token == T_NUMBER || token == T_IDENTIFIER)) {
       scan_err1(lc, _("Expected an IP number or a hostname, got: %s"), lc->str);
    }
-   char *errstr;
-   if (pass == 1 && !add_address((dlist **) (item->value), IPADDR::R_SINGLE_ADDR,
-                    htons(item->default_value), AF_INET, lc->str, 0, &errstr)) {
-      scan_err2(lc, _("can't add port (%s) to (%s)"), lc->str, errstr);
-      free(errstr);
+   if (pass == 1 && !add_address((dlist **)(item->value), IPADDR::R_SINGLE_ADDR,
+                    htons(item->default_value), AF_INET, lc->str, 0, 
+                    errmsg, sizeof(errmsg))) {
+      scan_err2(lc, _("can't add port (%s) to (%s)"), lc->str, errmsg);
    }
 }
 
 void store_addresses_port(LEX * lc, RES_ITEM * item, int index, int pass)
 {
+   char errmsg[1024];
    int token = lex_get_token(lc, T_SKIP_EOL);
    if (!(token == T_UNQUOTED_STRING || token == T_NUMBER || token == T_IDENTIFIER)) {
       scan_err1(lc, _("Expected a port number or string, got: %s"), lc->str);
    }
-   char *errstr;
    if (pass == 1 && !add_address((dlist **)(item->value), IPADDR::R_SINGLE_PORT,
-                    htons(item->default_value), AF_INET, 0, lc->str, &errstr)) {
-      scan_err2(lc, _("can't add port (%s) to (%s)"), lc->str, errstr);
-      free(errstr);
+                    htons(item->default_value), AF_INET, 0, lc->str, 
+                    errmsg, sizeof(errmsg))) {
+      scan_err2(lc, _("can't add port (%s) to (%s)"), lc->str, errmsg);
    }
 }
 
index 0c741c4b0bb1661314453fcfa9a3ca903c8288bb..bbfaf6eeea8848e0cebf40a7f660bd2a7e4d6b5f 100644 (file)
@@ -234,7 +234,11 @@ void bfree(void *buf)
 
 void *brealloc (void *buf, size_t size)
 {
+#ifdef SMARTALOC
+   buf = sm_realloc(__FILE__, __LINE__, buf, size);
+#else
    buf = realloc(buf, size);
+#endif
    if (buf == NULL) {
       berrno be;
       Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
@@ -243,7 +247,7 @@ void *brealloc (void *buf, size_t size)
 }
 
 
-void *bcalloc (size_t size1, size_t size2)
+void *bcalloc(size_t size1, size_t size2)
 {
   void *buf;
 
index fbaacafdce7e2ff284c6639a951018a3ee4b6c1f..58487769b2f617592a8a15217a77e57ebc158fc1 100644 (file)
@@ -94,12 +94,19 @@ char *bstrftime_nc(char *dt, int maxlen, utime_t tim)
 {
    time_t ttime = (time_t)tim;
    struct tm tm;
+   char *p, *q;
 
    /* ***FIXME**** the format and localtime_r() should be user configurable */
    (void)localtime_r(&ttime, &tm);
    /* NOTE! since the compiler complains about %y, I use %y and cut the century */
    strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm);
-   strcpy(dt+7, dt+9);             /* overlay the century */
+   /* overlay the century */
+   p = dt+7;
+   q = dt+9;
+   while (*q) {
+      *p++ = *q++;
+   }
+   *p = 0;
    return dt;
 }
 
index f5a624af82188f4f22b393b21bfc258b787339c4..f395122b3102b9e8a611993eca521eb5e5e2fae8 100644 (file)
@@ -301,7 +301,7 @@ void init_signals(void terminate(int sig))
    sigaction(SIGEMT,    &sighandle, NULL);
 #endif
 #ifdef SIGIOT
-/* sigaction(SIGIOT,    &sighandle, NULL);  used by debugger */
+   sigaction(SIGIOT,    &sighandle, NULL);                     
 #endif
    sigaction(SIGBUS,    &sighandle, NULL);
    sigaction(SIGFPE,    &sighandle, NULL);
index 8101067eac631019266b8560716679ec3fbb32cf..7f2ed1b2f85cc1ed32a2007c949c4a6d32291244 100644 (file)
@@ -91,6 +91,7 @@ struct abufhead {
    unsigned ablen;             /* Buffer length in bytes */
    const char *abfname;        /* File name pointer */
    sm_ushort ablineno;         /* Line number of allocation */
+   bool abin_use;              /* set when malloced and cleared when free */
 };
 
 static struct b_queue abqueue = {    /* Allocated buffer queue */
@@ -128,7 +129,8 @@ static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
       qinsert(&abqueue, (struct b_queue *) buf);
       head->ablen = nbytes;
       head->abfname = bufimode ? NULL : fname;
-      head->ablineno = (sm_ushort) lineno;
+      head->ablineno = (sm_ushort)lineno;
+      head->abin_use = true;
       /* Emplace end-clobber detector at end of buffer */
       buf[nbytes - 1] = (uint8_t)((((long) buf) & 0xFF) ^ 0xC5);
       buf += HEAD_SIZE;  /* Increment to user data start */
@@ -160,6 +162,7 @@ void sm_new_owner(const char *fname, int lineno, char *buf)
    buf -= HEAD_SIZE;  /* Decrement to header */
    ((struct abufhead *)buf)->abfname = bufimode ? NULL : fname;
    ((struct abufhead *)buf)->ablineno = (sm_ushort) lineno;
+   ((struct abufhead *)buf)->abin_use = true;
    return;
 }
 
@@ -186,6 +189,12 @@ void sm_free(const char *file, int line, void *fp)
          head->ablen, fp,
          head->abfname, head->ablineno);
 
+   if (!head->abin_use) {
+      V(mutex);
+      Emsg2(M_ABORT, 0, _("double free from %s:%d\n"), file, line);
+   }
+   head->abin_use = false;
+
    /* The following assertions will catch virtually every release
       of an address which isn't an allocated buffer. */
    if (qp->qnext->qprev != qp) {
@@ -217,9 +226,13 @@ void sm_free(const char *file, int line, void *fp)
       "designer  garbage"  (Duff  Kurland's  phrase) of alternating
       bits.  This is intended to ruin the day for any miscreant who
       attempts to access data through a pointer into storage that's
-      been previously released. */
+      been previously released.
+
+      Modified, kes May, 2007 to not zap the header. This allows us
+      to check the in_use bit and detect doubly freed buffers.
+   */
 
-   memset(cp, 0xAA, (int) head->ablen);
+   memset(cp+HEAD_SIZE, 0xAA, (int)(head->ablen - HEAD_SIZE));
 
    free(cp);
 }
@@ -282,14 +295,12 @@ void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
    /*  If  the  old  block  pointer  is  NULL, treat realloc() as a
       malloc().  SVID is silent  on  this,  but  many  C  libraries
       permit this.  */
-
    if (ptr == NULL) {
       return sm_malloc(fname, lineno, size);
    }
 
    /* If the old and new sizes are the same, be a nice guy and just
       return the buffer passed in.  */
-
    cp -= HEAD_SIZE;
    struct abufhead *head = (struct abufhead *)cp;
    osize = head->ablen - (HEAD_SIZE + 1);
@@ -306,7 +317,7 @@ void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
 // sm_bytes -= head->ablen;
 
    if ((buf = smalloc(fname, lineno, size)) != NULL) {
-      memcpy(buf, ptr, (int) sm_min(size, osize));
+      memcpy(buf, ptr, (int)sm_min(size, osize));
       /* If the new buffer is larger than the old, fill the balance
          of it with "designer garbage". */
       if (size > osize) {
@@ -314,7 +325,6 @@ void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
       }
 
       /* All done.  Free and dechain the original buffer. */
-
       sm_free(__FILE__, __LINE__, ptr);
    }
    Dmsg4(150, _("sm_realloc %d at %x from %s:%d\n"), size, buf, fname, lineno);
index 70a4f489b353f0ff5c04bbb51bac26ad2bb2b063..0b2b7c6222066a83984644fb859d6461dfdca743 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "2.1.11"
-#define BDATE   "26 May 2007"
-#define LSMDATE "26May07"
+#define BDATE   "28 May 2007"
+#define LSMDATE "28May07"
 
 #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
 #define BYEAR "2007"       /* year for copyright messages in progs */
index 64f75bbb857992ee04d49d071caaa70781fbe062..0249a337e6541629aee047a30d2f75ef1640bce3 100644 (file)
@@ -1,6 +1,9 @@
               Technical notes on version 2.1
 
 General:
+28May07
+kes  Minor refactoring of restore decryption code.
+kes  Add code to smartall.c to detect double free of a buffer.
 27May07
 kes  Add < > around %r in from field on mail command of bacula-dir.conf.in
      so that bsmtp will create a correct email address (mailbox only).