LDAPでTLSを使用できるようにLDAPモジュールをldap-tacacs.cで置き換えます。
さらにLDAPでBIND DNを指定できるようにldap.cを修正します。
--- ldap.c.old Fri Mar 10 15:19:25 2006
+++ ldap.c Tue Jul 25 13:57:22 2006
@@ -130,6 +130,10 @@
char *ldap_base;
char *ldap_attribute;
char *ldap_tls;
+#ifdef BINDDN
+ char *ldap_binddn;
+ char *ldap_bindpw;
+#endif
char *buffer;
int rc, port;
LDAP *ldap;
@@ -151,6 +155,10 @@
ldap_base = strstr(ldap_server, "/base=");
ldap_attribute = strstr(ldap_server, "/attribute=");
ldap_tls = strstr(ldap_server, "/tls=");
+#ifdef BINDDN
+ ldap_binddn = strstr(ldap_server, "/binddn=");
+ ldap_bindpw = strstr(ldap_server, "/bindpw=");
+#endif
if ( ldap_port == NULL )
port = LDAP_PORT;
if ( ldap_port != NULL ) {
@@ -169,6 +177,16 @@
*ldap_tls = '\0';
ldap_tls += 5;
}
+#ifdef BINDDN
+ if ( ldap_binddn != NULL ) {
+ *ldap_binddn = '\0';
+ ldap_binddn += 8;
+ }
+ if ( ldap_bindpw != NULL ) {
+ *ldap_bindpw = '\0';
+ ldap_bindpw += 8;
+ }
+#endif
if ( ldap_base == NULL || ldap_attribute == NULL ) {
if (debug) report(LOG_DEBUG, "Error parse ldap base or ldap attribute to use to authenticate");
free(buffer);
@@ -178,6 +196,15 @@
free(buffer);
return LDAP_FAIL;
}
+#ifdef BINDDN
+ if (ldap_binddn != NULL && ldap_bindpw != NULL) {
+ if (ldap_simple_bind_s(ldap, ldap_binddn, ldap_bindpw) != LDAP_SUCCESS) {
+ report(LOG_DEBUG, "Cannot bind by binddn\n");
+ free(buffer);
+ ldap_close(ldap);
+ }
+ }
+#endif
rc = ldap_verify_password(ldap,ldap_base, ldap_attribute, userid, password);
free(buffer);
ldap_close(ldap);
--- ldap.h.old Fri Mar 10 15:19:25 2006
+++ ldap.h Tue Jul 25 13:57:22 2006
@@ -1 +1,4 @@
int ldap_verify();
+
+/* ldap search with not anonymous bind but simple bind */
+#define BINDDN
sys/types.hをインクルードできるようにします。
--- config.h.in.old Tue Dec 19 01:58:02 2000 +++ config.h.in Tue May 16 14:13:19 2006 @@ -89,3 +89,5 @@ * /etc/shadow */ #undef SHADOW_PASSWORDS +/* Define if you have theheader file. */ +#undef HAVE_SYS_TYPES_H --- configure.old Sat Mar 17 00:05:09 2001 +++ configure Tue May 16 14:16:40 2006 @@ -1891,7 +1891,7 @@ fi -for ac_hdr in fcntl.h malloc.h strings.h sys/file.h sys/ioctl.h sys/time.h syslog.h unistd.h +for ac_hdr in fcntl.h malloc.h strings.h sys/file.h sys/ioctl.h sys/time.h sys/types.h syslog.h unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --- configure.in.old Sat Mar 17 00:05:06 2001 +++ configure.in Tue May 16 14:15:30 2006 @@ -152,7 +152,7 @@ dnl Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h malloc.h strings.h sys/file.h sys/ioctl.h sys/time.h syslog.h unistd.h) +AC_CHECK_HEADERS(fcntl.h malloc.h strings.h sys/file.h sys/ioctl.h sys/time.h sys/types.h syslog.h unistd.h) AC_CHECK_HEADERS(shadow.h,[ if test -f /etc/shadow ; then AC_DEFINE(SHADOW_PASSWORDS)
wtmpfileのI/OをFreeBSDでもできるようにしておきます。
--- do_acct.c.old Tue Dec 19 01:58:02 2000
+++ do_acct.c Mon Jul 24 12:31:07 2006
@@ -159,7 +159,11 @@
#endif
entry.ut_time = utime;
+#ifdef FREEBSD
+ wtmpfd = open(wtmpfile, O_CREAT | O_WRONLY | O_APPEND | O_FSYNC, 0644);
+#else
wtmpfd = open(wtmpfile, O_CREAT | O_WRONLY | O_APPEND | O_SYNC, 0644);
+#endif
if (wtmpfd < 0) {
report(LOG_ERR, "Can't open wtmp file %s -- %s",
wtmpfile, sys_errlist[errno]);
MD4/MD5演算を64bitクリーンで行えるように修正します。
sys/types.hをインクルードするようにして型を整えます。
コンパイラの警告が出ないようにします。
--- tac_plus.h.old Tue Dec 19 01:58:02 2000 +++ tac_plus.h Wed Jul 26 15:59:38 2006 @@ -70,7 +70,7 @@ */ /* #define REARMSIGNAL */ -#define VERSION "F4.0.3.alpha.v7(DB&PAM support)" +#define VERSION "F5.0.0.alpha(LDAP&DB&PAM support)" /* * System definitions. @@ -122,7 +122,9 @@ #define SYSV #define GETDTABLESIZE #define REAPCHILD +#ifndef SHADOW_PASSWORDS #define SHADOW_PASSWORDS +#endif #define NEED_BZERO #define REARMSIGNAL #endif /* SOLARIS */ @@ -136,7 +138,9 @@ #endif /* HPUX */ #ifdef FREEBSD +#ifndef HAVE_STRERROR #define CONST_SYSERRLIST +#endif #define STDLIB_MALLOC #define VOIDSIG #define NO_PWAGE @@ -681,7 +685,7 @@ extern char *cfg_get_global_secret(); #ifdef USE_PAM extern char *cfg_get_pam_service(); -#endif / *PAM */ +#endif /* PAM */ extern void cfg_clean_config(); extern char *cfg_nodestring(); @@ -695,11 +699,13 @@ extern void set_expiration_status(); /* miscellaneous */ +#ifndef HAVE_STRERROR #ifdef CONST_SYSERRLIST extern const char *const sys_errlist[]; #else extern char *sys_errlist[]; #endif +#endif extern int errno; extern int sendauth_fn(); extern int sendpass_fn(); @@ -742,5 +748,6 @@ extern struct timeval started_at; extern char *logfile; +extern char *pidfile; extern char *wtmpfile; extern int wtmpfd;
Solaris 64bit環境ではもはやsys_errlist[]はサポートされないので、 strerror()の存在を確認して使うようにしてしまいます。
diff -u config.c.old config.c
--- config.c.old Wed May 17 10:43:48 2006
+++ config.c Mon Aug 21 13:59:44 2006
@@ -1513,7 +1513,11 @@
if ((cf = fopen(cfile, "r")) == NULL) {
report(LOG_ERR, "read_config: fopen() error for file %s %s, exiting",
+#ifdef HAVE_STRERROR
+ cfile, strerror(errno));
+#else
cfile, sys_errlist[errno]);
+#endif
return (1);
}
if (parse_decls() || sym_error) {
diff -u config.h.in.old config.h.in
--- config.h.in.old Tue May 16 14:13:19 2006
+++ config.h.in Mon Aug 21 13:17:44 2006
@@ -91,3 +91,6 @@
/* Define if you have the header file. */
#undef HAVE_SYS_TYPES_H
+
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
diff -u configure.old configure
--- configure.old Tue May 16 14:16:40 2006
+++ configure Mon Aug 21 13:18:27 2006
@@ -2396,7 +2396,7 @@
fi
-for ac_func in regcomp select socket strcspn strdup strtol
+for ac_func in regcomp select socket strcspn strdup strtol strerror
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2403: checking for $ac_func" >&5
diff -u configure.in.old configure.in
--- configure.in.old Tue May 16 14:15:30 2006
+++ configure.in Mon Aug 21 13:18:07 2006
@@ -168,6 +168,6 @@
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_FUNC_WAIT3
-AC_CHECK_FUNCS(regcomp select socket strcspn strdup strtol)
+AC_CHECK_FUNCS(regcomp select socket strcspn strdup strtol strerror)
AC_OUTPUT(Makefile,echo timestamp > stamp-h)
diff -u do_acct.c.old do_acct.c
--- do_acct.c.old Fri Mar 10 14:55:16 2006
+++ do_acct.c Mon Aug 21 13:26:35 2006
@@ -31,7 +31,11 @@
if (write(acctfd, string, strlen(string)) != strlen(string)) {
report(LOG_ERR, "%s: couldn't write acct file %s %s",
session.peer,
+#ifdef HAVE_STRERROR
+ session.acctfile, strerror(errno));
+#else
session.acctfile, sys_errlist[errno]);
+#endif
return(1);
}
@@ -71,7 +75,11 @@
acctfd = open(session.acctfile, O_CREAT | O_WRONLY | O_APPEND,0640);
if (acctfd < 0) {
report(LOG_ERR, "Can't open acct file %s -- %s",
+#ifdef HAVE_STRERROR
+ session.acctfile, strerror(errno));
+#else
session.acctfile, sys_errlist[errno]);
+#endif
return(1);
}
}
@@ -159,10 +167,18 @@
#endif
entry.ut_time = utime;
- wtmpfd = open(wtmpfile, O_CREAT | O_WRONLY | O_APPEND , 0644);
+#ifdef FREEBSD
+ wtmpfd = open(wtmpfile, O_CREAT | O_WRONLY | O_APPEND | O_FSYNC, 0644);
+#else
+ wtmpfd = open(wtmpfile, O_CREAT | O_WRONLY | O_APPEND | O_SYNC, 0644);
+#endif
if (wtmpfd < 0) {
report(LOG_ERR, "Can't open wtmp file %s -- %s",
+#ifdef HAVE_STRERROR
+ wtmpfile, strerror(errno));
+#else
wtmpfile, sys_errlist[errno]);
+#endif
return(1);
}
@@ -173,7 +189,11 @@
if (write(wtmpfd, &entry, sizeof entry) != (sizeof entry)) {
report(LOG_ERR, "%s: couldn't write wtmp file %s %s",
+#ifdef HAVE_STRERROR
+ session.peer, wtmpfile, strerror(errno));
+#else
session.peer, wtmpfile, sys_errlist[errno]);
+#endif
return(1);
}
diff -u maxsess.c.old maxsess.c
--- maxsess.c.old Sat Apr 3 15:03:47 1999
+++ maxsess.c Mon Aug 21 13:30:28 2006
@@ -80,7 +80,11 @@
{
if (fseek(fp, offset, SEEK_SET) < 0) {
report(LOG_ERR, "%s fd=%d Cannot seek to %d %s",
+#ifdef HAVE_STRERROR
+ name, fileno(fp), offset, strerror(errno));
+#else
name, fileno(fp), offset, sys_errlist[errno]);
+#endif
}
if (fwrite(buf, size, 1, fp) != 1) {
report(LOG_ERR, "%s fd=%d Cannot write %d bytes",
@@ -292,7 +296,11 @@
if (errno == EINTR)
continue;
report(LOG_DEBUG, "%s: error in select %s fd %d",
+#ifdef HAVE_STRERROR
+ session.peer, strerror(errno), fd);
+#else
session.peer, sys_errlist[errno], fd);
+#endif
return (-1);
}
if (FD_ISSET(fd, &exceptfds)) {
@@ -312,7 +320,11 @@
continue;
}
report(LOG_DEBUG, "%s %s: error reading fd %d nread=%d %s",
+#ifdef HAVE_STRERROR
+ session.peer, session.port, fd, nread, strerror(errno));
+#else
session.peer, session.port, fd, nread, sys_errlist[errno]);
+#endif
return (-1); /* error */
}
if (nread == 0) {
@@ -381,7 +393,11 @@
if (host == NULL) {
report(LOG_ERR, "ckfinger: gethostbyname %s failure: %s",
+#ifdef HAVE_STRERROR
+ nas, strerror(errno));
+#else
nas, sys_errlist[errno]);
+#endif
return (0);
}
bcopy(host->h_addr, &sin.sin_addr, host->h_length);
@@ -390,11 +406,19 @@
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
+#ifdef HAVE_STRERROR
+ report(LOG_ERR, "ckfinger: socket: %s", strerror(errno));
+#else
report(LOG_ERR, "ckfinger: socket: %s", sys_errlist[errno]);
+#endif
return (0);
}
if (connect(s, (struct sockaddr *) & sin, sizeof(sin)) < 0) {
+#ifdef HAVE_STRERROR
+ report(LOG_ERR, "ckfinger: connect failure %s", strerror(errno));
+#else
report(LOG_ERR, "ckfinger: connect failure %s", sys_errlist[errno]);
+#endif
close(s);
return (0);
}
diff -u packet.c.old packet.c
--- packet.c.old Fri Mar 10 19:10:01 2006
+++ packet.c Mon Aug 21 13:32:01 2006
@@ -312,7 +312,11 @@
if (errno == EINTR)
continue;
report(LOG_DEBUG, "%s: error in select %s fd %d",
+#ifdef HAVE_STRERROR
+ session.peer, strerror(errno), fd);
+#else
session.peer, sys_errlist[errno], fd);
+#endif
return (-1);
}
if (FD_ISSET(fd, &exceptfds)) {
@@ -332,7 +336,11 @@
if (errno == EINTR)
goto again;
report(LOG_DEBUG, "%s %s: error reading fd %d nread=%d %s",
+#ifdef HAVE_STRERROR
+ session.peer, session.port, fd, nread, strerror(errno));
+#else
session.peer, session.port, fd, nread, sys_errlist[errno]);
+#endif
return (-1); /* error */
} else if (nread == 0) {
diff -u pwlib.c.old pwlib.c
--- pwlib.c.old Fri Mar 16 22:42:54 2001
+++ pwlib.c Mon Aug 21 13:33:11 2006
@@ -423,7 +423,11 @@
/* an alternate filename */
if (!(access(filename, R_OK) == 0)) {
report(LOG_ERR, "%s %s: Cannot access %s for user %s -- %s",
+#ifdef HAVE_STRERROR
+ session.peer, session.port, filename, user, strerror(errno));
+#else
session.peer, session.port, filename, user, sys_errlist[errno]);
+#endif
return (0);
}
diff -u tac_plus.c.old tac_plus.c
--- tac_plus.c.old Wed May 17 10:41:32 2006
+++ tac_plus.c Mon Aug 21 14:00:13 2006
@@ -151,7 +151,11 @@
if (s < 0) {
console++;
+#ifdef HAVE_STRERROR
+ report(LOG_ERR, "get_socket: socket: %s", strerror(errno));
+#else
report(LOG_ERR, "get_socket: socket: %s", sys_errlist[errno]);
+#endif
tac_exit(1);
}
#ifdef SO_REUSEADDR
@@ -164,7 +168,11 @@
console++;
report(LOG_ERR, "get_socket: bind %d %s",
ntohs(sin.sin_port),
+#ifdef HAVE_STRERROR
+ strerror(errno));
+#else
sys_errlist[errno]);
+#endif
tac_exit(1);
}
return (s);
@@ -300,7 +308,11 @@
session.sock = 0;
if (getpeername(session.sock, (struct sockaddr *) &name, &name_len)) {
+#ifdef HAVE_STRERROR
+ report(LOG_ERR, "getpeername failure %s", strerror(errno));
+#else
report(LOG_ERR, "getpeername failure %s", sys_errlist[errno]);
+#endif
} else {
struct hostent *hp;
hp = gethostbyaddr((char *) &name.sin_addr.s_addr,
@@ -313,7 +325,11 @@
}
#ifdef FIONBIO
if (ioctl(session.sock, FIONBIO, &on) < 0) {
+#ifdef HAVE_STRERROR
+ report(LOG_ERR, "ioctl(FIONBIO) %s", strerror(errno));
+#else
report(LOG_ERR, "ioctl(FIONBIO) %s", sys_errlist[errno]);
+#endif
tac_exit(1);
}
#endif
@@ -402,7 +418,11 @@
if (listen(s, SOMAXCONN) < 0) {
console++;
+#ifdef HAVE_STRERROR
+ report(LOG_ERR, "listen: %s", strerror(errno));
+#else
report(LOG_ERR, "listen: %s", sys_errlist[errno]);
+#endif
tac_exit(1);
}
@@ -418,19 +438,31 @@
fclose(fp);
} else
report(LOG_ERR, "Cannot write pid to %s %s",
+#ifdef HAVE_STRERROR
+ pidfilebuf, strerror(errno));
+#else
pidfilebuf, sys_errlist[errno]);
+#endif
#ifdef TAC_PLUS_GROUPID
if (setgid(TAC_PLUS_GROUPID))
report(LOG_ERR, "Cannot set group id to %d %s",
+#ifdef HAVE_STRERROR
+ TAC_PLUS_GROUPID, strerror(errno));
+#else
TAC_PLUS_GROUPID, sys_errlist[errno]);
#endif
+#endif
#ifdef TAC_PLUS_USERID
if (setuid(TAC_PLUS_USERID))
report(LOG_ERR, "Cannot set user id to %d %s",
+#ifdef HAVE_STRERROR
+ TAC_PLUS_USERID, strerror(errno));
+#else
TAC_PLUS_USERID, sys_errlist[errno]);
#endif
+#endif
#ifdef MAXSESS
maxsess_loginit();
@@ -455,7 +487,11 @@
if (errno == EINTR)
continue;
+#ifdef HAVE_STRERROR
+ report(LOG_ERR, "accept: %s", strerror(errno));
+#else
report(LOG_ERR, "accept: %s", sys_errlist[errno]);
+#endif
continue;
}
diff -u utils.c.old utils.c
--- utils.c.old Sat Apr 3 15:03:46 1999
+++ utils.c Mon Aug 21 13:48:08 2006
@@ -217,7 +217,11 @@
continue;
} else {
syslog(LOG_ERR, "fcntl lock error status %d on %s %d %s",
+#ifdef HAVE_STRERROR
+ status, filename, lockfd, strerror(errno));
+#else
status, filename, lockfd, sys_errlist[errno]);
+#endif
return(0);
}
}
@@ -227,7 +231,11 @@
if (errno != 0) {
syslog(LOG_ERR, "Cannot lock %s fd %d in %d tries %s",
+#ifdef HAVE_STRERROR
+ filename, lockfd, tries+1, strerror(errno));
+#else
filename, lockfd, tries+1, sys_errlist[errno]);
+#endif
/* who is hogging this lock */
flock.l_type = F_WRLCK;
@@ -293,7 +301,11 @@
status = fcntl(lockfd, F_UNLCK, &flock);
if (status == -1) {
syslog(LOG_ERR, "fcntl unlock error status %d on %s %d %s",
+#ifdef HAVE_STRERROR
+ status, filename, lockfd, strerror(errno));
+#else
status, filename, lockfd, sys_errlist[errno]);
+#endif
return(1);
}
あとはオプションを正しく扱えるようにしたりなど、好みに応じて適当 に修正しておきます。
--- config.c.old Fri Mar 16 18:04:27 2001
+++ config.c Wed May 17 10:43:48 2006
@@ -599,7 +599,8 @@
#endif
#ifdef USE_LDAP
case S_ldap:
- fprintf(stderr,"sym_code=%i, ldap\n",sym_code);
+ if (debug)
+ fprintf(stderr,"sym_code=%i, ldap\n",sym_code);
authen_default_method = sym_code;
break;
#endif
--- tac_plus.c.old Tue Dec 19 01:58:02 2000
+++ tac_plus.c Wed May 17 10:41:32 2006
@@ -42,6 +42,7 @@
struct session session; /* session data */
static char pidfilebuf[75]; /* holds current name of the pidfile */
+char *pidfile = NULL;
void start_session();
@@ -88,7 +89,7 @@
report(LOG_INFO, "Reading config");
- session.acctfile = tac_strdup("/var/log/acctfile");
+ session.acctfile = tac_strdup("/var/log/tac_plus-acct.log");
if (!session.cfgfile) {
report(LOG_ERR, "no config file specified");
@@ -199,10 +199,6 @@
int s;
FILE *fp;
int lookup_peer = 0;
-
- debug = 0; /* no debugging */
- standalone = 1; /* standalone */
- single = 0; /* single threaded */
/* initialise global session data */
bzero(&session, sizeof(session));
@@ -218,6 +223,7 @@
fprintf(stderr, "\t[ -t ] [ -P ] [ -g ] [ -p ]\n");
fprintf(stderr, "\t[ -d ] [ -i ] [ -v ] [ -s
]\n");
fprintf(stderr, "\t[ -l logfile ]");
+ fprintf(stderr, "\t[ -j pidfile ]");
#ifdef MAXSESS
fprintf(stderr, " [ -w whologfile ]");
#endif
@@ -225,7 +231,7 @@
tac_exit(1);
}
- while ((c = getopt(argc, argv, "td:C:ip:PgvsLl:w:u:")) != EOF)
+ while ((c = getopt(argc, argv, "td:C:j:ip:PgvsLl:w:u:")) != EOF)
switch (c) {
case 'L': /* lookup peer names via DNS */
lookup_peer++;
@@ -260,6 +266,9 @@
case 'l': /* logfile */
logfile = tac_strdup(optarg);
break;
+ case 'j': /* pidfile */
+ pidfile = tac_strdup(optarg);
+ break;
#ifdef MAXSESS
case 'w': /* wholog file */
wholog = tac_strdup(optarg);
@@ -406,14 +423,22 @@
if (listen(s, SOMAXCONN) < 0) {
console++;
+#ifdef HAVE_STRERROR
+ report(LOG_ERR, "listen: %s", strerror(errno));
+#else
report(LOG_ERR, "listen: %s", sys_errlist[errno]);
+#endif
tac_exit(1);
}
+ if (pidfile == NULL)
+ pidfile = TAC_PLUS_PIDFILE;
+ if (debug)
+ report(LOG_DEBUG, "pid file: %s", pidfile);
if (port == TAC_PLUS_PORT) {
- strcpy(pidfilebuf, TAC_PLUS_PIDFILE);
+ strcpy(pidfilebuf, pidfile);
} else {
- sprintf(pidfilebuf, "%s.%d", TAC_PLUS_PIDFILE, port);
+ sprintf(pidfilebuf, "%s.%d", pidfile, port);
}
/* write process id to pidfile */
Makefile.inをちょっと修正します。
--- Makefile.in.old Fri Mar 16 00:10:42 2001 +++ Makefile.in Mon Jul 24 12:41:36 2006 @@ -31,7 +31,8 @@ CC = @CC@ CPPFLAGS = @CPPFLAGS@ -CFLAGS = $(CPPFLAGS) @CFLAGS@ +INCLUDES = @CPPFLAGS@ +FLAGS = $(CPPFLAGS) @CFLAGS@ LDFLAGS = @LDFLAGS@ OSLIBS = @LIBS@ DEFINES = @DEFINES@
このスクリプトを実行します。
#!/bin/sh
OSTYPE=`uname`
case ${OSTYPE} in
SunOS)
CC=cc; export CC
CFLAGS="-O -xarch=v8"; export CFLAGS
CPPFLAGS="-I/usr/sfw/include -I/usr/local/include"; export CPPFLAGS
LDFLAGS="-L/usr/sfw/lib -R/usr/sfw/lib -L/usr/local/lib -R/usr/local/lib"; export LDFLAGS
OS=-DSOLARIS; export OS
;;
FreeBSD)
CPPFLAGS="-I/usr/local/include"; export CPPFLAGS
CFLAGS="-O2"; export CFLAGS
LDFLAGS="-L/usr/local/lib"; export LDFLAGS
OS=-DFREEBSD; export OS
;;
esac
./configure --with-ldap
makeしてインストールします。
% ./setup.sh % gmake # gmake install