1please.ini(5) User Manual please.ini(5)
2
3
4
6 please.ini - configuration file for access
7
9 The please.ini file contains one or more [sections] that hold ACL for
10 users of the please and pleaseedit programs.
11
12 please.ini is an ini file, sections can be named with a short descrip‐
13 tion of what the section provides. You may then find this helpful when
14 listing rights with please -l.
15
16 Rules are read and applied in the order they are presented in the con‐
17 figuration file. For example, if the user matches a permit rule to run
18 a command in an early section, but in a later section matches criteria
19 for a deny and no further matches, then the user will not be permitted
20 to run that command. The last match wins.
21
22 The properties permitted are described below and should appear at most
23 once per section. If a property is used more than once in a section,
24 the last one will be used.
25
27 [section-name]
28 section name, shown in list mode
29
30 include=[file]
31 read ini file, and continue to next section
32
33 includedir=[directory]
34 read .ini files in directory, and continue to next section, if
35 the directory does not exist config parse will fail
36
37 Sections with a name starting `default' will retain match actions
38
40 name=[regex]
41 mandatory, the user or group (see below) to match against
42
43 target=[regex]
44 user to execute or list as, defaults to root
45
46 target_group=[regex]
47 requires that the user runs with --group to run or edit with the
48 match
49
50 rule=[regex]
51 the regular expression that the command or edit path matches
52 against, defaults to ^$
53
54 notbefore=[YYYYmmdd|YYYYmmddHHMMSS]
55 will add HHMMSS as 00:00:00 to the date if not given, defaults
56 to never
57
58 notafter=[YYYYmmdd|YYYYmmddHHMMSS]
59 will add 23:59:59 to the date if not given, defaults to never
60
61 datematch=[Day dd Mon HH:MM:SS UTC YYYY]
62 regex to match a date string with
63
64 type=[edit/run/list]
65 this section’s mode behaviour, defaults to run, edit = pleaseed‐
66 it entry, list = user access rights listing
67
68 group=[true|false]
69 defaults to false, when true, the name (above) refers to a group
70 rather than a user
71
72 hostname=[regex]
73 permitted hostnames where this may apply. A hostname defined as
74 any or localhost will always match. Defaults to localhost
75
76 dir=[regex]
77 permitted directories to run within
78
79 permit_env=[regex]
80 allow environments that match regex to optionally pass through
81
82 regex is a regular expression, %{USER} will expand to the user who is
83 currently running please, %{HOSTNAME} expands to the hostname. See be‐
84 low for examples. Other %{} expansions may be added at a later date.
85
86 Spaces within arguments will be substituted as `\ ' (backslash space).
87 Use ^/bin/echo hello\\ world$ to match /bin/echo “hello world”, note
88 that \ is a regex escape character so it must be escaped, therefore
89 matching a space becomes `\\ ' (backslash backslash space).
90
91 To match a \ (backslash), the hex code \x5c can be used.
92
93 To match the string %{USER}, the sequence \x25\{USER\} can be used.
94
95 Rules starting exact are string matches and not regex processed and
96 take precedence over regex matches.
97
98 exact_name=[string]
99 only permit a user/group name that matches exactly
100
101 exact_hostname=[string]
102 only permit a hostname that matches exactly
103
104 exact_target=[string]
105 only permit a target that matches exactly
106
107 exact_target_group=[groupname]
108 requires that the user runs with --group to run or edit as
109 groupname
110
111 exact_rule=[string]
112 only permit a command rule that matches exactly
113
114 exact_dir=[string]
115 only permit a dir that matches exactly
116
118 permit=[true|false]
119 permit or disallow the entry, defaults to true
120
121 require_pass=[true|false]
122 if entry matches, require a password, defaults to true
123
124 timeout=[number]
125 length of timeout in whole seconds to wait for password input
126
127 last=[true|false]
128 if true, stop processing when entry is matched, defaults to
129 false
130
131 reason=[true|false|regex]
132 require a reason for execution/edit. If reason is true then any
133 reason will satisfy. Any string other than true or false will
134 be treated as a regex match. Defaults to false
135
136 syslog=[true|false]
137 log this activity to syslog, defaults to true
138
139 env_assign.[key]=[value]
140 assign value to environment key
141
142 editmode=[octal mode|keep]
143 (type=edit) set the file mode bits on replacement file to octal
144 mode. When set to keep use the existing file mode. If the file
145 is not present, or mode is not declared, then mode falls back to
146 0600. If there is a file present, then the mode is read and
147 used just prior to file rename
148
149 exitcmd=[program]
150 (type=edit) run program after editor exits as the target user,
151 if exit is zero, continue with file replacement. %{NEW} and
152 %{OLD} placeholders expand to new and old edit files
153
155 To allow all commands, you can use a greedy match (^.*$). You should
156 reduce this to the set of acceptable commands though.
157
158 [user_jim_root]
159 name = jim
160 target = root
161 rule = ^.*$
162
163 If you wish to permit a user to view another’s command set, then you
164 may do this using type=list (run by default). To list another user,
165 they must match the target regex.
166
167 [user_jim_list_root]
168 name = jim
169 type = list
170 target = root
171
172 type may also be edit if you wish to permit a file edit with pleaseed‐
173 it.
174
175 [user_jim_edit_hosts]
176 name = jim
177 type = edit
178 target = root
179 rule = ^/etc/hosts$
180 editmode = 644
181
182 Naming sections should help later when listing permissions.
183
184 Below, user mandy may run du without needing a password, but must enter
185 her password for a bash running as root:
186
187 [mandy_du]
188 name = mandy
189 rule = ^(/usr)?/bin/du .*$
190 require_pass = false
191 [mandy_some]
192 name = mandy
193 rule = ^(/usr)?/bin/bash$
194 require_pass = true
195
196 The rule regex can include repetitions. To permit running wc to count
197 the lines in the log files (we don’t know how many there are) in
198 /var/log. This sort of regex will allow multiple instances of a ()
199 group with +, which is used to define the character class [a-zA-
200 Z0-9-]+, the numeric class and the group near the end of the line. In
201 other words, multiple instances of files in /var/log that may end in
202 common log rotate forms -YYYYMMDD or .N.
203
204 This will permit commands such as the following, note how for efficien‐
205 cy find will combine arguments with + into fewer invocations. xargs
206 could have been used in place of find.
207
208 $ find /var/log -type f -exec please /usr/bin/wc {} \+
209
210 Here is a sample for the above scenario:
211
212 [user_jim_root_wc]
213 name = jim
214 target = root
215 permit = true
216 rule = ^/usr/bin/wc (/var/log/[a-zA-Z0-9-]+(\.\d+)?(\s)?)+$
217
218 User jim may only start or stop a docker container:
219
220 [user_jim_root_docker]
221 name = jim
222 target = root
223 permit = true
224 rule = ^/usr/bin/docker (start|stop) \S+
225
226 User ben may only edit /etc/fstab, and afterwards check the fstab file:
227
228 [ben_fstab]
229 name = ben
230 target = root
231 permit = true
232 type = edit
233 editmode = 644
234 rule = ^/etc/fstab$
235 exitcmd = /bin/findmnt --verify --tab-file %{NEW}
236
237 User ben may list only users eng, net and dba:
238
239 [ben_ops]
240 name = ben
241 permit = true
242 type = list
243 target = ^(eng|net|dba)ops$
244
245 All users may list their own permissions. You may or may not wish to
246 do this if you consider permitting a view of the rules to be a security
247 risk.
248
249 [list_own]
250 name = ^%{USER}$
251 permit = true
252 type = list
253 target = ^%{USER}$
254
256 When the user completes their edit, and the editor exits cleanly, if
257 exitcmd is included then this program will run as the target user. If
258 the program also exits cleanly then the temporary edit will be copied
259 to the destination.
260
261 %{OLD} and %{NEW} will expand to the old (existing source) file and ed‐
262 it candidate, respectively. To verify a file edit, ben’s entry to
263 check /etc/hosts after clean exit could look like this:
264
265 [ben_ops]
266 name = ben
267 permit = true
268 type = edit
269 editmode = 644
270 rule = ^/etc/hosts$
271 exitcmd = /usr/local/bin/check_hosts %{OLD} %{NEW}
272
273 /usr/local/bin/check_hosts takes two arguments, the original file as
274 the first argument and the modify candidate as the second argument. If
275 check_hosts terminates zero, then the edit is considered clean and the
276 original file is replaced with the candidate. Otherwise the edit file
277 is not copied and is left, pleaseedit will exit with the return value
278 from check_hosts.
279
280 A common exitcmd is to check the validity of please.ini, shown below.
281 This permits members of the admin group to edit /etc/please.ini if they
282 provide a reason (-r). Upon clean exit from the editor the tmp file
283 will be syntax checked.
284
285 [please_ini]
286 name = admins
287 group = true
288 reason = true
289 rule = /etc/please.ini
290 type = edit
291 editmode = 600
292 exitcmd = /usr/bin/please -c %{NEW}
293
295 For large environments it is not unusual for a third party to require
296 access during a short time frame for debugging. To accommodate this
297 there are the notbefore and notafter time brackets. These can be ei‐
298 ther YYYYmmdd or YYYYmmddHHMMSS.
299
300 The whole day is considered when using the shorter date form of YYYYm‐
301 mdd.
302
303 Many enterprises may wish to permit periods of access to a user for a
304 limited time only, even if that individual is considered to have a per‐
305 manent role.
306
307 User joker can do what they want as root on 1st April 2021:
308
309 [joker_april_first]
310 name = joker
311 target = root
312 permit = true
313 notbefore = 20210401
314 notafter = 20210401
315 rule = ^/bin/bash
316
318 datematch matches against the date string Day dd mon HH:MM:SS UTC Year.
319 This enables calendar style date matches.
320
321 Note that the day of the month (dd) will be padded with spaces if less
322 than two characters wide.
323
324 You can permit a group of users to run /usr/local/housekeeping/ scripts
325 every Monday:
326
327 [l2_housekeeping]
328 name = l2users
329 group = true
330 target = root
331 permit = true
332 rule = /usr/local/housekeeping/tidy_(logs|images|mail)
333 datematch = ^Mon\s+.*
334
336 When reason=true, a user must pass a reason with the -r option to
337 please and pleaseedit. Some organisations may prefer a reason to be
338 logged when a command is executed. This can be helpful for some situa‐
339 tions where something such as mkfs or useradd might be preferable to be
340 logged against a ticket.
341
342 [l2_user_admin]
343 name = l2users
344 group = true
345 target = root
346 permit = true
347 reason = true
348 rule = ^/usr/sbin/useradd -m \w+$
349
350 Or, if tickets have a known prefix:
351
352 reason = .*(bug|incident|ticket|change)\d+.*
353
354 Perhaps you want to add a mini molly-guard where the hostname must ap‐
355 pear in the reason:
356
357 [user_poweroff]
358 name = l2users
359 group = true
360 rule = (/usr)?/s?bin/(shutdown( -h now)?|poweroff|reboot)
361 require_pass = true
362 reason = .*%{HOSTNAME}.*
363
365 In some situations you may only want a command to run within a set of
366 directories. The directory is specified with the -d argument to
367 please. For example, a program may output to the current working di‐
368 rectory, which may only be desirable in certain locations.
369
370 [eng_build_aliases]
371 name = l2users
372 group = true
373 dir = ^/etc/mail$
374 rule = ^/usr/local/bin/build_aliases$
375
377 last = true stops processing at a match:
378
379 [mkfs]
380 name = l2users
381 group = true
382 target = root
383 permit = true
384 reason = true
385 rule = ^/sbin/mkfs.(ext[234]|xfs) /dev/sd[bcdefg]\d?$
386 last = true
387
388 For simplicity, there is no need to process other configured rules if
389 certain that the l2users group are safe to execute this. last should
390 only be used in situations where there will never be something that
391 could contradict the match in an undesired way later.
392
394 By default entries are logged to syslog. If you do not wish an entry
395 to be logged then specify syslog=false. In this case jim can run any‐
396 thing in /usr/bin/ as root and it will not be logged.
397
398 [maverick]
399 syslog = false
400 name = jim
401 rule = /usr/bin/.*
402 reason = false
403
405 /etc/please.ini
406
408 At a later date repeated properties within the same section may be
409 treated as a match list.
410
412 I welcome pull requests with open arms. New features always consid‐
413 ered.
414
416 Found a bug? Please either open a ticket or send a pull request/patch.
417
419 please(1)
420
422 Ed Neville (ed-please@s5h.net).
423
424
425
426please 0.5.3 10 June 2022 please.ini(5)