diff --git a/SAP-MaxDB/lib/check_mk/base/cee/plugins/bakery/maxdb.py b/SAP-MaxDB/lib/check_mk/base/cee/plugins/bakery/maxdb.py index ae84af9..7358cb8 100644 --- a/SAP-MaxDB/lib/check_mk/base/cee/plugins/bakery/maxdb.py +++ b/SAP-MaxDB/lib/check_mk/base/cee/plugins/bakery/maxdb.py @@ -38,14 +38,23 @@ def _get_maxdb_conf_lines(conf: dict[str, str]) -> list[str]: i.replace("backup", "backup:sep(124)").replace("data", "data:sep(61)") for i in item.get("modules", []) ] - db = [ - f"[{item.get('dbname')}]", - f"user={item.get('user')}", - f"password={item.get('password')}", + db = [f"[{item.get('dbname')}]"] + # Authentication: an XUSER key avoids storing plaintext credentials in + # maxdb.cfg. If configured, it takes precedence over user/password. + # The WATO rule nests the credentials under "auth"; older rule versions + # stored user/password directly on the item, so support both layouts. + auth = item.get("auth", item) + xuser_key = auth.get("xuser_key") + if xuser_key: + db.append(f"xuser_key={xuser_key}") + else: + db.append(f"user={auth.get('user')}") + db.append(f"password={auth.get('password')}") + db.extend([ "cmd_tool=" + item.get("cmd_tool", f"/sapdb/{item.get('dbname')}/db/bin/dbmcli"), f"timeout={item.get('timeout', 20)}", f"modules={str(modules)}", - ] + ]) out.extend(db) return out diff --git a/SAP-MaxDB/share/check_mk/agents/plugins/maxdb.py b/SAP-MaxDB/share/check_mk/agents/plugins/maxdb.py index cd2bf85..d42afef 100755 --- a/SAP-MaxDB/share/check_mk/agents/plugins/maxdb.py +++ b/SAP-MaxDB/share/check_mk/agents/plugins/maxdb.py @@ -63,7 +63,17 @@ def main(): if not re.search(r"^\/[a-zA-Z_0-9_.-\/]*\/bin\/dbmcli$", cmd): print(f"Stop Plugin, hence {cmd} does not match Regex") sys.exit(2) - cmd_line = [cmd, "-d", key, "-u", f"{value.get('user')},{value.get('password')}"] + # Authentication: prefer an XUSER key (dbmcli -U ) so that no + # plaintext credentials are needed in maxdb.cfg. Fall back to the + # classic -d -u if no xuser_key is configured. + xuser_key = value.get("xuser_key") + if xuser_key: + if not re.search(r"^[A-Za-z0-9_.-]+$", xuser_key): + print(f"Stop Plugin, hence xuser_key {xuser_key} does not match Regex") + sys.exit(2) + cmd_line = [cmd, "-U", xuser_key] + else: + cmd_line = [cmd, "-d", key, "-u", f"{value.get('user')},{value.get('password')}"] for check, queries in known_querys.items(): if check in run_checks: print(f"<<>>") diff --git a/SAP-MaxDB/share/check_mk/web/plugins/wato/agent_bakery_maxdb.py b/SAP-MaxDB/share/check_mk/web/plugins/wato/agent_bakery_maxdb.py index b39ab00..1568fde 100644 --- a/SAP-MaxDB/share/check_mk/web/plugins/wato/agent_bakery_maxdb.py +++ b/SAP-MaxDB/share/check_mk/web/plugins/wato/agent_bakery_maxdb.py @@ -12,6 +12,7 @@ Integer, Password, ListOf, + Alternative, ) from cmk.gui.i18n import _ @@ -37,18 +38,66 @@ def _valuespec_agent_config_maxdb(): TextInput(title=_("Name of Database"), help=_("MaxDB Name")), ), ( - "user", - TextInput( - title=_("Username"), help=_("User for Login into the MaxDB") - ), - ), - ( - "password", - Password( - title=_("Password of User"), + "auth", + Alternative( + title=_("Authentication"), help=_( - "Password for the user. Be careful the password is in clear text in the agent configuration." + "Choose how the plugin authenticates against the MaxDB. " + "Using an XUSER key (dbmcli -U <key>) is recommended, " + "as it avoids storing the password in clear text in the " + "agent configuration file maxdb.cfg. The XUSER key must be " + "created beforehand with xuser set for the OS user " + "that runs the Checkmk agent." ), + elements=[ + Dictionary( + title=_("XUSER key (no plaintext password)"), + elements=[ + ( + "xuser_key", + TextInput( + title=_("XUSER key"), + regex="^[A-Za-z0-9_.-]+$", + regex_error=_( + "Only letters, digits and _.- are allowed." + ), + help=_( + "Name of the XUSER entry to use with " + "dbmcli -U. Create it with e.g. " + "xuser set -U MONCSP -d CSP -u " + "MONITOR,secret as the agent's OS user." + ), + allow_empty=False, + ), + ), + ], + optional_keys=[], + ), + Dictionary( + title=_("User and password (clear text in maxdb.cfg)"), + elements=[ + ( + "user", + TextInput( + title=_("Username"), + help=_("User for Login into the MaxDB"), + ), + ), + ( + "password", + Password( + title=_("Password of User"), + help=_( + "Password for the user. Be careful the " + "password is in clear text in the agent " + "configuration." + ), + ), + ), + ], + optional_keys=[], + ), + ], ), ), (