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 """Script to ensure permissions on files/dirs are accurate.
31
32 """
33
34 import os
35 import os.path
36 import optparse
37 import sys
38 import logging
39
40 from ganeti import constants
41 from ganeti import errors
42 from ganeti import runtime
43 from ganeti import ssconf
44 from ganeti import utils
45 from ganeti import cli
46 from ganeti import pathutils
47 from ganeti import compat
48
49
50 (DIR,
51 FILE,
52 QUEUE_DIR) = range(1, 4)
53
54 ALL_TYPES = compat.UniqueFrozenset([
55 DIR,
56 FILE,
57 QUEUE_DIR,
58 ])
59
60
62 """Ensures permissions recursively down a directory.
63
64 This functions walks the path and sets permissions accordingly.
65
66 @param path: The absolute path to walk
67 @param uid: The uid used as owner
68 @param gid: The gid used as group
69 @param dir_perm: The permission bits set for directories
70 @param file_perm: The permission bits set for files
71
72 """
73 assert os.path.isabs(path), "Path %s is not absolute" % path
74 assert os.path.isdir(path), "Path %s is not a dir" % path
75
76 logging.debug("Recursively processing %s", path)
77
78 for root, dirs, files in os.walk(path):
79 for subdir in dirs:
80 utils.EnforcePermission(os.path.join(root, subdir), dir_perm, uid=uid,
81 gid=gid)
82
83 for filename in files:
84 utils.EnforcePermission(os.path.join(root, filename), file_perm, uid=uid,
85 gid=gid)
86
87
89 """Sets the correct permissions on all job files in the queue.
90
91 @param path: Directory path
92 @param mode: Wanted file mode
93 @param uid: Wanted user ID
94 @param gid: Wanted group ID
95
96 """
97 for filename in utils.ListVisibleFiles(path):
98 if constants.JOB_FILE_RE.match(filename):
99 utils.EnforcePermission(utils.PathJoin(path, filename), mode, uid=uid,
100 gid=gid)
101
102
104 """Processes a path component.
105
106 @param path: A tuple of the path component to process
107
108 """
109 (pathname, pathtype, mode, uid, gid) = path[0:5]
110
111 assert pathtype in ALL_TYPES
112
113 if pathtype in (DIR, QUEUE_DIR):
114
115 assert len(path) == 5
116 if pathtype == DIR:
117 utils.MakeDirWithPerm(pathname, mode, uid, gid)
118 elif pathtype == QUEUE_DIR:
119 EnsureQueueDir(pathname, mode, uid, gid)
120 elif pathtype == FILE:
121 (must_exist, ) = path[5:]
122 utils.EnforcePermission(pathname, mode, uid=uid, gid=gid,
123 must_exist=must_exist)
124
125
127 """Returns a tuple of path objects to process.
128
129 """
130 getent = runtime.GetEnts()
131 masterd_log = constants.DAEMONS_LOGFILES[constants.MASTERD]
132 noded_log = constants.DAEMONS_LOGFILES[constants.NODED]
133 confd_log = constants.DAEMONS_LOGFILES[constants.CONFD]
134 luxid_log = constants.DAEMONS_LOGFILES[constants.LUXID]
135 rapi_log = constants.DAEMONS_LOGFILES[constants.RAPI]
136 mond_log = constants.DAEMONS_LOGFILES[constants.MOND]
137
138 rapi_dir = os.path.join(pathutils.DATA_DIR, "rapi")
139 cleaner_log_dir = os.path.join(pathutils.LOG_DIR, "cleaner")
140 master_cleaner_log_dir = os.path.join(pathutils.LOG_DIR, "master-cleaner")
141
142
143
144
145 paths = [
146 (pathutils.DATA_DIR, DIR, 0755, getent.masterd_uid, getent.masterd_gid),
147 (pathutils.CLUSTER_DOMAIN_SECRET_FILE, FILE, 0640,
148 getent.masterd_uid, getent.masterd_gid, False),
149 (pathutils.CLUSTER_CONF_FILE, FILE, 0640,
150 getent.masterd_uid, getent.confd_gid, False),
151 (pathutils.CONFD_HMAC_KEY, FILE, 0440,
152 getent.confd_uid, getent.masterd_gid, False),
153 (pathutils.SSH_KNOWN_HOSTS_FILE, FILE, 0644,
154 getent.masterd_uid, getent.masterd_gid, False),
155 (pathutils.RAPI_CERT_FILE, FILE, 0440,
156 getent.rapi_uid, getent.masterd_gid, False),
157 (pathutils.SPICE_CERT_FILE, FILE, 0440,
158 getent.noded_uid, getent.masterd_gid, False),
159 (pathutils.SPICE_CACERT_FILE, FILE, 0440,
160 getent.noded_uid, getent.masterd_gid, False),
161 (pathutils.NODED_CERT_FILE, FILE, pathutils.NODED_CERT_MODE,
162 getent.masterd_uid, getent.masterd_gid, False),
163 (pathutils.NODED_CLIENT_CERT_FILE, FILE, pathutils.NODED_CERT_MODE,
164 getent.masterd_uid, getent.masterd_gid, False),
165 (pathutils.WATCHER_PAUSEFILE, FILE, 0644,
166 getent.masterd_uid, getent.masterd_gid, False),
167 ]
168
169 ss = ssconf.SimpleStore()
170 for ss_path in ss.GetFileList():
171 paths.append((ss_path, FILE, constants.SS_FILE_PERMS,
172 getent.noded_uid, getent.noded_gid, False))
173
174 paths.extend([
175 (pathutils.QUEUE_DIR, DIR, 0750, getent.masterd_uid, getent.daemons_gid),
176 (pathutils.QUEUE_DIR, QUEUE_DIR, constants.JOB_QUEUE_FILES_PERMS,
177 getent.masterd_uid, getent.daemons_gid),
178 (pathutils.JOB_QUEUE_DRAIN_FILE, FILE, 0644,
179 getent.masterd_uid, getent.daemons_gid, False),
180 (pathutils.JOB_QUEUE_LOCK_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS,
181 getent.masterd_uid, getent.daemons_gid, False),
182 (pathutils.JOB_QUEUE_SERIAL_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS,
183 getent.masterd_uid, getent.daemons_gid, False),
184 (pathutils.JOB_QUEUE_VERSION_FILE, FILE, constants.JOB_QUEUE_FILES_PERMS,
185 getent.masterd_uid, getent.daemons_gid, False),
186 (pathutils.JOB_QUEUE_ARCHIVE_DIR, DIR, 0750,
187 getent.masterd_uid, getent.daemons_gid),
188 (rapi_dir, DIR, 0750, getent.rapi_uid, getent.masterd_gid),
189 (pathutils.RAPI_USERS_FILE, FILE, 0640,
190 getent.rapi_uid, getent.masterd_gid, False),
191 (pathutils.RUN_DIR, DIR, 0775, getent.masterd_uid, getent.daemons_gid),
192 (pathutils.SOCKET_DIR, DIR, 0770, getent.masterd_uid, getent.daemons_gid),
193 (pathutils.MASTER_SOCKET, FILE, 0660,
194 getent.masterd_uid, getent.daemons_gid, False),
195 (pathutils.QUERY_SOCKET, FILE, 0660,
196 getent.luxid_uid, getent.daemons_gid, False),
197 (pathutils.BDEV_CACHE_DIR, DIR, 0755,
198 getent.noded_uid, getent.masterd_gid),
199 (pathutils.UIDPOOL_LOCKDIR, DIR, 0750,
200 getent.noded_uid, getent.masterd_gid),
201 (pathutils.DISK_LINKS_DIR, DIR, 0755,
202 getent.noded_uid, getent.masterd_gid),
203 (pathutils.CRYPTO_KEYS_DIR, DIR, 0700,
204 getent.noded_uid, getent.masterd_gid),
205 (pathutils.IMPORT_EXPORT_DIR, DIR, 0755,
206 getent.noded_uid, getent.masterd_gid),
207 (pathutils.LOG_DIR, DIR, 0770, getent.masterd_uid, getent.daemons_gid),
208 (masterd_log, FILE, 0600, getent.masterd_uid, getent.masterd_gid, False),
209 (confd_log, FILE, 0600, getent.confd_uid, getent.masterd_gid, False),
210 (luxid_log, FILE, 0600, getent.luxid_uid, getent.masterd_gid, False),
211 (noded_log, FILE, 0600, getent.noded_uid, getent.masterd_gid, False),
212 (rapi_log, FILE, 0600, getent.rapi_uid, getent.masterd_gid, False),
213 (mond_log, FILE, 0600, getent.mond_uid, getent.masterd_gid, False),
214 (pathutils.LOG_OS_DIR, DIR, 0750, getent.noded_uid, getent.daemons_gid),
215 (pathutils.LOG_XEN_DIR, DIR, 0750, getent.noded_uid, getent.daemons_gid),
216 (cleaner_log_dir, DIR, 0750, getent.noded_uid, getent.noded_gid),
217 (master_cleaner_log_dir, DIR, 0750, getent.masterd_uid, getent.masterd_gid),
218 (pathutils.INSTANCE_REASON_DIR, DIR, 0755, getent.noded_uid,
219 getent.noded_gid),
220 ])
221
222 return paths
223
224
226 """Parses the options passed to the program.
227
228 @return: Options and arguments
229
230 """
231 program = os.path.basename(sys.argv[0])
232
233 parser = optparse.OptionParser(usage="%prog [--full-run]",
234 prog=program)
235 parser.add_option(cli.DEBUG_OPT)
236 parser.add_option(cli.VERBOSE_OPT)
237 parser.add_option("--full-run", "-f", dest="full_run", action="store_true",
238 default=False, help=("Make a full run and set permissions"
239 " on archived jobs (time consuming)"))
240
241 return parser.parse_args()
242
243
245 """Main routine.
246
247 """
248 (opts, args) = ParseOptions()
249
250 utils.SetupToolLogging(opts.debug, opts.verbose)
251
252 if args:
253 logging.error("No arguments are expected")
254 return constants.EXIT_FAILURE
255
256 if opts.full_run:
257 logging.info("Running in full mode")
258
259 getent = runtime.GetEnts()
260
261 try:
262 for path in GetPaths():
263 ProcessPath(path)
264
265 if opts.full_run:
266 RecursiveEnsure(pathutils.JOB_QUEUE_ARCHIVE_DIR, getent.masterd_uid,
267 getent.daemons_gid, 0750, constants.JOB_QUEUE_FILES_PERMS)
268 except errors.GenericError, err:
269 logging.error("An error occurred while setting permissions: %s", err)
270 return constants.EXIT_FAILURE
271
272 return constants.EXIT_SUCCESS
273