From 5d9617445ed5fd5601274adb713635dafd2f6019 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 17 Jan 2004 14:10:22 +0000 Subject: [PATCH] First cut Console ACLs git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1014 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 1 + bacula/src/console/authenticate.c | 17 +++-- bacula/src/console/console.c | 10 +-- bacula/src/console/console_conf.c | 3 +- bacula/src/console/console_conf.h | 1 + bacula/src/dird/Makefile.in | 4 +- bacula/src/dird/bacula-dir.conf.in | 5 ++ bacula/src/dird/dird_conf.c | 80 +++++++++++++++--------- bacula/src/dird/dird_conf.h | 61 ++++++++++-------- bacula/src/dird/protos.h | 44 +++++++------ bacula/src/dird/ua.h | 2 - bacula/src/dird/ua_acl.c | 59 +++++++++++++++++ bacula/src/dird/ua_cmds.c | 14 ++--- bacula/src/dird/ua_output.c | 1 - bacula/src/dird/ua_select.c | 64 ++++++++++++++----- bacula/src/gnome2-console/authenticate.c | 17 +++-- bacula/src/gnome2-console/console.c | 33 +++++----- bacula/src/gnome2-console/console_conf.c | 75 +++++++++++----------- bacula/src/gnome2-console/console_conf.h | 11 ++-- bacula/src/lib/alist.h | 7 +++ bacula/src/lib/lex.c | 19 +++--- bacula/src/lib/parse_conf.c | 4 +- 22 files changed, 341 insertions(+), 191 deletions(-) create mode 100644 bacula/src/dird/ua_acl.c diff --git a/bacula/kernstodo b/bacula/kernstodo index d8790bd738..9727a4b2bc 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -58,6 +58,7 @@ For 1.33 Testing/Documentation: - Document Pool keyword for restore. For 1.33 +- Implement alist processing for ACLs from Console. - Finish code passing files=nnn to restore start. - Add Console usr permissions -- do by adding regex filters for jobs, clients, storage, ... diff --git a/bacula/src/console/authenticate.c b/bacula/src/console/authenticate.c index b6f0726a4c..ab503db8f2 100644 --- a/bacula/src/console/authenticate.c +++ b/bacula/src/console/authenticate.c @@ -47,21 +47,28 @@ static char OKhello[] = "1000 OK:"; /* * Authenticate Director */ -int authenticate_director(JCR *jcr, DIRRES *director, char *name) +int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) { BSOCK *dir = jcr->dir_bsock; int ssl_need = BNET_SSL_NONE; char bashed_name[MAX_NAME_LENGTH]; + char *password; /* * Send my name to the Director then do authentication */ - bstrncpy(bashed_name, name, sizeof(bashed_name)); - bash_spaces(bashed_name); + if (cons) { + bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name)); + bash_spaces(bashed_name); + password = cons->password; + } else { + bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name)); + password = director->password; + } bnet_fsend(dir, hello, bashed_name); - if (!cram_md5_get_auth(dir, director->password, ssl_need) || - !cram_md5_auth(dir, director->password, ssl_need)) { + if (!cram_md5_get_auth(dir, password, ssl_need) || + !cram_md5_auth(dir, password, ssl_need)) { sendit( _("Director authorization problem.\n" "Most likely the passwords do not agree.\n")); return 0; diff --git a/bacula/src/console/console.c b/bacula/src/console/console.c index 8ea78bbbad..6436ab9a35 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, char *name); +int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons); @@ -404,13 +404,7 @@ try_again: 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)) { + if (!authenticate_director(&jcr, dir, cons)) { 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 ef7eb49399..daeebc898b 100644 --- a/bacula/src/console/console_conf.c +++ b/bacula/src/console/console_conf.c @@ -72,6 +72,7 @@ static struct res_items cons_items[] = { {"rcfile", store_dir, ITEM(res_cons.rc_file), 0, 0, 0}, {"historyfile", store_dir, ITEM(res_cons.hist_file), 0, 0, 0}, {"requiressl", store_yesno, ITEM(res_cons.require_ssl), 1, ITEM_DEFAULT, 0}, + {"password", store_password, ITEM(res_cons.password), 0, ITEM_REQUIRED, 0}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -81,7 +82,7 @@ static struct res_items dir_items[] = { {"name", store_name, ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0}, {"description", store_str, ITEM(res_dir.hdr.desc), 0, 0, 0}, {"dirport", store_int, ITEM(res_dir.DIRport), 0, ITEM_DEFAULT, 9101}, - {"address", store_str, ITEM(res_dir.address), 0, ITEM_REQUIRED, 0}, + {"address", store_str, ITEM(res_dir.address), 0, 0, 0}, {"password", store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0}, {"enablessl", store_yesno, ITEM(res_dir.enable_ssl), 1, ITEM_DEFAULT, 0}, {NULL, NULL, NULL, 0, 0, 0} diff --git a/bacula/src/console/console_conf.h b/bacula/src/console/console_conf.h index e01c21bf78..0b9d52962c 100644 --- a/bacula/src/console/console_conf.h +++ b/bacula/src/console/console_conf.h @@ -34,6 +34,7 @@ struct s_res_con { char *rc_file; /* startup file */ char *hist_file; /* command history file */ int require_ssl; /* Require SSL on all connections */ + char *password; /* UA server password */ }; typedef struct s_res_con CONRES; diff --git a/bacula/src/dird/Makefile.in b/bacula/src/dird/Makefile.in index 851d93d336..a306b01484 100644 --- a/bacula/src/dird/Makefile.in +++ b/bacula/src/dird/Makefile.in @@ -29,7 +29,7 @@ SVRSRCS = dird.c admin.c authenticate.c \ jobq.c mountreq.c msgchan.c next_vol.c newvol.c \ recycle.c restore.c run_conf.c \ scheduler.c sql_cmds.c \ - ua_cmds.c ua_dotcmds.c \ + ua_acl.c ua_cmds.c ua_dotcmds.c \ ua_query.c \ ua_input.c ua_label.c ua_output.c ua_prune.c \ ua_purge.c ua_restore.c ua_run.c \ @@ -42,7 +42,7 @@ SVROBJS = dird.o admin.o authenticate.o \ jobq.o mountreq.o msgchan.o next_vol.o newvol.o \ recycle.o restore.o run_conf.o \ scheduler.o sql_cmds.o \ - ua_cmds.o ua_dotcmds.o \ + ua_acl.o ua_cmds.o ua_dotcmds.o \ ua_query.o \ ua_input.o ua_label.o ua_output.o ua_prune.o \ ua_purge.o ua_restore.o ua_run.o \ diff --git a/bacula/src/dird/bacula-dir.conf.in b/bacula/src/dird/bacula-dir.conf.in index bb56eacb04..a76448c7e7 100644 --- a/bacula/src/dird/bacula-dir.conf.in +++ b/bacula/src/dird/bacula-dir.conf.in @@ -177,6 +177,11 @@ Catalog { # and to the console Messages { Name = Standard +# +# NOTE! If you send to two email or more email addresses, you will need +# to replace the %r in the from field (-f part) with a single valid +# email address in both the mailcommand and the operatorcommand. +# mailcommand = "@sbindir@/bsmtp -h @smtp_host@ -f \"\(Bacula\) %r\" -s \"Bacula: %t %e of %c %l\" %r" operatorcommand = "@sbindir@/bsmtp -h @smtp_host@ -f \"\(Bacula\) %r\" -s \"Bacula: Intervention needed for %j\" %r" mail = @job_email@ = all, !skipped diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 3f4303b8a5..f41dce96e5 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -64,6 +64,7 @@ extern void store_inc(LEX *lc, struct res_items *item, int index, int pass); void store_jobtype(LEX *lc, struct res_items *item, int index, int pass); void store_level(LEX *lc, struct res_items *item, int index, int pass); void store_replace(LEX *lc, struct res_items *item, int index, int pass); +void store_acl(LEX *lc, struct res_items *item, int index, int pass); /* We build the current resource here as we are @@ -113,6 +114,15 @@ static struct res_items con_items[] = { {"description", store_str, ITEM(res_con.hdr.desc), 0, 0, 0}, {"enablessl", store_yesno, ITEM(res_con.enable_ssl), 1, ITEM_DEFAULT, 0}, {"password", store_password, ITEM(res_con.password), 0, ITEM_REQUIRED, 0}, + {"jobacl", store_acl, ITEM(res_con.ACL_lists), Job_ACL, 0, 0}, + {"clientacl", store_acl, ITEM(res_con.ACL_lists), Client_ACL, 0, 0}, + {"storageacl", store_acl, ITEM(res_con.ACL_lists), Storage_ACL, 0, 0}, + {"scheduleacl", store_acl, ITEM(res_con.ACL_lists), Schedule_ACL, 0, 0}, + {"runacl", store_acl, ITEM(res_con.ACL_lists), Run_ACL, 0, 0}, + {"poolacl", store_acl, ITEM(res_con.ACL_lists), Pool_ACL, 0, 0}, + {"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}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -250,16 +260,6 @@ static struct res_items sch_items[] = { {NULL, NULL, NULL, 0, 0, 0} }; -/* Group resource -- not implemented - * - * name handler value code flags default_value - */ -static struct res_items group_items[] = { - {"name", store_name, ITEM(res_group.hdr.name), 0, ITEM_REQUIRED, 0}, - {"description", store_str, ITEM(res_group.hdr.desc), 0, 0, 0}, - {NULL, NULL, NULL, 0, 0, 0} -}; - /* Pool resource * * name handler value code flags default_value @@ -323,7 +323,6 @@ struct s_res resources[] = { {"catalog", cat_items, R_CATALOG, NULL}, {"schedule", sch_items, R_SCHEDULE, NULL}, {"fileset", fs_items, R_FILESET, NULL}, - {"group", group_items, R_GROUP, NULL}, {"pool", pool_items, R_POOL, NULL}, {"messages", msgs_items, R_MSGS, NULL}, {"counter", counter_items, R_COUNTER, NULL}, @@ -402,7 +401,7 @@ char *level_to_str(int level) static char level_no[30]; char *str = level_no; - sprintf(level_no, "%d", level); /* default if not found */ + bsnprintf(level_no, sizeof(level_no), "%d", level); /* default if not found */ for (i=0; joblevels[i].level_name; i++) { if (level == joblevels[i].level) { str = joblevels[i].level_name; @@ -567,7 +566,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... if (res->res_sch.run) { int i; RUN *run = res->res_sch.run; - char buf[1000], num[10]; + char buf[1000], num[30]; sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name); if (!run) { break; @@ -577,7 +576,7 @@ next_run: bstrncpy(buf, " hour=", sizeof(buf)); for (i=0; i<24; i++) { if (bit_is_set(i, run->hour)) { - sprintf(num, "%d ", i); + bsnprintf(num, sizeof(num), "%d ", i); bstrncat(buf, num, sizeof(buf)); } } @@ -586,7 +585,7 @@ next_run: bstrncpy(buf, " mday=", sizeof(buf)); for (i=0; i<31; i++) { if (bit_is_set(i, run->mday)) { - sprintf(num, "%d ", i); + bsnprintf(num, sizeof(num), "%d ", i); bstrncat(buf, num, sizeof(buf)); } } @@ -595,7 +594,7 @@ next_run: bstrncpy(buf, " month=", sizeof(buf)); for (i=0; i<12; i++) { if (bit_is_set(i, run->month)) { - sprintf(num, "%d ", i); + bsnprintf(num, sizeof(num), "%d ", i); bstrncat(buf, num, sizeof(buf)); } } @@ -604,7 +603,7 @@ next_run: bstrncpy(buf, " wday=", sizeof(buf)); for (i=0; i<7; i++) { if (bit_is_set(i, run->wday)) { - sprintf(num, "%d ", i); + bsnprintf(num, sizeof(num), "%d ", i); bstrncat(buf, num, sizeof(buf)); } } @@ -613,7 +612,7 @@ next_run: bstrncpy(buf, " wom=", sizeof(buf)); for (i=0; i<5; i++) { if (bit_is_set(i, run->wom)) { - sprintf(num, "%d ", i); + bsnprintf(num, sizeof(num), "%d ", i); bstrncat(buf, num, sizeof(buf)); } } @@ -622,7 +621,7 @@ next_run: bstrncpy(buf, " woy=", sizeof(buf)); for (i=0; i<54; i++) { if (bit_is_set(i, run->woy)) { - sprintf(num, "%d ", i); + bsnprintf(num, sizeof(num), "%d ", i); bstrncat(buf, num, sizeof(buf)); } } @@ -650,9 +649,6 @@ next_run: sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name); } break; - case R_GROUP: - sendit(sock, "Group: name=%s\n", res->res_group.hdr.name); - break; case R_POOL: sendit(sock, "Pool: name=%s PoolType=%s\n", res->res_pool.hdr.name, res->res_pool.pool_type); @@ -761,6 +757,12 @@ void free_resource(int type) if (res->res_con.password) { free(res->res_con.password); } + for (int i=0; ires_con.ACL_lists[i]) { + delete res->res_con.ACL_lists[i]; + res->res_con.ACL_lists[i] = NULL; + } + } break; case R_CLIENT: if (res->res_client.address) { @@ -876,8 +878,6 @@ void free_resource(int type) free_msgs_res((MSGS *)res); /* free message resource */ res = NULL; break; - case R_GROUP: - break; default: printf("Unknown resource type %d in free_resource.\n", type); } @@ -935,7 +935,6 @@ void save_resource(int type, struct res_items *items, int pass) case R_CONSOLE: case R_CATALOG: case R_STORAGE: - case R_GROUP: case R_POOL: case R_MSGS: case R_FILESET: @@ -1037,9 +1036,6 @@ void save_resource(int type, struct res_items *items, int pass) case R_SCHEDULE: size = sizeof(SCHED); break; - case R_GROUP: - size = sizeof(GROUP); - break; case R_POOL: size = sizeof(POOL); break; @@ -1150,6 +1146,34 @@ void store_replace(LEX *lc, struct res_items *item, int index, int pass) set_bit(index, res_all.hdr.item_present); } +/* + * Store ACL (access control list) + * + */ +void store_acl(LEX *lc, struct res_items *item, int index, int pass) +{ + int token; + + for (;;) { + token = lex_get_token(lc, T_NAME); + if (pass == 1) { + if (((alist **)item->value)[item->code] == NULL) { + ((alist **)item->value)[item->code] = new alist(10, owned_by_alist); +// Dmsg1(400, "Defined new ACL alist at %d\n", item->code); + } + ((alist **)item->value)[item->code]->append(bstrdup(lc->str)); +// Dmsg2(400, "Appended to %d %s\n", item->code, lc->str); + } + token = lex_get_token(lc, T_ALL); + if (token == T_COMMA) { + continue; /* get another ACL */ + } + break; + } + set_bit(index, res_all.hdr.item_present); +} + + #ifdef old_deprecated_code /* * Store backup/verify info for Job record diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index 604c879983..ee2f15847d 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -30,23 +30,23 @@ /* * Resource codes -- they must be sequential for indexing */ -#define R_FIRST 1001 - -#define R_DIRECTOR 1001 -#define R_CLIENT 1002 -#define R_JOB 1003 -#define R_STORAGE 1004 -#define R_CATALOG 1005 -#define R_SCHEDULE 1006 -#define R_FILESET 1007 -#define R_GROUP 1008 -#define R_POOL 1009 -#define R_MSGS 1010 -#define R_COUNTER 1011 -#define R_CONSOLE 1012 -#define R_JOBDEFS 1013 - -#define R_LAST R_JOBDEFS +enum { + R_DIRECTOR = 1001, + R_CLIENT, + R_JOB, + R_STORAGE, + R_CATALOG, + R_SCHEDULE, + R_FILESET, + R_POOL, + R_MSGS, + R_COUNTER, + R_CONSOLE, + R_JOBDEFS +}; + +#define R_FIRST R_DIRECTOR +#define R_LAST R_JOBDEFS /* * Some resource attributes @@ -106,6 +106,23 @@ struct DIRRES { utime_t SDConnectTimeout; /* timeout in seconds */ }; + +/* + * Console ACL positions + */ +enum { + Job_ACL = 0, + Client_ACL, + Storage_ACL, + Schedule_ACL, + Run_ACL, + Pool_ACL, + Command_ACL, + FileSet_ACL, + Catalog_ACL, + Num_ACL /* keep last */ +}; + /* * Console Resource */ @@ -113,6 +130,7 @@ struct CONRES { RES hdr; char *password; /* UA server password */ int enable_ssl; /* Use SSL */ + alist *ACL_lists[Num_ACL]; /* pointers to ACLs */ }; @@ -261,14 +279,6 @@ struct SCHED { RUN *run; }; -/* - * Group Resource (not used) - * - */ -struct GROUP { - RES hdr; -}; - /* * Counter Resource */ @@ -323,7 +333,6 @@ union URES { JOB res_job; FILESET res_fs; SCHED res_sch; - GROUP res_group; POOL res_pool; MSGS res_msgs; COUNTER res_counter; diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 2eed7fdbaf..87bc67d8e5 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -62,7 +62,7 @@ int variable_expansion(JCR *jcr, char *inp, POOLMEM **exp); /* fd_cmds.c */ extern int connect_to_file_daemon(JCR *jcr, int retry_interval, - int max_retry_time, int verbose); + int max_retry_time, int verbose); extern int send_include_list(JCR *jcr); extern int send_exclude_list(JCR *jcr); extern int send_bootstrap_file(JCR *jcr); @@ -70,7 +70,7 @@ extern int send_level_command(JCR *jcr); extern int get_attributes_and_put_in_catalog(JCR *jcr); extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId); extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname, - char *link, char *attr, int stream); + char *link, char *attr, int stream); extern void get_level_since_time(JCR *jcr, char *since, int since_len); extern int send_run_before_and_after_commands(JCR *jcr); @@ -94,7 +94,7 @@ extern void mount_request(JCR *jcr, BSOCK *bs, char *buf); /* msgchan.c */ extern int connect_to_storage_daemon(JCR *jcr, int retry_interval, - int max_retry_time, int verbose); + int max_retry_time, int verbose); extern int start_storage_daemon_job(JCR *jcr); extern int start_storage_daemon_message_thread(JCR *jcr); extern int bget_dirmsg(BSOCK *bs); @@ -108,6 +108,10 @@ void check_if_volume_valid_or_recyclable(JCR *jcr, MEDIA_DBR *mr, char **reason) /* newvol.c */ int newVolume(JCR *jcr, MEDIA_DBR *mr); +/* ua_acl.c */ +bool acl_access_ok(UAContext *ua, int acl, char *item); +bool acl_access_ok(UAContext *ua, int acl, char *item, int len); + /* ua_cmds.c */ int do_a_command(UAContext *ua, char *cmd); int do_a_dot_command(UAContext *ua, char *cmd); @@ -142,28 +146,28 @@ JCR *create_control_jcr(char *base_name, int job_type); void free_ua_context(UAContext *ua); /* ua_select.c */ -STORE *select_storage_resource(UAContext *ua); -JOB *select_job_resource(UAContext *ua); -JOB *select_restore_job_resource(UAContext *ua); -CLIENT *select_client_resource(UAContext *ua); +STORE *select_storage_resource(UAContext *ua); +JOB *select_job_resource(UAContext *ua); +JOB *select_restore_job_resource(UAContext *ua); +CLIENT *select_client_resource(UAContext *ua); FILESET *select_fileset_resource(UAContext *ua); -int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr); -int select_media_dbr(UAContext *ua, MEDIA_DBR *mr); -int select_pool_dbr(UAContext *ua, POOL_DBR *pr); -int select_client_dbr(UAContext *ua, CLIENT_DBR *cr); - -void start_prompt(UAContext *ua, char *msg); -void add_prompt(UAContext *ua, char *prompt); -int do_prompt(UAContext *ua, char *automsg, char *msg, char *prompt, int max_prompt); -CAT *get_catalog_resource(UAContext *ua); +int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr); +int select_media_dbr(UAContext *ua, MEDIA_DBR *mr); +int select_pool_dbr(UAContext *ua, POOL_DBR *pr); +int select_client_dbr(UAContext *ua, CLIENT_DBR *cr); + +void start_prompt(UAContext *ua, char *msg); +void add_prompt(UAContext *ua, char *prompt); +int do_prompt(UAContext *ua, char *automsg, char *msg, char *prompt, int max_prompt); +CAT *get_catalog_resource(UAContext *ua); STORE *get_storage_resource(UAContext *ua, int use_default); -int get_media_type(UAContext *ua, char *MediaType, int max_media); -int get_pool_dbr(UAContext *ua, POOL_DBR *pr); -int get_client_dbr(UAContext *ua, CLIENT_DBR *cr); +int get_media_type(UAContext *ua, char *MediaType, int max_media); +int get_pool_dbr(UAContext *ua, POOL_DBR *pr); +int get_client_dbr(UAContext *ua, CLIENT_DBR *cr); POOL *get_pool_resource(UAContext *ua); POOL *select_pool_resource(UAContext *ua); CLIENT *get_client_resource(UAContext *ua); -int get_job_dbr(UAContext *ua, JOB_DBR *jr); +int get_job_dbr(UAContext *ua, JOB_DBR *jr); int find_arg_keyword(UAContext *ua, char **list); int find_arg(UAContext *ua, char *keyword); diff --git a/bacula/src/dird/ua.h b/bacula/src/dird/ua.h index 3a3b49dedf..d2ded609b4 100644 --- a/bacula/src/dird/ua.h +++ b/bacula/src/dird/ua.h @@ -28,7 +28,6 @@ #ifndef __UA_H_ #define __UA_H_ 1 - struct UAContext { BSOCK *UA_sock; BSOCK *sd; @@ -62,5 +61,4 @@ struct TREE_CTX { UAContext *ua; }; - #endif diff --git a/bacula/src/dird/ua_acl.c b/bacula/src/dird/ua_acl.c new file mode 100644 index 0000000000..11a9053604 --- /dev/null +++ b/bacula/src/dird/ua_acl.c @@ -0,0 +1,59 @@ +/* + * + * Bacula Director -- User Agent Access Control List (ACL) handling + * + * Kern Sibbald, January MMIV + * + * Version $Id$ + */ + +/* + Copyright (C) 2004 Kern Sibbald and John Walker + + 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. + + 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. + + */ + +#include "bacula.h" +#include "dird.h" + +/* + * Check if access is permitted to item in acl + */ +bool acl_access_ok(UAContext *ua, int acl, char *item) +{ + return acl_access_ok(ua, acl, item, strlen(item)); +} + + +bool acl_access_ok(UAContext *ua, int acl, char *item, int len) +{ + if (!ua->cons) { + Dmsg0(400, "Root cons access OK.\n"); + return true; /* No cons resource -> root console OK for everything */ + } + alist *list = ua->cons->ACL_lists[acl]; + if (!list) { + return false; /* List empty, reject */ + } + for (int i=0; isize(); i++) { + if (strncasecmp(item, (char *)list->get(i), len) == 0) { + Dmsg3(400, "Found %s in %d %s\n", item, acl, (char *)list->get(i)); + return true; + } + } + return false; +} diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index c71a1341b4..b5ac957074 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -129,12 +129,11 @@ int do_a_command(UAContext *ua, char *cmd) { unsigned int i; int len, stat; - int found; + bool found = false; - found = 0; stat = 1; - Dmsg1(120, "Command: %s\n", ua->UA_sock->msg); + Dmsg1(200, "Command: %s\n", ua->UA_sock->msg); if (ua->argc == 0) { return 1; } @@ -142,15 +141,16 @@ int do_a_command(UAContext *ua, char *cmd) len = strlen(ua->argk[0]); for (i=0; iargk[0], _(commands[i].key), len) == 0) { + if (!acl_access_ok(ua, Command_ACL, ua->argk[0], len)) { + break; + } stat = (*commands[i].func)(ua, cmd); /* go execute command */ - found = 1; + found = true; break; } } if (!found) { - pm_strcat(&ua->UA_sock->msg, _(": is an illegal command\n")); - ua->UA_sock->msglen = strlen(ua->UA_sock->msg); - bnet_send(ua->UA_sock); + bnet_fsend(ua->UA_sock, _("%s: is an illegal command.\n"), ua->argk[0]); } return stat; } diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 9725a6e47d..d20a42fdc4 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -82,7 +82,6 @@ static struct showstruct reses[] = { {N_("catalogs"), R_CATALOG}, {N_("schedules"), R_SCHEDULE}, {N_("filesets"), R_FILESET}, - {N_("groups"), R_GROUP}, {N_("pools"), R_POOL}, {N_("messages"), R_MSGS}, {N_("all"), -1}, diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index 1572bfa341..c667a8f7d0 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -149,7 +149,9 @@ STORE *select_storage_resource(UAContext *ua) start_prompt(ua, _("The defined Storage resources are:\n")); LockRes(); foreach_res(store, R_STORAGE) { - add_prompt(ua, store->hdr.name); + if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) { + add_prompt(ua, store->hdr.name); + } } UnlockRes(); do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)); @@ -168,7 +170,9 @@ FILESET *select_fileset_resource(UAContext *ua) start_prompt(ua, _("The defined FileSet resources are:\n")); LockRes(); foreach_res(fs, R_FILESET) { - add_prompt(ua, fs->hdr.name); + if (acl_access_ok(ua, FileSet_ACL, fs->hdr.name)) { + add_prompt(ua, fs->hdr.name); + } } UnlockRes(); do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)); @@ -188,15 +192,19 @@ CAT *get_catalog_resource(UAContext *ua) for (i=1; iargc; i++) { if (strcasecmp(ua->argk[i], _("catalog")) == 0 && ua->argv[i]) { - catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]); - break; + if (acl_access_ok(ua, Catalog_ACL, ua->argv[i])) { + catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]); + break; + } } } if (!catalog) { start_prompt(ua, _("The defined Catalog resources are:\n")); LockRes(); foreach_res(catalog, R_CATALOG) { - add_prompt(ua, catalog->hdr.name); + if (acl_access_ok(ua, Catalog_ACL, catalog->hdr.name)) { + add_prompt(ua, catalog->hdr.name); + } } UnlockRes(); do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)); @@ -217,7 +225,9 @@ JOB *select_job_resource(UAContext *ua) start_prompt(ua, _("The defined Job resources are:\n")); LockRes(); foreach_res(job, R_JOB) { - add_prompt(ua, job->hdr.name); + if (acl_access_ok(ua, Job_ACL, job->hdr.name)) { + add_prompt(ua, job->hdr.name); + } } UnlockRes(); do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)); @@ -236,7 +246,7 @@ JOB *select_restore_job_resource(UAContext *ua) start_prompt(ua, _("The defined Restore Job resources are:\n")); LockRes(); foreach_res(job, R_JOB) { - if (job->JobType == JT_RESTORE) { + if (job->JobType == JT_RESTORE && acl_access_ok(ua, Job_ACL, job->hdr.name)) { add_prompt(ua, job->hdr.name); } } @@ -259,7 +269,9 @@ CLIENT *select_client_resource(UAContext *ua) start_prompt(ua, _("The defined Client resources are:\n")); LockRes(); foreach_res(client, R_CLIENT) { - add_prompt(ua, client->hdr.name); + if (acl_access_ok(ua, Client_ACL, client->hdr.name)) { + add_prompt(ua, client->hdr.name); + } } UnlockRes(); do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)); @@ -280,6 +292,9 @@ CLIENT *get_client_resource(UAContext *ua) for (i=1; iargc; i++) { if ((strcasecmp(ua->argk[i], _("client")) == 0 || strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) { + if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) { + break; + } client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); if (client) { return client; @@ -314,6 +329,9 @@ int get_client_dbr(UAContext *ua, CLIENT_DBR *cr) for (i=1; iargc; i++) { if ((strcasecmp(ua->argk[i], _("client")) == 0 || strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) { + if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) { + break; + } bstrncpy(cr->Name, ua->argv[i], sizeof(cr->Name)); if (!db_get_client_record(ua->jcr, ua->db, cr)) { bsendmsg(ua, _("Could not find Client \"%s\": ERR=%s"), ua->argv[i], @@ -356,7 +374,8 @@ int select_client_dbr(UAContext *ua, CLIENT_DBR *cr) start_prompt(ua, _("Defined Clients:\n")); for (i=0; i < num_clients; i++) { ocr.ClientId = ids[i]; - if (!db_get_client_record(ua->jcr, ua->db, &ocr)) { + if (!db_get_client_record(ua->jcr, ua->db, &ocr) || + !acl_access_ok(ua, Client_ACL, ocr.Name)) { continue; } add_prompt(ua, ocr.Name); @@ -391,7 +410,8 @@ int select_client_dbr(UAContext *ua, CLIENT_DBR *cr) int get_pool_dbr(UAContext *ua, POOL_DBR *pr) { if (pr->Name[0]) { /* If name already supplied */ - if (db_get_pool_record(ua->jcr, ua->db, pr)) { + if (db_get_pool_record(ua->jcr, ua->db, pr) && + acl_access_ok(ua, Pool_ACL, pr->Name)) { return pr->PoolId; } bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), pr->Name, db_strerror(ua->db)); @@ -413,7 +433,8 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr) uint32_t *ids; for (i=1; iargc; i++) { - if (strcasecmp(ua->argk[i], _("pool")) == 0 && ua->argv[i]) { + if (strcasecmp(ua->argk[i], _("pool")) == 0 && ua->argv[i] && + acl_access_ok(ua, Pool_ACL, ua->argv[i])) { bstrncpy(pr->Name, ua->argv[i], sizeof(pr->Name)); if (!db_get_pool_record(ua->jcr, ua->db, pr)) { bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), ua->argv[i], @@ -438,7 +459,8 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr) start_prompt(ua, _("Defined Pools:\n")); for (i=0; i < num_pools; i++) { opr.PoolId = ids[i]; - if (!db_get_pool_record(ua->jcr, ua->db, &opr)) { + if (!db_get_pool_record(ua->jcr, ua->db, &opr) || + !acl_access_ok(ua, Pool_ACL, opr.Name)) { continue; } add_prompt(ua, opr.Name); @@ -525,7 +547,9 @@ POOL *select_pool_resource(UAContext *ua) start_prompt(ua, _("The defined Pool resources are:\n")); LockRes(); foreach_res(pool, R_POOL) { - add_prompt(ua, pool->hdr.name); + if (acl_access_ok(ua, Pool_ACL, pool->hdr.name)) { + add_prompt(ua, pool->hdr.name); + } } UnlockRes(); do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)); @@ -545,7 +569,7 @@ POOL *get_pool_resource(UAContext *ua) int i; i = find_arg_with_value(ua, "pool"); - if (i >= 0) { + if (i >= 0 && acl_access_ok(ua, Pool_ACL, ua->argv[i])) { pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]); if (pool) { return pool; @@ -593,7 +617,7 @@ int get_job_dbr(UAContext *ua, JOB_DBR *jr) jr->JobId = 0; bstrncpy(jr->Job, ua->argv[i], sizeof(jr->Job)); } else if (strcasecmp(ua->argk[i], _("jobid")) == 0 && ua->argv[i]) { - jr->JobId = atoi(ua->argv[i]); + jr->JobId = str_to_int64(ua->argv[i]); } else { continue; } @@ -760,7 +784,7 @@ STORE *get_storage_resource(UAContext *ua, int use_default) break; } else if (strcasecmp(ua->argk[i], _("jobid")) == 0) { - jobid = atoi(ua->argv[i]); + jobid = str_to_int64(ua->argv[i]); if (jobid <= 0) { bsendmsg(ua, _("Expecting jobid=nn command, got: %s\n"), ua->argk[i]); return NULL; @@ -784,13 +808,19 @@ STORE *get_storage_resource(UAContext *ua, int use_default) } } } - + if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) { + store = NULL; + } + if (!store && store_name) { store = (STORE *)GetResWithName(R_STORAGE, store_name); if (!store) { bsendmsg(ua, "Storage resource \"%s\": not found\n", store_name); } } + if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) { + store = NULL; + } /* No keywords found, so present a selection list */ if (!store) { store = select_storage_resource(ua); diff --git a/bacula/src/gnome2-console/authenticate.c b/bacula/src/gnome2-console/authenticate.c index 0aa3f7d365..aa0e440b5c 100644 --- a/bacula/src/gnome2-console/authenticate.c +++ b/bacula/src/gnome2-console/authenticate.c @@ -45,21 +45,28 @@ static char OKhello[] = "1000 OK:"; /* * Authenticate Director */ -int authenticate_director(JCR *jcr, DIRRES *director, char *name) +int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) { BSOCK *dir = jcr->dir_bsock; int ssl_need = BNET_SSL_NONE; char bashed_name[MAX_NAME_LENGTH]; + char *password; /* * Send my name to the Director then do authentication */ - bstrncpy(bashed_name, name, sizeof(bashed_name)); - bash_spaces(bashed_name); + if (cons) { + bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name)); + bash_spaces(bashed_name); + password = cons->password; + } else { + bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name)); + password = director->password; + } bnet_fsend(dir, hello, bashed_name); - if (!cram_md5_get_auth(dir, director->password, ssl_need) || - !cram_md5_auth(dir, director->password, ssl_need)) { + if (!cram_md5_get_auth(dir, password, ssl_need) || + !cram_md5_auth(dir, password, ssl_need)) { printf(_("%s: Director authorization problem.\n"), my_name); set_text(_("Director authorization problem.\n"), -1); return 0; diff --git a/bacula/src/gnome2-console/console.c b/bacula/src/gnome2-console/console.c index b7e76655fa..b0b9b2b9f6 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, char *name); +int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons); /* Exported variables */ GtkWidget *app1; /* application window */ @@ -172,7 +172,7 @@ int main(int argc, char *argv[]) LockRes(); ndir = 0; - for (dir=NULL; (dir = (DIRRES *)GetNextRes(R_DIRECTOR, (RES *)dir)); ) { + foreach_res(dir, R_DIRECTOR) { ndir++; } UnlockRes(); @@ -181,10 +181,6 @@ int main(int argc, char *argv[]) Without that I don't how to speak to the Director :-(\n"), configfile); } - if (test_config) { - terminate_console(0); - exit(0); - } app1 = create_app1(); @@ -212,13 +208,17 @@ Without that I don't how to speak to the Director :-(\n"), configfile); */ LockRes(); - for (con = NULL; (con = (CONRES *)GetNextRes(R_CONSOLE, (RES *)con)); ) { + foreach_res(con, R_CONSOLE) { + if (!con->fontface) { + Dmsg1(400, "No fontface for %s\n", con->hdr.name); + continue; + } text_font = gdk_font_load(con->fontface); if (text_font == NULL) { - Dmsg2(404, "Load of requested ConsoleFont \"%s\" (%s) failed!\n", + Dmsg2(400, "Load of requested ConsoleFont \"%s\" (%s) failed!\n", con->hdr.name, con->fontface); } else { - Dmsg2(404, "ConsoleFont \"%s\" (%s) loaded.\n", + Dmsg2(400, "ConsoleFont \"%s\" (%s) loaded.\n", con->hdr.name, con->fontface); break; } @@ -226,7 +226,7 @@ Without that I don't how to speak to the Director :-(\n"), configfile); UnlockRes(); if (text_font == NULL) { - Dmsg1(100, "Attempting to load fallback font %s\n", + Dmsg1(400, "Attempting to load fallback font %s\n", "-misc-fixed-medium-r-normal-*-*-130-*-*-c-*-iso8859-1"); text_font = gdk_font_load("-misc-fixed-medium-r-normal-*-*-130-*-*-c-*-iso8859-1"); } @@ -237,6 +237,11 @@ 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); + if (test_config) { + terminate_console(0); + exit(0); + } + initial = gtk_timeout_add(100, initial_connect_to_director, (gpointer)NULL); gtk_main(); @@ -401,13 +406,7 @@ int connect_to_director(gpointer data) 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)) { + if (!authenticate_director(&jcr, dir, cons)) { 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 7b5b1fbdd6..813e353ab5 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 * @@ -71,7 +71,7 @@ static struct res_items dir_items[] = { {"description", store_str, ITEM(res_dir.hdr.desc), 0, 0, 0}, {"dirport", store_int, ITEM(res_dir.DIRport), 0, ITEM_DEFAULT, 9101}, {"address", store_str, ITEM(res_dir.address), 0, ITEM_REQUIRED, 0}, - {"password", store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0}, + {"password", store_password, ITEM(res_dir.password), 0, 0, 0}, {"enablessl", store_yesno, ITEM(res_dir.enable_ssl), 1, ITEM_DEFAULT, 0}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -79,7 +79,8 @@ static struct res_items dir_items[] = { static struct res_items con_items[] = { {"name", store_name, ITEM(con_dir.hdr.name), 0, ITEM_REQUIRED, 0}, {"description", store_str, ITEM(con_dir.hdr.desc), 0, 0, 0}, - {"font", store_str, ITEM(con_dir.fontface), 0, ITEM_REQUIRED, 0}, + {"font", store_str, ITEM(con_dir.fontface), 0, 0, 0}, + {"password", store_password, ITEM(con_dir.password), 0, ITEM_REQUIRED, 0}, {"requiressl", store_yesno, ITEM(con_dir.require_ssl), 1, ITEM_DEFAULT, 0}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -90,8 +91,8 @@ 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} + {"console", con_items, R_CONSOLE, NULL}, + {NULL, NULL, 0, NULL} }; @@ -105,18 +106,18 @@ 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); + 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)); + reshdr->name, NPRT(res->con_dir.fontface)); break; default: printf("Unknown resource type %d\n", type); @@ -156,12 +157,12 @@ void free_resource(int type) switch (type) { case R_DIRECTOR: if (res->res_dir.address) { - free(res->res_dir.address); + free(res->res_dir.address); } break; case R_CONSOLE: if (res->con_dir.fontface) { - free(res->con_dir.fontface); + free(res->con_dir.fontface); } break; default: @@ -191,10 +192,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]); + } } } @@ -207,26 +208,26 @@ void save_resource(int type, struct res_items *items, int pass) switch (type) { /* Resources not containing a resource */ case R_DIRECTOR: - break; + break; case R_CONSOLE: - break; + break; default: Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type); - error = 1; - break; + 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; } @@ -249,20 +250,20 @@ void save_resource(int type, struct res_items *items, int pass) 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); } } } diff --git a/bacula/src/gnome2-console/console_conf.h b/bacula/src/gnome2-console/console_conf.h index b63d20ccc8..c9dde14855 100644 --- a/bacula/src/gnome2-console/console_conf.h +++ b/bacula/src/gnome2-console/console_conf.h @@ -12,12 +12,14 @@ /* * Resource codes -- they must be sequential for indexing */ -#define R_FIRST 1001 -#define R_DIRECTOR 1001 -#define R_CONSOLE 1002 +enum { + R_DIRECTOR = 1001, + R_CONSOLE, +}; -#define R_LAST R_CONSOLE +#define R_FIRST R_DIRECTOR +#define R_LAST R_CONSOLE /* * Some resource attributes @@ -42,6 +44,7 @@ typedef struct s_res_dir DIRRES; struct s_con_dir { RES hdr; char *fontface; /* Console Font specification */ + char *password; /* UA server password */ int require_ssl; /* Require SSL on all connections */ }; typedef struct s_con_dir CONRES; diff --git a/bacula/src/lib/alist.h b/bacula/src/lib/alist.h index 8b6755405b..bcce8abe9a 100644 --- a/bacula/src/lib/alist.h +++ b/bacula/src/lib/alist.h @@ -24,6 +24,13 @@ */ +/* Second arg of init */ +enum { + owned_by_alist = true, + not_owned_by_alist = false +}; + + /* * Array list -- much like a simplified STL vector * array of pointers to inserted items diff --git a/bacula/src/lib/lex.c b/bacula/src/lib/lex.c index 3b2a25bac3..b2a99ea1c2 100644 --- a/bacula/src/lib/lex.c +++ b/bacula/src/lib/lex.c @@ -57,12 +57,13 @@ static void s_err(char *file, int line, LEX *lc, char *msg, ...) va_end(arg_ptr); if (lc->line_no > lc->begin_line_no) { - sprintf(more, _("Problem probably begins at Line %d.\n"), lc->begin_line_no); + bsnprintf(more, sizeof(more), + _("Problem probably begins at line %d.\n"), lc->begin_line_no); } else { more[0] = 0; } e_msg(file, line, M_ERROR_TERM, 0, _("Config error: %s\n\ - : Line %d, col %d of file %s\n%s\n%s"), + : line %d, col %d of file %s\n%s\n%s"), buf, lc->line_no, lc->col_no, lc->fname, lc->line, more); } @@ -189,7 +190,7 @@ static void add_str(LEX *lf, int ch) { if (lf->str_len >= MAXSTRING-3) { Emsg3(M_ERROR_TERM, 0, _( - "Token too long, file: %s, line %d, begins at line %d\n"), + _("Config token too long, file: %s, line %d, begins at line %d\n")), lf->fname, lf->line_no, lf->begin_line_no); } lf->str[lf->str_len++] = ch; @@ -253,19 +254,19 @@ char *lex_tok_to_str(int token) static uint32_t scan_pint(LEX *lf, char *str) { - double dval = 0; + int64_t val = 0; if (!is_a_number(str)) { scan_err1(lf, "expected a positive integer number, got: %s", str); /* NOT REACHED */ } else { errno = 0; - dval = strtod(str, NULL); - if (errno != 0 || dval < 0) { + val = str_to_int64(str); + if (errno != 0 || val < 0) { scan_err1(lf, "expected a postive integer number, got: %s", str); /* NOT REACHED */ } } - return (uint32_t)dval; + return (uint32_t)val; } /* @@ -508,7 +509,7 @@ lex_get_token(LEX *lf, int expect) break; } errno = 0; - lf->int32_val = (int32_t)strtod(lf->str, NULL); + lf->int32_val = (int32_t)str_to_int64(lf->str); if (errno != 0) { scan_err2(lf, "expected an integer number, got %s: %s", lex_tok_to_str(token), lf->str); @@ -527,7 +528,7 @@ lex_get_token(LEX *lf, int expect) break; } errno = 0; - lf->int64_val = (int64_t)strtod(lf->str, NULL); + lf->int64_val = str_to_int64(lf->str); if (errno != 0) { scan_err2(lf, "expected an integer number, got %s: %s", lex_tok_to_str(token), lf->str); diff --git a/bacula/src/lib/parse_conf.c b/bacula/src/lib/parse_conf.c index aa908f9b8a..692ec0d219 100755 --- a/bacula/src/lib/parse_conf.c +++ b/bacula/src/lib/parse_conf.c @@ -214,10 +214,10 @@ void store_msgs(LEX *lc, struct res_items *item, int index, int pass) token = lex_get_token(lc, T_NAME); /* scan destination */ dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2); if (dest[0] != 0) { - strcat(dest, " "); /* separate multiple destinations with space */ + pm_strcat(&dest, " "); /* separate multiple destinations with space */ dest_len++; } - strcat(dest, lc->str); + pm_strcat(&dest, lc->str); dest_len += lc->str_len; Dmsg2(100, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest)); token = lex_get_token(lc, T_ALL); -- 2.39.5