FusionForge provides native security services by coupling your Postgresql database with the Name Service Switch (NSS). To use this functionality you need to compile, install and configure a NSS module that will handle communication with your database.
This module is called libnss_pgsql, and is available from . At the time of writing, the latest version is 1.4.0, which is used in this document and available for download here. And there's a also rpm available from. It's recommended to install libnss_pgsql via rpm. Note that different versions might have different compilation and configuration requirements.
UID and GID ranges
- System UID/GID range: [0 - 4,294,967,294]
- UID for FusionForge users: [20,001 - 65,534[
- GID for FusionForge users (dropped with FF 6.0): [20,001 - 65,534[
- GID for project groups: [10,001 - 50,000]
- GID for project SCMRW groups : [50,001 - 90,000]
- GID for project SCMRO groups : [100,001 - 140,000]
- ~45,000 users
- ~40,000 projects
The ID is the range is
groups.group_id in the database + range's start.
To test your system's limits:
sudo php -r 'posix_setgid(4294967294) or die(posix_strerror(posix_get_last_error()) . "\n"); posix_setuid(4294967294) or die(posix_strerror(posix_get_last_error()) . "\n"); system("id");'
If there's a real issue with these limitations, we can consider implementing dynamic UID allocation (without ranges), though this implies a more complex integration with the existing user accounts. Beware that existing installation rely on current UID/GIDs for quotas, and there's at least one instance that generates additional users for PHP webpages.
You can test the module with the following commands:
$ id <fusionforge_username> uid=38478(username) gid=100(users) groups=100(users),106029(project_scmro),56029(project_scmrw),16029(project) $ getent passwd <fusionforge_username> username:$1$Kk$SbtSNsMFBj1F/s1d/2aCU.:38478:38478:Real Name:/home/users/username:/bin/bash $ getent group <fusionforge_project_unixname> project:x:16029:username,username2 $ getent shadow <fusionforge_username> username:$1$Kk$SbtSNsMFBj1F/s1d/2aCU.:14087:0:99999:7:0:0:0
Should you encounter difficulties, try strace-ing the commands. For example:
$ strace getent group siteadmin
This documentation is for FusionForge 5.3 through RPM or source installation (aka Debian and FF 6.0 do it automatically.)
In this document we assume you are logged in as root on your server. We have successfully installed the module on CENTOS 5.7 Final, but on different UNIX based systems the process should work in a similar way.
There are two ways to install libnss_pgsql. It's recommended to install it via rpm.
The rpm file can be downloaded from . libnss-pgsql-1.4.0-2.x86_64.rpm will be used here.
After downloading the rpm file, install it by yum:
yum localinstall libnss-pgsql-1.4.0-2.x86_64.rpm --nogpgcheck
First we need to download and unpack the library, and set up our installation directory. Note that we use the /opt directory.
$ cd /opt $ wget http://pgfoundry.org/frs/download.php/605/libnss-pgsql-1.4.0.tgz $ tar -xvvf libnss-pgsql-1.4.0.tgz $ mkdir libnss_pgsql
Compilation and Installation
We start by compiling the library, using our installation directory as prefix and explicitly naming the directory where the configuration file will be stored. The latter needs to be done explicitly, since the library's defaults are not intuitive - at least in our case they weren't.
$ cd /opt/libnss-pgsql-1.4.0 $ ./configure --prefix=/opt/libnss_pgsql --sysconfdir=/etc $ make $ make install $ make distclean
Since we have installed the library in /opt/libnss_pgsql, we'll have to adjust the global library path to make sure the system can find our module. This is generally done in the loader-deamon's configuration, found at /etc/ld.so.conf.
Include the following on the first line of this file:
After this we need to rebuild the loader-deamon's cache file by running:
Now we need to configure both NSS and libnss_pgsql so that the former will utilize the latter, and the latter will be able to access the database and knows how to query your table structure.
For NSS to be able to utilize our new module, we need to add the module's name to its configuration. Convention tells us that it will look for a module (on the loader-deamon's path) by the name of libnss_[LIBNAME]. Therefor we will add pgsql as a module to use for passwd and group resolving. This is done in /etc/nsswitch.conf, at the passwd and group lines:
passwd: files pgsql group: files pgsql
The next step is to configure our module so that it can connect to our Postgresql server and understands FusionForge's table structure. Our compiled module includes a sample configuration that should reflect the parameters it expects and what it should return. This files can be produced by utils/install-nsspgsql.sh. Running "utils/install-nsspgsql.sh configure-files" will produce three files: nss-pgsql.conf.gforge-new, nss-pgsql-root.conf.gforge-new, nsswitch.conf.gforge-new. Rename these files to nss-pgsql.conf.gforge, nss-pgsql-root.conf, nsswitch.conf respectively, i.e remove "gforge-new" string in the file names.
Now we edit our queries in this file if needed. For us, the following works. You should be able to copy-paste it, fill in your password and have it working, providing you use all versions as specified above:
passwd: files pgsql #Added by GForge install #Comment by GForge install#passwd: files shadow: files pgsql #Added by GForge install #Comment by GForge install#shadow: files group: files pgsql #Added by GForge install #Comment by GForge install#group: files bootparams: nisplus [NOTFOUND=return] files ethers: files netmasks: files networks: files protocols: files rpc: files services: files netgroup: nisplus publickey: nisplus automount: files nisplus aliases: files nisplus
#----------------- DB connection connectionstring = user=gforge dbname=gforge #----------------- NSS queries getpwnam = SELECT login AS username,passwd,gecos,('/var/lib/gforge/chroot/home/users/' || login) AS homedir,shell,uid,gid FROM nss_passwd WHERE login = $1 getpwuid = SELECT login AS username,passwd,gecos,('/var/lib/gforge/chroot/home/users/' || login) AS homedir,shell,uid,gid FROM nss_passwd WHERE uid = $1 #allusers = SELECT login AS username,passwd,gecos,('/var/lib/gforge/chroot/home/users/' || login) AS homedir,shell,uid,gid FROM nss_passwd getgroupmembersbygid = SELECT login AS username FROM nss_passwd WHERE gid = $1 getgrnam = SELECT name AS groupname,'x',gid,ARRAY(SELECT user_name FROM nss_usergroups WHERE nss_usergroups.gid = nss_groups.gid) AS members FROM nss_groups WHERE name = $1 getgrgid = SELECT name AS groupname,'x',gid,ARRAY(SELECT user_name FROM nss_usergroups WHERE nss_usergroups.gid = nss_groups.gid) AS members FROM nss_groups WHERE gid = $1 #allgroups = SELECT name AS groupname,'x',gid,ARRAY(SELECT user_name FROM nss_usergroups WHERE nss_usergroups.gid = nss_groups.gid) AS members FROM nss_groups groups_dyn = SELECT ug.gid FROM nss_usergroups ug, nss_passwd p WHERE ug.uid = p.uid AND p.login = $1 AND ug.gid <> $2
### NSS Configuration for Gforge #----------------- DB connection shadowconnectionstring = user= dbname=gforge #----------------- NSS queries shadowbyname = SELECT login AS shadow_name, passwd AS shadow_passwd, 14087 AS shadow_lstchg, 0 AS shadow_min, 99999 AS shadow_max, 7 AS shadow_warn, AS shadow_inact, AS shadow_expire, AS shadow_flag FROM nss_passwd WHERE login = $1 shadow = SELECT login AS shadow_name, passwd AS shadow_passwd, 14087 AS shadow_lstchg, 0 AS shadow_min, 99999 AS shadow_max, 7 AS shadow_warn, AS shadow_inact, AS shadow_expire, AS shadow_flag FROM nss_passwd
Last but not least we need to make sure that FusionForge itself understands the type of authentication we want to use. This is important, because it needs to fill up the right tables in our database.
To achieve this we edit /etc/gforge/local.inc, find the $sys_account_manager_type variable and edit it to reflect:
$sys_account_manager_type = "pgsql";
Reload nscd (restart the service will not work):
service nscd reload
service unscd reload
or more directly:
nscd -i passwd && nscd -i group
Note this is important. It will flush the NSCD’s cache so that users in database can be fetched instead of only in /etc/passwd.
Also, using nscd or unscd is mandatory to avoid a loop in the NSS chain, see: User_accounts#nscd.