source: gpfs_3.1_ker2.6.20/lpp/mmfs/bin/mmauth @ 16

Last change on this file since 16 was 16, checked in by rock, 16 years ago
  • Property svn:executable set to *
File size: 49.9 KB
Line 
1#!/bin/ksh
2# IBM_PROLOG_BEGIN_TAG
3# This is an automatically generated prolog.
4
5
6
7# Licensed Materials - Property of IBM
8
9# (C) COPYRIGHT International Business Machines Corp. 2004,2006
10# All Rights Reserved
11
12# US Government Users Restricted Rights - Use, duplication or
13# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
14
15# IBM_PROLOG_END_TAG
16# @(#)80 1.38.1.4 src/avs/fs/mmfs/ts/admin/mmauth.sh, mmfs, avs_rgpfs24, rgpfs24s005a 6/14/06 14:39:42
17##############################################################################
18#
19# Usage:
20#
21#   mmauth genkey  {new | commit}
22#
23#   mmauth add     remoteClusterName -k keyfile [-l cipherList]
24#
25#   mmauth update  remoteClusterName [-C newClusterName]
26#                  [-k keyfile] [-l cipherList]
27#
28#   mmauth delete {remoteClusterName | all}
29#
30#   mmauth show   [remoteClusterName | all]
31#
32#   mmauth grant  {remoteClusterName | all} -f {device | all}
33#                 [-a {rw | ro | none}] [-r {uid:gid | no}]
34#
35#   mmauth deny   {remoteClusterName | all} -f {device | all}
36#
37# where
38#
39#   remoteClusterName   is the fully-qualified name for a remote cluster that
40#                 will be allowed to mount file systems owned by this cluster.
41#
42#   -C newClusterName  is the new fully-qualified cluster name for an
43#                 already-defined cluster remoteClusterName.
44#
45#   -k keyfile    is the authentication key file generated by the mmauth
46#                 command on the remote cluster.
47#
48#   -l cipherList   is the cipher list to be used when establishing a connection
49#                 to the remote cluster.
50#
51#   -f device     is the name of the file system for which access is being
52#                 granted or denied.
53#
54#   -a {rw | ro | none}   is the type of access being granted.  Default is "rw".
55#                 Specifying "none" is the same as running mmauth deny.
56#
57#   -r {uid:gid | no}  is a root credentials remapping (root-squash) option.
58#                 The UID and GID of all processes with root credentials
59#                 from the remote cluster, will be remapped to the specified
60#                 values. The default is not to remap the root UID and GID.
61#                 Note:  The UID and GID must be specified as an unsigned
62#                        integers or as symbolic names that can be resolved
63#                        by the OS to valid UID and GID.  Specifying 'no'
64#                        (or "off" or DEFAULT) turns off the remapping.
65#
66##############################################################################
67
68# Include global declarations and service routines.
69. /usr/lpp/mmfs/bin/mmglobfuncs
70. /usr/lpp/mmfs/bin/mmsdrfsdef
71. /usr/lpp/mmfs/bin/mmfsfuncs
72
73sourceFile="mmauth.sh"
74[[ -n $DEBUG || -n $DEBUGmmauth ]] && set -x
75$mmTRACE_ENTER "$*"
76
77# Local work files.  Names should be of the form:
78#   fn=${tmpDir}fn.${mmcmd}.$$
79verifiedKey=${tmpDir}verifiedKey.${mmcmd}.$$
80fsFile=${tmpDir}fsFile.${mmcmd}.$$
81tmpkey=${sslStageDir}tmpkey.${mmcmd}.$$
82
83LOCAL_FILES=" $verifiedKey $tmpkey $fsFile "
84
85
86# Local variables
87usageMsg=249
88contactNodesCount=0
89
90
91# Local functions
92
93##########################################################################
94#
95# Function:  Determine the SHA digest (fingerprint) that corresponds
96#            to the public key file for the specified cluster.
97#
98# Input:     $1 - cluster name
99#            $2 - sdrfs file to use
100#
101# Output:    The SHA digest string.
102#
103# Returns:   0 - no errors encountered
104#            1 - unexpected error
105#
106##########################################################################
107function getFingerprint  # <clusterName> <sdrfsFile>
108{
109  typeset sourceFile="mmauth.sh"
110  [[ -n $DEBUG || -n $DEBUGgetFingerprint ]] && set -x
111  typeset clusterName=$1
112  typeset sdrfs=$2
113
114  typeset sdrfsLine clusterNameField lineTypeField keyLine keyFingerprint
115
116  [[ ! -f $sdrfs ]] && return 1
117  $rm -f $tmpPublicKey
118
119  # Go through the current mmsdrfs file and retrieve the requested information.
120  IFS=":"
121  exec 4<&-
122  exec 4< $sdrfs
123  while read -u4 sdrfsLine
124  do
125    # Parse the line.
126    set -f ; set -- $sdrfsLine ; set +f
127    clusterNameField=$1
128    lineTypeField=$2
129
130    # We are interested only in the AUTHORIZED_KEY lines for the specified cluster.
131    if [[ $clusterNameField = $clusterName && $lineTypeField = $AUTHORIZED_KEY ]]
132    then
133      # The public key information is everything past the first 4 fields.
134      shift 4
135      keyLine=$*
136      keyLine="${keyLine%%+(:)}"
137
138      # Examine the lines.  If the key was generated by the cs4b version
139      # of mmauth genkey, there will be stanza lines and the fingerprint
140      # will be included.  If the fingerprint is missing, or if this is
141      # a key generated by a cs3b version of mmauth genkey, extract the
142      # public key in a temp file.
143      if [[ $keyLine = "clusterName="*            ||
144            $keyLine = "clusterID="*              ||
145            $keyLine = "genkeyFormat="*           ||
146            $keyLine = "genkeyCompatibleFormat="* ||
147            $keyLine = "keyGenNumber="*           ||
148            $keyLine = "publicKey="               ||
149            $keyLine = "certificate="             ]]
150      then
151        :  # Skip the line.
152
153      elif [[ $keyLine = "keyDigest="* ]]
154      then
155        # Return the key fingerprint.
156        keyFingerprint="${keyLine#keyDigest=}"
157        break
158
159      else
160        # Add the line to the key file.
161        IFS=""     # Reset IFS to preserve blanks and tabs.
162        print -- "$keyLine" >> $tmpPublicKey
163        checkForErrors "writing to file $tmpPublicKey" $?
164      fi  # end of if [[ $keyLine = "clusterName="* ]]
165    fi  # end of if [[ $clusterNameField = $clusterName && ...
166
167    IFS=":" # Change the separator back to ":" for the next iteration.
168
169  done  # end while read -u4 sdrfsLine
170
171  IFS="$IFS_sv"  # Restore the default IFS settings.
172
173  # If the fingerprint was not imbedded in the key stanza,
174  # determine it with the help of the openssl command.
175  if [[ -z $keyFingerprint && -s $tmpPublicKey ]]
176  then
177    keyFingerprint=$($openssl dgst -sha -hex < $tmpPublicKey)
178    checkForErrors "openssl dgst -sha -hex $tmpPublicKey" $?
179  fi
180  [[ -z $keyFingerprint ]] && keyFingerprint="(undefined)"
181
182  # Return the result.
183  print -- "$keyFingerprint"
184  return 0
185
186}  #------------ end function getFingerprint -----------------
187
188
189##########################################################################
190#
191# Function:  Determine the SHA digest (fingerprint) that corresponds
192#            to the specified public key file for the local cluster.
193#
194# Input:     $1 - key file to use
195#
196# Output:    The SHA digest string.
197#
198# Returns:   0 - no errors encountered
199#            1 - unexpected error
200#
201##########################################################################
202function getLocalFingerprint  # <keyFile>
203{
204  typeset sourceFile="mmauth.sh"
205  [[ -n $DEBUG || -n $DEBUGgetLocalFingerprint ]] && set -x
206  typeset keyFile=$1
207
208  typeset keyLine keyFingerprint
209
210  [[ ! -f $keyFile ]] && return 1
211  $rm -f $tmpPublicKey
212
213  # Go through the specified file and retrieve the requested information.
214  exec 4<&-
215  exec 4< $keyFile
216  while read -u4 keyLine
217  do
218    # Examine the lines.  If the key was generated by the cs4b version
219    # of mmauth genkey, there will be stanza lines and the fingerprint
220    # will be included.  If the fingerprint is missing, or if this is
221    # a key generated by a cs3b version of mmauth genkey, extract the
222    # public key in a temp file.
223    if [[ $keyLine = "clusterName="*            ||
224          $keyLine = "clusterID="*              ||
225          $keyLine = "genkeyFormat="*           ||
226          $keyLine = "genkeyCompatibleFormat="* ||
227          $keyLine = "keyGenNumber="*           ||
228          $keyLine = "publicKey="               ||
229          $keyLine = "certificate="             ]]
230    then
231      :  # Skip the line.
232
233    elif [[ $keyLine = "keyDigest="* ]]
234    then
235      # Return the key fingerprint.
236      keyFingerprint="${keyLine#keyDigest=}"
237      break
238
239    else
240      # Add the line to the key file.
241      print -- "$keyLine" >> $tmpPublicKey
242      checkForErrors "writing to file $tmpPublicKey" $?
243    fi  # end of if [[ $keyLine = "clusterName="* ]]
244  done  # end while read -u4 keyLine
245
246  # If the fingerprint was not imbedded in the key stanza,
247  # determine it with the help of the openssl command.
248  if [[ -z $keyFingerprint && -s $tmpPublicKey ]]
249  then
250    keyFingerprint=$($openssl dgst -sha -hex < $tmpPublicKey)
251    checkForErrors "openssl dgst -sha -hex $tmpPublicKey" $?
252  fi
253  [[ -z $keyFingerprint ]] && keyFingerprint="(undefined)"
254
255  # Return the result.
256  print -- "$keyFingerprint"
257  return 0
258
259}  #------------ end function getLocalFingerprint -----------------
260
261
262################################################################
263#
264# Function:  Retrieve the list of authorized file systems
265#            for a given cluster.
266#
267# Input:     $1 - cluster name
268#            $2 - sdrfs file to use
269#
270# Output:    A line for each of the file systems that
271#            the specified cluster is allowed to access.
272#            The following information is returned:
273#               deviceName (maxAccessAllowed, rootSquashInfo)
274#
275# Returns:   0 - success
276#            1 - error encountered
277#
278################################################################
279function getFileSystemList   # <clusterName> <sdrfs>
280{
281  typeset sourceFile="mmauth.sh"
282  [[ -n $DEBUG || -n $DEBUGgetFileSystemList ]] && set -x
283  $mmTRACE_ENTER "$*"
284  typeset clusterName=$1
285  typeset sdrfs=$2
286
287  typeset fsList rootAllowed rootMappedTo
288
289  [[ ! -s $sdrfs ]] &&  \
290    checkForErrors "getFileSystemList: Missing or empty file $sdrfs" 1
291
292  # Initialize dictionary items.
293  rootAllowed=$(printInfoMsg 180)
294  rootMappedTo=$(printInfoMsg 181)
295
296  # Retrieve the information from the mmsdrfs file.
297  fsList=$($awk -F: '                                \
298    $'$NODESETID_Field' == "'$clusterName'" &&       \
299    $'$LINE_TYPE_Field' == "'$AUTHORIZED_FS'"    {   \
300      { printf ("%-9s (%s, ",                        \
301                 $'$DEV_NAME_Field',                 \
302                 $'$ACCESS_TYPE_Field') }            \
303      if ( $'$ROOTSQUASH_UID_Field' == "") {         \
304        { printf ("%s)", rootAllowMsg) }             \
305      } else {                                       \
306        { printf ("%s %s:%s)",                       \
307                  rootMapMsg,                        \
308                  $'$ROOTSQUASH_UID_Field',          \
309                  $'$ROOTSQUASH_GID_Field') }        \
310      }                                              \
311      # Indent the information on the next line.     \
312      { printf ("\n%-21s", " ") }                    \
313    }                                                \
314    END { print fsList }                             \
315  ' rootAllowMsg="$rootAllowed" rootMapMsg="$rootMappedTo" $sdrfs)
316  checkForErrors awk $?
317
318  # Remove the last (empty) line from the result.
319  [[ -n $fsList ]] && fsList=${fsList%?                     }
320
321  print -- "$fsList"
322  return $rc
323
324}  #------ end of function getFileSystemList -----------------
325
326
327################################################################
328#
329# Function:  Verify the specified uid:god string.  Valid values
330#            are symbolic names that can be traslated to legitimate
331#            for the system UID and GID, or unsigned integers,
332#            or one of the keywords that turn off root squashing.
333#
334# Input:     $1 - uid:gid | off | no | DEFAULT | DELETE
335#            $2 - sdrfs file to use
336#
337# Output:    uid and gid converted to unsigned integers.
338#
339# Returns:   0 - success
340#            1 - error encountered
341#
342################################################################
343function verifyRootSquashString   # <rsquashString>
344{
345  typeset sourceFile="mmauth.sh"
346  [[ -n $DEBUG || -n $DEBUGverifyRootSquashString ]] && set -x
347  $mmTRACE_ENTER "$*"
348  typeset rsquashString=$1
349
350  typeset rsquashUid rsquashGid uid gid rc
351
352  # See if the string is one of the many keywords
353  # indicating no root squashing.
354  if [[ $rsquashString = off || $rsquashString = DEFAULT ||
355        $rsquashString = no  || $rsquashString = DELETE  ]]
356  then
357    print -- "DEFAULT"
358    return 0
359  fi
360
361  # Parse the input string.
362  IFS=":"
363  set -f ; set -- $rsquashString ; set +f
364  rsquashUid=$1
365  rsquashGid=$2
366  IFS="$IFS_sv"
367
368  if [[ $rsquashUid = +([0-9]) ]]
369  then
370    uid=$rsquashUid
371  elif [[ -n $rsquashUid ]]
372  then
373    uid=$($perl -e '
374      $uid = getpwnam "'$rsquashUid'";
375      if ($uid ne "") { printf "%u", $uid }
376    ')
377  else
378    uid=""
379  fi
380
381  if [[ $rsquashGid = +([0-9]) ]]
382  then
383    gid=$rsquashGid
384  elif [[ -n $rsquashGid ]]
385  then
386    gid=$($perl -e '
387      $gid = getgrnam "'$rsquashGid'";
388      if ($gid ne "") { printf "%u", $gid }
389    ')
390  else
391    gid=""
392  fi
393
394  if [[ -z $uid ]]
395  then
396    # Invalid user name.
397    printErrorMsg 172 $mmcmd $rsquashUid
398    rc=1
399  elif [[ -z $gid  ]]
400  then
401    # Invalid group name.
402    printErrorMsg 173 $mmcmd $rsquashGid
403    rc=1
404  else
405    # Everything is OK.
406    print -- "$uid $gid"
407    rc=0
408  fi
409
410  return $rc
411
412}  #------ end of function verifyRootSquashString -----------------
413
414
415
416#######################
417# Mainline processing
418#######################
419
420
421#######################################
422# Process the command line arguments.
423#######################################
424[[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] &&  \
425  syntaxError "help" $usageMsg
426
427action=$arg1
428[[ -z $action ]] &&  \
429  syntaxError "missingArgs" $usageMsg
430
431remoteClusterName=$arg2
432checkName clusterName 255 "$remoteClusterName"
433[[ $? -ne 0 ]] && cleanupAndExit
434
435# Allow "ls" to be used in place of "show".
436[[ $action = ls ]] && action=show
437
438# Allow "revoke" to be used in place of "deny".
439[[ $action = revoke ]] && action=deny
440
441# arg2 must be specified for all subcommands with the possible
442# exception of the "show" subcommand.  It is either the keyword
443# "new" or "commit" for the "genkey" subcommand, or is the name
444# of the remote cluster for the rest of the subcommands.
445if [[ -z $arg2 ]]
446then
447  if [[ $action = show ]]
448  then
449    remoteClusterName=all
450  elif [[ $action = add || $action = update || $action = delete ||
451          $action = grant || $action = deny || $action = genkey ]]
452  then
453    syntaxError "missingArgs" $usageMsg
454  else
455    syntaxError "keyword" $usageMsg "$action"
456  fi  # end if [[ $action = show ]]
457fi  # end if [[ -z $arg2 ]]
458
459# Continue with the rest of the parameters.
460if [[ $action = genkey ]]
461then
462  # The second argument must be "new" or "commit".
463  genkeyAction=$arg2
464  [[ $genkeyAction != new && $genkeyAction != commit ]] &&  \
465    syntaxError "keyword" $usageMsg "$action"
466
467  # No other arguments are expected.
468  [[ -n $arg3 ]] && syntaxError "extraArg" $usageMsg $arg3
469
470elif [[ $action = delete || $action = show ]]
471then
472  # No other arguments are expected.
473  [[ -n $arg3 ]] && syntaxError "extraArg" $usageMsg $arg3
474
475elif [[ $action = add || $action = update ]]
476then
477  shift 2    # Move past the cluster name in the parameter list.
478
479  # Process the individual arguments and the values associated with them.
480  while getopts :C:k:l: OPT
481  do
482    case $OPT in
483
484      C) [[ -n $Cflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
485         Cflag="-$OPT"; Carg=$OPTARG;
486         newClusterName=$Carg
487         [[ $action != update ]] &&  \
488           syntaxError "invalidOption" $usageMsg "-$OPT"
489         checkName clusterName 255 "$Carg"
490         [[ $? -ne 0 ]] && cleanupAndExit
491         ;;
492
493      k) [[ -n $kflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
494         kflag="-$OPT"; karg=$OPTARG;
495         [[ -z $karg || $karg = DEFAULT ]] && karg=DELETE
496         keyfile=$karg
497         ;;
498
499      l) [[ -n $lflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
500         lflag="-$OPT"; larg=$OPTARG;
501         [[ -z $larg || $larg = DEFAULT ]] && larg=DELETE
502         # Replace any colons in the cipher list string with commas.
503         cipherList=$(print -- "$larg" | $sed 's/:/,/g')
504         ;;
505
506       +[Ckl]) # Invalid option.
507          syntaxError "invalidOption" $usageMsg $OPT
508          ;;
509
510       :) # Missing argument.
511          syntaxError "missingValue" $usageMsg $OPTARG
512          ;;
513
514       *) # Invalid option.
515          syntaxError "invalidOption" $usageMsg $OPTARG
516          ;;
517     esac
518  done
519
520  shift OPTIND-1
521  [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1
522
523  # Ensure required parameters are specified.
524  if [[ $action = add ]]
525  then
526    [[ -z $karg ]] &&  \
527      syntaxError "missingArgs" $usageMsg
528  else  # $action = update
529    [[ -z $Carg && -z $karg && -z $larg ]] &&  \
530      syntaxError "missingArgs" $usageMsg
531  fi
532
533elif [[ $action = grant || $action = deny ]]
534then
535  shift 2    # Move past the cluster name in the parameter list.
536
537  # Process the individual arguments and the values associated with them.
538  while getopts :a:f:r: OPT
539  do
540    case $OPT in
541
542      a) [[ -n $aflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
543         aflag="-$OPT"; aarg=$OPTARG;
544         [[ $action = deny ]] &&  \
545           syntaxError "invalidOption" $usageMsg $OPT
546         [[ $aarg = none ]] && aarg=deny
547         [[ $aarg != rw && $aarg != ro && $aarg != deny ]] &&  \
548           syntaxError "invalidOption" $usageMsg "-$OPT $OPTARG"
549         accessType=$aarg
550         ;;
551
552      f) [[ -n $fflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
553         fflag="-$OPT"; farg=$OPTARG;
554         device=$farg
555         ;;
556
557      r) [[ -n $rflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
558         rflag="-$OPT"; rarg=$OPTARG;
559         ;;
560
561       +[afr]) # Invalid option.
562          syntaxError "invalidOption" $usageMsg $OPT
563          ;;
564
565       :) # Missing argument.
566          syntaxError "missingValue" $usageMsg $OPTARG
567          ;;
568
569       *) # Invalid option.
570          syntaxError "invalidOption" $usageMsg $OPTARG
571          ;;
572     esac
573  done
574
575  shift OPTIND-1
576  [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1
577
578  # Ensure required parameters are specified.
579  [[ -z $device ]] && \
580    syntaxError "missingArgs" $usageMsg
581
582  [[ -z $accessType ]] && accessType=rw
583
584  # Verify the device name.
585  deviceName=${device##+(/)dev+(/)}  # name stripped of /dev/ prefix
586  fqDeviceName="/dev/$deviceName"    # fully-qualified name (with /dev/ prefix)
587  if [[ $deviceName = /* ]]
588  then
589    printErrorMsg 169 $mmcmd $device
590    cleanupAndExit
591  elif [[ $deviceName = */* ]]
592  then
593    printErrorMsg 170 $mmcmd $device
594    cleanupAndExit
595  fi
596
597  # Verify the root squash string.
598  if [[ -z $rarg ]]
599  then
600    rsquashUid=""
601    rsquashGid=""
602  else
603    rsquashString=$(verifyRootSquashString $rarg)
604    [[ $? -ne 0 ]] &&  \
605      syntaxError "invalidOption" $noUsageMsg "-r $rarg"
606
607    if [[ $rsquashString = DEFAULT ]]
608    then
609      rsquashUid=""
610      rsquashGid=""
611    else
612      # Parse the result from verifyRootSquashString.
613      set -f ; set -- $rsquashString ; set +f
614      rsquashUid=$1
615      rsquashGid=$2
616    fi  # end of if [[ $rsquashString = DEFAULT ]]
617  fi  # end of if [[ -z $rsquashString ]]
618
619  # If the specified access type is "deny" (or "none"),
620  # convert the action to "deny".
621  [[ $accessType = deny ]] && action=deny
622
623else
624  # Invalid action requested.
625  syntaxError "keyword" $usageMsg "$action"
626fi  # end if [[ $action = genkey ]]
627
628# Determine the lookup order for resolving host names.
629[[ $osName != AIX ]] && resolveOrder=$(setHostResolveOrder)
630
631
632#######################################################################
633# Set up trap exception handling and call the gpfsInit function.
634# It will ensure that the local copy of the mmsdrfs and the rest of
635# the GPFS system files are up-to-date and will obtain the sdr lock.
636#######################################################################
637if [[ $action = show ]]
638then
639  trap pretrap2 HUP INT QUIT KILL
640  gpfsInitOutput=$(gpfsInit nolock)
641  rc=$?
642else
643  trap pretrap HUP INT QUIT KILL
644  # If action is genkey, tell gpfsInit (and related functions)
645  # to bypass the checking and rebuilding of the security files.
646  [[ $action = genkey ]] && export MMAUTH_GENKEY_RUNNING=yes
647  gpfsInitOutput=$(gpfsInit $lockId)
648  rc=$?
649  unset MMAUTH_GENKEY_RUNNING
650fi
651setGlobalVar $rc $gpfsInitOutput
652
653# Find out the default cipher list value to be used.
654if [[ $action = show ]]
655then
656  defaultCipherList=$(showCfgValue cipherList)
657fi
658
659
660#######################################################################
661# Perform any remaining parameter checking that requires knowledge of
662# the sdrfsFormatLevel level (set by gpfsInit above). Ensure the user
663# is not trying to utilize function that has not been enabled yet.
664#######################################################################
665# Ensure the key file exists and has the correct format.
666if [[ -n $keyfile && $keyfile != DELETE ]]
667then
668  verifyPublicKeyFile $keyfile $sdrfsFormatLevel $verifiedKey  \
669                      $newClusterName $remoteClusterName
670  [[ $? -ne 0 ]] && cleanupAndExit
671
672  if [[ $sdrfsFormatLevel -eq 0 ]]
673  then
674    # Ensure that the provided key file was generated by a 2.3 version of mmauth.
675    $grep -q -e "^clusterName=" $verifiedKey >/dev/null 2>&1
676    rc=$?
677    if [[ $rc -eq 0 ]]
678    then
679      print -u2 "$mmcmd:  The specified public key file cannot be handled until you"
680      print -u2 "    run \"mmchconfig release=LATEST\" to activate the new function."
681      cleanupAndExit
682    fi
683  fi  # end of if [[ $sdrfsFormatLevel -eq 0 ]]
684fi  # end of if [[ -n $keyfile && $keyfile != DELETE ]]
685
686# Ensure the version of openssl installed on this node
687# understands the specified cipher list.
688if [[ -n $cipherList && $cipherList != DELETE ]]
689then
690  if [[ $cipherList = "AUTHONLY" ]]
691  then
692    ciphers=$($openssl ciphers "NULL-SHA")
693  elif [[ $cipherList = *"AUTHONLY"* ]]
694  then
695    print -u2 "$mmcmd:  AUTHONLY cannot be specified in conjunction with other ciphers."
696  else
697    ciphers=$($openssl ciphers rsa "$cipherList")
698  fi
699
700  if [[ $cipherList != "AUTHONLY" && $sdrfsFormatLevel -eq 0 ]]
701  then
702    print -u2 "$mmcmd:  Support for cipher lists other than AUTHONLY has not been enabled yet."
703    print -u2 "    Run \"mmchconfig release=LATEST\" to activate the new function."
704    cleanupAndExit
705  fi
706
707  if [[ -z "$ciphers" ]]
708  then
709    # The specified cipher list is not supported.
710    printErrorMsg 483 $mmcmd "$value"
711    cleanupAndExit
712  else
713    :  # The new cipher list is acceptable.
714  fi  # end of if [[ -z "$ciphers" ]]
715fi  # end of if [[ -n $cipherList && $cipherList != DELETE ]]
716
717
718#######################################################################
719#
720# Go through the mmsdrfs file and make the necessary changes.
721#
722#######################################################################
723$rm -f $newsdrfs $nodefile $allClusterNodes
724IFS=":"
725exec 3<&-
726exec 3< $mmsdrfsFile
727while read -u3 sdrfsLine
728do
729  # Parse the line.
730  set -f ; set -A v -- - $sdrfsLine ; set +f
731
732  IFS="$IFS_sv"   # Restore the default IFS settings.
733  printLine=true  # Assume the line will be printed.
734
735  # Change some of the fields depending on the type of line.
736  case ${v[$LINE_TYPE_Field]} in
737
738    $VERSION_LINE )
739       # Increment the generation number.
740       newGenNumber=${v[$SDRFS_GENNUM_Field]}+1
741       v[$SDRFS_GENNUM_Field]=$newGenNumber
742
743       # Retrieve the current key generation numbers and other information.
744       newKeyGenNumber=${v[$NEW_KEY_Field]}
745       [[ -z $newKeyGenNumber ]] && newKeyGenNumber=0
746       committedKeyGenNumber=${v[$COMMITTED_KEY_Field]}
747       [[ -z $committedKeyGenNumber ]] && committedKeyGenNumber=0
748       secLevel=${v[$SECLEVEL_Field]}
749       [[ -z $secLevel ]] && secLevel=0
750       ourClusterName=${v[$CLUSTER_NAME_Field]}
751       ourClusterId=${v[$CLUSTERID_Field]#gpfs}
752
753       if [[ $action = genkey ]]
754       then
755         # Automatically "commit" old clusters that already have
756         # established private keys (with cs3b level of mmauth).
757         [[ $committedKeyGenNumber -eq 0 ]] &&  \
758           committedKeyGenNumber=$newKeyGenNumber
759
760         if [[ $genkeyAction = new ]]
761         then
762           # Do not allow a new key to be generated if a previously
763           # generated key has not been committed yet.
764           if [[ $committedKeyGenNumber -lt $newKeyGenNumber ]]
765           then
766             # Run: mmauth genkey commit.
767             printErrorMsg 157 $mmcmd "mmauth genkey commit"
768             cleanupAndExit
769           fi
770
771           # Increment the generation number for the new key
772           # that we are about to create.
773           (( newKeyGenNumber += 1 ))
774
775           # If this is the very first genkey request,
776           # or if the new code has not been activated yet,
777           # or if this the first genkey request after
778           # activating the new genkey file format,
779           # automatically commit the key.
780           [[ $newKeyGenNumber  -eq 1           ||
781              $sdrfsFormatLevel -eq 0           ||
782              -z ${v[$KEYFILE_FORMAT_Field]}    ||
783              ${v[$KEYFILE_FORMAT_Field]} -eq 0 ]] &&  \
784             committedKeyGenNumber=$newKeyGenNumber
785
786           # Put the key numbers in the mmsdrfs file.
787           v[$NEW_KEY_Field]=$newKeyGenNumber
788           v[$COMMITTED_KEY_Field]=$committedKeyGenNumber
789           [[ $sdrfsFormatLevel -ge 1 ]] &&  \
790             v[$KEYFILE_FORMAT_Field]=$CURRENT_KEYFILE_FORMAT
791
792         else  # genkeyAction = commit
793           # See if there is anything to commit.
794           if [[ $committedKeyGenNumber -eq $newKeyGenNumber ]]
795           then
796             if [[ $newKeyGenNumber -eq 0 ]]
797             then
798               # There is nothing to commit.
799               # Tell the user to run mmauth genkey new.
800               printErrorMsg 155 $mmcmd "mmauth genkey new"
801             else
802               # The current authentication files are already committed.
803               printErrorMsg 156 $mmcmd
804             fi
805             cleanupAndExit
806           fi
807
808           # Ensure a cipher list has been established.
809           if [[ $secLevel -eq 0 ]]
810           then
811             # You must establish a cipher list first.  Tell the user to run
812             #    mmauth update $ourClusterName -l <cipherList>
813             printErrorMsg 158 $mmcmd "mmauth update $ourClusterName -l <cipherList>"
814             cleanupAndExit
815           fi
816
817           # Things seem to be OK.  Commit the key.
818           committedKeyGenNumber=$newKeyGenNumber
819           v[$COMMITTED_KEY_Field]=$committedKeyGenNumber
820
821         fi  # end of if [[ $genkeyAction = new ]]
822       fi  # end of if [[ $action = genkey ]]
823
824       # See whether the target of the operation is the local cluster.
825       [[ $remoteClusterName = "." ]] &&  \
826         remoteClusterName=$ourClusterName
827
828       if [[ $remoteClusterName = $ourClusterName ]]
829       then
830         remoteClusterName=$HOME_CLUSTER
831         clusterFound=yes
832
833         if [[ $action = add || $action = delete ||
834               $action = grant || $action = deny ]]
835         then
836           # Operation not allowed for the local cluster.
837           printErrorMsg 294 $mmcmd
838           cleanupAndExit
839         fi
840
841         if [[ $action = update ]]
842         then
843           if [[ -n $newClusterName ]]
844           then
845             # Operation not allowed for the local cluster.
846             printErrorMsg 294 $mmcmd
847             cleanupAndExit
848           fi
849
850           if [[ -n $keyfile ]]
851           then
852             # Run "mmauth genkey" to establish a new key.
853             printErrorMsg 314 $mmcmd
854             cleanupAndExit
855           fi
856
857           if [[ -n $cipherList ]]
858           then
859             # Ensure the security level field is set correctly.
860             if [[ $cipherList = DELETE ]]
861             then
862               secLevel=0
863             else
864               if [[ $newKeyGenNumber -eq 0 ]]
865               then
866                 # Run "mmauth genkey" first.
867                 printErrorMsg 307 $mmcmd
868                 cleanupAndExit
869               fi
870               secLevel=1
871             fi  # end of if [[ $cipherList = DELETE ]]
872             v[$SECLEVEL_Field]=$secLevel
873           fi  # end of if [[ -n $cipherList ]]
874         fi  # end of if [[ $action = update ]]
875       fi  # end of if [[ $remoteClusterName = $ourClusterName ]]
876       ;;
877
878
879    $NODESET_HDR )
880       if [[ $action = update && -n $cipherList &&
881             $remoteClusterName = $HOME_CLUSTER ]]
882       then
883         # Update the cipher list for the local cluster.
884         currentCipherList=${v[$CIPHER_LIST_Field]}
885         [[ -z $currentCipherList ]] && currentCipherList=DELETE
886         if [[ $cipherList != DELETE ]]
887         then
888           v[$CIPHER_LIST_Field]=$cipherList
889         else
890           v[$CIPHER_LIST_Field]=""
891         fi
892       fi  # end of if [[ $action = update && -n $cipherList && ...
893       ;;
894
895
896    $MEMBER_NODE )
897       # Add the reliable node name to the appropriate files.
898
899       # allClusterNodes contains the names of all nodes in the cluster.
900       print -- "${v[$REL_HOSTNAME_Field]}" >> $allClusterNodes
901       checkForErrors "writing to file $allClusterNodes" $?
902
903       # nodefile contains the names of all nodes except the
904       # primary and backup servers and the node on which the
905       # command is executed (this node).
906       if [[ ${v[$REL_HOSTNAME_Field]} != $primaryServer &&
907             ${v[$REL_HOSTNAME_Field]} != $backupServer  &&
908             ${v[$REL_HOSTNAME_Field]} != $ourNodeName   ]]
909       then
910         print -- "${v[$REL_HOSTNAME_Field]}" >> $nodefile
911         checkForErrors "writing to file $nodefile" $?
912       fi
913
914       # If this is the line for the node that is executing
915       # this command, set the preferredNode variable.
916       [[ ${v[$NODE_NUMBER_Field]} = $ourNodeNumber ]] &&  \
917         preferredNode=${v[$REL_HOSTNAME_Field]}
918       ;;
919
920
921    $MMFSCFG )
922       if [[ $action = update && -n $cipherList &&
923             $remoteClusterName = $HOME_CLUSTER ]]
924       then
925         # If changing the cipher list for the local cluster, remove
926         # the line from the mmsdrfs file.  The mmfs.cfg information
927         # will be added back before committing the changes.
928         printLine=false
929
930         # Extract the mmfs.cfg information.
931         # It is everything past the first 4 fields.
932         cfgLine="${v[5]}:${v[6]}:${v[7]}:${v[8]}:${v[9]}:${v[10]}:${v[11]}"
933         cfgLine="$cfgLine:${v[12]}:${v[13]}:${v[14]}:${v[15]}:${v[16]}:${v[17]}"
934         cfgLine="$cfgLine:${v[18]}:${v[19]}:${v[20]}:${v[21]}:${v[22]}"
935
936         # To preserve tabs, temporarily set IFS to new line only.
937         IFS="
938"
939         # Strip trailing colons and write the line to the file.
940         print -- "${cfgLine%%+(:)}" >> $tmpCfg
941         checkForErrors "writing to file $tmpCfg" $?
942         IFS="$IFS_sv"  # Restore the default IFS settings.
943       fi  # end of if [[ $action = update && -n $cipherList && ...
944       ;;
945
946
947    $AUTHORIZED_CLUSTER )
948       if [[ ${v[$NODESETID_Field]} = $remoteClusterName ||
949             $remoteClusterName = all && ($action = show ||
950             $action = delete || $action = grant || $action = deny) ]]
951       then
952         clusterFound=yes
953         clusterNameList="$clusterNameList ${v[$NODESETID_Field]} "
954
955         # Processing depends on the specified action:
956         case $action in
957           add )
958              # The remote cluster is already defined.
959              printErrorMsg 316 $mmcmd $remoteClusterName
960              cleanupAndExit
961              ;;
962
963           update )
964              if [[ -n $cipherList ]]
965              then
966                if [[ $cipherList != DELETE ]]
967                then
968                  v[$CIPHER_LIST_Field]=$cipherList
969                else
970                  v[$CIPHER_LIST_Field]=""
971                fi
972              fi
973
974              [[ -n $newClusterName ]] &&  \
975                v[$NODESETID_Field]=$newClusterName
976              ;;
977
978           delete )
979              printLine=false
980              ;;
981
982           show )
983              # Display the cluster name.
984              header=$(printInfoMsg 442)
985              printf "%-20s %s\n" "$header" "${v[$NODESETID_Field]}"
986
987              # Display the cipher list.
988              header=$(printInfoMsg 443)
989              cipherList="${v[$CIPHER_LIST_Field]}"
990              if  [[ -z $cipherList ]]
991              then
992                # If there is no explicit cipher list for this cluster,
993                # we use the cipher list for the local cluster.
994                cipherList=$defaultCipherList
995                [[ -z $cipherList ]] && cipherList="(none specified)"
996              fi  # end of if  [[ -z $cipherList ]]
997              printf "%-20s %s\n" "$header" "$cipherList"
998
999              $rm -f $tmpPublicKey $fsFile
1000
1001              # Display the SHA digest (public key fingerprint).
1002              header=$(printInfoMsg 444)
1003              keyFingerprint=$(getFingerprint ${v[$NODESETID_Field]} $mmsdrfsFile)
1004              printf "%-20s %s\n" "$header" "$keyFingerprint"
1005
1006              # Display the file systems that can be accessed by the cluster.
1007              header=$(printInfoMsg 445)
1008              fsAuthList=$(getFileSystemList ${v[$NODESETID_Field]} $mmsdrfsFile)
1009              checkForErrors getFileSystemList $?
1010              [[ -z $fsAuthList ]] && fsAuthList="(none authorized)"
1011              printf "%-20s %s\n\n" "$header" "$fsAuthList"
1012              ;;
1013
1014           grant )
1015              : # noop
1016              ;;
1017
1018           deny )
1019              : # noop
1020              ;;
1021
1022           *) checkForErrors "unexpected action $action" 1
1023              ;;
1024         esac  # end case $action in
1025       fi  # end if [[ ${v[$NODESETID_Field]} = $remoteClusterName || ...
1026       ;;
1027
1028
1029    $AUTHORIZED_KEY )
1030       if [[ ${v[$NODESETID_Field]} = $remoteClusterName ||
1031             $remoteClusterName = all && ($action = show || $action = delete) ]]
1032       then
1033         # Processing depends on the specified action:
1034         case $action in
1035           add )
1036              # The remote cluster is already defined.
1037              printErrorMsg 316 $mmcmd $remoteClusterName
1038              cleanupAndExit
1039              ;;
1040
1041           update )
1042              [[ -n $keyfile ]] && printLine=false
1043
1044              if [[ -n $newClusterName ]]
1045              then
1046                v[$NODESETID_Field]=$newClusterName
1047                [[ ${v[$LINE_NUMBER_Field]} = 1 ]] &&  \
1048                  v[$KEY_Field]="clusterName=$newClusterName"
1049              fi
1050              ;;
1051
1052           delete )
1053              printLine=false
1054              ;;
1055
1056           show )
1057              : # noop
1058              ;;
1059
1060           grant )
1061              : # noop
1062              ;;
1063
1064           deny )
1065              : # noop
1066              ;;
1067
1068           *) checkForErrors "unexpected action $action" 1
1069              ;;
1070         esac  # end case $action in
1071       fi  # end if [[ ${v[$NODESETID_Field]} = $remoteClusterName || ...
1072       ;;
1073
1074
1075    $SG_HEADR )
1076       if [[ ${v[$DEV_NAME_Field]} = $deviceName || $device = all ]]
1077       then
1078         if [[ ${v[$NODESETID_Field]} = $HOME_CLUSTER ]]
1079         then
1080           # We are making changes to this file system.
1081           fsFound=yes
1082           fsList="$fsList ${v[$DEV_NAME_Field]} "
1083         elif [[ $device != all ]]
1084         then
1085           # Command is not allowed for remote file systems.
1086           printErrorMsg 106 $mmcmd $device ${v[$NODESETID_Field]}
1087           cleanupAndExit
1088         fi
1089       fi  # end if [[ ${v[$DEV_NAME_Field]} = $deviceName || $device = all ]]
1090       ;;
1091
1092
1093    $AUTHORIZED_FS )
1094       if [[ (${v[$NODESETID_Field]} = $remoteClusterName || $remoteClusterName = all)  &&
1095             (${v[$DEV_NAME_Field]} = $deviceName || $device = all || $action = delete) ]]
1096       then
1097         if [[ $action = delete || $action = deny ]]
1098         then
1099           # Remove from the file the affected AUTHORIZED_FS lines.
1100           printLine=false
1101         elif [[ $action = grant ]]
1102         then
1103           # If changing an existing authorization, update the affected fields.
1104           if [[ -n $aarg ]]
1105           then
1106             v[$ACCESS_TYPE_Field]=$accessType
1107           fi
1108           if [[ -n $rarg ]]
1109           then
1110             v[$ROOTSQUASH_UID_Field]=$rsquashUid
1111             v[$ROOTSQUASH_GID_Field]=$rsquashGid
1112           fi
1113
1114           # Tell the guy what exactly he is doing.
1115           if [[ -z ${v[$ROOTSQUASH_UID_Field]} ]]
1116           then
1117             printInfoMsg 182 $mmcmd ${v[$NODESETID_Field]}  \
1118                 ${v[$DEV_NAME_Field]} ${v[$ACCESS_TYPE_Field]}
1119           else
1120             printInfoMsg 183 $mmcmd ${v[$NODESETID_Field]}  \
1121                 ${v[$DEV_NAME_Field]} ${v[$ACCESS_TYPE_Field]}  \
1122                 ${v[$ROOTSQUASH_UID_Field]} ${v[$ROOTSQUASH_GID_Field]}
1123           fi
1124
1125           # Add the name of the fs to the list of processed file systems.
1126           # Note:  The trailing blank is important.
1127           processedFileSystems="$processedFileSystems ${v[$NODESETID_Field]}:${v[$DEV_NAME_Field]} "
1128         else
1129           :  # should not get here.
1130         fi  # end of if [[ $action = delete || $action = deny ]]
1131       fi  # end of if [[ (${v[$NODESETID_Field]} = $remoteClusterName ...
1132
1133       if [[ ${v[$NODESETID_Field]} = $remoteClusterName ]]
1134       then
1135          [[ $action = update && -n $newClusterName ]] &&  \
1136            v[$NODESETID_Field]=$newClusterName
1137       fi
1138       ;;
1139
1140
1141    * )  # Pass all other lines without a change.
1142       ;;
1143
1144  esac  # end of Change some of the fields
1145
1146  # Build and write the line to the new mmsdrfs file.
1147  if [[ $printLine = true ]]
1148  then
1149    print_newLine >> $newsdrfs
1150    checkForErrors "writing to file $newsdrfs" $?
1151  fi
1152
1153  IFS=":"  # Change the separator back to ":" for the next iteration.
1154
1155done  # end while read -u3 mmsdrfsFile
1156
1157IFS="$IFS_sv"  # Restore the default IFS settings.
1158
1159
1160#########################################
1161# Additional action-specific processing.
1162#########################################
1163if [[ $action = genkey ]]
1164then
1165  if [[ $genkeyAction = new ]]
1166  then
1167    # Ensure the OpenSSL code is installed.
1168    if [[ ! -x $openssl ]]
1169    then
1170      # openssl command not found.
1171      printErrorMsg 159 $mmcmd $openssl
1172      cleanupAndExit
1173    fi
1174
1175    # If the sslrandfile user exit is installed, use it to determine
1176    # the value for the -rand paramter for the openssl calls.
1177    if [[ -x $sslrandfile ]]
1178    then
1179      randFile=$($sslrandfile 2>/dev/null)
1180      [[ -n $randFile ]] &&  \
1181        randOpt="-rand $randFile"
1182    fi
1183
1184    # If the multiple keys support has not been activated yet,
1185    # ensure the daemon is not running anywhere.
1186    if [[ $sdrfsFormatLevel -eq 0 ]]
1187    then
1188      printInfoMsg 339
1189      verifyDaemonInactive $allClusterNodes $mmcmd
1190      [[ $? -ne 0 ]] && cleanupAndExit
1191      daemonInactive=yes
1192    fi
1193
1194    # Regenerate the openssl.conf file.
1195    $sed 's/= gpfsCluster/= '$ourClusterName'/' $opensslConfFile > $certConfigFile
1196    checkForErrors "creating $certConfigFile" $?
1197
1198    # Generate the new local private key.
1199    umask 077
1200    $openssl genrsa $randOpt -out $tmpPrivateKey 512
1201    checkForErrors "openssl genrsa $randOpt -out $tmpPrivateKey 512" $?
1202
1203    # If the multiple keys functionality is enabled, generate
1204    # the corresponding private key and certificate files.
1205    # Otherwise, stage the private key file as is.
1206    if [[ $sdrfsFormatLevel -eq 0 ]]
1207    then
1208      $cp $tmpPrivateKey ${privateKey}$newKeyGenNumber
1209      checkForErrors "cp $tmpPrivateKey ${privateKey}$newKeyGenNumber" $?
1210      $mv $tmpPrivateKey $tmpkey
1211      checkForErrors "mv $tmpPrivateKey $tmpkey" $?
1212      fileToStage="${privateKey}$newKeyGenNumber"
1213    else
1214      # Generate the public key file and find its SHA digest.
1215      $openssl rsa -in $tmpPrivateKey -pubout -out $tmpPublicKey
1216      checkForErrors "openssl rsa -in $tmpPrivateKey -pubout -out $tmpPublicKey" $?
1217      keyFingerprint=$($openssl dgst -sha -hex < $tmpPublicKey 2>/dev/null)
1218
1219      # Generate the certificate file.
1220      $openssl req $randOpt -new -x509 -days 16427 -key $tmpPrivateKey  \
1221               -out $tmpCertificate -config $certConfigFile
1222      checkForErrors  \
1223        "openssl req $randOpt -new -x509 -days 16427 -key $tmpPrivateKey -out $tmpCertificate -config $certConfigFile" $?
1224
1225      # Create the combined file with all relevant key information.
1226      #
1227      # The combined file consists of several (currently 6) simple stanza
1228      # lines followed by several (currently 3) variable length sections.
1229      # The order must be preserved.  If it becomes necessary in the future
1230      # to add additional information, the following rules should be obeyed:
1231      # - Any new simple stanza lines should follow the initial 6 lines
1232      #   but should come before any variable length sections.
1233      # - Any new variable length sections should come before the current
1234      #   three sections: privateKey, publicKey and certificate.
1235      #
1236      print -- "clusterName=$ourClusterName" > $tmpkey
1237      checkForErrors "writing to $tmpkey" $?
1238      print -- "clusterID=$ourClusterId" >> $tmpkey
1239      checkForErrors "writing to $tmpkey" $?
1240      print -- "genkeyFormat=$CURRENT_KEYFILE_FORMAT" >> $tmpkey
1241      checkForErrors "writing to $tmpkey" $?
1242      print -- "genkeyCompatibleFormat=$COMPATIBLE_KEYFILE_FORMAT" >> $tmpkey
1243      checkForErrors "writing to $tmpkey" $?
1244      print -- "keyGenNumber=$newKeyGenNumber" >> $tmpkey
1245      checkForErrors "writing to $tmpkey" $?
1246      print -- "keyDigest=$keyFingerprint" >> $tmpkey
1247      checkForErrors "writing to $tmpkey" $?
1248      print -- "privateKey=" >> $tmpkey
1249      checkForErrors "writing to $tmpkey" $?
1250      $cat $tmpPrivateKey >> $tmpkey
1251      checkForErrors "cat $tmpPrivateKey >> $tmpkey" $?
1252      print -- "publicKey=" >> $tmpkey
1253      checkForErrors "writing to $tmpkey" $?
1254      $cat $tmpPublicKey >> $tmpkey
1255      checkForErrors "cat $tmpPublicKey >> $tmpkey" $?
1256      print -- "certificate=" >> $tmpkey
1257      checkForErrors "writing to $tmpkey" $?
1258      $cat $tmpCertificate >> $tmpkey
1259      checkForErrors "cat $tmpCertificate >> $tmpkey" $?
1260
1261      # If everyting worked out OK so far, copy the new file in the ssl/stage directory.
1262      fileToStage="${genkeyData}$newKeyGenNumber"
1263      $cp $tmpkey $fileToStage
1264      checkForErrors "cp $tmpkey $fileToStage" $?
1265
1266    fi  # end of if [[ $sdrfsFormatLevel -eq 0 ]]
1267    umask $UMASK_sv
1268
1269    # Stage the newly-generated key file on the server nodes.
1270    # The files will be activated after the new key generation number
1271    # is committed as a result of the regular commit protocol.
1272    if [[ $primaryServer != $ourNodeName ]]
1273    then
1274      $rcp -p $fileToStage ${primaryServer}:$fileToStage
1275      checkForErrors "$rcp ${primaryServer}:$fileToStage" $?
1276    fi
1277
1278    if [[ -n $backupServer && $backupServer != $ourNodeName ]]
1279    then
1280      $rcp -p $fileToStage ${backupServer}:$fileToStage
1281      checkForErrors "$rcp ${backupServer}:$fileToStage" $?
1282    fi
1283
1284  else
1285    :  # There is nothing to do for genkeyAction commit at this point.
1286  fi  # end of if [[ $genkeyAction = new ]]
1287fi  # end of if [[ $action = genkey ]]
1288
1289
1290if [[ $action = add ]]
1291then
1292  # Generate the needed information for the mmsdrfs file.
1293  newLine="$remoteClusterName:$AUTHORIZED_CLUSTER:::$accessGranted::$cipherList:"
1294  print -- "$newLine" >> $newsdrfs
1295  checkForErrors "writing to file $newsdrfs" $?
1296
1297  # Process the -k keyfile option.
1298  if [[ -n $keyfile ]]
1299  then
1300    appendFile $remoteClusterName $verifiedKey $AUTHORIZED_KEY $newsdrfs
1301    checkForErrors  \
1302        "appendFile $remoteClusterName $verifiedKey $AUTHORIZED_KEY $newsdrfs" $?
1303  fi
1304fi  # end of if [[ $action = add ]]
1305
1306
1307if [[ $action = update ]]
1308then
1309  if [[ -z $clusterFound ]]
1310  then
1311    # The remote cluster is not authorized to access this cluster.
1312    printErrorMsg 259 $mmcmd $remoteClusterName
1313    cleanupAndExit
1314  fi
1315
1316  # Process the -k keyfile option.
1317  if [[ -n $keyfile && $keyfile != DELETE ]]
1318  then
1319    if [[ -n $newClusterName ]]
1320    then
1321      appendFile $newClusterName $verifiedKey $AUTHORIZED_KEY $newsdrfs
1322      checkForErrors  \
1323        "appendFile $newClusterName $verifiedKey $AUTHORIZED_KEY $newsdrfs" $?
1324    else
1325      appendFile $remoteClusterName $verifiedKey $AUTHORIZED_KEY $newsdrfs
1326      checkForErrors  \
1327        "appendFile $remoteClusterName $verifiedKey $AUTHORIZED_KEY $newsdrfs" $?
1328    fi
1329  fi  # end of if [[ -n $keyfile && $keyfile != DELETE ]]
1330
1331  # Process the -l cipherList option for the local cluster.
1332  if [[ -n $cipherList && $remoteClusterName = $HOME_CLUSTER ]]
1333  then
1334    # If changing the cipher list for the local cluster,
1335    # make changes to the mmfs.cfg file.
1336    $mmfixcfg "cipherList" "$cipherList" < $tmpCfg > $newcfg 2>/dev/null
1337    checkForErrors "mmfixcfg cipherList" $?
1338
1339    # Put the updated mmfs.cfg information back into the mmsdrfs file.
1340    appendCfgFile $HOME_CLUSTER $newcfg $newsdrfs
1341    checkForErrors "appendCfgFile" $?
1342
1343    # The daemon must be down on all nodes if we are about to switch
1344    # from a non-secure to a secure environment or vice-versa.
1345    if [[ $currentCipherList != $cipherList &&
1346          ( $currentCipherList = DELETE || $cipherList = DELETE ) ]]
1347    then
1348      printInfoMsg 339
1349      verifyDaemonInactive $allClusterNodes $mmcmd
1350      [[ $? -ne 0 ]] && cleanupAndExit
1351      daemonInactiveVerified=yes
1352    fi
1353  fi  # end of if [[ -n $cipherList && $remoteClusterName = $HOME_CLUSTER ]]
1354fi  # end of if [[ $action = update ]]
1355
1356
1357if [[ $action = delete ]]
1358then
1359  if [[ -z $clusterFound ]]
1360  then
1361    if [[ $remoteClusterName = all ]]
1362    then
1363      # There are no remote cluster authorizations.
1364      printErrorMsg 258 $mmcmd
1365    else
1366      # The remote cluster is not authorized to access this cluster.
1367      printErrorMsg 259 $mmcmd $remoteClusterName
1368    fi
1369    cleanupAndExit
1370  fi  # end of if [[ -z $clusterFound ]]
1371fi  # end of if [[ $action = delete ]]
1372
1373
1374if [[ $action = show ]]
1375then
1376  # Add the information for the local cluster at the end of the output.
1377  if [[ $remoteClusterName = all || $remoteClusterName = $HOME_CLUSTER ]]
1378  then
1379    clusterFound=yes
1380
1381    # Display the cluster name.
1382    header=$(printInfoMsg 442)
1383    printf "%-20s %s\n" "$header" "$ourClusterName (this cluster)"
1384
1385    # Display the cipher list.
1386    header=$(printInfoMsg 443)
1387    cipherList=$defaultCipherList
1388    [[ -z $cipherList ]] && cipherList="(none specified)"
1389    printf "%-20s %s\n" "$header" "$cipherList"
1390
1391
1392    # Display the SHA digest for the committed public key.
1393    header=$(printInfoMsg 444)
1394    keyFingerprint=$(getLocalFingerprint $committedPublicKey)
1395    printf "%-20s %s\n" "$header" "$keyFingerprint"
1396
1397    # Display the SHA digest for the uncommitted public key.
1398    if [[ -s $newPublicKey ]]
1399    then
1400      header=$(printInfoMsg 427)
1401      keyFingerprint=$(getLocalFingerprint $newPublicKey)
1402      printf "%-20s %s\n" "$header" "$keyFingerprint"
1403    fi
1404
1405    # Display the file systems that can be accessed by the cluster.
1406    header=$(printInfoMsg 445)
1407    fsAuthList="(all rw)"
1408    printf "%-20s %s\n\n" "$header" "$fsAuthList"
1409  fi  # end if [[ $remoteClusterName = all || $remoteClusterName = $HOME_CLUSTER ]]
1410
1411  if [[ -z $clusterFound ]]
1412  then
1413    # The remote cluster is not authorized to access this cluster.
1414    printErrorMsg 259 $mmcmd $remoteClusterName
1415    cleanupAndExit
1416  fi  # end of if [[ -z $clusterFound ]]
1417
1418  # Nothing more to do.
1419  cleanupAndExit 0
1420fi  # end of if [[ $action = show ]]
1421
1422
1423if [[ $action = grant ]]
1424then
1425  if [[ -z $clusterFound ]]
1426  then
1427    if [[ $remoteClusterName = all ]]
1428    then
1429      # There are no remote cluster definitions.
1430      printErrorMsg 262 $mmcmd
1431    else
1432      # The remote cluster is not defined.
1433      printErrorMsg 259 $mmcmd $remoteClusterName
1434    fi
1435    cleanupAndExit
1436  fi  # end of if [[ -z $clusterFound ]]
1437
1438  if [[ -z $fsFound ]]
1439  then
1440    if [[ $device = all ]]
1441    then
1442      # No file systems were found.
1443      printErrorMsg 200 $mmcmd
1444    else
1445      # The requested file system was not found.
1446      printErrorMsg 288 $mmcmd $device
1447    fi
1448    cleanupAndExit
1449  fi  # end of if [[ -z $fsFound ]]
1450
1451  # Generate the appropriate AUTHORIZED_FS lines.
1452  print -- ""  # put a blank separator line
1453  for fsName in $fsList
1454  do
1455    for remCluster in $clusterNameList
1456    do
1457      [[ $processedFileSystems = *" $remCluster:$fsName "* ]] && continue
1458
1459      newLine=$remCluster:$AUTHORIZED_FS:$fsName::$accessType:$rsquashUid:$rsquashGid:
1460      print -- "$newLine" >> $newsdrfs
1461      checkForErrors "writing to file $newsdrfs" $?
1462      if [[ -z $rsquashUid ]]
1463      then
1464        printInfoMsg 182 $mmcmd $remCluster $fsName $accessType
1465      else
1466        printInfoMsg 183 $mmcmd $remCluster $fsName $accessType $rsquashUid $rsquashGid
1467      fi
1468      print -- ""  # put a blank separator line
1469    done  # end of for remCluster in $clusterNameList
1470  done  # end of for fsName in $fsList
1471fi  # end of if [[ $action = grant ]]
1472
1473
1474if [[ $action = deny ]]
1475then
1476  if [[ -z $clusterFound ]]
1477  then
1478    if [[ $remoteClusterName = all ]]
1479    then
1480      # There are no remote cluster definitions.
1481      printErrorMsg 262 $mmcmd
1482    else
1483      # The remote cluster is not defined.
1484      printErrorMsg 259 $mmcmd $remoteClusterName
1485    fi
1486    cleanupAndExit
1487  fi  # end of if [[ -z $clusterFound ]]
1488
1489  if [[ -z $fsFound ]]
1490  then
1491    if [[ $device = all ]]
1492    then
1493      # No file systems were found.
1494      printErrorMsg 200 $mmcmd
1495    else
1496      # The requested file system was not found.
1497      printErrorMsg 288 $mmcmd $device
1498    fi
1499    cleanupAndExit
1500  fi  # end of if [[ -z $fsFound ]]
1501
1502  # Nothing more to do.  The appropriate AUTHORIZED_FS lines have been removed.
1503
1504fi  # end of if [[ $action = deny ]]
1505
1506
1507####################################################
1508# Sort the new mmsdrfs file and commit the changes.
1509####################################################
1510LC_ALL=C $SORT_MMSDRFS $newsdrfs -o $newsdrfs
1511checkForErrors "sorting $newsdrfs" $?
1512
1513trap "" HUP INT QUIT KILL
1514gpfsObjectInfo=$(commitChanges  \
1515   $nsId $nsId $gpfsObjectInfo $newGenNumber $newsdrfs $primaryServer)
1516rc=$?
1517if [[ $rc -ne 0 ]]
1518then
1519  # The commit step failed; we cannot replace the file in the sdr.
1520  printErrorMsg 381 $mmcmd
1521  cleanupAndExit
1522fi
1523
1524
1525##################
1526# Unlock the sdr.
1527##################
1528freeLockOnServer $primaryServer $ourNodeNumber >/dev/null
1529sdrLocked=no
1530trap posttrap HUP INT QUIT KILL
1531
1532# Issue "command was successful" message.
1533printErrorMsg 272 $mmcmd
1534
1535
1536#####################################################
1537# Asynchronously propagate the changes to all nodes.
1538#####################################################
1539if [[ $action = genkey && $genkeyAction = new ]]
1540then
1541  propagateKeyFile async $nodefile  \
1542    $newsdrfs $newGenNumber $fileToStage $newKeyGenNumber
1543else
1544  propagateSdrfsFile async $nodefile $newsdrfs $newGenNumber
1545fi
1546
1547if [[ $secLevel -gt 0 ]]
1548then
1549  # Notify all currently-running nodes to refresh their key files.
1550  $mmcommon onactive $preferredNode $allClusterNodes  \
1551    $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK       \
1552    tsdsh $mmremote refreshAuth >$tmpfile 2>&1
1553fi
1554
1555cleanupAndExit 0
1556
Note: See TracBrowser for help on using the repository browser.