1 #
   2 # CDDL HEADER START
   3 #
   4 # The contents of this file are subject to the terms of the
   5 # Common Development and Distribution License (the "License").
   6 # You may not use this file except in compliance with the License.
   7 #
   8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9 # or http://www.opensolaris.org/os/licensing.
  10 # See the License for the specific language governing permissions
  11 # and limitations under the License.
  12 #
  13 # When distributing Covered Code, include this CDDL HEADER in each
  14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15 # If applicable, add the following below this CDDL HEADER, with the
  16 # fields enclosed by brackets "[]" replaced with your own identifying
  17 # information: Portions Copyright [yyyy] [name of copyright owner]
  18 #
  19 # CDDL HEADER END
  20 #
  21 
  22 #
  23 # Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24 # Use is subject to license terms.
  25 #
  26 # TCL procedures for OPEN operation testing
  27 
  28 # NFSv4 constant:
  29 set OPEN4_RESULT_CONFIRM        2
  30 
  31 
  32 #---------------------------------------------------------
  33 # Test procedure to close the file; but also Open_confirm (if needed).
  34 #  Usage: ckclose nfh rflags seqid sid
  35 #       nfh:     the filehandle to be closed
  36 #       rflags:  the rflags for OPEN_CONFIRM
  37 #       seqid:   the sequence id
  38 #       sid:     the state id 
  39 #
  40 #  Return: 
  41 #       true:   Close succeed
  42 #       false:  things failed during the process
  43 #
  44 proc ckclose {nfh rflags seqid sid} {
  45     global DEBUG OPEN4_RESULT_CONFIRM
  46 
  47     set cont true
  48     if {[expr $rflags & $OPEN4_RESULT_CONFIRM] == $OPEN4_RESULT_CONFIRM} {
  49         putmsg stderr 1 "  Open_confirm $sid $seqid"
  50         set res [compound {Putfh $nfh; Open_confirm $sid $seqid}]
  51         if {$status != "OK"} {
  52             putmsg stderr 0 \
  53                 "\t Test FAIL: Open_confirm failed, status=($status)."
  54             putmsg stderr 1 "\t   res=($res)"
  55             set cont false
  56         }
  57         set sid [lindex [lindex $res 1] 2]
  58         incr seqid
  59     }
  60     # verify the filehandle of OPEN is good to close) and same as LOOKUP
  61     if {! [string equal $cont "false"]} {
  62         # Close the file
  63         putmsg stderr 1 "  Close $seqid $sid"
  64         set res [compound {Putfh $nfh; Close $seqid $sid}]
  65         if {$status != "OK"} {
  66             putmsg stderr 0 \
  67                 "\t Test FAIL: Close failed, status=($status)."
  68             putmsg stderr 1 "\t   res=($res)"
  69             set cont false
  70         }
  71     }
  72     return $cont
  73 }
  74 
  75 
  76 #--------------------------------------------------------------------
  77 # uid_open()
  78 #       Wrap for testing Open assertions for BADOWNER and
  79 #               verifying with getattr op.
  80 #       Returns OK if success, else the status code of the operation.
  81 #               parameters Aown Aowngrp are set to final attrs of file
  82 #
  83 
  84 proc uid_open {dfh fname clientid Aown Aowngrp Ares {Eown ""} \
  85         {Egrp ""}} {
  86         global DEBUG OPEN4_RESULT_CONFIRM
  87 
  88         # initialize attributes parameter
  89         upvar 1 $Aown own
  90         upvar 1 $Aowngrp owngrp
  91         upvar 1 $Ares res
  92 
  93         set status "UNRESOLVED"
  94         putmsg stdout 1 "\n"
  95         putmsg stdout 1 "uid_open $dfh $fname $clientid"
  96         putmsg stdout 1 "\t$Aown $Aowngrp $Ares \"$Eown\" \"$Egrp\""
  97         putmsg stdout 1 "status = $status"
  98 
  99         set attrib {}
 100         set attrs {}
 101         set O 0
 102         set G 0
 103 
 104         # pass tag if exists as global
 105         if {[info vars ::tag] != ""} {
 106                 upvar 1 tag tag
 107         }
 108 
 109         if {[string length $own] > 0}  {
 110                 lappend attrib "owner $own"
 111                 lappend attrs "owner"
 112                 set O 1
 113         }
 114         if {[string length $owngrp] > 0} {
 115                 lappend attrib "owner_group $owngrp"
 116                 lappend attrs "owner_group"
 117                 set G 1
 118         }
 119         putmsg stdout 1 "attrib = <$attrib>"
 120         putmsg stdout 1 "attrs = <$attrs>"
 121 
 122         lappend attrib "mode 0777"
 123         set seqid 1
 124         set rem_flag 0
 125         # Generate a compound request to test the attributes
 126         set st [catch {compound {Putfh $dfh; Open $seqid 3 0 {$clientid $fname}\
 127                 {1 0 {$attrib}} {0  $fname}; Getfh}} res]
 128         putmsg stdout 1 "compound{Putfh $dfh;"
 129         putmsg stdout 1 "\tOpen $seqid 3 0 {$clientid $fname}"
 130         putmsg stdout 1 "\t{1 0 {$attrib}}"
 131         putmsg stdout 1 "\t{0 $fname}; Getfh}"
 132         putmsg stdout 1 "res: <$res>"
 133         if {$status != "OK"} {
 134                 putmsg stdout 1 "Open return status=$status"
 135                 putmsg stdout 1 "catch result = $st"
 136                 return $status
 137         }
 138         set stateid [lindex [lindex $res 1] 2]
 139         set rflags [lindex [lindex $res 1] 4] 
 140         set ufh [lindex [lindex $res 2] 2]
 141         putmsg stdout 1 "stateid = $stateid\nrflags = $rflags\nufh = $ufh"
 142 
 143         # do open_confirm if needed, e.g. rflags has OPEN4_RESULT_CONFIRM set
 144         if {[expr $rflags & $OPEN4_RESULT_CONFIRM] == $OPEN4_RESULT_CONFIRM} {
 145                 incr seqid
 146                 set res [compound {Putfh $ufh; Open_confirm $stateid $seqid}]
 147                 putmsg stdout 1 "compound {Putfh $ufh;"
 148                 putmsg stdout 1 "Open_confirm $stateid $seqid}"
 149                 putmsg stdout 1 "Res: $res"
 150                 if {$status != "OK"} {
 151                         putmsg stdout 1 \
 152                                 "unable to openconfirm $fname ($status)."
 153                         return $status
 154                 }
 155                 set rem_flag 1
 156                 set stateid [lindex [lindex $res 1] 2]
 157         }
 158         incr seqid
 159         putmsg stdout 1 "stateid = $stateid\nseqid = $seqid"
 160 
 161         #verify the change in attribute
 162         set st2 [catch {compound {Putfh $ufh; Getattr $attrs}} res2]
 163         putmsg stdout 1 "compound{Putfh $ufh;\n\tGetattr $attrs}"
 164         putmsg stdout 1 "res: <$res2>"
 165         if {$status != "OK"} {
 166                 putmsg stdout 0 "\twarning: Getattr failed ($status)."
 167                 putmsg stdout 1 "return status=$status"
 168                 putmsg stdout 1 "catch result = $st2"
 169                 return $status
 170         } else {
 171                 set rattrs [lindex [lindex $res2 1] 2]
 172                 set owner ""
 173                 set owner_group ""
 174                 putmsg stdout 1 "returned attrs = $rattrs"
 175                 foreach attr $rattrs {
 176                         set name [ lindex $attr 0]
 177                         set val  [ lindex $attr 1]
 178 
 179                         switch $name {
 180                                 owner   { 
 181                                         set owner $val
 182                                 }
 183                                 owner_group     {
 184                                         set owner_group $val
 185                                 }
 186                                 default {}
 187                         }
 188                 }
 189                 putmsg stdout 1 "owner = $owner\nowner_group = $owner_group"
 190         }
 191         if {$rem_flag != 0} {
 192                 set res [compound {Putfh $ufh; Close $seqid $stateid; \
 193                         Putfh $dfh; Remove $fname}]
 194                 putmsg stdout 1 "compound {Putfh $ufh;"
 195                 putmsg stdout 1 "\tClose $seqid $stateid;"
 196                 putmsg stdout 1 "\tPutfh $dfh; Remove $fname}"
 197                 putmsg stdout 1 "Res: $res"
 198                 if {$status != "OK"} {
 199                         putmsg stdout 1 \
 200                                 "unable to close/remove $fname ($status)."
 201                 }
 202         }
 203 
 204         set Cstatus ""
 205         # if expected value different than value used
 206         if {$Eown != ""} {
 207                 set own $Eown
 208         }
 209         if {$Egrp != ""} {
 210                 set owngrp $Egrp
 211         }
 212         # compare to requested values
 213         # XXX should we enhance to ignore the case of the domain?
 214         if {$O == 1 && [string equal $own $owner] != 1} {
 215                 putmsg stdout 1 "owner set to $own, but is $owner"
 216                 set own $owner
 217                 set Cstatus "${Cstatus}OwnerMismatch"
 218         }
 219         if {$G == 1 && [string equal $owngrp $owner_group] != 1} {
 220                 putmsg stdout 1\
 221                         "group set to $owngrp, but is $owner_group"
 222                 set Cstatus "${Cstatus}GroupMismatch"
 223         }
 224 
 225         if {$Cstatus != ""} {
 226                 set status $Cstatus
 227         }
 228 
 229         putmsg stdout 1 "return $status"
 230         return $status
 231 }