1. 유저들을 공통 그룹으로 묶고 umask 와 setgid 를 이용해서 퍼미션과 그룹권한을 유지시키는 방법
2. CVSROOT/passwd 를 이용하여 CVS passwd 의 User map 을 이용하는 방법
3. CVSROOT tree 의 모든 파일들에 주기적으로 w 권한을 주는 방법
등등 여러가지 형태로 운영이 되는데, 이를 근본적으로 해결할 길이 없을까 찾다가 그냥, 패치를 해 보았습니다. 원래는 2번의 방법을 애용했었는데, 이번에 개발서버들을 AD + winbind 를 이용하여 Active directory
를 이용하여 통합 인증을 구현하다 보니, 2번의 방법이 상당히 번거로와 졌는데, 결국 이를 해결하기 위해, cvs 1.12 의 pam pactch (1.11 을 위한 패치는 Fedora 5 의 cvs 에 들어 있습니다.) 와 아래의 usermap patch 를 만들게 되었네요.
요즘은 SVN 을 많이 사용하는 것 같은데, CVS data 가 너무 많아서 SVN 으로 가기는 힘들거나 귀찮고, user mapping 이 필요한 경우에는 사용하시면 유용할 것 같습니다. 설정은.. CVSROOT/usermap 파일을 생성하시고, loginuser:mapping_user 와 같이 한라인에 하나씩 지정 하시면 됩니다. mapping_user 는 system 에 존재하는 계정이어야 합니다.
diff -urNp src.org/server.c src/server.c
--- src.org/server.c 2006-08-21 18:47:02.000000000 +0900
+++ src/server.c 2006-08-21 20:17:57.000000000 +0900
@@ -5785,7 +5785,53 @@ handle_return:
It might or might not be the same as host_user. */
CVS_Username = xmalloc (strlen (username) + 1);
strcpy (CVS_Username, username);
- }
+
+ if ( ! strcmp (username, host_user) ) {
+ char filename[256] = { 0, };
+ FILE *op;
+ int userlen = strlen (username);
+ char *linebuf = NULL;
+ size_t linebuf_len;
+ sprintf (filename, "%s/%s/usermap", repository, CVSROOTADM);
+
+ syslog (LOG_DAEMON | LOG_NOTICE, "oops: %s", filename);
+
+ op = CVS_FOPEN (filename, "r");
+ if ( op != NULL ) {
+ while ( getline (&linebuf, &linebuf_len, op) >= 0 ) {
+ if ( (strncmp (linebuf, username, userlen) == 0)
+ && (linebuf[userlen] == ':') ) {
+ char *mapuser = NULL;
+ char *ws = NULL;
+ char mapuserlen = 0;
+
+ mapuser = strchr (linebuf, ':');
+ if ( (ws = strchr (mapuser, ' ')) )
+ mapuser[ws - mapuser] = 0;
+ else if ( (ws = strchr (mapuser, '\t')) )
+ mapuser[ws - mapuser] = 0;
+ else if ( (ws = strchr (mapuser, '\r')) )
+ mapuser[ws - mapuser] = 0;
+ else if ( (ws = strchr (mapuser, '\n')) )
+ mapuser[ws - mapuser] = 0;
+
+ mapuserlen = strlen (mapuser) - 1;
+ if ( mapuserlen > 0 ) {
+ free (host_user);
+ host_user = xstrdup (mapuser + 1);
+ }
+ break;
+ }
+ }
+ }
+ if (linebuf) free (linebuf);
+
+ if ( ferror (op) )
+ error (0, errno, "cannot read %s", filename);
+ if ( fclose (op) < 0 )
+ error (0, errno, "cannot close %s", filename);
+ }
+ }
return host_user;
}