lol

nixos/taskserver: Enable cfg.group to read clients' certificates

This enables the services.taskserver.group to read the certificates
generated by the taskserver.service' preStart script.

+27 -7
+27 -7
nixos/modules/services/misc/taskserver/helper-tool.py
··· 61 61 os.setuid(uid) 62 62 63 63 64 + def run_as_taskd_group(): 65 + gid = grp.getgrnam(TASKD_GROUP).gr_gid 66 + os.setgid(gid) 67 + 64 68 def taskd_cmd(cmd, *args, **kwargs): 65 69 """ 66 70 Invoke taskd with the specified command with the privileges of the 'taskd' ··· 90 94 """ 91 95 return subprocess.check_output( 92 96 [CERTTOOL_COMMAND] + list(args), 93 - preexec_fn=lambda: os.umask(0o077), 97 + preexec_fn=run_as_taskd_group, 94 98 stderr=subprocess.STDOUT, 95 99 **kwargs 96 100 ) ··· 156 160 sys.stderr.write(msg.format(user)) 157 161 return 158 162 159 - basedir = os.path.join(TASKD_DATA_DIR, "keys", org, user) 160 - if os.path.exists(basedir): 163 + keysdir = os.path.join(TASKD_DATA_DIR, "keys" ) 164 + orgdir = os.path.join(keysdir , org ) 165 + userdir = os.path.join(orgdir , user ) 166 + if os.path.exists(userdir): 161 167 raise OSError("Keyfile directory for {} already exists.".format(user)) 162 168 163 - privkey = os.path.join(basedir, "private.key") 164 - pubcert = os.path.join(basedir, "public.cert") 169 + privkey = os.path.join(userdir, "private.key") 170 + pubcert = os.path.join(userdir, "public.cert") 165 171 166 172 try: 167 - os.makedirs(basedir, mode=0o700) 173 + # We change the permissions and the owner ship of the base directories 174 + # so that cfg.group and cfg.user could read the directories' contents. 175 + # See also: https://bugs.python.org/issue42367 176 + for bd in [keysdir, orgdir, userdir]: 177 + # Allow cfg.group, but not others to read the contents of this group 178 + os.makedirs(bd, exist_ok=True) 179 + # not using mode= argument to makedirs intentionally - forcing the 180 + # permissions we want 181 + os.chmod(bd, mode=0o750) 182 + os.chown( 183 + bd, 184 + uid=pwd.getpwnam(TASKD_USER).pw_uid, 185 + gid=grp.getgrnam(TASKD_GROUP).gr_gid, 186 + ) 168 187 169 188 certtool_cmd("-p", "--bits", CERT_BITS, "--outfile", privkey) 189 + os.chmod(privkey, 0o640) 170 190 171 191 template_data = [ 172 192 "organization = {0}".format(org), ··· 187 207 "--outfile", pubcert 188 208 ) 189 209 except: 190 - rmtree(basedir) 210 + rmtree(userdir) 191 211 raise 192 212 193 213