Here’s a tough one, if you like a challenge.
(Or it’s an easy one, and I’ve been staring at it for too long.)
I’m working on a script that fixes POSIX and ACL permissions for every folder within a pre-determined directory structure. We’ve already set these permissions in a .csv file, which I’ve saved in the resources folder of the contents of this app (which is called PermissionScript. Not particularly clever, I know). The script traverses the folder structure, comparing the name and path of the folder against listings in the .csv.
This actually works very well.
Where I run into a problem is that, with ACLs, I want to sort of fake propagation. As you may know, ACLs can be inherited to sub-directories and -files, but only if those files and folders were added after the ACLs were put into place. In order to account for this, my logic was to maintain a list of the ACLs whose properties included inheritance (the inheritance_list), pass it as a variable to the recursive handler on the way down, and apply these ACLs along with the normal ones to lower folders.
Since this list was in a recursive handler, it seems obvious that any added items going down will disappear on the way back up.
Buuuuut…
For some reason, any time ANY item is added to the inheritance_list, it stays for the duration of the script.
Perhaps my actual code will explain it better. This is the Traversal handler:
-- For reference, here is an explanation of every variable passed into the Traversal() handler:
--thisFolder is the folder for which I am changing the permissions.
-- folderList is the list of POSIX permissions from the .csv.
-- ACLList is the list of ACL permissions from the .csv.
-- ID_folder is the number of the column in the POSIX permissions list where the "ID" info is found.
-- owner_folder is the number of the column in the POSIX permissions list where the "owner" info is found.
-- group_folder is the number of the column in the POSIX permissions list where the "group" info is found.
-- permNums_folder is the number of the column in the POSIX permissions list where the permission numbers are found. (ie "777" for read, write, execute for owner, group, and others.)
-- location_folder is the number of the column in the POSIX permissions list where the Path info is found.
-- aclParent: if the number in this field is the same as that of ID_folder, this ACL should be applied.
-- inheritance_acl: either self or all.
-- command_acl: where the actual chmod command is in the .csv.
-- inheritance_list: the supposedly dynamic list of ACLs within a single hierarchy.
-- counter: It's literally a counter. To see how many folders were traversed. At one point, I was returning this value.
-- username_item: for use with "do shell script"'s
-- password_item: for use with "do shell script"'s
-- deletion_choice: user chose whether to delete the existing ACLs or retain them.
-- debugLog: debug log. I've removed anything relating to this, for brevity.
on Traversal(thisFolder, folderList, ACLList, ID_folder, owner_folder, group_folder, permNums_folder, location_folder, aclParent_acl, inheritance_acl, command_acl, inheritance_list, counter, username_item, password_item, deletionChoice, debugLog)
set origTIDs to AppleScript's text item delimiters
set myInheritance_List to inheritance_list
set counter to counter + 1
if deletionChoice is "Delete" then
set thisPerm to deleteExistingACLs(thisFolder, username_item, password_item)
end if
set myPOSIXList to findPosixList(thisFolder, folderList, location_folder) -- This returns the specific entry in the .csv for the POSIX permissions of this folder.
set myACLList to findACLList(ACLList, aclParent_acl, ID_folder, myPOSIXList, command_acl) -- This does the same thing for the ACL permissions.
-- Do POSIX permissions
set thisVariable to giveMePermission(thisFolder, username_item, password_item) -- This handler call sets the owner and group to "Nobody" and gives 777 access.
set posixChmod to chmodPOSIX(thisFolder, myPOSIXList, owner_folder, group_folder, permNums_folder, username_item, password_item) -- This handler actually applies the POSIX permissions.
-- Do Inherited ACL permissions
if myInheritance_List is not {} then
set locationOfFolder to quoted form of (POSIX path of (thisFolder as string))
repeat with m from 1 to count myInheritance_List
set thisACLList to item m of myInheritance_List as string
set thisCommand to parseCommand(thisACLList, command_acl)
set thisCommand to thisCommand & " " & locationOfFolder
set DIWinheritedAclCommand to do shell script thisCommand user name username_item password password_item with administrator privileges
-- Apply "inherited" ACLs. Basically, fake propagation.
end repeat
end if
if myACLList is not {} then
--Parse command
repeat with o from 1 to count myACLList
set thisACL to item o of myACLList
set locationOfFolder to quoted form of (POSIX path of (thisFolder as string))
set command to parseCommand(thisACL, command_acl)
set command to command & " " & locationOfFolder
-- Do ACL chmod command here.
set DIWaclCommand to do shell script command user name username_item password password_item with administrator privileges
if text item inheritance_acl of thisACL is not "self" then
if thisACL is not in (myInheritance_List as string) then set end of myInheritance_List to {thisACL}
end if
end repeat
astid(",")
end if
astid(origTIDs)
-- Traverse any contained folders.
set foldersToTraverse to {}
tell application "Finder" to set foldersToTraverse to every folder of thisFolder
if foldersToTraverse is not {} then
repeat with n from 1 to (count of items of foldersToTraverse) of foldersToTraverse
set thatFolder to (item n of foldersToTraverse)
set debugLog to Traversal(thatFolder, folderList, ACLList, ID_folder, , owner_folder, group_folder, , permNums_folder, location_folder, aclParent_acl, inheritance_acl, command_acl, myInheritance_List, counter, username_item, password_item, deletionChoice, debugLog)
end repeat
end if
set myInheritance_List to {}
return debugLog
end Traversal
Any of the given folders should have a MAXIMUM of maybe 5 ACLs. But by the time it traverses the last folder (which in this case is within the top folder that was chosen, not several folders down), it will apply every ACL it has ever put in the inheritance list.
Since I’m not returning the inheritance_list variable at any given point, I have no clue why this is happening. Any ideas?
Thanks,
_Josh
Model: Mac Pro
AppleScript: 2.0.1
Browser: Firefox 3.6.6
Operating System: Mac OS X (10.5)