blob: 4e86b0ef741585650aa827a3f6341b647df8780c [file] [log] [blame]
Piotr Dobrowolskia01905a2021-10-16 18:22:46 +02001#!/usr/bin/env nix-shell
2#!nix-shell -i python3 -p python3Packages.ldap3
3
4from ldap3 import Server, Connection, LEVEL
5from ldap3.utils.dn import escape_rdn
6import getpass
7import logging
8from pathlib import Path
9import filecmp
10import os
11
12import argparse
13
14parser = argparse.ArgumentParser()
15parser.add_argument("hostname", help="hostname")
16parser.add_argument("ldap_pass_file", type=Path, help="file containing lap password")
17
18header_warning = """
19################################### WARNING ####################################
20# This file was created automatically from LDAP database and *WILL* be
21# overwritten. If you need to add / remove keys make changes to
22# {}-admin group / members sshPublicKey attributes in LDAP and rerun
23# update_authorized_keys script
24################################################################################
25""".lstrip()
26
27def get_keys(connection: Connection, group: str):
28 c = connection
29
30 c.search(
31 search_base="ou=People,dc=hackerspace,dc=pl",
32 search_filter=(
33 "(&"
34 "(objectClass=hsMember)"
35 f"(memberOf=cn={escape_rdn(group)},ou=Group,dc=hackerspace,dc=pl)"
36 ")"
37 ),
38 search_scope=LEVEL,
39 attributes=["sshPublicKey"],
40 )
41
42 admin_keys = []
43 for entry in c.response:
44 attributes = entry["attributes"]
45 for key in entry["attributes"]["sshPublicKey"]:
46 yield key.strip()
47
48
49if __name__ == "__main__":
50 logging.basicConfig(level=logging.INFO)
51 args = parser.parse_args()
52
53 user = f"cn={escape_rdn(args.hostname)},ou=Boxen,dc=hackerspace,dc=pl"
54 password = args.ldap_pass_file.read_text().strip()
55
56 s = Server("ldap.hackerspace.pl", use_ssl=True)
57 with Connection(s, user=user, password=password, raise_exceptions=True) as c:
58 keys = list(get_keys(c, f"{args.hostname}-admin"))
59 if len(keys) < 2:
60 raise Exception("Less then two keys found - aborting")
61
62 ssh_dir = Path("/", "root", ".ssh")
63 ssh_dir.mkdir(mode=700, exist_ok=True)
64 ssh_dir.chmod(0o700)
65 new_file = ssh_dir.joinpath("authorized_keys_new")
66 old_file = ssh_dir.joinpath("authorized_keys")
67 try:
68 new_file.unlink()
69 except FileNotFoundError:
70 pass
71 new_file.write_bytes(
72 header_warning.format(args.hostname).encode() + b"\n".join(keys)
73 )
74 if not old_file.exists():
75 logging.info('Creating new "authorized_keys" file')
76 os.rename(new_file, old_file)
77 elif filecmp.cmp(new_file, old_file, shallow=False):
vukoca6dba92023-01-05 19:54:20 +010078 logging.debug('Nothing changed - "authorized_keys" file is up to date')
Piotr Dobrowolskia01905a2021-10-16 18:22:46 +020079 new_file.unlink()
80 else:
81 logging.info('Keys changed - overwriting "authorized_keys" file')
82 os.rename(new_file, old_file)