Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__nsswitch: new type #83

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
50 changes: 50 additions & 0 deletions type/__nsswitch/explorer/sources
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/sh -e
#
# 2023 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.
#

# NOTE: don’t check test -f, because /etc/nsswitch.conf can be a symbolic link
# (hello, Fedora)
test -e /etc/nsswitch.conf || exit 0

awk -v db_name="${__object_id:?}" '
{
sub(/[ \\t]*#.*$/, "")
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
113 changes: 113 additions & 0 deletions type/__nsswitch/gencode-remote
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/bin/sh -e
#
# 2023 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(){
awk -v sep="$1" 'NR>1{printf "%s",sep}{printf "%s",$0}END{printf ORS}'
}

if
join_lines ' ' <"${__object:?}/parameter/source" \
| cmp -s "${__object:?}/explorer/sources" -
then
# no changes needed
exit 0
fi


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 get_indent( i) {
# FIXME: handle tab stops?
i = index($0, $1) - 1
i += length($1)
i += index(substr($0, i+1), $2) - 1
return i
}
function guess_indent(key, cnt, il, i) {
# set initial cnt = 2 to ignore indentations which only occur once
il = (length(key) + 2); cnt = 2

for (i in indent) {
if (indent[i] > cnt) { il = i }
}
return il
}

BEGIN {
while (0 < (getline src < source_file)) {
sources = sources (sources ? " " : "") src
}
close(source_file)
}

$1 ~ /^[^#].*:/ {
# looks like an entry
db = substr($1, 1, index($1, ":") - 1)

i = get_indent()
if (i > (index($0, $1) + length($1))) {
# only remember if there is more than one space between db and sources
indent[i]++
}
}

db == db_name {
if (!f) {
# only replace the first occurrence
if (sources) {
match($0, /:[ \t]*/)
printf "%s%s" ORS, substr($0, 1, RSTART + RLENGTH - 1), sources
}
f = 1
}

while (/\\$/) { getline }
next
}

{ print }

END {
if (!f && sources) {
# append new entry
printf ("%-" guess_indent(db_name) "s%s" ORS), 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 <[email protected]>


COPYING
-------
Copyright \(C) 2023 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