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 theheader 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