LDAP support added
- This patch enables LCDd to retrieve its configuration options from an LDAP directory. - The code was tested with OpenLDAP 2.1.x (21<=x<=22) only. - LDAP support is disabled by default and has to be enabled with ./configure --enable-ldap. (See ./configure --help for other options. Not all options have any effect yet.) - Currently only anonymous LDAP binds are supported. - The DN of the main configuration object has to be passed to LCDd instead of the configuration file location: LCDd -c "ldap://yourhost.yourcompany.com/cn=config1,cn=lcdproc,dc=yourcompany dc=COM" The basic idea behind the LCDproc object classes is that they are more or less verbatim copies of the corresponding sections in a generic LCDd.conf - Unfortunately schema files cannot be provided yet, because LCDproc does not have a registered OID namespace and OID hijacking is prohibited.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
bin_PROGRAMS = lcdexec
|
||||
lcdexec_SOURCES = lcdexec.c menu.c menu.h
|
||||
lcdexec_LDADD = ../../shared/libLCDstuff.a
|
||||
lcdexec_LDADD = @ldap_libs@ ../../shared/libLCDstuff.a
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
bin_PROGRAMS = lcdproc
|
||||
lcdproc_SOURCES = main.c main.h mode.c mode.h batt.c batt.h chrono.c chrono.h cpu.c cpu.h cpu_smp.c cpu_smp.h disk.c disk.h load.c load.h mem.c mem.h machine_Linux.c machine_OpenBSD.c machine_FreeBSD.c machine_NetBSD.c machine_SunOS.c
|
||||
lcdproc_LDADD = ../../shared/libLCDstuff.a
|
||||
lcdproc_LDADD = @ldap_libs@ ../../shared/libLCDstuff.a
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
+180
@@ -202,6 +202,186 @@ AC_MODULES_INFO
|
||||
|
||||
LCD_DRIVERS_SELECT
|
||||
|
||||
dnl ######################################################################
|
||||
dnl Open LDAP
|
||||
dnl based on code from perdition http://www.vergenet.net/linux/perdition/
|
||||
dnl
|
||||
dnl not all options have effect at the moment
|
||||
|
||||
AC_SUBST(ldap_libs)
|
||||
AC_SUBST(ldap_includes)
|
||||
AC_SUBST(ldap_schemadir)
|
||||
|
||||
AC_MSG_CHECKING([if LDAP support has been enabled]);
|
||||
AC_ARG_ENABLE(
|
||||
ldap,
|
||||
[ --enable-ldap compile with LDAP support. ],
|
||||
[
|
||||
if test "$enable_ldap" = "yes"; then
|
||||
AC_MSG_RESULT("yes")
|
||||
else
|
||||
AC_MSG_RESULT("no")
|
||||
fi
|
||||
],
|
||||
[
|
||||
enable_ldap="no";
|
||||
AC_MSG_RESULT("no")
|
||||
]
|
||||
)
|
||||
|
||||
if test "$enable_ldap" = "yes"; then
|
||||
AC_ARG_WITH(
|
||||
ldap-includes,
|
||||
[ --with-ldap-includes=DIR
|
||||
Open LDAP include files are in DIR. ],
|
||||
[
|
||||
if test "$withval" = "no"; then
|
||||
ldap_build_dir="";
|
||||
else
|
||||
ldap_includepath="$withval"
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_MSG_CHECKING(OpenLDAP include path)
|
||||
for ldap_includepath in /usr/openldap/include /usr/local/openldap/include \
|
||||
/usr/include/openldap /usr/local/include/openldap \
|
||||
/usr/include /usr/local/include; do
|
||||
if test -f "${ldap_includepath}/ldap.h"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
AC_MSG_RESULT($ldap_includepath)
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
ldap_includes="-I$ldap_includepath"
|
||||
|
||||
if test "$enable_ldap" = "yes"; then
|
||||
AC_ARG_WITH(
|
||||
ldap-libraries,
|
||||
[ --with-ldap-libraries=DIR
|
||||
Open LDAP library files are in DIR. ],
|
||||
[
|
||||
if test "$withval" = "no"; then
|
||||
ldap_build_dir="";
|
||||
else
|
||||
ldap_libpath="$withval"
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_MSG_CHECKING(OpenLDAP library path)
|
||||
for ldap_libpath in /usr/openldap/lib /usr/local/openldap/lib \
|
||||
/usr/lib/openldap /usr/local/lib/openldap \
|
||||
/usr/lib /usr/local/lib; do
|
||||
if test -f "${ldap_libpath}/libldap.a" \
|
||||
-o -f "${ldap_libpath}/libldap.so"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
AC_MSG_RESULT($ldap_libpath)
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
ldap_libs="-L$ldap_libpath -lldap -llber"
|
||||
|
||||
if test "$enable_ldap" = "yes"; then
|
||||
AC_CHECK_FILE(
|
||||
$ldap_includepath/ldap.h,
|
||||
[ : ] ,
|
||||
[ enable_ldap="no" ]
|
||||
)
|
||||
fi
|
||||
|
||||
if test "$enable_ldap" = "yes"; then
|
||||
AC_CHECK_LIB(
|
||||
ldap,
|
||||
ldap_url_parse,
|
||||
[ : ],
|
||||
[ enable_ldap="no" ],
|
||||
$ldap_libs
|
||||
)
|
||||
fi
|
||||
|
||||
if test "$enable_ldap" = "yes"; then
|
||||
AC_MSG_CHECKING(OpenLDAP lud_exts in LDAPURLDesc)
|
||||
AC_TRY_COMPILE([#include <stdlib.h>
|
||||
#include <lber.h>
|
||||
#include <ldap.h>],
|
||||
[LDAPURLDesc ludp;
|
||||
ludp.lud_exts[0] = NULL;],
|
||||
AC_MSG_RESULT("yes")
|
||||
AC_DEFINE(WITH_LDAP_LUD_EXTS, 1, Compile with LDAP lud_exts),
|
||||
AC_MSG_RESULT("no")
|
||||
AC_MSG_WARN(
|
||||
""
|
||||
"************************************************************"
|
||||
"* Password and Username support will not be built in the"
|
||||
"* LDAP module. For Password and Username support compile"
|
||||
"* openldap2. Available from openldap.org"
|
||||
"************************************************************"
|
||||
)
|
||||
)
|
||||
fi
|
||||
|
||||
if test "$enable_ldap" = "yes"; then
|
||||
AC_CHECK_LIB(ldap, ldap_set_option,
|
||||
AC_DEFINE(WITH_LDAP_SET_OPTION, 1, Compile with LDAP set_option),
|
||||
AC_MSG_WARN(
|
||||
""
|
||||
"************************************************************"
|
||||
"* Cannot expicitly set network timeout or ldap protocol"
|
||||
"* version. For ldap_set_option support please use openlap2."
|
||||
"* Available from openldap.org"
|
||||
"************************************************************"
|
||||
),)
|
||||
fi
|
||||
|
||||
if test "$enable_ldap" = "yes"; then
|
||||
AC_ARG_WITH(
|
||||
ldap-schema-directory,
|
||||
[ --with-ldap-schema-directory=DIR
|
||||
Open LDAP schema files are in DIR. ],
|
||||
[
|
||||
if test "$withval" = "no"; then
|
||||
ldap_schemadir="";
|
||||
else
|
||||
ldap_schemadir="$withval"
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_MSG_CHECKING(OpenLDAP schema path)
|
||||
for ldap_schemadir in /etc/openldap/schema /etc/ldap/schema \
|
||||
/usr/local/openldap/etc/schema; do
|
||||
if test -f "${ldap_schemadir}/openldap.schema"; then
|
||||
break
|
||||
fi
|
||||
ldap_schemadir="Not found"
|
||||
done
|
||||
AC_MSG_RESULT($ldap_schemadir)
|
||||
if test "$ldap_schemadir" = "Not found"; then
|
||||
AC_MSG_WARN(
|
||||
""
|
||||
"************************************************************"
|
||||
"* Could not find OpenLDAP schema directory."
|
||||
"* lcdproc.schema will not be installed"
|
||||
"************************************************************"
|
||||
)
|
||||
ldap_schemadir=""
|
||||
fi
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
if test "$enable_ldap" = "yes"; then
|
||||
AC_DEFINE(WITH_LDAP_SUPPORT, 1, Compile in LDAP support)
|
||||
else
|
||||
ldab_libs="";
|
||||
ldap_includes="";
|
||||
fi
|
||||
|
||||
|
||||
AC_OUTPUT(Makefile
|
||||
shared/Makefile
|
||||
server/Makefile
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
SUBDIRS=drivers commands
|
||||
sbin_PROGRAMS=LCDd
|
||||
LCDd_SOURCES= client.c client.h clients.c clients.h input.c input.h main.c main.h menuitem.c menuitem.h menu.c menu.h menuscreens.c menuscreens.h parse.c parse.h render.c render.h screen.c screen.h screenlist.c screenlist.h serverscreens.c serverscreens.h sock.c sock.h widget.c widget.h drivers.c drivers.h driver.c driver.h
|
||||
LCDd_LDADD = ../shared/libLCDstuff.a commands/libLCDcommands.a
|
||||
LCDd_LDADD = @ldap_libs@ ../shared/libLCDstuff.a commands/libLCDcommands.a
|
||||
LCDd_LDFLAGS = -rdynamic -uget_args
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
+4
-1
@@ -1,3 +1,6 @@
|
||||
noinst_LIBRARIES = libLCDstuff.a
|
||||
libLCDstuff_a_SOURCES = LL.c LL.h sockets.c sockets.h str.c str.h configfile.c configfile.h debug.h report.c report.h snprintf.c snprintf.h
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
INCLUDES = @ldap_includes@ -I$(top_srcdir)
|
||||
|
||||
EXTRA_DIST = Makefile.in
|
||||
|
||||
@@ -6,17 +6,24 @@
|
||||
* COPYING file distributed with this package.
|
||||
*
|
||||
* Copyright (c) 2001, Joris Robijn
|
||||
* (c) 2003, Rene Wagner
|
||||
*
|
||||
*
|
||||
* Defines routines to read ini-file-like files.
|
||||
* Optionally retrieves settings from an LDAP directory (OpenLDAP 2.1.x)
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WITH_LDAP_SUPPORT
|
||||
# include <ldap.h>
|
||||
#endif /* WITH_LDAP_SUPPORT */
|
||||
|
||||
#include "shared/report.h"
|
||||
|
||||
|
||||
@@ -43,6 +50,20 @@ key * find_key( section * s, char * keyname, int skip );
|
||||
key * add_key( section * s, char * keyname, char * value );
|
||||
int process_config( section ** current_section, char (*get_next_char)(), char modify_section_allowed, char * source_descr );
|
||||
|
||||
#ifdef WITH_LDAP_SUPPORT
|
||||
int connect_to_ldap(void);
|
||||
|
||||
static LDAP * ld = NULL;
|
||||
int use_ldap=0;
|
||||
|
||||
static char * ldap_host=NULL, * ldap_base_dn=NULL;
|
||||
int ldap_port;
|
||||
|
||||
/* not supported for now
|
||||
* char ldap_user[255] = "",
|
||||
* ldap_pwd[255] = "";
|
||||
*/
|
||||
#endif /* WITH_LDAP_SUPPORT */
|
||||
|
||||
/**** EXTERNAL FUNCTIONS ****/
|
||||
|
||||
@@ -56,6 +77,41 @@ int config_read_file( char *filename )
|
||||
int pos=0;
|
||||
section * curr_section = NULL;
|
||||
|
||||
#ifdef WITH_LDAP_SUPPORT
|
||||
LDAPURLDesc * url = NULL;
|
||||
int retval;
|
||||
#endif /* WITH_LDAP_SUPPORT */
|
||||
|
||||
report( RPT_NOTICE, "Using Configuration File: %s", filename);
|
||||
|
||||
#ifdef WITH_LDAP_SUPPORT
|
||||
if (ldap_is_ldap_url( filename )) {
|
||||
use_ldap=1;
|
||||
|
||||
if (0 != (retval = ldap_url_parse( filename, &url))) {
|
||||
report( RPT_ERR, "Errors parsing LDAP URL %s: %s", filename, ldap_err2string(retval));
|
||||
ldap_free_urldesc(url);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ldap_host=strdup(url->lud_host);
|
||||
ldap_port=url->lud_port;
|
||||
report( RPT_INFO, "Using LDAP server: %s:%d", ldap_host, ldap_port);
|
||||
|
||||
ldap_base_dn=strdup(url->lud_dn);
|
||||
report( RPT_INFO, "Using LDAP base DN: %s", ldap_base_dn);
|
||||
|
||||
ldap_free_urldesc(url);
|
||||
|
||||
if (connect_to_ldap() < 0 ) {
|
||||
debug( RPT_DEBUG, "connect_to_ldap returned errors.");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* WITH_LDAP_SUPPORT */
|
||||
|
||||
/* We use a nested fuction to transfer the characters from buffer to parser*/
|
||||
char get_next_char() {
|
||||
if( pos>=bytesread ) {
|
||||
@@ -258,10 +314,94 @@ void config_clear()
|
||||
|
||||
/**** INTERNAL FUNCTIONS ****/
|
||||
|
||||
#ifdef WITH_LDAP_SUPPORT
|
||||
int
|
||||
connect_to_ldap (void)
|
||||
{
|
||||
int retval;
|
||||
LDAPMessage * res;
|
||||
|
||||
debug( RPT_INFO, "Connecting to LDAP server: %s:%d", ldap_host, ldap_port);
|
||||
|
||||
if (!(ld = ldap_init(ldap_host, ldap_port))) {
|
||||
report(RPT_ERR, "LDAP session could not be initialized.");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* disabled unless you really have a DN/pwd to bind to
|
||||
* WARNING: LCDd should not have LDAP write access!!
|
||||
*
|
||||
* if (LDAP_SUCCESS != (retval = ldap_simple_bind_s (ld, ldap_user, ldap_pwd))) {
|
||||
* report (RPT_ERR, "LDAP login on %s:%d failed: %s", ldap_host, ldap_port, ldap_err2string (retval));
|
||||
* ldap_unbind (ld);
|
||||
* ld = NULL;
|
||||
*
|
||||
* return (-1);
|
||||
* }
|
||||
* fprintf(stderr, "LDAP login successful on %s:%d\n", ldap_host, ldap_port);
|
||||
********************************************************/
|
||||
|
||||
/* check for the existence of the config object... */
|
||||
if (LDAP_SUCCESS != (retval = ldap_search_s (ld, ldap_base_dn, LDAP_SCOPE_BASE, "objectClass=lcdprocConfig", NULL, 0, &res))) {
|
||||
report( RPT_ERR, "Could not access LDAP server on %s:%d", ldap_host, ldap_port);
|
||||
return (-1);
|
||||
}
|
||||
if (0 == ldap_count_entries(ld, res)) {
|
||||
report( RPT_ERR, "No configuration object found in LDAP at: %s", ldap_base_dn);
|
||||
return (-1);
|
||||
}
|
||||
debug( RPT_DEBUG, "Configuration LDAP object found.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BUFSIZE 255
|
||||
#endif /* WITH_LDAP_SUPPORT */
|
||||
|
||||
section * find_section( char * sectionname )
|
||||
{
|
||||
section * s;
|
||||
|
||||
#ifdef WITH_LDAP_SUPPORT
|
||||
LDAPMessage * res;
|
||||
int retval;
|
||||
char *filter=NULL;
|
||||
|
||||
if (use_ldap) {
|
||||
debug( RPT_DEBUG, "Searching LDAP for section [%s]", sectionname);
|
||||
if (NULL == (filter = malloc(BUFSIZE))){
|
||||
report( RPT_ERR, "Could not allocate memory in find_section()");
|
||||
return NULL;
|
||||
}
|
||||
strcpy(filter, "cn=");
|
||||
strncat(filter, sectionname, BUFSIZE);
|
||||
if (LDAP_SUCCESS != (retval = ldap_search_s (ld, ldap_base_dn, LDAP_SCOPE_ONELEVEL, filter, NULL, 0, &res))) {
|
||||
if (NULL != filter) {
|
||||
free(filter);
|
||||
filter=NULL;
|
||||
}
|
||||
ldap_msgfree(res);
|
||||
report( RPT_ERR, "Could not access LDAP server on %s:%d", ldap_host, ldap_port);
|
||||
return NULL;
|
||||
}
|
||||
if (NULL != filter) {
|
||||
free(filter);
|
||||
filter=NULL;
|
||||
}
|
||||
if (0 == ldap_count_entries( ld, res )) {
|
||||
debug( RPT_DEBUG, "Section [%s] not found in LDAP.", sectionname);
|
||||
return NULL;
|
||||
}
|
||||
ldap_msgfree(res);
|
||||
debug( RPT_DEBUG, "Found section [%s] in LDAP", sectionname);
|
||||
s = (section*) malloc( sizeof( section ));
|
||||
s->name=strdup( sectionname );
|
||||
s->first_key = NULL;
|
||||
s->next_section = NULL;
|
||||
return s;
|
||||
}
|
||||
#endif /* WITH_LDAP_SUPPORT */
|
||||
|
||||
for( s=first_section; s; s=s->next_section ) {
|
||||
if( strcasecmp( s->name, sectionname ) == 0 ) {
|
||||
return s;
|
||||
@@ -292,9 +432,104 @@ key * find_key( section * s, char * keyname, int skip )
|
||||
int count = 0;
|
||||
key * last_key = NULL;
|
||||
|
||||
#ifdef WITH_LDAP_SUPPORT
|
||||
LDAPMessage * res;
|
||||
LDAPMessage * entry;
|
||||
int retval;
|
||||
char *buf=NULL;
|
||||
char **vals;
|
||||
#endif /* WITH_LDAP_SUPPORT */
|
||||
|
||||
/* Check for NULL section*/
|
||||
if(!s) return NULL;
|
||||
|
||||
#ifdef WITH_LDAP_SUPPORT
|
||||
if (use_ldap) {
|
||||
debug( RPT_DEBUG, "Searching LDAP for key '%s' in section [%s] skipping %d entries.", keyname, s->name, skip);
|
||||
|
||||
if (NULL == (buf = malloc(BUFSIZE))){
|
||||
report (RPT_ERR, "Could not allocate memory in find_key().");
|
||||
}
|
||||
strcpy(buf, "cn=");
|
||||
strncat(buf, s->name, BUFSIZE);
|
||||
if (LDAP_SUCCESS != (retval = ldap_search_s (ld, ldap_base_dn, LDAP_SCOPE_ONELEVEL, buf, NULL, 0, &res))) {
|
||||
if (NULL != buf) {
|
||||
free(buf);
|
||||
buf=NULL;
|
||||
}
|
||||
ldap_msgfree(res);
|
||||
report( RPT_ERR, "Could not access LDAP server on %s:%d", ldap_host, ldap_port);
|
||||
return NULL;
|
||||
}
|
||||
if (NULL == (entry = ldap_first_entry( ld, res ))) {
|
||||
debug( RPT_DEBUG, "Section [%s] not found in LDAP.", s->name);
|
||||
if (NULL != buf) {
|
||||
free(buf);
|
||||
buf=NULL;
|
||||
}
|
||||
/* DON'T enable the following
|
||||
* ldap_msgfree(entry);
|
||||
* ldap_msgfree below does that already
|
||||
*/
|
||||
ldap_msgfree(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
strcpy(buf, "lcdproc");
|
||||
strncat(buf, keyname, BUFSIZE);
|
||||
/* debug( RPT_DEBUG, "Key name translated to attribute name: %s", buf); */
|
||||
vals = ldap_get_values (ld, entry, buf);
|
||||
|
||||
if (skip+1 > ldap_count_values (vals)) {
|
||||
debug( RPT_DEBUG, "No such entry found.");
|
||||
if (NULL != buf) {
|
||||
free(buf);
|
||||
buf=NULL;
|
||||
}
|
||||
ldap_value_free(vals);
|
||||
/* DON'T enable the following
|
||||
* ldap_msgfree(entry);
|
||||
* ldap_msgfree below does that already
|
||||
*/
|
||||
ldap_msgfree(res);
|
||||
return NULL;
|
||||
}
|
||||
/* DON'T enable the following
|
||||
* ldap_msgfree(entry);
|
||||
* ldap_msgfree below does that already
|
||||
*/
|
||||
ldap_msgfree(res);
|
||||
if (vals && vals[skip]) {
|
||||
if (NULL != buf) {
|
||||
free(buf);
|
||||
buf=NULL;
|
||||
}
|
||||
buf=strdup(vals[skip]);
|
||||
debug( RPT_DEBUG, "Entry found. Value is: %s", buf);
|
||||
ldap_value_free (vals);
|
||||
|
||||
k=(key*) malloc( sizeof( key ));
|
||||
k->name = strdup( keyname );
|
||||
k->value = strdup( buf );
|
||||
k->next_key = NULL;
|
||||
|
||||
if (NULL != buf) {
|
||||
free(buf);
|
||||
buf=NULL;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
report( RPT_ERR, "LDAP server encountered errors.");
|
||||
ldap_value_free (vals);
|
||||
if (NULL != buf) {
|
||||
free(buf);
|
||||
buf=NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif /* WITH_LDAP_SUPPORT */
|
||||
|
||||
for( k=s->first_key; k; k=k->next_key ) {
|
||||
|
||||
/* Did we find the right key ?*/
|
||||
|
||||
Reference in New Issue
Block a user