1#!/bin/sh 2# 3# ident "%Z%%M% %I% %E% SMI" 4# 5# CDDL HEADER START 6# 7# The contents of this file are subject to the terms of the 8# Common Development and Distribution License (the "License"). 9# You may not use this file except in compliance with the License. 10# 11# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 12# or http://www.opensolaris.org/os/licensing. 13# See the License for the specific language governing permissions 14# and limitations under the License. 15# 16# When distributing Covered Code, include this CDDL HEADER in each 17# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 18# If applicable, add the following below this CDDL HEADER, with the 19# fields enclosed by brackets "[]" replaced with your own identifying 20# information: Portions Copyright [yyyy] [name of copyright owner] 21# 22# CDDL HEADER END 23# 24# 25# idsconfig -- script to setup iDS 5.x/6.x for Native LDAP II. 26# 27# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 28# Use is subject to license terms. 29# 30 31# 32# display_msg(): Displays message corresponding to the tag passed in. 33# 34display_msg() 35{ 36 case "$1" in 37 usage) cat <<EOF 38 $PROG: [ -v ] [ -i input file ] [ -o output file ] 39 i <input file> Get setup info from input file. 40 o <output file> Generate a server configuration output file. 41 v Verbose mode 42EOF 43 ;; 44 backup_server) cat <<EOF 45It is strongly recommended that you BACKUP the directory server 46before running $PROG. 47 48Hit Ctrl-C at any time before the final confirmation to exit. 49 50EOF 51 ;; 52 setup_complete) cat <<EOF 53 54$PROG: Setup of iDS server ${IDS_SERVER} is complete. 55 56EOF 57 ;; 58 display_vlv_list) cat <<EOF 59 60Note: idsconfig has created entries for VLV indexes. 61 62 For DS5.x, use the directoryserver(1m) script on ${IDS_SERVER} 63 to stop the server. Then, using directoryserver, follow the 64 directoryserver examples below to create the actual VLV indexes. 65 66 For DS6.x, use dsadm command delivered with DS6.x on ${IDS_SERVER} 67 to stop the server. Then, using dsadm, follow the 68 dsadm examples below to create the actual VLV indexes. 69 70EOF 71 ;; 72 cred_level_menu) cat <<EOF 73The following are the supported credential levels: 74 1 anonymous 75 2 proxy 76 3 proxy anonymous 77 4 self 78 5 self proxy 79 6 self proxy anonymous 80EOF 81 ;; 82 auth_method_menu) cat <<EOF 83The following are the supported Authentication Methods: 84 1 none 85 2 simple 86 3 sasl/DIGEST-MD5 87 4 tls:simple 88 5 tls:sasl/DIGEST-MD5 89 6 sasl/GSSAPI 90EOF 91 ;; 92 srvauth_method_menu) cat <<EOF 93The following are the supported Authentication Methods: 94 1 simple 95 2 sasl/DIGEST-MD5 96 3 tls:simple 97 4 tls:sasl/DIGEST-MD5 98 5 sasl/GSSAPI 99EOF 100 ;; 101 prompt_ssd_menu) cat <<EOF 102 A Add a Service Search Descriptor 103 D Delete a SSD 104 M Modify a SSD 105 P Display all SSD's 106 H Help 107 X Clear all SSD's 108 109 Q Exit menu 110EOF 111 ;; 112 summary_menu) 113 114 SUFFIX_INFO= 115 DB_INFO= 116 117 [ -n "${NEED_CREATE_SUFFIX}" ] && 118 { 119 SUFFIX_INFO=`cat <<EOF 120 121 Suffix to create : $LDAP_SUFFIX 122EOF 123` 124 [ -n "${NEED_CREATE_BACKEND}" ] && 125 DB_INFO=`cat <<EOF 126 127 Database to create : $IDS_DATABASE 128EOF 129` 130 } 131 132 cat <<EOF 133 Summary of Configuration 134 135 1 Domain to serve : $LDAP_DOMAIN 136 2 Base DN to setup : $LDAP_BASEDN$SUFFIX_INFO$DB_INFO 137 3 Profile name to create : $LDAP_PROFILE_NAME 138 4 Default Server List : $LDAP_SERVER_LIST 139 5 Preferred Server List : $LDAP_PREF_SRVLIST 140 6 Default Search Scope : $LDAP_SEARCH_SCOPE 141 7 Credential Level : $LDAP_CRED_LEVEL 142 8 Authentication Method : $LDAP_AUTHMETHOD 143 9 Enable Follow Referrals : $LDAP_FOLLOWREF 144 10 iDS Time Limit : $IDS_TIMELIMIT 145 11 iDS Size Limit : $IDS_SIZELIMIT 146 12 Enable crypt password storage : $NEED_CRYPT 147 13 Service Auth Method pam_ldap : $LDAP_SRV_AUTHMETHOD_PAM 148 14 Service Auth Method keyserv : $LDAP_SRV_AUTHMETHOD_KEY 149 15 Service Auth Method passwd-cmd: $LDAP_SRV_AUTHMETHOD_CMD 150 16 Search Time Limit : $LDAP_SEARCH_TIME_LIMIT 151 17 Profile Time to Live : $LDAP_PROFILE_TTL 152 18 Bind Limit : $LDAP_BIND_LIMIT 153 19 Service Search Descriptors Menu 154 155EOF 156 ;; 157 sfx_not_suitable) cat <<EOF 158 159Sorry, suffix ${LDAP_SUFFIX} is not suitable for Base DN ${LDAP_BASEDN} 160 161EOF 162 ;; 163 obj_not_found) cat <<EOF 164 165Sorry, ${PROG} can't find an objectclass for "$_ATT" attribute 166 167EOF 168 ;; 169 sfx_config_incons) cat <<EOF 170 171Sorry, there is no suffix mapping for ${LDAP_SUFFIX}, 172while ldbm database exists, server configuration needs to be fixed manually, 173look at cn=mapping tree,cn=config and cn=ldbm database,cn=plugins,cn=config 174 175EOF 176 ;; 177 ldbm_db_exist) cat <<EOF 178 179Database "${IDS_DATABASE}" already exists, 180however "${IDS_DATABASE_AVAIL}" name is available 181 182EOF 183 ;; 184 unable_find_db_name) cat <<EOF 185 186Unable to find any available database name close to "${IDS_DATABASE}" 187 188EOF 189 ;; 190 create_ldbm_db_error) cat <<EOF 191 192ERROR: unable to create suffix ${LDAP_SUFFIX} 193 due to server error that occurred during creation of ldbm database 194 195EOF 196 ;; 197 create_suffix_entry_error) cat <<EOF 198 199ERROR: unable to create entry ${LDAP_SUFFIX} of ${LDAP_SUFFIX_OBJ} class 200 201EOF 202 ;; 203 ldap_suffix_list) cat <<EOF 204 205No valid suffixes (naming contexts) were found for LDAP base DN: 206${LDAP_BASEDN} 207 208Available suffixes are: 209${LDAP_SUFFIX_LIST} 210 211EOF 212 ;; 213 sorry) cat <<EOF 214 215HELP - No help is available for this topic. 216 217EOF 218 ;; 219 create_suffix_help) cat <<EOF 220 221HELP - Our Base DN is ${LDAP_BASEDN} 222 and we need to create a Directory Suffix, 223 which can be equal to Base DN itself or be any of Base DN parents. 224 All intermediate entries up to suffix will be created on demand. 225 226EOF 227 ;; 228 enter_ldbm_db_help) cat <<EOF 229 230HELP - ldbm database is an internal database for storage of our suffix data. 231 Database name must be alphanumeric due to Directory Server restriction. 232 233EOF 234 ;; 235 backup_help) cat <<EOF 236 237HELP - Since idsconfig modifies the directory server configuration, 238 it is strongly recommended that you backup the server prior 239 to running this utility. This is especially true if the server 240 being configured is a production server. 241 242EOF 243 ;; 244 port_help) cat <<EOF 245 246HELP - Enter the port number the directory server is configured to 247 use for LDAP. 248 249EOF 250 ;; 251 domain_help) cat <<EOF 252 253HELP - This is the DNS domain name this server will be serving. You 254 must provide this name even if the server is not going to be populated 255 with hostnames. Any unqualified hostname stored in the directory 256 will be fully qualified using this DNS domain name. 257 258EOF 259 ;; 260 basedn_help) cat <<EOF 261 262HELP - This parameter defines the default location in the directory tree for 263 the naming services entries. You can override this default by using 264 serviceSearchDescriptors (SSD). You will be given the option to set up 265 an SSD later on in the setup. 266 267EOF 268 ;; 269 profile_help) cat <<EOF 270 271HELP - Name of the configuration profile with which the clients will be 272 configured. A directory server can store various profiles for multiple 273 groups of clients. The initialization tool, (ldapclient(1M)), assumes 274 "default" unless another is specified. 275 276EOF 277 ;; 278 def_srvlist_help) cat <<EOF 279 280HELP - Provide a list of directory servers to serve clients using this profile. 281 All these servers should contain consistent data and provide similar 282 functionality. This list is not ordered, and clients might change the 283 order given in this list. Note that this is a space separated list of 284 *IP addresses* (not host names). Providing port numbers is optional. 285 286EOF 287 ;; 288 pref_srvlist_help) cat <<EOF 289 290HELP - Provide a list of directory servers to serve this client profile. 291 Unlike the default server list, which is not ordered, the preferred 292 servers must be entered IN THE ORDER you wish to have them contacted. 293 If you do specify a preferred server list, clients will always contact 294 them before attempting to contact any of the servers on the default 295 server list. Note that you must enter the preferred server list as a 296 space-separated list of *IP addresses* (not host names). Providing port 297 numbers is optional. 298 299EOF 300 ;; 301 srch_scope_help) cat <<EOF 302 303HELP - Default search scope to be used for all searches unless they are 304 overwritten using serviceSearchDescriptors. The valid options 305 are "one", which would specify the search will only be performed 306 at the base DN for the given service, or "sub", which would specify 307 the search will be performed through *all* levels below the base DN 308 for the given service. 309 310EOF 311 ;; 312 cred_lvl_help) cat <<EOF 313 314HELP - This parameter defines what credentials the clients use to 315 authenticate to the directory server. This list might contain 316 multiple credential levels and is ordered. If a proxy level 317 is configured, you will also be prompted to enter a bind DN 318 for the proxy agent along with a password. This proxy agent 319 will be created if it does not exist. 320 321EOF 322 ;; 323 auth_help) cat <<EOF 324 325HELP - The default authentication method(s) to be used by all services 326 in the client using this profile. This is a ordered list of 327 authentication methods separated by a ';'. The supported methods 328 are provided in a menu. Note that sasl/DIGEST-MD5 binds require 329 passwords to be stored un-encrypted on the server. 330 331EOF 332 ;; 333 srvauth_help) cat <<EOF 334 335HELP - The authentication methods to be used by a given service. Currently 336 3 services support this feature: pam_ldap, keyserv, and passwd-cmd. 337 The authentication method specified in this attribute overrides 338 the default authentication method defined in the profile. This 339 feature can be used to select stronger authentication methods for 340 services which require increased security. 341 342EOF 343 ;; 344 pam_ldap_help) cat <<EOF 345 346HELP - The authentication method(s) to be used by pam_ldap when contacting 347 the directory server. This is a ordered list, and, if provided, will 348 override the default authentication method parameter. 349 350EOF 351 ;; 352 keyserv_help) cat <<EOF 353 354HELP - The authentication method(s) to be used by newkey(1M) and chkey(1) 355 when contacting the directory server. This is a ordered list and 356 if provided will override the default authentication method 357 parameter. 358 359EOF 360 ;; 361 passwd-cmd_help) cat <<EOF 362 363HELP - The authentication method(s) to be used by passwd(1) command when 364 contacting the directory server. This is a ordered list and if 365 provided will override the default authentication method parameter. 366 367EOF 368 ;; 369 referrals_help) cat <<EOF 370 371HELP - This parameter indicates whether the client should follow 372 ldap referrals if it encounters one during naming lookups. 373 374EOF 375 ;; 376 tlim_help) cat <<EOF 377 378HELP - The server time limit value indicates the maximum amount of time the 379 server would spend on a query from the client before abandoning it. 380 A value of '-1' indicates no limit. 381 382EOF 383 ;; 384 slim_help) cat <<EOF 385 386HELP - The server sizelimit value indicates the maximum number of entries 387 the server would return in respond to a query from the client. A 388 value of '-1' indicates no limit. 389 390EOF 391 ;; 392 crypt_help) cat <<EOF 393 394HELP - By default iDS does not store userPassword attribute values using 395 unix "crypt" format. If you need to keep your passwords in the crypt 396 format for NIS/NIS+ and pam_unix compatibility, choose 'yes'. If 397 passwords are stored using any other format than crypt, pam_ldap 398 MUST be used by clients to authenticate users to the system. Note 399 that if you wish to use sasl/DIGEST-MD5 in conjunction with pam_ldap, 400 user passwords must be stored in the clear format. 401 402EOF 403 ;; 404 srchtime_help) cat <<EOF 405 406HELP - The search time limit the client will enforce for directory 407 lookups. 408 409EOF 410 ;; 411 profttl_help) cat <<EOF 412 413HELP - The time to live value for profile. The client will refresh its 414 cached version of the configuration profile at this TTL interval. 415 416EOF 417 ;; 418 bindlim_help) cat <<EOF 419 420HELP - The time limit for the bind operation to the directory. This 421 value controls the responsiveness of the client in case a server 422 becomes unavailable. The smallest timeout value for a given 423 network architecture/conditions would work best. This is very 424 similar to setting TCP timeout, but only for LDAP bind operation. 425 426EOF 427 ;; 428 ssd_help) cat <<EOF 429 430HELP - Using Service Search Descriptors (SSD), you can override the 431 default configuration for a given service. The SSD can be 432 used to override the default search base DN, the default search 433 scope, and the default search filter to be used for directory 434 lookups. SSD are supported for all services (databases) 435 defined in nsswitch.conf(4). The default base DN is defined 436 in ldap(1). 437 438 Note: SSD are powerful tools in defining configuration profiles 439 and provide a great deal of flexibility. However, care 440 must be taken in creating them. If you decide to make use 441 of SSDs, consult the documentation first. 442 443EOF 444 ;; 445 ssd_menu_help) cat <<EOF 446 447HELP - Using this menu SSD can be added, updated, or deleted from 448 the profile. 449 450 A - This option creates a new SSD by prompting for the 451 service name, base DN, and scope. Service name is 452 any valid service as defined in ldap(1). base is 453 either the distinguished name to the container where 454 this service will use, or a relative DN followed 455 by a ','. 456 D - Delete a previously created SSD. 457 M - Modify a previously created SSD. 458 P - Display a list of all the previously created SSD. 459 X - Delete all of the previously created SSD. 460 461 Q - Exit the menu and continue with the server configuration. 462 463EOF 464 ;; 465 ldap_suffix_list_help) cat <<EOF 466 467HELP - No valid suffixes (naming contexts) are available on server 468 ${IDS_SERVER}:${IDS_PORT}. 469 You must set an LDAP Base DN that can be contained in 470 an existing suffix. 471 472EOF 473 ;; 474 esac 475} 476 477 478# 479# get_ans(): gets an answer from the user. 480# $1 instruction/comment/description/question 481# $2 default value 482# 483get_ans() 484{ 485 if [ -z "$2" ] 486 then 487 ${ECHO} "$1 \c" 488 else 489 ${ECHO} "$1 [$2] \c" 490 fi 491 492 read ANS 493 if [ -z "$ANS" ] 494 then 495 ANS=$2 496 fi 497} 498 499 500# 501# get_ans_req(): gets an answer (required) from the user, NULL value not allowed. 502# $@ instruction/comment/description/question 503# 504get_ans_req() 505{ 506 ANS="" # Set ANS to NULL. 507 while [ "$ANS" = "" ] 508 do 509 get_ans "$@" 510 [ "$ANS" = "" ] && ${ECHO} "NULL value not allowed!" 511 done 512} 513 514 515# 516# get_number(): Querys and verifies that number entered is numeric. 517# Function will repeat prompt user for number value. 518# $1 Message text. 519# $2 default value. 520# $3 Help argument. 521# 522get_number() 523{ 524 ANS="" # Set ANS to NULL. 525 NUM="" 526 527 get_ans "$1" "$2" 528 529 # Verify that value is numeric. 530 while not_numeric $ANS 531 do 532 case "$ANS" in 533 [Hh] | help | Help | \?) display_msg ${3:-sorry} ;; 534 * ) ${ECHO} "Invalid value: \"${ANS}\". \c" 535 ;; 536 esac 537 # Get a new value. 538 get_ans "Enter a numeric value:" "$2" 539 done 540 NUM=$ANS 541} 542 543 544# 545# get_negone_num(): Only allows a -1 or positive integer. 546# Used for values where -1 has special meaning. 547# 548# $1 - Prompt message. 549# $2 - Default value (require). 550# $3 - Optional help argument. 551get_negone_num() 552{ 553 while : 554 do 555 get_number "$1" "$2" "$3" 556 if is_negative $ANS 557 then 558 if [ "$ANS" = "-1" ]; then 559 break # -1 is OK, so break. 560 else # Need to re-enter number. 561 ${ECHO} "Invalid number: please enter -1 or positive number." 562 fi 563 else 564 break # Positive number 565 fi 566 done 567} 568 569 570# 571# get_passwd(): Reads a password from the user and verify with second. 572# $@ instruction/comment/description/question 573# 574get_passwd() 575{ 576 [ $DEBUG -eq 1 ] && ${ECHO} "In get_passwd()" 577 578 # Temporary PASSWD variables 579 _PASS1="" 580 _PASS2="" 581 582 /usr/bin/stty -echo # Turn echo OFF 583 584 # Endless loop that continues until passwd and re-entered passwd 585 # match. 586 while : 587 do 588 ANS="" # Set ANS to NULL. 589 590 # Don't allow NULL for first try. 591 while [ "$ANS" = "" ] 592 do 593 get_ans "$@" 594 [ "$ANS" = "" ] && ${ECHO} "" && ${ECHO} "NULL passwd not allowed!" 595 done 596 _PASS1=$ANS # Store first try. 597 598 # Get second try. 599 ${ECHO} "" 600 get_ans "Re-enter passwd:" 601 _PASS2=$ANS 602 603 # Test if passwords are identical. 604 if [ "$_PASS1" = "$_PASS2" ]; then 605 break 606 fi 607 608 # Move cursor down to next line and print ERROR message. 609 ${ECHO} "" 610 ${ECHO} "ERROR: passwords don't match; try again." 611 done 612 613 /usr/bin/stty echo # Turn echo ON 614 615 ${ECHO} "" 616} 617 618 619# 620# get_passwd_nochk(): Reads a password from the user w/o check. 621# $@ instruction/comment/description/question 622# 623get_passwd_nochk() 624{ 625 [ $DEBUG -eq 1 ] && ${ECHO} "In get_passwd_nochk()" 626 627 /usr/bin/stty -echo # Turn echo OFF 628 629 get_ans "$@" 630 631 /usr/bin/stty echo # Turn echo ON 632 633 ${ECHO} "" 634} 635 636 637# 638# get_menu_choice(): Get a menu choice from user. Continue prompting 639# till the choice is in required range. 640# $1 .. Message text. 641# $2 .. min value 642# $3 .. max value 643# $4 .. OPTIONAL: default value 644# 645# Return value: 646# MN_CH will contain the value selected. 647# 648get_menu_choice() 649{ 650 # Check for req parameter. 651 if [ $# -lt 3 ]; then 652 ${ECHO} "get_menu_choice(): Did not get required parameters." 653 return 1 654 fi 655 656 while : 657 do 658 get_ans "$1" "$4" 659 MN_CH=$ANS 660 is_negative $MN_CH 661 if [ $? -eq 1 ]; then 662 if [ $MN_CH -ge $2 ]; then 663 if [ $MN_CH -le $3 ]; then 664 return 665 fi 666 fi 667 fi 668 ${ECHO} "Invalid choice: $MN_CH" 669 done 670} 671 672 673# 674# get_confirm(): Get confirmation from the user. (Y/Yes or N/No) 675# $1 - Message 676# $2 - default value. 677# 678get_confirm() 679{ 680 _ANSWER= 681 682 while : 683 do 684 # Display Internal ERROR if $2 not set. 685 if [ -z "$2" ] 686 then 687 ${ECHO} "INTERNAL ERROR: get_confirm requires 2 args, 3rd is optional." 688 exit 2 689 fi 690 691 # Display prompt. 692 ${ECHO} "$1 [$2] \c" 693 694 # Get the ANSWER. 695 read _ANSWER 696 if [ "$_ANSWER" = "" ] && [ -n "$2" ] ; then 697 _ANSWER=$2 698 fi 699 case "$_ANSWER" in 700 [Yy] | yes | Yes | YES) return 1 ;; 701 [Nn] | no | No | NO) return 0 ;; 702 [Hh] | help | Help | \?) display_msg ${3:-sorry};; 703 * ) ${ECHO} "Please enter y or n." ;; 704 esac 705 done 706} 707 708 709# 710# get_confirm_nodef(): Get confirmation from the user. (Y/Yes or N/No) 711# No default value supported. 712# 713get_confirm_nodef() 714{ 715 _ANSWER= 716 717 while : 718 do 719 ${ECHO} "$@ \c" 720 read _ANSWER 721 case "$_ANSWER" in 722 [Yy] | yes | Yes | YES) return 1 ;; 723 [Nn] | no | No | NO) return 0 ;; 724 * ) ${ECHO} "Please enter y or n." ;; 725 esac 726 done 727} 728 729 730# 731# is_numeric(): Tells is a string is numeric. 732# 0 = Numeric 733# 1 = NOT Numeric 734# 735is_numeric() 736{ 737 # Check for parameter. 738 if [ $# -ne 1 ]; then 739 return 1 740 fi 741 742 # Determine if numeric. 743 expr "$1" + 1 > /dev/null 2>&1 744 if [ $? -ge 2 ]; then 745 return 1 746 fi 747 748 # Made it here, it's Numeric. 749 return 0 750} 751 752 753# 754# not_numeric(): Reverses the return values of is_numeric. Useful 755# for if and while statements that want to test for 756# non-numeric data. 757# 0 = NOT Numeric 758# 1 = Numeric 759# 760not_numeric() 761{ 762 is_numeric $1 763 if [ $? -eq 0 ]; then 764 return 1 765 else 766 return 0 767 fi 768} 769 770 771# 772# is_negative(): Tells is a Numeric value is less than zero. 773# 0 = Negative Numeric 774# 1 = Positive Numeric 775# 2 = NOT Numeric 776# 777is_negative() 778{ 779 # Check for parameter. 780 if [ $# -ne 1 ]; then 781 return 1 782 fi 783 784 # Determine if numeric. Can't use expr because -0 is 785 # considered positive?? 786 if is_numeric $1; then 787 case "$1" in 788 -*) return 0 ;; # Negative Numeric 789 *) return 1 ;; # Positive Numeric 790 esac 791 else 792 return 2 793 fi 794} 795 796 797# 798# check_domainname(): check validity of a domain name. Currently we check 799# that it has at least two components. 800# $1 the domain name to be checked 801# 802check_domainname() 803{ 804 if [ ! -z "$1" ] 805 then 806 t=`expr "$1" : '[^.]\{1,\}[.][^.]\{1,\}'` 807 if [ "$t" = 0 ] 808 then 809 return 1 810 fi 811 fi 812 return 0 813} 814 815 816# 817# check_baseDN(): check validity of the baseDN name. 818# $1 the baseDN name to be checked 819# 820# NOTE: The check_baseDN function does not catch all invalid DN's. 821# Its purpose is to reduce the number of invalid DN's to 822# get past the input routine. The invalid DN's will be 823# caught by the LDAP server when they are attempted to be 824# created. 825# 826check_baseDN() 827{ 828 ck_DN=$1 829 ${ECHO} " Checking LDAP Base DN ..." 830 if [ ! -z "$ck_DN" ]; then 831 [ $DEBUG -eq 1 ] && ${ECHO} "Checking baseDN: $ck_DN" 832 # Check for = (assignment operator) 833 ${ECHO} "$ck_DN" | ${GREP} "=" > /dev/null 2>&1 834 if [ $? -ne 0 ]; then 835 [ $DEBUG -eq 1 ] && ${ECHO} "check_baseDN: No '=' in baseDN." 836 return 1 837 fi 838 839 # Check all keys. 840 while : 841 do 842 # Get first key. 843 dkey=`${ECHO} $ck_DN | cut -d'=' -f1` 844 845 # Check that the key string is valid 846 check_attrName $dkey 847 if [ $? -ne 0 ]; then 848 [ $DEBUG -eq 1 ] && ${ECHO} "check_baseDN: invalid key=${dkey}" 849 return 1 850 fi 851 852 [ $DEBUG -eq 1 ] && ${ECHO} "check_baseDN: valid key=${dkey}" 853 854 # Remove first key from DN 855 ck_DN=`${ECHO} $ck_DN | cut -s -d',' -f2-` 856 857 # Break loop if nothing left. 858 if [ "$ck_DN" = "" ]; then 859 break 860 fi 861 done 862 fi 863 return 0 864} 865 866 867# 868# domain_2_dc(): Convert a domain name into dc string. 869# $1 .. Domain name. 870# 871domain_2_dc() 872{ 873 _DOM=$1 # Domain parameter. 874 _DOM_2_DC="" # Return value from function. 875 _FIRST=1 # Flag for first time. 876 877 export _DOM_2_DC # Make visible for others. 878 879 # Convert "."'s to spaces for "for" loop. 880 domtmp="`${ECHO} ${_DOM} | tr '.' ' '`" 881 for i in $domtmp; do 882 if [ $_FIRST -eq 1 ]; then 883 _DOM_2_DC="dc=${i}" 884 _FIRST=0 885 else 886 _DOM_2_DC="${_DOM_2_DC},dc=${i}" 887 fi 888 done 889} 890 891 892# 893# is_root_user(): Check to see if logged in as root user. 894# 895is_root_user() 896{ 897 case `id` in 898 uid=0\(root\)*) return 0 ;; 899 * ) return 1 ;; 900 esac 901} 902 903 904# 905# parse_arg(): Parses the command line arguments and sets the 906# appropriate variables. 907# 908parse_arg() 909{ 910 while getopts "dvhi:o:" ARG 911 do 912 case $ARG in 913 d) DEBUG=1;; 914 v) VERB="";; 915 i) INPUT_FILE=$OPTARG;; 916 o) OUTPUT_FILE=$OPTARG;; 917 \?) display_msg usage 918 exit 1;; 919 *) ${ECHO} "**ERROR: Supported option missing handler!" 920 display_msg usage 921 exit 1;; 922 esac 923 done 924 return `expr $OPTIND - 1` 925} 926 927 928# 929# init(): initializes variables and options 930# 931init() 932{ 933 # General variables. 934 PROG=`basename $0` # Program name 935 PID=$$ # Program ID 936 VERB='> /dev/null 2>&1' # NULL or "> /dev/null" 937 ECHO="/bin/echo" # print message on screen 938 EVAL="eval" # eval or echo 939 EGREP="/usr/bin/egrep" 940 GREP="/usr/bin/grep" 941 DEBUG=0 # Set Debug OFF 942 BACKUP=no_ldap # backup suffix 943 HOST="" # NULL or <hostname> 944 NAWK="/usr/bin/nawk" 945 946 DOM="" # Set to NULL 947 # If DNS domain (resolv.conf) exists use that, otherwise use domainname. 948 if [ -f /etc/resolv.conf ]; then 949 DOM=`/usr/xpg4/bin/grep -i -E '^domain|^search' /etc/resolv.conf \ 950 | awk '{ print $2 }' | tail -1` 951 fi 952 953 # If for any reason the DOM did not get set (error'd resolv.conf) set 954 # DOM to the domainname command's output. 955 if [ "$DOM" = "" ]; then 956 DOM=`domainname` # domain from domainname command. 957 fi 958 959 STEP=1 960 INTERACTIVE=1 # 0 = on, 1 = off (For input file mode) 961 DEL_OLD_PROFILE=0 # 0 (default), 1 = delete old profile. 962 963 # idsconfig specific variables. 964 INPUT_FILE="" 965 OUTPUT_FILE="" 966 NEED_PROXY=0 # 0 = No Proxy, 1 = Create Proxy. 967 LDAP_PROXYAGENT="" 968 LDAP_SUFFIX="" 969 LDAP_DOMAIN=$DOM # domainname on Server (default value) 970 GEN_CMD="" 971 972 # LDAP COMMANDS 973 LDAPSEARCH="/bin/ldapsearch -r" 974 LDAPMODIFY=/bin/ldapmodify 975 LDAPADD=/bin/ldapadd 976 LDAPDELETE=/bin/ldapdelete 977 LDAP_GEN_PROFILE=/usr/sbin/ldap_gen_profile 978 979 # iDS specific information 980 IDS_SERVER="" 981 IDS_PORT=389 982 NEED_TIME=0 983 NEED_SIZE=0 984 NEED_SRVAUTH_PAM=0 985 NEED_SRVAUTH_KEY=0 986 NEED_SRVAUTH_CMD=0 987 IDS_TIMELIMIT="" 988 IDS_SIZELIMIT="" 989 990 # LDAP PROFILE related defaults 991 LDAP_ROOTDN="cn=Directory Manager" # Provide common default. 992 LDAP_ROOTPWD="" # NULL passwd as default (i.e. invalid) 993 LDAP_PROFILE_NAME="default" 994 LDAP_BASEDN="" 995 LDAP_SERVER_LIST="" 996 LDAP_AUTHMETHOD="" 997 LDAP_FOLLOWREF="FALSE" 998 NEED_CRYPT="" 999 LDAP_SEARCH_SCOPE="one" 1000 LDAP_SRV_AUTHMETHOD_PAM="" 1001 LDAP_SRV_AUTHMETHOD_KEY="" 1002 LDAP_SRV_AUTHMETHOD_CMD="" 1003 LDAP_SEARCH_TIME_LIMIT=30 1004 LDAP_PREF_SRVLIST="" 1005 LDAP_PROFILE_TTL=43200 1006 LDAP_CRED_LEVEL="proxy" 1007 LDAP_BIND_LIMIT=10 1008 1009 # Prevent new files from being read by group or others. 1010 umask 077 1011 1012 # Service Search Descriptors 1013 LDAP_SERV_SRCH_DES="" 1014 1015 # Set and create TMPDIR. 1016 TMPDIR="/tmp/idsconfig.${PID}" 1017 if mkdir -m 700 ${TMPDIR} 1018 then 1019 # Cleanup on exit. 1020 trap 'rm -rf ${TMPDIR}; /usr/bin/stty echo; exit' 1 2 3 6 15 1021 else 1022 echo "ERROR: unable to create a safe temporary directory." 1023 exit 1 1024 fi 1025 LDAP_ROOTPWF=${TMPDIR}/rootPWD 1026 1027 # Set the SSD file name after setting TMPDIR. 1028 SSD_FILE=${TMPDIR}/ssd_list 1029 1030 # GSSAPI setup 1031 LDAP_KRB_REALM="" 1032 LDAP_GSSAPI_PROFILE="" 1033 SCHEMA_UPDATED=0 1034 1035 export DEBUG VERB ECHO EVAL EGREP GREP STEP TMPDIR 1036 export IDS_SERVER IDS_PORT LDAP_ROOTDN LDAP_ROOTPWD LDAP_SERVER_LIST 1037 export LDAP_BASEDN LDAP_ROOTPWF 1038 export LDAP_DOMAIN LDAP_SUFFIX LDAP_PROXYAGENT LDAP_PROXYAGENT_CRED 1039 export NEED_PROXY 1040 export LDAP_PROFILE_NAME LDAP_BASEDN LDAP_SERVER_LIST 1041 export LDAP_AUTHMETHOD LDAP_FOLLOWREF LDAP_SEARCH_SCOPE LDAP_SEARCH_TIME_LIMIT 1042 export LDAP_PREF_SRVLIST LDAP_PROFILE_TTL LDAP_CRED_LEVEL LDAP_BIND_LIMIT 1043 export NEED_SRVAUTH_PAM NEED_SRVAUTH_KEY NEED_SRVAUTH_CMD 1044 export LDAP_SRV_AUTHMETHOD_PAM LDAP_SRV_AUTHMETHOD_KEY LDAP_SRV_AUTHMETHOD_CMD 1045 export LDAP_SERV_SRCH_DES SSD_FILE 1046 export GEN_CMD LDAP_KRB_REALM LDAP_GSSAPI_PROFILE SCHEMA_UPDATED 1047} 1048 1049 1050# 1051# disp_full_debug(): List of all debug variables usually interested in. 1052# Grouped to avoid MASSIVE code duplication. 1053# 1054disp_full_debug() 1055{ 1056 [ $DEBUG -eq 1 ] && ${ECHO} " IDS_SERVER = $IDS_SERVER" 1057 [ $DEBUG -eq 1 ] && ${ECHO} " IDS_PORT = $IDS_PORT" 1058 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_ROOTDN = $LDAP_ROOTDN" 1059 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_ROOTPWD = $LDAP_ROOTPWD" 1060 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_DOMAIN = $LDAP_DOMAIN" 1061 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_SUFFIX = $LDAP_SUFFIX" 1062 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_BASEDN = $LDAP_BASEDN" 1063 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_PROFILE_NAME = $LDAP_PROFILE_NAME" 1064 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_SERVER_LIST = $LDAP_SERVER_LIST" 1065 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_PREF_SRVLIST = $LDAP_PREF_SRVLIST" 1066 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_SEARCH_SCOPE = $LDAP_SEARCH_SCOPE" 1067 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_CRED_LEVEL = $LDAP_CRED_LEVEL" 1068 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_AUTHMETHOD = $LDAP_AUTHMETHOD" 1069 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_FOLLOWREF = $LDAP_FOLLOWREF" 1070 [ $DEBUG -eq 1 ] && ${ECHO} " IDS_TIMELIMIT = $IDS_TIMELIMIT" 1071 [ $DEBUG -eq 1 ] && ${ECHO} " IDS_SIZELIMIT = $IDS_SIZELIMIT" 1072 [ $DEBUG -eq 1 ] && ${ECHO} " NEED_CRYPT = $NEED_CRYPT" 1073 [ $DEBUG -eq 1 ] && ${ECHO} " NEED_SRVAUTH_PAM = $NEED_SRVAUTH_PAM" 1074 [ $DEBUG -eq 1 ] && ${ECHO} " NEED_SRVAUTH_KEY = $NEED_SRVAUTH_KEY" 1075 [ $DEBUG -eq 1 ] && ${ECHO} " NEED_SRVAUTH_CMD = $NEED_SRVAUTH_CMD" 1076 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_SRV_AUTHMETHOD_PAM = $LDAP_SRV_AUTHMETHOD_PAM" 1077 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_SRV_AUTHMETHOD_KEY = $LDAP_SRV_AUTHMETHOD_KEY" 1078 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_SRV_AUTHMETHOD_CMD = $LDAP_SRV_AUTHMETHOD_CMD" 1079 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_SEARCH_TIME_LIMIT = $LDAP_SEARCH_TIME_LIMIT" 1080 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_PROFILE_TTL = $LDAP_PROFILE_TTL" 1081 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_BIND_LIMIT = $LDAP_BIND_LIMIT" 1082 1083 # Only display proxy stuff if needed. 1084 if [ $NEED_PROXY -eq 1 ]; then 1085 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_PROXYAGENT = $LDAP_PROXYAGENT" 1086 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_PROXYAGENT_CRED = $LDAP_PROXYAGENT_CRED" 1087 [ $DEBUG -eq 1 ] && ${ECHO} " NEED_PROXY = $NEED_PROXY" 1088 fi 1089 1090 # Service Search Descriptors are a special case. 1091 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_SERV_SRCH_DES = $LDAP_SERV_SRCH_DES" 1092} 1093 1094 1095# 1096# load_config_file(): Loads the config file. 1097# 1098load_config_file() 1099{ 1100 [ $DEBUG -eq 1 ] && ${ECHO} "In load_config_file()" 1101 1102 # Remove SSD lines from input file before sourcing. 1103 # The SSD lines must be removed because some forms of the 1104 # data could cause SHELL errors. 1105 ${GREP} -v "LDAP_SERV_SRCH_DES=" ${INPUT_FILE} > ${TMPDIR}/inputfile.noSSD 1106 1107 # Source the input file. 1108 . ${TMPDIR}/inputfile.noSSD 1109 1110 # If LDAP_SUFFIX is no set, try to utilize LDAP_TREETOP since older 1111 # config files use LDAP_TREETOP 1112 LDAP_SUFFIX="${LDAP_SUFFIX:-$LDAP_TREETOP}" 1113 1114 # Save password to temporary file. 1115 save_password 1116 1117 # Create the SSD file. 1118 create_ssd_file 1119 1120 # Display FULL debugging info. 1121 disp_full_debug 1122} 1123 1124# 1125# save_password(): Save password to temporary file. 1126# 1127save_password() 1128{ 1129 cat > ${LDAP_ROOTPWF} <<EOF 1130${LDAP_ROOTPWD} 1131EOF 1132} 1133 1134###################################################################### 1135# FUNCTIONS FOR prompt_config_info() START HERE. 1136###################################################################### 1137 1138# 1139# get_ids_server(): Prompt for iDS server name. 1140# 1141get_ids_server() 1142{ 1143 while : 1144 do 1145 # Prompt for server name. 1146 get_ans "Enter the JES Directory Server's hostname to setup:" "$IDS_SERVER" 1147 IDS_SERVER="$ANS" 1148 1149 # Ping server to see if live. If valid break out of loop. 1150 ping $IDS_SERVER > /dev/null 2>&1 1151 if [ $? -eq 0 ]; then 1152 break 1153 fi 1154 1155 # Invalid server, enter a new name. 1156 ${ECHO} "ERROR: Server '${IDS_SERVER}' is invalid or unreachable." 1157 IDS_SERVER="" 1158 done 1159 1160 # Set SERVER_ARGS and LDAP_ARGS since values might of changed. 1161 SERVER_ARGS="-h ${IDS_SERVER} -p ${IDS_PORT}" 1162 LDAP_ARGS="${SERVER_ARGS} ${AUTH_ARGS}" 1163 export SERVER_ARGS 1164 1165} 1166 1167# 1168# get_ids_port(): Prompt for iDS port number. 1169# 1170get_ids_port() 1171{ 1172 # Get a valid iDS port number. 1173 while : 1174 do 1175 # Enter port number. 1176 get_number "Enter the port number for iDS (h=help):" "$IDS_PORT" "port_help" 1177 IDS_PORT=$ANS 1178 # Do a simple search to check hostname and port number. 1179 # If search returns SUCCESS, break out, host and port must 1180 # be valid. 1181 ${LDAPSEARCH} -h ${IDS_SERVER} -p ${IDS_PORT} -b "" -s base "objectclass=*" > /dev/null 2>&1 1182 if [ $? -eq 0 ]; then 1183 break 1184 fi 1185 1186 # Invalid host/port pair, Re-enter. 1187 ${ECHO} "ERROR: Invalid host or port: ${IDS_SERVER}:${IDS_PORT}, Please re-enter!" 1188 get_ids_server 1189 done 1190 1191 # Set SERVER_ARGS and LDAP_ARGS since values might of changed. 1192 SERVER_ARGS="-h ${IDS_SERVER} -p ${IDS_PORT}" 1193 LDAP_ARGS="${SERVER_ARGS} ${AUTH_ARGS}" 1194 export SERVER_ARGS 1195} 1196 1197 1198# 1199# chk_ids_version(): Read the slapd config file and set variables 1200# 1201chk_ids_version() 1202{ 1203 [ $DEBUG -eq 1 ] && ${ECHO} "In chk_ids_version()" 1204 1205 # check iDS version number. 1206 eval "${LDAPSEARCH} ${SERVER_ARGS} -b cn=monitor -s base \"objectclass=*\" version | ${GREP} \"^version=\" | cut -f2 -d'/' | cut -f1 -d' ' > ${TMPDIR}/checkDSver 2>&1" 1207 if [ $? -ne 0 ]; then 1208 ${ECHO} "ERROR: Can not determine the version number of iDS!" 1209 exit 1 1210 fi 1211 IDS_VER=`cat ${TMPDIR}/checkDSver` 1212 IDS_MAJVER=`${ECHO} ${IDS_VER} | cut -f1 -d.` 1213 IDS_MINVER=`${ECHO} ${IDS_VER} | cut -f2 -d.` 1214 if [ "${IDS_MAJVER}" != "5" ] && [ "${IDS_MAJVER}" != "6" ]; then 1215 ${ECHO} "ERROR: $PROG only works with JES DS version 5.x and 6.x, not ${IDS_VER}." 1216 exit 1 1217 fi 1218 if [ $DEBUG -eq 1 ]; then 1219 ${ECHO} " IDS_MAJVER = $IDS_MAJVER" 1220 ${ECHO} " IDS_MINVER = $IDS_MINVER" 1221 fi 1222} 1223 1224 1225# 1226# get_dirmgr_dn(): Get the directory manger DN. 1227# 1228get_dirmgr_dn() 1229{ 1230 get_ans "Enter the directory manager DN:" "$LDAP_ROOTDN" 1231 LDAP_ROOTDN=$ANS 1232 1233 # Update ENV variables using DN. 1234 AUTH_ARGS="-D \"${LDAP_ROOTDN}\" -j ${LDAP_ROOTPWF}" 1235 LDAP_ARGS="${SERVER_ARGS} ${AUTH_ARGS}" 1236 export AUTH_ARGS LDAP_ARGS 1237} 1238 1239 1240# 1241# get_dirmgr_pw(): Get the Root DN passwd. (Root DN found in slapd.conf) 1242# 1243get_dirmgr_pw() 1244{ 1245 while : 1246 do 1247 # Get passwd. 1248 get_passwd_nochk "Enter passwd for ${LDAP_ROOTDN} :" 1249 LDAP_ROOTPWD=$ANS 1250 1251 # Store password in file. 1252 save_password 1253 1254 # Update ENV variables using DN's PW. 1255 AUTH_ARGS="-D \"${LDAP_ROOTDN}\" -j ${LDAP_ROOTPWF}" 1256 LDAP_ARGS="${SERVER_ARGS} ${AUTH_ARGS}" 1257 export AUTH_ARGS LDAP_ARGS 1258 1259 # Verify that ROOTDN and ROOTPWD are valid. 1260 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"\" -s base \"objectclass=*\" > ${TMPDIR}/checkDN 2>&1" 1261 if [ $? -ne 0 ]; then 1262 eval "${GREP} credential ${TMPDIR}/checkDN ${VERB}" 1263 if [ $? -eq 0 ]; then 1264 ${ECHO} "ERROR: Root DN passwd is invalid." 1265 else 1266 ${ECHO} "ERROR: Invalid Root DN <${LDAP_ROOTDN}>." 1267 get_dirmgr_dn 1268 fi 1269 else 1270 break # Both are valid. 1271 fi 1272 done 1273 1274 1275} 1276 1277 1278# 1279# get_domain(): Get the Domain that will be served by the LDAP server. 1280# $1 - Help argument. 1281# 1282get_domain() 1283{ 1284 # Use LDAP_DOMAIN as default. 1285 get_ans "Enter the domainname to be served (h=help):" $LDAP_DOMAIN 1286 1287 # Check domainname, and have user re-enter if not valid. 1288 check_domainname $ANS 1289 while [ $? -ne 0 ] 1290 do 1291 case "$ANS" in 1292 [Hh] | help | Help | \?) display_msg ${1:-sorry} ;; 1293 * ) ${ECHO} "Invalid domainname: \"${ANS}\"." 1294 ;; 1295 esac 1296 get_ans "Enter domainname to be served (h=help):" $DOM 1297 1298 check_domainname $ANS 1299 done 1300 1301 # Set the domainname to valid name. 1302 LDAP_DOMAIN=$ANS 1303} 1304 1305 1306# 1307# get_basedn(): Query for the Base DN. 1308# 1309get_basedn() 1310{ 1311 # Set the $_DOM_2_DC and assign to LDAP_BASEDN as default. 1312 # Then call get_basedn(). This method remakes the default 1313 # each time just in case the domain changed. 1314 domain_2_dc $LDAP_DOMAIN 1315 LDAP_BASEDN=$_DOM_2_DC 1316 1317 # Get Base DN. 1318 while : 1319 do 1320 get_ans_req "Enter LDAP Base DN (h=help):" "${_DOM_2_DC}" 1321 check_baseDN "$ANS" 1322 while [ $? -ne 0 ] 1323 do 1324 case "$ANS" in 1325 [Hh] | help | Help | \?) display_msg basedn_help ;; 1326 * ) ${ECHO} "Invalid base DN: \"${ANS}\"." 1327 ;; 1328 esac 1329 1330 # Re-Enter the BaseDN 1331 get_ans_req "Enter LDAP Base DN (h=help):" "${_DOM_2_DC}" 1332 check_baseDN "$ANS" 1333 done 1334 1335 # Set base DN and check its suffix 1336 LDAP_BASEDN=${ANS} 1337 check_basedn_suffix || 1338 { 1339 cleanup 1340 exit 1 1341 } 1342 1343 # suffix may need to be created, in that case get suffix from user 1344 [ -n "${NEED_CREATE_SUFFIX}" ] && 1345 { 1346 get_suffix || continue 1347 } 1348 1349 # suffix is ok, break out of the base dn inquire loop 1350 break 1351 done 1352} 1353 1354get_krb_realm() { 1355 1356 # To upper cases 1357 LDAP_KRB_REALM=`${ECHO} ${LDAP_DOMAIN} | ${NAWK} '{ print toupper($0) }'` 1358 get_ans_req "Enter Kerberos Realm:" "$LDAP_KRB_REALM" 1359 # To upper cases 1360 LDAP_KRB_REALM=`${ECHO} ${ANS} | ${NAWK} '{ print toupper($0) }'` 1361} 1362 1363# $1: DN 1364# $2: ldif file 1365add_entry_by_DN() { 1366 1367 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} -b \"${1}\" -s base \"objectclass=*\" ${VERB}" 1368 if [ $? -eq 0 ]; then 1369 ${ECHO} " ${1} already exists" 1370 return 0 1371 else 1372 ${EVAL} "${LDAPADD} ${LDAP_ARGS} -f ${2} ${VERB}" 1373 if [ $? -eq 0 ]; then 1374 ${ECHO} " ${1} is added" 1375 return 0 1376 else 1377 ${ECHO} " ERROR: failed to add ${1}" 1378 return 1 1379 fi 1380 fi 1381 1382} 1383# 1384# Kerberos princiapl to DN mapping rules 1385# 1386# Add rules for host credentails and user credentials 1387# 1388add_id_mapping_rules() { 1389 1390 ${ECHO} " Adding Kerberos principal to DN mapping rules..." 1391 1392 _C_DN="cn=GSSAPI,cn=identity mapping,cn=config" 1393 ( cat << EOF 1394dn: cn=GSSAPI,cn=identity mapping,cn=config 1395objectClass: top 1396objectClass: nsContainer 1397cn: GSSAPI 1398EOF 1399) > ${TMPDIR}/GSSAPI_container.ldif 1400 1401 add_entry_by_DN "${_C_DN}" "${TMPDIR}/GSSAPI_container.ldif" 1402 if [ $? -ne 0 ]; 1403 then 1404 ${RM} ${TMPDIR}/GSSAPI_container.ldif 1405 return 1406 fi 1407 1408 _H_CN="host_auth_${LDAP_KRB_REALM}" 1409 _H_DN="cn=${_H_CN}, ${_C_DN}" 1410 ( cat << EOF 1411dn: ${_H_DN} 1412objectClass: top 1413objectClass: nsContainer 1414objectClass: dsIdentityMapping 1415objectClass: dsPatternMatching 1416cn: ${_H_CN} 1417dsMatching-pattern: \${Principal} 1418dsMatching-regexp: host\/(.*).${LDAP_DOMAIN}@${LDAP_KRB_REALM} 1419dsSearchBaseDN: ou=hosts,${LDAP_BASEDN} 1420dsSearchFilter: (&(objectClass=ipHost)(cn=\$1)) 1421dsSearchScope: one 1422 1423EOF 1424) > ${TMPDIR}/${_H_CN}.ldif 1425 1426 add_entry_by_DN "${_H_DN}" "${TMPDIR}/${_H_CN}.ldif" 1427 1428 _U_CN="user_auth_${LDAP_KRB_REALM}" 1429 _U_DN="cn=${_U_CN}, ${_C_DN}" 1430 ( cat << EOF 1431dn: ${_U_DN} 1432objectClass: top 1433objectClass: nsContainer 1434objectClass: dsIdentityMapping 1435objectClass: dsPatternMatching 1436cn: ${_U_CN} 1437dsMatching-pattern: \${Principal} 1438dsMatching-regexp: (.*)@${LDAP_KRB_REALM} 1439dsMappedDN: uid=\$1,ou=People,${LDAP_BASEDN} 1440 1441EOF 1442) > ${TMPDIR}/${_U_CN}.ldif 1443 1444 add_entry_by_DN "${_U_DN}" "${TMPDIR}/${_U_CN}.ldif" 1445 1446} 1447 1448 1449# 1450# Modify ACL to allow root to read all the password and only self can read 1451# its own password when sasl/GSSAPI bind is used 1452# 1453modify_userpassword_acl_for_gssapi() { 1454 1455 _P_DN="ou=People,${LDAP_BASEDN}" 1456 _H_DN="ou=Hosts,${LDAP_BASEDN}" 1457 _P_ACI="self-read-pwd" 1458 1459 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} -b \"${_P_DN}\" -s base \"objectclass=*\" > /dev/null 2>&1" 1460 if [ $? -ne 0 ]; then 1461 ${ECHO} " ${_P_DN} does not exist" 1462 # Not Found. Create a new entry 1463 ( cat << EOF 1464dn: ${_P_DN} 1465ou: People 1466objectClass: top 1467objectClass: organizationalUnit 1468EOF 1469) > ${TMPDIR}/gssapi_people.ldif 1470 1471 add_entry_by_DN "${_P_DN}" "${TMPDIR}/gssapi_people.ldif" 1472 else 1473 ${ECHO} " ${_P_DN} already exists" 1474 fi 1475 1476 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} -b \"${_P_DN}\" -s base \"objectclass=*\" aci > ${TMPDIR}/chk_gssapi_aci 2>&1" 1477 1478 if [ $? -eq 0 ]; then 1479 ${EVAL} "${GREP} ${_P_ACI} ${TMPDIR}/chk_gssapi_aci > /dev/null 2>&1" 1480 if [ $? -eq 0 ]; then 1481 ${ECHO} " userpassword ACL ${_P_ACI} already exists." 1482 return 1483 else 1484 ${ECHO} " userpassword ACL ${_P_ACI} not found. Create a new one." 1485 fi 1486 else 1487 ${ECHO} " Error searching aci for ${_P_DN}" 1488 cat ${TMPDIR}/chk_gssapi_aci 1489 cleanup 1490 exit 1 1491 fi 1492 ( cat << EOF 1493dn: ${_P_DN} 1494changetype: modify 1495add: aci 1496aci: (targetattr="userPassword")(version 3.0; acl self-read-pwd; allow (read,search) userdn="ldap:///self" and authmethod="sasl GSSAPI";) 1497- 1498add: aci 1499aci: (targetattr="userPassword")(version 3.0; acl host-read-pwd; allow (read,search) userdn="ldap:///cn=*+ipHostNumber=*,ou=Hosts,${LDAP_BASEDN}" and authmethod="sasl GSSAPI";) 1500EOF 1501) > ${TMPDIR}/user_gssapi.ldif 1502 LDAP_TYPE_OR_VALUE_EXISTS=20 1503 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/user_gssapi.ldif ${VERB}" 1504 1505 case $? in 1506 0) 1507 ${ECHO} " ${_P_DN} uaserpassword ACL is updated." 1508 ;; 1509 20) 1510 ${ECHO} " ${_P_DN} uaserpassword ACL already exists." 1511 ;; 1512 *) 1513 ${ECHO} " ERROR: update of userpassword ACL for ${_P_DN} failed!" 1514 cleanup 1515 exit 1 1516 ;; 1517 esac 1518} 1519# 1520# $1: objectclass or attributetyp 1521# $2: name 1522search_update_schema() { 1523 1524 ATTR="${1}es" 1525 1526 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} -b cn=schema -s base \"objectclass=*\" ${ATTR} | ${GREP} -i \"${2}\" ${VERB}" 1527 if [ $? -ne 0 ]; then 1528 ${ECHO} "${1} ${2} does not exist." 1529 update_schema_attr 1530 update_schema_obj 1531 SCHEMA_UPDATED=1 1532 else 1533 ${ECHO} "${1} ${2} already exists. Schema has been updated" 1534 fi 1535} 1536 1537# 1538# $1: 1 - interactive, 0 - no 1539# 1540create_gssapi_profile() { 1541 1542 1543 if [ ${1} -eq 1 ]; then 1544 echo 1545 echo "You can create a sasl/GSSAPI enabled profile with default values now." 1546 get_confirm "Do you want to create a sasl/GSSAPI default profile ?" "n" 1547 1548 if [ $? -eq 0 ]; then 1549 return 1550 fi 1551 fi 1552 1553 # Add profile container if it does not exist 1554 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"ou=profile,${LDAP_BASEDN}\" -s base \"objectclass=*\" > /dev/null 2>&1" 1555 if [ $? -ne 0 ]; then 1556 ( cat << EOF 1557dn: ou=profile,${LDAP_BASEDN} 1558ou: profile 1559objectClass: top 1560objectClass: organizationalUnit 1561EOF 1562) > ${TMPDIR}/profile_people.ldif 1563 1564 add_entry_by_DN "ou=profile,${LDAP_BASEDN}" "${TMPDIR}/profile_people.ldif" 1565 1566 fi 1567 1568 search_update_schema "objectclass" "DUAConfigProfile" 1569 1570 _P_NAME="gssapi_${LDAP_KRB_REALM}" 1571 if [ ${1} -eq 1 ]; then 1572 _P_TMP=${LDAP_PROFILE_NAME} 1573 LDAP_PROFILE_NAME=${_P_NAME} 1574 get_profile_name 1575 LDAP_GSSAPI_PROFILE=${LDAP_PROFILE_NAME} 1576 LDAP_PROFILE_NAME=${_P_TMP} 1577 fi 1578 1579 _P_DN="cn=${LDAP_GSSAPI_PROFILE},ou=profile,${LDAP_BASEDN}" 1580 if [ ${DEL_OLD_PROFILE} -eq 1 ]; then 1581 DEL_OLD_PROFILE=0 1582 ${EVAL} "${LDAPDELETE} ${LDAP_ARGS} ${_P_DN} ${VERB}" 1583 fi 1584 1585 _SVR=`getent hosts ${IDS_SERVER} | ${NAWK} '{ print $1 }'` 1586 if [ ${IDS_PORT} -ne 389 ]; then 1587 _SVR="${_SVR}:${IDS_PORT}" 1588 fi 1589 1590 (cat << EOF 1591dn: ${_P_DN} 1592objectClass: top 1593objectClass: DUAConfigProfile 1594defaultServerList: ${_SVR} 1595defaultSearchBase: ${LDAP_BASEDN} 1596authenticationMethod: sasl/GSSAPI 1597followReferrals: ${LDAP_FOLLOWREF} 1598defaultSearchScope: ${LDAP_SEARCH_SCOPE} 1599searchTimeLimit: ${LDAP_SEARCH_TIME_LIMIT} 1600profileTTL: ${LDAP_PROFILE_TTL} 1601cn: ${LDAP_GSSAPI_PROFILE} 1602credentialLevel: self 1603bindTimeLimit: ${LDAP_BIND_LIMIT} 1604EOF 1605) > ${TMPDIR}/gssapi_profile.ldif 1606 1607 add_entry_by_DN "${_P_DN}" "${TMPDIR}/gssapi_profile.ldif" 1608 1609} 1610# 1611# Set up GSSAPI if necessary 1612# 1613gssapi_setup() { 1614 1615 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} -b \"\" -s base \"objectclass=*\" supportedSASLMechanisms | ${GREP} GSSAPI ${VERB}" 1616 if [ $? -ne 0 ]; then 1617 ${ECHO} " sasl/GSSAPI is not supported by this LDAP server" 1618 return 1619 fi 1620 1621 get_confirm "GSSAPI is supported. Do you want to set up gssapi:(y/n)" "n" 1622 if [ $? -eq 0 ]; then 1623 ${ECHO} 1624 ${ECHO} "GSSAPI is not set up." 1625 ${ECHO} "sasl/GSSAPI bind may not workif it's not set up before." 1626 else 1627 get_krb_realm 1628 add_id_mapping_rules 1629 modify_userpassword_acl_for_gssapi 1630 create_gssapi_profile 1 1631 ${ECHO} 1632 ${ECHO} "GSSAPI setup is done." 1633 fi 1634 1635 cat << EOF 1636 1637You can continue to create a profile and 1638configure the LDAP server. 1639Or you can stop now. 1640 1641EOF 1642 get_confirm "Do you want to stop:(y/n)" "n" 1643 if [ $? -eq 1 ]; then 1644 cleanup 1645 exit 1646 fi 1647 1648} 1649gssapi_setup_auto() { 1650 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} -b \"\" -s base \"objectclass=*\" supportedSASLMechanisms | ${GREP} GSSAPI ${VERB}" 1651 if [ $? -ne 0 ]; then 1652 ${ECHO} 1653 ${ECHO} "sasl/GSSAPI is not supported by this LDAP server" 1654 ${ECHO} 1655 return 1656 fi 1657 if [ -z "${LDAP_KRB_REALM}" ]; then 1658 ${ECHO} 1659 ${ECHO} "LDAP_KRB_REALM is not set. Skip gssapi setup." 1660 ${ECHO} "sasl/GSSAPI bind won't work properly." 1661 ${ECHO} 1662 return 1663 fi 1664 if [ -z "${LDAP_GSSAPI_PROFILE}" ]; then 1665 ${ECHO} 1666 ${ECHO} "LDAP_GSSAPI_PROFILE is not set. Default is gssapi_${LDAP_KRB_REALM}" 1667 ${ECHO} 1668 LDAP_GSSAPI_PROFILE="gssapi_${LDAP_KRB_REALM}" 1669 fi 1670 add_id_mapping_rules 1671 modify_userpassword_acl_for_gssapi 1672 create_gssapi_profile 0 1673} 1674# get_profile_name(): Enter the profile name. 1675# 1676get_profile_name() 1677{ 1678 # Reset Delete Old Profile since getting new profile name. 1679 DEL_OLD_PROFILE=0 1680 1681 # Loop until valid profile name, or replace. 1682 while : 1683 do 1684 # Prompt for profile name. 1685 get_ans "Enter the profile name (h=help):" "$LDAP_PROFILE_NAME" 1686 1687 # Check for Help. 1688 case "$ANS" in 1689 [Hh] | help | Help | \?) display_msg profile_help 1690 continue ;; 1691 * ) ;; 1692 esac 1693 1694 # Search to see if profile name already exists. 1695 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"cn=${ANS},ou=profile,${LDAP_BASEDN}\" -s base \"objectclass=*\" ${VERB}" 1696 if [ $? -eq 0 ]; then 1697 get_confirm_nodef "Are you sure you want to overwire profile cn=${ANS}?" 1698 if [ $? -eq 1 ]; then 1699 DEL_OLD_PROFILE=1 1700 return 0 # Replace old profile name. 1701 else 1702 ${ECHO} "Please re-enter a new profile name." 1703 fi 1704 else 1705 break # Unique profile name. 1706 fi 1707 done 1708 1709 # Set Profile Name. 1710 LDAP_PROFILE_NAME=$ANS 1711} 1712 1713 1714# 1715# get_srv_list(): Get the default server list. 1716# 1717get_srv_list() 1718{ 1719 # If LDAP_SERVER_LIST is NULL, then set, otherwise leave alone. 1720 if [ -z "${LDAP_SERVER_LIST}" ]; then 1721 LDAP_SERVER_LIST=`getent hosts ${IDS_SERVER} | awk '{print $1}'` 1722 if [ ${IDS_PORT} -ne 389 ]; then 1723 LDAP_SERVER_LIST="${LDAP_SERVER_LIST}:${IDS_PORT}" 1724 fi 1725 fi 1726 1727 # Prompt for new LDAP_SERVER_LIST. 1728 while : 1729 do 1730 get_ans "Default server list (h=help):" $LDAP_SERVER_LIST 1731 1732 # If help continue, otherwise break. 1733 case "$ANS" in 1734 [Hh] | help | Help | \?) display_msg def_srvlist_help ;; 1735 * ) break ;; 1736 esac 1737 done 1738 LDAP_SERVER_LIST=$ANS 1739} 1740 1741 1742# 1743# get_pref_srv(): The preferred server list (Overrides the server list) 1744# 1745get_pref_srv() 1746{ 1747 while : 1748 do 1749 get_ans "Preferred server list (h=help):" $LDAP_PREF_SRVLIST 1750 1751 # If help continue, otherwise break. 1752 case "$ANS" in 1753 [Hh] | help | Help | \?) display_msg pref_srvlist_help ;; 1754 * ) break ;; 1755 esac 1756 done 1757 LDAP_PREF_SRVLIST=$ANS 1758} 1759 1760 1761# 1762# get_search_scope(): Get the search scope from the user. 1763# 1764get_search_scope() 1765{ 1766 [ $DEBUG -eq 1 ] && ${ECHO} "In get_search_scope()" 1767 1768 _MENU_CHOICE=0 1769 while : 1770 do 1771 get_ans "Choose desired search scope (one, sub, h=help): " "one" 1772 _MENU_CHOICE=$ANS 1773 case "$_MENU_CHOICE" in 1774 one) LDAP_SEARCH_SCOPE="one" 1775 return 1 ;; 1776 sub) LDAP_SEARCH_SCOPE="sub" 1777 return 2 ;; 1778 h) display_msg srch_scope_help ;; 1779 *) ${ECHO} "Please enter \"one\", \"sub\", or \"h\"." ;; 1780 esac 1781 done 1782 1783} 1784 1785 1786# 1787# get_cred_level(): Function to display menu to user and get the 1788# credential level. 1789# 1790get_cred_level() 1791{ 1792 [ $DEBUG -eq 1 ] && ${ECHO} "In get_cred_level()" 1793 1794 _MENU_CHOICE=0 1795 display_msg cred_level_menu 1796 while : 1797 do 1798 get_ans "Choose Credential level [h=help]:" "1" 1799 _MENU_CHOICE=$ANS 1800 case "$_MENU_CHOICE" in 1801 1) LDAP_CRED_LEVEL="anonymous" 1802 return 1 ;; 1803 2) LDAP_CRED_LEVEL="proxy" 1804 return 2 ;; 1805 3) LDAP_CRED_LEVEL="proxy anonymous" 1806 return 3 ;; 1807 4) LDAP_CRED_LEVEL="self" 1808 SELF_GSSAPI=1 1809 return 4 ;; 1810 5) LDAP_CRED_LEVEL="self proxy" 1811 SELF_GSSAPI=1 1812 return 5 ;; 1813 6) LDAP_CRED_LEVEL="self proxy anonymous" 1814 SELF_GSSAPI=1 1815 return 6 ;; 1816 h) display_msg cred_lvl_help ;; 1817 *) ${ECHO} "Please enter 1, 2, 3, 4, 5 or 6." ;; 1818 esac 1819 done 1820} 1821 1822 1823# 1824# srvauth_menu_handler(): Enter the Service Authentication method. 1825# 1826srvauth_menu_handler() 1827{ 1828 # Display Auth menu 1829 display_msg srvauth_method_menu 1830 1831 # Get a Valid choice. 1832 while : 1833 do 1834 # Display appropriate prompt and get answer. 1835 if [ $_FIRST -eq 1 ]; then 1836 get_ans "Choose Service Authentication Method:" "1" 1837 else 1838 get_ans "Choose Service Authentication Method (0=reset):" 1839 fi 1840 1841 # Determine choice. 1842 _MENU_CHOICE=$ANS 1843 case "$_MENU_CHOICE" in 1844 1) _AUTHMETHOD="simple" 1845 break ;; 1846 2) _AUTHMETHOD="sasl/DIGEST-MD5" 1847 break ;; 1848 3) _AUTHMETHOD="tls:simple" 1849 break ;; 1850 4) _AUTHMETHOD="tls:sasl/DIGEST-MD5" 1851 break ;; 1852 5) _AUTHMETHOD="sasl/GSSAPI" 1853 break ;; 1854 0) _AUTHMETHOD="" 1855 _FIRST=1 1856 break ;; 1857 *) ${ECHO} "Please enter 1-5 or 0 to reset." ;; 1858 esac 1859 done 1860} 1861 1862 1863# 1864# auth_menu_handler(): Enter the Authentication method. 1865# 1866auth_menu_handler() 1867{ 1868 # Display Auth menu 1869 display_msg auth_method_menu 1870 1871 # Get a Valid choice. 1872 while : 1873 do 1874 # Display appropriate prompt and get answer. 1875 if [ $_FIRST -eq 1 ]; then 1876 get_ans "Choose Authentication Method (h=help):" "1" 1877 else 1878 get_ans "Choose Authentication Method (0=reset, h=help):" 1879 fi 1880 1881 # Determine choice. 1882 _MENU_CHOICE=$ANS 1883 case "$_MENU_CHOICE" in 1884 1) _AUTHMETHOD="none" 1885 break ;; 1886 2) _AUTHMETHOD="simple" 1887 break ;; 1888 3) _AUTHMETHOD="sasl/DIGEST-MD5" 1889 break ;; 1890 4) _AUTHMETHOD="tls:simple" 1891 break ;; 1892 5) _AUTHMETHOD="tls:sasl/DIGEST-MD5" 1893 break ;; 1894 6) _AUTHMETHOD="sasl/GSSAPI" 1895 break ;; 1896 0) _AUTHMETHOD="" 1897 _FIRST=1 1898 break ;; 1899 h) display_msg auth_help ;; 1900 *) ${ECHO} "Please enter 1-6, 0=reset, or h=help." ;; 1901 esac 1902 done 1903} 1904 1905 1906# 1907# get_auth(): Enter the Authentication method. 1908# 1909get_auth() 1910{ 1911 [ $DEBUG -eq 1 ] && ${ECHO} "In get_auth()" 1912 1913 _FIRST=1 # Flag for first time. 1914 _MENU_CHOICE=0 1915 _AUTHMETHOD="" # Tmp method. 1916 1917 while : 1918 do 1919 # Call Menu handler 1920 auth_menu_handler 1921 1922 # Add Auth Method to list. 1923 if [ $_FIRST -eq 1 ]; then 1924 LDAP_AUTHMETHOD="${_AUTHMETHOD}" 1925 _FIRST=0 1926 else 1927 LDAP_AUTHMETHOD="${LDAP_AUTHMETHOD};${_AUTHMETHOD}" 1928 fi 1929 1930 # Display current Authentication Method. 1931 ${ECHO} "" 1932 ${ECHO} "Current authenticationMethod: ${LDAP_AUTHMETHOD}" 1933 ${ECHO} "" 1934 1935 # Prompt for another Auth Method, or break out. 1936 get_confirm_nodef "Do you want to add another Authentication Method?" 1937 if [ $? -eq 0 ]; then 1938 break; 1939 fi 1940 done 1941} 1942 1943 1944# 1945# get_followref(): Whether or not to follow referrals. 1946# 1947get_followref() 1948{ 1949 get_confirm "Do you want the clients to follow referrals (y/n/h)?" "n" "referrals_help" 1950 if [ $? -eq 1 ]; then 1951 LDAP_FOLLOWREF="TRUE" 1952 else 1953 LDAP_FOLLOWREF="FALSE" 1954 fi 1955} 1956 1957 1958# 1959# get_timelimit(): Set the time limit. -1 is max time. 1960# 1961get_timelimit() 1962{ 1963 # Get current timeout value from cn=config. 1964 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"cn=config\" -s base \"objectclass=*\" nsslapd-timelimit > ${TMPDIR}/chk_timeout 2>&1" 1965 if [ $? -ne 0 ]; then 1966 ${ECHO} " ERROR: Could not reach LDAP server to check current timeout!" 1967 cleanup 1968 exit 1 1969 fi 1970 CURR_TIMELIMIT=`${GREP} timelimit ${TMPDIR}/chk_timeout | cut -f2 -d=` 1971 1972 get_negone_num "Enter the time limit for iDS (current=${CURR_TIMELIMIT}):" "-1" 1973 IDS_TIMELIMIT=$NUM 1974} 1975 1976 1977# 1978# get_sizelimit(): Set the size limit. -1 is max size. 1979# 1980get_sizelimit() 1981{ 1982 # Get current sizelimit value from cn=config. 1983 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"cn=config\" -s base \"objectclass=*\" nsslapd-sizelimit > ${TMPDIR}/chk_sizelimit 2>&1" 1984 if [ $? -ne 0 ]; then 1985 ${ECHO} " ERROR: Could not reach LDAP server to check current sizelimit!" 1986 cleanup 1987 exit 1 1988 fi 1989 CURR_SIZELIMIT=`${GREP} sizelimit ${TMPDIR}/chk_sizelimit | cut -f2 -d=` 1990 1991 get_negone_num "Enter the size limit for iDS (current=${CURR_SIZELIMIT}):" "-1" 1992 IDS_SIZELIMIT=$NUM 1993} 1994 1995 1996# 1997# get_want_crypt(): Ask user if want to store passwords in crypt? 1998# 1999get_want_crypt() 2000{ 2001 get_confirm "Do you want to store passwords in \"crypt\" format (y/n/h)?" "n" "crypt_help" 2002 if [ $? -eq 1 ]; then 2003 NEED_CRYPT="TRUE" 2004 else 2005 NEED_CRYPT="FALSE" 2006 fi 2007} 2008 2009 2010# 2011# get_srv_authMethod_pam(): Get the Service Auth Method for pam_ldap from user. 2012# 2013# NOTE: This function is base on get_auth(). 2014# 2015get_srv_authMethod_pam() 2016{ 2017 [ $DEBUG -eq 1 ] && ${ECHO} "In get_srv_authMethod_pam()" 2018 2019 _FIRST=1 # Flag for first time. 2020 _MENU_CHOICE=0 2021 _AUTHMETHOD="" # Tmp method. 2022 2023 while : 2024 do 2025 # Call Menu handler 2026 srvauth_menu_handler 2027 2028 # Add Auth Method to list. 2029 if [ $_FIRST -eq 1 ]; then 2030 if [ "$_AUTHMETHOD" = "" ]; then 2031 LDAP_SRV_AUTHMETHOD_PAM="" 2032 else 2033 LDAP_SRV_AUTHMETHOD_PAM="pam_ldap:${_AUTHMETHOD}" 2034 fi 2035 _FIRST=0 2036 else 2037 LDAP_SRV_AUTHMETHOD_PAM="${LDAP_SRV_AUTHMETHOD_PAM};${_AUTHMETHOD}" 2038 fi 2039 2040 # Display current Authentication Method. 2041 ${ECHO} "" 2042 ${ECHO} "Current authenticationMethod: ${LDAP_SRV_AUTHMETHOD_PAM}" 2043 ${ECHO} "" 2044 2045 # Prompt for another Auth Method, or break out. 2046 get_confirm_nodef "Do you want to add another Authentication Method?" 2047 if [ $? -eq 0 ]; then 2048 break; 2049 fi 2050 done 2051 2052 # Check in case user reset string and exited loop. 2053 if [ "$LDAP_SRV_AUTHMETHOD_PAM" = "" ]; then 2054 NEED_SRVAUTH_PAM=0 2055 fi 2056} 2057 2058 2059# 2060# get_srv_authMethod_key(): Get the Service Auth Method for keyserv from user. 2061# 2062# NOTE: This function is base on get_auth(). 2063# 2064get_srv_authMethod_key() 2065{ 2066 [ $DEBUG -eq 1 ] && ${ECHO} "In get_srv_authMethod_key()" 2067 2068 _FIRST=1 # Flag for first time. 2069 _MENU_CHOICE=0 2070 _AUTHMETHOD="" # Tmp method. 2071 2072 while : 2073 do 2074 # Call Menu handler 2075 srvauth_menu_handler 2076 2077 # Add Auth Method to list. 2078 if [ $_FIRST -eq 1 ]; then 2079 if [ "$_AUTHMETHOD" = "" ]; then 2080 LDAP_SRV_AUTHMETHOD_KEY="" 2081 else 2082 LDAP_SRV_AUTHMETHOD_KEY="keyserv:${_AUTHMETHOD}" 2083 fi 2084 _FIRST=0 2085 else 2086 LDAP_SRV_AUTHMETHOD_KEY="${LDAP_SRV_AUTHMETHOD_KEY};${_AUTHMETHOD}" 2087 fi 2088 2089 # Display current Authentication Method. 2090 ${ECHO} "" 2091 ${ECHO} "Current authenticationMethod: ${LDAP_SRV_AUTHMETHOD_KEY}" 2092 ${ECHO} "" 2093 2094 # Prompt for another Auth Method, or break out. 2095 get_confirm_nodef "Do you want to add another Authentication Method?" 2096 if [ $? -eq 0 ]; then 2097 break; 2098 fi 2099 done 2100 2101 # Check in case user reset string and exited loop. 2102 if [ "$LDAP_SRV_AUTHMETHOD_KEY" = "" ]; then 2103 NEED_SRVAUTH_KEY=0 2104 fi 2105} 2106 2107 2108# 2109# get_srv_authMethod_cmd(): Get the Service Auth Method for passwd-cmd from user. 2110# 2111# NOTE: This function is base on get_auth(). 2112# 2113get_srv_authMethod_cmd() 2114{ 2115 [ $DEBUG -eq 1 ] && ${ECHO} "In get_srv_authMethod_cmd()" 2116 2117 _FIRST=1 # Flag for first time. 2118 _MENU_CHOICE=0 2119 _AUTHMETHOD="" # Tmp method. 2120 2121 while : 2122 do 2123 # Call Menu handler 2124 srvauth_menu_handler 2125 2126 # Add Auth Method to list. 2127 if [ $_FIRST -eq 1 ]; then 2128 if [ "$_AUTHMETHOD" = "" ]; then 2129 LDAP_SRV_AUTHMETHOD_CMD="" 2130 else 2131 LDAP_SRV_AUTHMETHOD_CMD="passwd-cmd:${_AUTHMETHOD}" 2132 fi 2133 _FIRST=0 2134 else 2135 LDAP_SRV_AUTHMETHOD_CMD="${LDAP_SRV_AUTHMETHOD_CMD};${_AUTHMETHOD}" 2136 fi 2137 2138 # Display current Authentication Method. 2139 ${ECHO} "" 2140 ${ECHO} "Current authenticationMethod: ${LDAP_SRV_AUTHMETHOD_CMD}" 2141 ${ECHO} "" 2142 2143 # Prompt for another Auth Method, or break out. 2144 get_confirm_nodef "Do you want to add another Authentication Method?" 2145 if [ $? -eq 0 ]; then 2146 break; 2147 fi 2148 done 2149 2150 # Check in case user reset string and exited loop. 2151 if [ "$LDAP_SRV_AUTHMETHOD_CMD" = "" ]; then 2152 NEED_SRVAUTH_CMD=0 2153 fi 2154} 2155 2156 2157# 2158# get_srch_time(): Amount of time to search. 2159# 2160get_srch_time() 2161{ 2162 get_negone_num "Client search time limit in seconds (h=help):" "$LDAP_SEARCH_TIME_LIMIT" "srchtime_help" 2163 LDAP_SEARCH_TIME_LIMIT=$NUM 2164} 2165 2166 2167# 2168# get_prof_ttl(): The profile time to live (TTL) 2169# 2170get_prof_ttl() 2171{ 2172 get_negone_num "Profile Time To Live in seconds (h=help):" "$LDAP_PROFILE_TTL" "profttl_help" 2173 LDAP_PROFILE_TTL=$NUM 2174} 2175 2176 2177# 2178# get_bind_limit(): Bind time limit 2179# 2180get_bind_limit() 2181{ 2182 get_negone_num "Bind time limit in seconds (h=help):" "$LDAP_BIND_LIMIT" "bindlim_help" 2183 LDAP_BIND_LIMIT=$NUM 2184} 2185 2186 2187###################################################################### 2188# FUNCTIONS FOR Service Search Descriptor's START HERE. 2189###################################################################### 2190 2191 2192# 2193# add_ssd(): Get SSD's from user and add to file. 2194# 2195add_ssd() 2196{ 2197 [ $DEBUG -eq 1 ] && ${ECHO} "In add_ssd()" 2198 2199 # Enter the service id. Loop til unique. 2200 while : 2201 do 2202 get_ans "Enter the service id:" 2203 _SERV_ID=$ANS 2204 2205 # Grep for name existing. 2206 ${GREP} -i "^$ANS:" ${SSD_FILE} > /dev/null 2>&1 2207 if [ $? -eq 1 ]; then 2208 break 2209 fi 2210 2211 # Name exists, print message, let user decide. 2212 ${ECHO} "ERROR: Service id ${ANS} already exists." 2213 done 2214 2215 get_ans "Enter the base:" 2216 _BASE=$ANS 2217 2218 # Get the scope and verify that its one or sub. 2219 while : 2220 do 2221 get_ans "Enter the scope:" 2222 _SCOPE=$ANS 2223 case `${ECHO} ${_SCOPE} | tr '[A-Z]' '[a-z]'` in 2224 one) break ;; 2225 sub) break ;; 2226 *) ${ECHO} "${_SCOPE} is Not valid - Enter 'one' or 'sub'" ;; 2227 esac 2228 done 2229 2230 # Build SSD to add to file. 2231 _SSD="${_SERV_ID}:${_BASE}?${_SCOPE}" 2232 2233 # Add the SSD to the file. 2234 ${ECHO} "${_SSD}" >> ${SSD_FILE} 2235} 2236 2237 2238# 2239# delete_ssd(): Delete a SSD from the list. 2240# 2241delete_ssd() 2242{ 2243 [ $DEBUG -eq 1 ] && ${ECHO} "In delete_ssd()" 2244 2245 # Get service id name from user for SSD to delete. 2246 get_ans_req "Enter service id to delete:" 2247 2248 # Make sure service id exists. 2249 ${GREP} "$ANS" ${SSD_FILE} > /dev/null 2>&1 2250 if [ $? -eq 1 ]; then 2251 ${ECHO} "Invalid service id: $ANS not present in list." 2252 return 2253 fi 2254 2255 # Create temporary back SSD file. 2256 cp ${SSD_FILE} ${SSD_FILE}.bak 2257 if [ $? -eq 1 ]; then 2258 ${ECHO} "ERROR: could not create file: ${SSD_FILE}.bak" 2259 exit 1 2260 fi 2261 2262 # Use ${GREP} to remove the SSD. Read from temp file 2263 # and write to the orig file. 2264 ${GREP} -v "$ANS" ${SSD_FILE}.bak > ${SSD_FILE} 2265} 2266 2267 2268# 2269# modify_ssd(): Allow user to modify a SSD. 2270# 2271modify_ssd() 2272{ 2273 [ $DEBUG -eq 1 ] && ${ECHO} "In modify_ssd()" 2274 2275 # Prompt user for service id. 2276 get_ans_req "Enter service id to modify:" 2277 2278 # Put into temp _LINE. 2279 _LINE=`${GREP} "^$ANS:" ${SSD_FILE}` 2280 if [ "$_LINE" = "" ]; then 2281 ${ECHO} "Invalid service id: $ANS" 2282 return 2283 fi 2284 2285 # Display current filter for user to see. 2286 ${ECHO} "" 2287 ${ECHO} "Current SSD: $_LINE" 2288 ${ECHO} "" 2289 2290 # Get the defaults. 2291 _CURR_BASE=`${ECHO} $_LINE | cut -d: -f2 | cut -d'?' -f 1` 2292 _CURR_SCOPE=`${ECHO} $_LINE | cut -d: -f2 | cut -d'?' -f 2` 2293 2294 # Create temporary back SSD file. 2295 cp ${SSD_FILE} ${SSD_FILE}.bak 2296 if [ $? -eq 1 ]; then 2297 ${ECHO} "ERROR: could not create file: ${SSD_FILE}.bak" 2298 cleanup 2299 exit 1 2300 fi 2301 2302 # Removed the old line. 2303 ${GREP} -v "^$ANS:" ${SSD_FILE}.bak > ${SSD_FILE} 2>&1 2304 2305 # New Entry 2306 _SERV_ID=$ANS 2307 get_ans_req "Enter the base:" "$_CURR_BASE" 2308 _BASE=$ANS 2309 get_ans_req "Enter the scope:" "$_CURR_SCOPE" 2310 _SCOPE=$ANS 2311 2312 # Build the new SSD. 2313 _SSD="${_SERV_ID}:${_BASE}?${_SCOPE}" 2314 2315 # Add the SSD to the file. 2316 ${ECHO} "${_SSD}" >> ${SSD_FILE} 2317} 2318 2319 2320# 2321# display_ssd(): Display the current SSD list. 2322# 2323display_ssd() 2324{ 2325 [ $DEBUG -eq 1 ] && ${ECHO} "In display_ssd()" 2326 2327 ${ECHO} "" 2328 ${ECHO} "Current Service Search Descriptors:" 2329 ${ECHO} "==================================" 2330 cat ${SSD_FILE} 2331 ${ECHO} "" 2332 ${ECHO} "Hit return to continue." 2333 read __A 2334} 2335 2336 2337# 2338# prompt_ssd(): Get SSD's from user. 2339# 2340prompt_ssd() 2341{ 2342 [ $DEBUG -eq 1 ] && ${ECHO} "In prompt_ssd()" 2343 # See if user wants SSD's? 2344 get_confirm "Do you wish to setup Service Search Descriptors (y/n/h)?" "n" "ssd_help" 2345 [ "$?" -eq 0 ] && return 2346 2347 # Display menu for SSD choices. 2348 while : 2349 do 2350 display_msg prompt_ssd_menu 2351 get_ans "Enter menu choice:" "Quit" 2352 case "$ANS" in 2353 [Aa] | add) add_ssd ;; 2354 [Dd] | delete) delete_ssd ;; 2355 [Mm] | modify) modify_ssd ;; 2356 [Pp] | print | display) display_ssd ;; 2357 [Xx] | reset | clear) reset_ssd_file ;; 2358 [Hh] | Help | help) display_msg ssd_menu_help 2359 ${ECHO} " Press return to continue." 2360 read __A ;; 2361 [Qq] | Quit | quit) return ;; 2362 *) ${ECHO} "Invalid choice: $ANS please re-enter from menu." ;; 2363 esac 2364 done 2365} 2366 2367 2368# 2369# reset_ssd_file(): Blank out current SSD file. 2370# 2371reset_ssd_file() 2372{ 2373 [ $DEBUG -eq 1 ] && ${ECHO} "In reset_ssd_file()" 2374 2375 rm -f ${SSD_FILE} 2376 touch ${SSD_FILE} 2377} 2378 2379 2380# 2381# create_ssd_file(): Create a temporary file for SSD's. 2382# 2383create_ssd_file() 2384{ 2385 [ $DEBUG -eq 1 ] && ${ECHO} "In create_ssd_file()" 2386 2387 # Build a list of SSD's and store in temp file. 2388 ${GREP} "LDAP_SERV_SRCH_DES=" ${INPUT_FILE} | \ 2389 sed 's/LDAP_SERV_SRCH_DES=//' \ 2390 > ${SSD_FILE} 2391} 2392 2393 2394# 2395# ssd_2_config(): Append the SSD file to the output file. 2396# 2397ssd_2_config() 2398{ 2399 [ $DEBUG -eq 1 ] && ${ECHO} "In ssd_2_config()" 2400 2401 # Convert to config file format using sed. 2402 sed -e "s/^/LDAP_SERV_SRCH_DES=/" ${SSD_FILE} >> ${OUTPUT_FILE} 2403} 2404 2405 2406# 2407# ssd_2_profile(): Add SSD's to the GEN_CMD string. 2408# 2409ssd_2_profile() 2410{ 2411 [ $DEBUG -eq 1 ] && ${ECHO} "In ssd_2_profile()" 2412 2413 GEN_TMPFILE=${TMPDIR}/ssd_tmpfile 2414 touch ${GEN_TMPFILE} 2415 2416 # Add and convert each SSD to string. 2417 while read SSD_LINE 2418 do 2419 ${ECHO} " -a \"serviceSearchDescriptor=${SSD_LINE}\"\c" >> ${GEN_TMPFILE} 2420 done <${SSD_FILE} 2421 2422 # Add SSD's to GEN_CMD. 2423 GEN_CMD="${GEN_CMD} `cat ${GEN_TMPFILE}`" 2424} 2425 2426 2427# 2428# prompt_config_info(): This function prompts the user for the config 2429# info that is not specified in the input file. 2430# 2431prompt_config_info() 2432{ 2433 [ $DEBUG -eq 1 ] && ${ECHO} "In prompt_config_info()" 2434 2435 # Prompt for iDS server name. 2436 get_ids_server 2437 2438 # Prompt for iDS port number. 2439 get_ids_port 2440 2441 # Check iDS version for compatibility. 2442 chk_ids_version 2443 2444 # Check if the server supports the VLV. 2445 chk_vlv_indexes 2446 2447 # Get the Directory manager DN and passwd. 2448 get_dirmgr_dn 2449 get_dirmgr_pw 2450 2451 # 2452 # LDAP CLIENT PROFILE SPECIFIC INFORMATION. 2453 # (i.e. The fields that show up in the profile.) 2454 # 2455 get_domain "domain_help" 2456 2457 get_basedn 2458 2459 gssapi_setup 2460 2461 get_profile_name 2462 get_srv_list 2463 get_pref_srv 2464 get_search_scope 2465 2466 # If cred is "anonymous", make auth == "none" 2467 get_cred_level 2468 if [ "$LDAP_CRED_LEVEL" != "anonymous" ]; then 2469 get_auth 2470 fi 2471 2472 get_followref 2473 2474 # Query user about timelimt. 2475 get_confirm "Do you want to modify the server timelimit value (y/n/h)?" "n" "tlim_help" 2476 NEED_TIME=$? 2477 [ $NEED_TIME -eq 1 ] && get_timelimit 2478 2479 # Query user about sizelimit. 2480 get_confirm "Do you want to modify the server sizelimit value (y/n/h)?" "n" "slim_help" 2481 NEED_SIZE=$? 2482 [ $NEED_SIZE -eq 1 ] && get_sizelimit 2483 2484 # Does the user want to store passwords in crypt format? 2485 get_want_crypt 2486 2487 # Prompt for any Service Authentication Methods? 2488 get_confirm "Do you want to setup a Service Authentication Methods (y/n/h)?" "n" "srvauth_help" 2489 if [ $? -eq 1 ]; then 2490 # Does the user want to set Service Authentication Method for pam_ldap? 2491 get_confirm "Do you want to setup a Service Auth. Method for \"pam_ldap\" (y/n/h)?" "n" "pam_ldap_help" 2492 NEED_SRVAUTH_PAM=$? 2493 [ $NEED_SRVAUTH_PAM -eq 1 ] && get_srv_authMethod_pam 2494 2495 # Does the user want to set Service Authentication Method for keyserv? 2496 get_confirm "Do you want to setup a Service Auth. Method for \"keyserv\" (y/n/h)?" "n" "keyserv_help" 2497 NEED_SRVAUTH_KEY=$? 2498 [ $NEED_SRVAUTH_KEY -eq 1 ] && get_srv_authMethod_key 2499 2500 # Does the user want to set Service Authentication Method for passwd-cmd? 2501 get_confirm "Do you want to setup a Service Auth. Method for \"passwd-cmd\" (y/n/h)?" "n" "passwd-cmd_help" 2502 NEED_SRVAUTH_CMD=$? 2503 [ $NEED_SRVAUTH_CMD -eq 1 ] && get_srv_authMethod_cmd 2504 fi 2505 2506 2507 # Get Timeouts 2508 get_srch_time 2509 get_prof_ttl 2510 get_bind_limit 2511 2512 # Reset the sdd_file and prompt user for SSD. Will use menus 2513 # to build an SSD File. 2514 reset_ssd_file 2515 prompt_ssd 2516 2517 # Display FULL debugging info. 2518 disp_full_debug 2519 2520 # Extra blank line to separate prompt lines from steps. 2521 ${ECHO} " " 2522} 2523 2524 2525###################################################################### 2526# FUNCTIONS FOR display_summary() START HERE. 2527###################################################################### 2528 2529 2530# 2531# get_proxyagent(): Get the proxyagent DN. 2532# 2533get_proxyagent() 2534{ 2535 LDAP_PROXYAGENT="cn=proxyagent,ou=profile,${LDAP_BASEDN}" # default 2536 get_ans "Enter DN for proxy agent:" "$LDAP_PROXYAGENT" 2537 LDAP_PROXYAGENT=$ANS 2538} 2539 2540 2541# 2542# get_proxy_pw(): Get the proxyagent passwd. 2543# 2544get_proxy_pw() 2545{ 2546 get_passwd "Enter passwd for proxyagent:" 2547 LDAP_PROXYAGENT_CRED=$ANS 2548} 2549 2550 2551# 2552# display_summary(): Display a summary of values entered and let the 2553# user modify values at will. 2554# 2555display_summary() 2556{ 2557 [ $DEBUG -eq 1 ] && ${ECHO} "In display_summary()" 2558 2559 # Create lookup table for function names. First entry is dummy for 2560 # shift. 2561 TBL1="dummy" 2562 TBL2="get_domain get_basedn get_profile_name" 2563 TBL3="get_srv_list get_pref_srv get_search_scope get_cred_level" 2564 TBL4="get_auth get_followref" 2565 TBL5="get_timelimit get_sizelimit get_want_crypt" 2566 TBL6="get_srv_authMethod_pam get_srv_authMethod_key get_srv_authMethod_cmd" 2567 TBL7="get_srch_time get_prof_ttl get_bind_limit" 2568 TBL8="prompt_ssd" 2569 FUNC_TBL="$TBL1 $TBL2 $TBL3 $TBL4 $TBL5 $TBL6 $TBL7 $TBL8" 2570 2571 # Since menu prompt string is long, set here. 2572 _MENU_PROMPT="Enter config value to change: (1-19 0=commit changes)" 2573 2574 # Infinite loop. Test for 0, and break in loop. 2575 while : 2576 do 2577 # Display menu and get value in range. 2578 display_msg summary_menu 2579 get_menu_choice "${_MENU_PROMPT}" "0" "19" "0" 2580 _CH=$MN_CH 2581 2582 # Make sure where not exiting. 2583 if [ $_CH -eq 0 ]; then 2584 break # Break out of loop if 0 selected. 2585 fi 2586 2587 # Call appropriate function from function table. 2588 set $FUNC_TBL 2589 shift $_CH 2590 $1 # Call the appropriate function. 2591 done 2592 2593 # If cred level is still see if user wants a change? 2594 if ${ECHO} "$LDAP_CRED_LEVEL" | ${GREP} "proxy" > /dev/null 2>&1 2595 then 2596 if [ "$LDAP_AUTHMETHOD" != "none" ]; then 2597 NEED_PROXY=1 # I assume integer test is faster? 2598 get_proxyagent 2599 get_proxy_pw 2600 else 2601 ${ECHO} "WARNING: Since Authentication method is 'none'." 2602 ${ECHO} " Credential level will be set to 'anonymous'." 2603 LDAP_CRED_LEVEL="anonymous" 2604 fi 2605 fi 2606 2607 # Display FULL debugging info. 2608 disp_full_debug 2609 2610 # Final confirmation message. (ARE YOU SURE!) 2611 ${ECHO} " " 2612 get_confirm_nodef "WARNING: About to start committing changes. (y=continue, n=EXIT)" 2613 if [ $? -eq 0 ]; then 2614 ${ECHO} "Terminating setup without making changes at users request." 2615 cleanup 2616 exit 1 2617 fi 2618 2619 # Print newline 2620 ${ECHO} " " 2621} 2622 2623 2624# 2625# create_config_file(): Write config data to config file specified. 2626# 2627create_config_file() 2628{ 2629 [ $DEBUG -eq 1 ] && ${ECHO} "In create_config_file()" 2630 2631 # If output file exists, delete it. 2632 [ -f $OUTPUT_FILE ] && rm $OUTPUT_FILE 2633 2634 # Create output file. 2635 cat > $OUTPUT_FILE <<EOF 2636#!/bin/sh 2637# $OUTPUT_FILE - This file contains configuration information for 2638# Native LDAP. Use the idsconfig tool to load it. 2639# 2640# WARNING: This file was generated by idsconfig, and is intended to 2641# be loaded by idsconfig as is. DO NOT EDIT THIS FILE! 2642# 2643IDS_SERVER="$IDS_SERVER" 2644IDS_PORT=$IDS_PORT 2645IDS_TIMELIMIT=$IDS_TIMELIMIT 2646IDS_SIZELIMIT=$IDS_SIZELIMIT 2647LDAP_ROOTDN="$LDAP_ROOTDN" 2648LDAP_ROOTPWD=$LDAP_ROOTPWD 2649LDAP_DOMAIN="$LDAP_DOMAIN" 2650LDAP_SUFFIX="$LDAP_SUFFIX" 2651LDAP_KRB_REALM="$LDAP_KRB_REALM" 2652LDAP_GSSAPI_PROFILE="$LDAP_GSSAPI_PROFILE" 2653 2654# Internal program variables that need to be set. 2655NEED_PROXY=$NEED_PROXY 2656NEED_TIME=$NEED_TIME 2657NEED_SIZE=$NEED_SIZE 2658NEED_CRYPT=$NEED_CRYPT 2659 2660# LDAP PROFILE related defaults 2661LDAP_PROFILE_NAME="$LDAP_PROFILE_NAME" 2662DEL_OLD_PROFILE=1 2663LDAP_BASEDN="$LDAP_BASEDN" 2664LDAP_SERVER_LIST="$LDAP_SERVER_LIST" 2665LDAP_AUTHMETHOD="$LDAP_AUTHMETHOD" 2666LDAP_FOLLOWREF=$LDAP_FOLLOWREF 2667LDAP_SEARCH_SCOPE="$LDAP_SEARCH_SCOPE" 2668NEED_SRVAUTH_PAM=$NEED_SRVAUTH_PAM 2669NEED_SRVAUTH_KEY=$NEED_SRVAUTH_KEY 2670NEED_SRVAUTH_CMD=$NEED_SRVAUTH_CMD 2671LDAP_SRV_AUTHMETHOD_PAM="$LDAP_SRV_AUTHMETHOD_PAM" 2672LDAP_SRV_AUTHMETHOD_KEY="$LDAP_SRV_AUTHMETHOD_KEY" 2673LDAP_SRV_AUTHMETHOD_CMD="$LDAP_SRV_AUTHMETHOD_CMD" 2674LDAP_SEARCH_TIME_LIMIT=$LDAP_SEARCH_TIME_LIMIT 2675LDAP_PREF_SRVLIST="$LDAP_PREF_SRVLIST" 2676LDAP_PROFILE_TTL=$LDAP_PROFILE_TTL 2677LDAP_CRED_LEVEL="$LDAP_CRED_LEVEL" 2678LDAP_BIND_LIMIT=$LDAP_BIND_LIMIT 2679 2680# Proxy Agent 2681LDAP_PROXYAGENT="$LDAP_PROXYAGENT" 2682LDAP_PROXYAGENT_CRED=$LDAP_PROXYAGENT_CRED 2683 2684# Export all the variables (just in case) 2685export IDS_HOME IDS_PORT LDAP_ROOTDN LDAP_ROOTPWD LDAP_SERVER_LIST LDAP_BASEDN 2686export LDAP_DOMAIN LDAP_SUFFIX LDAP_PROXYAGENT LDAP_PROXYAGENT_CRED 2687export NEED_PROXY 2688export LDAP_PROFILE_NAME LDAP_BASEDN LDAP_SERVER_LIST 2689export LDAP_AUTHMETHOD LDAP_FOLLOWREF LDAP_SEARCH_SCOPE LDAP_SEARCH_TIME_LIMIT 2690export LDAP_PREF_SRVLIST LDAP_PROFILE_TTL LDAP_CRED_LEVEL LDAP_BIND_LIMIT 2691export NEED_SRVAUTH_PAM NEED_SRVAUTH_KEY NEED_SRVAUTH_CMD 2692export LDAP_SRV_AUTHMETHOD_PAM LDAP_SRV_AUTHMETHOD_KEY LDAP_SRV_AUTHMETHOD_CMD 2693export LDAP_SERV_SRCH_DES SSD_FILE LDAP_KRB_REALM LDAP_GSSAPI_PROFILE 2694 2695# Service Search Descriptors start here if present: 2696EOF 2697 # Add service search descriptors. 2698 ssd_2_config "${OUTPUT_FILE}" 2699 2700 # Add LDAP suffix preferences 2701 print_suffix_config >> "${OUTPUT_FILE}" 2702 2703 # Add the end of FILE tag. 2704 ${ECHO} "" >> ${OUTPUT_FILE} 2705 ${ECHO} "# End of $OUTPUT_FILE" >> ${OUTPUT_FILE} 2706} 2707 2708 2709# 2710# chk_vlv_indexes(): Do ldapsearch to see if server supports VLV. 2711# 2712chk_vlv_indexes() 2713{ 2714 # Do ldapsearch to see if server supports VLV. 2715 ${LDAPSEARCH} ${SERVER_ARGS} -b "" -s base "objectclass=*" > ${TMPDIR}/checkVLV 2>&1 2716 eval "${GREP} 2.16.840.1.113730.3.4.9 ${TMPDIR}/checkVLV ${VERB}" 2717 if [ $? -ne 0 ]; then 2718 ${ECHO} "ERROR: VLV is not supported on LDAP server!" 2719 cleanup 2720 exit 1 2721 fi 2722 [ $DEBUG -eq 1 ] && ${ECHO} " VLV controls found on LDAP server." 2723} 2724 2725# 2726# get_backend(): this function gets the relevant backend 2727# (database) for LDAP_BASED. 2728# Description: set IDS_DATABASE; exit on failure. 2729# Prerequisite: LDAP_BASEDN and LDAP_SUFFIX are 2730# valid. 2731# 2732# backend is retrieved from suffixes and subsuffixes 2733# defined under "cn=mapping tree,cn=config". The 2734# nsslapd-state attribute of these suffixes entries 2735# is filled with either Backend, Disabled or referrals 2736# related values. We only want those that have a true 2737# backend database to select the relevant backend. 2738# 2739get_backend() 2740{ 2741 [ $DEBUG -eq 1 ] && ${ECHO} "In get_backend()" 2742 2743 cur_suffix=${LDAP_BASEDN} 2744 prev_suffix= 2745 IDS_DATABASE= 2746 while [ "${cur_suffix}" != "${prev_suffix}" ] 2747 do 2748 [ $DEBUG -eq 1 ] && ${ECHO} "testing LDAP suffix: ${cur_suffix}" 2749 eval "${LDAPSEARCH} ${LDAP_ARGS} " \ 2750 "-b \"cn=\\\"${cur_suffix}\\\",cn=mapping tree,cn=config\" " \ 2751 "-s base nsslapd-state=Backend nsslapd-backend 2>&1 " \ 2752 "| ${GREP} 'nsslapd-backend=' " \ 2753 "> ${TMPDIR}/ids_database_name 2>&1" 2754 NUM_DBS=`wc -l ${TMPDIR}/ids_database_name | awk '{print $1}'` 2755 case ${NUM_DBS} in 2756 0) # not a suffix, or suffix not activated; try next 2757 prev_suffix=${cur_suffix} 2758 cur_suffix=`${ECHO} ${cur_suffix} | cut -f2- -d','` 2759 ;; 2760 1) # suffix found; get database name 2761 IDS_DATABASE=`cat ${TMPDIR}/ids_database_name | cut -d= -f2` 2762 ;; 2763 *) # can not handle more than one database per suffix 2764 ${ECHO} "ERROR: More than one database is configured " 2765 ${ECHO} " for $LDAP_SUFFIX!" 2766 ${ECHO} " $PROG can not configure suffixes where " 2767 ${ECHO} " more than one database is used for one suffix." 2768 cleanup 2769 exit 1 2770 ;; 2771 esac 2772 if [ -n "${IDS_DATABASE}" ]; then 2773 break 2774 fi 2775 done 2776 2777 if [ -z "${IDS_DATABASE}" ]; then 2778 # should not happen, since LDAP_BASEDN is supposed to be valid 2779 ${ECHO} "Could not find a valid backend for ${LDAP_BASEDN}." 2780 ${ECHO} "Exiting." 2781 cleanup 2782 exit 1 2783 fi 2784 2785 [ $DEBUG -eq 1 ] && ${ECHO} "IDS_DATABASE: ${IDS_DATABASE}" 2786} 2787 2788# 2789# validate_suffix(): This function validates ${LDAP_SUFFIX} 2790# THIS FUNCTION IS FOR THE LOAD CONFIG FILE OPTION. 2791# 2792validate_suffix() 2793{ 2794 [ $DEBUG -eq 1 ] && ${ECHO} "In validate_suffix()" 2795 2796 # Check LDAP_SUFFIX is not null 2797 if [ -z "${LDAP_SUFFIX}" ]; then 2798 ${ECHO} "Invalid suffix (null suffix)" 2799 cleanup 2800 exit 1 2801 fi 2802 2803 # Check LDAP_SUFFIX and LDAP_BASEDN are consistent 2804 # Convert to lower case for basename. 2805 format_string "${LDAP_BASEDN}" 2806 LOWER_BASEDN="${FMT_STR}" 2807 format_string "${LDAP_SUFFIX}" 2808 LOWER_SUFFIX="${FMT_STR}" 2809 2810 [ $DEBUG -eq 1 ] && ${ECHO} "LOWER_BASEDN: ${LOWER_BASEDN}" 2811 [ $DEBUG -eq 1 ] && ${ECHO} "LOWER_SUFFIX: ${LOWER_SUFFIX}" 2812 2813 if [ "${LOWER_BASEDN}" != "${LOWER_SUFFIX}" ]; then 2814 sub_basedn=`basename "${LOWER_BASEDN}" "${LOWER_SUFFIX}"` 2815 if [ "$sub_basedn" = "${LOWER_BASEDN}" ]; then 2816 ${ECHO} "Invalid suffix ${LOWER_SUFFIX}" 2817 ${ECHO} "for Base DN ${LOWER_BASEDN}" 2818 cleanup 2819 exit 1 2820 fi 2821 fi 2822 2823 # Check LDAP_SUFFIX does exist 2824 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} -b \"${LDAP_SUFFIX}\" -s base \"objectclass=*\" > ${TMPDIR}/checkSuffix 2>&1" && return 0 2825 2826 # Well, suffix does not exist, try to prepare create it ... 2827 NEED_CREATE_SUFFIX=1 2828 prep_create_sfx_entry || 2829 { 2830 cleanup 2831 exit 1 2832 } 2833 [ -n "${NEED_CREATE_BACKEND}" ] && 2834 { 2835 # try to use id attr value of the suffix as a database name 2836 IDS_DATABASE=${_VAL} 2837 prep_create_sfx_backend 2838 case $? in 2839 1) # cann't use the name we want, so we can either exit or use 2840 # some another available name - doing the last ... 2841 IDS_DATABASE=${IDS_DATABASE_AVAIL} 2842 ;; 2843 2) # unable to determine database name 2844 cleanup 2845 exit 1 2846 ;; 2847 esac 2848 } 2849 2850 [ $DEBUG -eq 1 ] && ${ECHO} "Suffix $LDAP_SUFFIX, Database $IDS_DATABASE" 2851} 2852 2853# 2854# validate_info(): This function validates the basic info collected 2855# So that some problems are caught right away. 2856# THIS FUNCTION IS FOR THE LOAD CONFIG FILE OPTION. 2857# 2858validate_info() 2859{ 2860 [ $DEBUG -eq 1 ] && ${ECHO} "In validate_info()" 2861 2862 # Set SERVER_ARGS, AUTH_ARGS, and LDAP_ARGS for the config file. 2863 SERVER_ARGS="-h ${IDS_SERVER} -p ${IDS_PORT}" 2864 AUTH_ARGS="-D \"${LDAP_ROOTDN}\" -j ${LDAP_ROOTPWF}" 2865 LDAP_ARGS="${SERVER_ARGS} ${AUTH_ARGS}" 2866 export SERVER_ARGS 2867 2868 # Check the Root DN and Root DN passwd. 2869 # Use eval instead of $EVAL because not part of setup. (validate) 2870 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"\" -s base \"objectclass=*\" > ${TMPDIR}/checkDN 2>&1" 2871 if [ $? -ne 0 ]; then 2872 eval "${GREP} credential ${TMPDIR}/checkDN ${VERB}" 2873 if [ $? -eq 0 ]; then 2874 ${ECHO} "ERROR: Root DN passwd is invalid." 2875 else 2876 ${ECHO} "ERROR2: Invalid Root DN <${LDAP_ROOTDN}>." 2877 fi 2878 cleanup 2879 exit 1 2880 fi 2881 [ $DEBUG -eq 1 ] && ${ECHO} " RootDN ... OK" 2882 [ $DEBUG -eq 1 ] && ${ECHO} " RootDN passwd ... OK" 2883 2884 # Check if the server supports the VLV. 2885 chk_vlv_indexes 2886 [ $DEBUG -eq 1 ] && ${ECHO} " VLV indexes ... OK" 2887 2888 # Check LDAP suffix 2889 validate_suffix 2890 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP suffix ... OK" 2891} 2892 2893# 2894# format_string(): take a string as argument and set FMT_STR 2895# to be the same string formatted as follow: 2896# - only lower case characters 2897# - no unnecessary spaces around , and = 2898# 2899format_string() 2900{ 2901 FMT_STR=`${ECHO} "$1" | tr '[A-Z]' '[a-z]' | 2902 sed -e 's/[ ]*,[ ]*/,/g' -e 's/[ ]*=[ ]*/=/g'` 2903} 2904 2905# 2906# prepare for the suffix entry creation 2907# 2908# input : LDAP_BASEDN, LDAP_SUFFIX - base dn and suffix; 2909# in/out : LDAP_SUFFIX_OBJ, LDAP_SUFFIX_ACI - initially may come from config. 2910# output : NEED_CREATE_BACKEND - backend for this suffix needs to be created; 2911# _RDN, _ATT, _VAL - suffix's RDN, id attribute name and its value. 2912# return : 0 - success, otherwise error. 2913# 2914prep_create_sfx_entry() 2915{ 2916 [ $DEBUG -eq 1 ] && ${ECHO} "In prep_create_sfx_entry()" 2917 2918 # check whether suffix corresponds to base dn 2919 format_string "${LDAP_BASEDN}" 2920 ${ECHO} ",${FMT_STR}" | ${GREP} ",${LDAP_SUFFIX}$" >/dev/null 2>&1 || 2921 { 2922 display_msg sfx_not_suitable 2923 return 1 2924 } 2925 2926 # parse LDAP_SUFFIX 2927 _RDN=`${ECHO} "${LDAP_SUFFIX}" | cut -d, -f1` 2928 _ATT=`${ECHO} "${_RDN}" | cut -d= -f1` 2929 _VAL=`${ECHO} "${_RDN}" | cut -d= -f2-` 2930 2931 # find out an objectclass for suffix entry if it is not defined yet 2932 [ -z "${LDAP_SUFFIX_OBJ}" ] && 2933 { 2934 get_objectclass ${_ATT} 2935 [ -z "${_ATTR_NAME}" ] && 2936 { 2937 display_msg obj_not_found 2938 return 1 2939 } 2940 LDAP_SUFFIX_OBJ=${_ATTR_NAME} 2941 } 2942 [ $DEBUG -eq 1 ] && ${ECHO} "Suffix entry object is ${LDAP_SUFFIX_OBJ}" 2943 2944 # find out an aci for suffix entry if it is not defined yet 2945 [ -z "${LDAP_SUFFIX_ACI}" ] && 2946 { 2947 # set Directory Server default aci 2948 LDAP_SUFFIX_ACI=`cat <<EOF 2949aci: (targetattr != "userPassword || passwordHistory || passwordExpirationTime 2950 || passwordExpWarned || passwordRetryCount || retryCountResetTime || 2951 accountUnlockTime || passwordAllowChangeTime") 2952 ( 2953 version 3.0; 2954 acl "Anonymous access"; 2955 allow (read, search, compare) userdn = "ldap:///anyone"; 2956 ) 2957aci: (targetattr != "nsroledn || aci || nsLookThroughLimit || nsSizeLimit || 2958 nsTimeLimit || nsIdleTimeout || passwordPolicySubentry || 2959 passwordExpirationTime || passwordExpWarned || passwordRetryCount || 2960 retryCountResetTime || accountUnlockTime || passwordHistory || 2961 passwordAllowChangeTime") 2962 ( 2963 version 3.0; 2964 acl "Allow self entry modification except for some attributes"; 2965 allow (write) userdn = "ldap:///self"; 2966 ) 2967aci: (targetattr = "*") 2968 ( 2969 version 3.0; 2970 acl "Configuration Administrator"; 2971 allow (all) userdn = "ldap:///uid=admin,ou=Administrators, 2972 ou=TopologyManagement,o=NetscapeRoot"; 2973 ) 2974aci: (targetattr ="*") 2975 ( 2976 version 3.0; 2977 acl "Configuration Administrators Group"; 2978 allow (all) groupdn = "ldap:///cn=Configuration Administrators, 2979 ou=Groups,ou=TopologyManagement,o=NetscapeRoot"; 2980 ) 2981EOF 2982` 2983 } 2984 [ $DEBUG -eq 1 ] && cat <<EOF 2985DEBUG: ACI for ${LDAP_SUFFIX} is 2986${LDAP_SUFFIX_ACI} 2987EOF 2988 2989 NEED_CREATE_BACKEND= 2990 2991 # check the suffix mapping tree ... 2992 # if mapping exists, suffix should work, otherwise DS inconsistent 2993 # NOTE: -b 'cn=mapping tree,cn=config' -s one 'cn=\"$1\"' won't work 2994 # in case of 'cn' value in LDAP is not quoted by '"', 2995 # -b 'cn=\"$1\",cn=mapping tree,cn=config' works in all cases 2996 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} \ 2997 -b 'cn=\"${LDAP_SUFFIX}\",cn=mapping tree,cn=config' \ 2998 -s base 'objectclass=*' dn ${VERB}" && 2999 { 3000 [ $DEBUG -eq 1 ] && ${ECHO} "Suffix mapping already exists" 3001 # get_backend() either gets IDS_DATABASE or exits 3002 get_backend 3003 return 0 3004 } 3005 3006 # no suffix mapping, just in case check ldbm backends consistency - 3007 # there are must be NO any databases pointing to LDAP_SUFFIX 3008 [ -n "`${EVAL} \"${LDAPSEARCH} ${LDAP_ARGS} \ 3009 -b 'cn=ldbm database,cn=plugins,cn=config' \ 3010 -s one 'nsslapd-suffix=${LDAP_SUFFIX}' dn\" 2>/dev/null`" ] && 3011 { 3012 display_msg sfx_config_incons 3013 return 1 3014 } 3015 3016 # ok, no suffix mapping, no ldbm database 3017 [ $DEBUG -eq 1 ] && ${ECHO} "DEBUG: backend needs to be created ..." 3018 NEED_CREATE_BACKEND=1 3019 return 0 3020} 3021 3022# 3023# prepare for the suffix backend creation 3024# 3025# input : IDS_DATABASE - requested ldbm db name (must be not null) 3026# in/out : IDS_DATABASE_AVAIL - available ldbm db name 3027# return : 0 - ldbm db name ok 3028# 1 - IDS_DATABASE exists, 3029# so IDS_DATABASE_AVAIL contains available name 3030# 2 - unable to find any available name 3031# 3032prep_create_sfx_backend() 3033{ 3034 [ $DEBUG -eq 1 ] && ${ECHO} "In prep_create_sfx_backend()" 3035 3036 # check if requested name available 3037 [ "${IDS_DATABASE}" = "${IDS_DATABASE_AVAIL}" ] && return 0 3038 3039 # get the list of database names start with a requested name 3040 _LDBM_DBS=`${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} \ 3041 -b 'cn=ldbm database,cn=plugins,cn=config' \ 3042 -s one 'cn=${IDS_DATABASE}*' cn"` 2>/dev/null 3043 3044 # find available db name based on a requested name 3045 _i=""; _i_MAX=10 3046 while [ ${_i:-0} -lt ${_i_MAX} ] 3047 do 3048 _name="${IDS_DATABASE}${_i}" 3049 ${ECHO} "${_LDBM_DBS}" | ${GREP} -i "^cn=${_name}$" >/dev/null 2>&1 || 3050 { 3051 IDS_DATABASE_AVAIL="${_name}" 3052 break 3053 } 3054 _i=`expr ${_i:-0} + 1` 3055 done 3056 3057 [ "${IDS_DATABASE}" = "${IDS_DATABASE_AVAIL}" ] && return 0 3058 3059 [ -n "${IDS_DATABASE_AVAIL}" ] && 3060 { 3061 display_msg ldbm_db_exist 3062 return 1 3063 } 3064 3065 display_msg unable_find_db_name 3066 return 2 3067} 3068 3069# 3070# add suffix if needed, 3071# suffix entry and backend MUST be prepared by 3072# prep_create_sfx_entry and prep_create_sfx_backend correspondingly 3073# 3074# input : NEED_CREATE_SUFFIX, LDAP_SUFFIX, LDAP_SUFFIX_OBJ, _ATT, _VAL 3075# LDAP_SUFFIX_ACI, NEED_CREATE_BACKEND, IDS_DATABASE 3076# return : 0 - suffix successfully created, otherwise error occured 3077# 3078add_suffix() 3079{ 3080 [ $DEBUG -eq 1 ] && ${ECHO} "In add_suffix()" 3081 3082 [ -n "${NEED_CREATE_SUFFIX}" ] || return 0 3083 3084 [ -n "${NEED_CREATE_BACKEND}" ] && 3085 { 3086 ${EVAL} "${LDAPADD} ${LDAP_ARGS} ${VERB}" <<EOF 3087dn: cn="${LDAP_SUFFIX}",cn=mapping tree,cn=config 3088objectclass: top 3089objectclass: extensibleObject 3090objectclass: nsMappingTree 3091cn: ${LDAP_SUFFIX} 3092nsslapd-state: backend 3093nsslapd-backend: ${IDS_DATABASE} 3094 3095dn: cn=${IDS_DATABASE},cn=ldbm database,cn=plugins,cn=config 3096objectclass: top 3097objectclass: extensibleObject 3098objectclass: nsBackendInstance 3099cn: ${IDS_DATABASE} 3100nsslapd-suffix: ${LDAP_SUFFIX} 3101EOF 3102 [ $? -ne 0 ] && 3103 { 3104 display_msg create_ldbm_db_error 3105 return 1 3106 } 3107 3108 ${ECHO} " ${STEP}. Database ${IDS_DATABASE} successfully created" 3109 STEP=`expr $STEP + 1` 3110 } 3111 3112 ${EVAL} "${LDAPADD} ${LDAP_ARGS} ${VERB}" <<EOF 3113dn: ${LDAP_SUFFIX} 3114objectclass: ${LDAP_SUFFIX_OBJ} 3115${_ATT}: ${_VAL} 3116${LDAP_SUFFIX_ACI} 3117EOF 3118 [ $? -ne 0 ] && 3119 { 3120 display_msg create_suffix_entry_error 3121 return 1 3122 } 3123 3124 ${ECHO} " ${STEP}. Suffix ${LDAP_SUFFIX} successfully created" 3125 STEP=`expr $STEP + 1` 3126 return 0 3127} 3128 3129# 3130# interactively get suffix and related info from a user 3131# 3132# input : LDAP_BASEDN - Base DN 3133# output : LDAP_SUFFIX - Suffix, _ATT, _VAL - id attribute and its value; 3134# LDAP_SUFFIX_OBJ, LDAP_SUFFIX_ACI - objectclass and aci; 3135# NEED_CREATE_BACKEND - tells whether backend needs to be created; 3136# IDS_DATABASE - prepared ldbm db name 3137# return : 0 - user gave a correct suffix 3138# 1 - suffix given by user cann't be created 3139# 3140get_suffix() 3141{ 3142 [ $DEBUG -eq 1 ] && ${ECHO} "In get_suffix()" 3143 3144 while : 3145 do 3146 get_ans "Enter suffix to be created (b=back/h=help):" ${LDAP_BASEDN} 3147 case "${ANS}" in 3148 [Hh] | Help | help | \? ) display_msg create_suffix_help ;; 3149 [Bb] | Back | back | \< ) return 1 ;; 3150 * ) 3151 format_string "${ANS}" 3152 LDAP_SUFFIX=${FMT_STR} 3153 prep_create_sfx_entry || continue 3154 3155 [ -n "${NEED_CREATE_BACKEND}" ] && 3156 { 3157 IDS_DATABASE_AVAIL= # reset the available db name 3158 3159 reenter_suffix= 3160 while : 3161 do 3162 get_ans "Enter ldbm database name (b=back/h=help):" \ 3163 ${IDS_DATABASE_AVAIL:-${_VAL}} 3164 case "${ANS}" in 3165 [Hh] | \? ) display_msg enter_ldbm_db_help ;; 3166 [Bb] | \< ) reenter_suffix=1; break ;; 3167 * ) 3168 IDS_DATABASE="${ANS}" 3169 prep_create_sfx_backend && break 3170 esac 3171 done 3172 [ -n "${reenter_suffix}" ] && continue 3173 3174 [ $DEBUG -eq 1 ] && cat <<EOF 3175DEBUG: backend name for suffix ${LDAP_SUFFIX} will be ${IDS_DATABASE} 3176EOF 3177 } 3178 3179 # eventually everything is prepared 3180 return 0 3181 ;; 3182 esac 3183 done 3184} 3185 3186# 3187# print out a script which sets LDAP suffix related preferences 3188# 3189print_suffix_config() 3190{ 3191 cat <<EOF2 3192# LDAP suffix related preferences used only if needed 3193IDS_DATABASE="${IDS_DATABASE}" 3194LDAP_SUFFIX_OBJ="$LDAP_SUFFIX_OBJ" 3195LDAP_SUFFIX_ACI=\`cat <<EOF 3196${LDAP_SUFFIX_ACI} 3197EOF 3198\` 3199export IDS_DATABASE LDAP_SUFFIX_OBJ LDAP_SUFFIX_ACI 3200EOF2 3201} 3202 3203# 3204# check_basedn_suffix(): check that there is an existing 3205# valid suffix to hold current base DN 3206# return: 3207# 0: valid suffix found or new one should be created, 3208# NEED_CREATE_SUFFIX flag actually indicates that 3209# 1: some error occures 3210# 3211check_basedn_suffix() 3212{ 3213 [ $DEBUG -eq 1 ] && ${ECHO} "In check_basedn_suffix()" 3214 3215 NEED_CREATE_SUFFIX= 3216 3217 # find out existing suffixes 3218 discover_serv_suffix 3219 3220 ${ECHO} " Validating LDAP Base DN and Suffix ..." 3221 3222 # check that LDAP Base DN might be added 3223 cur_ldap_entry=${LDAP_BASEDN} 3224 prev_ldap_entry= 3225 while [ "${cur_ldap_entry}" != "${prev_ldap_entry}" ] 3226 do 3227 [ $DEBUG -eq 1 ] && ${ECHO} "testing LDAP entry: ${cur_ldap_entry}" 3228 ${LDAPSEARCH} ${SERVER_ARGS} -b "${cur_ldap_entry}" \ 3229 -s one "objectclass=*" > /dev/null 2>&1 3230 if [ $? -eq 0 ]; then 3231 break 3232 else 3233 prev_ldap_entry=${cur_ldap_entry} 3234 cur_ldap_entry=`${ECHO} ${cur_ldap_entry} | cut -f2- -d','` 3235 fi 3236 done 3237 3238 if [ "${cur_ldap_entry}" = "${prev_ldap_entry}" ]; then 3239 ${ECHO} " No valid suffixes were found for Base DN ${LDAP_BASEDN}" 3240 3241 NEED_CREATE_SUFFIX=1 3242 return 0 3243 3244 else 3245 [ $DEBUG -eq 1 ] && ${ECHO} "found valid LDAP entry: ${cur_ldap_entry}" 3246 3247 # Now looking for relevant suffix for this entry. 3248 # LDAP_SUFFIX will then be used to add necessary 3249 # base objects. See add_base_objects(). 3250 format_string "${cur_ldap_entry}" 3251 lower_entry="${FMT_STR}" 3252 [ $DEBUG -eq 1 ] && ${ECHO} "final suffix list: ${LDAP_SUFFIX_LIST}" 3253 oIFS=$IFS 3254 [ $DEBUG -eq 1 ] && ${ECHO} "setting IFS to new line" 3255 IFS=' 3256' 3257 for suff in ${LDAP_SUFFIX_LIST} 3258 do 3259 [ $DEBUG -eq 1 ] && ${ECHO} "testing suffix: ${suff}" 3260 format_string "${suff}" 3261 lower_suff="${FMT_STR}" 3262 if [ "${lower_entry}" = "${lower_suff}" ]; then 3263 LDAP_SUFFIX="${suff}" 3264 break 3265 else 3266 dcstmp=`basename "${lower_entry}" "${lower_suff}"` 3267 if [ "${dcstmp}" = "${lower_entry}" ]; then 3268 # invalid suffix, try next one 3269 continue 3270 else 3271 # valid suffix found 3272 LDAP_SUFFIX="${suff}" 3273 break 3274 fi 3275 fi 3276 done 3277 [ $DEBUG -eq 1 ] && ${ECHO} "setting IFS to original value" 3278 IFS=$oIFS 3279 3280 [ $DEBUG -eq 1 ] && ${ECHO} "LDAP_SUFFIX: ${LDAP_SUFFIX}" 3281 3282 if [ -z "${LDAP_SUFFIX}" ]; then 3283 # should not happen, since we found the entry 3284 ${ECHO} "Could not find a valid suffix for ${LDAP_BASEDN}." 3285 ${ECHO} "Exiting." 3286 return 1 3287 fi 3288 3289 # Getting relevant database (backend) 3290 # IDS_DATABASE will then be used to create indexes. 3291 get_backend 3292 3293 return 0 3294 fi 3295} 3296 3297# 3298# discover_serv_suffix(): This function queries the server to find 3299# suffixes available 3300# return: 0: OK, suffix found 3301# 1: suffix not determined 3302discover_serv_suffix() 3303{ 3304 [ $DEBUG -eq 1 ] && ${ECHO} "In discover_serv_suffix()" 3305 3306 # Search the server for the TOP of the TREE. 3307 ${LDAPSEARCH} ${SERVER_ARGS} -b "" -s base "objectclass=*" > ${TMPDIR}/checkTOP 2>&1 3308 ${GREP} -i namingcontexts ${TMPDIR}/checkTOP | \ 3309 ${GREP} -i -v NetscapeRoot > ${TMPDIR}/treeTOP 3310 NUM_TOP=`wc -l ${TMPDIR}/treeTOP | awk '{print $1}'` 3311 case $NUM_TOP in 3312 0) 3313 [ $DEBUG -eq 1 ] && ${ECHO} "DEBUG: No suffix found in LDAP tree" 3314 return 1 3315 ;; 3316 *) # build the list of suffixes; take out 'namingContexts=' in 3317 # each line of ${TMPDIR}/treeTOP 3318 LDAP_SUFFIX_LIST=`cat ${TMPDIR}/treeTOP | 3319 awk '{ printf("%s\n",substr($0,16,length-15)) }'` 3320 ;; 3321 esac 3322 3323 [ $DEBUG -eq 1 ] && ${ECHO} " LDAP_SUFFIX_LIST = $LDAP_SUFFIX_LIST" 3324 return 0 3325} 3326 3327 3328# 3329# modify_cn(): Change the cn from MUST to MAY in ipNetwork. 3330# 3331modify_cn() 3332{ 3333 [ $DEBUG -eq 1 ] && ${ECHO} "In modify_cn()" 3334 3335 ( cat <<EOF 3336dn: cn=schema 3337changetype: modify 3338add: objectclasses 3339objectclasses: ( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' DESC 'Standard LDAP objectclass' SUP top STRUCTURAL MUST ( ipNetworkNumber ) MAY ( ipNetmaskNumber $ manager $ cn $ l $ description ) X-ORIGIN 'RFC 2307' )) 3340EOF 3341) > ${TMPDIR}/ipNetwork_cn 3342 3343 # Modify the cn for ipNetwork. 3344 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/ipNetwork_cn ${VERB}" 3345 if [ $? -ne 0 ]; then 3346 ${ECHO} " ERROR: update of cn for ipNetwork failed!" 3347 cleanup 3348 exit 1 3349 fi 3350} 3351 3352 3353# modify_timelimit(): Modify timelimit to user value. 3354modify_timelimit() 3355{ 3356 [ $DEBUG -eq 1 ] && ${ECHO} "In modify_timelimit()" 3357 3358 # Here doc to modify timelimit. 3359 ( cat <<EOF 3360dn: cn=config 3361changetype: modify 3362replace: nsslapd-timelimit 3363nsslapd-timelimit: ${IDS_TIMELIMIT} 3364EOF 3365) > ${TMPDIR}/ids_timelimit 3366 3367 # Add the entry. 3368 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/ids_timelimit ${VERB}" 3369 if [ $? -ne 0 ]; then 3370 ${ECHO} " ERROR: update of nsslapd-timelimit failed!" 3371 cleanup 3372 exit 1 3373 fi 3374 3375 # Display messages for modifications made in patch. 3376 ${ECHO} " ${STEP}. Changed timelimit to ${IDS_TIMELIMIT} in cn=config." 3377 STEP=`expr $STEP + 1` 3378} 3379 3380 3381# modify_sizelimit(): Modify sizelimit to user value. 3382modify_sizelimit() 3383{ 3384 [ $DEBUG -eq 1 ] && ${ECHO} "In modify_sizelimit()" 3385 3386 # Here doc to modify sizelimit. 3387 ( cat <<EOF 3388dn: cn=config 3389changetype: modify 3390replace: nsslapd-sizelimit 3391nsslapd-sizelimit: ${IDS_SIZELIMIT} 3392EOF 3393) > ${TMPDIR}/ids_sizelimit 3394 3395 # Add the entry. 3396 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/ids_sizelimit ${VERB}" 3397 if [ $? -ne 0 ]; then 3398 ${ECHO} " ERROR: update of nsslapd-sizelimit failed!" 3399 cleanup 3400 exit 1 3401 fi 3402 3403 # Display messages for modifications made in patch. 3404 ${ECHO} " ${STEP}. Changed sizelimit to ${IDS_SIZELIMIT} in cn=config." 3405 STEP=`expr $STEP + 1` 3406} 3407 3408 3409# modify_pwd_crypt(): Modify the passwd storage scheme to support CRYPT. 3410modify_pwd_crypt() 3411{ 3412 [ $DEBUG -eq 1 ] && ${ECHO} "In modify_pwd_crypt()" 3413 3414 # Here doc to modify passwordstoragescheme. 3415 # IDS 5.2 moved passwordchangesceme off to a new data structure. 3416 if [ $IDS_MAJVER -le 5 ] && [ $IDS_MINVER -le 1 ]; then 3417 ( cat <<EOF 3418dn: cn=config 3419changetype: modify 3420replace: passwordstoragescheme 3421passwordstoragescheme: crypt 3422EOF 3423 ) > ${TMPDIR}/ids_crypt 3424 else 3425 ( cat <<EOF 3426dn: cn=Password Policy,cn=config 3427changetype: modify 3428replace: passwordstoragescheme 3429passwordstoragescheme: crypt 3430EOF 3431 ) > ${TMPDIR}/ids_crypt 3432 fi 3433 3434 # Add the entry. 3435 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/ids_crypt ${VERB}" 3436 if [ $? -ne 0 ]; then 3437 ${ECHO} " ERROR: update of passwordstoragescheme failed!" 3438 cleanup 3439 exit 1 3440 fi 3441 3442 # Display messages for modifications made in patch. 3443 ${ECHO} " ${STEP}. Changed passwordstoragescheme to \"crypt\" in cn=config." 3444 STEP=`expr $STEP + 1` 3445} 3446 3447 3448# 3449# add_eq_indexes(): Add indexes to improve search performance. 3450# 3451add_eq_indexes() 3452{ 3453 [ $DEBUG -eq 1 ] && ${ECHO} "In add_eq_indexes()" 3454 3455 # Set eq indexes to add. 3456 _INDEXES="uidNumber ipNetworkNumber gidnumber oncrpcnumber automountKey" 3457 3458 if [ -z "${IDS_DATABASE}" ]; then 3459 get_backend 3460 fi 3461 3462 # Set _EXT to use as shortcut. 3463 _EXT="cn=index,cn=${IDS_DATABASE},cn=ldbm database,cn=plugins,cn=config" 3464 3465 # Display message to id current step. 3466 ${ECHO} " ${STEP}. Processing eq,pres indexes:" 3467 STEP=`expr $STEP + 1` 3468 3469 # For loop to create indexes. 3470 for i in ${_INDEXES}; do 3471 [ $DEBUG -eq 1 ] && ${ECHO} " Adding index for ${i}" 3472 3473 # Check if entry exists first, if so, skip to next. 3474 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} -b \"cn=${i},${_EXT}\" -s base \ 3475 \"objectclass=*\" > /dev/null 2>&1" 3476 if [ $? -eq 0 ]; then 3477 # Display index skipped. 3478 ${ECHO} " ${i} (eq,pres) skipped already exists" 3479 continue 3480 fi 3481 3482 # Here doc to create LDIF. 3483 ( cat <<EOF 3484dn: cn=${i},${_EXT} 3485objectClass: top 3486objectClass: nsIndex 3487cn: ${i} 3488nsSystemIndex: false 3489nsIndexType: pres 3490nsIndexType: eq 3491EOF 3492) > ${TMPDIR}/index_${i} 3493 3494 # Add the index. 3495 ${EVAL} "${LDAPMODIFY} -a ${LDAP_ARGS} -f ${TMPDIR}/index_${i} ${VERB}" 3496 if [ $? -ne 0 ]; then 3497 ${ECHO} " ERROR: Adding EQ,PRES index for ${i} failed!" 3498 cleanup 3499 exit 1 3500 fi 3501 3502 # Build date for task name. 3503 _YR=`date '+%y'` 3504 _MN=`date '+%m'` 3505 _DY=`date '+%d'` 3506 _H=`date '+%H'` 3507 _M=`date '+%M'` 3508 _S=`date '+%S'` 3509 3510 # Build task name 3511 TASKNAME="${i}_${_YR}_${_MN}_${_DY}_${_H}_${_M}_${_S}" 3512 3513 # Build the task entry to add. 3514 ( cat <<EOF 3515dn: cn=${TASKNAME}, cn=index, cn=tasks, cn=config 3516changetype: add 3517objectclass: top 3518objectclass: extensibleObject 3519cn: ${TASKNAME} 3520nsInstance: ${IDS_DATABASE} 3521nsIndexAttribute: ${i} 3522EOF 3523) > ${TMPDIR}/task_${i} 3524 3525 # Add the task. 3526 ${EVAL} "${LDAPMODIFY} -a ${LDAP_ARGS} -f ${TMPDIR}/task_${i} ${VERB}" 3527 if [ $? -ne 0 ]; then 3528 ${ECHO} " ERROR: Adding task for ${i} failed!" 3529 cleanup 3530 exit 1 3531 fi 3532 3533 # Wait for task to finish, display current status. 3534 while : 3535 do 3536 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} \ 3537 -b \"cn=${TASKNAME}, cn=index, cn=tasks, cn=config\" -s base \ 3538 \"objectclass=*\" nstaskstatus > \"${TMPDIR}/istask_${i}\" 2>&1" 3539 ${GREP} "${TASKNAME}" "${TMPDIR}/istask_${i}" > /dev/null 2>&1 3540 if [ $? -ne 0 ]; then 3541 break 3542 fi 3543 TASK_STATUS=`${GREP} -i nstaskstatus "${TMPDIR}/istask_${i}" | 3544 head -1 | cut -d: -f2` 3545 ${ECHO} " ${i} (eq,pres) $TASK_STATUS \r\c" 3546 ${ECHO} "$TASK_STATUS" | ${GREP} "Finished" > /dev/null 2>&1 3547 if [ $? -eq 0 ]; then 3548 break 3549 fi 3550 sleep 2 3551 done 3552 3553 # Print newline because of \c. 3554 ${ECHO} " " 3555 done 3556} 3557 3558 3559# 3560# add_sub_indexes(): Add indexes to improve search performance. 3561# 3562add_sub_indexes() 3563{ 3564 [ $DEBUG -eq 1 ] && ${ECHO} "In add_sub_indexes()" 3565 3566 # Set eq indexes to add. 3567 _INDEXES="ipHostNumber membernisnetgroup nisnetgrouptriple" 3568 3569 # Set _EXT to use as shortcut. 3570 _EXT="cn=index,cn=${IDS_DATABASE},cn=ldbm database,cn=plugins,cn=config" 3571 3572 3573 # Display message to id current step. 3574 ${ECHO} " ${STEP}. Processing eq,pres,sub indexes:" 3575 STEP=`expr $STEP + 1` 3576 3577 # For loop to create indexes. 3578 for i in ${_INDEXES}; do 3579 [ $DEBUG -eq 1 ] && ${ECHO} " Adding index for ${i}" 3580 3581 # Check if entry exists first, if so, skip to next. 3582 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} -b \"cn=${i},${_EXT}\" \ 3583 -s base \"objectclass=*\" > /dev/null 2>&1" 3584 if [ $? -eq 0 ]; then 3585 # Display index skipped. 3586 ${ECHO} " ${i} (eq,pres,sub) skipped already exists" 3587 continue 3588 fi 3589 3590 # Here doc to create LDIF. 3591 ( cat <<EOF 3592dn: cn=${i},${_EXT} 3593objectClass: top 3594objectClass: nsIndex 3595cn: ${i} 3596nsSystemIndex: false 3597nsIndexType: pres 3598nsIndexType: eq 3599nsIndexType: sub 3600EOF 3601) > ${TMPDIR}/index_${i} 3602 3603 # Add the index. 3604 ${EVAL} "${LDAPMODIFY} -a ${LDAP_ARGS} -f ${TMPDIR}/index_${i} ${VERB}" 3605 if [ $? -ne 0 ]; then 3606 ${ECHO} " ERROR: Adding EQ,PRES,SUB index for ${i} failed!" 3607 cleanup 3608 exit 1 3609 fi 3610 3611 # Build date for task name. 3612 _YR=`date '+%y'` 3613 _MN=`date '+%m'` 3614 _DY=`date '+%d'` 3615 _H=`date '+%H'` 3616 _M=`date '+%M'` 3617 _S=`date '+%S'` 3618 3619 # Build task name 3620 TASKNAME="${i}_${_YR}_${_MN}_${_DY}_${_H}_${_M}_${_S}" 3621 3622 # Build the task entry to add. 3623 ( cat <<EOF 3624dn: cn=${TASKNAME}, cn=index, cn=tasks, cn=config 3625changetype: add 3626objectclass: top 3627objectclass: extensibleObject 3628cn: ${TASKNAME} 3629nsInstance: ${IDS_DATABASE} 3630nsIndexAttribute: ${i} 3631EOF 3632) > ${TMPDIR}/task_${i} 3633 3634 # Add the task. 3635 ${EVAL} "${LDAPMODIFY} -a ${LDAP_ARGS} -f ${TMPDIR}/task_${i} ${VERB}" 3636 if [ $? -ne 0 ]; then 3637 ${ECHO} " ERROR: Adding task for ${i} failed!" 3638 cleanup 3639 exit 1 3640 fi 3641 3642 # Wait for task to finish, display current status. 3643 while : 3644 do 3645 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} \ 3646 -b \"cn=${TASKNAME}, cn=index, cn=tasks, cn=config\" -s base \ 3647 \"objectclass=*\" nstaskstatus > \"${TMPDIR}/istask_${i}\" 2>&1" 3648 ${GREP} "${TASKNAME}" "${TMPDIR}/istask_${i}" > /dev/null 2>&1 3649 if [ $? -ne 0 ]; then 3650 break 3651 fi 3652 TASK_STATUS=`${GREP} -i nstaskstatus "${TMPDIR}/istask_${i}" | 3653 head -1 | cut -d: -f2` 3654 ${ECHO} " ${i} (eq,pres,sub) $TASK_STATUS \r\c" 3655 ${ECHO} "$TASK_STATUS" | ${GREP} "Finished" > /dev/null 2>&1 3656 if [ $? -eq 0 ]; then 3657 break 3658 fi 3659 sleep 2 3660 done 3661 3662 # Print newline because of \c. 3663 ${ECHO} " " 3664 done 3665} 3666 3667 3668# 3669# add_vlv_indexes(): Add VLV indexes to improve search performance. 3670# 3671add_vlv_indexes() 3672{ 3673 [ $DEBUG -eq 1 ] && ${ECHO} "In add_vlv_indexes()" 3674 3675 # Set eq indexes to add. 3676 # Note semi colon separators because some filters contain colons 3677 _INDEX1="${LDAP_DOMAIN}.getgrent;${LDAP_DOMAIN}_group_vlv_index;ou=group;objectClass=posixGroup" 3678 _INDEX2="${LDAP_DOMAIN}.gethostent;${LDAP_DOMAIN}_hosts_vlv_index;ou=hosts;objectClass=ipHost" 3679 _INDEX3="${LDAP_DOMAIN}.getnetent;${LDAP_DOMAIN}_networks_vlv_index;ou=networks;objectClass=ipNetwork" 3680 _INDEX4="${LDAP_DOMAIN}.getpwent;${LDAP_DOMAIN}_passwd_vlv_index;ou=people;objectClass=posixAccount" 3681 _INDEX5="${LDAP_DOMAIN}.getrpcent;${LDAP_DOMAIN}_rpc_vlv_index;ou=rpc;objectClass=oncRpc" 3682 _INDEX6="${LDAP_DOMAIN}.getspent;${LDAP_DOMAIN}_shadow_vlv_index;ou=people;objectClass=shadowAccount" 3683 3684 # Indexes added during NIS to LDAP transition 3685 _INDEX7="${LDAP_DOMAIN}.getauhoent;${LDAP_DOMAIN}_auho_vlv_index;automountmapname=auto_home;objectClass=automount" 3686 _INDEX8="${LDAP_DOMAIN}.getsoluent;${LDAP_DOMAIN}_solu_vlv_index;ou=people;objectClass=SolarisUserAttr" 3687 _INDEX9="${LDAP_DOMAIN}.getauduent;${LDAP_DOMAIN}_audu_vlv_index;ou=people;objectClass=SolarisAuditUser" 3688 _INDEX10="${LDAP_DOMAIN}.getauthent;${LDAP_DOMAIN}_auth_vlv_index;ou=SolarisAuthAttr;objectClass=SolarisAuthAttr" 3689 _INDEX11="${LDAP_DOMAIN}.getexecent;${LDAP_DOMAIN}_exec_vlv_index;ou=SolarisProfAttr;&(objectClass=SolarisExecAttr)(SolarisKernelSecurityPolicy=*)" 3690 _INDEX12="${LDAP_DOMAIN}.getprofent;${LDAP_DOMAIN}_prof_vlv_index;ou=SolarisProfAttr;&(objectClass=SolarisProfAttr)(SolarisAttrLongDesc=*)" 3691 _INDEX13="${LDAP_DOMAIN}.getmailent;${LDAP_DOMAIN}_mail_vlv_index;ou=aliases;objectClass=mailGroup" 3692 _INDEX14="${LDAP_DOMAIN}.getbootent;${LDAP_DOMAIN}__boot_vlv_index;ou=ethers;&(objectClass=bootableDevice)(bootParameter=*)" 3693 _INDEX15="${LDAP_DOMAIN}.getethent;${LDAP_DOMAIN}_ethers_vlv_index;ou=ethers;&(objectClass=ieee802Device)(macAddress=*)" 3694 _INDEX16="${LDAP_DOMAIN}.getngrpent;${LDAP_DOMAIN}_netgroup_vlv_index;ou=netgroup;objectClass=nisNetgroup" 3695 _INDEX17="${LDAP_DOMAIN}.getipnent;${LDAP_DOMAIN}_ipn_vlv_index;ou=networks;&(objectClass=ipNetwork)(cn=*)" 3696 _INDEX18="${LDAP_DOMAIN}.getmaskent;${LDAP_DOMAIN}_mask_vlv_index;ou=networks;&(objectClass=ipNetwork)(ipNetmaskNumber=*)" 3697 _INDEX19="${LDAP_DOMAIN}.getprent;${LDAP_DOMAIN}_pr_vlv_index;ou=printers;objectClass=printerService" 3698 _INDEX20="${LDAP_DOMAIN}.getip4ent;${LDAP_DOMAIN}_ip4_vlv_index;ou=hosts;&(objectClass=ipHost)(ipHostNumber=*.*)" 3699 _INDEX21="${LDAP_DOMAIN}.getip6ent;${LDAP_DOMAIN}_ip6_vlv_index;ou=hosts;&(objectClass=ipHost)(ipHostNumber=*:*)" 3700 3701 _INDEXES="$_INDEX1 $_INDEX2 $_INDEX3 $_INDEX4 $_INDEX5 $_INDEX6 $_INDEX7 $_INDEX8 $_INDEX9 $_INDEX10 $_INDEX11 $_INDEX12 $_INDEX13 $_INDEX14 $_INDEX15 $_INDEX16 $_INDEX17 $_INDEX18 $_INDEX19 $_INDEX20 $_INDEX21 " 3702 3703 3704 # Set _EXT to use as shortcut. 3705 _EXT="cn=${IDS_DATABASE},cn=ldbm database,cn=plugins,cn=config" 3706 3707 3708 # Display message to id current step. 3709 ${ECHO} " ${STEP}. Processing VLV indexes:" 3710 STEP=`expr $STEP + 1` 3711 3712 # Reset temp file for vlvindex commands. 3713 [ -f ${TMPDIR}/ds5_vlvindex_list ] && rm ${TMPDIR}/ds5_vlvindex_list 3714 touch ${TMPDIR}/ds5_vlvindex_list 3715 [ -f ${TMPDIR}/ds6_vlvindex_list ] && rm ${TMPDIR}/ds6_vlvindex_list 3716 touch ${TMPDIR}/ds6_vlvindex_list 3717 3718 # Get the instance name from iDS server. 3719 _INSTANCE="<server-instance>" # Default to old output. 3720 3721 eval "${LDAPSEARCH} -v ${LDAP_ARGS} -b \"cn=config\" -s base \"objectclass=*\" nsslapd-instancedir | ${GREP} 'nsslapd-instancedir=' | cut -d'=' -f2- > ${TMPDIR}/instance_name 2>&1" 3722 3723 ${GREP} "slapd-" ${TMPDIR}/instance_name > /dev/null 2>&1 # Check if seems right? 3724 if [ $? -eq 0 ]; then # If success, grab name after "slapd-". 3725 _INST_DIR=`cat ${TMPDIR}/instance_name` 3726 _INSTANCE=`basename "${_INST_DIR}" | cut -d'-' -f2-` 3727 fi 3728 3729 # For loop to create indexes. 3730 for p in ${_INDEXES}; do 3731 [ $DEBUG -eq 1 ] && ${ECHO} " Adding index for ${i}" 3732 3733 # Break p (pair) into i and j parts. 3734 i=`${ECHO} $p | cut -d';' -f1` 3735 j=`${ECHO} $p | cut -d';' -f2` 3736 k=`${ECHO} $p | cut -d';' -f3` 3737 m=`${ECHO} $p | cut -d';' -f4` 3738 3739 # Set _jEXT to use as shortcut. 3740 _jEXT="cn=${j},${_EXT}" 3741 3742 # Check if entry exists first, if so, skip to next. 3743 ${LDAPSEARCH} ${SERVER_ARGS} -b "cn=${i},${_jEXT}" -s base "objectclass=*" > /dev/null 2>&1 3744 if [ $? -eq 0 ]; then 3745 # Display index skipped. 3746 ${ECHO} " ${i} vlv_index skipped already exists" 3747 continue 3748 fi 3749 3750 # Compute the VLV Scope from the LDAP_SEARCH_SCOPE. 3751 # NOTE: A value of "base (0)" does not make sense. 3752 case "$LDAP_SEARCH_SCOPE" in 3753 sub) VLV_SCOPE="2" ;; 3754 *) VLV_SCOPE="1" ;; 3755 esac 3756 3757 # Here doc to create LDIF. 3758 ( cat <<EOF 3759dn: ${_jEXT} 3760objectClass: top 3761objectClass: vlvSearch 3762cn: ${j} 3763vlvbase: ${k},${LDAP_BASEDN} 3764vlvscope: ${VLV_SCOPE} 3765vlvfilter: (${m}) 3766aci: (target="ldap:///${_jEXT}")(targetattr="*")(version 3.0; acl "Config";allow(read,search,compare)userdn="ldap:///anyone";) 3767 3768dn: cn=${i},${_jEXT} 3769cn: ${i} 3770vlvSort: cn uid 3771objectclass: top 3772objectclass: vlvIndex 3773EOF 3774) > ${TMPDIR}/vlv_index_${i} 3775 3776 # Add the index. 3777 ${EVAL} "${LDAPMODIFY} -a ${LDAP_ARGS} -f ${TMPDIR}/vlv_index_${i} ${VERB}" 3778 if [ $? -ne 0 ]; then 3779 ${ECHO} " ERROR: Adding VLV index for ${i} failed!" 3780 cleanup 3781 exit 1 3782 fi 3783 3784 # Print message that index was created. 3785 ${ECHO} " ${i} vlv_index Entry created" 3786 3787 # Add command to list of vlvindex commands to run. 3788 ${ECHO} " directoryserver -s ${_INSTANCE} vlvindex -n ${IDS_DATABASE} -T ${i}" >> ${TMPDIR}/ds5_vlvindex_list 3789 ${ECHO} " <install-path>/bin/dsadm reindex -l -t ${i} <directory-instance-path> ${LDAP_SUFFIX}" >> ${TMPDIR}/ds6_vlvindex_list 3790 done 3791} 3792 3793 3794# 3795# display_vlv_cmds(): Display VLV index commands to run on server. 3796# 3797display_vlv_cmds() 3798{ 3799 if [ -s "${TMPDIR}/ds5_vlvindex_list" -o \ 3800 -s "${TMPDIR}/ds6_vlvindex_list" ]; then 3801 display_msg display_vlv_list 3802 fi 3803 3804 if [ -s "${TMPDIR}/ds5_vlvindex_list" ]; then 3805 cat ${TMPDIR}/ds5_vlvindex_list 3806 fi 3807 3808 cat << EOF 3809 3810 3811EOF 3812 3813 if [ -s "${TMPDIR}/ds6_vlvindex_list" ]; then 3814 cat ${TMPDIR}/ds6_vlvindex_list 3815 fi 3816} 3817 3818 3819# 3820# update_schema_attr(): Update Schema to support Naming. 3821# 3822update_schema_attr() 3823{ 3824 [ $DEBUG -eq 1 ] && ${ECHO} "In update_schema_attr()" 3825 3826 ( cat <<EOF 3827dn: cn=schema 3828changetype: modify 3829add: attributetypes 3830attributetypes: ( 1.3.6.1.1.1.1.28 NAME 'nisPublickey' DESC 'NIS public key' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) 3831attributetypes: ( 1.3.6.1.1.1.1.29 NAME 'nisSecretkey' DESC 'NIS secret key' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) 3832attributetypes: ( 1.3.6.1.1.1.1.30 NAME 'nisDomain' DESC 'NIS domain' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) 3833attributetypes: ( 1.3.6.1.1.1.1.31 NAME 'automountMapName' DESC 'automount Map Name' EQUALITY caseExactIA5Match SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE ) 3834attributetypes: ( 1.3.6.1.1.1.1.32 NAME 'automountKey' DESC 'automount Key Value' EQUALITY caseExactIA5Match SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE ) 3835attributetypes: ( 1.3.6.1.1.1.1.33 NAME 'automountInformation' DESC 'automount information' EQUALITY caseExactIA5Match SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE ) 3836attributetypes: ( 1.3.6.1.4.1.42.2.27.1.1.12 NAME 'nisNetIdUser' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' ) 3837attributetypes: ( 1.3.6.1.4.1.42.2.27.1.1.13 NAME 'nisNetIdGroup' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' ) 3838attributetypes: ( 1.3.6.1.4.1.42.2.27.1.1.14 NAME 'nisNetIdHost' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' ) 3839attributetypes: ( rfc822mailMember-oid NAME 'rfc822mailMember' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' ) 3840attributetypes: ( 2.16.840.1.113730.3.1.30 NAME 'mgrpRFC822MailMember' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) 3841attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.15 NAME 'SolarisLDAPServers' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) 3842attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.16 NAME 'SolarisSearchBaseDN' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE ) 3843attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.17 NAME 'SolarisCacheTTL' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3844attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.18 NAME 'SolarisBindDN' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE ) 3845attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.19 NAME 'SolarisBindPassword' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE ) 3846attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.20 NAME 'SolarisAuthMethod' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15') 3847attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.21 NAME 'SolarisTransportSecurity' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15') 3848attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.22 NAME 'SolarisCertificatePath' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE ) 3849attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.23 NAME 'SolarisCertificatePassword' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE ) 3850attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.24 NAME 'SolarisDataSearchDN' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15') 3851attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.25 NAME 'SolarisSearchScope' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3852attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.26 NAME 'SolarisSearchTimeLimit' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE ) 3853attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.27 NAME 'SolarisPreferredServer' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15') 3854attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.28 NAME 'SolarisPreferredServerOnly' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3855attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.29 NAME 'SolarisSearchReferral' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3856attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.4 NAME 'SolarisAttrKeyValue' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3857attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.5 NAME 'SolarisAuditAlways' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3858attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.6 NAME 'SolarisAuditNever' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3859attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.7 NAME 'SolarisAttrShortDesc' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3860attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.8 NAME 'SolarisAttrLongDesc' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3861attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.9 NAME 'SolarisKernelSecurityPolicy' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3862attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.10 NAME 'SolarisProfileType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3863attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.11 NAME 'SolarisProfileId' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE ) 3864attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.12 NAME 'SolarisUserQualifier' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3865attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.13 NAME 'SolarisAttrReserved1' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3866attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.14 NAME 'SolarisAttrReserved2' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3867attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.1 NAME 'SolarisProjectID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE ) 3868attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.2 NAME 'SolarisProjectName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' SINGLE-VALUE ) 3869attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.3 NAME 'SolarisProjectAttr' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' ) 3870attributetypes: ( memberGid-oid NAME 'memberGid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' ) 3871attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.0 NAME 'defaultServerList' DESC 'Default LDAP server host address used by a DUA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3872attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.1 NAME 'defaultSearchBase' DESC 'Default LDAP base DN used by a DUA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE ) 3873attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.2 NAME 'preferredServerList' DESC 'Preferred LDAP server host addresses to be used by a DUA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3874attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.3 NAME 'searchTimeLimit' DESC 'Maximum time in seconds a DUA should allow for a search to complete' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE ) 3875attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.4 NAME 'bindTimeLimit' DESC 'Maximum time in seconds a DUA should allow for the bind operation to complete' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE ) 3876attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.5 NAME 'followReferrals' DESC 'Tells DUA if it should follow referrals returned by a DSA search result' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3877attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.6 NAME 'authenticationMethod' DESC 'A keystring which identifies the type of authentication method used to contact the DSA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3878attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.7 NAME 'profileTTL' DESC 'Time to live before a client DUA should re-read this configuration profile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE ) 3879attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.14 NAME 'serviceSearchDescriptor' DESC 'LDAP search descriptor list used by Naming-DUA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' ) 3880attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.9 NAME 'attributeMap' DESC 'Attribute mappings used by a Naming-DUA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) 3881attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.10 NAME 'credentialLevel' DESC 'Identifies type of credentials a DUA should use when binding to the LDAP server' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3882attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.11 NAME 'objectclassMap' DESC 'Objectclass mappings used by a Naming-DUA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) 3883attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.12 NAME 'defaultSearchScope' DESC 'Default search scope used by a DUA' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3884attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.13 NAME 'serviceCredentialLevel' DESC 'Search scope used by a service of the DUA' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) 3885attributetypes: ( 1.3.6.1.4.1.11.1.3.1.1.15 NAME 'serviceAuthenticationMethod' DESC 'Authentication Method used by a service of the DUA' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) 3886attributetypes:( 1.3.18.0.2.4.1140 NAME 'printer-uri' DESC 'A URI supported by this printer. This URI SHOULD be used as a relative distinguished name (RDN). If printer-xri-supported is implemented, then this URI value MUST be listed in a member value of printer-xri-supported.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) 3887attributetypes:( 1.3.18.0.2.4.1107 NAME 'printer-xri-supported' DESC 'The unordered list of XRI (extended resource identifiers) supported by this printer. Each member of the list consists of a URI (uniform resource identifier) followed by optional authentication and security metaparameters.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) 3888attributetypes:( 1.3.18.0.2.4.1135 NAME 'printer-name' DESC 'The site-specific administrative name of this printer, more end-user friendly than a URI.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE ) 3889attributetypes:( 1.3.18.0.2.4.1119 NAME 'printer-natural-language-configured' DESC 'The configured language in which error and status messages will be generated (by default) by this printer. Also, a possible language for printer string attributes set by operator, system administrator, or manufacturer. Also, the (declared) language of the "printer-name", "printer-location", "printer-info", and "printer-make-and-model" attributes of this printer. For example: "en-us" (US English) or "fr-fr" (French in France) Legal values of language tags conform to [RFC3066] "Tags for the Identification of Languages".' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE ) 3890attributetypes:( 1.3.18.0.2.4.1136 NAME 'printer-location' DESC 'Identifies the location of the printer. This could include things like: "in Room 123A", "second floor of building XYZ".' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE ) 3891attributetypes:( 1.3.18.0.2.4.1139 NAME 'printer-info' DESC 'Identifies the descriptive information about this printer. This could include things like: "This printer can be used for printing color transparencies for HR presentations", or "Out of courtesy for others, please print only small (1-5 page) jobs at this printer", or even "This printer is going away on July 1, 1997, please find a new printer".' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE ) 3892attributetypes:( 1.3.18.0.2.4.1134 NAME 'printer-more-info' DESC 'A URI used to obtain more information about this specific printer. For example, this could be an HTTP type URI referencing an HTML page accessible to a Web Browser. The information obtained from this URI is intended for end user consumption.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) 3893attributetypes:( 1.3.18.0.2.4.1138 NAME 'printer-make-and-model' DESC 'Identifies the make and model of the device. The device manufacturer MAY initially populate this attribute.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE ) 3894attributetypes:( 1.3.18.0.2.4.1133 NAME 'printer-ipp-versions-supported' DESC 'Identifies the IPP protocol version(s) that this printer supports, including major and minor versions, i.e., the version numbers for which this Printer implementation meets the conformance requirements.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} ) 3895attributetypes:( 1.3.18.0.2.4.1132 NAME 'printer-multiple-document-jobs-supported' DESC 'Indicates whether or not the printer supports more than one document per job, i.e., more than one Send-Document or Send-Data operation with document data.' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) 3896attributetypes:( 1.3.18.0.2.4.1109 NAME 'printer-charset-configured' DESC 'The configured charset in which error and status messages will be generated (by default) by this printer. Also, a possible charset for printer string attributes set by operator, system administrator, or manufacturer. For example: "utf-8" (ISO 10646/Unicode) or "iso-8859-1" (Latin1). Legal values are defined by the IANA Registry of Coded Character Sets and the "(preferred MIME name)" SHALL be used as the tag. For coherence with IPP Model, charset tags in this attribute SHALL be lowercase normalized. This attribute SHOULD be static (time of registration) and SHOULD NOT be dynamically refreshed attributetypes: (subsequently).' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63} SINGLE-VALUE ) 3897attributetypes:( 1.3.18.0.2.4.1131 NAME 'printer-charset-supported' DESC 'Identifies the set of charsets supported for attribute type values of type Directory String for this directory entry. For example: "utf-8" (ISO 10646/Unicode) or "iso-8859-1" (Latin1). Legal values are defined by the IANA Registry of Coded Character Sets and the preferred MIME name.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63} ) 3898attributetypes:( 1.3.18.0.2.4.1137 NAME 'printer-generated-natural-language-supported' DESC 'Identifies the natural language(s) supported for this directory entry. For example: "en-us" (US English) or "fr-fr" (French in France). Legal values conform to [RFC3066], Tags for the Identification of Languages.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63} ) 3899attributetypes:( 1.3.18.0.2.4.1130 NAME 'printer-document-format-supported' DESC 'The possible document formats in which data may be interpreted and printed by this printer. Legal values are MIME types come from the IANA Registry of Internet Media Types.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} ) 3900attributetypes:( 1.3.18.0.2.4.1129 NAME 'printer-color-supported' DESC 'Indicates whether this printer is capable of any type of color printing at all, including highlight color.' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) 3901attributetypes:( 1.3.18.0.2.4.1128 NAME 'printer-compression-supported' DESC 'Compression algorithms supported by this printer. For example: "deflate, gzip". Legal values include; "none", "deflate" attributetypes: (public domain ZIP), "gzip" (GNU ZIP), "compress" (UNIX).' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} ) 3902attributetypes:( 1.3.18.0.2.4.1127 NAME 'printer-pages-per-minute' DESC 'The nominal number of pages per minute which may be output by this printer (e.g., a simplex or black-and-white printer). This attribute is informative, NOT a service guarantee. Typically, it is the value used in marketing literature to describe this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) 3903attributetypes:( 1.3.18.0.2.4.1126 NAME 'printer-pages-per-minute-color' DESC 'The nominal number of color pages per minute which may be output by this printer (e.g., a simplex or color printer). This attribute is informative, NOT a service guarantee. Typically, it is the value used in marketing literature to describe this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) 3904attributetypes:( 1.3.18.0.2.4.1125 NAME 'printer-finishings-supported' DESC 'The possible finishing operations supported by this printer. Legal values include; "none", "staple", "punch", "cover", "bind", "saddle-stitch", "edge-stitch", "staple-top-left", "staple-bottom-left", "staple-top-right", "staple-bottom-right", "edge-stitch-left", "edge-stitch-top", "edge-stitch-right", "edge-stitch-bottom", "staple-dual-left", "staple-dual-top", "staple-dual-right", "staple-dual-bottom".' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} ) 3905attributetypes:( 1.3.18.0.2.4.1124 NAME 'printer-number-up-supported' DESC 'The possible numbers of print-stream pages to impose upon a single side of an instance of a selected medium. Legal values include; 1, 2, and 4. Implementations may support other values.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) 3906attributetypes:( 1.3.18.0.2.4.1123 NAME 'printer-sides-supported' DESC 'The number of impression sides (one or two) and the two-sided impression rotations supported by this printer. Legal values include; "one-sided", "two-sided-long-edge", "two-sided-short-edge".' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} ) 3907attributetypes:( 1.3.18.0.2.4.1122 NAME 'printer-media-supported' DESC 'The standard names/types/sizes (and optional color suffixes) of the media supported by this printer. For example: "iso-a4", "envelope", or "na-letter-white". Legal values conform to ISO 10175, Document Printing Application (DPA), and any IANA registered extensions.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} ) 3908attributetypes:( 1.3.18.0.2.4.1117 NAME 'printer-media-local-supported' DESC 'Site-specific names of media supported by this printer, in the language in "printer-natural-language-configured". For example: "purchasing-form" (site-specific name) as opposed to (in "printer-media-supported"): "na-letter" (standard keyword from ISO 10175).' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} ) 3909attributetypes:( 1.3.18.0.2.4.1121 NAME 'printer-resolution-supported' DESC 'List of resolutions supported for printing documents by this printer. Each resolution value is a string with 3 fields: 1) Cross feed direction resolution (positive integer), 2) Feed direction resolution (positive integer), 3) Resolution unit. Legal values are "dpi" (dots per inch) and "dpcm" (dots per centimeter). Each resolution field is delimited by ">". For example: "300> 300> dpi>".' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} ) 3910attributetypes:( 1.3.18.0.2.4.1120 NAME 'printer-print-quality-supported' DESC 'List of print qualities supported for printing documents on this printer. For example: "draft, normal". Legal values include; "unknown", "draft", "normal", "high".' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} ) 3911attributetypes:( 1.3.18.0.2.4.1110 NAME 'printer-job-priority-supported' DESC 'Indicates the number of job priority levels supported. An IPP conformant printer which supports job priority must always support a full range of priorities from "1" to "100" (to ensure consistent behavior), therefore this attribute describes the "granularity". Legal values of this attribute are from "1" to "100".' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) 3912attributetypes:( 1.3.18.0.2.4.1118 NAME 'printer-copies-supported' DESC 'The maximum number of copies of a document that may be printed as a single job. A value of "0" indicates no maximum limit. A value of "-1" indicates unknown.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) 3913attributetypes:( 1.3.18.0.2.4.1111 NAME 'printer-job-k-octets-supported' DESC 'The maximum size in kilobytes (1,024 octets actually) incoming print job that this printer will accept. A value of "0" indicates no maximum limit. A value of "-1" indicates unknown.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) 3914attributetypes:( 1.3.18.0.2.4.1112 NAME 'printer-current-operator' DESC 'The name of the current human operator responsible for operating this printer. It is suggested that this string include information that would enable other humans to reach the operator, such as a phone number.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE ) 3915attributetypes:( 1.3.18.0.2.4.1113 NAME 'printer-service-person' DESC 'The name of the current human service person responsible for servicing this printer. It is suggested that this string include information that would enable other humans to reach the service person, such as a phone number.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE ) 3916attributetypes:( 1.3.18.0.2.4.1114 NAME 'printer-delivery-orientation-supported' DESC 'The possible delivery orientations of pages as they are printed and ejected from this printer. Legal values include; "unknown", "face-up", and "face-down".' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} ) 3917attributetypes:( 1.3.18.0.2.4.1115 NAME 'printer-stacking-order-supported' DESC 'The possible stacking order of pages as they are printed and ejected from this printer. Legal values include; "unknown", "first-to-last", "last-to-first".' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} ) 3918attributetypes:( 1.3.18.0.2.4.1116 NAME 'printer-output-features-supported' DESC 'The possible output features supported by this printer. Legal values include; "unknown", "bursting", "decollating", "page-collating", "offset-stacking".' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} ) 3919attributetypes:( 1.3.18.0.2.4.1108 NAME 'printer-aliases' DESC 'Site-specific administrative names of this printer in addition the printer name specified for printer-name.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} ) 3920attributetypes:( 1.3.6.1.4.1.42.2.27.5.1.63 NAME 'sun-printer-bsdaddr' DESC 'Sets the server, print queue destination name and whether the client generates protocol extensions. "Solaris" specifies a Solaris print server extension. The value is represented by the following value: server "," destination ", Solaris".' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE ) 3921attributetypes:( 1.3.6.1.4.1.42.2.27.5.1.64 NAME 'sun-printer-kvp' DESC 'This attribute contains a set of key value pairs which may have meaning to the print subsystem or may be user defined. Each value is represented by the following: key "=" value.' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) 3922attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.57 NAME 'nisplusTimeZone' DESC 'tzone column from NIS+ timezone table' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) 3923attributetypes:( 1.3.6.1.4.1.42.2.27.5.1.67 NAME 'ipTnetTemplateName' DESC 'Trusted Solaris network template template_name' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) 3924attributetypes:( 1.3.6.1.4.1.42.2.27.5.1.68 NAME 'ipTnetNumber' DESC 'Trusted Solaris network template ip_address' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) 3925EOF 3926) > ${TMPDIR}/schema_attr 3927 3928 # Add the entry. 3929 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/schema_attr ${VERB}" 3930 if [ $? -ne 0 ]; then 3931 ${ECHO} " ERROR: update of schema attributes failed!" 3932 cleanup 3933 exit 1 3934 fi 3935 3936 # Display message that schema is updated. 3937 ${ECHO} " ${STEP}. Schema attributes have been updated." 3938 STEP=`expr $STEP + 1` 3939} 3940 3941 3942# 3943# update_schema_obj(): Update the schema objectclass definitions. 3944# 3945update_schema_obj() 3946{ 3947 [ $DEBUG -eq 1 ] && ${ECHO} "In update_schema_obj()" 3948 3949 # Add the objectclass definitions. 3950 ( cat <<EOF 3951dn: cn=schema 3952changetype: modify 3953add: objectclasses 3954objectclasses: ( 1.3.6.1.1.1.2.14 NAME 'NisKeyObject' SUP 'top' MUST (objectclass $ cn $ nisPublickey $ nisSecretkey) MAY (uidNumber $ description)) 3955 3956dn: cn=schema 3957changetype: modify 3958add: objectclasses 3959objectclasses: ( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' SUP 'top' MUST (objectclass $ nisDomain) MAY ()) 3960 3961dn: cn=schema 3962changetype: modify 3963add: objectclasses 3964objectclasses: ( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP 'top' MUST (objectclass $ automountMapName) MAY (description)) 3965 3966dn: cn=schema 3967changetype: modify 3968add: objectclasses 3969objectclasses: ( 1.3.6.1.1.1.2.17 NAME 'automount' SUP 'top' MUST (objectclass $ automountKey $ automountInformation ) MAY (description)) 3970 3971dn: cn=schema 3972changetype: modify 3973add: objectclasses 3974objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.7 NAME 'SolarisNamingProfile' SUP 'top' MUST (objectclass $ cn $ SolarisLDAPservers $ SolarisSearchBaseDN) MAY (SolarisBindDN $ SolarisBindPassword $ SolarisAuthMethod $ SolarisTransportSecurity $ SolarisCertificatePath $ SolarisCertificatePassword $ SolarisDataSearchDN $ SolarisSearchScope $ SolarisSearchTimeLimit $ SolarisPreferredServer $ SolarisPreferredServerOnly $ SolarisCacheTTL $ SolarisSearchReferral)) 3975 3976dn: cn=schema 3977changetype: modify 3978add: objectclasses 3979objectclasses: ( 2.16.840.1.113730.3.2.4 NAME 'mailGroup' SUP 'top' MUST (objectclass $ mail) MAY (cn $ mgrpRFC822MailMember)) 3980 3981dn: cn=schema 3982changetype: modify 3983add: objectclasses 3984objectclasses: ( 1.3.6.1.4.1.42.2.27.1.2.5 NAME 'nisMailAlias' SUP 'top' MUST (objectclass $ cn) MAY (rfc822mailMember)) 3985 3986dn: cn=schema 3987changetype: modify 3988add: objectclasses 3989objectclasses: ( 1.3.6.1.4.1.42.2.27.1.2.6 NAME 'nisNetId' SUP 'top' MUST (objectclass $ cn) MAY (nisNetIdUser $ nisNetIdGroup $ nisNetIdHost)) 3990 3991dn: cn=schema 3992changetype: modify 3993add: objectclasses 3994objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.2 NAME 'SolarisAuditUser' SUP 'top' AUXILIARY MUST (objectclass) MAY (SolarisAuditAlways $ SolarisAuditNever)) 3995 3996dn: cn=schema 3997changetype: modify 3998add: objectclasses 3999objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.3 NAME 'SolarisUserAttr' SUP 'top' AUXILIARY MUST (objectclass) MAY (SolarisUserQualifier $ SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisAttrKeyValue)) 4000 4001dn: cn=schema 4002changetype: modify 4003add: objectclasses 4004objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.4 NAME 'SolarisAuthAttr' SUP 'top' MUST (objectclass $ cn) MAY (SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisAttrShortDesc $ SolarisAttrLongDesc $ SolarisAttrKeyValue)) 4005 4006dn: cn=schema 4007changetype: modify 4008add: objectclasses 4009objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.5 NAME 'SolarisProfAttr' SUP 'top' MUST (objectclass $ cn) MAY (SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisAttrLongDesc $ SolarisAttrKeyValue)) 4010 4011dn: cn=schema 4012changetype: modify 4013add: objectclasses 4014objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.6 NAME 'SolarisExecAttr' SUP 'top' AUXILIARY MUST (objectclass) MAY (SolarisKernelSecurityPolicy $ SolarisProfileType $ SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisProfileID $ SolarisAttrKeyValue)) 4015 4016dn: cn=schema 4017changetype: modify 4018add: objectclasses 4019objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.1 NAME 'SolarisProject' SUP 'top' MUST (objectclass $ SolarisProjectID $ SolarisProjectName) MAY (memberUid $ memberGid $ description $ SolarisProjectAttr)) 4020 4021dn: cn=schema 4022changetype: modify 4023add: objectclasses 4024objectclasses: ( 1.3.6.1.4.1.11.1.3.1.2.4 NAME 'DUAConfigProfile' SUP 'top' DESC 'Abstraction of a base configuration for a DUA' MUST (cn) MAY (defaultServerList $ preferredServerList $ defaultSearchBase $ defaultSearchScope $ searchTimeLimit $ bindTimeLimit $ credentialLevel $ authenticationMethod $ followReferrals $ serviceSearchDescriptor $ serviceCredentialLevel $ serviceAuthenticationMethod $ objectclassMap $ attributeMap $ profileTTL)) 4025 4026dn: cn=schema 4027changetype: modify 4028add: objectclasses 4029objectclasses: ( 1.3.18.0.2.6.2549 NAME 'slpService' DESC 'DUMMY definition' SUP 'top' MUST (objectclass) MAY ()) 4030 4031dn: cn=schema 4032changetype: modify 4033add: objectclasses 4034objectclasses: ( 1.3.18.0.2.6.254 NAME 'slpServicePrinter' DESC 'Service Location Protocol (SLP) information.' AUXILIARY SUP 'slpService') 4035 4036dn: cn=schema 4037changetype: modify 4038add: objectclasses 4039objectclasses: ( 1.3.18.0.2.6.258 NAME 'printerAbstract' DESC 'Printer related information.' ABSTRACT SUP 'top' MAY ( printer-name $ printer-natural-language-configured $ printer-location $ printer-info $ printer-more-info $ printer-make-and-model $ printer-multiple-document-jobs-supported $ printer-charset-configured $ printer-charset-supported $ printer-generated-natural-language-supported $ printer-document-format-supported $ printer-color-supported $ printer-compression-supported $ printer-pages-per-minute $ printer-pages-per-minute-color $ printer-finishings-supported $ printer-number-up-supported $ printer-sides-supported $ printer-media-supported $ printer-media-local-supported $ printer-resolution-supported $ printer-print-quality-supported $ printer-job-priority-supported $ printer-copies-supported $ printer-job-k-octets-supported $ printer-current-operator $ printer-service-person $ printer-delivery-orientation-supported $ printer-stacking-order-supported $ printer-output-features-supported )) 4040 4041dn: cn=schema 4042changetype: modify 4043add: objectclasses 4044objectclasses: ( 1.3.18.0.2.6.255 NAME 'printerService' DESC 'Printer information.' STRUCTURAL SUP 'printerAbstract' MAY ( printer-uri $ printer-xri-supported )) 4045 4046dn: cn=schema 4047changetype: modify 4048add: objectclasses 4049objectclasses: ( 1.3.18.0.2.6.257 NAME 'printerServiceAuxClass' DESC 'Printer information.' AUXILIARY SUP 'printerAbstract' MAY ( printer-uri $ printer-xri-supported )) 4050 4051dn: cn=schema 4052changetype: modify 4053add: objectclasses 4054objectclasses: ( 1.3.18.0.2.6.256 NAME 'printerIPP' DESC 'Internet Printing Protocol (IPP) information.' AUXILIARY SUP 'top' MAY ( printer-ipp-versions-supported $ printer-multiple-document-jobs-supported )) 4055 4056dn: cn=schema 4057changetype: modify 4058add: objectclasses 4059objectclasses: ( 1.3.18.0.2.6.253 NAME 'printerLPR' DESC 'LPR information.' AUXILIARY SUP 'top' MUST ( printer-name ) MAY ( printer-aliases)) 4060 4061dn: cn=schema 4062changetype: modify 4063add: objectclasses 4064objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.14 NAME 'sunPrinter' DESC 'Sun printer information' SUP 'top' AUXILIARY MUST (objectclass $ printer-name) MAY (sun-printer-bsdaddr $ sun-printer-kvp)) 4065 4066dn: cn=schema 4067changetype: modify 4068add: objectclasses 4069objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.12 NAME 'nisplusTimeZoneData' DESC 'NIS+ timezone table data' SUP top STRUCTURAL MUST ( cn ) MAY ( nisplusTimeZone $ description ) ) 4070 4071dn: cn=schema 4072changetype: modify 4073add: objectclasses 4074objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.8 NAME 'ipTnetTemplate' DESC 'Object class for TSOL network templates' SUP 'top' MUST ( objectclass $ ipTnetTemplateName ) MAY ( SolarisAttrKeyValue ) ) 4075 4076dn: cn=schema 4077changetype: modify 4078add: objectclasses 4079objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.9 NAME 'ipTnetHost' DESC 'Associates an IP address or wildcard with a TSOL template_name' SUP 'top' AUXILIARY MUST ( objectclass $ ipTnetNumber ) ) 4080EOF 4081) > ${TMPDIR}/schema_obj 4082 4083 # Add the entry. 4084 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/schema_obj ${VERB}" 4085 if [ $? -ne 0 ]; then 4086 ${ECHO} " ERROR: update of schema objectclass definitions failed!" 4087 cleanup 4088 exit 1 4089 fi 4090 4091 # Display message that schema is updated. 4092 ${ECHO} " ${STEP}. Schema objectclass definitions have been added." 4093 STEP=`expr $STEP + 1` 4094} 4095 4096 4097# 4098# modify_top_aci(): Modify the ACI for the top entry to disable self modify 4099# of user attributes. 4100# 4101modify_top_aci() 4102{ 4103 [ $DEBUG -eq 1 ] && ${ECHO} "In modify_top_aci()" 4104 4105 # Set ACI Name 4106 ACI_NAME="LDAP_Naming_Services_deny_write_access" 4107 4108 # Search for ACI_NAME 4109 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"${LDAP_BASEDN}\" -s base objectclass=* aci > ${TMPDIR}/chk_top_aci 2>&1" 4110 if [ $? -ne 0 ]; then 4111 ${ECHO} "Error searching aci for ${LDAP_BASEDN}" 4112 cat ${TMPDIR}/chk_top_aci 4113 cleanup 4114 exit 1 4115 fi 4116 ${GREP} "${ACI_NAME}" ${TMPDIR}/chk_top_aci > /dev/null 2>&1 4117 if [ $? -eq 0 ]; then 4118 ${ECHO} " ${STEP}. Top level ACI ${ACI_NAME} already exists for ${LDAP_BASEDN}." 4119 STEP=`expr $STEP + 1` 4120 return 0 4121 fi 4122 4123 # Crate LDIF for top level ACI. 4124 ( cat <<EOF 4125dn: ${LDAP_BASEDN} 4126changetype: modify 4127add: aci 4128aci: (targetattr = "cn||uid||uidNumber||gidNumber||homeDirectory||shadowLastChange||shadowMin||shadowMax||shadowWarning||shadowInactive||shadowExpire||shadowFlag||memberUid||SolarisAuditAlways||SolarisAuditNever||SolarisAttrKeyValue||SolarisAttrReserved1||SolarisAttrReserved2||SolarisUserQualifier")(version 3.0; acl ${ACI_NAME}; deny (write) userdn = "ldap:///self";) 4129- 4130EOF 4131) > ${TMPDIR}/top_aci 4132 4133 # Add the entry. 4134 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/top_aci ${VERB}" 4135 if [ $? -ne 0 ]; then 4136 ${ECHO} " ERROR: Modify of top level ACI failed! (restricts self modify)" 4137 cleanup 4138 exit 1 4139 fi 4140 4141 # Display message that schema is updated. 4142 ${ECHO} " ${STEP}. ACI for ${LDAP_BASEDN} modified to disable self modify." 4143 STEP=`expr $STEP + 1` 4144} 4145 4146 4147# 4148# add_vlv_aci(): Add access control information (aci) for VLV. 4149# 4150add_vlv_aci() 4151{ 4152 [ $DEBUG -eq 1 ] && ${ECHO} "In add_vlv_aci()" 4153 4154 # Add the VLV ACI. 4155 ( cat <<EOF 4156dn: oid=2.16.840.1.113730.3.4.9,cn=features,cn=config 4157changetype: modify 4158replace: aci 4159aci: (targetattr != "aci") (version 3.0; acl "VLV Request Control"; allow(read,search,compare) userdn = "ldap:///anyone";) 4160EOF 4161) > ${TMPDIR}/vlv_aci 4162 4163 # Add the entry. 4164 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/vlv_aci ${VERB}" 4165 if [ $? -ne 0 ]; then 4166 ${ECHO} " ERROR: Add of VLV ACI failed!" 4167 cleanup 4168 exit 1 4169 fi 4170 4171 # Display message that schema is updated. 4172 ${ECHO} " ${STEP}. Add of VLV Access Control Information (ACI)." 4173 STEP=`expr $STEP + 1` 4174} 4175 4176 4177# 4178# set_nisdomain(): Add the NisDomainObject to the Base DN. 4179# 4180set_nisdomain() 4181{ 4182 [ $DEBUG -eq 1 ] && ${ECHO} "In set_nisdomain()" 4183 4184 # Check if nisDomain is already set. 4185 ${EVAL} "${LDAPSEARCH} ${LDAP_ARGS} -b \"${LDAP_BASEDN}\" -s base \ 4186 \"objectclass=*\"" > ${TMPDIR}/chk_nisdomain 2>&1 4187 ${EVAL} "${GREP} -i nisDomain ${TMPDIR}/chk_nisdomain ${VERB}" 4188 if [ $? -eq 0 ]; then 4189 ${ECHO} " ${STEP}. NisDomainObject for ${LDAP_BASEDN} was already set." 4190 STEP=`expr $STEP + 1` 4191 return 0 4192 fi 4193 4194 # Add the new top level containers. 4195 ( cat <<EOF 4196dn: ${LDAP_BASEDN} 4197changetype: modify 4198objectclass: nisDomainObject 4199nisdomain: ${LDAP_DOMAIN} 4200EOF 4201) > ${TMPDIR}/nis_domain 4202 4203 # Add the entry. 4204 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/nis_domain ${VERB}" 4205 if [ $? -ne 0 ]; then 4206 ${ECHO} " ERROR: update of NisDomainObject in ${LDAP_BASEDN} failed." 4207 cleanup 4208 exit 1 4209 fi 4210 4211 # Display message that schema is updated. 4212 ${ECHO} " ${STEP}. NisDomainObject added to ${LDAP_BASEDN}." 4213 STEP=`expr $STEP + 1` 4214} 4215 4216 4217# 4218# check_attrName(): Check that the attribute name is valid. 4219# $1 Key to check. 4220# Returns 0 : valid name 1 : invalid name 4221# 4222check_attrName() 4223{ 4224 [ $DEBUG -eq 1 ] && ${ECHO} "In check_attrName()" 4225 [ $DEBUG -eq 1 ] && ${ECHO} "check_attrName: Input Param = $1" 4226 4227 ${ECHO} $1 | ${EGREP} '^[0-9]+(\.[0-9]+)*$' > /dev/null 2>&1 4228 if [ $? -eq 0 ]; then 4229 ${EVAL} "${LDAPSEARCH} ${SERVER_ARGS} -b cn=schema -s base \"objectclass=*\" \ 4230 attributeTypes | ${EGREP} -i '^attributetypes[ ]*=[ ]*\([ ]*$1 ' ${VERB}" 4231 else 4232 ${EVAL} "${LDAPSEARCH} ${SERVER_ARGS} -b cn=schema -s base \"objectclass=*\" \ 4233 attributeTypes | ${EGREP} -i \"'$1'\" ${VERB}" 4234 fi 4235 4236 if [ $? -ne 0 ]; then 4237 return 1 4238 else 4239 return 0 4240 fi 4241} 4242 4243 4244# 4245# get_objectclass(): Determine the objectclass for the given attribute name 4246# $1 Attribute name to check. 4247# _ATTR_NAME Return value, Object Name or NULL if unknown to idsconfig. 4248# 4249# NOTE: An attribute name can be valid but still we might not be able 4250# to determine the objectclass from the table. 4251# In such cases, the user needs to create the necessary object(s). 4252# 4253get_objectclass() 4254{ 4255 [ $DEBUG -eq 1 ] && ${ECHO} "In get_objectclass()" 4256 [ $DEBUG -eq 1 ] && ${ECHO} "get_objectclass: Input Param = $1" 4257 4258 # Set return value to NULL string. 4259 _ATTR_NAME="" 4260 4261 # Test key for type: 4262 case `${ECHO} ${1} | tr '[A-Z]' '[a-z]'` in 4263 ou | organizationalunitname | 2.5.4.11) _ATTR_NAME="organizationalUnit" ;; 4264 dc | domaincomponent | 0.9.2342.19200300.100.1.25) _ATTR_NAME="domain" ;; 4265 o | organizationname | 2.5.4.10) _ATTR_NAME="organization" ;; 4266 c | countryname | 2.5.4.6) _ATTR_NAME="country" ;; 4267 *) _ATTR_NAME="" ;; 4268 esac 4269 4270 [ $DEBUG -eq 1 ] && ${ECHO} "get_objectclass: _ATTR_NAME = $_ATTR_NAME" 4271} 4272 4273 4274# 4275# add_base_objects(): Add any necessary base objects. 4276# 4277add_base_objects() 4278{ 4279 [ $DEBUG -eq 1 ] && ${ECHO} "In add_base_objects()" 4280 4281 # Convert to lower case for basename. 4282 format_string "${LDAP_BASEDN}" 4283 LOWER_BASEDN="${FMT_STR}" 4284 format_string "${LDAP_SUFFIX}" 4285 LOWER_SUFFIX="${FMT_STR}" 4286 4287 [ $DEBUG -eq 1 ] && ${ECHO} "LOWER_BASEDN: ${LOWER_BASEDN}" 4288 [ $DEBUG -eq 1 ] && ${ECHO} "LOWER_SUFFIX: ${LOWER_SUFFIX}" 4289 4290 # Create additional components. 4291 if [ "${LOWER_BASEDN}" = "${LOWER_SUFFIX}" ]; then 4292 [ $DEBUG -eq 1 ] && ${ECHO} "Base DN and Suffix equivalent" 4293 else 4294 # first, test that the suffix is valid 4295 dcstmp=`basename "${LOWER_BASEDN}" "${LOWER_SUFFIX}"` 4296 if [ "$dcstmp" = "${LOWER_BASEDN}" ]; then 4297 # should not happen since check_basedn_suffix() succeeded 4298 ${ECHO} "Invalid suffix ${LOWER_SUFFIX}" 4299 ${ECHO} "for Base DN ${LOWER_BASEDN}" 4300 cleanup 4301 exit 1 4302 fi 4303 # OK, suffix is valid, start working with LDAP_BASEDN 4304 # field separator is ',' (i.e., space is a valid character) 4305 dcstmp2="`${ECHO} ${LDAP_BASEDN} | 4306 sed -e 's/[ ]*,[ ]*/,/g' -e 's/[ ]*=[ ]*/=/g'`" 4307 dcs="" 4308 # use dcstmp to count the loop, and dcstmp2 to get the correct 4309 # string case 4310 # dcs should be in reverse order, only for these components 4311 # that need to be added 4312 while [ -n "${dcstmp}" ] 4313 do 4314 i2=`${ECHO} "$dcstmp2" | cut -f1 -d','` 4315 dk=`${ECHO} $i2 | awk -F= '{print $1}'` 4316 dc=`${ECHO} $i2 | awk -F= '{print $2}'` 4317 dcs="$dk=$dc,$dcs"; 4318 dcstmp2=`${ECHO} "$dcstmp2" | cut -f2- -d','` 4319 dcstmp=`${ECHO} "$dcstmp" | cut -f2- -d','` 4320 [ $DEBUG -eq 1 ] && \ 4321 ${ECHO} "dcs: ${dcs}\ndcstmp: ${dcstmp}\ndcstmp2: ${dcstmp2}\n" 4322 done 4323 4324 4325 4326 lastdc=${LDAP_SUFFIX} 4327 dc=`${ECHO} "${dcs}" | cut -f1 -d','` 4328 dcstmp=`${ECHO} "${dcs}" | cut -f2- -d','` 4329 while [ -n "${dc}" ]; do 4330 # Get Key and component from $dc. 4331 dk2=`${ECHO} $dc | awk -F= '{print $1}'` 4332 dc2=`${ECHO} $dc | awk -F= '{print $2}'` 4333 4334 # At this point, ${dk2} is a valid attribute name 4335 4336 # Check if entry exists first, if so, skip to next. 4337 ${LDAPSEARCH} ${SERVER_ARGS} -b "${dk2}=${dc2},$lastdc" -s base "objectclass=*" > /dev/null 2>&1 4338 if [ $? -eq 0 ]; then 4339 # Set the $lastdc to new dc. 4340 lastdc="${dk2}=${dc2},$lastdc" 4341 4342 # Process next component. 4343 dc=`${ECHO} "${dcstmp}" | cut -f1 -d','` 4344 dcstmp=`${ECHO} "${dcstmp}" | cut -f2- -d','` 4345 continue 4346 4347 fi 4348 4349 # Determine the objectclass for the entry. 4350 get_objectclass $dk2 4351 OBJ_Name=${_ATTR_NAME} 4352 if [ "${OBJ_Name}" = "" ]; then 4353 ${ECHO} "Cannot determine objectclass for $dk2" 4354 ${ECHO} "Please create ${dk2}=${dc2},$lastdc entry and rerun idsconfig" 4355 exit 1 4356 fi 4357 4358 # Add the new container. 4359 ( cat <<EOF 4360dn: ${dk2}=${dc2},$lastdc 4361${dk2}: $dc2 4362objectClass: top 4363objectClass: ${OBJ_Name} 4364EOF 4365) > ${TMPDIR}/base_objects 4366 4367 4368 # Set the $lastdc to new dc. 4369 lastdc="${dk2}=${dc2},$lastdc" 4370 4371 # Add the entry. 4372 ${EVAL} "${LDAPMODIFY} -a ${LDAP_ARGS} -f ${TMPDIR}/base_objects ${VERB}" 4373 if [ $? -ne 0 ]; then 4374 ${ECHO} " ERROR: update of base objects ${dc} failed." 4375 cleanup 4376 exit 1 4377 fi 4378 4379 # Display message that schema is updated. 4380 ${ECHO} " ${STEP}. Created DN component ${dc}." 4381 STEP=`expr $STEP + 1` 4382 4383 # Process next component. 4384 dc=`${ECHO} "${dcstmp}" | cut -f1 -d','` 4385 dcstmp=`${ECHO} "${dcstmp}" | cut -f2- -d','` 4386 done 4387 fi 4388} 4389 4390 4391# 4392# add_new_containers(): Add the top level classes. 4393# 4394# $1 = Base DN 4395# 4396add_new_containers() 4397{ 4398 [ $DEBUG -eq 1 ] && ${ECHO} "In add_new_containers()" 4399 4400 for ou in people group rpc protocols networks netgroup \ 4401 aliases hosts services ethers profile printers projects \ 4402 SolarisAuthAttr SolarisProfAttr Timezone ipTnet ; do 4403 4404 # Check if nismaps already exist. 4405 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"ou=${ou},${LDAP_BASEDN}\" -s base \"objectclass=*\" ${VERB}" 4406 if [ $? -eq 0 ]; then 4407 continue 4408 fi 4409 4410 # Create TMP file to add. 4411 ( cat <<EOF 4412dn: ou=${ou},${LDAP_BASEDN} 4413ou: ${ou} 4414objectClass: top 4415objectClass: organizationalUnit 4416EOF 4417) > ${TMPDIR}/toplevel.${ou} 4418 4419 # Add the entry. 4420 ${EVAL} "${LDAPMODIFY} -a ${LDAP_ARGS} -f ${TMPDIR}/toplevel.${ou} ${VERB}" 4421 if [ $? -ne 0 ]; then 4422 ${ECHO} " ERROR: Add of ou=${ou} container failed!" 4423 cleanup 4424 exit 1 4425 fi 4426 done 4427 4428 # Display message that top level OU containers complete. 4429 ${ECHO} " ${STEP}. Top level \"ou\" containers complete." 4430 STEP=`expr $STEP + 1` 4431} 4432 4433 4434# 4435# add_auto_maps(): Add the automount map entries. 4436# 4437# auto_home, auto_direct, auto_master, auto_shared 4438# 4439add_auto_maps() 4440{ 4441 [ $DEBUG -eq 1 ] && ${ECHO} "In add_auto_maps()" 4442 4443 # Set AUTO_MAPS for maps to create. 4444 AUTO_MAPS="auto_home auto_direct auto_master auto_shared" 4445 4446 for automap in $AUTO_MAPS; do 4447 # Check if automaps already exist. 4448 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"automountMapName=${automap},${LDAP_BASEDN}\" -s base \"objectclass=*\" ${VERB}" 4449 if [ $? -eq 0 ]; then 4450 continue 4451 fi 4452 4453 # Create the tmp file to add. 4454 ( cat <<EOF 4455dn: automountMapName=${automap},${LDAP_BASEDN} 4456automountMapName: ${automap} 4457objectClass: top 4458objectClass: automountMap 4459EOF 4460) > ${TMPDIR}/automap.${automap} 4461 4462 # Add the entry. 4463 ${EVAL} "${LDAPMODIFY} -a ${LDAP_ARGS} -f ${TMPDIR}/automap.${automap} ${VERB}" 4464 if [ $? -ne 0 ]; then 4465 ${ECHO} " ERROR: Add of automap ${automap} failed!" 4466 cleanup 4467 exit 1 4468 fi 4469 done 4470 4471 # Display message that automount entries are updated. 4472 ${ECHO} " ${STEP}. automount maps: $AUTO_MAPS processed." 4473 STEP=`expr $STEP + 1` 4474} 4475 4476 4477# 4478# add_proxyagent(): Add entry for nameservice to use to access server. 4479# 4480add_proxyagent() 4481{ 4482 [ $DEBUG -eq 1 ] && ${ECHO} "In add_proxyagent()" 4483 4484 # Check if nismaps already exist. 4485 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"${LDAP_PROXYAGENT}\" -s base \"objectclass=*\" ${VERB}" 4486 if [ $? -eq 0 ]; then 4487 ${ECHO} " ${STEP}. Proxy Agent ${LDAP_PROXYAGENT} already exists." 4488 STEP=`expr $STEP + 1` 4489 return 0 4490 fi 4491 4492 # Get cn and sn names from LDAP_PROXYAGENT. 4493 cn_tmp=`${ECHO} ${LDAP_PROXYAGENT} | cut -f1 -d, | cut -f2 -d=` 4494 4495 # Create the tmp file to add. 4496 ( cat <<EOF 4497dn: ${LDAP_PROXYAGENT} 4498cn: ${cn_tmp} 4499sn: ${cn_tmp} 4500objectclass: top 4501objectclass: person 4502userpassword: ${LDAP_PROXYAGENT_CRED} 4503EOF 4504) > ${TMPDIR}/proxyagent 4505 4506 # Add the entry. 4507 ${EVAL} "${LDAPMODIFY} -a ${LDAP_ARGS} -f ${TMPDIR}/proxyagent ${VERB}" 4508 if [ $? -ne 0 ]; then 4509 ${ECHO} " ERROR: Adding proxyagent failed!" 4510 cleanup 4511 exit 1 4512 fi 4513 4514 # Display message that schema is updated. 4515 ${ECHO} " ${STEP}. Proxy Agent ${LDAP_PROXYAGENT} added." 4516 STEP=`expr $STEP + 1` 4517} 4518 4519 4520# 4521# allow_proxy_read_pw(): Give Proxy Agent read permission for password. 4522# 4523allow_proxy_read_pw() 4524{ 4525 [ $DEBUG -eq 1 ] && ${ECHO} "In allow_proxy_read_pw()" 4526 4527 # Set ACI Name 4528 PROXY_ACI_NAME="LDAP_Naming_Services_proxy_password_read" 4529 4530 # Search for ACI_NAME 4531 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"${LDAP_BASEDN}\" -s base objectclass=* aci > ${TMPDIR}/chk_proxyread_aci 2>&1" 4532 ${GREP} "${PROXY_ACI_NAME}" ${TMPDIR}/chk_proxyread_aci > /dev/null 2>&1 4533 if [ $? -eq 0 ]; then 4534 ${ECHO} " ${STEP}. Proxy ACI ${PROXY_ACI_NAME=} already exists for ${LDAP_BASEDN}." 4535 STEP=`expr $STEP + 1` 4536 return 0 4537 fi 4538 4539 # Create the tmp file to add. 4540 ( cat <<EOF 4541dn: ${LDAP_BASEDN} 4542changetype: modify 4543add: aci 4544aci: (target="ldap:///${LDAP_BASEDN}")(targetattr="userPassword")(version 3.0; acl ${PROXY_ACI_NAME}; allow (compare,read,search) userdn = "ldap:///${LDAP_PROXYAGENT}";) 4545EOF 4546) > ${TMPDIR}/proxy_read 4547 4548 # Add the entry. 4549 ${EVAL} "${LDAPMODIFY} ${LDAP_ARGS} -f ${TMPDIR}/proxy_read ${VERB}" 4550 if [ $? -ne 0 ]; then 4551 ${ECHO} " ERROR: Allow ${LDAP_PROXYAGENT} to read password failed!" 4552 cleanup 4553 exit 1 4554 fi 4555 4556 # Display message that schema is updated. 4557 ${ECHO} " ${STEP}. Give ${LDAP_PROXYAGENT} read permission for password." 4558 STEP=`expr $STEP + 1` 4559} 4560 4561 4562# 4563# add_profile(): Add client profile to server. 4564# 4565add_profile() 4566{ 4567 [ $DEBUG -eq 1 ] && ${ECHO} "In add_profile()" 4568 4569 # If profile name already exists, DELETE it, and add new one. 4570 eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"cn=${LDAP_PROFILE_NAME},ou=profile,${LDAP_BASEDN}\" -s base \"objectclass=*\" ${VERB}" 4571 if [ $? -eq 0 ]; then 4572 # Create Delete file. 4573 ( cat <<EOF 4574cn=${LDAP_PROFILE_NAME},ou=profile,${LDAP_BASEDN} 4575EOF 4576) > ${TMPDIR}/del_profile 4577 4578 # Check if DEL_OLD_PROFILE is set. (If not ERROR) 4579 if [ $DEL_OLD_PROFILE -eq 0 ]; then 4580 ${ECHO} "ERROR: Profile name ${LDAP_PROFILE_NAME} exists! Add failed!" 4581 exit 1 4582 fi 4583 4584 # Delete the OLD profile. 4585 ${EVAL} "${LDAPDELETE} ${LDAP_ARGS} -f ${TMPDIR}/del_profile ${VERB}" 4586 if [ $? -ne 0 ]; then 4587 ${ECHO} " ERROR: Attempt to DELETE profile failed!" 4588 cleanup 4589 exit 1 4590 fi 4591 fi 4592 4593 # Build the "ldapclient genprofile" command string to execute. 4594 GEN_CMD="ldapclient genprofile -a \"profileName=${LDAP_PROFILE_NAME}\"" 4595 4596 # Add required argument defaultSearchBase. 4597 GEN_CMD="${GEN_CMD} -a \"defaultSearchBase=${LDAP_BASEDN}\"" 4598 4599 # Add optional parameters. 4600 [ -n "$LDAP_SERVER_LIST" ] && \ 4601 GEN_CMD="${GEN_CMD} -a \"defaultServerList=${LDAP_SERVER_LIST}\"" 4602 [ -n "$LDAP_SEARCH_SCOPE" ] && \ 4603 GEN_CMD="${GEN_CMD} -a \"defaultSearchScope=${LDAP_SEARCH_SCOPE}\"" 4604 [ -n "$LDAP_CRED_LEVEL" ] && \ 4605 GEN_CMD="${GEN_CMD} -a \"credentialLevel=${LDAP_CRED_LEVEL}\"" 4606 [ -n "$LDAP_AUTHMETHOD" ] && \ 4607 GEN_CMD="${GEN_CMD} -a \"authenticationMethod=${LDAP_AUTHMETHOD}\"" 4608 [ -n "$LDAP_FOLLOWREF" ] && \ 4609 GEN_CMD="${GEN_CMD} -a \"followReferrals=${LDAP_FOLLOWREF}\"" 4610 [ -n "$LDAP_SEARCH_TIME_LIMIT" ] && \ 4611 GEN_CMD="${GEN_CMD} -a \"searchTimeLimit=${LDAP_SEARCH_TIME_LIMIT}\"" 4612 [ -n "$LDAP_PROFILE_TTL" ] && \ 4613 GEN_CMD="${GEN_CMD} -a \"profileTTL=${LDAP_PROFILE_TTL}\"" 4614 [ -n "$LDAP_BIND_LIMIT" ] && \ 4615 GEN_CMD="${GEN_CMD} -a \"bindTimeLimit=${LDAP_BIND_LIMIT}\"" 4616 [ -n "$LDAP_PREF_SRVLIST" ] && \ 4617 GEN_CMD="${GEN_CMD} -a \"preferredServerList=${LDAP_PREF_SRVLIST}\"" 4618 [ -n "$LDAP_SRV_AUTHMETHOD_PAM" ] && \ 4619 GEN_CMD="${GEN_CMD} -a \"serviceAuthenticationMethod=${LDAP_SRV_AUTHMETHOD_PAM}\"" 4620 [ -n "$LDAP_SRV_AUTHMETHOD_KEY" ] && \ 4621 GEN_CMD="${GEN_CMD} -a \"serviceAuthenticationMethod=${LDAP_SRV_AUTHMETHOD_KEY}\"" 4622 [ -n "$LDAP_SRV_AUTHMETHOD_CMD" ] && \ 4623 GEN_CMD="${GEN_CMD} -a \"serviceAuthenticationMethod=${LDAP_SRV_AUTHMETHOD_CMD}\"" 4624 4625 # Check if there are any service search descriptors to ad. 4626 if [ -s "${SSD_FILE}" ]; then 4627 ssd_2_profile 4628 fi 4629 4630 # Execute "ldapclient genprofile" to create profile. 4631 eval ${GEN_CMD} > ${TMPDIR}/gen_profile 2> ${TMPDIR}/gen_profile_ERR 4632 if [ $? -ne 0 ]; then 4633 ${ECHO} " ERROR: ldapclient genprofile failed!" 4634 cleanup 4635 exit 1 4636 fi 4637 4638 # Add the generated profile.. 4639 ${EVAL} "${LDAPMODIFY} -a ${LDAP_ARGS} -f ${TMPDIR}/gen_profile ${VERB}" 4640 if [ $? -ne 0 ]; then 4641 ${ECHO} " ERROR: Attempt to add profile failed!" 4642 cleanup 4643 exit 1 4644 fi 4645 4646 # Display message that schema is updated. 4647 ${ECHO} " ${STEP}. Generated client profile and loaded on server." 4648 STEP=`expr $STEP + 1` 4649} 4650 4651 4652# 4653# cleanup(): Remove the TMPDIR and all files in it. 4654# 4655cleanup() 4656{ 4657 [ $DEBUG -eq 1 ] && ${ECHO} "In cleanup()" 4658 4659 rm -fr ${TMPDIR} 4660} 4661 4662 4663# 4664# * * * MAIN * * * 4665# 4666# Description: 4667# This script assumes that the iPlanet Directory Server (iDS) is 4668# installed and that setup has been run. This script takes the 4669# iDS server from that point and sets up the infrastructure for 4670# LDAP Naming Services. After running this script, ldapaddent(1M) 4671# or some other tools can be used to populate data. 4672 4673# Initialize the variables that need to be set to NULL, or some 4674# other initial value before the rest of the functions can be called. 4675init 4676 4677# Parse command line arguments. 4678parse_arg $* 4679shift $? 4680 4681# Print extra line to separate from prompt. 4682${ECHO} " " 4683 4684# Either Load the user specified config file 4685# or prompt user for config info. 4686if [ -n "$INPUT_FILE" ] 4687then 4688 load_config_file 4689 INTERACTIVE=0 # Turns off prompts that occur later. 4690 validate_info # Validate basic info in file. 4691 chk_ids_version # Check iDS version for compatibility. 4692 gssapi_setup_auto 4693else 4694 # Display BACKUP warning to user. 4695 display_msg backup_server 4696 get_confirm "Do you wish to continue with server setup (y/n/h)?" "n" "backup_help" 4697 if [ $? -eq 0 ]; then # if No, cleanup and exit. 4698 cleanup ; exit 1 4699 fi 4700 4701 # Prompt for values. 4702 prompt_config_info 4703 display_summary # Allow user to modify results. 4704 INTERACTIVE=1 # Insures future prompting. 4705fi 4706 4707# Modify slapd.oc.conf to ALLOW cn instead of REQUIRE. 4708modify_cn 4709 4710# Modify timelimit to user value. 4711[ $NEED_TIME -eq 1 ] && modify_timelimit 4712 4713# Modify sizelimit to user value. 4714[ $NEED_SIZE -eq 1 ] && modify_sizelimit 4715 4716# Modify the password storage scheme to support CRYPT. 4717if [ "$NEED_CRYPT" = "TRUE" ]; then 4718 modify_pwd_crypt 4719fi 4720 4721# Update the schema (Attributes, Objectclass Definitions) 4722if [ ${SCHEMA_UPDATED} -eq 0 ]; then 4723 update_schema_attr 4724 update_schema_obj 4725fi 4726 4727# Add suffix together with its root entry (if needed) 4728add_suffix || 4729{ 4730 cleanup 4731 exit 1 4732} 4733 4734# Add base objects (if needed) 4735add_base_objects 4736 4737# Update the NisDomainObject. 4738# The Base DN might of just been created, so this MUST happen after 4739# the base objects have been added! 4740set_nisdomain 4741 4742# Add top level classes (new containers) 4743add_new_containers 4744 4745# Add common nismaps. 4746add_auto_maps 4747 4748# Modify top ACI. 4749modify_top_aci 4750 4751# Add Access Control Information for VLV. 4752add_vlv_aci 4753 4754# if Proxy needed, Add Proxy Agent and give read permission for password. 4755if [ $NEED_PROXY -eq 1 ]; then 4756 add_proxyagent 4757 allow_proxy_read_pw 4758fi 4759 4760# Generate client profile and add it to the server. 4761add_profile 4762 4763# Add Indexes to improve Search Performance. 4764add_eq_indexes 4765add_sub_indexes 4766add_vlv_indexes 4767 4768# Display setup complete message 4769display_msg setup_complete 4770 4771# Display VLV index commands to be executed on server. 4772display_vlv_cmds 4773 4774# Create config file if requested. 4775[ -n "$OUTPUT_FILE" ] && create_config_file 4776 4777# Removed the TMPDIR and all files in it. 4778cleanup 4779 4780exit 0 4781# end of MAIN. 4782