Discussion:
Debugging nsswitch.conf
Ron Wills
2021-04-19 19:05:48 UTC
Permalink
I'm attempting to create something like a BBS with sshd within a jail.
Because of the flexablity of ssh I want the absolute minimum in the
jail and I want sshd to authenicate through PostgreSQL.

I have both libnss-pgsql and pam-pgsql installed and added to the jail.
When I set nsswitch.conf to:
groups: files
passwd: files

I can see the users from the master.passwd file and can see pam-pgsql
connect to the database and fail. The failure is because the two aren't
currently in sync.

When I set nsswitch.conf to:
groups: pgsql
passwd: pgsql

I get absolutely nothing. Getent returns nothing. I see nothing logged.
I don't see any attempts to connect to the database. NSS just silently
fails. I'm at lose. I'm sure I'm probably just missing something
simple... Here's the nss configuration for the jail at the
moment on FreeBSD 12.2.

/etc/nsswitch.conf

#group: files [notfound=continue] pgsql
group: pgsql
group_compat: nis
hosts: files dns
networks: files
#passwd: files [notfound=continue] pgsql
passwd: pgsql
passwd_compat: nis
shells: files
services: compat
services_compat: nis
protocols: files
rpc: files

/etc/nss-pgsql.conf

# It is advised if you run postgresql on the same server as libnss-pgsql that you have
# ssl connection turned off in your connection string.
# You can hang your machine attempting to connect to the postgresql database.
# sslmode=disable
#
# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=279581
#
# Without a running nscd, PQconnectdb attempts to setup the SSL
# environment and searches for $HOME/.postgresql/server.crt (or similar),
# calling getpwuid to retrieve the home-directory. This obviously causes
# another entrance into libnss-pgsql which results in a hang while waiting
# for the (already owned) lock.
connectionstring = host=/tmp dbname=accounts user=nss password=x connect_timeout=1 sslmode=disable

# you can use anything postgres accepts as table expression

# Must return "usernames", 1 column, list
getgroupmembersbygid = SELECT username FROM passwd JOIN passwd_groups ug USING (uid) WHERE ug.gid = $1
# Must return passwd_name, passwd_passwd, passwd_gecos, passwd_dir, passwd_shell, passwd_uid, passwd_gid
getpwnam = SELECT username, passwd, gecos, homedir, shell, uid, gid FROM passwd WHERE username = $1
# Must return passwd_name, passwd_passwd, passwd_gecos, passwd_dir, passwd_shell, passwd_uid, passwd_gid
getpwuid = SELECT username, passwd, gecos, homedir, shell, uid, gid FROM passwd WHERE uid = $1
# All users
allusers = SELECT username, passwd, gecos, homedir, shell, uid, gid FROM passwd
# Must return group_name, group_passwd, group_gid
getgrnam = SELECT groupname, passwd, gid, array_to_string(SELECT username FROM passwd_groups WHERE passwd_groups.gid = groups.gid),chr(10)) as members FROM groups WHERE groupname = $1
# Must return group_name, group_passwd, group_gid
getgrgid = SELECT groupname, passwd, gid, array_to_string(SELECT username from passwd_groups WHERE passwd_groups.gid = groups.gid),chr(10)) as members FROM groups WHERE gid = $1
# Must return gid. %s MUST appear first for username match in where clause
groups_dyn = SELECT ug.gid FROM passwd JOIN passwd_groups ug USING (uid) where username = $1 and ug.gid <> $2

# allgroups can use 2 flavours,
# 1. get the group table and requery getgroupmembersbygid for all group members.
# this produces 1 query per group.
# 2. pass the list of usernames with they query as an aggregate, each username must be split by '\n' or chr(10)
# the new version is usually faster
#allgroups = SELECT groupname, passwd, gid FROM group_table
allgroups = SELECT groupname, passwd, gid, array_to_string(ARRAY(SELECT username FROM passwd_groups JOIN passwd USING (uid) WHERE passwd_groups.gid = groups.gid),chr(10)) AS members FROM groups

