- Look at why SIGPIPE during connection can cause seg fault in
writing the daemon message, when Dir dropped to bacula:bacula
- Look at zlib 32 => 64 problems.
-- Ensure that connection to daemon failure always indicates what
- daemon it was trying to connect to.
- Try turning on disk seek code.
- Possibly turn on St. Bernard code.
- Fix bextract to restore ACLs, or better yet, use common
routines.
- Do we migrate appendable Volumes?
- Remove queue.c code.
-- Add bconsole option to use stdin/out instead of conio.
-- Fix ClientRunBefore/AfterJob compatibility.
- Fix re-read of last block to check if job has actually written
a block, and check if block was written by a different job
(i.e. multiple simultaneous jobs writing).
- Fix wx-console scanning problem with commas in names.
- Add manpages to the list of directories for make install. Notify
Scott
+- Add bconsole option to use stdin/out instead of conio.
+- Fix ClientRunBefore/AfterJob compatibility.
+- Ensure that connection to daemon failure always indicates what
+ daemon it was trying to connect to.
could override the Storage parameter for full and/or differential
backups, then the Full job would use the proper Storage device, which
has more capacity (i.e. a 8TB tape library.
+
+
+Item: Implement multiple numeric backup levels as supported by dump
+Date: 3 April 2006
+Origin: Daniel Rich <drich@employees.org>
+Status:
+What: Dump allows specification of backup levels numerically instead of just
+ "full", "incr", and "diff". In this system, at any given level, all
+ files are backed up that were were modified since the last backup of a
+ higher level (with 0 being the highest and 9 being the lowest). A
+ level 0 is therefore equivalent to a full, level 9 an incremental, and
+ the levels 1 through 8 are varying levels of differentials. For
+ bacula's sake, these could be represented as "full", "incr", and
+ "diff1", "diff2", etc.
+
+Why: Support of multiple backup levels would provide for more advanced backup
+ rotation schemes such as "Towers of Hanoi". This would allow better
+ flexibility in performing backups, and can lead to shorter recover
+ times.
+
+Notes: Legato Networker supports a similar system with full, incr, and 1-9 as
+ levels.
+
+Kern notes: I think this would add very little functionality, but a *lot* of
+ additional overhead to Bacula.
if (!auth_success) {
stop_bsock_timer(tid);
Dmsg0(50, _("Director and Storage daemon passwords or names not the same.\n"));
- Jmsg0(jcr, M_FATAL, 0,
- _("Director unable to authenticate with Storage daemon. Possible causes:\n"
+ Jmsg2(jcr, M_FATAL, 0,
+ _("Director unable to authenticate with Storage daemon on \"%s:%d\". Possible causes:\n"
"Passwords or names not the same or\n"
"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"));
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
+ sd->host, sd->port);
return 0;
}
/* Engage TLS! Full Speed Ahead! */
if (!bnet_tls_client(store->tls_ctx, sd)) {
stop_bsock_timer(tid);
- Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
+ Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD on \"%s:%d\"\n"),
+ sd->host, sd->port);
return 0;
}
}
Dmsg1(116, ">stored: %s", sd->msg);
if (bnet_recv(sd) <= 0) {
stop_bsock_timer(tid);
- Jmsg1(jcr, M_FATAL, 0, _("bdird<stored: bad response to Hello command: ERR=%s\n"),
- bnet_strerror(sd));
+ Jmsg3(jcr, M_FATAL, 0, _("bdird<stored: \"%s:%s\" bad response to Hello command: ERR=%s\n"),
+ sd->who, sd->host, bnet_strerror(sd));
return 0;
}
Dmsg1(110, "<stored: %s", sd->msg);
stop_bsock_timer(tid);
if (strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
Dmsg0(50, _("Storage daemon rejected Hello command\n"));
- Jmsg0(jcr, M_FATAL, 0, _("Storage daemon rejected Hello command\n"));
+ Jmsg2(jcr, M_FATAL, 0, _("Storage daemon on \"%s:%d\" rejected Hello command\n"),
+ sd->host, sd->port);
return 0;
}
return 1;
btimer_t *tid = start_bsock_timer(fd, AUTH_TIMEOUT);
if (!bnet_fsend(fd, hello, dirname)) {
stop_bsock_timer(tid);
- Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon. ERR=%s\n"), bnet_strerror(fd));
+ Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon on \"%s:%d\". ERR=%s\n"),
+ fd->host, fd->port, bnet_strerror(fd));
return 0;
}
Dmsg1(50, "Sent: %s", fd->msg);
stop_bsock_timer(tid);
Dmsg0(50, _("Director and File daemon passwords or names not the same.\n"));
Jmsg(jcr, M_FATAL, 0,
- _("Unable to authenticate with File daemon. Possible causes:\n"
+ _("Unable to authenticate with File daemon on \"%s:%d\". Possible causes:\n"
"Passwords or names not the same or\n"
"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"));
+ "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
+ fd->host, fd->port);
return 0;
}
/* Verify that the remote host is willing to meet our TLS requirements */
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: Remote server did not advertise required TLS support.\n"));
+ Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD \"%s:%s\" did not advertise required TLS support.\n"),
+ fd->who, fd->host);
return 0;
}
/* Verify that we are willing to meet the remote host's requirements */
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: Remote server requires TLS.\n"));
+ Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD on \"%s:%d\" requires TLS.\n"),
+ fd->host, fd->port);
return 0;
}
/* Engage TLS! Full Speed Ahead! */
if (!bnet_tls_client(client->tls_ctx, fd)) {
stop_bsock_timer(tid);
- Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
+ Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD on \"%s:%d\".\n"),
+ fd->host, fd->port);
return 0;
}
}
stop_bsock_timer(tid);
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 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));
return 0;
}
Dmsg1(110, "<stored: %s", fd->msg);
stop_bsock_timer(tid);
if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) {
Dmsg0(50, _("File daemon rejected Hello command\n"));
- Jmsg(jcr, M_FATAL, 0, _("File daemon rejected Hello command\n"));
+ Jmsg(jcr, M_FATAL, 0, _("File daemon on \"%s:%d\" rejected Hello command\n"),
+ fd->host, fd->port);
return 0;
}
return 1;
{"commandacl", store_acl, ITEM(res_con.ACL_lists), Command_ACL, 0, 0},
{"filesetacl", store_acl, ITEM(res_con.ACL_lists), FileSet_ACL, 0, 0},
{"catalogacl", store_acl, ITEM(res_con.ACL_lists), Catalog_ACL, 0, 0},
+ {"whereacl", store_acl, ITEM(res_con.ACL_lists), Where_ACL, 0, 0},
{"tlsenable", store_bool, ITEM(res_con.tls_enable), 0, 0, 0},
{"tlsrequire", store_bool, ITEM(res_con.tls_require), 0, 0, 0},
{"tlsverifypeer", store_bool, ITEM(res_con.tls_verify_peer), 0, ITEM_DEFAULT, true},
int token;
for (;;) {
- token = lex_get_token(lc, T_NAME);
+ token = lex_get_token(lc, T_STRING);
if (pass == 1) {
if (((alist **)item->value)[item->code] == NULL) {
((alist **)item->value)[item->code] = New(alist(10, owned_by_alist));
Command_ACL,
FileSet_ACL,
Catalog_ACL,
+ Where_ACL,
Num_ACL /* keep last */
};
*/
/*
- Copyright (C) 2004-2005 Kern Sibbald
+ Copyright (C) 2004-2006 Kern Sibbald
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
+ modify it under the terms of the GNU General Public License
+ version 2 as amended with additional clauses defined in the
+ file LICENSE in the main source directory.
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., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional details.
*/
/* If no console resource => default console and all is permitted */
if (!ua->cons) {
Dmsg0(1400, "Root cons access OK.\n");
- return true; /* No cons resource -> root console OK for everything */
+ return true; /* No cons resource -> root console OK for everything */
}
alist *list = ua->cons->ACL_lists[acl];
- if (!list) {
- return false; /* List empty, reject everything */
+ if (!list) { /* empty list */
+ if (len == 0 && acl == Where_ACL) {
+ return true; /* Empty list for Where => empty where */
+ }
+ return false; /* List empty, reject everything */
}
/* Special case *all* gives full access */
for (int i=0; i<list->size(); i++) {
if (strcasecmp(item, (char *)list->get(i)) == 0) {
Dmsg3(1400, "ACL found %s in %d %s\n", item, acl, (char *)list->get(i));
- return true;
+ return true;
}
}
return false;
i = find_arg_with_value(ua, "where");
if (i >= 0) {
rx.where = ua->argv[i];
+ if (!acl_access_ok(ua, Where_ACL, rx.where)) {
+ bsendmsg(ua, _("Forbidden \"where\" specified.\n"));
+ goto bail_out;
+ }
}
if (!open_db(ua)) {
/* Build run command */
if (rx.where) {
+ if (!acl_access_ok(ua, Where_ACL, rx.where)) {
+ bsendmsg(ua, _("Forbidden \"where\" specified.\n"));
+ goto bail_out;
+ }
Mmsg(ua->cmd,
"run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s\""
" where=\"%s\" files=%d catalog=\"%s\"",
return 0;
}
where = ua->argv[i];
+ if (!acl_access_ok(ua, Where_ACL, where)) {
+ bsendmsg(ua, _("Forbidden \"where\" specified.\n"));
+ return 0;
+ }
kw_ok = true;
break;
case 10: /* bootstrap */
Jmsg(jcr, M_FATAL, 0, _("3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n"),
slot, drive, be.strerror());
rtn_stat = -1; /* hard error */
+ dev->Slot = -1; /* mark unknown */
}
Dmsg2(100, "load slot %d status=%d\n", slot, status);
unlock_changer(dcr);
int get_autochanger_loaded_slot(DCR *dcr)
{
JCR *jcr = dcr->jcr;
+ DEVICE *dev = dcr->dev;
POOLMEM *changer, *results;
int status, loaded;
uint32_t timeout = dcr->device->max_changer_wait;
int drive = dcr->dev->drive_index;
+ if (!dev->is_autochanger()) {
+ return -1;
+ }
if (!dcr->device->changer_command) {
Jmsg(jcr, M_FATAL, 0, _("3992 Missing Changer command.\n"));
return -1;
}
+ if (dev->Slot >0) {
+ return dev->Slot;
+ }
results = get_pool_memory(PM_MESSAGE);
changer = get_pool_memory(PM_FNAME);
/* Find out what is loaded, zero means device is unloaded */
lock_changer(dcr);
- Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded drive %d\" command.\n"),
+ Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded? drive %d\" command.\n"),
drive);
changer = edit_device_codes(dcr, changer, dcr->device->changer_command, "loaded");
*results = 0;
if (status == 0) {
loaded = str_to_int32(results);
if (loaded > 0) {
- Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded drive %d\", result is Slot %d.\n"),
+ Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n"),
drive, loaded);
- dcr->dev->Slot = loaded;
+ dev->Slot = loaded;
} else {
- Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded drive %d\", result: nothing loaded.\n"),
+ Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n"),
drive);
- dcr->dev->Slot = 0;
+ dev->Slot = -1; /* unknown */
}
} else {
berrno be;
be.set_errno(status);
- Jmsg(jcr, M_INFO, 0, _("3991 Bad autochanger \"loaded drive %d\" command: ERR=%s.\n"),
+ Jmsg(jcr, M_INFO, 0, _("3991 Bad autochanger \"loaded? drive %d\" command: ERR=%s.\n"),
drive, be.strerror());
loaded = -1; /* force unload */
}
slot, dev->drive_index, be.strerror());
ok = false;
} else {
- dev->Slot = 0; /* nothing loaded */
+ dev->Slot = -1; /* unknown */
}
free_pool_memory(changer);
unlock_changer(dcr);
slot, dev->drive_index, be.strerror());
ok = false;
} else {
- dev->Slot = 0; /* nothing loaded */
+ dev->Slot = -1; /* nothing loaded */
Dmsg0(100, "Slot unloaded\n");
}
unlock_changer(dcr);
dev = (DEVICE *)malloc(sizeof(DEVICE));
memset(dev, 0, sizeof(DEVICE));
+ dev->Slot = -1; /* unknown */
/* Copy user supplied device parameters from Resource */
dev->dev_name = get_memory(strlen(device->device_name)+1);
Dmsg4(29, "open dev: type=%d dev_name=%s vol=%s mode=%s\n", dev_type,
print_name(), VolCatInfo.VolCatName, mode_to_str(omode));
state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
+ Slot = -1; /* unknown slot */
label_type = B_BACULA_LABEL;
if (is_tape() || is_fifo()) {
open_tape_device(dcr, omode);
int nonblocking = O_NONBLOCK;
Dmsg0(29, "open dev: device is tape\n");
- if (is_autochanger()) {
- get_autochanger_loaded_slot(dcr);
- }
+ get_autochanger_loaded_slot(dcr);
set_mode(omode);
timeout = max_open_wait;
{
POOL_MEM archive_name(PM_FNAME);
- if (is_autochanger()) {
- get_autochanger_loaded_slot(dcr);
- }
+ get_autochanger_loaded_slot(dcr);
/*
* Handle opening of File Archive (not a tape)
part_size = 0;
part_start = 0;
EndFile = EndBlock = 0;
+ Slot = -1; /* unknown slot */
free_volume(this);
memset(&VolCatInfo, 0, sizeof(VolCatInfo));
memset(&VolHdr, 0, sizeof(VolHdr));
uint32_t EndFile; /* Last file number */
uint32_t EndBlock; /* Last block number */
int32_t LabelType; /* Bacula/ANSI/IBM */
- int32_t Slot; /* Slot in changer */
+ int32_t Slot; /* >0=Slot loaded, 0=nothing, -1=unknown */
bool InChanger; /* Set if vol in current magazine */
uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */
uint32_t VolCatMaxFiles; /* Maximum files to write to volume */
return ok;
}
-bool truncate_dvd(DCR *dcr) {
+bool truncate_dvd(DCR *dcr)
+{
DEVICE* dev = dcr->dev;
if (dev->fd >= 0) {
/* Checks if we can write on a non-blank DVD: meaning that it just have been
* truncated (there is only one zero-sized file on the DVD, with the right
* volume name). */
-bool check_can_write_on_non_blank_dvd(DCR *dcr) {
+bool check_can_write_on_non_blank_dvd(DCR *dcr)
+{
DEVICE* dev = dcr->dev;
DIR* dp;
struct dirent *entry, *result;
#undef VERSION
#define VERSION "1.39.21"
-#define BDATE "23 August 2006"
-#define LSMDATE "23Aug06"
+#define BDATE "26 August 2006"
+#define LSMDATE "26Aug06"
#define BYEAR "2006" /* year for copyright messages in progs */
/* Debug flags */
Technical notes on version 1.39
General:
+26Aug06
+kes Add host:port to connect failure messages to FD and SD from Dir.
+kes Add WhereACL to console ACL list. If nothing is specified, only
+ the default is permitted for restore. Otherwise, *all* allows any
+ path, or you can specify permitted paths. This should allow control
+ over where users can restore files. This is untested.
+kes Modified message to add a ? (as in loaded?) when querying the autochanger
+ for what Slot is loaded.
+kes Fixed the use of Slot, so that is more correctly maintained, thus
+ eliminating unneeded duplicate calls to determine what Slot is loaded.
+
25Aug06
kes Install man pages with 'make install'
kes wx-console crashes because of differences between Bacula and wxWidgets