From 2d97b8834a2c5d3e29855bf7f2bc49a6c4ceb51d Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 22 Feb 2007 15:31:08 +0000 Subject: [PATCH] kes Begin implementing new comm signals for API. kes Fix a few places in lib/message.c where the open fd may not be zeroed. kes Continue implementing lib/bsock.c (real class). Make jcr, who, host, and port private. There are new methods to access them for non-class use. This required touching a number of files. 21Feb07 kes Add LANG=C to autoconf/randpass so it works with languages other than English. Fixes bug #788. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4233 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/AUTHORS | 1 + bacula/autoconf/randpass | 1 + bacula/src/cats/mysql.c | 25 ++-- bacula/src/dird/authenticate.c | 44 +++--- bacula/src/dird/ua_dotcmds.c | 12 +- bacula/src/filed/authenticate.c | 20 +-- bacula/src/filed/job.c | 2 +- bacula/src/lib/bnet.c | 232 +++++++------------------------ bacula/src/lib/bsock.c | 187 ++++++++++++++++++++++++- bacula/src/lib/bsock.h | 27 +++- bacula/src/lib/crypto.c | 40 +++--- bacula/src/lib/message.c | 13 +- bacula/src/stored/acquire.c | 14 +- bacula/src/stored/authenticate.c | 28 ++-- bacula/src/stored/dircmd.c | 2 +- bacula/src/stored/fd_cmds.c | 4 +- bacula/src/stored/job.c | 2 +- bacula/src/version.h | 4 +- bacula/technotes-2.1 | 10 ++ 19 files changed, 372 insertions(+), 296 deletions(-) diff --git a/bacula/AUTHORS b/bacula/AUTHORS index 16372396f8..70463722ea 100644 --- a/bacula/AUTHORS +++ b/bacula/AUTHORS @@ -27,6 +27,7 @@ Daniele Eccher David Boyes David Duchscher D. Scott Barninger +Devin Reade Eamon Brosnan Eric Bollengier Erich Prinz diff --git a/bacula/autoconf/randpass b/bacula/autoconf/randpass index af30bfb929..2294a23331 100755 --- a/bacula/autoconf/randpass +++ b/bacula/autoconf/randpass @@ -3,6 +3,7 @@ # Generate a random password, written to standard output # By John Walker # +LANG=C if test "x$1" = "x" ; then PWL=48 # Password length in characters else diff --git a/bacula/src/cats/mysql.c b/bacula/src/cats/mysql.c index fc2d008e68..8e9e5261cf 100644 --- a/bacula/src/cats/mysql.c +++ b/bacula/src/cats/mysql.c @@ -1,16 +1,7 @@ -/* - * Bacula Catalog Database routines specific to MySQL - * These are MySQL specific routines -- hopefully all - * other files are generic. - * - * Kern Sibbald, March 2000 - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2006 Free Software Foundation Europe e.V. + Copyright (C) 2000-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. @@ -34,6 +25,15 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Bacula Catalog Database routines specific to MySQL + * These are MySQL specific routines -- hopefully all + * other files are generic. + * + * Kern Sibbald, March 2000 + * + * Version $Id$ + */ /* The following is necessary so that we do not include @@ -375,8 +375,8 @@ int db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler } char *my_mysql_batch_lock_path_query = "LOCK TABLES Path write, " - " batch write, " - " Path as p write "; + " batch write, " + " Path as p write "; char *my_mysql_batch_lock_filename_query = "LOCK TABLES Filename write, " @@ -404,4 +404,3 @@ char *my_mysql_batch_fill_filename_query = "INSERT IGNORE INTO Filename (Name)" " WHERE f.Name = a.Name) "; #endif /* HAVE_MYSQL */ - diff --git a/bacula/src/dird/authenticate.c b/bacula/src/dird/authenticate.c index 799f8e255f..a8fdbbbdda 100644 --- a/bacula/src/dird/authenticate.c +++ b/bacula/src/dird/authenticate.c @@ -95,10 +95,10 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store) if (auth_success) { auth_success = cram_md5_challenge(sd, store->password, tls_local_need, compatible); if (!auth_success) { - Dmsg1(50, "cram_challenge failed for %s\n", sd->who); + Dmsg1(50, "cram_challenge failed for %s\n", sd->who()); } } else { - Dmsg1(50, "cram_respond failed for %s\n", sd->who); + Dmsg1(50, "cram_respond failed for %s\n", sd->who()); } if (!auth_success) { @@ -110,7 +110,7 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store) "Maximum Concurrent Jobs exceeded on the SD or\n" "SD networking messed up (restart daemon).\n" "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"), - sd->host, sd->port); + sd->host(), sd->port()); return 0; } @@ -134,7 +134,7 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store) if (!bnet_tls_client(store->tls_ctx, sd)) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD on \"%s:%d\"\n"), - sd->host, sd->port); + sd->host(), sd->port()); return 0; } } @@ -143,7 +143,7 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store) if (bnet_recv(sd) <= 0) { stop_bsock_timer(tid); Jmsg3(jcr, M_FATAL, 0, _("bdirdwho, sd->host, bnet_strerror(sd)); + sd->who(), sd->host(), bnet_strerror(sd)); return 0; } Dmsg1(110, "msg); @@ -151,7 +151,7 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store) if (strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) { Dmsg0(50, _("Storage daemon rejected Hello command\n")); Jmsg2(jcr, M_FATAL, 0, _("Storage daemon on \"%s:%d\" rejected Hello command\n"), - sd->host, sd->port); + sd->host(), sd->port()); return 0; } return 1; @@ -180,7 +180,7 @@ int authenticate_file_daemon(JCR *jcr) if (!bnet_fsend(fd, hello, dirname)) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon on \"%s:%d\". ERR=%s\n"), - fd->host, fd->port, bnet_strerror(fd)); + fd->host(), fd->port(), bnet_strerror(fd)); return 0; } Dmsg1(50, "Sent: %s", fd->msg); @@ -198,10 +198,10 @@ int authenticate_file_daemon(JCR *jcr) if (auth_success) { auth_success = cram_md5_challenge(fd, client->password, tls_local_need, compatible); if (!auth_success) { - Dmsg1(50, "cram_auth failed for %s\n", fd->who); + Dmsg1(50, "cram_auth failed for %s\n", fd->who()); } } else { - Dmsg1(50, "cram_get_auth failed for %s\n", fd->who); + Dmsg1(50, "cram_get_auth failed for %s\n", fd->who()); } if (!auth_success) { stop_bsock_timer(tid); @@ -212,7 +212,7 @@ int authenticate_file_daemon(JCR *jcr) "Maximum Concurrent Jobs exceeded on the FD or\n" "FD networking messed up (restart daemon).\n" "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"), - fd->host, fd->port); + fd->host(), fd->port()); return 0; } @@ -220,7 +220,7 @@ int authenticate_file_daemon(JCR *jcr) if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD \"%s:%s\" did not advertise required TLS support.\n"), - fd->who, fd->host); + fd->who(), fd->host()); return 0; } @@ -228,7 +228,7 @@ int authenticate_file_daemon(JCR *jcr) if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD on \"%s:%d\" requires TLS.\n"), - fd->host, fd->port); + fd->host(), fd->port()); return 0; } @@ -238,7 +238,7 @@ int authenticate_file_daemon(JCR *jcr) if (!bnet_tls_client(client->tls_ctx, fd)) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD on \"%s:%d\".\n"), - fd->host, fd->port); + fd->host(), fd->port()); return 0; } } @@ -249,7 +249,7 @@ int authenticate_file_daemon(JCR *jcr) Dmsg1(50, _("Bad response from File daemon to Hello command: ERR=%s\n"), bnet_strerror(fd)); Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon on \"%s:%d\" to Hello command: ERR=%s\n"), - fd->host, fd->port, bnet_strerror(fd)); + fd->host(), fd->port(), bnet_strerror(fd)); return 0; } Dmsg1(110, "msg); @@ -257,7 +257,7 @@ int authenticate_file_daemon(JCR *jcr) if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) { Dmsg0(50, _("File daemon rejected Hello command\n")); Jmsg(jcr, M_FATAL, 0, _("File daemon on \"%s:%d\" rejected Hello command\n"), - fd->host, fd->port); + fd->host(), fd->port()); return 0; } return 1; @@ -279,18 +279,18 @@ int authenticate_user_agent(UAContext *uac) alist *verify_list = NULL; -// Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who, -// ua->host, ua->port, ua->msglen); +// Emsg4(M_INFO, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(), +// ua->host(), ua->port(), ua->msglen); if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) { - Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who, - ua->host, ua->port, ua->msglen); + Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(), + ua->host(), ua->port(), ua->msglen); return 0; } if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) { ua->msg[100] = 0; /* terminate string */ - Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who, - ua->host, ua->port, ua->msg); + Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(), + ua->host(), ua->port(), ua->msg); return 0; } @@ -379,7 +379,7 @@ auth_done: if (!auth_success) { bnet_fsend(ua, "%s", _(Dir_sorry)); Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"), - name, ua->who, ua->host, ua->port); + name, ua->who(), ua->host(), ua->port()); sleep(5); return 0; } diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index 53326616d7..a236ff3c2e 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -91,7 +91,7 @@ static struct cmdstruct commands[] = { { NT_(".storage"), storagecmd, NULL}, { NT_(".types"), typescmd, NULL} }; -#define comsize (sizeof(commands)/sizeof(struct cmdstruct)) +#define comsize ((int)(sizeof(commands)/sizeof(struct cmdstruct))) /* * Execute a command from the UA @@ -113,13 +113,11 @@ int do_a_dot_command(UAContext *ua, const char *cmd) if (len == 1) { return 1; /* no op */ } - for (i=0; i<(int)comsize; i++) { /* search for command */ + for (i=0; iargk[0], _(commands[i].key), len) == 0) { bool gui = ua->gui; ua->gui = true; - if (ua->api) { - sock->signal(BNET_CMD_BEGIN); - } + if (ua->api) sock->signal(BNET_CMD_BEGIN); ok = (*commands[i].func)(ua, cmd); /* go execute command */ ua->gui = gui; found = true; @@ -130,9 +128,9 @@ int do_a_dot_command(UAContext *ua, const char *cmd) pm_strcat(sock->msg, _(": is an invalid command\n")); sock->msglen = strlen(sock->msg); sock->send(); - sock->signal(BNET_INVALID_CMD); + if (ua->api) sock->signal(BNET_INVALID_CMD); } - sock->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED); + if (ua->api) sock->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED); return 1; } diff --git a/bacula/src/filed/authenticate.c b/bacula/src/filed/authenticate.c index fa09accd87..0a326e9435 100644 --- a/bacula/src/filed/authenticate.c +++ b/bacula/src/filed/authenticate.c @@ -62,9 +62,9 @@ static bool authenticate(int rcode, BSOCK *bs, JCR* jcr) } if (bs->msglen < 25 || bs->msglen > 500) { Dmsg2(50, "Bad Hello command from Director at %s. Len=%d.\n", - bs->who, bs->msglen); + bs->who(), bs->msglen); char addr[64]; - char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr; + char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr; Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"), who, bs->msglen); goto auth_fatal; @@ -73,10 +73,10 @@ static bool authenticate(int rcode, BSOCK *bs, JCR* jcr) if (sscanf(bs->msg, "Hello Director %s calling", dirname) != 1) { char addr[64]; - char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr; + char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr; bs->msg[100] = 0; Dmsg2(50, "Bad Hello command from Director at %s: %s\n", - bs->who, bs->msg); + bs->who(), bs->msg); Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"), who, bs->msg); goto auth_fatal; @@ -88,7 +88,7 @@ static bool authenticate(int rcode, BSOCK *bs, JCR* jcr) } if (!director) { char addr[64]; - char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr; + char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr; Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"), dirname, who); goto auth_fatal; @@ -120,17 +120,17 @@ static bool authenticate(int rcode, BSOCK *bs, JCR* jcr) auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible); if (!auth_success) { char addr[64]; - char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr; + char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr; Dmsg1(50, "cram_get_auth failed for %s\n", who); } } else { char addr[64]; - char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr; + char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr; Dmsg1(50, "cram_auth failed for %s\n", who); } if (!auth_success) { Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"), - bs->who); + bs->who()); goto auth_fatal; } @@ -231,12 +231,12 @@ int authenticate_storagedaemon(JCR *jcr) goto auth_fatal; } if (!auth_success) { - Dmsg1(50, "cram_respond failed for %s\n", sd->who); + Dmsg1(50, "cram_respond failed for %s\n", sd->who()); } else { /* Now challenge him */ auth_success = cram_md5_challenge(sd, jcr->sd_auth_key, tls_local_need, compatible); if (!auth_success) { - Dmsg1(50, "cram_challenge failed for %s\n", sd->who); + Dmsg1(50, "cram_challenge failed for %s\n", sd->who()); } } diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index c29b2461e5..89aa461d58 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -217,7 +217,7 @@ void *handle_client_request(void *dirp) jcr->pki_keypair = me->pki_keypair; jcr->pki_signers = me->pki_signers; jcr->pki_recipients = me->pki_recipients; - dir->jcr = jcr; + dir->set_jcr(jcr); enable_backup_privileges(NULL, 1 /* ignore_errors */); /**********FIXME******* add command handler error code */ diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index 20986a4f2b..7dc1f143fb 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -119,7 +119,7 @@ int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes) if (nwritten != nbytes) { berrno be; bsock->b_errno = errno; - Qmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"), + Qmsg1(bsock->jcr(), M_FATAL, 0, _("Attr spool write error. ERR=%s\n"), be.strerror()); Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes); errno = bsock->b_errno; @@ -188,105 +188,7 @@ int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes) */ int32_t bnet_recv(BSOCK * bsock) { - int32_t nbytes; - int32_t pktsiz; - - if (!bsock) { - return BNET_HARDEOF; - } - bsock->msg[0] = 0; - bsock->msglen = 0; - if (bsock->errors || bsock->terminated) { - return BNET_HARDEOF; - } - - bsock->read_seqno++; /* bump sequence number */ - bsock->timer_start = watchdog_time; /* set start wait time */ - bsock->timed_out = 0; - /* get data size -- in int32_t */ - if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) { - bsock->timer_start = 0; /* clear timer */ - /* probably pipe broken because client died */ - if (errno == 0) { - bsock->b_errno = ENODATA; - } else { - bsock->b_errno = errno; - } - bsock->errors++; - return BNET_HARDEOF; /* assume hard EOF received */ - } - bsock->timer_start = 0; /* clear timer */ - if (nbytes != sizeof(int32_t)) { - bsock->errors++; - bsock->b_errno = EIO; - Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), - sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port); - return BNET_ERROR; - } - - pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */ - - if (pktsiz == 0) { /* No data transferred */ - bsock->timer_start = 0; /* clear timer */ - bsock->in_msg_no++; - bsock->msglen = 0; - return 0; /* zero bytes read */ - } - - /* If signal or packet size too big */ - if (pktsiz < 0 || pktsiz > 1000000) { - if (pktsiz > 0) { /* if packet too big */ - Qmsg3(bsock->jcr, M_FATAL, 0, - _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"), - bsock->who, bsock->host, bsock->port); - pktsiz = BNET_TERMINATE; /* hang up */ - } - if (pktsiz == BNET_TERMINATE) { - bsock->terminated = 1; - } - bsock->timer_start = 0; /* clear timer */ - bsock->b_errno = ENODATA; - bsock->msglen = pktsiz; /* signal code */ - return BNET_SIGNAL; /* signal */ - } - - /* Make sure the buffer is big enough + one byte for EOS */ - if (pktsiz >= (int32_t) sizeof_pool_memory(bsock->msg)) { - bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100); - } - - bsock->timer_start = watchdog_time; /* set start wait time */ - bsock->timed_out = 0; - /* now read the actual data */ - if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) { - bsock->timer_start = 0; /* clear timer */ - if (errno == 0) { - bsock->b_errno = ENODATA; - } else { - bsock->b_errno = errno; - } - bsock->errors++; - Qmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"), - bsock->who, bsock->host, bsock->port, bnet_strerror(bsock)); - return BNET_ERROR; - } - bsock->timer_start = 0; /* clear timer */ - bsock->in_msg_no++; - bsock->msglen = nbytes; - if (nbytes != pktsiz) { - bsock->b_errno = EIO; - bsock->errors++; - Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), - pktsiz, nbytes, bsock->who, bsock->host, bsock->port); - return BNET_ERROR; - } - /* always add a zero by to properly terminate any - * string that was send to us. Note, we ensured above that the - * buffer is at least one byte longer than the message length. - */ - bsock->msg[nbytes] = 0; /* terminate in case it is a string */ - sm_check(__FILE__, __LINE__, false); - return nbytes; /* return actual length of message */ + return bsock->recv(); } @@ -342,7 +244,7 @@ int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t siz if (nbytes != (size_t) bsock->msglen) { berrno be; Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen); - Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"), + Qmsg1(bsock->jcr(), M_FATAL, 0, _("fread attr spool error. ERR=%s\n"), be.strerror()); update_attr_spool_size(tsize - last); return 0; @@ -358,7 +260,7 @@ int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t siz update_attr_spool_size(tsize - last); if (ferror(bsock->spool_fd)) { berrno be; - Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"), + Qmsg1(bsock->jcr(), M_FATAL, 0, _("fread attr spool error. ERR=%s\n"), be.strerror()); return 0; } @@ -407,15 +309,15 @@ bool bnet_send(BSOCK * bsock) } if (rc < 0) { if (!bsock->suppress_error_msgs && !bsock->timed_out) { - Qmsg4(bsock->jcr, M_ERROR, 0, + Qmsg4(bsock->jcr(), M_ERROR, 0, _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who, - bsock->host, bsock->port, bnet_strerror(bsock)); + bsock->host(), bsock->port(), bnet_strerror(bsock)); } } else { - Qmsg5(bsock->jcr, M_ERROR, 0, + Qmsg5(bsock->jcr(), M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), - sizeof(int32_t), bsock->who, - bsock->host, bsock->port, rc); + sizeof(int32_t), bsock->who(), + bsock->host(), bsock->port(), rc); } return false; } @@ -439,15 +341,16 @@ bool bnet_send(BSOCK * bsock) } if (rc < 0) { if (!bsock->suppress_error_msgs) { - Qmsg5(bsock->jcr, M_ERROR, 0, + Qmsg5(bsock->jcr(), M_ERROR, 0, _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"), - bsock->msglen, bsock->who, - bsock->host, bsock->port, bnet_strerror(bsock)); + bsock->msglen, bsock->who(), + bsock->host(), bsock->port(), bnet_strerror(bsock)); } } else { - Qmsg5(bsock->jcr, M_ERROR, 0, + Qmsg5(bsock->jcr(), M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), - bsock->msglen, bsock->who, bsock->host, bsock->port, rc); + bsock->msglen, bsock->who(), bsock->host(), + bsock->port(), rc); } return false; } @@ -467,7 +370,7 @@ bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) tls = new_tls_connection(ctx, bsock->fd); if (!tls) { - Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n")); + Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n")); return false; } @@ -475,15 +378,15 @@ bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) /* Initiate TLS Negotiation */ if (!tls_bsock_accept(bsock)) { - Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS Negotiation failed.\n")); + Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n")); goto err; } if (verify_list) { if (!tls_postconnect_verify_cn(tls, verify_list)) { - Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed." + Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed." " Peer certificate did not match a required commonName\n"), - bsock->host); + bsock->host()); goto err; } } @@ -506,7 +409,7 @@ bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock) tls = new_tls_connection(ctx, bsock->fd); if (!tls) { - Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n")); + Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n")); return false; } @@ -517,8 +420,9 @@ bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock) goto err; } - if (!tls_postconnect_verify_host(tls, bsock->host)) { - Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), bsock->host); + if (!tls_postconnect_verify_host(tls, bsock->host())) { + Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), + bsock->host()); goto err; } return true; @@ -531,12 +435,12 @@ err: #else bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) { - Jmsg(bsock->jcr, M_ABORT, 0, _("TLS enabled but not configured.\n")); + Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enabled but not configured.\n")); return false; } bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock) { - Jmsg(bsock->jcr, M_ABORT, 0, _("TLS enable but not configured.\n")); + Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enable but not configured.\n")); return false; } #endif /* HAVE_TLS */ @@ -668,7 +572,7 @@ static const char *resolv_host(int family, const char *host, dlist * addr_list) struct hostent *hp; const char *errmsg; - P(ip_mutex); + P(ip_mutex); /* gethostbyname() is not thread safe */ #ifdef HAVE_GETHOSTBYNAME2 if ((hp = gethostbyname2(host, family)) == NULL) { #else @@ -967,23 +871,23 @@ bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw) } start_size = dbuf_size; if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) { - Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n")); + Qmsg0(bs->jcr(), M_FATAL, 0, _("Could not malloc BSOCK data buffer\n")); return false; } if (rw & BNET_SETBUF_READ) { while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET, SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) { berrno be; - Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror()); + Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror()); dbuf_size -= TAPE_BSIZE; } Dmsg1(200, "set network buffer size=%d\n", dbuf_size); if (dbuf_size != start_size) { - Qmsg1(bs->jcr, M_WARNING, 0, + Qmsg1(bs->jcr(), M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size); } if (dbuf_size % TAPE_BSIZE != 0) { - Qmsg1(bs->jcr, M_ABORT, 0, + Qmsg1(bs->jcr(), M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"), dbuf_size); } @@ -998,16 +902,16 @@ bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw) while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET, SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) { berrno be; - Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror()); + Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror()); dbuf_size -= TAPE_BSIZE; } Dmsg1(900, "set network buffer size=%d\n", dbuf_size); if (dbuf_size != start_size) { - Qmsg1(bs->jcr, M_WARNING, 0, + Qmsg1(bs->jcr(), M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size); } if (dbuf_size % TAPE_BSIZE != 0) { - Qmsg1(bs->jcr, M_ABORT, 0, + Qmsg1(bs->jcr(), M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"), dbuf_size); } @@ -1028,13 +932,13 @@ int bnet_set_nonblocking (BSOCK *bsock) { /* Get current flags */ if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) { berrno be; - Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror()); + Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror()); } /* Set O_NONBLOCK flag */ if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) { berrno be; - Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror()); + Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror()); } bsock->blocking = 0; @@ -1062,13 +966,13 @@ int bnet_set_blocking (BSOCK *bsock) /* Get current flags */ if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) { berrno be; - Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror()); + Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror()); } /* Set O_NONBLOCK flag */ if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) { berrno be; - Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror()); + Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror()); } bsock->blocking = 1; @@ -1093,7 +997,7 @@ void bnet_restore_blocking (BSOCK *bsock, int flags) #ifndef HAVE_WIN32 if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) { berrno be; - Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror()); + Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror()); } bsock->blocking = (flags & O_NONBLOCK); @@ -1164,9 +1068,9 @@ BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int bsock->blocking = 1; bsock->msg = get_pool_memory(PM_MESSAGE); bsock->errmsg = get_pool_memory(PM_MESSAGE); - bsock->who = bstrdup(who); - bsock->host = bstrdup(host); - bsock->port = port; + bsock->set_who(bstrdup(who)); + bsock->set_host(bstrdup(host)); + bsock->set_port(port); memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr)); memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr)); /* @@ -1174,21 +1078,21 @@ BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int * heartbeats are implemented */ bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */ - bsock->jcr = jcr; + bsock->set_jcr(jcr); return bsock; } BSOCK *dup_bsock(BSOCK * osock) { - BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK)); + BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK)); memcpy(bsock, osock, sizeof(BSOCK)); bsock->msg = get_pool_memory(PM_MESSAGE); bsock->errmsg = get_pool_memory(PM_MESSAGE); - if (osock->who) { - bsock->who = bstrdup(osock->who); + if (osock->who()) { + bsock->set_who(bstrdup(osock->who())); } - if (osock->host) { - bsock->host = bstrdup(osock->host); + if (osock->host()) { + bsock->set_host(bstrdup(osock->host())); } bsock->duped = true; return bsock; @@ -1197,48 +1101,10 @@ BSOCK *dup_bsock(BSOCK * osock) /* Close the network connection */ void bnet_close(BSOCK * bsock) { - BSOCK *next; - - for (; bsock != NULL; bsock = next) { - next = bsock->next; - if (!bsock->duped) { -#ifdef HAVE_TLS - /* Shutdown tls cleanly. */ - if (bsock->tls) { - tls_bsock_shutdown(bsock); - free_tls_connection(bsock->tls); - bsock->tls = NULL; - } -#endif /* HAVE_TLS */ - if (bsock->timed_out) { - shutdown(bsock->fd, 2); /* discard any pending I/O */ - } - socketClose(bsock->fd); /* normal close */ - } - term_bsock(bsock); - } - return; + bsock->close(); /* this calls destroy */ } void term_bsock(BSOCK * bsock) { - if (bsock->msg) { - free_pool_memory(bsock->msg); - bsock->msg = NULL; - } else { - ASSERT(1 == 0); /* double close */ - } - if (bsock->errmsg) { - free_pool_memory(bsock->errmsg); - bsock->errmsg = NULL; - } - if (bsock->who) { - free(bsock->who); - bsock->who = NULL; - } - if (bsock->host) { - free(bsock->host); - bsock->host = NULL; - } - free(bsock); + bsock->destroy(); } diff --git a/bacula/src/lib/bsock.c b/bacula/src/lib/bsock.c index b290240662..8567f37fdd 100644 --- a/bacula/src/lib/bsock.c +++ b/bacula/src/lib/bsock.c @@ -38,6 +38,16 @@ #include "jcr.h" #include +#ifdef HAVE_WIN32 +#define socketRead(fd, buf, len) ::recv(fd, buf, len, 0) +#define socketWrite(fd, buf, len) ::send(fd, buf, len, 0) +#define socketClose(fd) ::closesocket(fd) +#else +#define socketRead(fd, buf, len) ::read(fd, buf, len) +#define socketWrite(fd, buf, len) ::write(fd, buf, len) +#define socketClose(fd) ::close(fd) +#endif + /* * Send a message over the network. The send consists of * two network packets. The first is sends a 32 bit integer containing @@ -85,15 +95,15 @@ bool BSOCK::send() } if (rc < 0) { if (!suppress_error_msgs) { - Qmsg5(jcr, M_ERROR, 0, + Qmsg5(m_jcr, M_ERROR, 0, _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"), - msglen, who, - host, port, bnet_strerror(this)); + msglen, m_who, + m_host, m_port, bnet_strerror(this)); } } else { - Qmsg5(jcr, M_ERROR, 0, + Qmsg5(m_jcr, M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), - msglen, who, host, port, rc); + msglen, m_who, m_host, m_port, rc); } return false; } @@ -131,6 +141,124 @@ bool BSOCK::fsend(const char *fmt, ...) return send(); } +/* + * Receive a message from the other end. Each message consists of + * two packets. The first is a header that contains the size + * of the data that follows in the second packet. + * Returns number of bytes read (may return zero) + * Returns -1 on signal (BNET_SIGNAL) + * Returns -2 on hard end of file (BNET_HARDEOF) + * Returns -3 on error (BNET_ERROR) + * + * Unfortunately, it is a bit complicated because we have these + * four return types: + * 1. Normal data + * 2. Signal including end of data stream + * 3. Hard end of file + * 4. Error + * Using is_bnet_stop() and is_bnet_error() you can figure this all out. + */ +int32_t BSOCK::recv() +{ + int32_t nbytes; + int32_t pktsiz; + + msg[0] = 0; + msglen = 0; + if (errors || terminated) { + return BNET_HARDEOF; + } + + read_seqno++; /* bump sequence number */ + timer_start = watchdog_time; /* set start wait time */ + timed_out = 0; + /* get data size -- in int32_t */ + if ((nbytes = read_nbytes(this, (char *)&pktsiz, sizeof(int32_t))) <= 0) { + timer_start = 0; /* clear timer */ + /* probably pipe broken because client died */ + if (errno == 0) { + b_errno = ENODATA; + } else { + b_errno = errno; + } + errors++; + return BNET_HARDEOF; /* assume hard EOF received */ + } + timer_start = 0; /* clear timer */ + if (nbytes != sizeof(int32_t)) { + errors++; + b_errno = EIO; + Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), + sizeof(int32_t), nbytes, m_who, m_host, m_port); + return BNET_ERROR; + } + + pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */ + + if (pktsiz == 0) { /* No data transferred */ + timer_start = 0; /* clear timer */ + in_msg_no++; + msglen = 0; + return 0; /* zero bytes read */ + } + + /* If signal or packet size too big */ + if (pktsiz < 0 || pktsiz > 1000000) { + if (pktsiz > 0) { /* if packet too big */ + Qmsg3(m_jcr, M_FATAL, 0, + _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"), + m_who, m_host, m_port); + pktsiz = BNET_TERMINATE; /* hang up */ + } + if (pktsiz == BNET_TERMINATE) { + terminated = 1; + } + timer_start = 0; /* clear timer */ + b_errno = ENODATA; + msglen = pktsiz; /* signal code */ + return BNET_SIGNAL; /* signal */ + } + + /* Make sure the buffer is big enough + one byte for EOS */ + if (pktsiz >= (int32_t) sizeof_pool_memory(msg)) { + msg = realloc_pool_memory(msg, pktsiz + 100); + } + + timer_start = watchdog_time; /* set start wait time */ + timed_out = 0; + /* now read the actual data */ + if ((nbytes = read_nbytes(this, msg, pktsiz)) <= 0) { + timer_start = 0; /* clear timer */ + if (errno == 0) { + b_errno = ENODATA; + } else { + b_errno = errno; + } + errors++; + Qmsg4(m_jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"), + m_who, m_host, m_port, bnet_strerror(this)); + return BNET_ERROR; + } + timer_start = 0; /* clear timer */ + in_msg_no++; + msglen = nbytes; + if (nbytes != pktsiz) { + b_errno = EIO; + errors++; + Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), + pktsiz, nbytes, m_who, m_host, m_port); + return BNET_ERROR; + } + /* always add a zero by to properly terminate any + * string that was send to us. Note, we ensured above that the + * buffer is at least one byte longer than the message length. + */ + msg[nbytes] = 0; /* terminate in case it is a string */ + sm_check(__FILE__, __LINE__, false); + return nbytes; /* return actual length of message */ +} + + /* * Send a signal */ @@ -142,3 +270,52 @@ bool BSOCK::signal(int signal) } return send(); } + +void BSOCK::close() +{ + BSOCK *bsock = this; + BSOCK *next; + + for (; bsock; bsock = next) { + next = bsock->m_next; /* get possible pointer to next before destoryed */ + if (!bsock->duped) { +#ifdef HAVE_TLS + /* Shutdown tls cleanly. */ + if (bsock->tls) { + tls_bsock_shutdown(bsock); + free_tls_connection(bsock->tls); + bsock->tls = NULL; + } +#endif /* HAVE_TLS */ + if (bsock->timed_out) { + shutdown(bsock->fd, 2); /* discard any pending I/O */ + } + socketClose(bsock->fd); /* normal close */ + } + destroy(); /* free the packet */ + } + return; +} + +void BSOCK::destroy() +{ + if (msg) { + free_pool_memory(msg); + msg = NULL; + } else { + ASSERT(1 == 0); /* double close */ + } + if (errmsg) { + free_pool_memory(errmsg); + errmsg = NULL; + } + if (m_who) { + free(m_who); + m_who = NULL; + } + if (m_host) { + free(m_host); + m_host = NULL; + } + free(this); +} diff --git a/bacula/src/lib/bsock.h b/bacula/src/lib/bsock.h index 31b57fd534..8c9089408d 100644 --- a/bacula/src/lib/bsock.h +++ b/bacula/src/lib/bsock.h @@ -41,6 +41,13 @@ class BSOCK { +private: + BSOCK *m_next; /* next BSOCK if duped */ + JCR *m_jcr; /* jcr or NULL for error msgs */ + char *m_who; /* Name of daemon to which we are talking */ + char *m_host; /* Host name/IP */ + int m_port; /* desired port */ + public: uint64_t read_seqno; /* read sequence number */ uint32_t in_msg_no; /* input message number */ @@ -49,7 +56,6 @@ public: TLS_CONNECTION *tls; /* associated tls connection */ int32_t msglen; /* message length */ int b_errno; /* bsock errno */ - int port; /* desired port */ int blocking; /* blocking state (0 = nonblocking, 1 = blocking) */ volatile int errors; /* incremented for each error on socket */ volatile bool suppress_error_msgs: 1; /* set to suppress error messages */ @@ -60,20 +66,27 @@ public: volatile time_t timer_start; /* time started read/write */ volatile time_t timeout; /* timeout BSOCK after this interval */ POOLMEM *msg; /* message pool buffer */ - char *who; /* Name of daemon to which we are talking */ - char *host; /* Host name/IP */ POOLMEM *errmsg; /* edited error message */ RES *res; /* Resource to which we are connected */ - BSOCK *next; /* next BSOCK if duped */ FILE *spool_fd; /* spooling file */ - JCR *jcr; /* jcr or NULL for error msgs */ - struct sockaddr client_addr; /* client's IP address */ - struct sockaddr_in peer_addr; /* peer's IP address */ + struct sockaddr client_addr; /* client's IP address */ + struct sockaddr_in peer_addr; /* peer's IP address */ /* methods -- in bsock.c */ + int32_t recv(); bool send(); bool fsend(const char*, ...); bool signal(int signal); + void close(); /* close connection and destroy packet */ + void destroy(); /* destroy socket packet */ + void set_jcr(JCR *jcr) { m_jcr = jcr; }; + void set_who(char *who) { m_who = who; }; + void set_host(char *host) { m_host = host; }; + void set_port(int port) { m_port = port; }; + char *who() { return m_who; }; + char *host() { return m_host; }; + int port() { return m_port; }; + JCR *jcr() { return m_jcr; }; }; diff --git a/bacula/src/lib/crypto.c b/bacula/src/lib/crypto.c index 5ae8c2e1df..83ea648fda 100644 --- a/bacula/src/lib/crypto.c +++ b/bacula/src/lib/crypto.c @@ -1,25 +1,7 @@ -/* - * crypto.c Encryption support functions - * - * Author: Landon Fuller - * - * Version $Id$ - * - * This file was contributed to the Bacula project by Landon Fuller. - * - * Landon Fuller has been granted a perpetual, worldwide, non-exclusive, - * no-charge, royalty-free, irrevocable copyright license to reproduce, - * prepare derivative works of, publicly display, publicly perform, - * sublicense, and distribute the original work contributed by Landon Fuller - * to the Bacula project in source or object form. - * - * If you wish to license these contributions under an alternate open source - * license please contact Landon Fuller . - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2005-2006 Free Software Foundation Europe e.V. + Copyright (C) 2005-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. @@ -43,6 +25,24 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * crypto.c Encryption support functions + * + * Author: Landon Fuller + * + * Version $Id$ + * + * This file was contributed to the Bacula project by Landon Fuller. + * + * Landon Fuller has been granted a perpetual, worldwide, non-exclusive, + * no-charge, royalty-free, irrevocable copyright license to reproduce, + * prepare derivative works of, publicly display, publicly perform, + * sublicense, and distribute the original work contributed by Landon Fuller + * to the Bacula project in source or object form. + * + * If you wish to license these contributions under an alternate open source + * license please contact Landon Fuller . + */ #include "bacula.h" @@ -783,7 +783,7 @@ crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST return CRYPTO_ERROR_BAD_SIGNATURE; } else if (ok < 0) { /* Shouldn't happen */ - openssl_post_errors(M_ERROR, _("OpenSSL error occured")); + openssl_post_errors(M_ERROR, _("OpenSSL error occurred")); return CRYPTO_ERROR_INTERNAL; } } diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 9b0f3069e5..e4cef4e6ac 100644 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -9,7 +9,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2006 Free Software Foundation Europe e.V. + Copyright (C) 2000-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. @@ -33,6 +33,14 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Bacula message handling routines + * + * Kern Sibbald, April 2000 + * + * Version $Id$ + * + */ #include "bacula.h" @@ -426,6 +434,7 @@ void close_msg(JCR *jcr) case MD_APPEND: if (d->fd) { fclose(d->fd); /* close open file descriptor */ + d->fd = NULL; } break; case MD_MAIL: @@ -486,6 +495,7 @@ void close_msg(JCR *jcr) rem_temp_file: /* Remove temp file */ fclose(d->fd); + d->fd = NULL; unlink(d->mail_filename); free_pool_memory(d->mail_filename); d->mail_filename = NULL; @@ -747,6 +757,7 @@ send_to_file: /* On error, we close and reopen to handle log rotation */ if (ferror(d->fd)) { fclose(d->fd); + d->fd = NULL; if (open_dest_file(jcr, d, mode)) { fputs(dt, d->fd); fputs(msg, d->fd); diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 5748591267..ab6f6f20c4 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -1,10 +1,3 @@ -/* - * Routines to acquire and release a device for read/write - * - * Kern Sibbald, August MMII - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution @@ -32,6 +25,13 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Routines to acquire and release a device for read/write + * + * Kern Sibbald, August MMII + * + * Version $Id$ + */ #include "bacula.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ diff --git a/bacula/src/stored/authenticate.c b/bacula/src/stored/authenticate.c index 2efba058a3..25175b56be 100644 --- a/bacula/src/stored/authenticate.c +++ b/bacula/src/stored/authenticate.c @@ -62,9 +62,9 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr) } if (bs->msglen < 25 || bs->msglen > 500) { Dmsg2(50, "Bad Hello command from Director at %s. Len=%d.\n", - bs->who, bs->msglen); + bs->who(), bs->msglen); Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"), - bs->who, bs->msglen); + bs->who(), bs->msglen); return 0; } dirname = get_pool_memory(PM_MESSAGE); @@ -73,9 +73,9 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr) if (sscanf(bs->msg, "Hello Director %127s calling", dirname) != 1) { bs->msg[100] = 0; Dmsg2(50, "Bad Hello command from Director at %s: %s\n", - bs->who, bs->msg); + bs->who(), bs->msg); Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"), - bs->who, bs->msg); + bs->who(), bs->msg); return 0; } director = NULL; @@ -86,10 +86,10 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr) } if (!director) { Dmsg2(50, "Connection from unknown Director %s at %s rejected.\n", - dirname, bs->who); + dirname, bs->who()); Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n" "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"), - dirname, bs->who); + dirname, bs->who()); free_pool_memory(dirname); return 0; } @@ -113,10 +113,10 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr) if (auth_success) { auth_success = cram_md5_respond(bs, director->password, &tls_remote_need, &compatible); if (!auth_success) { - Dmsg1(50, "cram_get_auth failed with %s\n", bs->who); + Dmsg1(50, "cram_get_auth failed with %s\n", bs->who()); } } else { - Dmsg1(50, "cram_auth failed with %s\n", bs->who); + Dmsg1(50, "cram_auth failed with %s\n", bs->who()); } if (!auth_success) { @@ -175,8 +175,8 @@ int authenticate_director(JCR *jcr) if (!authenticate(R_DIRECTOR, dir, jcr)) { bnet_fsend(dir, "%s", Dir_sorry); - Dmsg1(50, "Unable to authenticate Director at %s.\n", dir->who); - Emsg1(M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who); + Dmsg1(50, "Unable to authenticate Director at %s.\n", dir->who()); + Emsg1(M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who()); bmicrosleep(5, 0); return 0; } @@ -213,16 +213,16 @@ int authenticate_filed(JCR *jcr) /* Respond to his challenge */ auth_success = cram_md5_respond(fd, jcr->sd_auth_key, &tls_remote_need, &compatible); if (!auth_success) { - Dmsg1(50, "cram-get-auth failed with %s\n", fd->who); + Dmsg1(50, "cram-get-auth failed with %s\n", fd->who()); } } else { - Dmsg1(50, "cram-auth failed with %s\n", fd->who); + Dmsg1(50, "cram-auth failed with %s\n", fd->who()); } if (!auth_success) { Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n" "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"), - fd->who); + fd->who()); auth_success = false; goto auth_fatal; } @@ -256,7 +256,7 @@ auth_fatal: if (!auth_success) { Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n" "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"), - fd->who); + fd->who()); } jcr->authenticated = auth_success; return auth_success; diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 8987fbfb1d..639b2148c8 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -178,7 +178,7 @@ void *handle_connection_request(void *arg) Dmsg0(110, "Start Dir Job\n"); jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */ jcr->dir_bsock = bs; /* save Director bsock */ - jcr->dir_bsock->jcr = jcr; + jcr->dir_bsock->set_jcr(jcr); jcr->dcrs = New(alist(10, not_owned_by_alist)); /* Initialize FD start condition variable */ int errstat = pthread_cond_init(&jcr->job_start_wait, NULL); diff --git a/bacula/src/stored/fd_cmds.c b/bacula/src/stored/fd_cmds.c index 63c163ff00..e06a6c437e 100644 --- a/bacula/src/stored/fd_cmds.c +++ b/bacula/src/stored/fd_cmds.c @@ -118,7 +118,7 @@ void run_job(JCR *jcr) BSOCK *dir = jcr->dir_bsock; char ec1[30]; - dir->jcr = jcr; + dir->set_jcr(jcr); Dmsg1(120, "Start run Job=%s\n", jcr->Job); bnet_fsend(dir, Job_start, jcr->Job); jcr->start_time = time(NULL); @@ -145,7 +145,7 @@ void do_fd_commands(JCR *jcr) bool found, quit; BSOCK *fd = jcr->file_bsock; - fd->jcr = jcr; + fd->set_jcr(jcr); for (quit=false; !quit;) { int stat; diff --git a/bacula/src/stored/job.c b/bacula/src/stored/job.c index 2bd6be9d24..57cc0487e5 100644 --- a/bacula/src/stored/job.c +++ b/bacula/src/stored/job.c @@ -208,7 +208,7 @@ void handle_filed_connection(BSOCK *fd, char *job_name) } jcr->file_bsock = fd; - jcr->file_bsock->jcr = jcr; + jcr->file_bsock->set_jcr(jcr); Dmsg1(110, "Found Job %s\n", job_name); diff --git a/bacula/src/version.h b/bacula/src/version.h index b537b3c126..d19cf37086 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "2.1.4" -#define BDATE "19 February 2007" -#define LSMDATE "19Feb07" +#define BDATE "21 February 2007" +#define LSMDATE "21Feb07" #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n" #define BYEAR "2007" /* year for copyright messages in progs */ diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index 2154d89b34..cc9fe335ba 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -1,6 +1,16 @@ Technical notes on version 2.1 General: +22Feb08 +kes Begin implementing new comm signals for API. +kes Fix a few places in lib/message.c where the open fd may + not be zeroed. +kes Continue implementing lib/bsock.c (real class). Make jcr, + who, host, and port private. There are new methods to access + them for non-class use. This required touching a number of files. +21Feb07 +kes Add LANG=C to autoconf/randpass so it works with languages other + than English. Fixes bug #788. 20Feb07 ebl Revert ClientRunBeforeJob to old position as in 1.38.X. This fixes bug #780 -- 2.39.5