LDAP for radiusd patch. (LDAP radius)
Ключевые слова: LDAP, radius, (найти похожие документы)
From: XXXXXXX
Subject: LDAP for radiusd patch.
Date: Mon, 10 Aug 1998 09:47:54 +0000
diff -Naur radiusd-cistron-1.5.4.3/doc/README.ldap radiusd-cistron-1.5.4.3-beta18-ldap/doc/README.ldap
--- radiusd-cistron-1.5.4.3/doc/README.ldap Wed Dec 31 19:00:00 1969
+++ radiusd-cistron-1.5.4.3-beta18-ldap/doc/README.ldap Fri May 14 14:05:32 1999
@@ -0,0 +1,31 @@
+I really need to write up some decent documentation, but this is the first
+beta patch. I have tested this with cistron-1.5.4.3-beta15, using the
+netscape ldap sdk. The server I was testing it against is OpenLDAP 1.2.0
+
+This patch is based on the MySQL Cistron patch by oyarzun@wilmington.net.
+
+The only configuration that needs to be done is the /etc/raddb/ldapserver
+file which should look similar to this:
+
+ server localhost
+ basedn "o=Someorg, c=US"
+ port 389
+ login "cn=radiusserver, o=Someorg, c=US"
+ password mypassword
+ filter "(uid=%u)"
+ doauth yes
+
+There is a sample config file in the raddb/ directory.
+
+If the login and password lines are not included or are blank then an
+anonymous bind will be made to the ldap server. The filter line needs to
+be quoted, and a %u will be replaced by the username attempting to
+authenticate.
+
+You also need to set Auth-Type = LDAP for the authentication to happen.
+
+I will be working on this as time permits, and hopefully looking into
+using async ldap calls which should speed up the auth requests some.
+
+Email with problems/suggestions james@wwnet.net
+
diff -Naur radiusd-cistron-1.5.4.3/raddb/dictionary radiusd-cistron-1.5.4.3-beta18-ldap/raddb/dictionary
--- radiusd-cistron-1.5.4.3/raddb/dictionary Sun Mar 21 07:32:00 1999
+++ radiusd-cistron-1.5.4.3-beta18-ldap/raddb/dictionary Fri May 14 14:05:32 1999
@@ -228,6 +228,7 @@
#
# Cistron extensions
#
+VALUE Auth-Type LDAP 252
VALUE Auth-Type Pam 253
VALUE Auth-Type Accept 254
diff -Naur radiusd-cistron-1.5.4.3/raddb/ldapserver radiusd-cistron-1.5.4.3-beta18-ldap/raddb/ldapserver
--- radiusd-cistron-1.5.4.3/raddb/ldapserver Wed Dec 31 19:00:00 1969
+++ radiusd-cistron-1.5.4.3-beta18-ldap/raddb/ldapserver Fri May 14 14:05:32 1999
@@ -0,0 +1,7 @@
+server localhost
+port 389
+basedn "o=Someorg, c=US"
+login "cn=radiusserver, o=Someorg, c=US"
+password mypassword
+filter "(uid=%u)"
+doauth yes
diff -Naur radiusd-cistron-1.5.4.3/raddb/users radiusd-cistron-1.5.4.3-beta18-ldap/raddb/users
--- radiusd-cistron-1.5.4.3/raddb/users Wed Jul 22 07:50:44 1998
+++ radiusd-cistron-1.5.4.3-beta18-ldap/raddb/users Fri May 14 14:05:32 1999
@@ -91,7 +91,8 @@
# First setup all accounts to be checked against the UNIX /etc/passwd.
# (Unless a password was already given earlier in this file).
#
-DEFAULT Auth-Type = System
+#DEFAULT Auth-Type = System
+DEFAULT Auth-Type = LDAP
Fall-Through = 1
#
diff -Naur radiusd-cistron-1.5.4.3/src/Make.inc radiusd-cistron-1.5.4.3-beta18-ldap/src/Make.inc
--- radiusd-cistron-1.5.4.3/src/Make.inc Wed May 5 09:18:37 1999
+++ radiusd-cistron-1.5.4.3-beta18-ldap/src/Make.inc Fri May 14 14:11:51 1999
@@ -6,13 +6,13 @@
SERVER_OBJS = radiusd.o dict.o files.o util.o md5.o attrprint.o \
acct.o radius.o pam.o log.o version.o proxy.o \
- exec.o auth.o timestr.o cache.o
+ exec.o auth.o timestr.o cache.o ldap.o
SERVERDBM_OBJS = radiusddbm.o dict.o filesdbm.o util.o md5.o attrprint.o \
acct.o radius.o pam.o log.o versiondbm.o proxy.o \
- exec.o auth.o timestr.o cache.o
+ exec.o auth.o timestr.o cache.o ldap.o
SERVER_SRCS = radiusd.c dict.c files.c util.c md5.c attrprint.c acct.c \
radius.c pam.c log.c version.c proxy.c \
- exec.c auth.c timestr.c cache.c
+ exec.c auth.c timestr.c cache.c ldap.c
INCLUDES = radius.h conf.h
all: radiusd radwho radzap raduse radtest
@@ -20,14 +20,15 @@
dbm: radiusd.dbm builddbm
radiusd: $(SERVER_OBJS)
- $(CC) $(LDFLAGS) -o radiusd $(SERVER_OBJS) $(LIBS) $(LCRYPT) $(PAMLIB)
+ $(CC) $(LDFLAGS) -o radiusd $(SERVER_OBJS) $(LIBS) $(LCRYPT) \
+ $(PAMLIB) $(LDAPLIB)
radiusd.dbm: $(SERVERDBM_OBJS)
$(CC) $(LDFLAGS) -o radiusd.dbm $(SERVERDBM_OBJS) $(LIBS) $(LCRYPT) \
- $(DBMLIB) $(PAMLIB)
+ $(DBMLIB) $(PAMLIB) $(LDAPLIB)
radiusd.o: radiusd.c $(INCLUDES)
- $(CC) $(CFLAGS) -c radiusd.c
+ $(CC) $(CFLAGS) $(LDAP) -c radiusd.c
radiusddbm.o: radiusd.c $(INCLUDES)
$(CC) $(CFLAGS) $(DBM) -c radiusd.c -o radiusddbm.o
@@ -59,6 +60,9 @@
cache.o: cache.c $(INCLUDES)
$(CC) $(CFLAGS) -c cache.c
+ldap.o: ldap.c $(INCLUDES)
+ $(CC) $(CFLAGS) $(LDAP) -c ldap.c
+
proxy.o: proxy.c $(INCLUDES)
$(CC) $(CFLAGS) -c proxy.c
@@ -66,7 +70,7 @@
$(CC) $(CFLAGS) -c exec.c
auth.o: auth.c $(INCLUDES)
- $(CC) $(CFLAGS) $(PAM) -c auth.c
+ $(CC) $(CFLAGS) $(PAM) $(LDAP) -c auth.c
version.o: version.c $(INCLUDES)
$(CC) $(CFLAGS) -o version.o -c version.c
diff -Naur radiusd-cistron-1.5.4.3/src/Makefile radiusd-cistron-1.5.4.3-beta18-ldap/src/Makefile
--- radiusd-cistron-1.5.4.3/src/Makefile Tue Nov 17 06:08:47 1998
+++ radiusd-cistron-1.5.4.3-beta18-ldap/src/Makefile Fri May 14 14:12:27 1999
@@ -25,6 +25,10 @@
#PAM = -DPAM
#PAMLIB = -lpam -ldl
+# Uncomment these if you want LDAP support
+LDAP = -DUSELDAP
+LDAPLIB = -lldapssl30 -lpthread
+
BINDIR = /usr/local/bin
SBINDIR = /usr/local/sbin
diff -Naur radiusd-cistron-1.5.4.3/src/auth.c radiusd-cistron-1.5.4.3-beta18-ldap/src/auth.c
--- radiusd-cistron-1.5.4.3/src/auth.c Wed May 5 09:45:14 1999
+++ radiusd-cistron-1.5.4.3-beta18-ldap/src/auth.c Fri May 14 14:05:32 1999
@@ -322,6 +322,8 @@
auth_type = PW_AUTHTYPE_SYSTEM;
else if(password_pair && !strcmp(password_pair->strvalue,"PAM"))
auth_type = PW_AUTHTYPE_PAM;
+ else if(password_pair &&!strcmp(password_pair->strvalue,"LDAP"))
+ auth_type = PW_AUTHTYPE_LDAP;
else
auth_type = PW_AUTHTYPE_LOCAL;
}
@@ -369,6 +371,16 @@
result = -1;
#else
log(L_ERR, "%s: PAM authentication not available",
+ name);
+ result = -1;
+#endif
+ break;
+ case PW_AUTHTYPE_LDAP:
+#ifdef USELDAP
+ if (ldap_pass(name, string) != 0)
+ result = -1;
+#else
+ log(L_ERR, "%s: LDAP Authentication not available",
name);
result = -1;
#endif
diff -Naur radiusd-cistron-1.5.4.3/src/ldap.c radiusd-cistron-1.5.4.3-beta18-ldap/src/ldap.c
--- radiusd-cistron-1.5.4.3/src/ldap.c Wed Dec 31 19:00:00 1969
+++ radiusd-cistron-1.5.4.3-beta18-ldap/src/ldap.c Fri May 14 14:05:32 1999
@@ -0,0 +1,335 @@
+/*
+ * ldap.c Functions to access the LDAP database.
+ *
+ * This is mostly from a Mysql+Cistron patch from oyarzun@wilmington.net
+ *
+ * Much of the Mysql connection and accounting code was taken from
+ * Wim Bonis's (bonis@kiss.de) accounting patch to livingston radius
+ * 2.01. His patch can be found at:
+ *
+ * ftp://ftp.kiss.de/pub/unix/livingston/mysql-patches.tgz
+ *
+ * Version: @(#)ldap.c 1.10 29-Jan-1999 james@wwnet.net
+ *
+ */
+
+#ifdef USELDAP
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <time.h>
+#include <ctype.h>
+#include <strings.h>
+
+#include <ldap.h>
+
+#include "radiusd.h"
+
+static char *make_filter(char *, char *);
+static void fieldcpy(char *, char **);
+char ldap_server[40];
+int ldap_port;
+char ldap_login[40];
+char ldap_password[20];
+char ldap_filter[256];
+char ldap_basedn[256];
+int use_ldap_auth;
+
+
+/*************************************************************************
+ *
+ * Function: radldap_init
+ *
+ * Purpose: Reads in radldap Config File
+ *
+ *************************************************************************/
+
+int radldap_init ()
+{
+ FILE *ldapcfd;
+ char dummystr[64];
+ char namestr[64];
+ int line_no;
+ char buffer[256];
+ char ldapcfile[256];
+ char *ptr;
+
+ strcpy(ldap_server,"");
+ strcpy(ldap_login,"");
+ strcpy(ldap_password,"");
+ strcpy(ldap_basedn,"");
+ strcpy(ldap_filter,"");
+ ldap_port = 389;
+ use_ldap_auth = 0;
+
+ sprintf(ldapcfile, "%s/%s", radius_dir, "ldapserver");
+ if((ldapcfd = fopen(ldapcfile, "r")) == (FILE *)NULL) {
+ log(L_ERR,"could not read ldapserver file %s",ldapcfile);
+ return(-1);
+ }
+
+ line_no = 0;
+ while(fgets(buffer, sizeof(buffer), ldapcfd) != (char *)NULL) {
+ line_no++;
+
+ /* Skip empty space */
+ if(*buffer == '#' || *buffer == '\0' || *buffer == '\n') {
+ continue;
+ }
+
+ if(strncasecmp(buffer, "server", 6) == 0) {
+ /* Read the SERVER line */
+ if(sscanf(buffer, "%s%s", dummystr, namestr) != 2) {
+ log(L_ERR,"invalid attribute on line %d of ldapserver file %s",
+ line_no,ldapcfile);
+ use_ldap_auth = 0;
+ } else {
+ strcpy(ldap_server,namestr);
+ }
+ }
+ if(strncasecmp(buffer, "port", 4) == 0) {
+ /* Read the PORT line */
+ if(sscanf(buffer, "%s%s", dummystr, namestr) != 2) {
+ log(L_ERR,"invalid attribute on line %d of ldapserver file %s",
+ line_no,ldapcfile);
+ } else {
+ ldap_port = atoi(namestr);
+ }
+ }
+ if(strncasecmp(buffer, "login", 5) == 0) {
+ /* Read the LOGIN line */
+ if(sscanf(buffer, "%s%s", dummystr, namestr) != 2) {
+ log(L_ERR,"invalid attribute on line %d of ldapserver file %s, using NULL login",
+ line_no,ldapcfile);
+ strcpy(ldap_login,"");
+ } else {
+ strcpy(ldap_login,namestr);
+ }
+ }
+ if(strncasecmp(buffer, "password", 8) == 0) {
+ /* Read the PASSWORD line */
+ if(sscanf(buffer, "%s%s", dummystr, namestr) != 2) {
+ log(L_ERR,"invalid attribute on line %d of ldapserver file %s, using NULL password",
+ line_no,ldapcfile);
+ strcpy(ldap_password,"");
+ } else {
+ strcpy(ldap_password,namestr);
+ }
+ }
+ if(strncasecmp(buffer, "basedn", 6) == 0) {
+ /* Read the BASEDN line */
+ ptr = buffer + 6;
+ fieldcpy(ldap_basedn,&ptr);
+ }
+ if(strncasecmp(buffer, "filter", 6) == 0) {
+ ptr = buffer + 6;
+ fieldcpy(ldap_filter,&ptr);
+ }
+ if(strncasecmp(buffer, "doauth", 6) == 0) {
+ /* Read the DOAUTH line */
+ if(sscanf(buffer, "%s%s", dummystr, namestr) != 2) {
+ log(L_ERR,"invalid attribute on line %d of ldapserver file %s",
+ line_no,ldapcfile);
+ } else {
+ if(strncasecmp(namestr, "yes", 3) == 0) {
+ use_ldap_auth = 1;
+ } else {
+ use_ldap_auth = 0;
+ }
+ }
+ }
+ }
+ fclose(ldapcfd);
+
+/* if (!ldap_password)
+ strcpy(ldap_password,"");
+ if (!ldap_login)
+ strcpy(ldap_login,"");
+*/
+ log(L_INFO,"LDAP_init: using: %s:%d,%s,%s,%s,%d",
+ ldap_server,
+ ldap_port,
+ ldap_login,
+ ldap_filter,
+ ldap_basedn,
+ use_ldap_auth);
+
+ return 0;
+}
+
+
+/*************************************************************************
+ *
+ * Function: ldap_pass
+ *
+ * Purpose: Check the user's password against ldap database
+ *
+ *************************************************************************/
+
+int ldap_pass(char *name, char *passwd)
+{
+ static LDAP *ld;
+ LDAPMessage *result, *msg;
+ char *filter, *dn,
+ *attrs[] = { "uid",
+ NULL };
+
+ if (use_ldap_auth == 0)
+ {
+ log(L_ERR,"LDAP Auth specified in users file, but not in ldapserver file");
+ return -1;
+ }
+ if (ld == NULL) {
+ if ( (ld = ldap_init(ldap_server,ldap_port)) == NULL)
+ return -1;
+ if ( (ldap_simple_bind_s(ld,ldap_login,ldap_password)) != LDAP_SUCCESS) {
+ log(L_ERR,"LDAP ldap_simple_bind_s failed");
+ ldap_unbind_s(ld);
+ return -1;
+ }
+
+ } else {
+ log(L_ERR,"ldap handle already open");
+ }
+
+ DEBUG("LDAP login attempt by '%s' with password '%s'",name,passwd);
+
+ if (ld != NULL) {
+ filter = make_filter(ldap_filter, name);
+
+ if (ldap_search_s(ld,ldap_basedn,LDAP_SCOPE_SUBTREE,filter,attrs,1,&result) != LDAP_SUCCESS) {
+ ldap_unbind_s(ld);
+ return -1;
+ }
+
+ if ((ldap_count_entries(ld,result)) != 1) {
+ ldap_unbind_s(ld);
+ return -1;
+ }
+
+ if ((msg = ldap_first_entry(ld,result)) == NULL) {
+ ldap_unbind_s(ld);
+ return -1;
+ }
+
+ if ((dn = ldap_get_dn(ld,msg)) == NULL) {
+ ldap_unbind_s(ld);
+ return -1;
+ }
+
+ if (strlen(passwd) == 0) {
+ ldap_unbind_s(ld);
+ return -1;
+ }
+
+ if (ldap_simple_bind_s(ld,dn,passwd) != LDAP_SUCCESS) {
+ ldap_unbind_s(ld);
+ return -1;
+ }
+
+ ldap_memfree(dn);
+ ldap_unbind_s(ld);
+
+ DEBUG("User %s successfully authenticated via LDAP", name);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+/*
+ * Replace %<whatever> in a string.
+ *
+ * %u User name
+ *
+ */
+static char *make_filter(char *str, char *name)
+{
+ static char buf[MAX_AUTH_QUERY_LEN];
+ int i = 0, c;
+ char *p;
+
+ for(p = str; *p; p++) {
+ c = *p;
+ if (c != '%' && c != '\\') {
+ buf[i++] = *p;
+ continue;
+ }
+ if (*++p == 0) break;
+ if (c == '%') switch(*p) {
+ case '%':
+ buf[i++] = *p;
+ break;
+ case 'u': /* User name */
+ if (name != NULL)
+ strcpy(buf + i, name);
+ else
+ strcpy(buf + i, " ");
+ i += strlen(buf + i);
+ break;
+ default:
+ buf[i++] = '%';
+ buf[i++] = *p;
+ break;
+ }
+ if (c == '\\') switch(*p) {
+ case 'n':
+ buf[i++] = '\n';
+ break;
+ case 'r':
+ buf[i++] = '\r';
+ break;
+ case 't':
+ buf[i++] = '\t';
+ break;
+ default:
+ buf[i++] = '\\';
+ buf[i++] = *p;
+ break;
+ }
+ }
+ if (i >= MAX_AUTH_QUERY_LEN)
+ i = MAX_AUTH_QUERY_LEN - 1;
+ buf[i++] = 0;
+ return buf;
+}
+
+static void fieldcpy(char *string, char **uptr)
+{
+ char *ptr;
+
+ ptr = *uptr;
+ while (*ptr == ' ' || *ptr == '\t') {
+ ptr++;
+ }
+ if(*ptr == '"') {
+ ptr++;
+ while(*ptr != '"' && *ptr != '\0' && *ptr != '\n') {
+ *string++ = *ptr++;
+ }
+ *string = '\0';
+ if(*ptr == '"') {
+ ptr++;
+ }
+ *uptr = ptr;
+ return;
+ }
+
+ while(*ptr != ' ' && *ptr != '\t' && *ptr != '\0' && *ptr != '\n' &&
+ *ptr != '=' && *ptr != ',') {
+ *string++ = *ptr++;
+ }
+ *string = '\0';
+ *uptr = ptr;
+ return;
+}
+
+#endif /* USELDAP */
+
diff -Naur radiusd-cistron-1.5.4.3/src/radius.h radiusd-cistron-1.5.4.3-beta18-ldap/src/radius.h
--- radiusd-cistron-1.5.4.3/src/radius.h Tue Apr 20 08:37:42 1999
+++ radiusd-cistron-1.5.4.3-beta18-ldap/src/radius.h Fri May 14 14:05:32 1999
@@ -175,6 +175,7 @@
#define PW_AUTHTYPE_SECURID 2
#define PW_AUTHTYPE_CRYPT 3
#define PW_AUTHTYPE_REJECT 4
+#define PW_AUTHTYPE_LDAP 252
#define PW_AUTHTYPE_PAM 253
#define PW_AUTHTYPE_ACCEPT 254
diff -Naur radiusd-cistron-1.5.4.3/src/radiusd.c radiusd-cistron-1.5.4.3-beta18-ldap/src/radiusd.c
--- radiusd-cistron-1.5.4.3/src/radiusd.c Wed May 5 09:44:45 1999
+++ radiusd-cistron-1.5.4.3-beta18-ldap/src/radiusd.c Fri May 14 14:05:32 1999
@@ -131,6 +131,13 @@
if (res == 0 && read_config_files() != 0)
res = -1;
+#ifdef USELDAP
+ if (radldap_init() != 0) {
+ log(L_ERR,"LDAP Error: LDAP could not be initialized");
+ res = -1;
+ }
+#endif
+
if (res != 0) {
if (pid == radius_pid) {
log(L_ERR|L_CONS,
diff -Naur radiusd-cistron-1.5.4.3/src/radiusd.h radiusd-cistron-1.5.4.3-beta18-ldap/src/radiusd.h
--- radiusd-cistron-1.5.4.3/src/radiusd.h Wed May 5 09:45:01 1999
+++ radiusd-cistron-1.5.4.3-beta18-ldap/src/radiusd.h Fri May 14 14:05:32 1999
@@ -34,6 +34,10 @@
#include "radius.h"
#include "conf.h"
+#ifdef USELDAP
+#include <ldap.h>
+#endif
+
/* Server data structures */
typedef struct dict_attr {
@@ -272,6 +276,14 @@
/* exec.c */
char *radius_xlate(char *, VALUE_PAIR *req, VALUE_PAIR *reply);
+
+/* ldap.c */
+#ifdef USELDAP
+#define MAX_AUTH_QUERY_LEN 256
+
+int radldap_init();
+int ldap_pass(char *, char *);
+#endif
/* timestr.c */
int timestr_match(char *, time_t);