Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions type/__nsswitch/explorer/sources
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
#
# 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
157 changes: 157 additions & 0 deletions type/__nsswitch/gencode-remote
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
#

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
73 changes: 73 additions & 0 deletions type/__nsswitch/man.rst
Original file line number Diff line number Diff line change
@@ -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 <dennis.camera--@--riiengineering.ch>


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.
Empty file added type/__nsswitch/nonparallel
Empty file.
1 change: 1 addition & 0 deletions type/__nsswitch/parameter/optional_multiple
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
source