blob: 33658945391405905358c034cefb573f9dbe57a2 (
plain)
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
|
#!/bin/sh /etc/rc.common
# Copyright (C) 2010-2025 OpenWrt.org
START=85
STOP=10
USE_PROCD=1
PROG_netatalk='/usr/sbin/netatalk'
# Default config file location
config_file='/etc/afp.conf'
# Config file contents and status
afpd_config=''
config_overwrite=''
config_error=0
setup_error=0
# Log tag
log_tag='afpd-init'
# Configuration dictionary
valid_global='|'
valid_global=$valid_global'ad_domain|admin_auth_user|admin_group|force_user|force_group|k5_keytab|k5_service|k5_realm|'
valid_global=$valid_global'nt_domain|nt_separator|save_password|set_password|uam_list|uam_path|mac_charset|unix_charset|'
valid_global=$valid_global'vol_charset|passwd_file|passwd_minlen|afp_interfaces|afp_listen|afp_port|appletalk|'
valid_global=$valid_global'cnid_listen|cnid_server|ddp_address|ddp_zone|disconnect_time|dsireadbuf|hostname|'
valid_global=$valid_global'max_connections|sleep_time|chmod_request|dircachesize|extmap_file|'
valid_global=$valid_global'force_xattr_with_sticky_bit|guest_account|ignored_attributes|legacy_icon|login_message|'
valid_global=$valid_global'mimic_model|vol_dbpath|zeroconf_name|log_file|log_level|map_acls|ldap_auth_method|'
valid_global=$valid_global'ldap_auth_dn|ldap_auth_pw|ldap_uri|ldap_userbase|ldap_userscope|ldap_groupbase|'
valid_global=$valid_global'ldap_groupscope|ldap_uuid_attr|ldap_name_attr|ldap_group_attr|ldap_uuid_string|'
valid_global=$valid_global'ldap_uuid_encoding|ldap_user_filter|ldap_group_filter|vol_dbnest|fce_ignore_names|'
valid_homes='|basedir_regex|path|home_name|'
valid_volume='|'
valid_volume=$valid_volume'mac_charset|unix_charset|vol_charset|casefold|chmod_request|force_xattr_with_sticky_bit|'
valid_volume=$valid_volume'ignored_attributes|login_message|vol_dbpath|path|server_name|vol_size_limit|valid_users|'
valid_volume=$valid_volume'invalid_users|hosts_allow|hosts_deny|ea|password|file_perm|directory_perm|umask|preexec|'
valid_volume=$valid_volume'postexec|root_preexec|root_postexec|rolist|rwlist|veto_files|acls|case_sensitive|prodos|'
valid_volume=$valid_volume'read_only|time_machine|vol_dbnest|cnid_scheme|volume_name|'
valid_share='share_name'
NL=$'\n'
generate_config() {
# Save name of sections
config_name=''
global_name=''
homes_name=''
volume_names=''
# Volume name validation
share_names=''
fixed_names=''
# Call-back per section
config_cb() {
section_type="$1"
section_name="$2"
# Call-back per option
option_cb() {
local name="$1"
local value="$2"
# Validate options against dictionary of possible values
if [ "$section_type" = 'setup' -a "$CONFIG_SECTION" = "$config_name" ]; then
if [ "$name" = 'config_overwrite' ]; then
if [ "$value" = "0" -o "$value" = "1" ]; then
config_overwrite=$value
else
# Garbage on this option means we should not proceed no matter what
logger -p err -t $log_tag "Invalid SETUP config_overwrite option: $value"
setup_error=1
fi
elif [ "$name" = 'config_file' ]; then
config_file="$value"
else
config_error=1 && logger -p err -t $log_tag "Invalid SETUP configuration option: $name:$value"
fi
elif [ "$section_type" = 'global' -a "$CONFIG_SECTION" = "$global_name" ]; then
case "$valid_global" in
*'|'$name'|'*) afpd_config=$afpd_config"${name//_/ } = $value$NL" ;;
*) config_error=1 && logger -p err -t $log_tag "Invalid GLOBAL configuration option: $name:$value" ;;
esac
elif [ "$section_type" = 'homes' -a "$CONFIG_SECTION" = "$homes_name" ]; then
case "$valid_homes" in
*'|'$name'|'*) afpd_config=$afpd_config"${name//_/ } = $value$NL" ;;
*) config_error=1 && logger -p err -t $log_tag "Invalid HOMES configuration option: $name:$value" ;;
esac
elif [ "$section_type" = 'volume' ]; then
if [ "$name" = "$valid_share" ]; then
# Special case - share name... check for duplicates... track changes... fix heading.
case "||$share_names" in
*'||'$value'||'*) config_error=1 && logger -p err -t $log_tag "Duplicated share name $CONFIG_SECTION-$name:$value" ;;
*) ;;
esac
share_names=$share_names"$value||"
fixed_names=$fixed_names"$CONFIG_SECTION "
afpd_config="${afpd_config//\[\[$CONFIG_SECTION\]\]/[$value]}"
else
case "$valid_volume" in
*'|'$name'|'*) afpd_config=$afpd_config"${name//_/ } = $value$NL" ;;
*) config_error=1 && logger -p err -t $log_tag "Invalid VOLUME $CONFIG_SECTION configuration option: $name:$value" ;;
esac
fi
else
config_error=1 && logger -p err -t $log_tag "Invalid option. Section: $CONFIG_SECTION ($section_type), option: $name:$value"
fi
}
# Call-back per list - error, we don't use lists
list_cb() {
config_error=1 && logger -p err -t $log_tag "Invalid list in $CONFIG_SECTION: $1:$2"
}
# Identify sections and create section headers (placeholder for volumes)
if [ "$section_type" = 'setup' ]; then
# Find the name of the first (and only?) setup (control) section
if [ -z "$config_name" ]; then
config_name=$section_name
else
config_error=1 && logger -p err -t $log_tag 'Multiple SETUP sections defined'
fi
elif [ "$section_type" = 'global' ]; then
# Find the name of the first (and only?) global section
if [ -z "$global_name" ]; then
global_name=$section_name
[ -z "$afpd_config" ] || afpd_config=$afpd_config"$NL"
afpd_config=$afpd_config"[Global]$NL"
else
config_error=1 && logger -p err -t $log_tag 'Multiple GLOBAL sections defined'
fi
elif [ "$section_type" = 'homes' ]; then
# Find the name of the first (and only?) homes section
if [ -z "$homes_name" ]; then
homes_name=$section_name
[ -z "$afpd_config" ] || afpd_config=$afpd_config"$NL"
afpd_config=$afpd_config"[Homes]$NL"
else
config_error=1 && logger -p err -t $log_tag 'Multiple HOMES sections defined'
fi
elif [ "$section_type" = 'volume' ]; then
# Collect the names of the volume sections
volume_names=$volume_names"$section_name "
[ -z "$afpd_config" ] || afpd_config=$afpd_config"$NL"
afpd_config=$afpd_config"[[$section_name]]$NL"
elif [ "$section_type" != '' ]; then
# It's not the end of file
config_error=1 && logger -p err -t $log_tag "Invalid $section_type section defined"
fi
}
# Load config (trigger callbacks)
config_load afpd
# config_overwrite is messed up... don't know what to do
if [ "$setup_error" -eq 1 ]; then
exit 1
fi
# So, should we? Shouldn't? Nobody said but gave us share details.
[ -z "$config_overwrite" ] && [ -n "$volume_names" -o -n "$homes_name" ] && {
logger -p warn -t $log_tag "No valid config_overwrite at SETUP config. Ignoring defined VOLUMES and/or HOMES"
}
# Only update configuration file if UCI config asks for it
build_config=$(expr "${config_overwrite}" == "1")
if [ "$build_config" -eq 1 ]; then
# One last check for valid volume names
[ "$volume_names" = "$fixed_names" ] || {
config_error=1 && logger -p err -t $log_tag "Not all volumes have valid option $valid_share"
}
# Continue only if configuration was decent - any errors were logged already
if [ "$config_error" -eq 1 ]; then
exit 1
fi
# Create file
mkdir -p `dirname "$config_file"`
echo "$afpd_config" > "$config_file"
logger -p info -t $log_tag "Configuration written to $config_file"
else
logger -p info -t $log_tag 'Configuration not modified - setup:config_overwrite=0 or missing'
fi
}
start_service() {
mkdir -p /var/netatalk/CNID/
generate_config
procd_open_instance
procd_set_param command $PROG_netatalk -d -F $config_file
procd_set_param file $config_file
procd_set_param respawn
procd_close_instance
}
|