/ home  / projects  / samba-pgsql

Samba-PostGreSQL SAM

This is extremely beta!

One of the big questions asked in Samba, and indeed in almost all unix services is if its possible to unify the passwords between them. Whether or not this is a Good Thing has been debated endlessly, however I know that I would love not to have the duplication of effort required in maintaining many user bases.

To this end I have set up from scratch a Linux system that runs almost entirely from a PostGreSQL database. All configuration options are read from the database and all users/groups are stored in the database. By using a NSSWITCH module for PostGreSQL and making some elaborate views on my User/Group tables, I have managed to allow users/groups in the database to be used in file permissions etc. Also, as I am no longer limited to the /etc/group file where you can only specify users as members, I can now make groups part of other groups.

Now I would like Samba to authenticate against these tables and indeed to be able to store machine accounts etc. Samba has support for LDAP authentication but as I really don't like LDAP I needed another solution. If necessary I'd LDAP frontend with PG as the backend but I'd like to avoid this if possible. To this end I spent a day looking through the Samba code and have written an authentication module for PostGreSQL. It wasn't hard, and most of the work had already been done in the TDB and LDAP modules.

I'm still working on this but as I see the queries for PGSQL modules fairly often in the newsgroups I'm going to put up what I've done so far. Hopefully you can use it and modify it to your own needs. I've tried to make it fairly generic. Eventually I'll provide a diff that does all the following but I'm busy now!

In order to install, you're going to need to do the following: -

  • Extract Samba V2.2.8a somewhere.
  • Copy pdb_pgsql.c into Samba/source/passdb.
  • Copy loadparm.c into Samba/source/param. This will overwrite a file there. Otherwise copy and paste all the stuff from my file that is between the #ifdef WITH_PGSQL markers.
  • Copy proto.h into Samba/source/include. Note that this will overwrite a file there. Otherwise copy and paste all the lines under the section /* pgsql Stuff */
  • Do a configure, then edit include/config.h and add the following three lines to it:
           #define WITH_PGSQL 1
           #define WITH_PGSQL_SAM 1
           #undef  WITH_SMBPASSWD_SAM
          
  • Do a make and it should hopefully compile. Install it
  • Edit smb.conf and add the pgsql config options to it

The pgsql config options to smb.conf are as follows:

  • pg server = xxx.xxx.xxx.xxx - The address of the database server
  • pg database = dbname - The name of the database
  • pg user = dbuser - The database username
  • pg password = dbpass - The database username's password
  • pg query byusername = SELECT *... - The query needed to retrieve the details of a user. %username will be expanded to the username.
  • pg query byuid = SELECT * ... - The query needed to retrieve the details of a user. $uid will expand to the uid.
  • pg query byrid = SELECT * ... - The query needed to retrieve the details of a user. %rid will expand to the rid. If this is not set the rid will be converted to a uid and the uid query will be run.
  • pg update byusername = UPDATE ... - The update query needed to update a user. Currently %f expands to fullname, %d to description, %l to Lanman password, %n to NT password, %u to username.
  • pg delete by username = DELETE ... - The delete query needed to delete a user. Currently %username expands to username.

For the SELECT queries, the following column names are needed:

  • uid, username, gid

For the SELECT queries, the following columns are used if available:

  • pwdLastSet, logonTime, logoffTime, kickoffTime, pwdCanChange
  • pwdMustChange, displayName, homedrive, smbhome, scriptPath
  • profilePath, description, userWorkstations, rid, primaryGroup
  • lm_pw, nt_pw, plainPassword, acctFlags

If plainPassword exists, AND lm_pw and nt_pw do not exist or are blank, then the lanman and nt hashes are generated from the plainPassword.

My smb.conf has the following for the queries:

  • pg query byusername = SELECT * from v_sambaAccount WHERE username='%username';
  • pg query byuid = SELECT * from v_sambaAccount WHERE uid='%uid';
  • pg update byusername = UPDATE authuser SET authuser_fullname='%f', authuser_description='%d', authuser_passwd_lm='%l', authuser_passwd_nt='%n' WHERE authuser_username='%u';

My database has the following for v_sambaAccount view:

auth=# \d v_sambaaccount
         View "public.v_sambaaccount"
    Column     |       Type        | Modifiers
---------------+-------------------+-----------
 uid           | integer           |
 username      | character varying |
 plainpassword | character varying |
 nt_pw         | character varying |
 lm_pw         | character varying |
 displayname   | character varying |
 smbhome       | character varying |
 description   | character varying |
    

View definition: SELECT (authuser.authuser_id + 10000) AS uid, authuser.authuser_username AS username, authuser.authuser_password AS plainpassword, authuser.authuser_passwd_nt AS nt_pw, authuser.authuser_passwd_lm AS lm_pw, authuser.authuser_fullname AS displayname, ('/data/user/'::character varying || authuser.authuser_username) AS smbhome, authuser.authuser_description AS description FROM authuser;

There is probably heaps of things still wrong with this code as I've not tested it fully yet. Also you will note that a lot of the code is exactly the same as the LDAP code so they deserve most of the credit.

Download


HTTP Directory