【环境】
[root@localhost ~]# cat /etc/issue
Red Hat Enterprise Linux AS release 4 (Nahant Update 4)
[root@localhost ~]# cvs --version
Concurrent Versions System (CVS) 1.11.22 (client/server)
with CVSACL Patch 1.2.5 (cvsacl.sourceforge.net)
【CVS服务器配置】
1. 验证是否已安装CVS
[root@localhost ~]# rpm -q cvs
cvs-1.11.17-9.RHEL4
(出现上述类似的版本信息,说明已安装CVS)
2. 下载CVSACL
一般来说,Linux下都有安装CVS,但是版本都比较低,得去下载含有ACL的CVS安装包,以下为下载链接:
http://sourceforge.net/projects/cvsacl/files/cvsacl/cvsacl-1.2.5/
共有2个文件
cvsacl-1.2.5-for-cvs-1.11.22.tar.gz ------补丁包
cvs-1.11.22-cvsacl-1.2.5-patched.tar.gz ------安装包+补丁包
这个安装包是CVS+ACL的安装包,为什么下载这样的安装包,原因在于我们单单安装CVS满足不了我们目录权限控制要求,还得安装ACL来加强CVS目录权限的控制。
3. 安装CVSACL
//上传cvs-1.11.22-cvsacl-1.2.5-patched.tar.gz至/tmp,解压缩
[root@localhost tmp]# tar -zxvf cvs-1.11.22-cvsacl-1.2.5-patched.tar.gz
//修改cvs-1.11.22-cvsacl-1.2.5-patched目录名称为 cvs-1.11.22
[root@localhost tmp]# mv cvs-1.11.22-cvsacl-1.2.5-patched cvs-1.11.22
//编译安装
[root@localhost tmp]# cd cvs-1.11.22
[root@localhost cvs-1.11.22]# ./configure
[root@localhost cvs-1.11.22]# make
[root@localhost cvs-1.11.22]# make install
//查看cvs版本
[root@localhost setup_cvs]# cvs –version
如果显示以下内容表示安装成功
Concurrent Versions System (CVS) 1.11.22 (client/server)
with CVSACL Patch 1.2.5 (cvsacl.sourceforge.net)
(注:如果系统中已安装CVS,不必删除,直接安装CVSACL即可。)
4. 创建cvspserver文件
以root用户登陆系统,在/etc/xinetd.d/ 目录下创建一个cvspserver 文件(xinetd.d 的服务配置文件,可任意定义服务名称),内容如下:
service cvspserver
{
disable = no
socket_type = stream
protocol = tcp
user = root
wait = no
server = /usr/bin/cvs
server_args = -f --allow-root=/cvsdata/sys pserver
log_on_success += USERID
log_on_failure += USERID
}
(/cvsdata/sys 这里作为存放仓库数据目录,如果需要多个存放目录可以一直添加,例如:server_args = -f --allow-root=/cvsdata/sys --allow-root=/cvsdata/ppda pserver)
5. CVS服务配置
修改/etc/services 文件,增加如下两行:
cvspserver 2401/tcp # CVS client/server operations
cvspserver 2401/udp # CVS client/server operations
(一般来说,如果默认安装了CVS,则这两行是默认存在,无需添加;若这两行前面存在#字键,则把它们去掉。)
然后执行命令service xinetd restart 重新启动xinetd 服务即可,例如:
[root@localhost ~]# service xinetd restart
Stopping xinetd: [ OK ]
Starting xinetd: [ OK ]
至此,xinetd 监听端口2401,并在有客户端连接2401 时,将所有来自网络的连接包转给/usr/bin/cvs 程序作为其标准输入,将cvs程序向标准输出输出的内容通过socket 输出到客户端程序,建立客户端程序与cvs 程序之间的c/s 结构的数据通讯。我们为使用:psever: 方式远程访问CVS 数据库做好了必要的配置。
【CVS权限控制】
1. 使用root 用户创建用于CVS的专用系统组和用户
[root@localhost ~]# groupadd cvs
[root@localhost ~]# useradd -g cvs -G cvs -d /cvsdata cvsroot
2. 用户cvsroot 登陆,初始化cvs服务器环境
[cvsroot@localhost ~]$ cvs -d /cvsdata/sys init
cvs 初始化指令执行完成后,在初始化目录/cvsdata/sys 下会产生CVSROOT文件夹,安装ACL包的CVS会在CVSROOT目录下多产生三个文件:Aclconfig、Access、Aclconfig,v
3. 设置CVS配置库归属及权限
//修改权限为用户和组用户可以读&写&执行
[cvsroot@localhost ~]$ chmod 777 -R /cvsdata/sys
4. 创建CVS用户
[cvsroot@localhost ~]$ cd /cvsdata/sys/CVSROOT
//使用apache htpasswd 命令,先创建一个跟系统用户cvsroot 相同名字的cvs用户
[cvsroot@localhost CVSROOT]$ htpasswd –c passwd cvsroot
//上述创建的cvsroot 用户信息及其密码会保存在CVSROOT目录中的passwd 文件中。(-c表示创建密钥文件,文件名为passwd,cvsroot 为帐户名。密码已经用CRYPT encryption 加密后存在passwd 文件中。)
[cvsroot@localhost CVSROOT]$ vi passwd
cvsroot:z/bkn3gJA/1Jk
这里需要注意,passwd的文件完整格式是:
login_name:password:uid:gid:user_name:home:shell
使用htpasswd –c 生成的passwd 文件中的用户并没有指定user_name,即只有两项:
login_name:password
使用此用户能成功登录CVS,但是如果进行任何的操作会提示没有此系统用户,需要补全passwd 文件内容,将格式改为:
login_name:password:user_name
例如:cvsroot:z/bkn3gJA/1Jk:cvsroot
增加用户指令:
[cvsroot@localhost CVSROOT]$ htpasswd –b passwd login_name1 login_name1_passwd
其中passwd为密码文件名,login_name1 为CVS用户名,login_name1_passwd 为用户密码,同样增加完用户后也要编辑passwd 文件,增加user_name(这里是:cvsroot)。
//假设这里还需要额外4个CVS用户
[cvsroot@localhost CVSROOT]$ htpasswd –b passwd login_name2 login_name2_passwd
[cvsroot@localhost CVSROOT]$ htpasswd –b passwd login_name3 login_name3_passwd
[cvsroot@localhost CVSROOT]$ htpasswd –b passwd login_name4 login_name4_passwd
[cvsroot@localhost CVSROOT]$ htpasswd –b passwd login_name5 login_name5_passwd
5. 修改/cvsdata/sys/CVSROOT/aclconfig 配置文件
//取消使用系统的组用户,使用CVS的组用户
[cvsroot@localhost CVSROOT]$ vi /cvsdata/sys/CVSROOT/aclconfig
# Set `UseSystemGroups' to yes to use system group definitions (/etc/group).
#UseSystemGroups=yes
# Set `UseCVSGroups' to yes to use another group file.
UseCVSGroups=yes
说明:
UseSystemGroups=yes 行首添加“#”,表示注释掉。
UseCVSGroups=yes 去除行首的“#”,表示启用此句。
6. 创建CVS组
在CVSROOT文件夹中创建group 文件,并将cvs的用户添加到此组中
[cvsroot@localhost CVSROOT]$ touch /cvsdata/sys/CVSROOT/group
group文件格式如下:
group_name:x:1:login_name1,login_name2,login_name3
login_name 之间以“,”隔开。
注:cvsacl有个bug,必须在组用户最前边添加一个不存在的cvs用户,group 文件才会生效。即login_name1 为一个不存在的cvs用户(没有在passwd文件中无此用户)
例如:
modules_admin_groud:x:1:nonexistence,login_name1,login_name2
modules_dir1_groud:x:1:nonexistence,login_name3
modules_dir2_groud:x:1:nonexistence,login_name4
modules_dir3_groud:x:1:nonexistence,login_name5
modules_dir4_groud:x:1:nonexistence,login_name3,login_name4,login_name5
7. 使用cvsacl细化权限
使用cvs racl 命令设置权限,命令执行成功后,会在屏幕中显示执行结果,并且会在access 文件(就是在“初始化cvs服务器环境”中提到的使用acl 在CVSROOT中多出来的3个文件之一)中记录用户对于指定目录的权限信息。
a)命令说明
Usage: cvs racl [user||group:permissions] [-Rl] [-r tag] [directories...] [files...]
-R Process directories recursively.
-r rev Existing revision/tag.
-l List defined ACLs.
b)权限参数
c)如果没有通过cvs racl指定用户或组对某个文件的权限,那么这个用户或组会对此目录具有最大权限(只受文件本身属性限制)
因此在实际对CVS中的项目进行权限设置时,必须指定用户对每一个文件的权限,但是如果设置了默认访问权限为n,那么就存在这个问题。
d)添加管理员权限
[cvsroot@localhost ~]$ cd /cvsdata/sys
[cvsroot@localhost sys]$ cvs -d /cvsdata/sys/ racl cvsroot:p –r ALL ALL
(使用命令:cvs --help-options 可知“-d /cvsdata/sys/ ”的说明: -d CVS_root Overrides $CVSROOT as the root of the CVS tree.)
查看access 文件的权限设置信息
[cvsroot@localhost ~]$ vi CVSROOT/access
# CVS ACL definitions file. DO NOT EDIT MANUALLY
d:ALL:ALL:cvsroot!p:
由于我们需要个管理员管理cvs的日常维护,所以我们设置cvsroot为具有全部权限。
此时需要设置其他用户对目录文件的默认访问权限为n(用户不能做任何CVS操作)
//再次修改/cvsdata/sys/CVSROOT/aclconfig 配置文件(注意:如果在上一次配置aclconfig时作如下修改,则对cvsroot用户的权限授予会报错)
[cvsroot@localhost CVSROOT]$ vi /cvsdata/sys/CVSROOT/aclconfig
# Default CVSACL Permission to use.
CVSACLDefaultPermissions=n
e)添加并设置其他用户(组)对modules 相关目录的权限
// 添加modules 目录
[cvsroot@localhost sys]$ mkdir modules_name
// 设置组modules_admin_groud 对modules 目录modules_name 的权限
[cvsroot@localhost sys]$ cvs -d /cvsdata/sys/ racl modules_admin_groud:p –r ALL modules_name
那么项目组modules_admin_groud 成员login_name1、login_name2 就已经拥有了modules_name 目录的p权限;
// 类似,设置组modules_dir1_groud 对modules 目录modules_name/dir1 的权限
[cvsroot@localhost sys]$ cvs -d /cvsdata/sys/ racl modules_dir1_groud:p –r ALL modules_name/dir1
那么项目组modules_dir1_groud 成员login_name3 就已经拥有了modules_name/dir1 目录的p权限;
// 类似,设置组modules_dir2_groud 对modules 目录modules_name/dir2 的权限
[cvsroot@localhost sys]$ cvs -d /cvsdata/sys/ racl modules_dir2_groud:p –r ALL modules_name/dir2
那么项目组modules_dir2_groud 成员login_name4 就已经拥有了modules_name/dir2 目录的p权限;
// 类似,设置组modules_dir3_groud 对modules 目录modules_name/dir3 的权限
[cvsroot@localhost sys]$ cvs -d /cvsdata/sys/ racl modules_dir3_groud:p –r ALL modules_name/dir3
那么项目组modules_dir3_groud 成员login_name5 就已经拥有了modules_name/dir3 目录的p权限;
// 类似,设置组modules_dir4_groud 对modules 目录modules_name/dir4 的权限
[cvsroot@localhost sys]$ cvs -d /cvsdata/sys/ racl modules_dir4_groud:p –r ALL modules_name/dir4
那么项目组modules_dir4_groud 成员login_name3、login_name4、login_name5 就已经拥有了modules_name/dir4 目录的p权限;
综上所述:
成员login_name1、login_name2拥有对modules 下所有目录的p权限;
成员login_name3拥有对modules 下modules_name/dir1 和modules_name/dir4目录的p权限;
成员login_name4拥有对modules 下modules_name/dir2 和modules_name/dir4目录的p权限;
成员login_name5拥有对modules 下modules_name/dir3 和modules_name/dir4目录的p权限;