forked from hswaw/hscloud
83 lines
2.8 KiB
Python
Executable File
83 lines
2.8 KiB
Python
Executable File
#!/usr/bin/env nix-shell
|
|
#!nix-shell -i python3 -p python3Packages.ldap3
|
|
|
|
from ldap3 import Server, Connection, LEVEL
|
|
from ldap3.utils.dn import escape_rdn
|
|
import getpass
|
|
import logging
|
|
from pathlib import Path
|
|
import filecmp
|
|
import os
|
|
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("hostname", help="hostname")
|
|
parser.add_argument("ldap_pass_file", type=Path, help="file containing lap password")
|
|
|
|
header_warning = """
|
|
################################### WARNING ####################################
|
|
# This file was created automatically from LDAP database and *WILL* be
|
|
# overwritten. If you need to add / remove keys make changes to
|
|
# {}-admin group / members sshPublicKey attributes in LDAP and rerun
|
|
# update_authorized_keys script
|
|
################################################################################
|
|
""".lstrip()
|
|
|
|
def get_keys(connection: Connection, group: str):
|
|
c = connection
|
|
|
|
c.search(
|
|
search_base="ou=People,dc=hackerspace,dc=pl",
|
|
search_filter=(
|
|
"(&"
|
|
"(objectClass=hsMember)"
|
|
f"(memberOf=cn={escape_rdn(group)},ou=Group,dc=hackerspace,dc=pl)"
|
|
")"
|
|
),
|
|
search_scope=LEVEL,
|
|
attributes=["sshPublicKey"],
|
|
)
|
|
|
|
admin_keys = []
|
|
for entry in c.response:
|
|
attributes = entry["attributes"]
|
|
for key in entry["attributes"]["sshPublicKey"]:
|
|
yield key.strip()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
logging.basicConfig(level=logging.INFO)
|
|
args = parser.parse_args()
|
|
|
|
user = f"cn={escape_rdn(args.hostname)},ou=Boxen,dc=hackerspace,dc=pl"
|
|
password = args.ldap_pass_file.read_text().strip()
|
|
|
|
s = Server("ldap.hackerspace.pl", use_ssl=True)
|
|
with Connection(s, user=user, password=password, raise_exceptions=True) as c:
|
|
keys = list(get_keys(c, f"{args.hostname}-admin"))
|
|
if len(keys) < 2:
|
|
raise Exception("Less then two keys found - aborting")
|
|
|
|
ssh_dir = Path("/", "root", ".ssh")
|
|
ssh_dir.mkdir(mode=700, exist_ok=True)
|
|
ssh_dir.chmod(0o700)
|
|
new_file = ssh_dir.joinpath("authorized_keys_new")
|
|
old_file = ssh_dir.joinpath("authorized_keys")
|
|
try:
|
|
new_file.unlink()
|
|
except FileNotFoundError:
|
|
pass
|
|
new_file.write_bytes(
|
|
header_warning.format(args.hostname).encode() + b"\n".join(keys)
|
|
)
|
|
if not old_file.exists():
|
|
logging.info('Creating new "authorized_keys" file')
|
|
os.rename(new_file, old_file)
|
|
elif filecmp.cmp(new_file, old_file, shallow=False):
|
|
logging.info('Nothing changed - "authorized_keys" file is up to date')
|
|
new_file.unlink()
|
|
else:
|
|
logging.info('Keys changed - overwriting "authorized_keys" file')
|
|
os.rename(new_file, old_file)
|