scope: refuse `&x` where x is a local variable
[nit.git] / lib / privileges / privileges.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Process privileges management utilities
18 #
19 # Used mainly by daemons and such to aquire resources as su and
20 # then drop back to a restricted user.
21 module privileges
22
23 import opts
24 import posix
25
26 redef class Text
27 # Does the operating system know the user named `self`?
28 fun user_exists: Bool
29 do
30 var passwd = new Passwd.from_name(to_s)
31 return not passwd.address_is_null
32 end
33
34 # Does the operating system know the group named `self`?
35 fun group_exists: Bool
36 do
37 var passwd = new Group.from_name(to_s)
38 return not passwd.address_is_null
39 end
40 end
41
42 # Class to manage user groups
43 class UserGroup
44
45 # User name
46 var user: String
47
48 # Group name
49 var group: nullable String
50
51 # Drop privileges of the running program to those of `self`
52 #
53 # require: `user.user_exists and (group == null or group.group_exists)`
54 fun drop_privileges
55 do
56 var passwd = new Passwd.from_name(user)
57 assert not passwd.address_is_null
58 var uid = passwd.uid
59
60 var group = group
61 var gid
62 if group != null then
63 var gpasswd = new Group.from_name(group)
64 assert not gpasswd.address_is_null
65 gid = gpasswd.gid
66 else gid = passwd.gid
67
68 sys.gid = gid
69 sys.uid = uid
70 end
71 end
72
73 # Option to ask for a username and group
74 class OptionUserAndGroup
75 super OptionParameter
76
77 redef type VALUE: nullable UserGroup
78
79 # Create an `OptionUserAndGroup` for dropping privileges
80 init for_dropping_privileges
81 do
82 init("Drop privileges to user:group or simply user", null, ["-u", "--usergroup"])
83 end
84
85 redef fun convert(str)
86 do
87 var words = str.split(":")
88 if words.length == 1 then
89 return new UserGroup(str, null)
90 else if words.length == 2 then
91 return new UserGroup(words[0], words[1])
92 else
93 errors.add("Option {names.join(", ")} expected parameter in the format \"user:group\" or simply \"user\".\n")
94 return null
95 end
96 end
97 end