Commit 743d6937 authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[master] LDAP: Pathces, IPv6 support, GSSAPI support

   Merges in 39056.
parent 6a39bcf0
......@@ -253,6 +253,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDAP_CFLAGS = @LDAP_CFLAGS@
LDAP_LIBS = @LDAP_LIBS@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
......
......@@ -179,6 +179,26 @@ by Eric Young (eay@cryptsoft.com).
class has been deleted.
[ISC-Bugs #39978]
- LDAP Patches - Numerous small patches submitted by contributors have
been applied to the contributed code which supplies LDAP support.
In addition, two larger submissions have also been included. The
first adds support for IPv6 configuration adn the second provides
GSSAPI authentication.
[ISC-Bugs #39056]
[ISC-Bugs #22742]
[ISC-Bugs #24449]
[ISC-Bugs #28545]
[ISC-Bugs #29873]
[ISC-Bugs #30183]
[ISC-Bugs #30402]
[ISC-Bugs #32217]
[ISC-Bugs #32240]
[ISC-Bugs #33176]
[ISC-Bugs #33178]
[ISC-Bugs #36409]
[ISC-Bugs #36774]
[ISC-Bugs #37876]
Changes since 4.3.2rc2
- None
......
......@@ -260,6 +260,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDAP_CFLAGS = @LDAP_CFLAGS@
LDAP_LIBS = @LDAP_LIBS@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
......
......@@ -233,6 +233,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDAP_CFLAGS = @LDAP_CFLAGS@
LDAP_LIBS = @LDAP_LIBS@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
......
......@@ -267,6 +267,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDAP_CFLAGS = @LDAP_CFLAGS@
LDAP_LIBS = @LDAP_LIBS@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
......
......@@ -147,13 +147,21 @@ save_parse_state(struct parse *cfile) {
/*
* Return the parser to the previous saved state.
*
* You must call save_parse_state() before calling
* restore_parse_state(), but you can call restore_parse_state() any
* number of times after that.
* You must call save_parse_state() every time before calling
* restore_parse_state().
*
* Note: When the read function callback is in use in ldap mode,
* a call to get_char() may reallocate the buffer and will append
* config data to the buffer until a state restore.
* Do not restore to the (freed) pointer and size, but use new one.
*/
isc_result_t
restore_parse_state(struct parse *cfile) {
struct parse *saved_state;
#if defined(LDAP_CONFIGURATION)
char *inbuf = cfile->inbuf;
size_t size = cfile->bufsiz;
#endif
if (cfile->saved_state == NULL) {
return DHCP_R_NOTYET;
......@@ -161,7 +169,13 @@ restore_parse_state(struct parse *cfile) {
saved_state = cfile->saved_state;
memcpy(cfile, saved_state, sizeof(*cfile));
cfile->saved_state = saved_state;
dfree(saved_state, MDL);
cfile->saved_state = NULL;
#if defined(LDAP_CONFIGURATION)
cfile->inbuf = inbuf;
cfile->bufsiz = size;
#endif
return ISC_R_SUCCESS;
}
......@@ -476,6 +490,8 @@ read_whitespace(int c, struct parse *cfile) {
}
cfile->tokbuf[ofs++] = c;
c = get_char(cfile);
if (c == EOF)
return END_OF_FILE;
} while (!((c == '\n') && cfile->eol_token) &&
isascii(c) && isspace(c));
......
......@@ -271,6 +271,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDAP_CFLAGS = @LDAP_CFLAGS@
LDAP_LIBS = @LDAP_LIBS@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
......
......@@ -626,6 +626,7 @@ am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
LDAP_CFLAGS
LDAP_LIBS
ac_prefix_program
HAVE_ATF_FALSE
HAVE_ATF_TRUE
......@@ -766,6 +767,8 @@ with_relay6_pid_file
with_libbind
with_ldap
with_ldapcrypto
with_ldap_gssapi
with_ldapcasa
'
ac_precious_vars='build_alias
host_alias
......@@ -1463,6 +1466,10 @@ Optional Packages:
--with-ldap enable OpenLDAP support in dhcpd (default is no)
--with-ldapcrypto enable OpenLDAP crypto support in dhcpd (default is
no)
--with-ldap-gssapi enable krb5/gssapi authentication for OpenLDAP in
dhcpd (default is no)
--with-ldapcasa enable LDAP CASA auth support in dhcpd (default is
no)
Some influential environment variables:
CC C compiler command
......@@ -6674,10 +6681,34 @@ else
fi
# Gssapi to allow LDAP to authenticate with a keytab
# Check whether --with-ldap-gssapi was given.
if test "${with_ldap_gssapi+set}" = set; then :
withval=$with_ldap_gssapi; ldap_gssapi=$withval
else
ldap_gssapi=no
fi
# LDAP CASA auth support.
# Check whether --with-ldapcasa was given.
if test "${with_ldapcasa+set}" = set; then :
withval=$with_ldapcasa; ldapcasa=$withval
else
ldapcasa=no
fi
# OpenLDAP support is disabled by default, if enabled then SSL support is an
# extra optional that is also disabled by default. Enabling LDAP SSL support
# implies enabling LDAP support.
if test x$ldap = xyes || test x$ldapcrypto = xyes ; then
# implies enabling LDAP support. Similarly, KRB5 support implies LDAP support,
# but doesn't include SSL. The two are not dependant.
if test x$ldap = xyes || test x$ldapcrypto = xyes || test x$ldap_gssapi = xyes; then
saved_LIBS="$LIBS"
LIBS=""
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ldap_initialize" >&5
$as_echo_n "checking for library containing ldap_initialize... " >&6; }
if ${ac_cv_search_ldap_initialize+:} false; then :
......@@ -6800,14 +6831,136 @@ as_fn_error $? "*** Cannot find ber_pvt_opt_on with -llber - do you need to inst
See \`config.log' for more details" "$LINENO" 5; }
fi
if test x$ldap_gssapi = xyes ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing krb5_init_context" >&5
$as_echo_n "checking for library containing krb5_init_context... " >&6; }
if ${ac_cv_search_krb5_init_context+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char krb5_init_context ();
int
main ()
{
return krb5_init_context ();
;
return 0;
}
_ACEOF
for ac_lib in '' krb5; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_krb5_init_context=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_krb5_init_context+:} false; then :
break
fi
done
if ${ac_cv_search_krb5_init_context+:} false; then :
else
ac_cv_search_krb5_init_context=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_krb5_init_context" >&5
$as_echo "$ac_cv_search_krb5_init_context" >&6; }
ac_res=$ac_cv_search_krb5_init_context
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "*** Cannot find krb5_init_context with -lkrb5 - do you need to install a Kerberos Devel package?
See \`config.log' for more details" "$LINENO" 5; }
fi
fi
# Create LDAP_LIBS which we specify them explicitly rather than lumping them in with LIBS
LDAP_LIBS=$LIBS
LIBS="$saved_LIBS"
for ac_header in ldap.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "ldap.h" "ac_cv_header_ldap_h" "$ac_includes_default"
if test "x$ac_cv_header_ldap_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LDAP_H 1
_ACEOF
fi
done
for ac_func in inet_pton inet_ntop
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
if test x$ldapcrypto = xyes ; then
LDAP_CFLAGS="-DLDAP_CONFIGURATION -DLDAP_USE_SSL"
else
LDAP_CFLAGS="-DLDAP_CONFIGURATION"
LDAP_CFLAGS="-DLDAP_CONFIGURATION"
if test x$ldapcasa = xyes ; then
for ac_header in micasa_mgmd.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "micasa_mgmd.h" "ac_cv_header_micasa_mgmd_h" "$ac_includes_default"
if test "x$ac_cv_header_micasa_mgmd_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_MICASA_MGMD_H 1
_ACEOF
LDAP_CFLAGS="$LDAP_CFLAGS -DLDAP_CASA_AUTH"
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "*** Cannot find micasa_mgmd.h for ldap casa auth support
See \`config.log' for more details" "$LINENO" 5; }
fi
done
fi
if test x$ldapcrypto = xyes ; then
LDAP_CFLAGS="$LDAP_CFLAGS -DLDAP_USE_SSL"
fi
if test x$ldap_gssapi = xyes; then
LDAP_CFLAGS="$LDAP_CFLAGS -DLDAP_USE_GSSAPI"
fi
LDAP_CFLAGS=$LDAP_CFLAGS
fi
# Append selected warning levels to CFLAGS before substitution (but after
......
......@@ -636,20 +636,63 @@ AC_ARG_WITH(ldapcrypto,
[ldapcrypto=$withval],
[ldapcrypto=no])
# Gssapi to allow LDAP to authenticate with a keytab
AC_ARG_WITH(ldap-gssapi,
AC_HELP_STRING([--with-ldap-gssapi],
[enable krb5/gssapi authentication for OpenLDAP in dhcpd (default is no)]),
[ldap_gssapi=$withval],
[ldap_gssapi=no])
# LDAP CASA auth support.
AC_ARG_WITH(ldapcasa,
AC_HELP_STRING([--with-ldapcasa],
[enable LDAP CASA auth support in dhcpd (default is no)]),
[ldapcasa=$withval],
[ldapcasa=no])
# OpenLDAP support is disabled by default, if enabled then SSL support is an
# extra optional that is also disabled by default. Enabling LDAP SSL support
# implies enabling LDAP support.
if test x$ldap = xyes || test x$ldapcrypto = xyes ; then
# implies enabling LDAP support. Similarly, KRB5 support implies LDAP support,
# but doesn't include SSL. The two are not dependant.
if test x$ldap = xyes || test x$ldapcrypto = xyes || test x$ldap_gssapi = xyes; then
saved_LIBS="$LIBS"
LIBS=""
AC_SEARCH_LIBS(ldap_initialize, [ldap], ,
AC_MSG_FAILURE([*** Cannot find ldap_initialize with -lldap - do you need to install an OpenLDAP2 Devel package?]))
AC_SEARCH_LIBS(ber_pvt_opt_on, [lber], ,
AC_MSG_FAILURE([*** Cannot find ber_pvt_opt_on with -llber - do you need to install an OpenLDAP2 Devel package?]))
if test x$ldap_gssapi = xyes ; then
AC_SEARCH_LIBS(krb5_init_context, [krb5], ,
AC_MSG_FAILURE([*** Cannot find krb5_init_context with -lkrb5 - do you need to install a Kerberos Devel package?]))
fi
# Create LDAP_LIBS which we specify them explicitly rather than lumping them in with LIBS
AC_SUBST(LDAP_LIBS, [$LIBS])
LIBS="$saved_LIBS"
AC_CHECK_HEADERS([ldap.h])
AC_CHECK_FUNCS([inet_pton inet_ntop])
LDAP_CFLAGS="-DLDAP_CONFIGURATION"
if test x$ldapcasa = xyes ; then
AC_CHECK_HEADERS([micasa_mgmd.h],[
LDAP_CFLAGS="$LDAP_CFLAGS -DLDAP_CASA_AUTH"
], AC_MSG_FAILURE([*** Cannot find micasa_mgmd.h for ldap casa auth support]))
fi
if test x$ldapcrypto = xyes ; then
AC_SUBST(LDAP_CFLAGS, ["-DLDAP_CONFIGURATION -DLDAP_USE_SSL"])
else
AC_SUBST(LDAP_CFLAGS, ["-DLDAP_CONFIGURATION"])
LDAP_CFLAGS="$LDAP_CFLAGS -DLDAP_USE_SSL"
fi
if test x$ldap_gssapi = xyes; then
LDAP_CFLAGS="$LDAP_CFLAGS -DLDAP_USE_GSSAPI"
fi
AC_SUBST(LDAP_CFLAGS, [$LDAP_CFLAGS])
fi
# Append selected warning levels to CFLAGS before substitution (but after
......
......@@ -83,6 +83,12 @@ options:
ldap-tls-reqcert, ldap-tls-ca-file, ldap-tls-ca-dir, ldap-tls-cert
ldap-tls-key, ldap-tls-crlcheck, ldap-tls-ciphers, ldap-tls-randfile
The ldap-init-retry <num> enables an optional ldap connect retry loop with
the specified number of retries with a one second sleep between each try
during the initial startup of the dhcp server.
It allows to catch the condition, that the (remote) ldap server is not yet
started at the start time of the dhcp server.
All of these parameters should be self explanatory except for the ldap-method.
You can set this to static or dynamic. If you set it to static, the
configuration is read once on startup, and LDAP isn't used anymore. But, if
......@@ -189,3 +195,38 @@ into problems reading the configuration, try running dhcpd with the -d flag.
If you still have problems, edit the site.conf file in the DHCP source and
add the line: COPTS= -DDEBUG_LDAP and recompile DHCP. (make sure you run make
clean and rerun configure before you rebuild).
DHCPv6 requires a separate instance of the dhcpd server from the
DHCPv4 server.
It is convenient to use distinct LDAP login DNs for the two servers,
and setup LDAP access restrictions in the LDAP server, so that each
DHCP server only has access to its own data.
You will need to create a separate configuration file,
call it /etc/dhcpd6.conf. For example:
ldap-server "localhost";
ldap-port 389;
ldap-username "cn=DHCPv6 User, dc=ntelos, dc=net";
ldap-password "blahblah";
ldap-base-dn "dc=ntelos, dc=net";
ldap-method dynamic;
ldap-debug-file "/var/log/dhcp-ldap-startup.log";
And use these command line arguments to dhcpd:
dhcpd eth... -6 -cf /etc/dhcpd6.conf -pf /var/run/dhcpd6.pid -lf /var/lib/dhcpd6/dhcpd.leases
For DHCPv6, the client configuration is the same, but substitute the
Client ID for the Ethernet hardware address. Here is an example of a
host definition for a DHCPv6 client:
dn: cn=examplehost,cn=XXXX:XXXX:XXXX:XXXX::/64,cn=Network-eth1,cn=DHCPv6,dc=example,dc=com
objectClass: top
objectClass: dhcpHost
cn: examplehost
dhcpClientId: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
dhcpStatements: fixed-address6 XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX
option host-name "examplehost.ipv6.example.com"
option domain-name "ipv6.example.com"
......@@ -334,6 +334,18 @@ attributetype ( 2.16.840.1.113719.1.203.4.56
DESC 'Generic attribute that allows coments within any DHCP object'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
attributetype ( 2.16.840.1.113719.1.203.4.57
NAME 'dhcpClientId'
EQUALITY caseIgnoreIA5Match
DESC 'client Identifier.'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
attributetype ( 2.16.840.1.113719.1.203.4.58
NAME 'dhcpRange6'
EQUALITY caseIgnoreIA5Match
DESC 'The starting & ending IP Addresses in the range (inclusive), separated by a hyphen; if the range only contains one address, then just the address can be specified with no hyphen. Each range is defined as a separate value.'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
# Classes
objectclass ( 2.16.840.1.113719.1.203.6.1
......@@ -378,7 +390,7 @@ objectclass ( 2.16.840.1.113719.1.203.6.6
DESC 'This represents information about a particular client'
SUP top
MUST cn
MAY (dhcpLeaseDN $ dhcpHWAddress $ dhcpOptionsDN $ dhcpStatements $ dhcpComments $ dhcpOption)
MAY (dhcpLeaseDN $ dhcpHWAddress $ dhcpOptionsDN $ dhcpStatements $ dhcpComments $ dhcpOption $ dhcpClientId)
X-NDS_CONTAINMENT ('dhcpService' 'dhcpSubnet' 'dhcpGroup') )
objectclass ( 2.16.840.1.113719.1.203.6.7
......@@ -459,4 +471,18 @@ objectclass ( 2.16.840.1.113719.1.203.6.16
MAY ( dhcpServiceDN $dhcpServerDN $ dhcpSharedNetworkDN $ dhcpSubnetDN $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $ dhcpClassesDN $ dhcpKeyDN $ dhcpZoneDN $ dhcpFailOverPeerDN $ dhcpOption $ dhcpComments)
X-NDS_CONTAINMENT ('organization' 'organizationalunit' 'domain') )
objectclass ( 2.16.840.1.113719.1.203.6.17
NAME 'dhcpSubnet6'
DESC 'This class defines an IPv6 subnet. This is a container object.'
SUP top
MUST ( cn )
MAY ( dhcpRange6 $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $ dhcpClassesDN $ dhcpLeasesDN $ dhcpOptionsDN $ dhcpZoneDN $ dhcpKeyDN $ dhcpFailOverPeerDN $ dhcpStatements $ dhcpComments $ dhcpOption $ dhcpPermitList ) X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork') )
objectclass ( 2.16.840.1.113719.1.203.6.18
NAME 'dhcpPool6'
DESC 'This stores configuration information about an IPv6 pool.'
SUP top
MUST ( cn $ dhcpRange6 )
MAY ( dhcpClassesDN $ dhcpPermitList $ dhcpLeasesDN $ dhcpOptionsDN $ dhcpZoneDN $dhcpKeyDN $ dhcpStatements $ dhcpComments $ dhcpOption )
X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpSharedNetwork') )
......@@ -137,6 +137,7 @@ add_dn_to_stack
local ($dn) = @_;
$current_dn = "$dn, $current_dn";
$curentry{'current_dn'} = $current_dn;
}
......@@ -154,6 +155,26 @@ parse_error
exit (1);
}
sub
new_entry
{
if (%curentry) {
$curentry{'current_dn'} = $current_dn;
push(@entrystack, {%curentry});
undef(%curentry);
}
}
sub
pop_entry
{
if (%curentry) {
push(@outputlist, {%curentry});
}
$rentry = pop(@entrystack);
%curentry = %$rentry if $rentry;
}
sub
print_entry
......@@ -167,7 +188,7 @@ print_entry
print "cn: $server\n";
print "objectClass: top\n";
print "objectClass: dhcpServer\n";
print "dhcpServiceDN: $current_dn\n";
print "dhcpServiceDN: $curentry{'current_dn'}\n";
if(grep(/FaIlOvEr/i, @use))
{
foreach my $fo_peer (keys %failover)
......@@ -179,7 +200,7 @@ print_entry
}
print "\n";
print "dn: $current_dn\n";
print "dn: $curentry{'current_dn'}\n";
print "cn: $dhcpcn\n";
print "objectClass: top\n";
print "objectClass: dhcpService\n";
......@@ -195,7 +216,7 @@ print_entry
}
elsif ($curentry{'type'} eq 'subnet')
{
print "dn: $current_dn\n";
print "dn: $curentry{'current_dn'}\n";
print "cn: " . $curentry{'ip'} . "\n";
print "objectClass: top\n";
print "objectClass: dhcpSubnet\n";
......@@ -215,7 +236,7 @@ print_entry
}
elsif ($curentry{'type'} eq 'shared-network')
{
print "dn: $current_dn\n";
print "dn: $curentry{'current_dn'}\n";
print "cn: " . $curentry{'descr'} . "\n";
print "objectClass: top\n";
print "objectClass: dhcpSharedNetwork\n";
......@@ -226,7 +247,7 @@ print_entry
}
elsif ($curentry{'type'} eq 'group')
{
print "dn: $current_dn\n";
print "dn: $curentry{'current_dn'}\n";
print "cn: group", $curentry{'idx'}, "\n";
print "objectClass: top\n";
print "objectClass: dhcpGroup\n";
......@@ -237,7 +258,7 @@ print_entry
}
elsif ($curentry{'type'} eq 'host')
{
print "dn: $current_dn\n";
print "dn: $curentry{'current_dn'}\n";
print "cn: " . $curentry{'host'} . "\n";
print "objectClass: top\n";
print "objectClass: dhcpHost\n";
......@@ -254,7 +275,7 @@ print_entry
}
elsif ($curentry{'type'} eq 'pool')
{
print "dn: $current_dn\n";
print "dn: $curentry{'current_dn'}\n";
print "cn: pool", $curentry{'idx'}, "\n";
print "objectClass: top\n";
print "objectClass: dhcpPool\n";
......@@ -273,7 +294,7 @@ print_entry
}
elsif ($curentry{'type'} eq 'class')
{
print "dn: $current_dn\n";
print "dn: $curentry{'current_dn'}\n";
print "cn: " . $curentry{'class'} . "\n";
print "objectClass: top\n";
print "objectClass: dhcpClass\n";
......@@ -284,7 +305,7 @@ print_entry
}
elsif ($curentry{'type'} eq 'subclass')
{
print "dn: $current_dn\n";
print "dn: $curentry{'current_dn'}\n";
print "cn: " . $curentry{'subclass'} . "\n";
print "objectClass: top\n";
print "objectClass: dhcpSubClass\n";
......@@ -344,7 +365,7 @@ sub parse_subnet
{
local ($ip, $tmp, $netmask);
print_entry () if %curentry;
new_entry ();
$ip = next_token (0);
parse_error () if !defined ($ip);
......@@ -374,7 +395,7 @@ sub parse_shared_network
{
local ($descr, $tmp);
print_entry () if %curentry;
new_entry ();
$descr = next_token (0);
parse_error () if !defined ($descr);
......@@ -393,7 +414,7 @@ sub parse_host
{
local ($descr, $tmp);
print_entry () if %curentry;
new_entry ();
$host = next_token (0);
parse_error () if !defined ($host);
......@@ -412,7 +433,7 @@ sub parse_group
{
local ($descr, $tmp);
print_entry () if