-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlockdown_function.sh
More file actions
203 lines (179 loc) · 6.38 KB
/
lockdown_function.sh
File metadata and controls
203 lines (179 loc) · 6.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/bin/bash
# Lockdown function - Makes files/directories read-only and immutable
# Usage: lockdown [OPTIONS] FILE/PATTERN...
# -u, --unlock Reverse the lockdown (make mutable and writable)
# -c, --check Check the lockdown status of files
# -h, --help Show help message
NC='\033[0m'
RED='\033[31m'
TEAL='\033[36m'
GREEN='\033[32m'
YELLOW='\033[33m'
lockdown() {
local unlock_mode=false
local check_mode=false
local targets=()
local recursive_flag=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
-u|--unlock)
unlock_mode=true
shift
;;
-c|--check)
check_mode=true
shift
;;
-h|--help)
cat << EOF
Lockdown - Protect files and directories from modification
Usage: lockdown [OPTIONS] FILE/PATTERN...
Options:
-u, --unlock Reverse the lockdown (make mutable and writable)
-c, --check Check the lockdown status of files
-h, --help Show this help message
Examples:
lockdown file.txt # Lock a single file
lockdown *.dll # Lock all .dll files
lockdown Tools/ # Lock directory and contents
lockdown -u file.txt # Unlock a file
lockdown --check *.dll # Check status of .dll files
lockdown file1.txt dir/ *.log # Lock multiple targets
Note: Requires sudo privileges for chattr operations
EOF
return 0
;;
*)
targets+=("$1")
shift
;;
esac
done
# Check if we have targets
if [[ ${#targets[@]} -eq 0 ]]; then
echo -e "${RED}Error${NC}: ${YELLOW}No files or directories specified${NC}"
echo -e "Use '${YELLOW}lockdown -h${NC}' for help"
return 1
fi
# Function to check status
check_status() {
local item="$1"
local writable="Yes"
local immutable="No"
# Check write permissions
if [[ ! -w "$item" ]]; then
writable="No"
fi
# Check immutable attribute (requires lsattr)
if command -v lsattr &>/dev/null; then
if lsattr "$item" 2>/dev/null | grep -q '^\S*i'; then
immutable="Yes"
fi
fi
printf "%-40s Writable: %-3s Immutable: %-3s\n" "$item" "$writable" "$immutable"
}
# Function to process a single item
process_item() {
local item="$1"
local is_dir=false
if [[ -d "$item" ]]; then
is_dir=true
recursive_flag="-R"
else
recursive_flag=""
fi
if $check_mode; then
# Check mode
if $is_dir; then
echo "Directory: $item"
check_status "$item"
# Check contents of directory
find "$item" -maxdepth 3 2>/dev/null | head -20 | while read -r subitem; do
check_status "$subitem"
done
local count=$(find "$item" 2>/dev/null | wc -l)
if [[ $count -gt 20 ]]; then
echo " ... and $((count - 20)) more items"
fi
else
check_status "$item"
fi
elif $unlock_mode; then
# Unlock mode - Order: first make mutable, then make writable
echo -e "${YELLOW} ${NC} Unlocking: ${TEAL}$item${NC}"
# First, remove immutable attribute (needs to be done before chmod)
if sudo chattr -i $recursive_flag "$item" 2>/dev/null; then
echo -e " $TEAL✓ ${GREEN}Removed immutable attribute $NC"
else
echo -e " $RED⚠$NC ${YELLOW}Could not remove immutable attribute (may not have been set) $NC"
fi
# Then, restore write permissions
if chmod a+w $recursive_flag "$item" 2>/dev/null; then
echo -e " $TEAL✓ ${GREEN}Restored write permissions $NC"
else
echo -e " $RED✗$NC ${YELLOW}Failed to restore write permissions $NC"
return 1
fi
else
# Lock mode - Order: first remove write, then make immutable
echo -e "${YELLOW} ${NC} Locking down: ${TEAL}$item${NC}"
# First, remove write permissions
if chmod a-w $recursive_flag "$item" 2>/dev/null; then
echo -e " $TEAL✓ ${GREEN}Removed write permissions $NC"
else
echo -e " $RED✗$NC ${YELLOW}Failed to remove write permissions $NC"
return 1
fi
# Then, set immutable attribute
if sudo chattr +i $recursive_flag "$item" 2>/dev/null; then
echo -e " $TEAL✓$NC ${GREEN}Set immutable attribute $NC"
else
echo -e " $RED⚠$NC ${YELLOW}Could not set immutable attribute (needs sudo) $NC"
fi
fi
}
# Process each target
local has_errors=false
for target in "${targets[@]}"; do
# Expand globs and process each match
local matches=()
# Use nullglob to handle non-matching patterns gracefully
#shopt -s nullglob
#matches=($target)
#shopt -u nullglob
if [[ ${#matches[@]} -eq 0 ]]; then
# No glob matches, check if it's a literal file/directory
if [[ -e "$target" ]]; then
process_item "$target"
if [[ $? -ne 0 ]]; then
has_errors=true
fi
else
echo -e "Warning: No matches found for: $target"
has_errors=true
fi
else
# Process all matches
for item in "${matches[@]}"; do
if [[ -e "$item" ]]; then
process_item "$item"
if [[ $? -ne 0 ]]; then
has_errors=true
fi
fi
done
fi
echo "" # Empty line between targets for readability
done
# Return status
if $has_errors; then
return 1
else
return 0
fi
}
# Optional: Create shorter aliases
alias ld='lockdown'
alias ldu='lockdown -u'
alias ldc='lockdown -c'