From 14688fe152ffecdc82336decd897a0b5e56bb670 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Wed, 19 Jun 2002 19:44:57 +0000 Subject: [PATCH] bootstrap improvements -- kes19Jun02 git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@45 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/baconfig.h | 6 + bacula/src/dird/authenticate.c | 17 +- bacula/src/filed/authenticate.c | 22 ++- bacula/src/jcr.h | 1 + bacula/src/lib/lex.c | 93 +++++++++- bacula/src/lib/lex.h | 70 ++++--- bacula/src/lib/parse_conf.c | 48 ++--- bacula/src/lib/watchdog.c | 22 ++- bacula/src/stored/Makefile.in | 2 +- bacula/src/stored/authenticate.c | 26 ++- bacula/src/stored/bsr.h | 16 +- bacula/src/stored/match_bsr.c | 4 +- bacula/src/stored/parse_bsr.c | 303 ++++++++++++++++++++----------- bacula/src/stored/read.c | 35 ++++ bacula/src/stored/stored.h | 2 +- bacula/src/version.h | 4 +- 16 files changed, 468 insertions(+), 203 deletions(-) diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index 5472c7f651..b36517f2c3 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -182,7 +182,11 @@ extern void _v(char *file, int line, pthread_mutex_t *m); #define Dmsg6(lvl, msg, a1, a2, a3, a4, a5, a6) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6) #define Dmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7) #define Dmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) +#define Dmsg9(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9) d_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9) +#define Dmsg10(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) d_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) #define Dmsg11(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) d_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) +#define Dmsg12(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) d_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) +#define Dmsg13(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) d_msg(__FILE__,__LINE__,lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) #else #define Dmsg0(lvl, msg) #define Dmsg1(lvl, msg, a1) @@ -194,6 +198,8 @@ extern void _v(char *file, int line, pthread_mutex_t *m); #define Dmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7) #define Dmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) #define Dmsg11(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) +#define Dmsg12(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) +#define Dmsg13(lvl,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) #endif /* DEBUG */ /* Daemon Error Messages that are delivered according to the message resource */ diff --git a/bacula/src/dird/authenticate.c b/bacula/src/dird/authenticate.c index 16c3da759a..7f7fd6b7ee 100644 --- a/bacula/src/dird/authenticate.c +++ b/bacula/src/dird/authenticate.c @@ -60,11 +60,12 @@ int authenticate_storage_daemon(JCR *jcr) * Send my name to the Storage daemon then do authentication */ if (!bnet_fsend(sd, hello, director->hdr.name)) { - Emsg1(M_FATAL, 0, _("Auth send error. ERR=%s\n"), bnet_strerror(sd)); + Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd)); + return 0; } if (!cram_md5_get_auth(sd, jcr->store->password) || !cram_md5_auth(sd, jcr->store->password)) { - Emsg0(M_FATAL, 0, _("Storage daemon authorization failed.\n")); + Jmsg0(jcr, M_FATAL, 0, _("Director and Storage daemon passwords not the same.\n")); return 0; } Dmsg1(6, ">stored: %s", sd->msg); @@ -91,21 +92,24 @@ int authenticate_file_daemon(JCR *jcr) /* * Send my name to the File daemon then do authentication */ - bnet_fsend(fd, hello, director->hdr.name); + if (!bnet_fsend(fd, hello, director->hdr.name)) { + Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon. ERR=%s\n"), bnet_strerror(fd)); + return 0; + } if (!cram_md5_get_auth(fd, jcr->client->password) || !cram_md5_auth(fd, jcr->client->password)) { - Emsg0(M_FATAL, 0, _("File daemon authentication failed.\n")); + Jmsg(jcr, M_FATAL, 0, _("Director and File daemon passwords not the same.\n")); return 0; } Dmsg1(6, ">filed: %s", fd->msg); if (bnet_recv(fd) <= 0) { - Emsg1(M_FATAL, 0, _("bdirdmsg); if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) != 0) { - Emsg0(M_FATAL, 0, _("File daemon rejected Hello command\n")); + Jmsg(jcr, M_FATAL, 0, _("File daemon rejected Hello command\n")); return 0; } return 1; @@ -131,6 +135,7 @@ int authenticate_user_agent(BSOCK *ua) if (!ok) { bnet_fsend(ua, "%s", _(Dir_sorry)); Emsg0(M_WARNING, 0, _("Unable to authenticate User Agent\n")); + sleep(5); return 0; } bnet_fsend(ua, "1000 OK: %s Version: " VERSION " (" DATE ")\n", my_name); diff --git a/bacula/src/filed/authenticate.c b/bacula/src/filed/authenticate.c index 1a2b6b4d72..8c99fdeb42 100644 --- a/bacula/src/filed/authenticate.c +++ b/bacula/src/filed/authenticate.c @@ -50,7 +50,7 @@ static int authenticate(int rcode, BSOCK *bs) if (sscanf(bs->msg, "Hello Director %s calling\n", name) != 1) { free_pool_memory(name); - Emsg1(M_FATAL, 0, _("Authentication failure: %s"), bs->msg); + Emsg1(M_FATAL, 0, _("Bad Hello command from Director: %s"), bs->msg); return 0; } director = NULL; @@ -60,8 +60,14 @@ static int authenticate(int rcode, BSOCK *bs) break; } UnlockRes(); - if (director && (!cram_md5_auth(bs, director->password) || - !cram_md5_get_auth(bs, director->password))) { + if (!director) { + Emsg1(M_FATAL, 0, _("Connection from unknown Director %s rejected.\n"), name); + free_pool_memory(name); + return 0; + } + if (!cram_md5_auth(bs, director->password) || + !cram_md5_get_auth(bs, director->password)) { + Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n")); director = NULL; } free_pool_memory(name); @@ -82,7 +88,8 @@ int authenticate_director(JCR *jcr) if (!authenticate(R_DIRECTOR, dir)) { bnet_fsend(dir, "%s", Dir_sorry); - Emsg0(M_ERROR, 0, _("Unable to authenticate Director\n")); + Emsg0(M_FATAL, 0, _("Unable to authenticate Director\n")); + sleep(5); return 0; } return bnet_fsend(dir, "%s", OK_hello); @@ -95,7 +102,12 @@ int authenticate_director(JCR *jcr) int authenticate_storagedaemon(JCR *jcr) { BSOCK *sd = jcr->store_bsock; + int stat; - return cram_md5_get_auth(sd, jcr->sd_auth_key) && + stat = cram_md5_get_auth(sd, jcr->sd_auth_key) && cram_md5_auth(sd, jcr->sd_auth_key); + if (!stat) { + Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n")); + } + return stat; } diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 31a3536069..3b7139621d 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -188,6 +188,7 @@ struct s_jcr { uint32_t end_file; /* End file written */ /* Parmaters for Open Read Session */ + BSR *bsr; /* Bootstrap record -- has everything */ uint32_t read_VolSessionId; uint32_t read_VolSessionTime; uint32_t read_StartFile; diff --git a/bacula/src/lib/lex.c b/bacula/src/lib/lex.c index c25697fc30..51a6784842 100644 --- a/bacula/src/lib/lex.c +++ b/bacula/src/lib/lex.c @@ -38,7 +38,10 @@ void scan_to_eol(LEX *lc) { int token; Dmsg0(150, "start scan to eof\n"); - while ((token = lex_get_token(lc)) != T_EOL) { + lc->expect = 0; /* clear expectations */ + if (token != T_EOL) { + while ((token = lex_get_token(lc)) != T_EOL) { + } } Dmsg0(150, "done scan to eof\n"); } @@ -56,7 +59,7 @@ void s_err(char *file, int line, LEX *lc, char *msg, ...) bvsnprintf(buf, sizeof(buf), msg, arg_ptr); va_end(arg_ptr); - e_msg(file, line, M_ERROR_TERM, 0, "Config error: %s,\n\ + e_msg(file, line, M_ERROR_TERM, 0, "Config error: %s\n\ : Line %d, col %d of file %s\n%s\n", buf, lc->line_no, lc->col_no, lc->fname, lc->line); } @@ -240,6 +243,21 @@ lex_tok_to_str(int token) } } +static uint32_t scan_pint(LEX *lf, char *str) +{ + double dval; + if (!is_a_number(str)) { + scan_err1(lf, "expected a positive integer number, got: %s", str); + } else { + errno = 0; + dval = strtod(str, NULL); + if (errno != 0 || dval < 0) { + scan_err1(lf, "expected a postive integer number, got: %s", str); + } + } + return (uint32_t)dval; +} + /* * * Get the next token from the input @@ -417,5 +435,76 @@ lex_get_token(LEX *lf) } Dmsg2(290, "lex returning: line %d token: %s\n", lf->line_no, lex_tok_to_str(token)); lf->token = token; + + /* + * Here is where we check to see if the user has set certain + * expectations (e.g. 32 bit integer). If so, we do type checking + * and possible additional scanning (e.g. for range). + */ + switch (lf->expect) { + case T_PINT32: + lf->pint32_val = scan_pint(lf, lf->str); + lf->pint32_val2 = lf->pint32_val; + token = T_PINT32; + break; + + case T_PINT32_RANGE: + if (token == T_NUMBER) { + lf->pint32_val = scan_pint(lf, lf->str); + lf->pint32_val2 = lf->pint32_val; + token = T_PINT32; + } else { + char *p = strchr(lf->str, '-'); + if (!p) { + scan_err1(lf, "expected an integer or a range, got: %s", lf->str); + } + *p++ = 0; /* terminate first half of range */ + lf->pint32_val = scan_pint(lf, lf->str); + lf->pint32_val2 = scan_pint(lf, p); + token = T_PINT32_RANGE; + } + break; + + case T_INT32: + if (token != T_NUMBER || !is_a_number(lf->str)) { + scan_err1(lf, "expected an integer number, got: %s", lf->str); + } else { + errno = 0; + lf->int32_val = (int32_t)strtod(lf->str, NULL); + if (errno != 0) { + scan_err1(lf, "expected an integer number, got: %s", lf->str); + } + } + token = T_INT32; + break; + + case T_INT64: + Dmsg2(400, "int64=:%s: %f\n", lf->str, strtod(lf->str, NULL)); + if (token != T_NUMBER || !is_a_number(lf->str)) { + scan_err1(lf, "expected an integer number, got: %s", lf->str); + } else { + errno = 0; + lf->int64_val = (int64_t)strtod(lf->str, NULL); + if (errno != 0) { + scan_err1(lf, "expected an integer number, got: %s", lf->str); + } + } + token = T_INT64; + break; + + case T_NAME: + if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { + scan_err1(lf, "expected a name: %s", lf->str); + } else if (lf->str_len > MAX_RES_NAME_LENGTH) { + scan_err3(lf, "name %s length %d too long, max is %d\n", lf->str, + lf->str_len, MAX_RES_NAME_LENGTH); + } + token = T_NAME; + break; + + default: + break; /* no expectation given */ + } + lf->token = token; /* set possible new token */ return token; } diff --git a/bacula/src/lib/lex.h b/bacula/src/lib/lex.h index 4b52291818..ec642a95be 100644 --- a/bacula/src/lib/lex.h +++ b/bacula/src/lib/lex.h @@ -32,26 +32,35 @@ #define _LEX_H /* Lex get_char() return values */ -#define L_EOF (-1) -#define L_EOL (-2) +#define L_EOF (-1) +#define L_EOL (-2) /* Internal tokens */ -#define T_NONE 100 +#define T_NONE 100 /* Tokens returned by get_token() */ -#define T_EOF 101 -#define T_NUMBER 102 -#define T_IPADDR 103 -#define T_IDENTIFIER 104 -#define T_STRING 105 -#define T_QUOTED_STRING 106 -#define T_BOB 108 /* begin block */ -#define T_EOB 109 /* end of block */ -#define T_EQUALS 110 -#define T_COMMA 111 -#define T_EOL 112 -#define T_SEMI 113 -#define T_ERROR 200 +#define T_EOF 101 +#define T_NUMBER 102 +#define T_IPADDR 103 +#define T_IDENTIFIER 104 +#define T_STRING 105 +#define T_QUOTED_STRING 106 +#define T_BOB 108 /* begin block */ +#define T_EOB 109 /* end of block */ +#define T_EQUALS 110 +#define T_COMMA 111 +#define T_EOL 112 +#define T_SEMI 113 +#define T_ERROR 200 +/* + * The following will be returned only if + * the appropriate expect flag has been set + */ +#define T_PINT32 114 /* positive integer */ +#define T_PINT32_RANGE 115 /* positive integer range */ +#define T_INT32 116 /* integer */ +#define T_INT64 117 /* 64 bit integer */ +#define T_NAME 118 /* resource name */ /* Lexical state */ enum lex_state { @@ -66,22 +75,27 @@ enum lex_state { }; /* Lex scan options */ -#define LOPT_NO_IDENT 0x1 /* No Identifiers -- use string */ +#define LOPT_NO_IDENT 0x1 /* No Identifiers -- use string */ /* Lexical context */ typedef struct s_lex_context { - int options; /* scan options */ - char *fname; /* filename */ - FILE *fd; /* file descriptor */ - char line[MAXSTRING]; /* input line */ - char str[MAXSTRING]; /* string being scanned */ - int str_len; /* length of string */ - int line_no; /* file line number */ - int col_no; /* char position on line */ - enum lex_state state; /* lex_state variable */ - int ch; /* last char/L_VAL returned by get_char */ + struct s_lex_context *next; /* pointer to next lexical context */ + int options; /* scan options */ + int expect; /* types expected */ + char *fname; /* filename */ + FILE *fd; /* file descriptor */ + char line[MAXSTRING]; /* input line */ + char str[MAXSTRING]; /* string being scanned */ + int str_len; /* length of string */ + int line_no; /* file line number */ + int col_no; /* char position on line */ + enum lex_state state; /* lex_state variable */ + int ch; /* last char/L_VAL returned by get_char */ int token; - struct s_lex_context *next; /* pointer to next lexical context */ + uint32_t pint32_val; + uint32_t pint32_val2; + int32_t int32_val; + int64_t int64_val; } LEX; #endif /* _LEX_H */ diff --git a/bacula/src/lib/parse_conf.c b/bacula/src/lib/parse_conf.c index 61f7d7eadc..e063b6f84e 100755 --- a/bacula/src/lib/parse_conf.c +++ b/bacula/src/lib/parse_conf.c @@ -333,16 +333,10 @@ void store_name(LEX *lc, struct res_items *item, int index, int pass) { int token; + lc->expect = T_NAME; token = lex_get_token(lc); - if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { - scan_err1(lc, "expected an identifier or string, got: %s", lc->str); - } else if (lc->str_len > MAX_RES_NAME_LENGTH) { - scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, - lc->str_len, MAX_RES_NAME_LENGTH); - } else { - /* Store the name both pass 1 and pass 2 */ - *(item->value) = bstrdup(lc->str); - } + /* Store the name both pass 1 and pass 2 */ + *(item->value) = bstrdup(lc->str); scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); } @@ -356,16 +350,11 @@ void store_strname(LEX *lc, struct res_items *item, int index, int pass) { int token; + lc->expect = T_NAME; token = lex_get_token(lc); - if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { - scan_err1(lc, "expected an identifier or string, got: %s", lc->str); - } else if (lc->str_len > MAX_RES_NAME_LENGTH) { - scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, - lc->str_len, MAX_RES_NAME_LENGTH); - } else { - /* Store the name */ - if (pass == 1) - *(item->value) = bstrdup(lc->str); + /* Store the name */ + if (pass == 1) { + *(item->value) = bstrdup(lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); @@ -488,17 +477,9 @@ void store_pint(LEX *lc, struct res_items *item, int index, int pass) { int token; + lc->expect = T_PINT32; token = lex_get_token(lc); - if (token != T_NUMBER || !is_a_number(lc->str)) { - scan_err1(lc, "expected a positive integer number, got: %s", lc->str); - } else { - errno = 0; - token = (int)strtod(lc->str, NULL); - if (errno != 0 || token < 0) { - scan_err1(lc, "expected a postive integer number, got: %s", lc->str); - } - *(int *)(item->value) = token; - } + *(int *)(item->value) = lc->pint32_val; scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); } @@ -509,16 +490,9 @@ void store_int64(LEX *lc, struct res_items *item, int index, int pass) { int token; + lc->expect = T_INT64; token = lex_get_token(lc); - Dmsg2(400, "int64=:%s: %f\n", lc->str, strtod(lc->str, NULL)); - if (token != T_NUMBER || !is_a_number(lc->str)) { - scan_err1(lc, "expected an integer number, got: %s", lc->str); - } else { - errno = 0; - *(int64_t *)(item->value) = (int64_t)strtod(lc->str, NULL); - if (errno != 0) - scan_err1(lc, "expected an integer number, got: %s", lc->str); - } + *(int64_t *)(item->value) = lc->int64_val; scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); } diff --git a/bacula/src/lib/watchdog.c b/bacula/src/lib/watchdog.c index 9cda310aa7..7d345d5fe8 100755 --- a/bacula/src/lib/watchdog.c +++ b/bacula/src/lib/watchdog.c @@ -134,6 +134,7 @@ static void *watchdog_thread(void *arg) for ( ;!quit; ) { struct timeval tv; struct timezone tz; + time_t timer_start; Dmsg0(200, "Top of for loop\n"); @@ -149,21 +150,30 @@ static void *watchdog_thread(void *arg) continue; } fd = jcr->store_bsock; - if (fd && fd->timer_start && (watchdog_time - fd->timer_start) > fd->timeout) { + timer_start = fd->timer_start; + if (fd && timer_start && (watchdog_time - timer_start) > fd->timeout) { fd->timed_out = TRUE; - Jmsg(jcr, M_ERROR, 0, "Watchdog sending kill to thread stalled reading Storage daemon.\n"); + Jmsg(jcr, M_ERROR, 0, _( +"Watchdog sending kill after %d secs to thread stalled reading Storage daemon.\n"), + watchdog_time - timer_start); pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); } fd = jcr->file_bsock; - if (fd && fd->timer_start && (watchdog_time - fd->timer_start) > fd->timeout) { + timer_start = fd->timer_start; + if (fd && timer_start && (watchdog_time - timer_start) > fd->timeout) { fd->timed_out = TRUE; - Jmsg(jcr, M_ERROR, 0, "Watchdog sending kill to thread stalled reading File daemon.\n"); + Jmsg(jcr, M_ERROR, 0, _( +"Watchdog sending kill after %d secs to thread stalled reading File daemon.\n"), + watchdog_time - timer_start); pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); } fd = jcr->dir_bsock; - if (fd && fd->timer_start && (watchdog_time - fd->timer_start) > fd->timeout) { + timer_start = fd->timer_start; + if (fd && timer_start && (watchdog_time - timer_start) > fd->timeout) { fd->timed_out = TRUE; - Jmsg(jcr, M_ERROR, 0, "Watchdog sending kill to thread stalled reading Director.\n"); + Jmsg(jcr, M_ERROR, 0, _( +"Watchdog sending kill after %d secs to thread stalled reading Director.\n"), + watchdog_time - timer_start); pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); } diff --git a/bacula/src/stored/Makefile.in b/bacula/src/stored/Makefile.in index 21dad53ec7..35ea4a20bf 100644 --- a/bacula/src/stored/Makefile.in +++ b/bacula/src/stored/Makefile.in @@ -80,7 +80,7 @@ btape: $(TAPEOBJS) ../lib/libbac.a ../cats/libsql.a bls: ../findlib/libfind.a $(BLSOBJS) ../lib/libbac.a $(CXX) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BLSOBJS) $(LIBS) $(DLIB) -lbac -lfind -lm -bextract: ../findlib/libfind.a $(BEXTOBJS) +bextract: ../findlib/libfind.a $(BEXTOBJS) ../lib/libbac.a $(CXX) $(LDFLAGS) -L../lib -L../findlib -o $@ $(BEXTOBJS) $(LIBS) $(DLIB) $(FDLIBS) -lbac -lfind -lm bscan: ../findlib/libfind.a $(SCNOBJS) ../cats/libsql.a diff --git a/bacula/src/stored/authenticate.c b/bacula/src/stored/authenticate.c index 77a41a9703..be18fb9ca0 100644 --- a/bacula/src/stored/authenticate.c +++ b/bacula/src/stored/authenticate.c @@ -40,7 +40,7 @@ static char OK_hello[] = "3000 OK Hello\n"; static int authenticate(int rcode, BSOCK *bs) { char *name; - DIRRES *director; + DIRRES *director = NULL; if (rcode != R_DIRECTOR) { Emsg1(M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode); @@ -50,8 +50,7 @@ static int authenticate(int rcode, BSOCK *bs) name = (char *) check_pool_memory_size(name, bs->msglen); if (sscanf(bs->msg, "Hello Director %127s calling\n", name) != 1) { - free_pool_memory(name); - Emsg1(M_FATAL, 0, _("Authentication failure: %s\n"), bs->msg); + Emsg1(M_FATAL, 0, _("Bad Hello command from Director: %s\n"), bs->msg); return 0; } director = NULL; @@ -61,12 +60,21 @@ static int authenticate(int rcode, BSOCK *bs) break; } UnlockRes(); - if (director && (!cram_md5_auth(bs, director->password) || - !cram_md5_get_auth(bs, director->password))) { - director = NULL; + if (!director) { + Emsg1(M_FATAL, 0, _("Connection from unknown Director %s rejected.\n"), name); + goto bail_out; } + if (!cram_md5_auth(bs, director->password) || + !cram_md5_get_auth(bs, director->password)) { + Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n")); + goto bail_out; + } + free_pool_memory(name); + return 1; + +bail_out: free_pool_memory(name); - return (director != NULL); + return 0; } /* @@ -88,6 +96,7 @@ int authenticate_director(JCR *jcr) if (!authenticate(R_DIRECTOR, dir)) { bnet_fsend(dir, "%s", Dir_sorry); Emsg0(M_ERROR, 0, _("Unable to authenticate Director\n")); + sleep(5); return 0; } return bnet_fsend(dir, "%s", OK_hello); @@ -101,5 +110,8 @@ int authenticate_filed(JCR *jcr) cram_md5_get_auth(fd, jcr->sd_auth_key)) { jcr->authenticated = TRUE; } + if (!jcr->authenticated) { + Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon rejected.\n")); + } return jcr->authenticated; } diff --git a/bacula/src/stored/bsr.h b/bacula/src/stored/bsr.h index c6728e17fd..6e08841214 100644 --- a/bacula/src/stored/bsr.h +++ b/bacula/src/stored/bsr.h @@ -48,12 +48,19 @@ typedef struct s_bsr_client { typedef struct s_bsr_sessid { struct s_bsr_sessid *next; - int type; - uint32_t sessid1; + uint32_t sessid; uint32_t sessid2; int found; } BSR_SESSID; +typedef struct s_bsr_volfile { + struct s_bsr_volfile *next; + uint32_t sfile; /* start file */ + uint32_t efile; /* end file */ + int found; +} BSR_VOLFILE; + + typedef struct s_bsr_sesstime { struct s_bsr_sesstime *next; uint32_t sesstime; @@ -62,13 +69,15 @@ typedef struct s_bsr_sesstime { typedef struct s_bsr_findex { struct s_bsr_findex *next; - int32_t FileIndex; + int32_t findex; /* start file index */ + int32_t findex2; /* end file index */ int found; } BSR_FINDEX; typedef struct s_bsr_jobid { struct s_bsr_jobid *next; uint32_t JobId; + uint32_t JobId2; int found; } BSR_JOBID; @@ -101,6 +110,7 @@ typedef struct s_bsr { BSR_JOBID *JobId; BSR_JOBTYPE *JobType; BSR_JOBLEVEL *JobLevel; + BSR_VOLFILE *volfile; FF_PKT *ff; /* include/exclude */ } BSR; diff --git a/bacula/src/stored/match_bsr.c b/bacula/src/stored/match_bsr.c index 2bdcbcb8ae..2038f5ef45 100755 --- a/bacula/src/stored/match_bsr.c +++ b/bacula/src/stored/match_bsr.c @@ -169,7 +169,7 @@ static int match_file_index(BSR_FINDEX *findex, DEV_RECORD *rec) if (!findex) { return 1; /* no specification matches all */ } - if (findex->FileIndex == rec->FileIndex) { + if (findex->findex >= rec->FileIndex && findex->findex2 <= rec->FileIndex) { findex->found++; return 1; } @@ -185,7 +185,7 @@ static int match_sessid(BSR_SESSID *sessid, DEV_RECORD *rec) if (!sessid) { return 1; /* no specification matches all */ } - if (sessid->sessid1 == rec->VolSessionId) { + if (sessid->sessid >= rec->VolSessionId && sessid->sessid2 <= rec->VolSessionId) { sessid->found++; return 1; } diff --git a/bacula/src/stored/parse_bsr.c b/bacula/src/stored/parse_bsr.c index e26ad8af47..0a32e9cdc8 100755 --- a/bacula/src/stored/parse_bsr.c +++ b/bacula/src/stored/parse_bsr.c @@ -40,6 +40,7 @@ static BSR *store_jobtype(LEX *lc, BSR *bsr); static BSR *store_joblevel(LEX *lc, BSR *bsr); static BSR *store_file_index(LEX *lc, BSR *bsr); static BSR *store_sessid(LEX *lc, BSR *bsr); +static BSR *store_volfile(LEX *lc, BSR *bsr); static BSR *store_sesstime(LEX *lc, BSR *bsr); static BSR *store_include(LEX *lc, BSR *bsr); static BSR *store_exclude(LEX *lc, BSR *bsr); @@ -61,6 +62,7 @@ struct kw_items items[] = { {"volsessiontime", store_sesstime}, {"include", store_include}, {"exclude", store_exclude}, + {"volfile", store_volfile}, {NULL, NULL} }; @@ -101,7 +103,7 @@ BSR *parse_bsr(char *cf) if (token != T_EQUALS) { scan_err1(lc, "expected an equals, got: %s", lc->str); } - Dmsg1(150, "calling handler for %s\n", items[i].name); + Dmsg1(100, "calling handler for %s\n", items[i].name); /* Call item handler */ bsr = items[i].handler(lc, bsr); i = -1; @@ -145,13 +147,9 @@ static BSR *store_client(LEX *lc, BSR *bsr) int token; BSR_CLIENT *client; - token = lex_get_token(lc); - if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { - scan_err1(lc, "expected an identifier or string, got: %s", lc->str); - } else if (lc->str_len > MAX_RES_NAME_LENGTH) { - scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, - lc->str_len, MAX_RES_NAME_LENGTH); - } else { + for (;;) { + lc->expect = T_NAME; + token = lex_get_token(lc); client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT)); memset(client, 0, sizeof(BSR_CLIENT)); client->ClientName = bstrdup(lc->str); @@ -169,8 +167,13 @@ static BSR *store_client(LEX *lc, BSR *bsr) } } } + lc->expect = 0; + token = lex_get_token(lc); + if (token != T_COMMA) { + break; + } } - scan_to_eol(lc); +// scan_to_eol(lc); return bsr; } @@ -179,26 +182,20 @@ static BSR *store_job(LEX *lc, BSR *bsr) int token; BSR_JOB *job; + lc->expect = T_NAME; token = lex_get_token(lc); - if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { - scan_err1(lc, "expected an identifier or string, got: %s", lc->str); - } else if (lc->str_len > MAX_RES_NAME_LENGTH) { - scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, - lc->str_len, MAX_RES_NAME_LENGTH); + job = (BSR_JOB *)malloc(sizeof(BSR_JOB)); + memset(job, 0, sizeof(BSR_JOB)); + job->Job = bstrdup(lc->str); + /* Add it to the end of the client chain */ + if (!bsr->job) { + bsr->job = job; } else { - job = (BSR_JOB *)malloc(sizeof(BSR_JOB)); - memset(job, 0, sizeof(BSR_JOB)); - job->Job = bstrdup(lc->str); - /* Add it to the end of the client chain */ - if (!bsr->job) { - bsr->job = job; - } else { - /* Add to end of chain */ - BSR_JOB *bc = bsr->job; - for ( ;bc->next; bc=bc->next) - { } - bc->next = job; - } + /* Add to end of chain */ + BSR_JOB *bc = bsr->job; + for ( ;bc->next; bc=bc->next) + { } + bc->next = job; } scan_to_eol(lc); return bsr; @@ -207,22 +204,15 @@ static BSR *store_job(LEX *lc, BSR *bsr) static BSR *store_file_index(LEX *lc, BSR *bsr) { int token; - int32_t FileIndex; BSR_FINDEX *findex; - - token = lex_get_token(lc); - if (token != T_NUMBER || !is_a_number(lc->str)) { - scan_err1(lc, "expected a positive integer number, got: %s", lc->str); - } else { - errno = 0; - FileIndex = strtoul(lc->str, NULL, 10); - if (errno != 0) { - scan_err1(lc, "expected a integer number, got: %s", lc->str); - } + for (;;) { + lc->expect = T_PINT32_RANGE; + token = lex_get_token(lc); findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX)); memset(findex, 0, sizeof(BSR_FINDEX)); - findex->FileIndex = FileIndex; + findex->findex = lc->pint32_val; + findex->findex2 = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->FileIndex) { bsr->FileIndex = findex; @@ -233,8 +223,13 @@ static BSR *store_file_index(LEX *lc, BSR *bsr) { } bs->next = findex; } + lc->expect = 0; + token = lex_get_token(lc); + if (token != T_COMMA) { + break; + } } - scan_to_eol(lc); +// scan_to_eol(lc); return bsr; } @@ -242,22 +237,15 @@ static BSR *store_file_index(LEX *lc, BSR *bsr) static BSR *store_jobid(LEX *lc, BSR *bsr) { int token; - uint32_t JobId; BSR_JOBID *jobid; - - token = lex_get_token(lc); - if (token != T_NUMBER || !is_a_number(lc->str)) { - scan_err1(lc, "expected a positive integer number, got: %s", lc->str); - } else { - errno = 0; - JobId = strtoul(lc->str, NULL, 10); - if (errno != 0) { - scan_err1(lc, "expected a integer number, got: %s", lc->str); - } + for (;;) { + lc->expect = T_PINT32_RANGE; + token = lex_get_token(lc); jobid = (BSR_JOBID *)malloc(sizeof(BSR_JOBID)); memset(jobid, 0, sizeof(BSR_JOBID)); - jobid->JobId = JobId; + jobid->JobId = lc->pint32_val; + jobid->JobId2 = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->JobId) { bsr->JobId = jobid; @@ -268,8 +256,13 @@ static BSR *store_jobid(LEX *lc, BSR *bsr) { } bs->next = jobid; } + lc->expect = 0; + token = lex_get_token(lc); + if (token != T_COMMA) { + break; + } } - scan_to_eol(lc); +// scan_to_eol(lc); return bsr; } @@ -290,25 +283,56 @@ static BSR *store_joblevel(LEX *lc, BSR *bsr) + +/* + * Routine to handle Volume start/end file + */ +static BSR *store_volfile(LEX *lc, BSR *bsr) +{ + int token; + BSR_VOLFILE *volfile; + + for (;;) { + lc->expect = T_PINT32_RANGE; + token = lex_get_token(lc); + volfile = (BSR_VOLFILE *)malloc(sizeof(BSR_VOLFILE)); + memset(volfile, 0, sizeof(BSR_VOLFILE)); + volfile->sfile = lc->pint32_val; + volfile->efile = lc->pint32_val2; + /* Add it to the end of the chain */ + if (!bsr->volfile) { + bsr->volfile = volfile; + } else { + /* Add to end of chain */ + BSR_VOLFILE *bs = bsr->volfile; + for ( ;bs->next; bs=bs->next) + { } + bs->next = volfile; + } + lc->expect = 0; + token = lex_get_token(lc); + if (token != T_COMMA) { + break; + } + } +// scan_to_eol(lc); + return bsr; +} + + + static BSR *store_sessid(LEX *lc, BSR *bsr) { int token; - uint32_t sessid1; BSR_SESSID *sid; - - token = lex_get_token(lc); - if (token != T_NUMBER || !is_a_number(lc->str)) { - scan_err1(lc, "expected a positive integer number, got: %s", lc->str); - } else { - errno = 0; - sessid1 = strtoul(lc->str, NULL, 10); - if (errno != 0) { - scan_err1(lc, "expected a integer number, got: %s", lc->str); - } + for (;;) { + lc->expect = T_PINT32_RANGE; + token = lex_get_token(lc); sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID)); memset(sid, 0, sizeof(BSR_SESSID)); - sid->sessid1 = sessid1; + sid->sessid = lc->pint32_val; + sid->sessid2 = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->sessid) { bsr->sessid = sid; @@ -319,40 +343,35 @@ static BSR *store_sessid(LEX *lc, BSR *bsr) { } bs->next = sid; } + lc->expect = 0; + token = lex_get_token(lc); + if (token != T_COMMA) { + break; + } } - scan_to_eol(lc); +// scan_to_eol(lc); return bsr; } static BSR *store_sesstime(LEX *lc, BSR *bsr) { int token; - uint32_t sesstime; BSR_SESSTIME *stime; - + lc->expect = T_PINT32; token = lex_get_token(lc); - if (token != T_NUMBER || !is_a_number(lc->str)) { - scan_err1(lc, "expected a positive integer number, got: %s", lc->str); + stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME)); + memset(stime, 0, sizeof(BSR_SESSTIME)); + stime->sesstime = lc->pint32_val; + /* Add it to the end of the chain */ + if (!bsr->sesstime) { + bsr->sesstime = stime; } else { - errno = 0; - sesstime = strtoul(lc->str, NULL, 10); - if (errno != 0) { - scan_err1(lc, "expected a integer number, got: %s", lc->str); - } - stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME)); - memset(stime, 0, sizeof(BSR_SESSTIME)); - stime->sesstime = sesstime; - /* Add it to the end of the chain */ - if (!bsr->sesstime) { - bsr->sesstime = stime; - } else { - /* Add to end of chain */ - BSR_SESSTIME *bs = bsr->sesstime; - for ( ;bs->next; bs=bs->next) - { } - bs->next = stime; - } + /* Add to end of chain */ + BSR_SESSTIME *bs = bsr->sesstime; + for ( ;bs->next; bs=bs->next) + { } + bs->next = stime; } scan_to_eol(lc); return bsr; @@ -370,29 +389,105 @@ static BSR *store_exclude(LEX *lc, BSR *bsr) return bsr; } +void dump_volfile(BSR_VOLFILE *volfile) +{ + if (!volfile) { + return; + } + Dmsg2(-1, +"VolFile : %u-%u\n", volfile->sfile, volfile->efile); + dump_volfile(volfile->next); +} + +void dump_findex(BSR_FINDEX *FileIndex) +{ + if (!FileIndex) { + return; + } + if (FileIndex->findex == FileIndex->findex2) { + Dmsg1(-1, "FileIndex : %u\n", FileIndex->findex); + } else { + Dmsg2(-1, "FileIndex : %u-%u\n", FileIndex->findex, FileIndex->findex2); + } + dump_findex(FileIndex->next); +} + +void dump_jobid(BSR_JOBID *jobid) +{ + if (!jobid) { + return; + } + if (jobid->JobId == jobid->JobId2) { + Dmsg1(-1, "JobId : %u\n", jobid->JobId); + } else { + Dmsg2(-1, "JobId : %u-%u\n", jobid->JobId, jobid->JobId2); + } + dump_jobid(jobid->next); +} + +void dump_sessid(BSR_SESSID *sessid) +{ + if (!sessid) { + return; + } + if (sessid->sessid == sessid->sessid2) { + Dmsg1(-1, "SessId : %u\n", sessid->sessid); + } else { + Dmsg2(-1, "SessId : %u-%u\n", sessid->sessid, sessid->sessid2); + } + dump_sessid(sessid->next); +} + + +void dump_client(BSR_CLIENT *client) +{ + if (!client) { + return; + } + Dmsg1(-1, "Client : %s\n", client->ClientName); + dump_client(client->next); +} + +void dump_job(BSR_JOB *job) +{ + if (!job) { + return; + } + Dmsg1(-1, "Job : %s\n", job->Job); + dump_job(job->next); +} + +void dump_sesstime(BSR_SESSTIME *sesstime) +{ + if (!sesstime) { + return; + } + Dmsg1(-1, "SessTime : %u\n", sesstime->sesstime); + dump_sesstime(sesstime->next); +} + + + + + void dump_bsr(BSR *bsr) { if (!bsr) { Dmsg0(-1, "BSR is NULL\n"); return; } - Dmsg8(-1, + Dmsg2(-1, "Next : 0x%x\n" -"VolumeName : %s\n" -"Client : %s\n" -"Job : %s\n" -"JobId : %u\n" -"SessId : %u\n" -"SessTime : %u\n" -"FileIndex : %d\n", +"VolumeName : %s\n", bsr->next, - bsr->VolumeName ? bsr->VolumeName : "*None*", - bsr->client ? bsr->client->ClientName : "*None*", - bsr->job ? bsr->job->Job : "*None*", - bsr->JobId ? bsr->JobId->JobId : 0, - bsr->sessid ? bsr->sessid->sessid1 : 0, - bsr->sesstime ? bsr->sesstime->sesstime : 0, - bsr->FileIndex ? bsr->FileIndex->FileIndex : 0); + bsr->VolumeName ? bsr->VolumeName : "*None*"); + dump_sessid(bsr->sessid); + dump_sesstime(bsr->sesstime); + dump_volfile(bsr->volfile); + dump_client(bsr->client); + dump_jobid(bsr->JobId); + dump_job(bsr->job); + dump_findex(bsr->FileIndex); if (bsr->next) { Dmsg0(-1, "\n"); dump_bsr(bsr->next); @@ -400,6 +495,7 @@ void dump_bsr(BSR *bsr) } + /********************************************************************* * * Free bsr resources @@ -422,6 +518,7 @@ void free_bsr(BSR *bsr) free_bsr_item((BSR *)bsr->client); free_bsr_item((BSR *)bsr->sessid); free_bsr_item((BSR *)bsr->sesstime); + free_bsr_item((BSR *)bsr->volfile); if (bsr->VolumeName) { free(bsr->VolumeName); } diff --git a/bacula/src/stored/read.c b/bacula/src/stored/read.c index 8d3c719de8..d956494a10 100644 --- a/bacula/src/stored/read.c +++ b/bacula/src/stored/read.c @@ -109,6 +109,7 @@ int do_read_data(JCR *jcr) */ for ( ;ok; ) { DEV_RECORD *record; /* for reading label of multi-volumes */ + SESSION_LABEL sessrec; /* session record */ if (job_cancelled(jcr)) { ok = FALSE; @@ -156,6 +157,34 @@ int do_read_data(JCR *jcr) /* Some sort of label? */ if (rec.FileIndex < 0) { + char *rtype; + switch (rec.FileIndex) { + case PRE_LABEL: + rtype = "Fresh Volume Label"; + break; + case VOL_LABEL: + rtype = "Volume Label"; + unser_volume_label(dev, &rec); + break; + case SOS_LABEL: + rtype = "Begin Session"; + unser_session_label(&sessrec, &rec); + break; + case EOS_LABEL: + rtype = "End Session"; + break; + case EOM_LABEL: + rtype = "End of Media"; + break; + default: + rtype = "Unknown"; + break; + } + if (debug_level > 0) { + printf("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n", + rtype, rec.VolSessionId, rec.VolSessionTime, rec.Stream, rec.data_len); + } + Dmsg1(40, "Got label = %d\n", rec.FileIndex); if (rec.FileIndex == EOM_LABEL) { /* end of tape? */ Dmsg0(40, "Get EOM LABEL\n"); @@ -164,6 +193,12 @@ int do_read_data(JCR *jcr) continue; /* ignore other labels */ } + /* ****FIXME***** make sure we REALLY have a session record */ + if (jcr->bsr && !match_bsr(jcr->bsr, &rec, &dev->VolHdr, &sessrec)) { + Dmsg0(50, "BSR rejected record\n"); + continue; + } + if (rec.VolSessionId != jcr->read_VolSessionId || rec.VolSessionTime != jcr->read_VolSessionTime) { Dmsg0(50, "Ignore record ids not equal\n"); diff --git a/bacula/src/stored/stored.h b/bacula/src/stored/stored.h index 91d274510d..022f3ee62f 100644 --- a/bacula/src/stored/stored.h +++ b/bacula/src/stored/stored.h @@ -31,8 +31,8 @@ #include "record.h" #include "dev.h" #include "stored_conf.h" -#include "jcr.h" #include "bsr.h" +#include "jcr.h" #include "protos.h" #ifdef HAVE_LIBZ #include /* compression headers */ diff --git a/bacula/src/version.h b/bacula/src/version.h index 9125719d82..073aee4e81 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.22" #define VSTRING "1" -#define DATE "15 June 2002" -#define LSMDATE "15Jun02" +#define DATE "19 June 2002" +#define LSMDATE "19Jun02" /* Debug flags */ #define DEBUG 1 -- 2.39.5