File and Folder Permissions Management on macOS
Manage file and folder permissions across your MacFleet devices using command-line tools. This tutorial covers permission models, ownership management, access control implementation, and enterprise-wide permission policy deployment.
Understanding macOS Permission System
macOS uses a Unix-based permission system with three types of permissions and three user categories:
Permission Types
- Read (r) - View file contents or list directory contents
- Write (w) - Modify file contents or create/delete files in directory
- Execute (x) - Run file as program or access directory
User Categories
- Owner (u) - The user who created the file/folder
- Group (g) - Users belonging to the file's group
- Others (o) - All other system users
Permission Representations
Read | Write | Execute | Octal | Symbolic |
---|---|---|---|---|
✗ | ✗ | ✗ | 0 | --- |
✗ | ✗ | ✓ | 1 | --x |
✗ | ✓ | ✗ | 2 | -w- |
✗ | ✓ | ✓ | 3 | -wx |
✓ | ✗ | ✗ | 4 | r-- |
✓ | ✗ | ✓ | 5 | r-x |
✓ | ✓ | ✗ | 6 | rw- |
✓ | ✓ | ✓ | 7 | rwx |
Basic Permission Management
View File/Folder Permissions
#!/bin/bash
# View permissions for specific file or folder
TARGET_PATH="$1"
if [[ -z "$TARGET_PATH" ]]; then
echo "❌ Please specify a file or folder path"
echo "Usage: $0 /path/to/file/or/folder"
exit 1
fi
if [[ ! -e "$TARGET_PATH" ]]; then
echo "❌ Path does not exist: $TARGET_PATH"
exit 1
fi
echo "📋 Permission details for: $TARGET_PATH"
ls -la "$TARGET_PATH"
echo ""
echo "📊 Detailed permission breakdown:"
ls -la "$TARGET_PATH" | while read -r line; do
if [[ "$line" != total* ]]; then
echo "Full output: $line"
# Extract permission string
perms=$(echo "$line" | awk '{print $1}')
if [[ ${#perms} -eq 10 ]]; then
echo "File type: ${perms:0:1}"
echo "Owner permissions: ${perms:1:3}"
echo "Group permissions: ${perms:4:3}"
echo "Others permissions: ${perms:7:3}"
fi
fi
done
Set Permissions Using Octal Notation
#!/bin/bash
# Set permissions using octal notation (e.g., 755, 644)
TARGET_PATH="$1"
PERMISSION="$2"
if [[ -z "$TARGET_PATH" || -z "$PERMISSION" ]]; then
echo "❌ Please specify path and permission"
echo "Usage: $0 /path/to/file 755"
echo "Common permissions:"
echo " 755 - rwxr-xr-x (owner: full, group/others: read+execute)"
echo " 644 - rw-r--r-- (owner: read+write, group/others: read-only)"
echo " 600 - rw------- (owner: read+write, group/others: no access)"
exit 1
fi
if [[ ! -e "$TARGET_PATH" ]]; then
echo "❌ Path does not exist: $TARGET_PATH"
exit 1
fi
# Validate permission format
if [[ ! "$PERMISSION" =~ ^[0-7]{3}$ ]]; then
echo "❌ Invalid permission format. Use 3-digit octal (e.g., 755)"
exit 1
fi
echo "🔧 Setting permissions $PERMISSION on: $TARGET_PATH"
# Show current permissions
echo "Current permissions:"
ls -la "$TARGET_PATH"
# Apply new permissions
if chmod "$PERMISSION" "$TARGET_PATH"; then
echo "✅ Permissions updated successfully"
echo "New permissions:"
ls -la "$TARGET_PATH"
else
echo "❌ Failed to set permissions"
exit 1
fi
Set Permissions Using Symbolic Notation
#!/bin/bash
# Set permissions using symbolic notation (e.g., u=rwx,g=rx,o=r)
TARGET_PATH="$1"
PERMISSION="$2"
if [[ -z "$TARGET_PATH" || -z "$PERMISSION" ]]; then
echo "❌ Please specify path and permission"
echo "Usage: $0 /path/to/file 'u=rwx,g=rx,o=r'"
echo "Symbolic notation examples:"
echo " u=rwx,g=rx,o=rx - Owner: full, Group/Others: read+execute"
echo " u=rw,g=r,o=r - Owner: read+write, Group/Others: read-only"
echo " u=rw,g=,o= - Owner: read+write, Group/Others: no access"
exit 1
fi
if [[ ! -e "$TARGET_PATH" ]]; then
echo "❌ Path does not exist: $TARGET_PATH"
exit 1
fi
echo "🔧 Setting permissions '$PERMISSION' on: $TARGET_PATH"
# Show current permissions
echo "Current permissions:"
ls -la "$TARGET_PATH"
# Apply new permissions
if chmod "$PERMISSION" "$TARGET_PATH"; then
echo "✅ Permissions updated successfully"
echo "New permissions:"
ls -la "$TARGET_PATH"
else
echo "❌ Failed to set permissions"
exit 1
fi
Ownership Management
Change File/Folder Owner
#!/bin/bash
# Change ownership of file or folder
TARGET_PATH="$1"
NEW_OWNER="$2"
if [[ -z "$TARGET_PATH" || -z "$NEW_OWNER" ]]; then
echo "❌ Please specify path and new owner"
echo "Usage: $0 /path/to/file username"
exit 1
fi
if [[ ! -e "$TARGET_PATH" ]]; then
echo "❌ Path does not exist: $TARGET_PATH"
exit 1
fi
# Verify user exists
if ! id "$NEW_OWNER" &>/dev/null; then
echo "❌ User does not exist: $NEW_OWNER"
echo "Available users:"
dscl . list /Users | grep -v "^_"
exit 1
fi
echo "👤 Changing owner of '$TARGET_PATH' to: $NEW_OWNER"
# Show current ownership
echo "Current ownership:"
ls -la "$TARGET_PATH"
# Change ownership
if sudo chown "$NEW_OWNER" "$TARGET_PATH"; then
echo "✅ Ownership changed successfully"
echo "New ownership:"
ls -la "$TARGET_PATH"
else
echo "❌ Failed to change ownership"
exit 1
fi
Change File/Folder Group
#!/bin/bash
# Change group ownership of file or folder
TARGET_PATH="$1"
NEW_GROUP="$2"
if [[ -z "$TARGET_PATH" || -z "$NEW_GROUP" ]]; then
echo "❌ Please specify path and new group"
echo "Usage: $0 /path/to/file groupname"
echo "Common groups: admin, staff, wheel, everyone"
exit 1
fi
if [[ ! -e "$TARGET_PATH" ]]; then
echo "❌ Path does not exist: $TARGET_PATH"
exit 1
fi
# Verify group exists
if ! dscl . read /Groups/"$NEW_GROUP" &>/dev/null; then
echo "❌ Group does not exist: $NEW_GROUP"
echo "Available groups:"
dscl . list /Groups | grep -v "^_"
exit 1
fi
echo "👥 Changing group of '$TARGET_PATH' to: $NEW_GROUP"
# Show current ownership
echo "Current ownership:"
ls -la "$TARGET_PATH"
# Change group ownership
if sudo chgrp "$NEW_GROUP" "$TARGET_PATH"; then
echo "✅ Group ownership changed successfully"
echo "New ownership:"
ls -la "$TARGET_PATH"
else
echo "❌ Failed to change group ownership"
exit 1
fi
Recursive Permission Management
Set Permissions Recursively
#!/bin/bash
# Set permissions recursively on directory and all contents
TARGET_DIR="$1"
DIR_PERMISSION="$2"
FILE_PERMISSION="$3"
if [[ -z "$TARGET_DIR" || -z "$DIR_PERMISSION" || -z "$FILE_PERMISSION" ]]; then
echo "❌ Please specify directory path and permissions"
echo "Usage: $0 /path/to/directory 755 644"
echo "This will set directories to 755 and files to 644"
exit 1
fi
if [[ ! -d "$TARGET_DIR" ]]; then
echo "❌ Directory does not exist: $TARGET_DIR"
exit 1
fi
echo "🔄 Setting recursive permissions on: $TARGET_DIR"
echo "Directories will be set to: $DIR_PERMISSION"
echo "Files will be set to: $FILE_PERMISSION"
# Count items to process
dir_count=$(find "$TARGET_DIR" -type d | wc -l)
file_count=$(find "$TARGET_DIR" -type f | wc -l)
echo "Found $dir_count directories and $file_count files to process"
read -p "Continue? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Operation cancelled"
exit 0
fi
# Set permissions on directories
echo "🗂️ Setting directory permissions..."
if find "$TARGET_DIR" -type d -exec chmod "$DIR_PERMISSION" {} \;; then
echo "✅ Directory permissions set successfully"
else
echo "❌ Failed to set directory permissions"
exit 1
fi
# Set permissions on files
echo "📄 Setting file permissions..."
if find "$TARGET_DIR" -type f -exec chmod "$FILE_PERMISSION" {} \;; then
echo "✅ File permissions set successfully"
else
echo "❌ Failed to set file permissions"
exit 1
fi
echo "✅ Recursive permission update completed"
Enterprise Permission Management Script
#!/bin/bash
# MacFleet Permission Management Tool
# Comprehensive file and folder permission management for enterprise environments
# Configuration
LOG_FILE="/var/log/macfleet_permissions.log"
BACKUP_DIR="/var/backups/macfleet/permissions"
POLICY_FILE="/etc/macfleet/permission_policies.conf"
REPORT_DIR="/var/reports/macfleet/permissions"
# Logging function
log_action() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# Setup directories
setup_directories() {
for dir in "$BACKUP_DIR" "$REPORT_DIR" "$(dirname "$POLICY_FILE")"; do
if [[ ! -d "$dir" ]]; then
sudo mkdir -p "$dir"
log_action "Created directory: $dir"
fi
done
}
# Create permission backup
create_permission_backup() {
local target_path="$1"
local backup_file="$BACKUP_DIR/permissions_$(basename "$target_path")_$(date +%Y%m%d_%H%M%S).txt"
echo "📦 Creating permission backup for: $target_path"
if [[ -d "$target_path" ]]; then
# Backup directory permissions recursively
find "$target_path" -exec ls -la {} \; > "$backup_file" 2>/dev/null
else
# Backup single file permissions
ls -la "$target_path" > "$backup_file" 2>/dev/null
fi
if [[ $? -eq 0 ]]; then
echo "✅ Backup created: $backup_file"
log_action "Permission backup created: $backup_file"
else
echo "⚠️ Warning: Could not create backup"
log_action "Warning: Backup creation failed for $target_path"
fi
}
# Apply enterprise permission policy
apply_enterprise_policy() {
local policy_name="$1"
echo "🏢 Applying enterprise permission policy: $policy_name"
log_action "Starting enterprise policy application: $policy_name"
case "$policy_name" in
"secure_documents")
apply_secure_documents_policy
;;
"shared_workspace")
apply_shared_workspace_policy
;;
"application_deployment")
apply_application_deployment_policy
;;
"system_hardening")
apply_system_hardening_policy
;;
*)
echo "❌ Unknown policy: $policy_name"
return 1
;;
esac
}
# Secure documents policy
apply_secure_documents_policy() {
echo "🔒 Applying secure documents permission policy..."
local secure_dirs=(
"/Users/Shared/SecureDocuments"
"/opt/macfleet/confidential"
"/var/secure"
)
for dir in "${secure_dirs[@]}"; do
if [[ -d "$dir" ]]; then
echo "Securing directory: $dir"
# Create backup
create_permission_backup "$dir"
# Apply secure permissions (owner: full, group: read, others: none)
sudo find "$dir" -type d -exec chmod 750 {} \;
sudo find "$dir" -type f -exec chmod 640 {} \;
# Set admin group ownership
sudo chgrp -R admin "$dir"
log_action "Secure permissions applied to: $dir"
fi
done
}
# Shared workspace policy
apply_shared_workspace_policy() {
echo "👥 Applying shared workspace permission policy..."
local shared_dirs=(
"/Users/Shared/TeamWork"
"/opt/macfleet/shared"
"/var/shared"
)
for dir in "${shared_dirs[@]}"; do
if [[ -d "$dir" ]]; then
echo "Configuring shared directory: $dir"
# Create backup
create_permission_backup "$dir"
# Apply shared permissions (owner: full, group: full, others: read)
sudo find "$dir" -type d -exec chmod 775 {} \;
sudo find "$dir" -type f -exec chmod 664 {} \;
# Set staff group ownership
sudo chgrp -R staff "$dir"
log_action "Shared permissions applied to: $dir"
fi
done
}
# Application deployment policy
apply_application_deployment_policy() {
echo "📱 Applying application deployment permission policy..."
local app_dirs=(
"/Applications"
"/opt/macfleet/applications"
"/usr/local/bin"
)
for dir in "${app_dirs[@]}"; do
if [[ -d "$dir" ]]; then
echo "Securing application directory: $dir"
# Create backup
create_permission_backup "$dir"
# Apply application permissions (owner: full, group/others: read+execute)
sudo find "$dir" -type d -exec chmod 755 {} \;
sudo find "$dir" -type f -name "*.app" -exec chmod 755 {} \;
sudo find "$dir" -type f ! -name "*.app" -exec chmod 644 {} \;
# Set admin ownership
sudo chown -R root:admin "$dir"
log_action "Application permissions applied to: $dir"
fi
done
}
# System hardening policy
apply_system_hardening_policy() {
echo "🛡️ Applying system hardening permission policy..."
local system_dirs=(
"/etc"
"/var/log"
"/usr/bin"
"/usr/sbin"
)
for dir in "${system_dirs[@]}"; do
if [[ -d "$dir" ]]; then
echo "Hardening system directory: $dir"
# Create backup
create_permission_backup "$dir"
# Apply restrictive permissions
case "$dir" in
"/etc")
sudo find "$dir" -type f -exec chmod 644 {} \;
sudo find "$dir" -type d -exec chmod 755 {} \;
;;
"/var/log")
sudo find "$dir" -type f -exec chmod 640 {} \;
sudo find "$dir" -type d -exec chmod 750 {} \;
;;
"/usr/bin"|"/usr/sbin")
sudo find "$dir" -type f -exec chmod 755 {} \;
sudo find "$dir" -type d -exec chmod 755 {} \;
;;
esac
# Ensure root ownership
sudo chown -R root:wheel "$dir"
log_action "System hardening applied to: $dir"
fi
done
}
# Audit permission compliance
audit_permissions() {
local target_path="$1"
local audit_file="$REPORT_DIR/permission_audit_$(date +%Y%m%d_%H%M%S).txt"
echo "🔍 Auditing permissions for: $target_path"
{
echo "MacFleet Permission Audit Report"
echo "Generated: $(date)"
echo "Target: $target_path"
echo "Host: $(hostname)"
echo "=================================="
echo ""
if [[ -d "$target_path" ]]; then
echo "=== Directory Structure and Permissions ==="
find "$target_path" -exec ls -la {} \; 2>/dev/null
echo ""
echo "=== Permission Summary ==="
echo "Total items: $(find "$target_path" | wc -l)"
echo "Directories: $(find "$target_path" -type d | wc -l)"
echo "Files: $(find "$target_path" -type f | wc -l)"
echo ""
echo "=== World-Writable Files (Security Risk) ==="
find "$target_path" -type f -perm -002 -ls 2>/dev/null || echo "None found"
echo ""
echo "=== SUID/SGID Files ==="
find "$target_path" -type f \( -perm -4000 -o -perm -2000 \) -ls 2>/dev/null || echo "None found"
echo ""
echo "=== Files with No Owner/Group ==="
find "$target_path" -nouser -o -nogroup 2>/dev/null || echo "None found"
else
echo "=== Single File Permissions ==="
ls -la "$target_path"
fi
} > "$audit_file"
echo "📊 Audit report saved to: $audit_file"
log_action "Permission audit completed: $audit_file"
}
# Fix common permission issues
fix_common_issues() {
echo "🔧 Fixing common permission issues..."
# Fix world-writable files
echo "Fixing world-writable files..."
local world_writable
world_writable=$(find /Users -type f -perm -002 2>/dev/null | head -10)
if [[ -n "$world_writable" ]]; then
echo "Found world-writable files:"
echo "$world_writable"
echo "$world_writable" | while read -r file; do
if [[ -f "$file" ]]; then
echo "Fixing: $file"
sudo chmod o-w "$file"
log_action "Removed world-write permission from: $file"
fi
done
else
echo "✅ No world-writable files found"
fi
# Fix common application permission issues
echo "Fixing application permissions..."
if [[ -d "/Applications" ]]; then
sudo find /Applications -name "*.app" -type d -exec chmod 755 {} \; 2>/dev/null
log_action "Fixed application permissions in /Applications"
fi
# Fix user home directory permissions
echo "Fixing user home directory permissions..."
for user_home in /Users/*; do
if [[ -d "$user_home" && "$(basename "$user_home")" != "Shared" ]]; then
username=$(basename "$user_home")
if id "$username" &>/dev/null; then
sudo chmod 755 "$user_home"
sudo chown "$username:staff" "$user_home"
log_action "Fixed home directory permissions for: $username"
fi
fi
done
echo "✅ Common permission issues fixed"
}
# Generate permission report
generate_permission_report() {
local report_file="$REPORT_DIR/permission_report_$(date +%Y%m%d_%H%M%S).txt"
echo "📊 Generating comprehensive permission report..."
{
echo "MacFleet Permission Management Report"
echo "Generated: $(date)"
echo "Hostname: $(hostname)"
echo "User: $(whoami)"
echo "======================================="
echo ""
echo "=== System Information ==="
echo "macOS Version: $(sw_vers -productVersion)"
echo "Build: $(sw_vers -buildVersion)"
echo "Kernel: $(uname -r)"
echo ""
echo "=== Critical Directory Permissions ==="
for dir in "/Applications" "/System" "/usr" "/etc" "/var"; do
if [[ -d "$dir" ]]; then
echo "$dir: $(ls -ld "$dir" | awk '{print $1, $3, $4}')"
fi
done
echo ""
echo "=== User Home Directory Permissions ==="
for user_home in /Users/*; do
if [[ -d "$user_home" ]]; then
echo "$(basename "$user_home"): $(ls -ld "$user_home" | awk '{print $1, $3, $4}')"
fi
done
echo ""
echo "=== Security Concerns ==="
echo "World-writable files: $(find /Users -type f -perm -002 2>/dev/null | wc -l)"
echo "SUID files: $(find /usr -type f -perm -4000 2>/dev/null | wc -l)"
echo "SGID files: $(find /usr -type f -perm -2000 2>/dev/null | wc -l)"
echo ""
echo "=== Recent Permission Changes ==="
tail -20 "$LOG_FILE" 2>/dev/null || echo "No recent changes logged"
} > "$report_file"
echo "📊 Report saved to: $report_file"
log_action "Permission report generated: $report_file"
}
# Main execution function
main() {
local action="${1:-help}"
local target="${2:-}"
local permission="${3:-}"
log_action "=== MacFleet Permission Management Started ==="
setup_directories
case "$action" in
"view")
if [[ -n "$target" ]]; then
audit_permissions "$target"
else
echo "❌ Please specify target path"
echo "Usage: $0 view /path/to/target"
fi
;;
"set")
if [[ -n "$target" && -n "$permission" ]]; then
create_permission_backup "$target"
chmod "$permission" "$target"
log_action "Set permissions $permission on $target"
else
echo "❌ Please specify target and permission"
echo "Usage: $0 set /path/to/target 755"
fi
;;
"policy")
if [[ -n "$target" ]]; then
apply_enterprise_policy "$target"
else
echo "❌ Please specify policy name"
echo "Available policies: secure_documents, shared_workspace, application_deployment, system_hardening"
fi
;;
"audit")
if [[ -n "$target" ]]; then
audit_permissions "$target"
else
audit_permissions "/Users"
fi
;;
"fix")
fix_common_issues
;;
"report")
generate_permission_report
;;
"help"|*)
echo "MacFleet Permission Management Tool"
echo "Usage: $0 [action] [target] [permission]"
echo ""
echo "Actions:"
echo " view [path] - View permissions for path"
echo " set [path] [perm] - Set permissions (e.g., 755)"
echo " policy [name] - Apply enterprise permission policy"
echo " audit [path] - Audit permissions and security"
echo " fix - Fix common permission issues"
echo " report - Generate comprehensive report"
echo " help - Show this help message"
echo ""
echo "Policies:"
echo " secure_documents - Apply secure document permissions"
echo " shared_workspace - Configure shared workspace permissions"
echo " application_deployment - Set application directory permissions"
echo " system_hardening - Apply system security hardening"
;;
esac
log_action "=== MacFleet Permission Management Completed ==="
}
# Execute main function
main "$@"
Common Permission Scenarios
Secure File Storage
# Create secure directory with restricted access
sudo mkdir -p /opt/macfleet/secure
sudo chmod 700 /opt/macfleet/secure
sudo chown root:admin /opt/macfleet/secure
Shared Team Directory
# Create shared directory for team collaboration
sudo mkdir -p /Users/Shared/TeamProject
sudo chmod 775 /Users/Shared/TeamProject
sudo chgrp staff /Users/Shared/TeamProject
Application Deployment
# Set standard application permissions
sudo chmod 755 /Applications/MyApp.app
sudo chown root:admin /Applications/MyApp.app
Permission Reference Guide
Common Permission Patterns
Use Case | Octal | Symbolic | Description |
---|---|---|---|
Private file | 600 | rw------- | Owner read/write only |
Shared file | 644 | rw-r--r-- | Owner write, others read |
Executable | 755 | rwxr-xr-x | Owner full, others read/execute |
Secure directory | 700 | rwx------ | Owner access only |
Shared directory | 755 | rwxr-xr-x | Owner full, others read/list |
Team directory | 775 | rwxrwxr-x | Owner/group full, others read |
Quick Commands Reference
# View permissions
ls -la filename
stat -f "%A %N" filename
# Set permissions
chmod 755 filename # Octal notation
chmod u=rwx,g=rx,o=rx filename # Symbolic notation
# Change ownership
chown user:group filename # Change both user and group
chown user filename # Change user only
chgrp group filename # Change group only
# Recursive operations
chmod -R 755 directory/ # Apply to all contents
chown -R user:group directory/ # Change ownership recursively
Security Considerations
- Principle of Least Privilege - Grant minimum necessary permissions
- Regular Audits - Monitor permission changes and compliance
- Backup Before Changes - Always create backups before modifications
- World-Writable Files - Avoid or carefully control world-writable permissions
- SUID/SGID Files - Monitor and limit special permission files
- System Directory Protection - Maintain strict permissions on system directories
Troubleshooting
Permission Denied Errors
# Check current permissions
ls -la /path/to/file
# Check if you have sudo access
sudo -l
# Fix common permission issues
sudo chmod +r /path/to/file # Add read permission
sudo chmod +x /path/to/file # Add execute permission
Ownership Issues
# Check current ownership
ls -la /path/to/file
# Fix ownership
sudo chown $(whoami) /path/to/file # Make current user owner
sudo chgrp staff /path/to/file # Set to staff group
Important Notes
- Administrative privileges may be required for system files
- Backup permissions before making changes for easy restoration
- Test changes on individual devices before fleet deployment
- Document permission policies for compliance and auditing
- Monitor security with regular permission audits