diff --git a/enterprise_gateway/services/kernels/remotemanager.py b/enterprise_gateway/services/kernels/remotemanager.py index 36df28466..2c3899375 100644 --- a/enterprise_gateway/services/kernels/remotemanager.py +++ b/enterprise_gateway/services/kernels/remotemanager.py @@ -6,7 +6,8 @@ import signal import re import uuid - +from pwd import getpwnam +import grp from tornado import web from ipython_genutils.py3compat import unicode_type from ipython_genutils.importstring import import_item @@ -19,6 +20,7 @@ from enterprise_gateway.mixins import EnterpriseGatewayConfigMixin + def get_process_proxy_config(kernelspec): """ Return the process-proxy stanza from the kernelspec. @@ -147,7 +149,7 @@ async def start_kernel(self, *args, **kwargs): username = KernelSessionManager.get_kernel_username(**kwargs) self.log.debug("RemoteMappingKernelManager.start_kernel: {kernel_name}, kernel_username: {username}". format(kernel_name=kwargs['kernel_name'], username=username)) - + self.connection_dir=os.path.join(os.path.expanduser('~'+username),".local/share/jupyter/runtime/") # Check max kernel limits self._enforce_kernel_limits(username) @@ -571,8 +573,17 @@ def write_connection_file(self): self.hb_port = ports[3] self.control_port = ports[4] - return super(RemoteKernelManager, self).write_connection_file() + cf = super(RemoteKernelManager, self).write_connection_file() + username=self.user_overrides.get('KERNEL_USERNAME',None) + if username: + uid=getpwnam(username).pw_uid + guid=grp.getgrnam(username).gr_gid + os.chown(self.connection_file,uid,guid) + self.log.debug(f"Local connection file chowned:{self.connection_file} to {username}") + else: + raise RuntimeError("Unrecognized user") + return cf def _get_process_proxy(self): """ Reads the associated kernelspec and to see if has a process proxy stanza. diff --git a/enterprise_gateway/services/processproxies/processproxy.py b/enterprise_gateway/services/processproxies/processproxy.py index 06c44a13e..5d594d8c0 100644 --- a/enterprise_gateway/services/processproxies/processproxy.py +++ b/enterprise_gateway/services/processproxies/processproxy.py @@ -36,7 +36,7 @@ from zmq.ssh import tunnel from ..sessions.kernelsessionmanager import KernelSessionManager - +from jupyterhub.spawner import set_user_setuid # Default logging level of paramiko produces too much noise - raise to warning only. logging.getLogger('paramiko').setLevel(os.getenv('EG_SSH_LOG_LEVEL', logging.WARNING)) @@ -911,7 +911,18 @@ def __init__(self, kernel_manager, proxy_config): async def launch_process(self, kernel_cmd, **kwargs): await super(LocalProcessProxy, self).launch_process(kernel_cmd, **kwargs) - + user=kwargs["env"].get("KERNEL_USERNAME",None) + self.log.info(f"KARGS {kwargs}") + + if user: + kwargs["preexec_fn"]=set_user_setuid(user,chdir=False) + else: + raise RuntimeError("Trying to run as root on host, unrecognized user") + # launch the local run.sh + working_dir=kwargs["env"].get("KERNEL_WORKING_DIR",None) + if working_dir: + kwargs["cwd"]=working_dir + # launch the local run.sh self.local_proc = self.launch_kernel(kernel_cmd, **kwargs) self.pid = self.local_proc.pid