def xpra_group() -> int: if POSIX: try: groups = os.getgroups() group_id = get_group_id(MMAP_GROUP) log("xpra_group() group(%s)=%s, groups=%s", MMAP_GROUP, group_id, groups) if group_id and group_id in groups: return group_id except Exception: log("xpra_group()", exc_info=True) return 0
def xpra_group(): if POSIX: try: username = os.getgroups() groups = get_groups(username) if MMAP_GROUP in groups: group_id = get_group_id(MMAP_GROUP) if group_id >= 0: return group_id except Exception: log("xpra_group()", exc_info=True) return 0
def create_unix_domain_socket(sockpath, socket_permissions=0o600): #convert this to a umask! umask = 0o777 - socket_permissions listener = socket.socket(socket.AF_UNIX) listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #bind the socket, using umask to set the correct permissions orig_umask = os.umask(umask) try: listener.bind(sockpath) finally: os.umask(orig_umask) try: inode = os.stat(sockpath).st_ino except: inode = -1 #set to the "xpra" group if we are a member of it, or if running as root: uid = getuid() username = get_username_for_uid(uid) groups = get_groups(username) if uid == 0 or GROUP in groups: group_id = get_group_id(GROUP) if group_id >= 0: try: os.lchown(sockpath, -1, group_id) except Exception as e: log = get_network_logger() log.warn("Warning: failed to set '%s' group ownership", GROUP) log.warn(" on socket '%s':", sockpath) log.warn(" %s", e) #don't know why this doesn't work: #os.fchown(listener.fileno(), -1, group_id) def cleanup_socket(): log = get_network_logger() try: cur_inode = os.stat(sockpath).st_ino except: log.info("socket '%s' already deleted", sockpath) return delpath = sockpath log("cleanup_socket '%s', original inode=%s, new inode=%s", sockpath, inode, cur_inode) if cur_inode == inode: log.info("removing socket %s", delpath) try: os.unlink(delpath) except: pass return listener, cleanup_socket
def create_system_dir(self, sps): if not POSIX or OSX or not sps: return xpra_group_id = get_group_id(SOCKET_DIR_GROUP) if sps.startswith("/run/xpra") or sps.startswith("/var/run/xpra"): #create the directory and verify its permissions #which should have been set correctly by tmpfiles.d, #but may have been set wrong if created by systemd's socket activation instead d = sps.split("/xpra")[0] + "/xpra" try: if os.path.exists(d): stat = os.stat(d) mode = stat.st_mode if (mode & SOCKET_DIR_MODE) != SOCKET_DIR_MODE: log.warn("Warning: invalid permissions on '%s' : %s", d, oct(mode)) mode = mode | SOCKET_DIR_MODE log.warn(" changing to %s", oct(mode)) os.chmod(d, mode) if xpra_group_id >= 0 and stat.st_gid != xpra_group_id: import grp group = grp.getgrgid(stat.st_gid)[0] log.warn("Warning: invalid group on '%s': %s", d, group) log.warn(" changing to '%s'", SOCKET_DIR_GROUP) os.lchown(d, stat.st_uid, xpra_group_id) else: log.info( "creating '%s' with permissions %s and group '%s'", d, oct(SOCKET_DIR_MODE), SOCKET_DIR_GROUP) with umask_context(0): os.mkdir(d, SOCKET_DIR_MODE) stat = os.stat(d) if xpra_group_id >= 0 and stat.st_gid != xpra_group_id: os.lchown(d, stat.st_uid, xpra_group_id) mode = os.stat(d).st_mode log("%s permissions: %s", d, oct(mode)) except OSError as e: log("create_system_dir()", exc_info=True) log.error( "Error: failed to create or change the permissions on '%s':", d) log.error(" %s", e)
def check_peercred(self, connection, uids="", gids="", allow_owner=False): allow_uids = allow_gids = None if uids or allow_owner: allow_uids = [] if allow_owner: allow_uids.append(getuid()) for x in uids.split(":"): if not x.strip(): continue x = osexpand(x.strip()) try: allow_uids.append(int(x)) except ValueError: import pwd #pylint: disable=import-outside-toplevel try: pw = pwd.getpwnam(x) allow_uids.append(pw.pw_uid) except KeyError: log.warn("Warning: unknown username '%s'", x) log("peercred: allow_uids(%s)=%s", uids, allow_uids) if gids: allow_gids = [] for x in gids.split(":"): if not x.strip(): continue x = osexpand(x.strip()) try: allow_gids.append(int(x)) except ValueError: gid = get_group_id(x) if gid >= 0: allow_gids.append(gid) else: log.warn("Warning: unknown group '%s'", x) log("peercred: allow_gids(%s)=%s", gids, allow_gids) self.do_check_peercred(connection, allow_uids, allow_gids)
def create_unix_domain_socket(sockpath, mmap_group=False, socket_permissions="600"): if mmap_group: #when using the mmap group option, use '660' umask = 0o117 else: #parse octal mode given as config option: try: if type(socket_permissions) == int: sperms = socket_permissions else: #assume octal string: sperms = int(socket_permissions, 8) assert sperms >= 0 and sperms <= 0o777 except ValueError: raise ValueError( "invalid socket permissions (must be an octal number): '%s'" % socket_permissions) #now convert this to a umask! umask = 0o777 - sperms listener = socket.socket(socket.AF_UNIX) listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #bind the socket, using umask to set the correct permissions orig_umask = os.umask(umask) try: listener.bind(sockpath) finally: os.umask(orig_umask) try: inode = os.stat(sockpath).st_ino except: inode = -1 #set to the "xpra" group if we are a member of it, or if running as root: uid = getuid() username = get_username_for_uid(uid) groups = get_groups(username) if uid == 0 or GROUP in groups: group_id = get_group_id(GROUP) if group_id >= 0: try: os.lchown(sockpath, -1, group_id) except Exception as e: log = get_network_logger() log.warn("Warning: failed to set '%s' group ownership", GROUP) log.warn(" on socket '%s':", sockpath) log.warn(" %s", e) #don't know why this doesn't work: #os.fchown(listener.fileno(), -1, group_id) def cleanup_socket(): log = get_network_logger() try: cur_inode = os.stat(sockpath).st_ino except: log.info("socket '%s' already deleted", sockpath) return delpath = sockpath log("cleanup_socket '%s', original inode=%s, new inode=%s", sockpath, inode, cur_inode) if cur_inode == inode: log.info("removing socket %s", delpath) try: os.unlink(delpath) except: pass return listener, cleanup_socket
def setup_local_sockets(bind, socket_dir, socket_dirs, display_name, clobber, mmap_group="auto", socket_permissions="600", username="", uid=0, gid=0): log = get_network_logger() log("setup_local_sockets%s", (bind, socket_dir, socket_dirs, display_name, clobber, mmap_group, socket_permissions, username, uid, gid)) if not bind: return {} if not socket_dir and (not socket_dirs or (len(socket_dirs) == 1 and not socket_dirs[0])): if WIN32: socket_dirs = [""] else: raise InitExit( EXIT_SOCKET_CREATION_ERROR, "at least one socket directory must be set to use unix domain sockets" ) from xpra.platform.dotxpra import DotXpra, norm_makepath dotxpra = DotXpra(socket_dir or socket_dirs[0], socket_dirs, username, uid, gid) if display_name is not None and not WIN32: display_name = normalize_local_display_name(display_name) defs = {} try: sockpaths = {} log("setup_local_sockets: bind=%s, dotxpra=%s", bind, dotxpra) for b in bind: if b in ("none", ""): continue parts = b.split(",") sockpath = parts[0] options = {} if len(parts) == 2: options = parse_simple_dict(parts[1]) if sockpath == "auto": assert display_name is not None for sockpath in dotxpra.norm_socket_paths(display_name): sockpaths[sockpath] = options log("sockpaths(%s)=%s (uid=%i, gid=%i)", display_name, sockpaths, uid, gid) else: sockpath = dotxpra.osexpand(sockpath) if os.path.isabs(sockpath): pass elif sockpath.endswith("/") or (os.path.exists(sockpath) and os.path.isdir(sockpath)): assert display_name is not None sockpath = os.path.abspath(sockpath) if not os.path.exists(sockpath): os.makedirs(sockpath) sockpath = norm_makepath(sockpath, display_name) else: sockpath = dotxpra.socket_path(sockpath) sockpaths[sockpath] = options assert sockpaths, "no socket paths to try for %s" % b #expand and remove duplicate paths: tmp = {} for tsp, options in sockpaths.items(): sockpath = dotxpra.osexpand(tsp) if sockpath in tmp: log.warn("Warning: skipping duplicate bind path %s", sockpath) continue tmp[sockpath] = options sockpaths = tmp log("sockpaths=%s", sockpaths) #create listeners: if WIN32: from xpra.platform.win32.namedpipes.listener import NamedPipeListener from xpra.platform.win32.dotxpra import PIPE_PATH for sockpath, options in sockpaths.items(): npl = NamedPipeListener(sockpath) ppath = sockpath if ppath.startswith(PIPE_PATH): ppath = ppath[len(PIPE_PATH):] log.info("created named pipe '%s'", ppath) defs[("named-pipe", npl, sockpath, npl.stop)] = options else: def checkstate(sockpath, state): if state not in (DotXpra.DEAD, DotXpra.UNKNOWN): if state == DotXpra.INACCESSIBLE: raise InitException( "An xpra server is already running at %s\n" % (sockpath, )) raise InitExit( EXIT_SERVER_ALREADY_EXISTS, "You already have an xpra server running at %s\n" " (did you want 'xpra upgrade'?)" % (sockpath, )) #remove exisiting sockets if clobber is set, #otherwise verify there isn't a server already running #and create the directories for the sockets: unknown = [] for sockpath in sockpaths: if clobber and os.path.exists(sockpath): os.unlink(sockpath) else: state = dotxpra.get_server_state(sockpath, 1) log("state(%s)=%s", sockpath, state) checkstate(sockpath, state) if state == dotxpra.UNKNOWN: unknown.append(sockpath) d = os.path.dirname(sockpath) try: kwargs = {} if d in ("/var/run/xpra", "/run/xpra"): #this is normally done by tmpfiles.d, #but we may need to do it ourselves in some cases: kwargs["mode"] = SOCKET_DIR_MODE xpra_gid = get_group_id(SOCKET_DIR_GROUP) if xpra_gid > 0: kwargs["gid"] = xpra_gid log("creating sockdir=%s, kwargs=%s" % (d, kwargs)) dotxpra.mksockdir(d, **kwargs) log("%s permission mask: %s", d, oct(os.stat(d).st_mode)) except Exception as e: log.warn("Warning: failed to create socket directory '%s'", d) log.warn(" %s", e) del e #wait for all the unknown ones: log("sockets in unknown state: %s", unknown) if unknown: #re-probe them using threads so we can do them in parallel: threads = [] def timeout_probe(sockpath): #we need a loop because "DEAD" sockets may return immediately #(ie: when the server is starting up) start = monotonic_time() while monotonic_time() - start < WAIT_PROBE_TIMEOUT: state = dotxpra.get_server_state( sockpath, WAIT_PROBE_TIMEOUT) log("timeout_probe() get_server_state(%s)=%s", sockpath, state) if state not in (DotXpra.UNKNOWN, DotXpra.DEAD): break sleep(1) log.warn( "Warning: some of the sockets are in an unknown state:") for sockpath in unknown: log.warn(" %s", sockpath) t = start_thread(timeout_probe, "probe-%s" % sockpath, daemon=True, args=(sockpath, )) threads.append(t) log.warn( " please wait as we allow the socket probing to timeout") #wait for all the threads to do their job: for t in threads: t.join(WAIT_PROBE_TIMEOUT + 1) if sockpaths: #now we can re-check quickly: #(they should all be DEAD or UNKNOWN): for sockpath in sockpaths: state = dotxpra.get_server_state(sockpath, 1) log("state(%s)=%s", sockpath, state) checkstate(sockpath, state) try: if os.path.exists(sockpath): os.unlink(sockpath) except OSError: pass #socket permissions: if mmap_group.lower() in TRUE_OPTIONS: #when using the mmap group option, use '660' sperms = 0o660 else: #parse octal mode given as config option: try: if isinstance(socket_permissions, int): sperms = socket_permissions else: #assume octal string: sperms = int(socket_permissions, 8) assert 0 <= sperms <= 0o777, "invalid socket permission value %s" % oct( sperms) except ValueError: raise ValueError("invalid socket permissions " + "(must be an octal number): '%s'" % socket_permissions) from None #now try to create all the sockets: for sockpath, options in sockpaths.items(): #create it: try: sock, cleanup_socket = create_unix_domain_socket( sockpath, sperms) log.info("created unix domain socket '%s'", sockpath) defs[("unix-domain", sock, sockpath, cleanup_socket)] = options except Exception as e: handle_socket_error(sockpath, sperms, e) del e except Exception: for sock, cleanup_socket in defs.items(): try: cleanup_socket() except Exception as e: log.error("Error cleaning up socket %s:", sock) log.error(" %s", e) del e raise return defs
def __init__(self, username, **kwargs): log("peercred.Authenticator(%s, %s)", username, kwargs) if not POSIX: log.warn("Warning: peercred authentication is not supported on %s", os.name) return self.uid = -1 self.gid = -1 self.peercred_check = False connection = kwargs.get("connection", None) uids = kwargs.pop("uid", None) gids = kwargs.pop("gid", None) allow_uids = None allow_gids = None if uids: allow_uids = [] for x in uids.split(","): x = osexpand(x.strip()) try: allow_uids.append(int(x)) except ValueError: import pwd try: pw = pwd.getpwnam(x) uids.append(pw.pw_uid) except KeyError: log.warn("Warning: unknown username '%s'", x) log("peercred: allow_uids(%s)=%s", uids, allow_uids) if gids: allow_gids = [] for x in gids.split(","): x = osexpand(x.strip()) try: allow_gids.append(int(x)) except ValueError: gid = get_group_id(x) if gid >= 0: allow_gids.append(gid) else: log.warn("Warning: unknown group '%s'", x) log("peercred: allow_gids(%s)=%s", gids, allow_gids) try: from xpra.net.bytestreams import SocketConnection if connection and isinstance(connection, SocketConnection): sock = connection._socket peercred = get_peercred(sock) log("get_peercred(%s)=%s", sock, peercred) if not peercred: log.warn("Warning: failed to get peer credentials on %s", sock) return _, uid, gid = peercred if allow_uids is not None and uid not in allow_uids: log.warn("Warning: peercred access denied,") log.warn(" uid %i is not in the whitelist: %s", uid, csv(allow_uids)) elif allow_gids is not None and gid not in allow_gids: log.warn("Warning: peercred access denied,") log.warn(" gid %i is not in the whitelist: %s", gid, csv(allow_gids)) else: self.peercred_check = True self.uid = uid self.gid = gid else: log( "peercred: invalid connection '%s' (not a socket connection)", connection) except Exception as e: log.error("Error: cannot get peer uid") log.error(" %s", e) SysAuthenticator.__init__(self, username, **kwargs)
def init_client_mmap(mmap_group=None, socket_filename=None, size=128 * 1024 * 1024, filename=None): """ Initializes an mmap area, writes the token in it and returns: (success flag, mmap_area, mmap_size, temp_file, mmap_filename) The caller must keep hold of temp_file to ensure it does not get deleted! This is used by the client. """ def rerr(): return False, False, None, 0, None, None log("init_mmap%s", (mmap_group, socket_filename, size, filename)) mmap_filename = filename mmap_temp_file = None delete = True def validate_size(size): assert size >= 64 * 1024 * 1024, "mmap size is too small: %sB (minimum is 64MB)" % std_unit( size) assert size <= 4 * 1024 * 1024 * 1024, "mmap is too big: %sB (maximum is 4GB)" % std_unit( size) try: import mmap unit = max(4096, mmap.PAGESIZE) #add 8 bytes for the mmap area control header zone: mmap_size = roundup(size + 8, unit) if WIN32: validate_size(mmap_size) if not filename: from xpra.os_util import get_hex_uuid filename = "xpra-%s" % get_hex_uuid() mmap_filename = filename mmap_area = mmap.mmap(0, mmap_size, filename) #not a real file: delete = False mmap_temp_file = None else: assert POSIX if filename: if os.path.exists(filename): fd = os.open(filename, os.O_EXCL | os.O_RDWR) mmap_size = os.path.getsize(mmap_filename) validate_size(mmap_size) #mmap_size = 4*1024*1024 #size restriction needed with ivshmem delete = False log.info("Using existing mmap file '%s': %sMB", mmap_filename, mmap_size // 1024 // 1024) else: validate_size(mmap_size) import errno flags = os.O_CREAT | os.O_EXCL | os.O_RDWR try: fd = os.open(filename, flags) mmap_temp_file = None #os.fdopen(fd, 'w') mmap_filename = filename except OSError as e: if e.errno == errno.EEXIST: log.error( "Error: the mmap file '%s' already exists", filename) return rerr() raise else: validate_size(mmap_size) import tempfile from xpra.platform.paths import get_mmap_dir mmap_dir = get_mmap_dir() subs = os.environ.copy() subs.update({ "UID": os.getuid(), "GID": os.getgid(), "PID": os.getpid(), }) mmap_dir = shellsub(mmap_dir, subs) if mmap_dir and not os.path.exists(mmap_dir): os.mkdir(mmap_dir, 0o700) if not mmap_dir or not os.path.exists(mmap_dir): raise Exception("mmap directory %s does not exist!" % mmap_dir) #create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures #that the file is readable and writable only by the creating user ID try: temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir) except OSError as e: log.error("Error: cannot create mmap file:") log.error(" %s", e) return rerr() #keep a reference to it so it does not disappear! mmap_temp_file = temp mmap_filename = temp.name fd = temp.file.fileno() #set the group permissions and gid if the mmap-group option is specified mmap_group = (mmap_group or "") if POSIX and mmap_group and mmap_group not in FALSE_OPTIONS: group_id = None if mmap_group == "SOCKET": group_id = get_socket_group(socket_filename) elif mmap_group.lower() == "auto": group_id = xpra_group() if not group_id and socket_filename: group_id = get_socket_group(socket_filename) elif mmap_group.lower() in TRUE_OPTIONS: log.info("parsing legacy mmap-group value '%s' as 'auto'", mmap_group) log.info(" please update your configuration") group_id = xpra_group() or get_socket_group( socket_filename) else: group_id = get_group_id(mmap_group) if group_id > 0: log("setting mmap file %s to group id=%i", mmap_filename, group_id) try: os.fchown(fd, -1, group_id) except OSError as e: log("fchown(%i, %i, %i) on %s", fd, -1, group_id, mmap_filename, exc_info=True) log.error( "Error: failed to change group ownership of mmap file to '%s':", mmap_group) log.error(" %s", e) from stat import S_IRUSR, S_IWUSR, S_IRGRP, S_IWGRP os.fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) log("using mmap file %s, fd=%s, size=%s", mmap_filename, fd, mmap_size) os.lseek(fd, mmap_size - 1, os.SEEK_SET) assert os.write(fd, b'\x00') os.lseek(fd, 0, os.SEEK_SET) mmap_area = mmap.mmap(fd, length=mmap_size) return True, delete, mmap_area, mmap_size, mmap_temp_file, mmap_filename except Exception as e: log("failed to setup mmap: %s", e, exc_info=True) log.error("Error: mmap setup failed:") log.error(" %s", e) clean_mmap(mmap_filename) return rerr()
def setup_local_sockets(bind, socket_dir, socket_dirs, display_name, clobber, mmap_group=False, socket_permissions="600", username="", uid=0, gid=0): if not bind: return [] if not socket_dir and (not socket_dirs or (len(socket_dirs) == 1 and not socket_dirs[0])): if WIN32: socket_dirs = [""] else: raise InitException( "at least one socket directory must be set to use unix domain sockets" ) dotxpra = DotXpra(socket_dir or socket_dirs[0], socket_dirs, username, uid, gid) display_name = normalize_local_display_name(display_name) log = get_network_logger() defs = [] try: sockpaths = [] log("setup_local_sockets: bind=%s", bind) for b in bind: sockpath = b if b == "none" or b == "": continue elif b == "auto": sockpaths += dotxpra.norm_socket_paths(display_name) log("sockpaths(%s)=%s (uid=%i, gid=%i)", display_name, sockpaths, uid, gid) else: sockpath = dotxpra.osexpand(b) if b.endswith("/") or (os.path.exists(sockpath) and os.path.isdir(sockpath)): sockpath = os.path.abspath(sockpath) if not os.path.exists(sockpath): os.makedirs(sockpath) sockpath = norm_makepath(sockpath, display_name) elif os.path.isabs(b): sockpath = b else: sockpath = dotxpra.socket_path(b) sockpaths += [sockpath] assert sockpaths, "no socket paths to try for %s" % b #expand and remove duplicate paths: tmp = [] for tsp in sockpaths: sockpath = dotxpra.osexpand(tsp) if sockpath in tmp: log.warn("Warning: skipping duplicate bind path %s", sockpath) continue tmp.append(sockpath) sockpaths = tmp #create listeners: if WIN32: from xpra.platform.win32.namedpipes.listener import NamedPipeListener for sockpath in sockpaths: npl = NamedPipeListener(sockpath) log.info("created named pipe: %s", sockpath) defs.append((("named-pipe", npl, sockpath), npl.stop)) else: def checkstate(sockpath, state): if state not in (DotXpra.DEAD, DotXpra.UNKNOWN): if state == DotXpra.INACCESSIBLE: raise InitException( "An xpra server is already running at %s\n" % (sockpath, )) raise InitException( "You already have an xpra server running at %s\n" " (did you want 'xpra upgrade'?)" % (sockpath, )) #remove exisiting sockets if clobber is set, #otherwise verify there isn't a server already running #and create the directories for the sockets: unknown = [] for sockpath in sockpaths: if clobber and os.path.exists(sockpath): os.unlink(sockpath) else: state = dotxpra.get_server_state(sockpath, 1) log("state(%s)=%s", sockpath, state) checkstate(sockpath, state) if state == dotxpra.UNKNOWN: unknown.append(sockpath) d = os.path.dirname(sockpath) try: kwargs = {} if getuid( ) == 0 and d == "/var/run/xpra" or d == "/run/xpra": #this is normally done by tmpfiles.d, #but we may need to do it ourselves in some cases: kwargs = {"mode": 0o775} xpra_gid = get_group_id("xpra") if xpra_gid > 0: kwargs["gid"] = xpra_gid log("creating sockdir=%s, kwargs=%s" % (d, kwargs)) dotxpra.mksockdir(d, **kwargs) except Exception as e: log.warn("Warning: failed to create socket directory '%s'", d) log.warn(" %s", e) del e #wait for all the unknown ones: log("sockets in unknown state: %s", unknown) if unknown: #re-probe them using threads so we can do them in parallel: from time import sleep from xpra.make_thread import start_thread threads = [] def timeout_probe(sockpath): #we need a loop because "DEAD" sockets may return immediately #(ie: when the server is starting up) start = monotonic_time() while monotonic_time() - start < WAIT_PROBE_TIMEOUT: state = dotxpra.get_server_state( sockpath, WAIT_PROBE_TIMEOUT) log("timeout_probe() get_server_state(%s)=%s", sockpath, state) if state not in (DotXpra.UNKNOWN, DotXpra.DEAD): break sleep(1) log.warn( "Warning: some of the sockets are in an unknown state:") for sockpath in unknown: log.warn(" %s", sockpath) t = start_thread(timeout_probe, "probe-%s" % sockpath, daemon=True, args=(sockpath, )) threads.append(t) log.warn( " please wait as we allow the socket probing to timeout") #wait for all the threads to do their job: for t in threads: t.join(WAIT_PROBE_TIMEOUT + 1) if sockpaths: #now we can re-check quickly: #(they should all be DEAD or UNKNOWN): for sockpath in sockpaths: state = dotxpra.get_server_state(sockpath, 1) log("state(%s)=%s", sockpath, state) checkstate(sockpath, state) try: if os.path.exists(sockpath): os.unlink(sockpath) except: pass #socket permissions: if mmap_group: #when using the mmap group option, use '660' sperms = 0o660 else: #parse octal mode given as config option: try: if type(socket_permissions) == int: sperms = socket_permissions else: #assume octal string: sperms = int(socket_permissions, 8) assert sperms >= 0 and sperms <= 0o777, "invalid socket permission value %s" % oct( sperms) except ValueError: raise ValueError( "invalid socket permissions (must be an octal number): '%s'" % socket_permissions) #now try to create all the sockets: for sockpath in sockpaths: #create it: try: sock, cleanup_socket = create_unix_domain_socket( sockpath, sperms) log.info("created unix domain socket: %s", sockpath) defs.append( (("unix-domain", sock, sockpath), cleanup_socket)) except Exception as e: handle_socket_error(sockpath, sperms, e) del e except: for sock, cleanup_socket in defs: try: cleanup_socket() except Exception as e: log.error("Error cleaning up socket %s:", sock) log.error(" %s", e) del e defs = [] raise return defs