From 099fc761d52104a69c0d0fd2f114b0a0735307e7 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 15 Jan 2004 14:03:43 +0000 Subject: [PATCH] Implement first cut of multiple consoles git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1012 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/console/authenticate.c | 7 +- bacula/src/console/console.c | 14 ++- bacula/src/console/console_conf.c | 2 +- bacula/src/console/console_conf.h | 44 ++++---- bacula/src/dird/authenticate.c | 28 +++-- bacula/src/gnome2-console/authenticate.c | 7 +- bacula/src/gnome2-console/console.c | 66 ++++++----- bacula/src/gnome2-console/console_conf.c | 134 +++++++++++------------ 8 files changed, 168 insertions(+), 134 deletions(-) diff --git a/bacula/src/console/authenticate.c b/bacula/src/console/authenticate.c index ef679da182..b6f0726a4c 100644 --- a/bacula/src/console/authenticate.c +++ b/bacula/src/console/authenticate.c @@ -47,15 +47,18 @@ static char OKhello[] = "1000 OK:"; /* * Authenticate Director */ -int authenticate_director(JCR *jcr, DIRRES *director) +int authenticate_director(JCR *jcr, DIRRES *director, char *name) { BSOCK *dir = jcr->dir_bsock; int ssl_need = BNET_SSL_NONE; + char bashed_name[MAX_NAME_LENGTH]; /* * Send my name to the Director then do authentication */ - bnet_fsend(dir, hello, "UserAgent"); + bstrncpy(bashed_name, name, sizeof(bashed_name)); + bash_spaces(bashed_name); + bnet_fsend(dir, hello, bashed_name); if (!cram_md5_get_auth(dir, director->password, ssl_need) || !cram_md5_auth(dir, director->password, ssl_need)) { diff --git a/bacula/src/console/console.c b/bacula/src/console/console.c index 51f49961d0..b59e601eba 100644 --- a/bacula/src/console/console.c +++ b/bacula/src/console/console.c @@ -51,7 +51,7 @@ extern int rl_catch_signals; #endif /* Imported functions */ -int authenticate_director(JCR *jcr, DIRRES *director); +int authenticate_director(JCR *jcr, DIRRES *director, char *name); @@ -398,7 +398,17 @@ try_again: return 1; } jcr.dir_bsock = UA_sock; - if (!authenticate_director(&jcr, dir)) { + + LockRes(); + CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL); + UnlockRes(); + char *con_name; + if (cons) { + con_name = cons->hdr.name; + } else { + con_name = "*UserAgent*"; + } + if (!authenticate_director(&jcr, dir, con_name)) { fprintf(stderr, "ERR=%s", UA_sock->msg); terminate_console(0); return 1; diff --git a/bacula/src/console/console_conf.c b/bacula/src/console/console_conf.c index f69975c2d2..ef7eb49399 100644 --- a/bacula/src/console/console_conf.c +++ b/bacula/src/console/console_conf.c @@ -235,7 +235,7 @@ void save_resource(int type, struct res_items *items, int pass) /* The following code is only executed during pass 1 */ switch (type) { case R_CONSOLE: - size = sizeof(CONSRES); + size = sizeof(CONRES); break; case R_DIRECTOR: size = sizeof(DIRRES); diff --git a/bacula/src/console/console_conf.h b/bacula/src/console/console_conf.h index 7326b55bfe..e01c21bf78 100644 --- a/bacula/src/console/console_conf.h +++ b/bacula/src/console/console_conf.h @@ -9,41 +9,41 @@ /* * Resource codes -- they must be sequential for indexing */ -#define R_FIRST 1001 +#define R_FIRST 1001 -#define R_CONSOLE 1001 -#define R_DIRECTOR 1002 +#define R_CONSOLE 1001 +#define R_DIRECTOR 1002 -#define R_LAST R_DIRECTOR +#define R_LAST R_DIRECTOR /* * Some resource attributes */ -#define R_NAME 1020 -#define R_ADDRESS 1021 -#define R_PASSWORD 1022 -#define R_TYPE 1023 -#define R_BACKUP 1024 +#define R_NAME 1020 +#define R_ADDRESS 1021 +#define R_PASSWORD 1022 +#define R_TYPE 1023 +#define R_BACKUP 1024 /* Definition of the contents of each Resource */ /* Console "globals" */ -struct s_res_cons { - RES hdr; - char *rc_file; /* startup file */ - char *hist_file; /* command history file */ - int require_ssl; /* Require SSL on all connections */ +struct s_res_con { + RES hdr; + char *rc_file; /* startup file */ + char *hist_file; /* command history file */ + int require_ssl; /* Require SSL on all connections */ }; -typedef struct s_res_cons CONSRES; +typedef struct s_res_con CONRES; /* Director */ struct s_res_dir { - RES hdr; - int DIRport; /* UA server port */ - char *address; /* UA server address */ - char *password; /* UA server password */ - int enable_ssl; /* Use SSL */ + RES hdr; + int DIRport; /* UA server port */ + char *address; /* UA server address */ + char *password; /* UA server password */ + int enable_ssl; /* Use SSL */ }; typedef struct s_res_dir DIRRES; @@ -52,8 +52,8 @@ typedef struct s_res_dir DIRRES; * resource structure definitions. */ union u_res { - struct s_res_dir res_dir; - struct s_res_cons res_cons; + struct s_res_dir res_dir; + struct s_res_con res_cons; RES hdr; }; diff --git a/bacula/src/dird/authenticate.c b/bacula/src/dird/authenticate.c index 9ec6d81bf1..9dacdb6d87 100644 --- a/bacula/src/dird/authenticate.c +++ b/bacula/src/dird/authenticate.c @@ -128,11 +128,11 @@ int authenticate_file_daemon(JCR *jcr) */ int authenticate_user_agent(BSOCK *ua) { - char name[MAXSTRING]; + char name[MAX_NAME_LENGTH]; int ssl_need = BNET_SSL_NONE; - int ok; + bool ok; - if (ua->msglen < 16 || ua->msglen >= MAXSTRING-1) { + if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) { Emsg2(M_ERROR, 0, _("UA Hello from %s is invalid. Len=%d\n"), ua->who, ua->msglen); return 0; @@ -144,14 +144,24 @@ int authenticate_user_agent(BSOCK *ua) ua->msg); return 0; } - - ok = cram_md5_auth(ua, director->password, ssl_need) && - cram_md5_get_auth(ua, director->password, ssl_need); - + name[MAXSTRING-1] = 0; /* terminate name */ + if (strcmp(name, "*UserAgent*") == 0) { /* default console */ + ok = cram_md5_auth(ua, director->password, ssl_need) && + cram_md5_get_auth(ua, director->password, ssl_need); + } else { + unbash_spaces(name); + CONRES *cons = (CONRES *)GetResWithName(R_CONSOLE, name); + if (cons) { + ok = cram_md5_auth(ua, cons->password, ssl_need) && + cram_md5_get_auth(ua, cons->password, ssl_need); + } else { + ok = false; + } + } if (!ok) { bnet_fsend(ua, "%s", _(Dir_sorry)); - Emsg1(M_WARNING, 0, _("Unable to authenticate User Agent at %s.\n"), - ua->who); + Emsg2(M_ERROR, 0, _("Unable to authenticate User Agent \"%s\" at %s.\n"), + name, ua->who); sleep(5); return 0; } diff --git a/bacula/src/gnome2-console/authenticate.c b/bacula/src/gnome2-console/authenticate.c index 3fe7a2f1be..0aa3f7d365 100644 --- a/bacula/src/gnome2-console/authenticate.c +++ b/bacula/src/gnome2-console/authenticate.c @@ -45,15 +45,18 @@ static char OKhello[] = "1000 OK:"; /* * Authenticate Director */ -int authenticate_director(JCR *jcr, DIRRES *director) +int authenticate_director(JCR *jcr, DIRRES *director, char *name) { BSOCK *dir = jcr->dir_bsock; int ssl_need = BNET_SSL_NONE; + char bashed_name[MAX_NAME_LENGTH]; /* * Send my name to the Director then do authentication */ - bnet_fsend(dir, hello, "UserAgent"); + bstrncpy(bashed_name, name, sizeof(bashed_name)); + bash_spaces(bashed_name); + bnet_fsend(dir, hello, bashed_name); if (!cram_md5_get_auth(dir, director->password, ssl_need) || !cram_md5_auth(dir, director->password, ssl_need)) { diff --git a/bacula/src/gnome2-console/console.c b/bacula/src/gnome2-console/console.c index 1fb76c08d4..b7e76655fa 100644 --- a/bacula/src/gnome2-console/console.c +++ b/bacula/src/gnome2-console/console.c @@ -32,7 +32,7 @@ #include "support.h" /* Imported functions */ -int authenticate_director(JCR *jcr, DIRRES *director); +int authenticate_director(JCR *jcr, DIRRES *director, char *name); /* Exported variables */ GtkWidget *app1; /* application window */ @@ -127,30 +127,29 @@ int main(int argc, char *argv[]) while ((ch = getopt(argc, argv, "bc:d:r:st?")) != -1) { switch (ch) { - case 'c': /* configuration file */ - if (configfile != NULL) - free(configfile); - configfile = bstrdup(optarg); - break; - - case 'd': - debug_level = atoi(optarg); - if (debug_level <= 0) - debug_level = 1; - break; - - case 's': /* turn off signals */ - no_signals = TRUE; - break; - - case 't': - test_config = TRUE; - break; - - case '?': - default: - usage(); - + case 'c': /* configuration file */ + if (configfile != NULL) + free(configfile); + configfile = bstrdup(optarg); + break; + + case 'd': + debug_level = atoi(optarg); + if (debug_level <= 0) + debug_level = 1; + break; + + case 's': /* turn off signals */ + no_signals = TRUE; + break; + + case 't': + test_config = TRUE; + break; + + case '?': + default: + usage(); } } argc -= optind; @@ -238,7 +237,6 @@ Without that I don't how to speak to the Director :-(\n"), configfile); gtk_widget_modify_font (status1, font_desc); pango_font_description_free (font_desc); - initial = gtk_timeout_add(100, initial_connect_to_director, (gpointer)NULL); gtk_main(); @@ -261,8 +259,9 @@ static gint message_handler(gpointer data) int disconnect_from_director(gpointer data) { - if (!quit) + if (!quit) { set_status(_(" Not Connected")); + } if (UA_sock) { bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */ bnet_close(UA_sock); @@ -345,7 +344,7 @@ int connect_to_director(gpointer data) if (ndir > 1) { LockRes(); - for (dir = NULL; (dir = (DIRRES *)GetNextRes(R_DIRECTOR, (RES *)dir)); ) { + foreach_res(dir, R_DIRECTOR) { sprintf(buf, "%s at %s:%d", dir->hdr.name, dir->address, dir->DIRport); printf("%s\n", buf); @@ -399,7 +398,16 @@ int connect_to_director(gpointer data) } jcr.dir_bsock = UA_sock; - if (!authenticate_director(&jcr, dir)) { + LockRes(); + CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL); + UnlockRes(); + char *con_name; + if (cons) { + con_name = cons->hdr.name; + } else { + con_name = "*UserAgent*"; + } + if (!authenticate_director(&jcr, dir, con_name)) { set_text(UA_sock->msg, UA_sock->msglen); return 0; } diff --git a/bacula/src/gnome2-console/console_conf.c b/bacula/src/gnome2-console/console_conf.c index 725fc024d9..7b5b1fbdd6 100644 --- a/bacula/src/gnome2-console/console_conf.c +++ b/bacula/src/gnome2-console/console_conf.c @@ -8,14 +8,14 @@ * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and - * lib/parse_config.h. - * These files contain the parser code, some utility - * routines, and the common store routines (name, int, - * string). + * lib/parse_config.h. + * These files contain the parser code, some utility + * routines, and the common store routines (name, int, + * string). * * 3. The daemon specific file, which contains the Resource - * definitions as well as any specific store routines - * for the resource records. + * definitions as well as any specific store routines + * for the resource records. * * Kern Sibbald, January MM, September MM * @@ -91,7 +91,7 @@ static struct res_items con_items[] = { struct s_res resources[] = { {"director", dir_items, R_DIRECTOR, NULL}, {"consolefont", con_items, R_CONSOLE, NULL}, - {NULL, NULL, 0, NULL} + {NULL, NULL, 0, NULL} }; @@ -105,21 +105,21 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... printf("No record for %d %s\n", type, res_to_str(type)); return; } - if (type < 0) { /* no recursion */ + if (type < 0) { /* no recursion */ type = - type; recurse = 0; } switch (type) { - case R_DIRECTOR: - printf("Director: name=%s address=%s DIRport=%d\n", reshdr->name, - res->res_dir.address, res->res_dir.DIRport); - break; - case R_CONSOLE: - printf("Console: name=%s font face=%s\n", - reshdr->name, NPRT(res->con_dir.fontface)); - break; - default: - printf("Unknown resource type %d\n", type); + case R_DIRECTOR: + printf("Director: name=%s address=%s DIRport=%d\n", reshdr->name, + res->res_dir.address, res->res_dir.DIRport); + break; + case R_CONSOLE: + printf("Console: name=%s font face=%s\n", + reshdr->name, NPRT(res->con_dir.fontface)); + break; + default: + printf("Unknown resource type %d\n", type); } if (recurse && res->res_dir.hdr.next) { dump_resource(type, res->res_dir.hdr.next, sendit, sock); @@ -154,18 +154,18 @@ void free_resource(int type) } switch (type) { - case R_DIRECTOR: - if (res->res_dir.address) { - free(res->res_dir.address); - } - break; - case R_CONSOLE: - if (res->con_dir.fontface) { - free(res->con_dir.fontface); - } - break; - default: - printf("Unknown resource type %d\n", type); + case R_DIRECTOR: + if (res->res_dir.address) { + free(res->res_dir.address); + } + break; + case R_CONSOLE: + if (res->con_dir.fontface) { + free(res->con_dir.fontface); + } + break; + default: + printf("Unknown resource type %d\n", type); } /* Common stuff again -- free the resource, recurse to next one */ free(res); @@ -191,10 +191,10 @@ void save_resource(int type, struct res_items *items, int pass) */ for (i=0; items[i].name; i++) { if (items[i].flags & ITEM_REQUIRED) { - if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { + if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { Emsg2(M_ABORT, 0, "%s item is required in %s resource, but not found.\n", - items[i].name, resources[rindex]); - } + items[i].name, resources[rindex]); + } } } @@ -205,64 +205,64 @@ void save_resource(int type, struct res_items *items, int pass) */ if (pass == 2) { switch (type) { - /* Resources not containing a resource */ - case R_DIRECTOR: - break; + /* Resources not containing a resource */ + case R_DIRECTOR: + break; - case R_CONSOLE: - break; + case R_CONSOLE: + break; - default: - Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type); - error = 1; - break; + default: + Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type); + error = 1; + break; } /* Note, the resoure name was already saved during pass 1, * so here, we can just release it. */ if (res_all.res_dir.hdr.name) { - free(res_all.res_dir.hdr.name); - res_all.res_dir.hdr.name = NULL; + free(res_all.res_dir.hdr.name); + res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { - free(res_all.res_dir.hdr.desc); - res_all.res_dir.hdr.desc = NULL; + free(res_all.res_dir.hdr.desc); + res_all.res_dir.hdr.desc = NULL; } return; } /* The following code is only executed during pass 1 */ switch (type) { - case R_DIRECTOR: - size = sizeof(DIRRES); - break; - case R_CONSOLE: - size = sizeof(CONRES); - break; - default: - printf("Unknown resource type %d\n", type); - error = 1; - break; + case R_DIRECTOR: + size = sizeof(DIRRES); + break; + case R_CONSOLE: + size = sizeof(CONRES); + break; + default: + printf("Unknown resource type %d\n", type); + error = 1; + break; } /* Common */ if (!error) { res = (URES *)malloc(size); memcpy(res, &res_all, size); if (!resources[rindex].res_head) { - resources[rindex].res_head = (RES *)res; /* store first entry */ + resources[rindex].res_head = (RES *)res; /* store first entry */ } else { - RES *next; - /* Add new res to end of chain */ - for (next=resources[rindex].res_head; next->next; next=next->next) { - if (strcmp(next->name, res->res_dir.hdr.name) == 0) { - Emsg2(M_ERROR_TERM, 0, + RES *next; + /* Add new res to end of chain */ + for (next=resources[rindex].res_head; next->next; next=next->next) { + if (strcmp(next->name, res->res_dir.hdr.name) == 0) { + Emsg2(M_ERROR_TERM, 0, _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), - resources[rindex].name, res->res_dir.hdr.name); - } - } - next->next = (RES *)res; + resources[rindex].name, res->res_dir.hdr.name); + } + } + next->next = (RES *)res; Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), - res->res_dir.hdr.name); + res->res_dir.hdr.name); } } } -- 2.39.5