#!/bin/sh # This script replaces the dnsmasq leasefile with an sqlite database # for performance on slow storage, and updates DNS records for # assigned addresses. cmd="${1}" # dnsmasq calls this script on startup for each known lease, ignore it [ "${cmd}" != "init" ] && [ -z "${DNSMASQ_INTERFACE}" ] && exit 0 # parameters db=/var/lib/misc/dnsmasq.leases.db domain={{ domain }} ldap_user={{ password.ldap_user }} ttl=3600 # sanitize input mac="${2//[![:xdigit:]:]/}" ipv4="${3//[![:digit:].]/}" hostname="${4//[![:alnum:]_-]/}" client_id="${DNSMASQ_CLIENT_ID//[![:xdigit:]:]/}" # construct SQL to query or update leases, and nsupdate script to update DNS records dns="" sql="" case "${cmd}" in "init") # init runs as root, so ensure the dnsmasq user can write to database later touch "${db}" chown dnsmasq:dnsmasq "${db}" setfacl -m u:dnsmasq:rwx "$(dirname ${db})" setfacl -m u:dnsmasq:r "/etc/krb5.keytab" # needed for DNS updates # ensure the leases table exists, and get all leases from it sql="CREATE TABLE IF NOT EXISTS leases ( ipv4 TEXT PRIMARY KEY NOT NULL, mac TEXT NOT NULL, hostname TEXT NOT NULL, client_id TEXT NOT NULL, renewed INTEGER NOT NULL); SELECT renewed, mac, ipv4, hostname, client_id FROM leases;" ;; "add" | "old") # add or update the lease sql="INSERT INTO leases VALUES ('${ipv4}', '${mac}', '${hostname:-*}', '${client_id:-*}', unixepoch()) ON CONFLICT(ipv4) DO UPDATE SET renewed = unixepoch();" # add or update the DNS record if [ -n "${hostname}" ] ; then dns="update add ${hostname}.${domain} ${ttl} A ${ipv4}\n" fi if [ -n "${DNSMASQ_OLD_HOSTNAME}" ] ; then dns="${dns}update del ${DNSMASQ_OLD_HOSTNAME}.${domain}\n" fi ;; "del") # delete the lease sql="DELETE FROM leases WHERE ipv4 = '${ipv4}';" # TODO probably delete the DNS record ;; esac # update lease database if [ -n "${sql}" ]; then sqlite3 -separator " " "${db}" "${sql}" fi # update DNS records if [ -n "${dns}" ]; then kinit -k "${ldap_user}" echo -e "${dns}send" | nsupdate -g fi