Copyright © 2001, 2004, 2005 Jörg Wendland, Wichert Akkerman, Russell Smith
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation. There are no invariant sections. A copy of the license is included in the section entitled "GNU Free Documentation License".
Table of Contents
List of Examples
This document covers setup and use of the Name Service Switch (NSS)
Module libnss-pgsql.so
. Its purpose is replace the
flatfile user, group and shadow databases in /etc
with a
relational database on a PostgreSQL server. It is highly configurable to
fit onto most existing databases.
For installation instructions please see the files
README
and INSTALL
in the
source distribution.
To use this module you will need a PostgreSQL database containing some sort of user account information. See Example A.1, “Database schema” for an example database.
Table of Contents
To use this module with a database you will need at least three tables
in that database. One for account data (the information usually stored
in /etc/passwd
), one for group data
(/etc/group
) and another one storing information
about groupmembership (there is a m:n relation between passwd and group
so you need this weak entity). If you have an existing database you do
not want to modify you can use views or table expressions (see
Example A.2, “Configuration file”), of course. You can also optionally store
shadow information (/etc/shadow
) in the database
as well. Depending on your security requirements another table or view
may be needed.
There have to be some required fields in those tables. They are described below.
login name
password
numerical user id (uid)
numerical primary group id (gid)
login shell
description (gecos)
home directory
group name
group password
numerical group id (gid)
An example database schema can be found in Example A.1, “Database schema”. See there for how to construct the groupmember table.
Having a working database, you must write your configfile
/etc/nss-pgsql.conf
. If you also want shadow
support, you must write a second config file
/etc/nss-pgsql-root.conf
These files have a simple syntax:
LINE := COMMENT | EMPTY | STATEMENT COMMENT := '#' <text> EMPTY := '' STATEMENT := KEYWORD '=' <value>
With KEYWORD being one of the following (all are required):
The connection string to connect to the server. You can include any valid PostgreSQL options.
A query that returns passwd_name, passwd_passwd, passwd_gecos, passwd_dir, passwd_shell, passwd_uid, passwd_gid for a given username
A query that returns passwd_name, passwd_passwd, passwd_gecos, passwd_dir, passwd_shell, passwd_uid, passwd_gid for a given uid
A query that returns group_name, group_passwd, group_gid for a given group name
A query that returns group_name, group_passwd, group_gid for a given gid
A query that returns username, password, gecos, home_dir, shell, uid, primarygid for every user
A query that returns group_name, group_passwd, group_gid for every group
A query that returns a list of gid's a particular user is in. excluding their primary group.
A query that returns a list of usernames for a given gid
A query returning shadow_name, shadow_passwd, shadow_lstchg, shadow_min, shadow_max, shadow_warn, shadow_inact, shadow_expire, shadow_flag for a given username
A query returning shadow_name, shadow_passwd, shadow_lstchg, shadow_min, shadow_max, shadow_warn, shadow_inact, shadow_expire, shadow_flag for all users
![]() | Caution |
---|---|
You can do serious damage to your system if you do not know what you
are doing! If you are trying changes in the Name Service Switch for the
very first time, consider doing that in a chroot environment or a test
machine. Have at least an editor with
|
Setting up the Name Service Switch is fairly easy, given a
working installation of the libnss-pgsql module. Just add an
entry pgsql the passwd and
group lines of
/etc/nsswitch.conf
. You can tune the behaviour with
options between the entries to get a fully working system. Useful lines
in /etc/nsswitch.conf
would look like these:
passwd: files [SUCCESS=continue] pgsql group: files [SUCCESS=continue] pgsql shadow: files [SUCCESS=continue] pgsql
This will make your libc look into the standard
passwd
and group
files first
and then use libnss-pgsql. The option
[SUCCESS=continue] ensures that all accounts or groups
are retrieved when using the iteration functions
getpwent(3) and
getgrent(3).
Example A.1. Database schema
-- Default table setup for nss-pgsql CREATE SEQUENCE group_id MINVALUE 1000 MAXVALUE 2147483647 NO CYCLE; CREATE SEQUENCE user_id MINVALUE 1000 MAXVALUE 2147483647 NO CYCLE; CREATE TABLE "group_table" ( "gid" int4 NOT NULL DEFAULT nextval('group_id'), "groupname" character varying(16) NOT NULL, "descr" character varying, "passwd" character varying(20), PRIMARY KEY ("gid") ); CREATE TABLE "passwd_table" ( "username" character varying(64) NOT NULL, "passwd" character varying(128) NOT NULL, "uid" int4 NOT NULL DEFAULT nextval('user_id'), "gid" int4 NOT NULL, "gecos" character varying(128), "homedir" character varying(256) NOT NULL, "shell" character varying DEFAULT '/bin/bash' NOT NULL, PRIMARY KEY ("username") ); CREATE TABLE "usergroups" ( "gid" int4 NOT NULL, "uid" int4 NOT NULL, PRIMARY KEY ("gid", "uid"), CONSTRAINT "ug_gid_fkey" FOREIGN KEY ("gid") REFERENCES "groups"("gid"), CONSTRAINT "ug_uid_fkey" FOREIGN KEY ("uid") REFERENCES "accounts"("uid") ); CREATE TABLE "shadow_table" ( "username" character varying(64) NOT NULL, "passwd" character varying(128) NOT NULL, "lastchange" int4 NOT NULL, "min" int4 NOT NULL, "max" int4 NOT NULL, "warn" int4 NOT NULL, "inact" int4 NOT NULL, "expire" int4 NOT NULL, "flag" int4 NOT NULL, PRIMARY KEY ("username") );
Example A.2. Configuration file
connectionstring = hostaddr=127.0.0.1 dbname=unix user=postgres password=XXX connect_timeout=1 # you can use anything postgres accepts as table expression # Must return "usernames", 1 column, list getgroupmembersbygid = SELECT username FROM passwd_table WHERE 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_table 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_table WHERE uid = $1 # All users allusers = SELECT username, passwd, gecos, homedir, shell, uid, gid FROM passwd_table # Must return group_name, group_passwd, group_gid getgrnam = SELECT groupname, passwd, gid FROM group_table WHERE groupname = $1 # Must return group_name, group_passwd, group_gid getgrgid = SELECT groupname, passwd, gid FROM group_table WHERE gid = $1 # Must return gid. %s MUST appear first for username match in where clause groups_dyn = SELECT ug.gid FROM passwd_table JOIN usergroups USING (uid) where username = $1 and ug.gid <> $2 allgroups = SELECT groupname, passwd, gid FROM group_table
# example configfile for PostgreSQL NSS module # this file must be readable for root only connectionstring = hostaddr=127.0.0.1 dbname=unix user=postgres connect_timeout=1 #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_table WHERE username = $1 shadow = SELECT * FROM shadow_table