hue_ldap_test.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. #!/bin/bash
  2. # Licensed to Cloudera, Inc. under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. Cloudera, Inc. licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. #This script will grab current Hue configuration for ldap
  18. #and run ldapsearch commands to validate the config
  19. #NOTE: This script requires ldapsearch to be installed
  20. #parse command line arguments
  21. parse_arguments()
  22. {
  23. # Test that we're using compatible getopt version.
  24. getopt -T > /dev/null
  25. if [[ $? -ne 4 ]]; then
  26. echo "Incompatible getopt version."
  27. exit 1
  28. fi
  29. # Parse short and long option parameters.
  30. OUTPUT_DIR=/tmp/hue_ldap_test
  31. TEST_USER=
  32. TEST_GROUP=
  33. HUE_CONF_DIR=
  34. GETOPT=`getopt -n $0 -o o:,u:,g:,c:,v,h \
  35. -l outdir:,user:,group:,conf:,verbose,help \
  36. -- "$@"`
  37. eval set -- "$GETOPT"
  38. while true;
  39. do
  40. case "$1" in
  41. -o|--outdir)
  42. OUTPUT_DIR=$2
  43. shift 2
  44. ;;
  45. -u|--user)
  46. TEST_USER=$2
  47. shift 2
  48. ;;
  49. -g|--group)
  50. TEST_GROUP=$2
  51. shift 2
  52. ;;
  53. -c|--conf)
  54. HUE_CONF_DIR=$2
  55. shift 2
  56. ;;
  57. -v|--verbose)
  58. VERBOSE=1
  59. shift
  60. ;;
  61. --)
  62. shift
  63. break
  64. ;;
  65. *)
  66. usage
  67. exit 1
  68. ;;
  69. esac
  70. done
  71. #
  72. }
  73. usage()
  74. {
  75. cat << EOF
  76. usage: $0 [options]
  77. Tests Hue Server Ldap Config by runnning ldapsearch:
  78. OPTIONS
  79. -o|--outdir <outdir> Location to dump ldap test report - default /tmp/hue_ldap_test.
  80. -u|--user <user> Required: User that exists in ldap to search for
  81. -g|--group <group> Group that exists in ldap to search for - default, does not search for group.
  82. -c|--conf <dir> Custom Hue conf directory with hue.ini for quicker testing - default, hue process dir.
  83. -h|--help Show this message.
  84. EOF
  85. }
  86. debug()
  87. {
  88. if [[ ! -z $VERBOSE ]]
  89. then
  90. echo "$1"
  91. fi
  92. }
  93. report()
  94. {
  95. echo "$1" | tee -a ${REPORT_FILE}
  96. }
  97. message()
  98. {
  99. case "$1" in
  100. "SEARCH_METHOD")
  101. MESSAGE="WARN: ldap_username_pattern, nt_domain and search_bind_authentication are exclusive, only one should be set at a time."
  102. ;;
  103. *)
  104. MESSAGE="Unknown message type"
  105. ;;
  106. esac
  107. if [[ -z $2 ]]
  108. then
  109. echo "${MESSAGE}" | tee -a ${REPORT_FILE}
  110. fi
  111. }
  112. main()
  113. {
  114. parse_arguments "$@"
  115. LDAPSEARCH=$(which ldapsearch)
  116. if [[ -z ${TEST_USER} ]]
  117. then
  118. echo "-u <ldapuser> required"
  119. usage
  120. exit 1
  121. fi
  122. if [[ ! ${USER} =~ .*root* ]]
  123. then
  124. echo "Script must be run as root: exiting"
  125. exit 1
  126. fi
  127. if [[ ! -f ${LDAPSEARCH} ]]
  128. then
  129. echo "ldapsearch not found, please install ldapsearch"
  130. exit 1
  131. else
  132. LDAPSEARCH_COMMAND="${LDAPSEARCH} -x -LLL"
  133. fi
  134. AGENT_PROCESS_DIR="/var/run/cloudera-scm-agent/process"
  135. PARCEL_DIR=/opt/cloudera/parcels/CDH
  136. ORACLE_HOME=/opt/cloudera/parcels/ORACLE_INSTANT_CLIENT/instantclient_11_2/
  137. LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ORACLE_HOME}
  138. if [ ! -d "/usr/lib/hadoop" ]
  139. then
  140. CDH_HOME=$PARCEL_DIR
  141. else
  142. CDH_HOME=/usr
  143. fi
  144. if [[ -z ${HUE_CONF_DIR} ]]
  145. then
  146. if [ -d "${AGENT_PROCESS_DIR}" ]
  147. then
  148. HUE_CONF_DIR="${AGENT_PROCESS_DIR}/`ls -1 ${AGENT_PROCESS_DIR} | grep HUE | sort -n | tail -1 `"
  149. else
  150. HUE_CONF_DIR="/etc/hue/conf"
  151. fi
  152. fi
  153. TMP_ENV_FILE=${HUE_CONF_DIR}/hue_tmp_env.sh
  154. TMP_PASS_FILE=${HUE_CONF_DIR}/hue_tmp_ldap_pass.txt
  155. TMP_FILE=${HUE_CONF_DIR}/hue_tmp.txt
  156. touch ${TMP_ENV_FILE}
  157. chmod 600 ${TMP_ENV_FILE}
  158. touch ${TMP_PASS_FILE}
  159. chmod 600 ${TMP_PASS_FILE}
  160. mkdir -p ${OUTPUT_DIR}
  161. REPORT_FILE=${OUTPUT_DIR}/hue_ldap_report.txt
  162. rm -f ${REPORT_FILE}
  163. if [ -d "${CDH_HOME}/lib/hue/build/env/bin" ]
  164. then
  165. COMMAND="${CDH_HOME}/lib/hue/build/env/bin/hue shell"
  166. else
  167. COMMAND="${CDH_HOME}/share/hue/build/env/bin/hue shell"
  168. fi
  169. export CDH_HOME HUE_CONF_DIR ORACLE_HOME LD_LIBRARY_PATH COMMAND
  170. report "CDH_HOME: ${CDH_HOME}"
  171. report "HUE_CONF_DIR: ${HUE_CONF_DIR}"
  172. report ""
  173. ${COMMAND} >> /dev/null 2>&1 <<EOF
  174. import desktop.conf
  175. def write_property( hue_ldap_conf_file, ldap_config, property_name):
  176. if property_name != "bind_password":
  177. try:
  178. func = getattr(ldap_config, "%s" % (property_name.upper()))
  179. except AttributeError:
  180. print 'function not found "%s" ()' % (property_name.upper().get())
  181. else:
  182. property_value=func.get()
  183. else:
  184. try:
  185. property_value = desktop.conf.get_ldap_bind_password(ldap_config)
  186. except AttributeError:
  187. property_value = ldap_config.BIND_PASSWORD.get()
  188. hue_ldap_conf_file.write("%s=\"%s\"\n" % (property_name,property_value))
  189. return
  190. hue_ldap_conf_file = open('${TMP_ENV_FILE}', 'w')
  191. hue_ldap_conf_file.write("#!/bin/bash\n")
  192. server = None
  193. ldap_config = desktop.conf.LDAP.LDAP_SERVERS.get()[server] if server else desktop.conf.LDAP
  194. write_property( hue_ldap_conf_file, ldap_config, "ldap_url")
  195. write_property( hue_ldap_conf_file, ldap_config, "bind_dn")
  196. write_property( hue_ldap_conf_file, ldap_config, "bind_password")
  197. write_property( hue_ldap_conf_file, ldap_config, "ldap_cert")
  198. write_property( hue_ldap_conf_file, ldap_config, "search_bind_authentication")
  199. write_property( hue_ldap_conf_file, ldap_config, "base_dn")
  200. write_property( hue_ldap_conf_file, ldap_config, "nt_domain")
  201. write_property( hue_ldap_conf_file, ldap_config, "use_start_tls")
  202. write_property( hue_ldap_conf_file, ldap_config, "ldap_username_pattern")
  203. write_property( hue_ldap_conf_file, ldap_config, "follow_referrals")
  204. write_property( hue_ldap_conf_file, ldap_config.USERS, "user_filter")
  205. write_property( hue_ldap_conf_file, ldap_config.USERS, "user_name_attr")
  206. write_property( hue_ldap_conf_file, ldap_config.GROUPS, "group_filter")
  207. write_property( hue_ldap_conf_file, ldap_config.GROUPS, "group_name_attr")
  208. write_property( hue_ldap_conf_file, ldap_config.GROUPS, "group_member_attr")
  209. EOF
  210. source ${TMP_ENV_FILE}
  211. if [[ -z ${ldap_url} ]]
  212. then
  213. report "Required attribute ldap_url is not set"
  214. exit 1
  215. else
  216. LDAPSEARCH_COMMAND="${LDAPSEARCH_COMMAND} -H ${ldap_url}"
  217. fi
  218. if [[ -z ${ldap_cert} || ${ldap_cert} =~ .*None.* ]]
  219. then
  220. LDAPSEARCH_COMMAND="LDAPTLS_REQCERT=never ${LDAPSEARCH_COMMAND}"
  221. else
  222. LDAPSEARCH_COMMAND="LDAPTLS_REQCERT=ALLOW LDAPTLS_CACERT=${ldap_cert} ${LDAPSEARCH_COMMAND}"
  223. fi
  224. LDAPSEARCH_COMMAND_NOBASE=${LDAPSEARCH_COMMAND}
  225. if [[ -z ${base_dn} || ${base_dn} == "None" ]]
  226. then
  227. if [[ -z ${ldap_username_pattern} || ${ldap_username_pattern} == "None" ]]
  228. then
  229. report "WARN: base_dn is not set and may be required"
  230. fi
  231. else
  232. LDAPSEARCH_COMMAND="${LDAPSEARCH_COMMAND} -b \"${base_dn}\""
  233. fi
  234. LDAPSEARCH_COMMAND_NOAUTH=${LDAPSEARCH_COMMAND}
  235. if [[ ! -z ${bind_dn} && ${bind_dn} != "None" ]]
  236. then
  237. if [[ -z ${bind_password} || ${bind_password} == "None" ]]
  238. then
  239. report "WARN: if bind_dn is set, then bind_password is required"
  240. fi
  241. if [[ ! -z ${nt_domain} && ${nt_domain} != "None" ]]
  242. then
  243. bind_dn=${bind_dn}@${nt_domain}
  244. fi
  245. echo -n "${bind_password}" > ${TMP_PASS_FILE}
  246. LDAPSEARCH_COMMAND="${LDAPSEARCH_COMMAND} -D ${bind_dn// /\\ } -y ${TMP_PASS_FILE}"
  247. LDAPSEARCH_COMMAND_NOBASE="${LDAPSEARCH_COMMAND} -D ${bind_dn// /\\ } -y ${TMP_PASS_FILE}"
  248. fi
  249. SEARCH_METHOD_FLAG=
  250. if [[ ${search_bind_authentication} == "True" ]]
  251. then
  252. if [[ ! -z ${nt_domain} && ${nt_domain} != "None" ]]
  253. then
  254. message "SEARCH_METHOD" ${SEARCH_METHOD_FLAG}
  255. SEARCH_METHOD_FLAG=true
  256. fi
  257. if [[ ! -z ${ldap_username_pattern} && ${ldap_username_pattern} != "None" ]]
  258. then
  259. message "SEARCH_METHOD" ${SEARCH_METHOD_FLAG}
  260. SEARCH_METHOD_FLAG=true
  261. fi
  262. fi
  263. if [[ ! -z ${nt_domain} && ${nt_domain} != "None" ]]
  264. then
  265. if [[ ${search_bind_authentication} == "True" ]]
  266. then
  267. message "SEARCH_METHOD" ${SEARCH_METHOD_FLAG}
  268. SEARCH_METHOD_FLAG=true
  269. fi
  270. if [[ ! -z ${ldap_username_pattern} && ${ldap_username_pattern} != "None" ]]
  271. then
  272. message "SEARCH_METHOD" ${SEARCH_METHOD_FLAG}
  273. SEARCH_METHOD_FLAG=true
  274. fi
  275. fi
  276. if [[ ! -z ${ldap_username_pattern} && ${ldap_username_pattern} != "None" ]]
  277. then
  278. if [[ ${search_bind_authentication} == "True" ]]
  279. then
  280. message "SEARCH_METHOD" ${SEARCH_METHOD_FLAG}
  281. SEARCH_METHOD_FLAG=true
  282. fi
  283. if [[ ! -z ${nt_domain} && ${nt_domain} != "None" ]]
  284. then
  285. message "SEARCH_METHOD" ${SEARCH_METHOD_FLAG}
  286. SEARCH_METHOD_FLAG=true
  287. fi
  288. fi
  289. USER_FILTER="(&(${user_filter})(${user_name_attr}=${TEST_USER}))"
  290. GROUP_FILTER="(&(${group_filter})(${group_name_attr}=${TEST_GROUP}))"
  291. cat ${TMP_ENV_FILE} | grep -v bind_password | grep -v bash >> ${REPORT_FILE}
  292. report ""
  293. if [[ ! -z ${ldap_username_pattern} && ${ldap_username_pattern} != "None" ]]
  294. then
  295. LDAPSEARCH_USER_COMMAND="${LDAPSEARCH_COMMAND_NOBASE} -b \"${ldap_username_pattern//\<username\>/${TEST_USER}}\""
  296. else
  297. LDAPSEARCH_USER_COMMAND="${LDAPSEARCH_COMMAND} '${USER_FILTER}'"
  298. fi
  299. report "Running ldapsearch command on user ${TEST_USER}:"
  300. report "${LDAPSEARCH_USER_COMMAND}"
  301. eval ${LDAPSEARCH_USER_COMMAND} 2>&1 | grep -vi password | tee ${TMP_FILE}
  302. USER_BIND_DN=`grep -i "dn:" ${TMP_FILE} | awk -F\: '{print $2}'`
  303. cat ${TMP_FILE} >> ${REPORT_FILE}
  304. report ""
  305. LDAPSEARCH_USER_COMMAND="${LDAPSEARCH_COMMAND_NOBASE} '(${user_name_attr}=${TEST_USER})'"
  306. report "Running ldapsearch command on user ${TEST_USER} without base or filter:"
  307. report "${LDAPSEARCH_USER_COMMAND}"
  308. eval ${LDAPSEARCH_USER_COMMAND} 2>&1 | grep -vi password | tee -a ${REPORT_FILE}
  309. report ""
  310. if [[ ! -z ${TEST_GROUP} ]]
  311. then
  312. LDAPSEARCH_GROUP_COMMAND="${LDAPSEARCH_COMMAND} '${GROUP_FILTER}'"
  313. report "Running ldapsearch command on group ${TEST_GROUP}:"
  314. report "${LDAPSEARCH_GROUP_COMMAND}"
  315. eval ${LDAPSEARCH_GROUP_COMMAND} 2>&1 | tee -a ${REPORT_FILE}
  316. report ""
  317. LDAPSEARCH_GROUP_COMMAND="${LDAPSEARCH_COMMAND_NOBASE} '(${group_name_attr}=${TEST_GROU})'"
  318. report "Running ldapsearch command on group ${TEST_GROUP} without base or filter:"
  319. report "${LDAPSEARCH_GROUP_COMMAND}"
  320. eval ${LDAPSEARCH_GROUP_COMMAND} 2>&1 | tee -a ${REPORT_FILE}
  321. fi
  322. report ""
  323. LDAPSEARCH_ROOT_COMMAND="${LDAPSEARCH_COMMAND_NOBASE} -s base -b ''"
  324. report "Running ldapsearch command on root dse:"
  325. report "${LDAPSEARCH_ROOT_COMMAND}"
  326. eval ${LDAPSEARCH_ROOT_COMMAND} 2>&1 | tee -a ${REPORT_FILE}
  327. LDAPSEARCH_USER_BIND_COMMAND="${LDAPSEARCH_COMMAND_NOAUTH} -D ${USER_BIND_DN// /\\ } -W '${USER_FILTER}' dn ${user_name_attr}"
  328. report "Running ldapsearch command binding as ${USER_BIND_DN}(${TEST_USER}):"
  329. report "When prompted please enter ${USER_BIND_DN}'s password:"
  330. report "${LDAPSEARCH_USER_BIND_COMMAND}"
  331. eval ${LDAPSEARCH_USER_BIND_COMMAND} 2>&1 | tee -a ${REPORT_FILE}
  332. echo "View ${REPORT_FILE} for more details"
  333. rm -f ${TMP_ENV_FILE} ${TMP_PASS_FILE} ${TMP_FILE}
  334. }
  335. main "$@"