diff --git a/src/console/console_conf.c b/src/console/console_conf.c index a99defa7969..7a3ff3049c5 100644 --- a/src/console/console_conf.c +++ b/src/console/console_conf.c @@ -120,8 +120,12 @@ static RES_TABLE resources[] = { { NULL, NULL, 0 } }; -/* Dump contents of resource */ -void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock) +/* + * Dump contents of resource + */ +void dump_resource(int type, RES *reshdr, + void sendit(void *sock, const char *fmt, ...), + void *sock, bool hide_sensitive_data) { POOL_MEM buf; URES *res = (URES *)reshdr; @@ -146,7 +150,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm sendit(sock, "%s", buf.c_str()); if (recurse && res->res_dir.hdr.next) { - dump_resource(type, res->res_dir.hdr.next, sendit, sock); + dump_resource(type, res->res_dir.hdr.next, sendit, sock, hide_sensitive_data); } } diff --git a/src/dird/Makefile.in b/src/dird/Makefile.in index 379a093eaf2..226c59f97fd 100644 --- a/src/dird/Makefile.in +++ b/src/dird/Makefile.in @@ -33,9 +33,10 @@ SVRSRCS = admin.c authenticate.c autoprune.c backup.c bsr.c catreq.c \ inc_conf.c job.c jobq.c migrate.c mountreq.c msgchan.c ndmp_dma.c \ newvol.c next_vol.c quota.c socket_server.c recycle.c restore.c \ run_conf.c sd_cmds.c scheduler.c stats.c ua_acl.c ua_audit.c \ - ua_cmds.c ua_dotcmds.c ua_input.c ua_impexp.c ua_label.c ua_output.c \ - ua_prune.c ua_purge.c ua_query.c ua_restore.c ua_run.c ua_select.c \ - ua_server.c ua_status.c ua_tree.c ua_update.c vbackup.c verify.c + ua_cmds.c ua_configure.c ua_dotcmds.c ua_input.c ua_impexp.c \ + ua_label.c ua_output.c ua_prune.c ua_purge.c ua_query.c ua_restore.c \ + ua_run.c ua_select.c ua_server.c ua_status.c ua_tree.c ua_update.c \ + vbackup.c verify.c SVROBJS = $(SVRSRCS:.c=.o) DBCHKSRCS = dbcheck.c dird_conf.c ua_acl.c ua_audit.c run_conf.c inc_conf.c diff --git a/src/dird/dird_conf.c b/src/dird/dird_conf.c index ffa36baeef2..a7ee901e71e 100644 --- a/src/dird/dird_conf.c +++ b/src/dird/dird_conf.c @@ -1375,7 +1375,7 @@ static inline void print_config_run(RES_ITEM *item, POOL_MEM &cfg_str) } } -bool FILESETRES::print_config(POOL_MEM &buff) +bool FILESETRES::print_config(POOL_MEM &buff, bool hide_sensitive_data) { POOL_MEM cfg_str; POOL_MEM temp; @@ -1779,7 +1779,9 @@ const char *level_to_str(int level) /* * Dump contents of resource */ -void dump_resource(int type, RES *ures, void sendit(void *sock, const char *fmt, ...), void *sock) +void dump_resource(int type, RES *ures, + void sendit(void *sock, const char *fmt, ...), + void *sock, bool hide_sensitive_data) { URES *res = (URES *)ures; bool recurse = true; @@ -1798,71 +1800,71 @@ void dump_resource(int type, RES *ures, void sendit(void *sock, const char *fmt, switch (type) { case R_DIRECTOR: - res->res_dir.print_config(buf); + res->res_dir.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; case R_PROFILE: - res->res_profile.print_config(buf); + res->res_profile.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; case R_CONSOLE: - res->res_con.print_config(buf); + res->res_con.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; case R_COUNTER: - res->res_counter.print_config(buf); + res->res_counter.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; case R_CLIENT: if (!ua || acl_access_ok(ua, Client_ACL, res->res_client.hdr.name)) { - res->res_client.print_config(buf); + res->res_client.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_DEVICE: - res->res_dev.print_config(buf); + res->res_dev.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; case R_STORAGE: if (!ua || acl_access_ok(ua, Storage_ACL, res->res_store.hdr.name)) { - res->res_store.print_config(buf); + res->res_store.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_CATALOG: if (!ua || acl_access_ok(ua, Catalog_ACL, res->res_cat.hdr.name)) { - res->res_cat.print_config(buf); + res->res_cat.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_JOBDEFS: case R_JOB: if (!ua || acl_access_ok(ua, Job_ACL, res->res_job.hdr.name)) { - res->res_job.print_config(buf); + res->res_job.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_FILESET: { if (!ua || acl_access_ok(ua, FileSet_ACL, res->res_fs.hdr.name)) { - res->res_fs.print_config(buf); + res->res_fs.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; } case R_SCHEDULE: if (!ua || acl_access_ok(ua, Schedule_ACL, res->res_sch.hdr.name)) { - res->res_sch.print_config(buf); + res->res_sch.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_POOL: if (!ua || acl_access_ok(ua, Pool_ACL, res->res_pool.hdr.name)) { - res->res_pool.print_config(buf); + res->res_pool.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_MSGS: - res->res_msgs.print_config(buf); + res->res_msgs.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; default: @@ -1871,7 +1873,7 @@ void dump_resource(int type, RES *ures, void sendit(void *sock, const char *fmt, } if (recurse && res->res_dir.hdr.next) { - dump_resource(type, res->res_dir.hdr.next, sendit, sock); + dump_resource(type, res->res_dir.hdr.next, sendit, sock, hide_sensitive_data); } } @@ -3592,7 +3594,7 @@ static void parse_config_cb(LEX *lc, RES_ITEM *item, int index, int pass) * callback function for print_config * See ../lib/res.c, function BRSRES::print_config, for more generic handling. */ -static void print_config_cb(RES_ITEM *items, int i, POOL_MEM &cfg_str) +static void print_config_cb(RES_ITEM *items, int i, POOL_MEM &cfg_str, bool hide_sensitive_data) { POOL_MEM temp; diff --git a/src/dird/dird_conf.h b/src/dird/dird_conf.h index 08cc05e54e8..a6361ab5fc2 100644 --- a/src/dird/dird_conf.h +++ b/src/dird/dird_conf.h @@ -97,7 +97,6 @@ bool print_config_schema_json(POOL_MEM &buff); /* * Director Resource - * */ class DIRRES: public BRSRES { public: @@ -518,7 +517,7 @@ class FILESETRES : public BRSRES { bool enable_vss; /* Enable Volume Shadow Copy */ /* Methods */ - bool print_config(POOL_MEM& buff); + bool print_config(POOL_MEM& buff, bool hide_sensitive_data); }; /* diff --git a/src/dird/ua_cmds.c b/src/dird/ua_cmds.c index 1532f4a6ffe..d6f0c84957b 100644 --- a/src/dird/ua_cmds.c +++ b/src/dird/ua_cmds.c @@ -36,6 +36,7 @@ extern jobq_t job_queue; /* job queue */ /* Imported functions */ extern int autodisplay_cmd(UAContext *ua, const char *cmd); +extern int configure_cmd(UAContext *ua, const char *cmd); extern int gui_cmd(UAContext *ua, const char *cmd); extern int label_cmd(UAContext *ua, const char *cmd); extern int list_cmd(UAContext *ua, const char *cmd); @@ -108,6 +109,8 @@ static struct cmdstruct commands[] = { NT_("on | off"), false, true }, { NT_("cancel"), cancel_cmd, _("Cancel a job"), NT_("storage= | jobid= | job= | ujobid= | state= | all yes"), false, true }, + { NT_("configure"), configure_cmd, _("Configure director"), + NT_("terminal"), false, true }, { NT_("create"), create_cmd, _("Create DB Pool from resource"), NT_("pool="), false, true }, { NT_("delete"), delete_cmd, _("Delete volume, pool or job"), diff --git a/src/dird/ua_configure.c b/src/dird/ua_configure.c new file mode 100644 index 00000000000..06c4e2a43b0 --- /dev/null +++ b/src/dird/ua_configure.c @@ -0,0 +1,36 @@ +/* + BAREOSĀ® - Backup Archiving REcovery Open Sourced + + Copyright (C) 2015-2015 Bareos GmbH & Co. KG + + This program is Free Software; you can redistribute it and/or + modify it under the terms of version three of the GNU Affero General Public + License as published by the Free Software Foundation and included + in the file LICENSE. + + 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ +/* + * BAREOS Director -- Interactive configuration engine for director. + * + * Written by Marco van Wieringen, January 2015 + */ + +#include "bareos.h" +#include "dird.h" + +/* Forward referenced functions */ + +int configure_cmd(UAContext *ua, const char *cmd) +{ + ua->send_msg("Interactive configuration not implemented\n"); + return 1; +} diff --git a/src/dird/ua_output.c b/src/dird/ua_output.c index 40adc47bd17..d73ec7c2206 100644 --- a/src/dird/ua_output.c +++ b/src/dird/ua_output.c @@ -215,9 +215,16 @@ int show_cmd(UAContext *ua, const char *cmd) int recurse; char *res_name; RES *res = NULL; + bool hide_sensitive_data; Dmsg1(20, "show: %s\n", ua->UA_sock->msg); + /* + * When the console has no access to the configure cmd then any show cmd + * will suppress all sensitive information like for instance passwords. + */ + hide_sensitive_data = !acl_access_ok(ua, Command_ACL, "configure", false); + LockRes(); for (i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], _("disabled"))) { @@ -284,7 +291,7 @@ int show_cmd(UAContext *ua, const char *cmd) continue; default: if (my_config->m_res_head[j - my_config->m_r_first]) { - dump_resource(j, my_config->m_res_head[j - my_config->m_r_first], bsendmsg, ua); + dump_resource(j, my_config->m_res_head[j - my_config->m_r_first], bsendmsg, ua, hide_sensitive_data); } break; } @@ -292,7 +299,7 @@ int show_cmd(UAContext *ua, const char *cmd) break; case -2: ua->send_msg(_("Keywords for the show command are:\n")); - for (j=0; avail_resources[j].res_name; j++) { + for (j = 0; avail_resources[j].res_name; j++) { ua->error_msg("%s\n", _(avail_resources[j].res_name)); } goto bail_out; @@ -303,7 +310,7 @@ int show_cmd(UAContext *ua, const char *cmd) ua->error_msg(_("Resource %s not found\n"), res_name); goto bail_out; default: - dump_resource(recurse ? type : -type, res, bsendmsg, ua); + dump_resource(recurse ? type : -type, res, bsendmsg, ua, hide_sensitive_data); break; } } diff --git a/src/filed/filed_conf.c b/src/filed/filed_conf.c index 0411b4583c3..6686c91ff45 100644 --- a/src/filed/filed_conf.c +++ b/src/filed/filed_conf.c @@ -167,7 +167,9 @@ static RES_TABLE resources[] = { /* * Dump contents of resource */ -void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock) +void dump_resource(int type, RES *reshdr, + void sendit(void *sock, const char *fmt, ...), + void *sock, bool hide_sensitive_data) { POOL_MEM buf; URES *res = (URES *)reshdr; @@ -198,7 +200,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm sendit(sock, "%s", buf.c_str()); if (recurse && res->res_dir.hdr.next) { - dump_resource(type, res->res_dir.hdr.next, sendit, sock); + dump_resource(type, res->res_dir.hdr.next, sendit, sock, hide_sensitive_data); } } diff --git a/src/lib/parse_conf.c b/src/lib/parse_conf.c index 7aa2b46ff85..c39edc31a6c 100644 --- a/src/lib/parse_conf.c +++ b/src/lib/parse_conf.c @@ -58,8 +58,6 @@ #define MAX_PATH 1024 #endif -extern void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock); - /* * Define the Union of all the common resource structure definitions. */ @@ -316,7 +314,7 @@ bool CONFIG::parse_config() if (debug_level >= 900 && pass == 2) { int i; for (i = m_r_first; i <= m_r_last; i++) { - dump_resource(i, m_res_head[i-m_r_first], prtmsg, NULL); + dump_resource(i, m_res_head[i-m_r_first], prtmsg, NULL, false); } } lc = lex_close_file(lc); @@ -654,11 +652,12 @@ void CONFIG::init_resource(int type, RES_ITEM *items, int pass) } } -void CONFIG::dump_resources(void sendit(void *sock, const char *fmt, ...), void *sock) +void CONFIG::dump_resources(void sendit(void *sock, const char *fmt, ...), + void *sock, bool hide_sensitive_data) { for (int i = m_r_first; i <= m_r_last; i++) { if (m_res_head[i - m_r_first]) { - ::dump_resource(i,m_res_head[i - m_r_first],sendit,sock); + dump_resource(i,m_res_head[i - m_r_first],sendit, sock, hide_sensitive_data); } } } diff --git a/src/lib/parse_conf.h b/src/lib/parse_conf.h index 726273332ec..db02eeacf37 100644 --- a/src/lib/parse_conf.h +++ b/src/lib/parse_conf.h @@ -264,7 +264,7 @@ class BRSRES { /* Methods */ char *name() const; - bool print_config(POOL_MEM &buf); + bool print_config(POOL_MEM &buf, bool hide_sensitive_data = false); }; inline char *BRSRES::name() const { return this->hdr.name; } @@ -300,12 +300,12 @@ class MSGSRES : public BRSRES { void wait_not_in_use(); /* in message.c */ void lock(); /* in message.c */ void unlock(); /* in message.c */ - bool print_config(POOL_MEM& buff); + bool print_config(POOL_MEM &buff, bool hide_sensitive_data = false); }; typedef void (INIT_RES_HANDLER)(RES_ITEM *item, int pass); typedef void (STORE_RES_HANDLER)(LEX *lc, RES_ITEM *item, int index, int pass); -typedef void (PRINT_RES_HANDLER)(RES_ITEM *items, int i, POOL_MEM &cfg_str); +typedef void (PRINT_RES_HANDLER)(RES_ITEM *items, int i, POOL_MEM &cfg_str, bool hide_sensitive_data); /* * New C++ configuration routines @@ -356,7 +356,8 @@ class CONFIG { RES **save_resources(); RES **new_res_head(); void init_resource(int type, RES_ITEM *items, int pass); - void dump_resources(void sendit(void *sock, const char *fmt, ...), void *sock); + void dump_resources(void sendit(void *sock, const char *fmt, ...), + void *sock, bool hide_sensitive_data = false); }; CONFIG *new_config_parser(); @@ -377,7 +378,8 @@ RES *GetResWithName(int rcode, const char *name); RES *GetNextRes(int rcode, RES *res); void b_LockRes(const char *file, int line); void b_UnlockRes(const char *file, int line); -void dump_resource(int type, RES *res, void sendmsg(void *sock, const char *fmt, ...), void *sock); +void dump_resource(int type, RES *res, void sendmsg(void *sock, const char *fmt, ...), + void *sock, bool hide_sensitive_data = false); void free_resource(RES *res, int type); void init_resource(int type, RES_ITEM *item); void save_resource(int type, RES_ITEM *item, int pass); diff --git a/src/lib/res.c b/src/lib/res.c index 5a6732a600a..65373206056 100644 --- a/src/lib/res.c +++ b/src/lib/res.c @@ -1380,7 +1380,7 @@ static inline void print_config_time(RES_ITEM *item, POOL_MEM &cfg_str) indent_config_item(cfg_str, 1, temp.c_str()); } -bool MSGSRES::print_config(POOL_MEM &buff) +bool MSGSRES::print_config(POOL_MEM &buff, bool hide_sensitive_data) { int len; POOLMEM *cmdbuf; @@ -1458,7 +1458,7 @@ bool MSGSRES::print_config(POOL_MEM &buff) return true; } -bool BRSRES::print_config(POOL_MEM &buff) +bool BRSRES::print_config(POOL_MEM &buff, bool hide_sensitive_data) { POOL_MEM cfg_str; POOL_MEM temp; @@ -1621,17 +1621,22 @@ bool BRSRES::print_config(POOL_MEM &buff) password = items[i].pwdvalue; if (password && password->value != NULL) { - switch (password->encoding) { - case p_encoding_clear: - Dmsg2(200, "%s = \"%s\"\n", items[i].name, password->value); - Mmsg(temp, "%s = \"%s\"\n", items[i].name, password->value); - break; - case p_encoding_md5: - Dmsg2(200, "%s = \"[md5]%s\"\n", items[i].name, password->value); - Mmsg(temp, "%s = \"[md5]%s\"\n", items[i].name, password->value); - break; - default: - break; + if (hide_sensitive_data) { + Dmsg1(200, "%s = \"****************\"\n", items[i].name); + Mmsg(temp, "%s = \"****************\"\n", items[i].name); + } else { + switch (password->encoding) { + case p_encoding_clear: + Dmsg2(200, "%s = \"%s\"\n", items[i].name, password->value); + Mmsg(temp, "%s = \"%s\"\n", items[i].name, password->value); + break; + case p_encoding_md5: + Dmsg2(200, "%s = \"[md5]%s\"\n", items[i].name, password->value); + Mmsg(temp, "%s = \"[md5]%s\"\n", items[i].name, password->value); + break; + default: + break; + } } indent_config_item(cfg_str, 1, temp.c_str()); } @@ -1811,7 +1816,7 @@ bool BRSRES::print_config(POOL_MEM &buff) * This is a non-generic type call back to the daemon to get things printed. */ if (my_config->m_print_res) { - my_config->m_print_res(items, i, cfg_str); + my_config->m_print_res(items, i, cfg_str, hide_sensitive_data); } break; } diff --git a/src/qt-console/bat_conf.cpp b/src/qt-console/bat_conf.cpp index d53ca78c142..11cc45b9092 100644 --- a/src/qt-console/bat_conf.cpp +++ b/src/qt-console/bat_conf.cpp @@ -128,7 +128,9 @@ static RES_TABLE resources[] = { /* * Dump contents of resource */ -void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock) +void dump_resource(int type, RES *reshdr, + void sendit(void *sock, const char *fmt, ...), + void *sock, bool hide_sensitive_data) { URES *res = (URES *)reshdr; bool recurse = true; @@ -157,7 +159,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm printf(_("Unknown resource type %d\n"), type); } if (recurse && res->dir_res.hdr.next) { - dump_resource(type, res->dir_res.hdr.next, sendit, sock); + dump_resource(type, res->dir_res.hdr.next, sendit, sock, hide_sensitive_data); } } diff --git a/src/qt-tray-monitor/tray_conf.cpp b/src/qt-tray-monitor/tray_conf.cpp index 95a6320e0b8..93f5ebd8ae5 100644 --- a/src/qt-tray-monitor/tray_conf.cpp +++ b/src/qt-tray-monitor/tray_conf.cpp @@ -163,7 +163,8 @@ static RES_TABLE resources[] = { /* * Dump contents of resource */ -void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock) +void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), + void *sock, bool hide_sensitive_data) { POOL_MEM buf; URES *res = (URES *)reshdr; @@ -187,7 +188,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm sendit(sock, "%s", buf.c_str()); if (recurse && res->res_monitor.hdr.next) { - dump_resource(type, res->res_monitor.hdr.next, sendit, sock); + dump_resource(type, res->res_monitor.hdr.next, sendit, sock, hide_sensitive_data); } } diff --git a/src/stored/status.c b/src/stored/status.c index 233a4ef1686..0d7ec07bb56 100644 --- a/src/stored/status.c +++ b/src/stored/status.c @@ -123,7 +123,7 @@ static void list_resources(STATUS_PKT *sp) sendit(msg, len, sp); } - dump_resource(R_DEVICE, resources[R_DEVICE - my_config->m_r_first], sp); + dump_resource(R_DEVICE, resources[R_DEVICE - my_config->m_r_first], sp, false); if (!sp->api) { len = pm_strcpy(msg, "====\n\n"); diff --git a/src/stored/stored_conf.c b/src/stored/stored_conf.c index 48e7213a94b..b407868c650 100644 --- a/src/stored/stored_conf.c +++ b/src/stored/stored_conf.c @@ -441,7 +441,9 @@ static void store_compressionalgorithm(LEX *lc, RES_ITEM *item, int index, int p /* * Dump contents of resource */ -void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock) +void dump_resource(int type, RES *reshdr, + void sendit(void *sock, const char *fmt, ...), + void *sock, bool hide_sensitive_data) { POOL_MEM buf; URES *res = (URES *)reshdr; @@ -472,7 +474,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm sendit(sock, "%s", buf.c_str()); if (recurse && res->res_dir.hdr.next) { - dump_resource(type, (RES *)res->res_dir.hdr.next, sendit, sock); + dump_resource(type, (RES *)res->res_dir.hdr.next, sendit, sock, hide_sensitive_data); } }