1#!/bin/sh 2###################################################################### 3# 4# $Id: webjob-create-profile,v 1.89 2012/01/07 08:01:17 mavrik Exp $ 5# 6###################################################################### 7# 8# Copyright 2007-2012 The WebJob Project, All Rights Reserved. 9# 10###################################################################### 11# 12# Purpose: Create a WebJob profile. 13# 14###################################################################### 15 16IFS=' 17' 18 19PROGRAM=`basename ${0}` 20 21umask 027 22 23###################################################################### 24# 25# VerifyPassword 26# 27###################################################################### 28 29VerifyPassword() 30{ 31 MY_ARG_CLIENT_ID=${1} 32 MY_ARG_PASSWORD=${2} 33 MY_ARG_HTUSERS_ENTRY=${3} 34 35 MY_TARGET_PASSWORD_HASH=`echo "${MY_ARG_HTUSERS_ENTRY}" | sed "s/^${MY_ARG_CLIENT_ID}://; s/^LOCKED//;"` 36 37 case "${MY_TARGET_PASSWORD_HASH}" in 38 \$apr1\$*) 39 MY_ACTUAL_PASSWORD_HASH=`perl -e 'use Crypt::PasswdMD5; print apache_md5_crypt(q('${MY_ARG_PASSWORD}'), q('${MY_TARGET_PASSWORD_HASH}')), "\n";'` 40 ;; 41 [0-9A-Za-z./][0-9A-Za-z./]*) 42 MY_ACTUAL_PASSWORD_HASH=`perl -e 'print crypt(q('${MY_ARG_PASSWORD}'), q('${MY_TARGET_PASSWORD_HASH}')), "\n";'` 43 ;; 44 *) 45 return 1 46 ;; 47 esac 48 49 if [ X"${MY_ACTUAL_PASSWORD_HASH}" = X"${MY_TARGET_PASSWORD_HASH}" ] ; then 50 return 0 51 fi 52 53 return 1 54} 55 56###################################################################### 57# 58# VerifyPrograms 59# 60###################################################################### 61 62VerifyPrograms() 63{ 64 MY_PROGRAMS=" 65htpasswd 66perl 67webjob-cfg-get-kvps 68webjob-cfg-update-list 69webjob-dsvtool 70webjob-jqd-create-queue 71webjob-jqd-list-members 72webjob-jqd-update-group 73webjob-mldbm-create-client 74webjob-mldbm-get-config-kvps 75webjob-mldbm-set-config-kvps 76" 77 MY_DIRS=`echo "${PATH}" | sed 's/:/ /g;'` 78 79 for MY_PROGRAM in ${MY_PROGRAMS} ; do 80 MY_PROGRAM_FOUND=0 81 for MY_DIR in ${MY_DIRS} ; do 82 MY_TEST_PATH="${MY_DIR}/${MY_PROGRAM}" 83 if [ -x ${MY_TEST_PATH} ] ; then 84 MY_PROGRAM_FOUND=1 85 break; 86 fi 87 done 88 if [ ${MY_PROGRAM_FOUND} -ne 1 ] ; then 89 echo "${PROGRAM}: Error='Unable to locate an executable instance of ${MY_PROGRAM} in the current PATH (${PATH}).'" 1>&2 90 exit 2 91 fi 92 done 93} 94 95###################################################################### 96# 97# Usage 98# 99###################################################################### 100 101Usage() 102{ 103 echo 1>&2 104 echo "${PROGRAM} [-C webjob-client-home] [-e {plain|base64}] [-g jqd-group[,jqd-group[...]]] [-H webjob-home] [-h host] [-i ip] [-n webjob-server-cn] [-o option[,option[,...]]] [-P password] [-r registration-code] [-S webjob-server-home] [-s webjob-server] [-T timeslot] -p {unix|winx} -c client [key=value [...]]" 1>&2 105 echo 1>&2 106 exit 1 107} 108 109###################################################################### 110# 111# Main 112# 113###################################################################### 114 115CLIENT_HOSTNAME="" 116 117CLIENT_IP="" 118 119ENCODING="base64" 120 121JQD_GROUP_LIST="" 122 123OPTIONS="" 124 125PASSWORD="" 126 127PASSWORD_SPECIFIED="0" 128 129PLATFORM="" 130 131TIMESLOT="" 132 133WEBJOB_CLIENT_HOME="" 134 135WEBJOB_REGISTRATION_CODE="" 136 137WEBJOB_SERVER="" 138 139WEBJOB_SERVER_CLIENT_HOME="/usr/local/webjob" 140 141WEBJOB_SERVER_CN="" 142 143WEBJOB_SERVER_HOME="/var/webjob" 144 145while getopts "C:c:e:g:H:h:i:n:o:P:p:r:S:s:T:" OPTION ; do 146 case "${OPTION}" in 147 C) 148 WEBJOB_CLIENT_HOME="${OPTARG}" 149 ;; 150 c) 151 CLIENT_ID="${OPTARG}" 152 ;; 153 e) 154 ENCODING="${OPTARG}" 155 ;; 156 g) 157 JQD_GROUP_LIST="${OPTARG}" 158 ;; 159 H) 160 WEBJOB_HOME="${OPTARG}" 161 ;; 162 h) 163 CLIENT_HOSTNAME="${OPTARG}" 164 ;; 165 i) 166 CLIENT_IP="${OPTARG}" 167 ;; 168 n) 169 WEBJOB_SERVER_CN="${OPTARG}" 170 ;; 171 o) 172 OPTIONS="${OPTARG}" 173 ;; 174 P) 175 PASSWORD="${OPTARG}" 176 PASSWORD_SPECIFIED="1" 177 ;; 178 p) 179 PLATFORM="${OPTARG}" 180 ;; 181 r) 182 WEBJOB_REGISTRATION_CODE="${OPTARG}" 183 ;; 184 S) 185 WEBJOB_SERVER_HOME="${OPTARG}" 186 ;; 187 s) 188 WEBJOB_SERVER="${OPTARG}" 189 ;; 190 T) 191 TIMESLOT="${OPTARG}" 192 ;; 193 *) 194 Usage 195 ;; 196 esac 197done 198 199shift `expr ${OPTIND} - 1` 200 201if [ -z "${CLIENT_ID}" ] ; then 202 Usage 203fi 204 205case "${ENCODING}" in 206[Pp][Ll][Aa][Ii][Nn]) 207 ENCODING="plain" 208 ;; 209[Bb][Aa][Ss][Ee]64) 210 ENCODING="base64" 211 ;; 212*) 213 Usage 214 ;; 215esac 216 217case "${PLATFORM}" in 218[Uu][Nn][Ii][Xx]) 219 OS_CLASS="UNIX" 220 PLATFORM="unix" 221 if [ -z "${WEBJOB_CLIENT_HOME}" ] ; then 222 WEBJOB_CLIENT_HOME='/usr/local/webjob' 223 fi 224 ;; 225[Ww][Ii][Nn][Xx]) 226 OS_CLASS="WINX" 227 PLATFORM="winx" 228 if [ -z "${WEBJOB_CLIENT_HOME}" ] ; then 229 WEBJOB_CLIENT_HOME='c:\\webjob' 230 fi 231 ;; 232*) 233 Usage 234 ;; 235esac 236 237if [ -n "${TIMESLOT}" ] ; then 238 echo "${TIMESLOT}" | egrep "^([0-9]|[1-2][0-9])$" > /dev/null 2>&1 239 if [ $? -ne 0 ] ; then 240 echo "${PROGRAM}: Error='Timeslot (${TIMESLOT}) does not pass muster. A value in the range [0-29] is required.'" 1>&2 241 exit 2 242 fi 243fi 244 245if [ -n "${WEBJOB_REGISTRATION_CODE}" ] ; then 246 perl -e 'exit(($ARGV[0] =~ /^[0-9A-Za-z]{5}(-[0-9A-Za-z]{5}){2,11}$/) ? 0 : 1);' "${WEBJOB_REGISTRATION_CODE}" > /dev/null 2>&1 247 if [ $? -ne 0 ] ; then 248 echo "${PROGRAM}: Error='The registration code (${WEBJOB_REGISTRATION_CODE}) not pass muster.'" 1>&2 249 exit 2 250 fi 251fi 252 253PATH=${WEBJOB_HOME=/usr/local/webjob}/bin:${PATH} ; export PATH 254 255VerifyPrograms 256 257if [ ! -d "${WEBJOB_SERVER_HOME}" ] ; then 258 echo "${PROGRAM}: Error='Server home directory (${WEBJOB_SERVER_HOME}) does not exist.'" 1>&2 259 exit 2 260fi 261 262WEBJOB_SERVER_CONFIG_FILE="${WEBJOB_SERVER_HOME}/config/server.cfg" 263if [ ! -f "${WEBJOB_SERVER_CONFIG_FILE}" ] ; then 264 echo "${PROGRAM}: Error='Server config file (${WEBJOB_SERVER_CONFIG_FILE}) does not exist.'" 1>&2 265 exit 2 266fi 267 268HOSTNAME=`webjob-cfg-get-kvps -t webjob.server -f ${WEBJOB_SERVER_CONFIG_FILE} -o BeQuiet,ValuesOnly Hostname` 269if [ -z "${HOSTNAME}" ] ; then 270 HOSTNAME=`hostname` 271fi 272 273if [ -z "${WEBJOB_SERVER}" ] ; then 274 WEBJOB_SERVER="${HOSTNAME}" 275 if [ -z "${WEBJOB_SERVER}" ] ; then 276 echo "${PROGRAM}: Error='Unable to determine hostname. Use the \"-s\" option to specify the server hostname or IP address.'" 1>&2 277 exit 2 278 fi 279fi 280 281if [ -z "${WEBJOB_SERVER_CN}" ] ; then 282 WEBJOB_SERVER_CN="${HOSTNAME}" 283 if [ -z "${WEBJOB_SERVER_CN}" ] ; then 284 echo "${PROGRAM}: Error='Unable to determine hostname. Use the \"-n\" option to specify the server common name.'" 1>&2 285 exit 2 286 fi 287fi 288 289WWW_OWNER=`webjob-cfg-get-kvps -t webjob.server -f ${WEBJOB_SERVER_CONFIG_FILE} -o BeQuiet,ValuesOnly ApacheOwner` 290if [ -z "${WWW_OWNER}" ] ; then 291 WWW_OWNER="www" 292fi 293WWW_OWNER_TEST=`awk -F: '{print $1}' /etc/passwd | egrep "${WWW_OWNER}"` 294if [ -z "${WWW_OWNER_TEST}" ] ; then 295 echo "${PROGRAM}: Error='Unable to verify that \"${WWW_OWNER}\" is a valid owner. Make sure that ApacheOwner is set properly in ${WEBJOB_SERVER_CONFIG_FILE}.'" 1>&2 296 exit 2 297fi 298 299WWW_GROUP=`webjob-cfg-get-kvps -t webjob.server -f ${WEBJOB_SERVER_CONFIG_FILE} -o BeQuiet,ValuesOnly ApacheGroup` 300if [ -z "${WWW_GROUP}" ] ; then 301 WWW_GROUP="www" 302fi 303WWW_GROUP_TEST=`awk -F: '{print $1}' /etc/group | egrep "${WWW_GROUP}"` 304if [ -z "${WWW_GROUP_TEST}" ] ; then 305 echo "${PROGRAM}: Error='Unable to verify that \"${WWW_GROUP}\" is a valid group. Make sure that ApacheGroup is set properly in ${WEBJOB_SERVER_CONFIG_FILE}.'" 1>&2 306 exit 2 307fi 308 309if [ -z "${CLIENT_HOSTNAME}" ] ; then 310 CLIENT_HOSTNAME=`echo "${CLIENT_ID}" | sed 's/^client_//;' | awk -F. '{print $1}'` 311 if [ -z "${CLIENT_HOSTNAME}" ] ; then 312 echo "${PROGRAM}: Error='Unable to derive hostname. Use the \"-h\" option to specify the client hostname.'" 1>&2 313 exit 2 314 fi 315fi 316 317###################################################################### 318# 319# Ensure that all prerequisites exist. Any error is considered fatal 320# since it implies that the server's configuration is not complete. 321# 322###################################################################### 323 324HTUSERS_FILE="${WEBJOB_SERVER_HOME}/config/apache/ht-client" 325if [ ! -f "${HTUSERS_FILE}" ] ; then 326 echo "${PROGRAM}: Error='Password file (${HTUSERS_FILE}) does not exist.'" 1>&2 327 exit 2 328fi 329 330NPH_CONFIG_CONFIG_DIR="${WEBJOB_SERVER_HOME}/config/nph-config" 331if [ ! -d "${NPH_CONFIG_CONFIG_DIR}" ] ; then 332 echo "${PROGRAM}: Error='Override directory (${NPH_CONFIG_CONFIG_DIR}) does not exist.'" 1>&2 333 exit 2 334fi 335 336NPH_CONFIG_HOST_ACCESS_FILE="${WEBJOB_SERVER_HOME}/config/nph-config/nph-config-hosts.access" 337if [ ! -f "${NPH_CONFIG_HOST_ACCESS_FILE}" ] ; then 338 echo "${PROGRAM}: Error='Host access file (${NPH_CONFIG_HOST_ACCESS_FILE}) for nph-config.cgi does not exist.'" 1>&2 339 exit 2 340fi 341 342NPH_WEBJOB_CONFIG_DIR="${WEBJOB_SERVER_HOME}/config/nph-webjob" 343if [ ! -d "${NPH_WEBJOB_CONFIG_DIR}" ] ; then 344 echo "${PROGRAM}: Error='Override directory (${NPH_WEBJOB_CONFIG_DIR}) does not exist.'" 1>&2 345 exit 2 346fi 347 348NPH_WEBJOB_HOST_ACCESS_FILE="${WEBJOB_SERVER_HOME}/config/nph-webjob/nph-webjob-hosts.access" 349if [ ! -f "${NPH_WEBJOB_HOST_ACCESS_FILE}" ] ; then 350 echo "${PROGRAM}: Error='Host access file (${NPH_WEBJOB_HOST_ACCESS_FILE}) for nph-webjob.cgi does not exist.'" 1>&2 351 exit 2 352fi 353 354WEBJOB_CLIENT_DB="${WEBJOB_SERVER_HOME}/db/mldbm/client.db" 355if [ ! -f "${WEBJOB_CLIENT_DB}" ] ; then 356 echo "${PROGRAM}: Error='Client DB (${WEBJOB_CLIENT_DB}) does not exist.'" 1>&2 357 exit 2 358fi 359 360WEBJOB_GROUP_FILE="${WEBJOB_SERVER_HOME}/config/jqd/groups" 361if [ ! -f "${WEBJOB_GROUP_FILE}" ] ; then 362 echo "${PROGRAM}: Error='Group file (${WEBJOB_GROUP_FILE}) does not exist.'" 1>&2 363 exit 2 364fi 365 366WEBJOB_JQD_DIR="${WEBJOB_SERVER_HOME}/spool/jqd" 367if [ ! -d "${WEBJOB_JQD_DIR}" ] ; then 368 echo "${PROGRAM}: Error='JQD directory (${WEBJOB_JQD_DIR}) does not exist.'" 1>&2 369 exit 2 370fi 371 372WEBJOB_PROFILES_DIR="${WEBJOB_SERVER_HOME}/profiles" 373if [ ! -d "${WEBJOB_PROFILES_DIR}" ] ; then 374 echo "${PROGRAM}: Error='Profiles directory (${WEBJOB_PROFILES_DIR}) does not exist.'" 1>&2 375 exit 2 376fi 377 378WEBJOB_SKEL_DIR="${WEBJOB_SERVER_HOME}/config/skel" 379if [ ! -d "${WEBJOB_SKEL_DIR}" ] ; then 380 echo "${PROGRAM}: Error='Skeleton directory (${WEBJOB_SKEL_DIR}) does not exist.'" 1>&2 381 exit 2 382fi 383 384 #################################################################### 385 # 386 # Parse the options list. 387 # 388 #################################################################### 389 390 FORCE="0" 391 392 FORCE_PASSWORD="0" 393 394 LOCAL_PROFILE="0" 395 396 LOCK_PROFILE="0" 397 398 for OPTION in `echo "${OPTIONS}" | sed 's/,/ /g;' | tr '[A-Z]' '[a-z]'` ; do 399 case "${OPTION}" in 400 force) 401 FORCE="1" 402 ;; 403 forcepassword) 404 FORCE_PASSWORD="1" 405 ;; 406 localprofile) 407 LOCAL_PROFILE="1" 408 ;; 409 lockprofile) 410 LOCK_PROFILE="1" 411 ;; 412 esac 413 done 414 415###################################################################### 416# 417# Do some work. 418# 419###################################################################### 420 421MY_ERROR_FLAG=0 422 423 #################################################################### 424 # 425 # Do a sanity check on the client ID. 426 # 427 #################################################################### 428 429 MY_CLIENT_ID_OK=`echo ${CLIENT_ID} | perl -n -e 'if ($_ =~ /^(?:[A-Za-z](?:(?:[0-9A-Za-z]|[_-](?=[^.]))){0,62})(?:[.][A-Za-z](?:(?:[0-9A-Za-z]|[_-](?=[^.]))){0,62}){0,127}$/) { print "pass\n"; } else { print "fail\n"; }'` 430 431 if [ x"${MY_CLIENT_ID_OK}" != x"pass" ] ; then 432 echo "${PROGRAM}: Error='Client ID (${CLIENT_ID}) does not pass muster. The profile will not be created.'" 1>&2 433 exit 2 434 fi 435 436 #################################################################### 437 # 438 # Conditionally generate a password, and update the htusers file. 439 # If the htusers file already has an entry for this client and no 440 # password was specified and the force option is disabled, abort -- 441 # blindly updating the htusers file with a new password could lock 442 # out existing clients. If a password was specified, then assume 443 # that user wants the htusers file to be updated. 444 # 445 #################################################################### 446 447 if [ ${PASSWORD_SPECIFIED} -eq 0 -a -n "${WEBJOB_PASSWORD}" ] ; then 448 PASSWORD="${WEBJOB_PASSWORD}" 449 PASSWORD_SPECIFIED="1" 450 fi 451 452 if [ ${PASSWORD_SPECIFIED} -eq 1 ] ; then 453 if [ -n "${PASSWORD}" ] ; then 454 echo "${PASSWORD}" | egrep "^0:[0-9A-Za-z/+]+={0,2}$" > /dev/null 2>&1 455 if [ $? -eq 0 ] ; then 456 MY_PASSWORD=`echo "${PASSWORD}" | perl -p -e 'use MIME::Base64; chomp; $_=~ s/^0://; $_=decode_base64($_);'` 457 else 458 MY_PASSWORD=${PASSWORD} 459 fi 460 else 461 : # Empty passwords are not allowed. This error will be caught below. 462 fi 463 else 464 MY_PASSWORD=`webjob-dsvtool -p` 465 fi 466 467 echo "${MY_PASSWORD}" | egrep "^[0-9A-Za-z/+]{8,}$" > /dev/null 2>&1 468 if [ $? -ne 0 ] ; then 469 echo "${PROGRAM}: Error='The password for ${CLIENT_ID} does not pass muster. The profile will not be created.'" 1>&2 470 exit 2 471 fi 472 473 MY_HTUSERS_ENTRY=`egrep "^${CLIENT_ID}:" ${HTUSERS_FILE} 2> /dev/null` 474 if [ -n "${MY_HTUSERS_ENTRY}" ] ; then 475 if [ ${FORCE_PASSWORD} -eq 0 ] ; then 476 if [ ${PASSWORD_SPECIFIED} -eq 1 ] ; then 477 VerifyPassword "${CLIENT_ID}" "${MY_PASSWORD}" "${MY_HTUSERS_ENTRY}" 478 if [ $? -ne 0 ] ; then 479 echo "${PROGRAM}: Error='Client (${CLIENT_ID}) already has an htusers entry, and the supplied password is not correct.'" 1>&2 480 exit 4 # XER_PasswordRequired 481 fi 482 else 483 echo "${PROGRAM}: Error='Client (${CLIENT_ID}) already has an htusers entry. To continue, either supply the current password with the \"-P\" option or use the \"ForcePassword\" option to force a password update.'" 1>&2 484 exit 4 # XER_PasswordRequired 485 fi 486 fi 487 fi 488 489 echo "Updating ${HTUSERS_FILE}" 490 491 if [ ${LOCK_PROFILE} -eq 1 ] ; then 492 MY_NEW_HTUSERS_ENTRY=`htpasswd -b -m -n ${CLIENT_ID} ${MY_PASSWORD} | sed "s/^${CLIENT_ID}:/${CLIENT_ID}:LOCKED/;"` 493 else 494 MY_NEW_HTUSERS_ENTRY=`htpasswd -b -m -n ${CLIENT_ID} ${MY_PASSWORD}` 495 fi 496 if [ -n "${MY_NEW_HTUSERS_ENTRY}" ] ; then 497 webjob-cfg-set-kvps -d : -f ${HTUSERS_FILE} "${MY_NEW_HTUSERS_ENTRY}" 498 if [ $? -ne 0 ] ; then 499 echo "${PROGRAM}: Error='Unable to set password for ${CLIENT_ID}.'" 1>&2 500 MY_ERROR_FLAG=1 501 fi 502 fi 503 504 if [ x"${ENCODING}" = x"base64" ] ; then 505 MY_ENCODED_PASSWORD=`echo "${MY_PASSWORD}" | perl -p -e 'use MIME::Base64; chomp; $_="0:".encode_base64($_);'` 506 else 507 MY_ENCODED_PASSWORD=${MY_PASSWORD} 508 fi 509 510 #################################################################### 511 # 512 # Create the profile tree. 513 # 514 #################################################################### 515 516 MY_PROFILE_DIR="${WEBJOB_PROFILES_DIR}/${CLIENT_ID}" 517 518 MY_ETC_DIR="${MY_PROFILE_DIR}/etc" 519 520 MY_COMMANDS_DIR="${MY_PROFILE_DIR}/commands" 521 522 MY_CONFIGS_DIR="${MY_PROFILE_DIR}/configs" 523 524 MY_CONTENT_DIR="${MY_PROFILE_DIR}/content" 525 526 MY_DSV_DIR="${MY_PROFILE_DIR}/dsv" 527 528 MY_HOOKS_DIR="${MY_PROFILE_DIR}/hooks" 529 530 MY_RUN_DIR="${MY_PROFILE_DIR}/run" 531 532 MY_TRIGGERS_DIR="${MY_PROFILE_DIR}/triggers" 533 534 MY_WORKERS_DIR="${MY_PROFILE_DIR}/workers" 535 536 MY_DIRS=" 537${MY_PROFILE_DIR} 538${MY_ETC_DIR} 539${MY_COMMANDS_DIR} 540${MY_CONFIGS_DIR} 541${MY_CONTENT_DIR} 542${MY_HOOKS_DIR} 543${MY_TRIGGERS_DIR} 544${MY_WORKERS_DIR} 545" 546 547 if [ ${LOCAL_PROFILE} -eq 1 ] ; then 548 MY_DIRS="${MY_DIRS} ${MY_DSV_DIR} ${MY_RUN_DIR}" 549 fi 550 551 for MY_DIR in ${MY_DIRS} ; do 552 if [ ! -d "${MY_DIR}" ] ; then 553 echo "Creating ${MY_DIR}" 554 mkdir -p ${MY_DIR} 555 if [ $? -ne 0 ] ; then 556 echo "${PROGRAM}: Error='Encountered a problem while creating ${MY_DIR}.'" 1>&2 557 MY_ERROR_FLAG=1 558 fi 559 else 560 echo "Skipping ${MY_DIR} (already exists)" 561 fi 562 done 563 564 if [ ${LOCAL_PROFILE} -eq 1 ] ; then 565 chmod 700 ${MY_RUN_DIR} 566 fi 567 568 #################################################################### 569 # 570 # Create symlinks to support local profiles. 571 # 572 #################################################################### 573 574 if [ ${LOCAL_PROFILE} -eq 1 ] ; then 575 for MY_DIR in "bin" ; do 576 MY_SYMLINK="${MY_PROFILE_DIR}/${MY_DIR}" 577 if [ ! -L "${MY_SYMLINK}" ] ; then 578 echo "Creating ${MY_SYMLINK}" 579 if [ ${FORCE} -eq 1 ] ; then 580 MY_LN_OPTS="-f" 581 else 582 MY_LN_OPTS="" 583 fi 584 ln -s ${MY_LN_OPTS} ${WEBJOB_SERVER_CLIENT_HOME}/${MY_DIR} ${MY_SYMLINK} 585 if [ $? -ne 0 ] ; then 586 echo "${PROGRAM}: Error='Encountered a problem while creating config symlink for ${CLIENT_ID}.'" 1>&2 587 MY_ERROR_FLAG=1 588 fi 589 fi 590 done 591 fi 592 593 #################################################################### 594 # 595 # Create config files. 596 # 597 #################################################################### 598 599 WEBJOB_CLIENT_HOME_ESCAPED=`echo "${WEBJOB_CLIENT_HOME}" | perl -p -e 's,(\x5c),$1$1,g;'` 600 601 for MY_EXT in "-a" "-b" ; do 602 for MY_NAME in "upload" ; do 603 MY_FILE=${MY_NAME}${MY_EXT}.cfg 604 MY_CONFIG_FILE="${MY_ETC_DIR}/${MY_FILE}" 605 MY_SKEL_CONFIG_FILE="${WEBJOB_SKEL_DIR}/${MY_NAME}-${PLATFORM}${MY_EXT}.cfg" 606 if [ -f "${MY_SKEL_CONFIG_FILE}" ] ; then 607 if [ ! -f ${MY_CONFIG_FILE} -o ${FORCE} -eq 1 -o ${FORCE_PASSWORD} -eq 1 ] ; then 608 echo "Creating ${MY_CONFIG_FILE}" 609 # Note that %sample_client_home must be replaced before %sample_client to prevent unwanted substitutions. 610 # Note that %sample_server_cn must be replaced before %sample_server to prevent unwanted substitutions. 611 sed \ 612 -e "s#%sample_password#${MY_ENCODED_PASSWORD}#g;" \ 613 -e "s#%sample_client_home#${WEBJOB_CLIENT_HOME_ESCAPED}#g;" \ 614 -e "s#%sample_client#${CLIENT_ID}#g;" \ 615 -e "s#%sample_server_cn#${WEBJOB_SERVER_CN}#g;" \ 616 -e "s#%sample_server#${WEBJOB_SERVER}#g;" \ 617 ${MY_SKEL_CONFIG_FILE} > ${MY_CONFIG_FILE} 618 if [ $? -ne 0 ] ; then 619 echo "${PROGRAM}: Error='Encountered a problem while creating ${MY_FILE} for ${CLIENT_ID}.'" 1>&2 620 MY_ERROR_FLAG=1 621 fi 622 else 623 echo "Skipping ${MY_CONFIG_FILE} (already exists)" 624 fi 625 fi 626 done 627 done 628 629 for MY_EXT in "-a" "-b" ; do 630 for MY_NAME in "upload" ; do 631 MY_FILE=${MY_NAME}${MY_EXT}.ptr 632 MY_CONFIG_FILE="${MY_ETC_DIR}/${MY_FILE}" 633 MY_SKEL_CONFIG_FILE="${WEBJOB_SKEL_DIR}/${MY_NAME}-${PLATFORM}${MY_EXT}.ptr" 634 if [ -f "${MY_SKEL_CONFIG_FILE}" ] ; then 635 if [ ! -f ${MY_CONFIG_FILE} -o ${FORCE} -eq 1 ] ; then 636 echo "Creating ${MY_CONFIG_FILE}" 637 sed \ 638 -e "s#%sample_client_home#${WEBJOB_CLIENT_HOME_ESCAPED}#g;" \ 639 ${MY_SKEL_CONFIG_FILE} > ${MY_CONFIG_FILE} 640 if [ $? -ne 0 ] ; then 641 echo "${PROGRAM}: Error='Encountered a problem while creating ${MY_FILE} for ${CLIENT_ID}.'" 1>&2 642 MY_ERROR_FLAG=1 643 fi 644 else 645 echo "Skipping ${MY_CONFIG_FILE} (already exists)" 646 fi 647 fi 648 done 649 done 650 651 MY_NAME="upload" 652 MY_FILE="${MY_NAME}.cfg" 653 MY_CONFIG_FILE="${MY_ETC_DIR}/${MY_FILE}" 654 CONFIG_POINTER=`webjob-mldbm-get-config-kvps -d ${WEBJOB_CLIENT_DB} -c ${CLIENT_ID} -o BeQuiet,ValuesOnly ConfigPointer | tr '[a-z]' '[A-Z]'` 655 if [ X"${CONFIG_POINTER}" = X"B" ] ; then 656 MY_POINTER_FILE="${MY_ETC_DIR}/${MY_NAME}-b.ptr" 657 else 658 CONFIG_POINTER="A" 659 MY_POINTER_FILE="${MY_ETC_DIR}/${MY_NAME}-a.ptr" 660 fi 661 if [ ! -f ${MY_CONFIG_FILE} -o ${FORCE} -eq 1 ] ; then 662 echo "Creating ${MY_CONFIG_FILE}" 663 cp -p ${MY_POINTER_FILE} ${MY_CONFIG_FILE} 664 if [ $? -ne 0 ] ; then 665 echo "${PROGRAM}: Error='Encountered a problem while creating ${MY_FILE} for ${CLIENT_ID}.'" 1>&2 666 MY_ERROR_FLAG=1 667 fi 668 else 669 echo "Skipping ${MY_CONFIG_FILE} (already exists)" 670 fi 671 672 #################################################################### 673 # 674 # Find the next timeslot, and write it to a timeslot file. Use a 675 # default value of zero for local profiles. Also, do not use local 676 # timeslot values when computing the timeslot for a given (remote) 677 # client. 678 # 679 #################################################################### 680 681 if [ ${LOCAL_PROFILE} -eq 1 -a -z "${TIMESLOT}" ] ; then 682 TIMESLOT=0 683 fi 684 685 if [ -n "${TIMESLOT}" ] ; then 686 MY_TIMESLOT=${TIMESLOT} 687 else 688 MY_TIMESLOT_FILES="" 689 for MY_CLIENT in `webjob-jqd-list-members -G ${WEBJOB_GROUP_FILE} -i %all -e %all_local` ; do 690 MY_TIMESLOT_FILE="${WEBJOB_PROFILES_DIR}/${MY_CLIENT}/workers/hourly.cfg" 691 if [ -f "${MY_TIMESLOT_FILE}" ] ; then 692 MY_TIMESLOT_FILES="${MY_TIMESLOT_FILES} ${MY_TIMESLOT_FILE}" 693 fi 694 done 695 if [ -n "${MY_TIMESLOT_FILES}" ] ; then 696 MY_TIMESLOT=`\ 697 { 698 egrep -h '^Minute=[0-9][0-9]?$' ${MY_TIMESLOT_FILES} 2> /dev/null | awk -F= '{print $2}' 2> /dev/null; 699 perl -e 'for ($i=0; $i<=29; $i++){printf("%d\n", $i)}' ; 700 } | sort | uniq -c | sort -n -k 1 -k 2 | sed '1!d;' | awk '{print $2}'` 701 fi 702 echo "${MY_TIMESLOT}" | egrep "^([0-9]|[1-2][0-9])$" > /dev/null 2>&1 703 if [ $? -ne 0 ] ; then 704 MY_TIMESLOT="0" 705 fi 706 fi 707 708 MY_DAY_OF_WEEK="*" 709 MY_DAY_OF_MONTH="*" 710 MY_MONTH="*" 711 for MY_NAME in "hourly" "daily" ; do 712 if [ X"${MY_NAME}" = X"hourly" ] ; then 713 MY_MINUTE="${MY_TIMESLOT}" 714 MY_HOUR="*" 715 else 716 MY_MINUTE=`expr ${MY_TIMESLOT} + 30` 717 MY_HOUR="0" 718 fi 719 MY_FILE="${MY_NAME}.cfg" 720 MY_WORKERS_FILE="${MY_WORKERS_DIR}/${MY_FILE}" 721 MY_SKEL_WORKERS_FILE="${WEBJOB_SKEL_DIR}/worker-${MY_NAME}-${PLATFORM}.cfg" 722 if [ -f "${MY_SKEL_WORKERS_FILE}" ] ; then 723 if [ ! -f ${MY_WORKERS_FILE} -o ${FORCE} -eq 1 ] ; then 724 echo "Creating ${MY_WORKERS_FILE}" 725 # Note that %wjcd_home is intended for the end system, but it conflicts with %w, so it must be handled as a special case. 726 sed \ 727 -e "s#%wjcd_home#%escaped_wjcd_home#g;" \ 728 -e "s#%M#${MY_MINUTE}#g;" \ 729 -e "s#%H#${MY_HOUR}#g;" \ 730 -e "s#%w#${MY_DAY_OF_WEEK}#g;" \ 731 -e "s#%d#${MY_DAY_OF_MONTH}#g;" \ 732 -e "s#%m#${MY_MONTH}#g;" \ 733 -e "s#%escaped_wjcd_home#%wjcd_home#g;" \ 734 ${MY_SKEL_WORKERS_FILE} > ${MY_WORKERS_FILE} 735 if [ $? -ne 0 ] ; then 736 echo "${PROGRAM}: Error='Encountered a problem while creating ${MY_FILE} for ${CLIENT_ID}.'" 1>&2 737 MY_ERROR_FLAG=1 738 fi 739 else 740 echo "Skipping ${MY_WORKERS_FILE} (already exists)" 741 fi 742 fi 743 done 744 745 #################################################################### 746 # 747 # Change the group so the WWW user can access the client's files. 748 # 749 #################################################################### 750 751 chgrp -f -R ${WWW_GROUP} ${MY_PROFILE_DIR} 752 if [ $? -ne 0 ] ; then 753 echo "${PROGRAM}: Error='Encountered a problem while setting group ownerships for ${CLIENT_ID}.'" 1>&2 754 MY_ERROR_FLAG=1 755 fi 756 757 #################################################################### 758 # 759 # Add the client to the 'all' group. If the profile is local, also 760 # add the client to the 'all_local' group. Update any other groups 761 # specified by the user. 762 # 763 #################################################################### 764 765 echo "Updating ${WEBJOB_GROUP_FILE}" 766 767 webjob-jqd-update-group -a -G ${WEBJOB_GROUP_FILE} -m merge -g all ${CLIENT_ID} 768 if [ $? -ne 0 ] ; then 769 echo "${PROGRAM}: Error='Encountered a problem while updating the \"all\" group in ${WEBJOB_GROUP_FILE} for ${CLIENT_ID}.'" 1>&2 770 MY_ERROR_FLAG=1 771 fi 772 773 if [ ${LOCAL_PROFILE} -eq 1 ] ; then 774 webjob-jqd-update-group -a -G ${WEBJOB_GROUP_FILE} -m merge -g all_local ${CLIENT_ID} 775 if [ $? -ne 0 ] ; then 776 echo "${PROGRAM}: Error='Encountered a problem while updating the \"all_local\" group in ${WEBJOB_GROUP_FILE} for ${CLIENT_ID}.'" 1>&2 777 MY_ERROR_FLAG=1 778 fi 779 fi 780 781 for MY_JQD_GROUP in `echo ${JQD_GROUP_LIST} | sed 's/,/ /g;'` ; do 782 webjob-jqd-update-group -a -G ${WEBJOB_GROUP_FILE} -m merge -g ${MY_JQD_GROUP} ${CLIENT_ID} 783 if [ $? -ne 0 ] ; then 784 echo "${PROGRAM}: Error='Encountered a problem while updating the \"${MY_JQD_GROUP}\" group in ${WEBJOB_GROUP_FILE} for ${CLIENT_ID}.'" 1>&2 785 MY_ERROR_FLAG=1 786 fi 787 done 788 789 #################################################################### 790 # 791 # Create the client's job queue. 792 # 793 #################################################################### 794 795 if [ -d ${WEBJOB_JQD_DIR}/${CLIENT_ID} ] ; then 796 echo "Updating ${WEBJOB_JQD_DIR}/${CLIENT_ID}" 797 else 798 echo "Creating ${WEBJOB_JQD_DIR}/${CLIENT_ID}" 799 fi 800 801 MY_OPTS="-q" 802 if [ ${LOCK_PROFILE} -eq 1 ] ; then 803 MY_OPTS="${MY_OPTS} -l" 804 fi 805 webjob-jqd-create-queue ${MY_OPTS} -d ${WEBJOB_JQD_DIR} -o ${WWW_OWNER} ${CLIENT_ID} 806 if [ $? -ne 0 ] ; then 807 echo "${PROGRAM}: Error='Encountered a problem creating ${WEBJOB_JQD_DIR} for ${CLIENT_ID}.'" 1>&2 808 MY_ERROR_FLAG=1 809 fi 810 811 #################################################################### 812 # 813 # Lower the umask. The next few tasks need to create world-readable 814 # directories and files. 815 # 816 #################################################################### 817 818 umask 022 819 820 #################################################################### 821 # 822 # Create nph-config override directories. 823 # 824 #################################################################### 825 826 for MY_NAME in "clients" ; do 827 MY_OVERRIDE_DIR="${NPH_CONFIG_CONFIG_DIR}/${MY_NAME}/${CLIENT_ID}" 828 if [ ! -d "${MY_OVERRIDE_DIR}" ] ; then 829 echo "Creating ${MY_OVERRIDE_DIR}" 830 mkdir -p ${MY_OVERRIDE_DIR} 831 if [ $? -ne 0 ] ; then 832 echo "${PROGRAM}: Error='Encountered a problem while creating ${MY_OVERRIDE_DIR}.'" 1>&2 833 MY_ERROR_FLAG=1 834 fi 835 else 836 echo "Skipping ${MY_OVERRIDE_DIR} (already exists)" 837 fi 838 done 839 840 #################################################################### 841 # 842 # Create nph-webjob override directories. 843 # 844 #################################################################### 845 846 for MY_NAME in "clients" "queues" ; do 847 MY_OVERRIDE_DIR="${NPH_WEBJOB_CONFIG_DIR}/${MY_NAME}/${CLIENT_ID}" 848 if [ ! -d "${MY_OVERRIDE_DIR}" ] ; then 849 echo "Creating ${MY_OVERRIDE_DIR}" 850 mkdir -p ${MY_OVERRIDE_DIR} 851 if [ $? -ne 0 ] ; then 852 echo "${PROGRAM}: Error='Encountered a problem while creating ${MY_OVERRIDE_DIR}.'" 1>&2 853 MY_ERROR_FLAG=1 854 fi 855 else 856 echo "Skipping ${MY_OVERRIDE_DIR} (already exists)" 857 fi 858 done 859 860 #################################################################### 861 # 862 # Create nph-webjob queue override config file. 863 # 864 #################################################################### 865 866 MY_FILE="${NPH_WEBJOB_CONFIG_DIR}/queues/${CLIENT_ID}/nph-webjob.cfg" 867 if [ ! -f ${MY_FILE} -o ${FORCE} -eq 1 ] ; then 868 echo "Creating ${MY_FILE}" 869 cat > ${MY_FILE} <<EOF 870JobQueueActive=Y 871JobQueuePqActiveLimit=5 872JobQueuePqAnswerLimit=5 873JobQueueSqActiveLimit=1 874JobQueueSqAnswerLimit=1 875EOF 876 if [ $? -ne 0 ] ; then 877 echo "${PROGRAM}: Error='Encountered a problem while creating ${MY_FILE} for ${CLIENT_ID}.'" 1>&2 878 MY_ERROR_FLAG=1 879 fi 880 else 881 echo "Skipping ${MY_FILE} (already exists)" 882 fi 883 884 #################################################################### 885 # 886 # Restore the default umask. 887 # 888 #################################################################### 889 890 umask 027 891 892 #################################################################### 893 # 894 # Add the client to client.db, and set any client-specific KVPs. 895 # 896 #################################################################### 897 898 echo "Updating ${WEBJOB_CLIENT_DB}" 899 900 webjob-mldbm-create-client -q -d ${WEBJOB_CLIENT_DB} ${CLIENT_ID} 901 if [ $? -ne 0 ] ; then 902 echo "${PROGRAM}: Error='Encountered a problem while updating ${WEBJOB_CLIENT_DB} for ${CLIENT_ID}.'" 1>&2 903 MY_ERROR_FLAG=1 904 fi 905 906 MY_SECONDS=`perl -e 'print time();'` 907 908 MY_KVPS="'ClientId=${CLIENT_ID}' 'ConfigPointer=${CONFIG_POINTER}' 'Created=${MY_SECONDS}' 'Hostname=${CLIENT_HOSTNAME}' 'OsClass=${OS_CLASS}' 'Password=${MY_ENCODED_PASSWORD}' 'Timeslot=${MY_TIMESLOT}' 'WebJobHome=${WEBJOB_CLIENT_HOME}'" 909 if [ -n "${CLIENT_IP}" ] ; then 910 MY_KVPS="${MY_KVPS} 'Ipv4Address=${CLIENT_IP}' 'HostAccessList=${CLIENT_IP}/32'" 911 fi 912 if [ ${LOCK_PROFILE} -eq 1 ] ; then 913 MY_KVPS="${MY_KVPS} 'ProfileState=locked'" 914 else 915 MY_KVPS="${MY_KVPS} 'ProfileState=active'" 916 fi 917 if [ -n "${WEBJOB_REGISTRATION_CODE}" ] ; then 918 MY_KVPS="${MY_KVPS} 'RegistrationCode=${WEBJOB_REGISTRATION_CODE}'" 919 fi 920 if [ ${#} -gt 0 ] ; then 921 for MY_KVP in "${@}" ; do # NOTE: Quotes are required to retain embedded spaces. 922 MY_KVPS="${MY_KVPS} '${MY_KVP}'" 923 done 924 fi 925 eval webjob-mldbm-set-config-kvps -d ${WEBJOB_CLIENT_DB} -c ${CLIENT_ID} ${MY_KVPS} 926 if [ $? -ne 0 ] ; then 927 echo "${PROGRAM}: Error='Encountered a problem while updating ${WEBJOB_CLIENT_DB} for ${CLIENT_ID}.'" 1>&2 928 MY_ERROR_FLAG=1 929 fi 930 931 #################################################################### 932 # 933 # Conditionally update the host access lists. 934 # 935 #################################################################### 936 937 HOST_ACCESS_LIST=`webjob-mldbm-get-config-kvps -d ${WEBJOB_CLIENT_DB} -c ${CLIENT_ID} -o BeQuiet,ValuesOnly HostAccessList | sed 's/,/ /g;'` 938 if [ -n "${HOST_ACCESS_LIST}" ] ; then 939 for HOST_ACCESS_FILE in ${NPH_CONFIG_HOST_ACCESS_FILE} ${NPH_WEBJOB_HOST_ACCESS_FILE} ; do 940 webjob-cfg-update-list -a -m merge -f ${HOST_ACCESS_FILE} -k ${CLIENT_ID} ${HOST_ACCESS_LIST} 941 if [ $? -ne 0 ] ; then 942 echo "${PROGRAM}: Error='Encountered a problem while updating ${HOST_ACCESS_FILE} for ${CLIENT_ID}.'" 1>&2 943 MY_ERROR_FLAG=1 944 fi 945 done 946 fi 947 948###################################################################### 949# 950# Shutdown and go home. 951# 952###################################################################### 953 954if [ ${MY_ERROR_FLAG} -eq 1 ] ; then 955 echo "${PROGRAM}: Error='Encountered one or more errors. The profile for ${CLIENT_ID} is incomplete.'" 1>&2 956 exit 3 # XER_PartialSuccess 957else 958 exit 0 # XER_OK 959fi 960