/etc/nss-pgsql-root.conf

# example configfile for PostgreSQL NSS module
# this file must be readable for root only

shadowconnectionstring = host=/tmp dbname=accounts user=nss password=x connect_timeout=1 sslmode=disable

#Query in the following format
#shadow_name, shadow_passwd, shadow_lstchg, shadow_min, shadow_max, shadow_warn, shadow_inact, shadow_expire, shadow_flag
shadowbyname = SELECT * FROM shadow WHERE username = $1
shadow = SELECT * FROM shadow
Ron Wills
2021-04-21 02:40:21 UTC
Permalink
Post by Ron Wills
I'm attempting to create something like a BBS with sshd within a jail.
Because of the flexablity of ssh I want the absolute minimum in the
jail and I want sshd to authenicate through PostgreSQL.
I have both libnss-pgsql and pam-pgsql installed and added to the jail.
groups: files
passwd: files
I can see the users from the master.passwd file and can see pam-pgsql
connect to the database and fail. The failure is because the two aren't
currently in sync.
groups: pgsql
passwd: pgsql
I ran ktrace on "getent passwd" and discovered the problem. When pgsql
is specified, nss attempts to load the library nss_pgsql.so.1. The
package libnss-pgsql installs the library lib_pgsql.so.2.0.0 and links.
Renaming the libraries fixed the problem.

If I'm not mistaken here I'm seeing two problems.

The most obvious being the library file name in the package.

The other problem is with the nss system. Should it be looking for a
versioned library file. Wouldn't searching for nss_pgsql.so be better
form than nss_pgsql.so.1? And possibly the man page for nsswitch.conf
should include some kind of blurb for loadable modules. I haven't been
able to find any other documentation on the nss system than there.

