测试环境:Debian 6.0 (squeeze)
安装mysql、phpmyadmin、libpam-mysql和libnss-mysql
以下对数据库的操作使用phpmyadmin来实现。
创建数据库user_database,用于存放用户数据。
在数据库中创建以下的表
名称 | 说明 | 字段数 |
users | 每个记录对应于一个用户 | 15 |
groups | 每个记录对应于一个群 | 5 |
users_groups | 一个用户可包含到多个群中 | 2 |
需要注意的是,不可使用group作为表名称,因为group是SQL语句中的关键字
users表
字段 | 说明 | 类型 | 长度 | 默认值 | 备注 |
ID | 索引编号 | INT |
|
| 自动增长、主键 |
Account | 用户帐户 | VARCHAR | 64 | '' |
|
Name | 用户姓名 | VARCHAR | 64 | '' |
|
Shell | 用户Shell | VARCHAR | 32 | '/bin/bash' |
|
Password | 用户密码 | VARCHAR | 64 | '' | 可以是加密后的 |
Status | 账户状态 | CHAR | 1 | 'A' | A表示有效,否则无效 |
Uid |
| INT |
|
|
|
Gid |
| INT |
|
|
|
Home | 用户目录 | VARCHAR | 64 | '/home' |
|
LastChange | 最后修改日期(自1970年1月1日起的天数) | VARCHAR | 64 | '' |
|
Min | 两次修改口令之间所需的最小天数 | INT |
|
| 0表示无限制 |
Max | 口令保持有效的最大天数 | INT |
|
| 空白表示不限制密码有效期,这将不使用Warning和Inactive特性,但需要修改字段属性为VARCHAR来表示空白。一般用99999表示无限制。 |
Warning | 提前多少天通知密码失效 | INT |
|
| 0表示不警告(这可能需要修改字段属性为VARCHAR),一般为7 |
Inactive | 超过口令必须更改的日期多少天后,系统会自动将这个帐户停止 | INT |
|
| 空白表示不限制 |
Expire | 账户失效日期(自1970年1月1日起的天数) | VARCHAR | 64 |
| 空白表示不限制 |
groups表
字段 | 说明 | 类型 | 长度 | 默认值 | 备注 |
ID | 索引编号 | INT |
|
| 自动增长、主键 |
Name | 群名称 | VARCHAR | 64 | '' |
|
gid |
| INT |
|
|
|
Status | 群状态 | CHAR | 1 | 'A' | A表示有效,否则无效 |
Password | 群密码 | VARCHAR | 64 | 'x' |
|
users_groups群与用户关系表,此表用来表示每个群中的用户
字段 | 说明 | 类型 | 长度 | 默认值 | 备注 |
user_ID | 用户在users表中的编号 | INT |
|
| 不是uid |
groups_ID | 群在groups中的编号 | INT |
|
| 不是gid |
建立两个数据库用户PAM_user和PAM_root,其中pam_root有该数据库的全部权限,而PAM_user则仅能对users中部分字段和groups/users_groups全部字段进行查询
PAM_user可查询的字段:
ID | 索引编号 |
Account | 用户帐户 |
Name | 用户姓名 |
Shell | 用户Shell |
Status | 账户状态 |
uid |
|
gid |
|
Home | 用户目录 |
修改/etc/nsswitch.conf,改为(在以下三行后面添加mysql)
passwd: compat mysql
group: compat mysql
shadow: compat mysql
修改/etc/nss-mysql.conf的以下行,注意密码要设置为PAM_user的密码,若表的名字有改动,要相应修改(例如users改为abc,则users.gid应改为abc.gid)
conf.version = 2;
users.host =inet:localhost:3306;
users.database =user_database;
users.db_user = PAM_user;
users.db_password = PAM_user的密码;
#users.backup_host =inet:backup:3306;
#users.backup_database =nss_mysql_backup;
users.table = users;
users.where_clause =users.Status = 'A';
users.user_column =users.Account;
users.password_column =users.Password;
users.userid_column =users.ID;
users.uid_column = users.uid;
users.gid_column = users.gid;
users.realname_column =users.Name;
users.homedir_column =users.Home;
users.shell_column =users.Shell;
groups.group_info_table =groups;
groups.where_clause =groups.Status = 'A';
groups.group_name_column =groups.Name;
groups.groupid_column =groups.ID;
groups.gid_column =groups.gid;
groups.password_column =groups.Password;
groups.members_table =users_groups;
groups.member_userid_column =users_groups.users_ID;
groups.member_groupid_column =users_groups.groups_ID;
修改/etc/nss-mysql-root.conf的以下行,注意密码要设置为PAM_root的密码,若表的名字有改动,要相应修改(例如users改为abc,则users.gid应改为abc.gid)
conf.version = 2;
shadow.host =inet:localhost:3306;
shadow.database =user_database;
shadow.db_user = PAM_root;
shadow.db_password = PAM_root的密码;
#shadow.backup_host =inet:backup:3306;
#shadow.backup_database =nss_mysql_backup;
shadow.table = users;
shadow.where_clause =users.Status = 'A';
shadow.userid_column =users.ID;
shadow.user_column =users.Account;
shadow.password_column =users.Password;
shadow.lastchange_column =users.LastChange;
shadow.min_column = users.Min;
shadow.max_column = users.Max;
shadow.warn_column =users.Warning;
shadow.inact_column =users.Inactive;
shadow.expire_column =users.Expire;
为了避免其他用户看到PAM_root的密码,/etc/nss-mysql-root.conf应只允许root用户查看:
chown root/etc/nss-mysql-root.conf
chmod 600/etc/nss-mysql-root.conf
修改/etc/pam-mysql.conf的以下行,注意密码要设置为PAM_root的密码,若表的名字有改动,要相应修改(例如users改为abc,则users.gid应改为abc.gid)
users.host = localhost
users.database = user_database
users.db_user = PAM_root
users.db_passwd = PAM_root的密码
#users.where_clause = (host)
users.table = users
#users.update_table = (update_table)
users.user_column = Account
users.password_column = Password
#users.status_column = (statcolumn)
users.password_crypt = 1
#users.use_323_password =(use_323_passwd)
users.use_md5 = yes
#users.where_clause = (where)
#users.disconnect_every_operation = (disconnect_every_op) *1
#verbose = (verbose)
#log.enabled = (sqllog)
#log.table = (logtable)
#log.message_column = (logmsgcolumn)
#log.pid_column = (logpidcolumn)
#log.user_column = (logusercolumn)
#log.host_column = (loghostcolumn)
#log.rhost_column = (logrhostcolumn) *2
#log.time_column = (logtimecolumn)
为了避免其他用户看到PAM_root的密码,/etc/pam-mysql.conf应只允许root用户查看:
chown root /etc/pam-mysql.conf
chmod 600 /etc/pam-mysql.conf
修改/etc/pam.d/common-account,在pam_unix.so上面添加一行:
account sufficient pam_mysql.so config_file=/etc/pam-mysql.conf
修改/etc/pam.d/common-auth,在pam_unix.so上面添加一行:
auth sufficient pam_mysql.so config_file=/etc/pam-mysql.conf
修改/etc/pam.d/common-session,在pam_permit.so上面添加一行:
session sufficient pam_mysql.so config_file=/etc/pam-mysql.conf
修改/etc/pam.d/common-password,在pam_unix.so上面添加一行:
password sufficient pam_mysql.so config_file=/etc/pam-mysql.conf
对于新增加的用户,需要使用password来更新用户密码。
已验证,可支持密钥文件不询问密码直接登录。
为了方便使用,还需要实现以下脚本:
add_users.sh | 从文本文件批量导入 |
add_user.sh | 添加一个用户(交互式) |
delete_user.sh | 删除一个用户(按用户名) |
add_group.sh | 新建一个组 |
delete_group.sh | 删除一个组 |