diff --git a/type/__nsswitch/explorer/sources b/type/__nsswitch/explorer/sources new file mode 100755 index 000000000..7aa71d60e --- /dev/null +++ b/type/__nsswitch/explorer/sources @@ -0,0 +1,52 @@ +#!/bin/sh -e +# +# 2023,2025 Dennis Camera (dennis.camera at riiengineering.ch) +# +# This file is part of skonfig-base. +# +# skonfig-base is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# skonfig-base is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with skonfig-base. If not, see . +# +# Prints the sources currently configured for the database. +# + +test -f /etc/nsswitch.conf || exit 0 + +awk -v db_name="${__object_id:?}" ' +# prepare line +{ + # remove comments + sub(/[ \\t]*#.*$/, "") + # merge line continuations to single line (line continuations do not apply + # to comments, btw). + while (/\\$/) { + sub(/\\$/, (0 < (getline _nl) ? _nl : "")) + } +} + +$1 == db_name ":" { + # store found line, because in nsswitch.conf(5) the last match wins + line = $0 +} + +END { + if (line) { + $0 = line + + for (i = 2; i <= NF; ++i) { + printf "%s%s", (i>2 ? " " : ""), $i + } + printf ORS + } +} +' /etc/nsswitch.conf diff --git a/type/__nsswitch/gencode-remote b/type/__nsswitch/gencode-remote new file mode 100755 index 000000000..357469ade --- /dev/null +++ b/type/__nsswitch/gencode-remote @@ -0,0 +1,157 @@ +#!/bin/sh -e +# +# 2023,2025 Dennis Camera (dennis.camera at riiengineering.ch) +# +# This file is part of skonfig-base. +# +# skonfig-base is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# skonfig-base is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with skonfig-base. If not, see . +# + +join_lines() { + test -r "$2" || return 0 + awk -v sep="$1" 'NR>1{printf "%s",sep}{printf "%s",$0}END{printf ORS}' "$2" +} + +if + join_lines ' ' "${__object:?}/parameter/source" \ + | cmp -s "${__object:?}/explorer/sources" - +then + # no changes needed + exit 0 +fi + +os=$(cat "${__global:?}/explorer/os") +case ${os} +in + (fedora|redhat|centos|almalinux|rocky|oraclelinux|scientific|amazon) + echo 'This type currently does not work on Red Hat, because it does not support authconfig/authselect.' >&2 + echo 'Please contribute an implementation for it if you can.' >&2 + exit 1 + ;; + (solaris) + case $(cat "${__global:?}/explorer/os_version") + in + (5.11|5.11.*|'') + # Solaris 11 manages name service switch information in SMF + # https://docs.oracle.com/cd/E23824_01/html/821-1455/c8switch-18904.html + echo 'This type currently does not work on Solaris 11, because it does not support managing the information in SMF.' >&2 + echo 'Please contribute an implementation for it if you can.' >&2 + exit 1 + ;; + esac + ;; +esac + +if ! test -s "${__object:?}/explorer/sources" +then + # possibly the file does not exist + cat <<'EOF' +test -f /etc/nsswitch.conf || ( + umask 0022 + :>/etc/nsswitch.conf + chown 0:0 /etc/nsswitch.conf +) + +EOF +fi + +# update nsswitch.conf(5) + +# NOTE: the updated content is cat(1) into /etc/nsswitch.conf to achieve the +# correct behaviour if /etc/nsswitch.conf is a symbolic link. +cat <<'EOF' +awk -v db_name="${__object_id:?}" -v source_file="${__object:?}/parameter/source" ' +function update_indents( i, _l) { + _l = $0 + while (_l ~ /[\t]/) { + # expand tab stops + i = index(_l, "\t")-1 + _l = substr(_l, 1, i) sprintf("%"(TAB_WIDTH - (i % TAB_WIDTH))"s", "") substr(_l, i+2) + } + + i = index(_l, $1) - 1 + i += length($1) + i += index(substr(_l, i+1), $2) - 1 + + if (/[\t]/ || i > (index(_l, $1) + length($1))) { + # only remember indentation if there are at least two spaces or a tab + indents[i]++ + num_indents++ + num_indents_tabs += /[\t]/ + } +} +function fmt_db(db, cnt, cnt_total, il, i) { + # set initial cnt = 2 to ignore indentations which only occur once + il = (length(db) + 1); cnt = 2 + + for (i in indents) { + cnt_total += indents[i] + if (indents[i] > cnt) { il = i; cnt = indents[i] } + } + + if ((cnt * 2) <= cnt_total) { + # no clear indentation style (< 50%), ignore + return db " " + } + + if ((2 * num_indents_tabs) > num_indents) { + # this file uses tabs predominantly + cnt = (il - length(db)) / TAB_WIDTH + for (i = 0; i < cnt; ++i) { db = db "\t" } + return db + } else { + return sprintf("%-"il"s", db) + } +} + +BEGIN { + TAB_WIDTH = 8 + + while (0 < (getline src < source_file)) { + sources = sources (sources ? " " : "") src + } + close(source_file) +} + +$1 ~ /:$/ { + # looks like an entry + update_indents() + + if ($1 == db_name":") { + # only replace the first occurrence + if (!f && sources) { + match($0, /:[ \t]*/) + printf "%s%s" ORS, substr($0, 1, RSTART + RLENGTH - 1), sources + } + f = 1 + while (/\\$/) { getline } + } else { + print + while (/\\$/) { getline; print } + } + next +} + +{ print } + +END { + if (!f && sources) { + # append new entry + printf "%s%s" ORS, fmt_db(db_name":"), sources + } +} +' /etc/nsswitch.conf >/etc/nsswitch.conf.tmp \ +&& cat /etc/nsswitch.conf.tmp >/etc/nsswitch.conf +rm -f /etc/nsswitch.conf.tmp +EOF diff --git a/type/__nsswitch/man.rst b/type/__nsswitch/man.rst new file mode 100644 index 000000000..3aa0b6198 --- /dev/null +++ b/type/__nsswitch/man.rst @@ -0,0 +1,73 @@ +cdist-type__nsswitch(7) +======================= + +NAME +---- +cdist-type__nsswitch - manage Name Service Switch database configuration + + +DESCRIPTION +----------- +This type can be used to manage database configurations in the +:strong:`nsswitch.conf`\ (5) file. + +This type does no checking whether your operating system/libc respects the +nsswitch.conf file, this job is up to you. + + +OPTIONAL PARAMETERS +------------------- +source + Specify the name of a source for this database (with optional criteria + appended to the source name in square brackets ``[]``). + See :strong:`nsswitch.conf`\ (5) for the options supported by your operating + system. + + Can be used multiple times so specify multiple sources which will be queried + in the order specified. + + If no sources are given, the database entry will be removed from + :strong:`nsswitch.conf`\ (5). + + +EXAMPLES +-------- + +.. code-block:: sh + + # Configure NSS to query LDAP for users/groups (Linux) + __nsswitch passwd \ + --source ldap \ + --source files + __nsswitch group \ + --source ldap \ + --source files + __nsswitch shadow \ + --source ldap \ + --source files + + # Configure NSS host lookup to include mDNS (using libnss-mdns on Linux) + # Other OSs may use different source names, e.g. mdns_minimal is called + # multicast_dns on NetBSD + __nsswitch hosts \ + --source files \ + --source 'mdns_minimal [NOTFOUND=return]' \ + --source dns + + +SEE ALSO +-------- +* :strong:`nsswitch.conf`\ (5) + + +AUTHORS +------- +* Dennis Camera + + +COPYING +------- +Copyright \(C) 2023, 2025 Dennis Camera. +You can redistribute it and/or modify it under the terms of the GNU General +Public License as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. diff --git a/type/__nsswitch/nonparallel b/type/__nsswitch/nonparallel new file mode 100644 index 000000000..e69de29bb diff --git a/type/__nsswitch/parameter/optional_multiple b/type/__nsswitch/parameter/optional_multiple new file mode 100644 index 000000000..5a18cd2fb --- /dev/null +++ b/type/__nsswitch/parameter/optional_multiple @@ -0,0 +1 @@ +source