Rails Recipe: NIS/YP Login for Ruby on Rails (RoR)
Tilo Sloboda, Jan 2006
Most examples of Rails login controllers in books assume you store the
user passwords in your database. This may be good for applications
where you have 'random' users sign-up via the web. However in an
enterprise environment you want to leverage the existing NIS/YP
infrastructure or LDAP infrastructure, and not maintain user passwords
in your application. Usually in a large enterprise environment all the
user data is stored/maintained in LDAP, and the data from the NIS
database is fed from the LDAP master.
This Rails recipe shows how to use check user passwords against an existing NIS/YP server.
Ingredients:
You will need the 'ruby-nis' library from
Takaaki Tateishi, which is available at http://sourceforge.net/projects/ruby-nis/ and http://raa.ruby-lang.org/project/ruby-nis/
. You will need to download it, un-tar it, and then do a
'ruby extconf.rb' to create a Makefile. After that you need to run
'make' and 'make install' as root. After you installed the Ruby
NIS library, you can start an irb session and type: require 'irb'
If the result is 'true', then the library installation succeeded.
You need to make sure that the machine where you intend to run/develop your Rails application on has a working NIS/YP setup.
You can type "ypwhich" to verify that it can bind to a NIS server -- this UNIX command should yield the name of the NIS-server.
Implementation:
Go to your Rails application's directory.
ruby script/generate migration add_user_table
Then fill out the migration code to look like this:
class AddUserTable < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column "nis_userid",
:string # a user's
UNIX user name, e.g. 'tilo'
t.column "unix_uid",
:integer # a user's
UNIX UID, e.g. '1001'
t.column "unix_gid",
:integer #
a user's UNIX GID, e.g. '123'
t.column "fullname",
:string
# a user's full name - taken from NIS - e.g. 'Tilo Sloboda'
t.column "homedir",
:string
# a user's home directory, e.g. '/home/tilo'
t.column "first_login", :datetime
t.column "last_login", :datetime
end
end
def self.down
drop_table :users
end
end
This user record captures most of what is stored in NIS, but please
note that it does not capture or store the user's password. The benefit
of this is that the user can maintain/change his/her password in a
central location (usually provided by IT), and that you don't have to
worry about users who change or forget their passwords.
Please note that the userid above is the user's UNIX user-id. Do not
confuse this with user.id, which refers to the primary key 'id" of the
user table.
We will have to make sure that a user's record only gets created after s/he successfully logs in.
We can now use the migration above to generate the database table with the following command:
rake migrate
Next, we will need an Active Record model to support our new table:
ruby script/generate model User
Please note that we will not generate any users manually through an
admin interface! The reason is simple: our application is not
authoritative to create new users - it's merely a consumer of the user
records which are already stored in NIS/YP! The
authoritative source is either LDAP or NIS.