From f624c4de5cee39d936675c6174ed445093a6289d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kristoffer=20Gr=C3=B6nlund?= <krig@koru.se>
Date: Thu, 5 Dec 2013 13:15:47 +0100
Subject: [PATCH 1/3] High: oracle: Make monitoring user configurable
 (bnc#850589)

The OCFMON user needs to have unlimited password
expiry, otherwise the agent will fail if the
password expires.

This patch creates a special monitoring profile
as well as a monitoring user, and sets the password
expiry to be unlimited.

To avoid the automatic creation of user or profile,
the monitoring user and profile can be supplied as
parameters to the agent.

This patch also converts the provided user and profile
name to uppercase, to avoid issues with case-sensitivity.
---
 heartbeat/oracle | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 99 insertions(+), 7 deletions(-)

diff --git a/heartbeat/oracle b/heartbeat/oracle
index d6b2c50..ff7a904 100755
--- a/heartbeat/oracle
+++ b/heartbeat/oracle
@@ -27,6 +27,9 @@
 #	OCF_RESKEY_ipcrm (optional; defaults to "instance")
 #	OCF_RESKEY_clear_backupmode (optional; default to "false")
 #	OCF_RESKEY_shutdown_method (optional; default to "checkpoint/abort")
+#	OCF_RESKEY_monuser (optional; defaults to "OCFMON")
+#	OCF_RESKEY_monpassword (optional; defaults to "OCFMON")
+#	OCF_RESKEY_monprofile (optional; defaults to "OCFMONPROFILE")
 #
 # Initialization:
 
@@ -56,6 +59,11 @@ oracle_usage() {
 	!
 }
 
+# Defaults
+OCF_RESKEY_monuser_default="OCFMON"
+OCF_RESKEY_monpassword_default="OCFMON"
+OCF_RESKEY_monprofile_default="OCFMONPROFILE"
+
 oracle_meta_data() {
 	cat <<END
 <?xml version="1.0"?>
@@ -100,6 +108,39 @@ If this does not work for you, just set it explicitely.
 <content type="string" default="" />
 </parameter>
 
+<parameter name="monuser" unique="0">
+<longdesc lang="en">
+Monitoring user name. Every connection as
+sysdba is logged in an audit log. This can
+result in a large number of new files created.
+A new user is created (if it doesn't exist) in
+the start action and subsequently used in monitor.
+It should have very limited rights. Make sure
+that the password for this user does not expire.
+</longdesc>
+<shortdesc lang="en">monuser</shortdesc>
+<content type="string" default="$OCF_RESKEY_monuser_default" />
+</parameter>
+
+<parameter name="monpassword" unique="0">
+<longdesc lang="en">
+Password for the monitoring user. Make sure
+that the password for this user does not expire.
+</longdesc>
+<shortdesc lang="en">monpassword</shortdesc>
+<content type="string" default="$OCF_RESKEY_monpassword_default" />
+</parameter>
+
+<parameter name="monprofile" unique="0">
+<longdesc lang="en">
+Profile used by the monitoring user. If the
+profile does not exist, it will be created
+with a non-expiring password.
+</longdesc>
+<shortdesc lang="en">monprofile</shortdesc>
+<content type="string" default="$OCF_RESKEY_monprofile_default" />
+</parameter>
+
 <parameter name="ipcrm" unique="0">
 <longdesc lang="en">
 Sometimes IPC objects (shared memory segments and semaphores)
@@ -250,7 +291,7 @@ dbasql() {
 	runsql "connect / as sysdba" $*
 }
 monsql() {
-	runsql "connect $MONUSR/$MONUSR" $*
+	runsql "connect $MONUSR/\"$MONPWD\"" $*
 }
 # use dbasql_one if the query should result in a single line output
 # at times people stuff commands in oracle .profile
@@ -325,22 +366,63 @@ getipc() {
 	echo "oradebug tracefile_name"
 	echo "oradebug ipc"
 }
+show_mon_profile() {
+	echo "select PROFILE from dba_profiles where PROFILE='$MONPROFILE';"
+}
+mk_mon_profile() {
+	cat<<EOF
+create profile $MONPROFILE limit FAILED_LOGIN_ATTEMPTS UNLIMITED PASSWORD_LIFE_TIME UNLIMITED;
+EOF
+}
 show_mon_user() {
 	echo "select USERNAME, ACCOUNT_STATUS from dba_users where USERNAME='$MONUSR';"
 }
 mk_mon_user() {
 	cat<<EOF
-create user $MONUSR identified by $MONUSR;
+create user $MONUSR identified by "$MONPWD" profile $MONPROFILE;
 grant create session to $MONUSR;
 grant select on v_\$instance to $MONUSR;
 EOF
 }
-check_mon_user() {
+show_mon_user_profile() {
+	echo "select PROFILE from dba_users where USERNAME='$MONUSR';"
+}
+set_mon_user_profile() {
+	echo "alter user $MONUSR profile $MONPROFILE;"
+}
+check_mon_profile() {
 	local output
-	dbasql show_mon_user | grep -w "^$MONUSR" >/dev/null &&
+	output=`dbasql show_mon_profile`
+	if echo "$output" | grep -iw "^$MONPROFILE" >/dev/null; then
 		return 0
+	fi
+	output=`dbasql mk_mon_profile show_mon_profile`
+	if echo "$output" | grep -iw "^$MONPROFILE" >/dev/null; then
+		return 0
+	else
+		ocf_log err "could not create $MONPROFILE oracle profile"
+		ocf_log err "sqlplus output: $output"
+		return 1
+	fi
+}
+check_mon_user() {
+	local output
+	output=`dbasql show_mon_user`
+	if echo "$output" | grep -iw "^$MONUSR" >/dev/null; then
+		output=`dbasql show_mon_user_profile`
+		if echo "$output" | grep -iw "^$MONPROFILE" >/dev/null; then
+			return 0
+		else
+			output=`dbasql set_mon_user_profile`
+			echo "$output" | grep -iw "^User altered." >/dev/null &&
+				return 0
+			ocf_log err "could not set profile for $MONUSR oracle user"
+			ocf_log err "sqlplus output: $output"
+			return 1
+		fi
+	fi
 	output=`dbasql mk_mon_user show_mon_user`
-	if echo "$output" | grep -w "^$MONUSR" >/dev/null; then
+	if echo "$output" | grep -iw "^$MONUSR" >/dev/null; then
 		return 0
 	else
 		ocf_log err "could not create $MONUSR oracle user"
@@ -417,7 +499,7 @@ ipcdesc() {
 }
 rmipc() {
 	local what=$1 id=$2
-	ipcs -$what | filteroraipc | grep -w $id >/dev/null 2>&1 ||
+	ipcs -$what | filteroraipc | grep -iw $id >/dev/null 2>&1 ||
 		return
 	ocf_log info "Removing `ipcdesc $what` $id."
 	ipcrm -$what $id
@@ -541,6 +623,11 @@ oracle_start() {
 	fi
 	output=`dbasql dbopen`
 
+	# check/create the monitor profile
+	if ! check_mon_profile; then
+		return $OCF_ERR_GENERIC
+	fi
+
 	# check/create the monitor user
 	if ! check_mon_user; then
 		return $OCF_ERR_GENERIC
@@ -650,7 +737,12 @@ show_procs() {
 proc_pids() { show_procs | awk '{print $1}'; }
 PROCS_CLEANUP_TIME="30"
 
-MONUSR="OCFMON"
+MONUSR=${OCF_RESKEY_monuser:-$OCF_RESKEY_monuser_default}
+MONPWD=${OCF_RESKEY_monpassword:-$OCF_RESKEY_monpassword_default}
+MONPROFILE=${OCF_RESKEY_monprofile_default:-$OCF_RESKEY_monprofile_default}
+
+MONUSR=$(echo $MONUSR | awk '{print toupper($0)}')
+MONPROFILE=$(echo $MONPROFILE | awk '{print toupper($0)}')
 OCF_REQUIRED_PARAMS="sid"
 OCF_REQUIRED_BINARIES="sqlplus"
 ocf_rarun $*
-- 
1.9.2

