|
|
|
@ -1,6 +1,4 @@ |
|
|
|
|
import contextlib |
|
|
|
|
import grp |
|
|
|
|
import pwd |
|
|
|
|
from typing import Union, Dict, List |
|
|
|
|
|
|
|
|
|
from flask import g |
|
|
|
@ -119,19 +117,6 @@ class LDAPService: |
|
|
|
|
|
|
|
|
|
def _get_next_uid(self, conn: ldap3.Connection, min_id: int, max_id: int) -> int: |
|
|
|
|
"""Gets the next available UID number between min_id and max_id, inclusive.""" |
|
|
|
|
def uid_exists(uid: int) -> bool: |
|
|
|
|
try: |
|
|
|
|
pwd.getpwuid(uid) |
|
|
|
|
return True |
|
|
|
|
except KeyError: |
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
def gid_exists(gid: int) -> bool: |
|
|
|
|
try: |
|
|
|
|
grp.getgrgid(gid) |
|
|
|
|
return True |
|
|
|
|
except KeyError: |
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
def ldap_uid_or_gid_exists(uid: int) -> bool: |
|
|
|
|
return conn.search( |
|
|
|
@ -139,12 +124,17 @@ class LDAPService: |
|
|
|
|
f'(|(uidNumber={uid})(gidNumber={uid}))', |
|
|
|
|
size_limit=1) |
|
|
|
|
|
|
|
|
|
# TODO: replace this with binary search |
|
|
|
|
for uid in range(min_id, max_id + 1): |
|
|
|
|
if uid_exists(uid) or gid_exists(uid) or ldap_uid_or_gid_exists(uid): |
|
|
|
|
continue |
|
|
|
|
return uid |
|
|
|
|
raise Exception('no UIDs remaining') |
|
|
|
|
while min_id != max_id: |
|
|
|
|
cur_uid = (min_id + max_id) // 2 |
|
|
|
|
if ldap_uid_or_gid_exists(cur_uid): |
|
|
|
|
min_id = cur_uid + 1 |
|
|
|
|
else: |
|
|
|
|
max_id = cur_uid |
|
|
|
|
|
|
|
|
|
if ldap_uid_or_gid_exists(min_id): |
|
|
|
|
raise Exception('no UIDs remaining') |
|
|
|
|
else: |
|
|
|
|
return min_id |
|
|
|
|
|
|
|
|
|
def add_sudo_role(self, uid: str): |
|
|
|
|
conn = self._get_ldap_conn() |
|
|
|
|