I'm new to FreeBSD and I'm not quite sure where I should report this.
I'd be happy to help to improve things where I can :)
Post by Ron Wills
I get absolutely nothing. Getent returns nothing. I see nothing logged.
I don't see any attempts to connect to the database. NSS just silently
fails. I'm at lose. I'm sure I'm probably just missing something
simple... Here's the nss configuration for the jail at the
moment on FreeBSD 12.2.
/etc/nsswitch.conf
#group: files [notfound=continue] pgsql
group: pgsql
group_compat: nis
hosts: files dns
networks: files
#passwd: files [notfound=continue] pgsql
passwd: pgsql
passwd_compat: nis
shells: files
services: compat
services_compat: nis
protocols: files
rpc: files
/etc/nss-pgsql.conf
# It is advised if you run postgresql on the same server as libnss-pgsql that you have
# ssl connection turned off in your connection string.
# You can hang your machine attempting to connect to the postgresql database.
# sslmode=disable
#
# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=279581
#
# Without a running nscd, PQconnectdb attempts to setup the SSL
# environment and searches for $HOME/.postgresql/server.crt (or similar),
# calling getpwuid to retrieve the home-directory. This obviously causes
# another entrance into libnss-pgsql which results in a hang while waiting
# for the (already owned) lock.
connectionstring = host=/tmp dbname=accounts user=nss password=x connect_timeout=1 sslmode=disable
# you can use anything postgres accepts as table expression
# Must return "usernames", 1 column, list
getgroupmembersbygid = SELECT username FROM passwd JOIN passwd_groups ug USING (uid) WHERE ug.gid = $1
# Must return passwd_name, passwd_passwd, passwd_gecos, passwd_dir, passwd_shell, passwd_uid, passwd_gid
getpwnam = SELECT username, passwd, gecos, homedir, shell, uid, gid FROM passwd WHERE username = $1
# Must return passwd_name, passwd_passwd, passwd_gecos, passwd_dir, passwd_shell, passwd_uid, passwd_gid
getpwuid = SELECT username, passwd, gecos, homedir, shell, uid, gid FROM passwd WHERE uid = $1
# All users
allusers = SELECT username, passwd, gecos, homedir, shell, uid, gid FROM passwd
# Must return group_name, group_passwd, group_gid
getgrnam = SELECT groupname, passwd, gid, array_to_string(SELECT username FROM passwd_groups WHERE passwd_groups.gid = groups.gid),chr(10)) as members FROM groups WHERE groupname = $1
# Must return group_name, group_passwd, group_gid
getgrgid = SELECT groupname, passwd, gid, array_to_string(SELECT username from passwd_groups WHERE passwd_groups.gid = groups.gid),chr(10)) as members FROM groups WHERE gid = $1
# Must return gid. %s MUST appear first for username match in where clause
groups_dyn = SELECT ug.gid FROM passwd JOIN passwd_groups ug USING (uid) where username = $1 and ug.gid <> $2
# allgroups can use 2 flavours,
# 1. get the group table and requery getgroupmembersbygid for all group members.
# this produces 1 query per group.
# 2. pass the list of usernames with they query as an aggregate, each username must be split by '\n' or chr(10)
# the new version is usually faster
#allgroups = SELECT groupname, passwd, gid FROM group_table
allgroups = SELECT groupname, passwd, gid, array_to_string(ARRAY(SELECT username FROM passwd_groups JOIN passwd USING (uid) WHERE passwd_groups.gid = groups.gid),chr(10)) AS members FROM groups
/etc/nss-pgsql-root.conf
# example configfile for PostgreSQL NSS module
# this file must be readable for root only
shadowconnectionstring = host=/tmp dbname=accounts user=nss password=x connect_timeout=1 sslmode=disable
#Query in the following format
#shadow_name, shadow_passwd, shadow_lstchg, shadow_min, shadow_max, shadow_warn, shadow_inact, shadow_expire, shadow_flag
shadowbyname = SELECT * FROM shadow WHERE username = $1
shadow = SELECT * FROM shadow
Ron Wills
2021-04-21 14:35:18 UTC
Permalink
Post by Ron Wills
Post by Ron Wills
I'm attempting to create something like a BBS with sshd within a jail.
Because of the flexablity of ssh I want the absolute minimum in the
jail and I want sshd to authenicate through PostgreSQL.
I have both libnss-pgsql and pam-pgsql installed and added to the jail.
groups: files
passwd: files
I can see the users from the master.passwd file and can see pam-pgsql
connect to the database and fail. The failure is because the two aren't
currently in sync.
groups: pgsql
passwd: pgsql
I ran ktrace on "getent passwd" and discovered the problem. When pgsql
is specified, nss attempts to load the library nss_pgsql.so.1. The
package libnss-pgsql installs the library lib_pgsql.so.2.0.0 and links.
Renaming the libraries fixed the problem.
Incase anyone is interested a cleaner fix is to add the following line
to /etc/libmap.conf:

nss_pgsql.so.1 libnss_pgsql.so.2

This will remap the library loading to the correct library.
Post by Ron Wills
If I'm not mistaken here I'm seeing two problems.
The most obvious being the library file name in the package.
The other problem is with the nss system. Should it be looking for a
versioned library file. Wouldn't searching for nss_pgsql.so be better
form than nss_pgsql.so.1? And possibly the man page for nsswitch.conf
should include some kind of blurb for loadable modules. I haven't been
able to find any other documentation on the nss system than there.
I'm new to FreeBSD and I'm not quite sure where I should report this.
I'd be happy to help to improve things where I can :)
Post by Ron Wills
I get absolutely nothing. Getent returns nothing. I see nothing logged.
I don't see any attempts to connect to the database. NSS just silently
fails. I'm at lose. I'm sure I'm probably just missing something
simple... Here's the nss configuration for the jail at the
moment on FreeBSD 12.2.
Loading...