PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/ser-0.9.6/modules/postgres/serpgctl

#
Shell | 783 lines | 701 code | 39 blank | 43 comment | 22 complexity | a97aad4a5a5cdfb967983cdc04fb3e51 MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0
  1. #!/bin/sh
  2. #
  3. # $Id: serpgctl,v 1.1 2003/04/08 01:25:35 lgfausak Exp $
  4. #
  5. # sc: ser control; tool for maintaining ser's databases
  6. #
  7. # History:
  8. # --------
  9. # 2003-04-06 this is a hack, from serctl, to make work with postgres
  10. # 2003-02-23 Thomas's start|stop commands checked in
  11. #
  12. # To-DO:
  13. # -----
  14. # - generalization for other than mysql databases
  15. # - front-end to updating administrative mysql password would
  16. # be a convenient thing to have
  17. #
  18. # I copy this over the top of the existing serctl program.
  19. #
  20. # configuration for starting/stopping ser
  21. PID_FILE=/var/run/ser.pid
  22. SYSLOG=1 # 0=output to console, 1=output to syslog
  23. STARTOPTIONS= # for example -dddd
  24. # ser's FIFO server
  25. if [ -z "$SER_FIFO" ]; then
  26. SER_FIFO=/tmp/ser_fifo
  27. fi
  28. # period in which stats are reprinted
  29. if [ -z "$WATCH_PERIOD" ] ; then
  30. WATCH_PERIOD=2
  31. fi
  32. PW="test"
  33. # SQL config
  34. if [ -z "$SQL_DB" ] ; then
  35. SQL_DB=ser
  36. fi
  37. if [ -z "$SQL_HOST" ] ; then
  38. SQL_HOST=localhost
  39. fi
  40. if [ -z "$SQL_PORT" ] ; then
  41. SQL_PORT=5432
  42. fi
  43. if [ -z "$SQL_USER" ] ; then
  44. SQL_USER=ser
  45. fi
  46. # the read-only user for whom password may be stored here
  47. if [ -z "$RO_USER" ] ; then
  48. RO_USER=serro
  49. fi
  50. if [ -z "$RO_PW" ] ; then
  51. RO_PW=47serro11
  52. fi
  53. # binaries
  54. GENHA1='gen_ha1'
  55. PGSQL='psql'
  56. SER='sr'
  57. LAST_LINE='tail -1'
  58. # ACL name verification
  59. VERIFY_ACL=1
  60. ACL_GROUPS="local ld int voicemail free-pstn"
  61. # expiration time for alias table
  62. FOREVER='2020-05-28 21:32:15'
  63. FOREVER_REL=1073741823
  64. VERSION='$Revision: 1.1 $'
  65. #### SQL names
  66. # Usr Loc Table
  67. USRLOC=location
  68. USER_COLUMN=username
  69. CALLID_COLUMN=callid
  70. # subscriber table
  71. TABLE=subscriber
  72. REALM_COLUMN=domain
  73. HA1_COLUMN=HA1
  74. HA1B_COLUMN=HA1B
  75. PASSWORD_COLUMN=password
  76. SUBSCRIBER_COLUMN='username'
  77. EMAIL_COLUMN=email_address
  78. SUB_CREATED_COLUMN=datetime_created
  79. SUB_MODIFIED_COLUMN=datetime_modified
  80. PHP_LIB_COLUMN=phplib_id
  81. # acl table
  82. ACL_TABLE=grp
  83. ACL_USER_COLUMN=user
  84. ACL_GROUP_COLUMN=grp
  85. ACL_MODIFIED_COLUMN=last_modified
  86. # aliases table
  87. A_TABLE=aliases
  88. A_USER_COLUMN=user
  89. A_CONTACT_COLUMN=contact
  90. A_EXPIRES_COLUMN=expires
  91. A_Q_COLUMN=q
  92. A_CALLID_COLUMN=callid
  93. A_CSEQ_COLUMN=cseq
  94. A_LAST_MODIFIED_COLUMN=last_modified
  95. FIFO_DBG=0
  96. #===================================================================
  97. usage() {
  98. CMD=`basename $0`
  99. if [ "0$VERIFY_ACL" -eq 1 ] ; then
  100. EXTRA_TEXT="ACL privileges are: $ACL_GROUPS"
  101. fi
  102. cat <<EOF
  103. $0 $VERSION
  104. usage:
  105. * subscribers *
  106. $CMD add <username> <password> <email> .. add a new subscriber (*)
  107. $CMD passwd <username> <passwd> ......... change user's password (*)
  108. $CMD rm <username> ...................... delete a user (*)
  109. $CMD mail <username> .................... send an email to a user
  110. $CMD alias show [<alias>] ............... show aliases
  111. $CMD alias rm <alias> ................... remove an alias
  112. $CMD alias add <alias> <uri> ............ add an aliases
  113. * access control lists *
  114. $CMD acl show [<username>] .............. show user membership
  115. $CMD acl grant <username> <group> ....... grant user membership (*)
  116. $CMD acl revoke <username> [<group>] .... grant user membership(s) (*)
  117. * usrloc *
  118. $CMD ul show [<username>]................ show in-RAM online users
  119. $CMD ul rm <username> ................... delete user's UsrLoc entries
  120. $CMD ul add <username> <uri> ............ introduce a permanent UrLoc entry
  121. $CMD showdb [<username>] ................ show online users flushed in DB
  122. * server health *
  123. $CMD monitor ............................ show internal status
  124. $CMD ps ................................. show runnig processes
  125. $CMD fifo ............................... send raw commands to FIFO
  126. * server control *
  127. $CMD start .............................. start ser
  128. $CMD stop ............................... stop ser
  129. $CMD restart ............................ restart ser
  130. Commands labeled with (*) will prompt for a MySQL password.
  131. If the variable PW is set, the password will not be prompted.
  132. $EXTRA_TEXT
  133. EOF
  134. }
  135. # check the parameter if it is a valid SIP URI
  136. # quite simplified now -- it captures just very basic
  137. # errors
  138. check_uri() {
  139. echo "$1" | grep -E "^sip:([a-zA-Z0-9_]+@)?.*\..*"
  140. }
  141. #params: none
  142. # output: PW
  143. prompt_pw() {
  144. if [ -z "$PW" ] ; then
  145. savetty=`stty -g`
  146. printf "Postgres password: "
  147. stty -echo
  148. read PW
  149. stty $savetty
  150. echo
  151. fi
  152. }
  153. # process output from FIFO server; if everything is ok
  154. # skip the first "ok" line and proceed to returned
  155. # parameters
  156. filter_fl()
  157. {
  158. # tail +2
  159. awk 'BEGIN {line=0;IGNORECASE=1;}
  160. {line++}
  161. line==1 && /^200 ok/ { next }
  162. { print }'
  163. }
  164. fifo_cmd()
  165. {
  166. if [ "0${FIFO_DBG}" -eq 1 ] ; then
  167. echo "entering fifo_cmd $*"
  168. fi
  169. if [ "$#" -lt 1 ]; then
  170. echo "ERROR: fifo_cmd must take at least command name as parameter"
  171. exit
  172. fi
  173. name=ser_receiver_$$
  174. path=/tmp/$name
  175. if [ ! -w $SER_FIFO ]; then
  176. echo "Error opening ser's FIFO $SER_FIFO"
  177. echo "Make sure you have line fifo=$SER_FIFO in your config"
  178. exit 1
  179. fi
  180. mkfifo $path
  181. if [ $? -ne 0 ] ; then
  182. echo "error opening read fifo $path"
  183. exit 1
  184. fi
  185. chmod a+w $path
  186. # construct the command now
  187. CMD=":$1:$name\n";
  188. shift
  189. while [ -n "$1" ] ; do
  190. CMD="${CMD}${1}\n"
  191. shift
  192. done
  193. CMD="${CMD}\n"
  194. trap "rm -f $path; exit 1" 2
  195. # start reader now so that it is ready for replies
  196. # immediately after a request was sent out
  197. cat < $path | filter_fl &
  198. # issue FIFO request (printf taken to deal with \n)
  199. printf "$CMD" > $SER_FIFO
  200. # wait for the reader to complete
  201. wait
  202. rm $path
  203. if [ "0${FIFO_DBG}" -eq 1 ] ; then
  204. printf "FIFO command was:\n$CMD"
  205. fi
  206. }
  207. # $1 = name $2=path $3=attempt
  208. print_stats() {
  209. echo "[cycle #: $3; if constant make sure server lives and fifo is on]"
  210. cat < $2 | filter_fl &
  211. cat > $SER_FIFO <<EOF
  212. :version:$1
  213. EOF
  214. wait
  215. cat < $2 | filter_fl &
  216. cat > $SER_FIFO << EOF
  217. :uptime:$1
  218. EOF
  219. wait
  220. echo
  221. echo Transaction Statistics
  222. cat < $2 | filter_fl &
  223. cat > $SER_FIFO <<EOF
  224. :t_stats:$1
  225. EOF
  226. wait
  227. echo
  228. echo Stateless Server Statistics
  229. cat < $2 | filter_fl &
  230. cat > $SER_FIFO <<EOF
  231. :sl_stats:$1
  232. EOF
  233. wait
  234. echo
  235. echo UsrLoc Stats
  236. cat < $2 | filter_fl &
  237. cat > $SER_FIFO <<EOF
  238. :ul_stats:$1
  239. EOF
  240. wait
  241. }
  242. # input: sql query, optional mysql command-line params
  243. sql_query() {
  244. # if password not yet queried, query it now
  245. if [ -z "$PW" ] ; then
  246. savetty=`stty -g`
  247. printf "MySql password: "
  248. stty -echo
  249. read PW >&2
  250. stty $savetty
  251. echo >&2
  252. fi
  253. $PGSQL $2\
  254. -A -q -t \
  255. -P fieldsep=" " \
  256. -h $SQL_HOST \
  257. -U $SQL_USER \
  258. $SQL_DB \
  259. -c "$1"
  260. }
  261. # input: sql query, optional mysql command-line params
  262. sql_ro_query() {
  263. $PGSQL $2\
  264. -h $SQL_HOST \
  265. -U $SQL_USER \
  266. $SQL_DB \
  267. -c "$1"
  268. }
  269. # input: sql query, optional mysql command-line params
  270. sql_ro_raw_query() {
  271. $PGSQL $2\
  272. -A -q -t \
  273. -P fieldsep=" " \
  274. -h $SQL_HOST \
  275. -U $SQL_USER \
  276. $SQL_DB \
  277. -c "$1"
  278. }
  279. usrloc() {
  280. if [ "$#" -lt 2 ] ; then
  281. echo "usrloc: too few parameters"
  282. exit 1
  283. fi
  284. if [ "$1" = "alias" ] ; then
  285. TABLE="$A_TABLE"
  286. elif [ "$1" = "ul" ] ; then
  287. TABLE="$USRLOC"
  288. else
  289. echo "usrloc: unknown table name"
  290. exit 1
  291. fi
  292. shift
  293. case $1 in
  294. show)
  295. if [ $# -eq 2 ] ; then
  296. fifo_cmd ul_show_contact $TABLE $2
  297. elif [ $# -eq 1 ] ; then
  298. fifo_cmd ul_dump
  299. else
  300. echo "wrong number of params for usrloc show"
  301. usage
  302. exit 1
  303. fi
  304. exit $?
  305. ;;
  306. add)
  307. if [ $# -ne 3 ] ; then
  308. usage
  309. exit 1
  310. fi
  311. shift
  312. check_uri "$2"
  313. if [ "$?" -ne "0" ] ; then
  314. echo "$2 is not a valid URI"
  315. exit 1
  316. fi
  317. fifo_cmd ul_add "$TABLE" "$1" "$2" "$FOREVER_REL" "1.00" "0"
  318. exit $?
  319. ;;
  320. rm)
  321. if [ $# -ne 2 ] ; then
  322. usage
  323. exit 1
  324. fi
  325. shift
  326. fifo_cmd ul_rm $TABLE $1
  327. ;;
  328. *)
  329. usage
  330. exit 1
  331. ;;
  332. esac
  333. }
  334. acl() {
  335. case $1 in
  336. show)
  337. if [ $# -eq 2 ] ; then
  338. is_user $2
  339. if [ $? -ne 0 ] ; then
  340. echo non-existent user
  341. exit 1;
  342. fi
  343. CLAUSE=" WHERE $ACL_USER_COLUMN='$2' "
  344. elif [ $# -ne 1 ] ; then
  345. usage
  346. exit 1
  347. fi
  348. QUERY="select * FROM $ACL_TABLE $CLAUSE ; "
  349. sql_ro_query "$QUERY"
  350. ;;
  351. grant)
  352. if [ $# -lt 3 ] ; then
  353. usage
  354. exit 1
  355. fi
  356. prompt_pw
  357. is_user $2
  358. if [ $? -ne 0 ] ; then
  359. echo non-existent user
  360. exit 1
  361. fi
  362. SIP_USER="$2"
  363. shift 2
  364. while [ $# -gt 0 ] ; do
  365. if [ $VERIFY_ACL -eq 1 ] ; then
  366. found=0
  367. for i in $ACL_GROUPS ; do
  368. if [ "$1" = "$i" ] ; then
  369. found=1
  370. break
  371. fi
  372. done
  373. if [ $found -eq 0 ] ; then
  374. echo "Invalid privilege: $1 ignored"
  375. shift
  376. continue
  377. fi
  378. fi
  379. QUERY="insert into $ACL_TABLE \
  380. ($ACL_USER_COLUMN,$ACL_GROUP_COLUMN,$ACL_MODIFIED_COLUMN) \
  381. values ('$SIP_USER','$1', now());"
  382. sql_query "$QUERY"
  383. if [ $? -ne 0 ] ; then
  384. echo "SQL Error"
  385. exit 1
  386. fi
  387. shift
  388. done
  389. $0 acl show $SIP_USER
  390. ;;
  391. revoke)
  392. if [ $# -eq 3 ] ; then
  393. CLAUSE=" and $ACL_GROUP_COLUMN='$3' "
  394. elif [ $# -ne 2 ] ; then
  395. usage
  396. exit 1
  397. fi
  398. QUERY="delete from $ACL_TABLE where \
  399. $ACL_TABLE.$ACL_USER_COLUMN='$2' $CLAUSE"
  400. sql_query "$QUERY"
  401. $0 acl show $2
  402. ;;
  403. *)
  404. usage
  405. exit 1
  406. ;;
  407. esac
  408. }
  409. # params: user
  410. # output: false if exists, true otherwise
  411. is_user() {
  412. QUERY="select count(*) from $TABLE \
  413. where $SUBSCRIBER_COLUMN='$1' and $REALM_COLUMN='$SIP_DOMAIN';"
  414. CNT=`sql_ro_raw_query "$QUERY" | grep -v ERROR | $LAST_LINE`
  415. if [ "0$CNT" -eq 0 ] ; then
  416. false
  417. else
  418. true
  419. fi
  420. }
  421. # params: user, password
  422. # output: HA1, HA1B
  423. credentials()
  424. {
  425. HA1=`$GENHA1 $1 $SIP_DOMAIN $2`
  426. if [ $? -ne 0 ] ; then
  427. echo "HA1 calculation failed"
  428. exit 1
  429. fi
  430. HA1B=`$GENHA1 "$1@$SIP_DOMAIN" $SIP_DOMAIN $2`
  431. if [ $? -ne 0 ] ; then
  432. echo "HA1B calculation failed"
  433. exit 1
  434. fi
  435. }
  436. #================================================================
  437. if [ -z "$SIP_DOMAIN" ] ; then
  438. echo
  439. echo "You need to set environment variable SIP_DOMAIN (e.g. to 'foobar.com') first"
  440. echo
  441. # This confuses new users cause its easy to miss the information above
  442. # usage
  443. exit 1
  444. fi
  445. # if the script calls itself ...
  446. export PW
  447. case $1 in
  448. start)
  449. DIR=`dirname $0`
  450. echo
  451. printf "Starting SER : "
  452. if [ -r $PID_FILE ] ; then
  453. echo "PID file exists! ($PID_FILE) already running?"
  454. exit 1
  455. else
  456. if [ $SYSLOG = 1 ] ; then
  457. $DIR/ser -P $PID_FILE $STARTOPTIONS 1>/dev/null 2>/dev/null
  458. else
  459. $DIR/ser -P $PID_FILE -E $STARTOPTIONS
  460. fi
  461. sleep 1
  462. echo "started pid(`cat $PID_FILE`)"
  463. fi
  464. exit 0
  465. ;;
  466. stop)
  467. printf "Stopping SER : "
  468. if [ -r $PID_FILE ] ; then
  469. kill `cat $PID_FILE`
  470. echo "stopped"
  471. else
  472. echo No PID file found!
  473. exit 1
  474. fi
  475. exit 0
  476. ;;
  477. restart)
  478. DIR=`dirname $0`
  479. printf "Stopping SER : "
  480. if [ -r $PID_FILE ] ; then
  481. kill `cat $PID_FILE`
  482. echo "stopped"
  483. else
  484. echo No PID file found! SER problably not running
  485. exit 1
  486. fi
  487. sleep 2
  488. printf "Starting SER : "
  489. if [ -r $PID_FILE ] ; then
  490. echo "PID file exists! ($PID_FILE) already running?"
  491. exit 1
  492. else
  493. if [ $SYSLOG = 1 ] ; then
  494. $DIR/ser -P $PID_FILE $STARTOPTIONS 1>/dev/null 2>/dev/null
  495. else
  496. $DIR/ser -P $PID_FILE -E $STARTOPTIONS
  497. fi
  498. sleep 1
  499. echo "started pid(`cat $PID_FILE`)"
  500. fi
  501. exit 0
  502. ;;
  503. passwd)
  504. if [ $# -ne 3 ] ; then
  505. usage
  506. exit 1
  507. fi
  508. shift
  509. credentials $1 $2
  510. prompt_pw
  511. is_user $1
  512. if [ $? -ne 0 ] ; then
  513. echo non-existent user
  514. exit 1
  515. fi
  516. QUERY="update $TABLE \
  517. set $HA1_COLUMN='$HA1', $HA1B_COLUMN='$HA1B', $PASSWORD_COLUMN='$2' \
  518. , $SUB_MODIFIED_COLUMN=now() \
  519. WHERE $SUBSCRIBER_COLUMN='$1' and $REALM_COLUMN='$SIP_DOMAIN';"
  520. sql_query "$QUERY"
  521. if [ $? -ne 0 ] ; then
  522. echo "password change failed"
  523. else
  524. echo "password change succeeded"
  525. fi
  526. ;;
  527. add)
  528. if [ $# -ne 4 ] ; then
  529. usage
  530. exit 1
  531. fi
  532. shift
  533. credentials $1 $2
  534. prompt_pw
  535. is_user $1
  536. if [ $? -eq 0 ] ; then
  537. echo user already exists
  538. exit 1
  539. fi
  540. QUERY="insert into $TABLE \
  541. ($SUBSCRIBER_COLUMN,$REALM_COLUMN,$HA1_COLUMN,\
  542. $HA1B_COLUMN,$PASSWORD_COLUMN,$EMAIL_COLUMN, $SUB_CREATED_COLUMN, \
  543. $PHP_LIB_COLUMN,datetime_modified ) \
  544. values ('$1','$SIP_DOMAIN','$HA1','$HA1B','$2', '$3', now(), '$HA1', now() );";
  545. sql_query "$QUERY"
  546. if [ $? -ne 0 ] ; then
  547. echo "introducing a new user to the database failed"
  548. else
  549. echo "new user added"
  550. fi
  551. ;;
  552. monitor|console|moni|con)
  553. name=ser_receiver_$$
  554. path=/tmp/$name
  555. if [ ! -w $SER_FIFO ]; then
  556. echo "Error opening ser's FIFO $SER_FIFO"
  557. echo "Make sure you have line fifo=$SER_FIFO in your config"
  558. exit 1
  559. fi
  560. mkfifo $path
  561. if [ $? -ne 0 ] ; then
  562. echo "error opening read fifo $path"
  563. exit 1
  564. fi
  565. trap "rm $path; clear; echo sc monitor ^C-ed; exit 1" 2
  566. attempt=0
  567. clear
  568. while [ 1 -eq 1 ]; do
  569. attempt=`expr $attempt + 1`
  570. #clear
  571. tput cup 0 0
  572. print_stats $name $path $attempt
  573. sleep $WATCH_PERIOD
  574. done
  575. rm $path
  576. exit 0
  577. ;;
  578. mail)
  579. if [ $# -ne 2 ] ; then
  580. usage
  581. exit 1
  582. fi
  583. shift
  584. QUERY="select $TABLE.$EMAIL_COLUMN from $TABLE where \
  585. $TABLE.$SUBSCRIBER_COLUMN='$1'"
  586. EA=`sql_ro_raw_query "$QUERY" "-B" | grep -v ERROR | $LAST_LINE`
  587. if [ $? -ne 0 ] ; then
  588. echo "MySql query failed"
  589. exit 1
  590. fi
  591. echo "Write email to $1: $EA now ..."
  592. mail -s "Message from $SIP_DOMAIN SIP admin" $EA
  593. if [ $? -eq 0 ] ; then
  594. echo message sent
  595. else
  596. echo sending message failed
  597. fi
  598. ;;
  599. alias|ul)
  600. usrloc "$@"
  601. ;;
  602. online)
  603. fifo_cmd ul_dump |grep aor| awk '{print $3}' | sort | sort -mu
  604. exit $?
  605. ;;
  606. showdb|userdb)
  607. if [ $# -eq 2 ] ; then
  608. is_user $2
  609. if [ $? -ne 0 ] ; then
  610. echo non-existent user
  611. exit 1;
  612. fi
  613. elif [ $# -ne 1 ] ; then
  614. usage
  615. exit 1
  616. fi
  617. shift
  618. QUERY1="select $TABLE.$EMAIL_COLUMN from $TABLE where \
  619. $TABLE.$SUBSCRIBER_COLUMN='$1'"
  620. QUERY2="select $USRLOC.* from $USRLOC where \
  621. $USRLOC.$USER_COLUMN='$1' order by expires desc"
  622. QUERY3="select $USRLOC.$USER_COLUMN, $TABLE.$EMAIL_COLUMN, $USRLOC.$CALLID_COLUMN \
  623. from $TABLE, $USRLOC where \
  624. $TABLE.$SUBSCRIBER_COLUMN=$USRLOC.$USER_COLUMN order by $USRLOC.$USER_COLUMN"
  625. if [ $# -eq 1 ] ; then
  626. sql_ro_query "$QUERY1"
  627. sql_ro_query "$QUERY2"
  628. else
  629. sql_ro_query "$QUERY3"
  630. fi
  631. echo "Note: Due to usage of cache, server's list " \
  632. "may differ from DB list."
  633. ;;
  634. rm)
  635. if [ $# -ne 2 ] ; then
  636. usage
  637. exit 1
  638. fi
  639. shift
  640. prompt_pw
  641. is_user $1
  642. if [ $? -ne 0 ] ; then
  643. echo non-existent user
  644. exit 1
  645. fi
  646. QUERY="delete from $TABLE where $TABLE.$SUBSCRIBER_COLUMN='$1'"
  647. sql_query "$QUERY"
  648. $0 acl revoke $1 > /dev/null 2>&1
  649. $0 dul $1 > /dev/null 2>&1
  650. ;;
  651. ps)
  652. fifo_cmd ps
  653. ;;
  654. acl)
  655. shift
  656. acl "$@"
  657. ;;
  658. fifo)
  659. shift
  660. fifo_cmd "$@"
  661. ;;
  662. version)
  663. echo "$0 $VERSION"
  664. ;;
  665. *)
  666. usage
  667. exit 1
  668. ;;
  669. esac