David Boyes
David Duchscher
D. Scott Barninger
+Devin Reade
Eamon Brosnan
Eric Bollengier
Erich Prinz
# 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
-/*
- * 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.
(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
}
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, "
" WHERE f.Name = a.Name) ";
#endif /* HAVE_MYSQL */
-
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) {
"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;
}
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;
}
}
if (bnet_recv(sd) <= 0) {
stop_bsock_timer(tid);
Jmsg3(jcr, M_FATAL, 0, _("bdird<stored: \"%s:%s\" bad response to Hello command: ERR=%s\n"),
- sd->who, sd->host, bnet_strerror(sd));
+ sd->who(), sd->host(), bnet_strerror(sd));
return 0;
}
Dmsg1(110, "<stored: %s", sd->msg);
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;
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);
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);
"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;
}
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;
}
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;
}
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;
}
}
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, "<stored: %s", fd->msg);
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;
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;
}
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;
}
{ 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
if (len == 1) {
return 1; /* no op */
}
- for (i=0; i<(int)comsize; i++) { /* search for command */
+ for (i=0; i<comsize; i++) { /* search for command */
if (strncasecmp(ua->argk[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;
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;
}
}
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;
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;
}
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;
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;
}
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());
}
}
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 */
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;
*/
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();
}
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;
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;
}
}
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;
}
}
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;
}
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;
}
/* 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;
}
}
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;
}
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;
#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 */
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
}
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);
}
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);
}
/* 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;
/* 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;
#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);
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));
/*
* 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;
/* 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();
}
#include "jcr.h"
#include <netdb.h>
+#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
}
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;
}
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
*/
}
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);
+}
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 */
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 */
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; };
};
-/*
- * crypto.c Encryption support functions
- *
- * Author: Landon Fuller <landonf@opendarwin.org>
- *
- * 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 <landonf@opendarwin.org>.
- */
/*
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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * crypto.c Encryption support functions
+ *
+ * Author: Landon Fuller <landonf@opendarwin.org>
+ *
+ * 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 <landonf@opendarwin.org>.
+ */
#include "bacula.h"
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;
}
}
/*
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.
(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"
case MD_APPEND:
if (d->fd) {
fclose(d->fd); /* close open file descriptor */
+ d->fd = NULL;
}
break;
case MD_MAIL:
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;
/* 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);
-/*
- * Routines to acquire and release a device for read/write
- *
- * Kern Sibbald, August MMII
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
(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 */
}
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);
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;
}
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;
}
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) {
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;
}
/* 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;
}
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;
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);
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);
bool found, quit;
BSOCK *fd = jcr->file_bsock;
- fd->jcr = jcr;
+ fd->set_jcr(jcr);
for (quit=false; !quit;) {
int stat;
}
jcr->file_bsock = fd;
- jcr->file_bsock->jcr = jcr;
+ jcr->file_bsock->set_jcr(jcr);
Dmsg1(110, "Found Job %s\n", job_name);
#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 */
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