Attached find a series of patches that implement a CLDAP server as a dirsrv plugin.
The server right now responds only to a very limited class of requests, as observed on the wire. But it can be easily expanded to respond to additional requests as needed. Tested against windows 2008 with which I had create a trust. To test you need Sumit's uncommitted adtrust code to successfully create the trust and provision the IPA tree with the right data. Simo. -- Simo Sorce * Red Hat, Inc * New York
>From 9ffe37efbd18b5da084a8328766bacd6e3c31e0b Mon Sep 17 00:00:00 2001 From: Simo Sorce <[email protected]> Date: Wed, 16 Nov 2011 09:59:46 -0500 Subject: [PATCH 1/6] Add NT domain GUID attribute. We need this to be able to re-set it, as ipaUniqueID cannot be arbitraily set to a value. Only needed for the domain object. --- install/share/60basev3.ldif | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/install/share/60basev3.ldif b/install/share/60basev3.ldif index d118de2f04a81c0b858d20b5aeb997e6e313fd9a..f518541586b2df9ed08718098a7f170563aa4e1d 100644 --- a/install/share/60basev3.ldif +++ b/install/share/60basev3.ldif @@ -13,7 +13,8 @@ attributeTypes: (2.16.840.1.113730.3.8.11.6 NAME 'ipaNTLogonScript' DESC 'User L attributeTypes: (2.16.840.1.113730.3.8.11.7 NAME 'ipaNTProfilePath' DESC 'User Profile Path' EQUALITY caseIgnoreMatch OREDRING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3' ) attributeTypes: (2.16.840.1.113730.3.8.11.8 NAME 'ipaNTHomeDirectory' DESC 'User Home Directory Path' EQUALITY caseIgnoreMatch OREDRING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3' ) attributeTypes: (2.16.840.1.113730.3.8.11.9 NAME 'ipaNTHomeDirectoryDrive' DESC 'User Home Drive Letter' EQUALITY caseIgnoreMatch OREDRING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3' ) +attributeTypes: (2.16.840.1.113730.3.8.11.10 NAME 'ipaNTDomainGUID' DESC 'NT Domain GUID' EQUALITY caseIgnoreIA5Match OREDRING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'IPA v3' ) objectClasses: (2.16.840.1.113730.3.8.12.1 NAME 'ipaExternalGroup' SUP top STRUCTURAL MUST ( cn ) MAY ( ipaExternalMember $ memberOf $ description $ owner) X-ORIGIN 'IPA v3' ) objectClasses: (2.16.840.1.113730.3.8.12.2 NAME 'ipaNTUserAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier ) MAY ( ipaNTHash $ ipaNTLogonScript $ ipaNTProfilePath $ ipaNTHomeDirectory $ ipaNTHomeDirectoryDrive ) X-ORIGIN 'IPA v3' ) objectClasses: (2.16.840.1.113730.3.8.12.3 NAME 'ipaNTGroupAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier ) X-ORIGIN 'IPA v3' ) -objectClasses: (2.16.840.1.113730.3.8.12.4 NAME 'ipaNTDomainAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier $ ipaNTFlatName ) MAY ( ipaNTFallbackPrimaryGroup ) X-ORIGIN 'IPA v3' ) +objectClasses: (2.16.840.1.113730.3.8.12.4 NAME 'ipaNTDomainAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier $ ipaNTFlatName $ ipaNTDomainGUID ) MAY ( ipaNTFallbackPrimaryGroup ) X-ORIGIN 'IPA v3' ) -- 1.7.7.1
>From 926e2d8249d7453d95d907ca7cb2641745f9f412 Mon Sep 17 00:00:00 2001 From: Simo Sorce <[email protected]> Date: Wed, 9 Nov 2011 19:03:48 -0500 Subject: [PATCH 2/6] Create skeleton CLDAP server as a DS plugin --- daemons/configure.ac | 2 + daemons/ipa-slapi-plugins/Makefile.am | 1 + daemons/ipa-slapi-plugins/ipa-cldap/Makefile.am | 49 +++++ .../ipa-cldap/ipa-cldap-conf.ldif | 16 ++ daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.c | 225 ++++++++++++++++++++ daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h | 72 +++++++ .../ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c | 48 ++++ freeipa.spec.in | 15 +- 8 files changed, 422 insertions(+), 6 deletions(-) create mode 100644 daemons/ipa-slapi-plugins/ipa-cldap/Makefile.am create mode 100644 daemons/ipa-slapi-plugins/ipa-cldap/ipa-cldap-conf.ldif create mode 100644 daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.c create mode 100644 daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h create mode 100644 daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c diff --git a/daemons/configure.ac b/daemons/configure.ac index f89c50d62a3d59c3dddd3439f285fe6e5d9b89ee..46f476574cee0d48910748496cfb1faa2df974bf 100644 --- a/daemons/configure.ac +++ b/daemons/configure.ac @@ -234,6 +234,7 @@ PKG_PROG_PKG_CONFIG() PKG_CHECK_MODULES([TALLOC], [talloc]) PKG_CHECK_MODULES([TEVENT], [tevent]) PKG_CHECK_MODULES([NDRPAC], [ndr_krb5pac]) +PKG_CHECK_MODULES([NDRNBT], [ndr_nbt]) dnl --------------------------------------------------------------------------- @@ -300,6 +301,7 @@ AC_CONFIG_FILES([ Makefile ipa-kdb/Makefile ipa-slapi-plugins/Makefile + ipa-slapi-plugins/ipa-cldap/Makefile ipa-slapi-plugins/ipa-enrollment/Makefile ipa-slapi-plugins/ipa-lockout/Makefile ipa-slapi-plugins/ipa-pwd-extop/Makefile diff --git a/daemons/ipa-slapi-plugins/Makefile.am b/daemons/ipa-slapi-plugins/Makefile.am index 25f50d5f7c64f4daa88e71c6e9d600009a8c46fe..29b985e69424c9f2ce453ea3607cdb0e936bcce2 100644 --- a/daemons/ipa-slapi-plugins/Makefile.am +++ b/daemons/ipa-slapi-plugins/Makefile.am @@ -1,6 +1,7 @@ NULL = SUBDIRS = \ + ipa-cldap \ ipa-enrollment \ ipa-lockout \ ipa-modrdn \ diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/Makefile.am b/daemons/ipa-slapi-plugins/ipa-cldap/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..b563e98763d78298b64de92c59716bacd8c822a4 --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-cldap/Makefile.am @@ -0,0 +1,49 @@ +NULL = + +PLUGIN_COMMON_DIR=../common + +INCLUDES = \ + -I. \ + -I$(srcdir) \ + -I$(PLUGIN_COMMON_DIR) \ + -I$(COMMON_BER_DIR) \ + -DPREFIX=\""$(prefix)"\" \ + -DBINDIR=\""$(bindir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DLIBEXECDIR=\""$(libexecdir)"\" \ + -DDATADIR=\""$(datadir)"\" \ + $(AM_CFLAGS) \ + $(LDAP_CFLAGS) \ + $(WARN_CFLAGS) \ + $(NDRNBT_CFLAGS) \ + $(NULL) + +plugindir = $(libdir)/dirsrv/plugins +plugin_LTLIBRARIES = \ + libipa_cldap.la \ + $(NULL) + +libipa_cldap_la_SOURCES = \ + ipa_cldap_worker.c \ + ipa_cldap.c \ + $(NULL) + +libipa_cldap_la_LDFLAGS = -avoid-version + +libipa_cldap_la_LIBADD = \ + $(LDAP_LIBS) \ + $(NDRNBT_LIBS) \ + $(NULL) + +appdir = $(IPA_DATA_DIR) +app_DATA = \ + ipa-cldap-conf.ldif \ + $(NULL) + +EXTRA_DIST = \ + $(app_DATA) \ + $(NULL) + +MAINTAINERCLEANFILES = \ + *~ \ + Makefile.in diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa-cldap-conf.ldif b/daemons/ipa-slapi-plugins/ipa-cldap/ipa-cldap-conf.ldif new file mode 100644 index 0000000000000000000000000000000000000000..2d70b9acfde7dabdb23c0db8dad49d84204b32b1 --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa-cldap-conf.ldif @@ -0,0 +1,16 @@ +dn: cn=ipa_cldap,cn=plugins,cn=config +changetype: add +objectclass: top +objectclass: nsSlapdPlugin +objectclass: extensibleObject +cn: ipa_cldap +nsslapd-pluginpath: libipa_cldap +nsslapd-plugininitfunc: ipa_cldap_init +nsslapd-plugintype: postoperation +nsslapd-pluginenabled: on +nsslapd-pluginid: ipa_cldap_init +nsslapd-pluginversion: @PACKAGE_VERSION@ +nsslapd-pluginvendor: RedHat +nsslapd-plugindescription: CLDAP Server to interoperate with AD +nsslapd-plugin-depends-on-type: database +nsslapd-basedn: $SUFFIX diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.c b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.c new file mode 100644 index 0000000000000000000000000000000000000000..545c244ed1a161d525e8a538ae1706d463e2ba4f --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.c @@ -0,0 +1,225 @@ +/** BEGIN COPYRIGHT BLOCK + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Additional permission under GPLv3 section 7: + * + * In the following paragraph, "GPL" means the GNU General Public + * License, version 3 or any later version, and "Non-GPL Code" means + * code that is governed neither by the GPL nor a license + * compatible with the GPL. + * + * You may link the code of this Program with Non-GPL Code and convey + * linked combinations including the two, provided that such Non-GPL + * Code only links to the code of this Program through those well + * defined interfaces identified in the file named EXCEPTION found in + * the source code files (the "Approved Interfaces"). The files of + * Non-GPL Code may instantiate templates or use macros or inline + * functions from the Approved Interfaces without causing the resulting + * work to be covered by the GPL. Only the copyright holders of this + * Program may make changes or additions to the list of Approved + * Interfaces. + * + * Authors: + * Simo Sorce <[email protected]> + * + * Copyright (C) 2011 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +#include "ipa_cldap.h" +#include "util.h" + +Slapi_PluginDesc ipa_cldap_desc = { + IPA_CLDAP_PLUGIN_NAME, + "FreeIPA project", + "FreeIPA/3.0", + IPA_CLDAP_PLUGIN_DESC +}; + +static int ipa_cldap_start(Slapi_PBlock *pb) +{ + struct ipa_cldap_ctx *ctx; + int ret; + + ret = slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &ctx); + if (ret) { + LOG_FATAL("No plugin context ?!\n"); + return -1; + } + + ret = pthread_create(&ctx->tid, NULL, ipa_cldap_worker, ctx); + if (ret) { + LOG_FATAL("Failed to create worker thread\n"); + return -1; + } + + LOG("Plugin statrup completed.\n"); + + return 0; +} + +static int ipa_cldap_stop(Slapi_PBlock *pb) +{ + struct ipa_cldap_ctx *ctx; + void *retval; + int ret; + + ret = slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &ctx); + if (ret) { + LOG_FATAL("No plugin context ?!\n"); + return -1; + } + + ctx->stop = true; + ret = pthread_join(ctx->tid, &retval); + if (ret) { + LOG_FATAL("Failed to stop worker thread\n"); + return -1; + } + + LOG("Plugin shutdown completed.\n"); + + return 0; +} + +static int ipa_cldap_init_service(Slapi_PBlock *pb, + struct ipa_cldap_ctx **cldap_ctx) +{ + struct ipa_cldap_ctx *ctx; + struct sockaddr_in6 addr; + Slapi_Entry *e; + int flags; + int val; + int ret; + + ctx = calloc(1, sizeof(struct ipa_cldap_ctx)); + if (!ctx) { + return ENOMEM; + } + ctx->sd = -1; + + ret = slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &ctx->plugin_id); + if ((ret != 0) || (NULL == ctx->plugin_id)) { + LOG_FATAL("Could not get identity or identity was NULL\n"); + if (ret == 0) { + ret = -1; + } + goto done; + } + + slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &e); + if (!e) { + LOG_FATAL("Plugin configuration not found!\n"); + return -1; + } + + ctx->base_dn = slapi_entry_attr_get_charptr(e, "nsslapd-basedn"); + if (!ctx->base_dn) { + LOG_FATAL("Plugin configuration not found!\n"); + return -1; + } + + ctx->sd = socket(PF_INET6, SOCK_DGRAM, 0); + if (ctx->sd == -1) { + LOG_FATAL("Failed to create socket\n"); + ret = EIO; + goto done; + } + + val = 1; + ret = setsockopt(ctx->sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + if (ret == -1) { + ret = errno; + LOG("Failed to make socket immediately reusable (%d, %s)\n", + ret, strerror(ret)); + } + + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(CLDAP_PORT); + + ret = bind(ctx->sd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret == -1) { + ret = errno; + LOG_FATAL("Failed to bind socket (%d, %s)\n", ret, strerror(ret)); + goto done; + } + + flags = fcntl(ctx->sd, F_GETFL); + if ((flags & O_NONBLOCK) == 0) { + ret = fcntl(ctx->sd, F_SETFL, flags | O_NONBLOCK); + if (ret == -1) { + ret = errno; + LOG_FATAL("Failed to set socket to non-blocking\n"); + goto done; + } + } + +done: + if (ret) { + if (ctx->sd != -1) { + close(ctx->sd); + } + free(ctx); + } else { + *cldap_ctx = ctx; + } + return ret; +} + +static int ipa_cldap_post_init(Slapi_PBlock *pb) +{ + return 0; +} + +/* Initialization function */ +int ipa_cldap_init(Slapi_PBlock *pb) +{ + struct ipa_cldap_ctx *cldap_ctx = NULL; + int ret; + + ret = ipa_cldap_init_service(pb, &cldap_ctx); + if (ret) { + LOG_FATAL("Failed to initialize CLDAP Plugin\n"); + /* do not cause DS to stop, simply do nothing */ + return 0; + } + + /* Register the plug-in */ + ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03); + if (!ret) { + ret = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, &ipa_cldap_desc); + } + if (!ret) { + ret = slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, &ipa_cldap_start); + } + if (!ret) { + ret = slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, &ipa_cldap_stop); + } + if (!ret) { + ret = slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, cldap_ctx); + } + if (ret) { + LOG_FATAL("Failed to initialize plug-in\n" ); + return -1; + } + + slapi_register_plugin("postoperation", 1, + "ipa_cldap_post_init", + ipa_cldap_post_init, + "CLDAP post ops", NULL, + cldap_ctx->plugin_id); + + return 0; +} diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h new file mode 100644 index 0000000000000000000000000000000000000000..fa86501dd37fcf604474a3390d9725fa85197c56 --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h @@ -0,0 +1,72 @@ +/** BEGIN COPYRIGHT BLOCK + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Additional permission under GPLv3 section 7: + * + * In the following paragraph, "GPL" means the GNU General Public + * License, version 3 or any later version, and "Non-GPL Code" means + * code that is governed neither by the GPL nor a license + * compatible with the GPL. + * + * You may link the code of this Program with Non-GPL Code and convey + * linked combinations including the two, provided that such Non-GPL + * Code only links to the code of this Program through those well + * defined interfaces identified in the file named EXCEPTION found in + * the source code files (the "Approved Interfaces"). The files of + * Non-GPL Code may instantiate templates or use macros or inline + * functions from the Approved Interfaces without causing the resulting + * work to be covered by the GPL. Only the copyright holders of this + * Program may make changes or additions to the list of Approved + * Interfaces. + * + * Authors: + * Simo Sorce <[email protected]> + * + * Copyright (C) 2011 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +#ifndef _IPA_CLDAP_H_ +#define _IPA_CLDAP_H_ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdlib.h> +#include <pthread.h> +#include <dirsrv/slapi-plugin.h> +#include "util.h" + +#define IPA_CLDAP_PLUGIN_NAME "CLDAP Server" +#define IPA_CLDAP_PLUGIN_DESC "MS/AD introperable CLDAP server" + +#define IPA_PLUGIN_NAME IPA_CLDAP_PLUGIN_NAME +#define CLDAP_PORT 389 + +struct ipa_cldap_ctx { + Slapi_ComponentId *plugin_id; + pthread_t tid; + char *base_dn; + volatile bool stop; + int sd; +}; + +void *ipa_cldap_worker(struct ipa_cldap_ctx *ctx); + +#endif /* _IPA_CLDAP_H_ */ diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c new file mode 100644 index 0000000000000000000000000000000000000000..d90f0e16bc6ea51cb7e5250ef9b952224105211b --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c @@ -0,0 +1,48 @@ +/** BEGIN COPYRIGHT BLOCK + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Additional permission under GPLv3 section 7: + * + * In the following paragraph, "GPL" means the GNU General Public + * License, version 3 or any later version, and "Non-GPL Code" means + * code that is governed neither by the GPL nor a license + * compatible with the GPL. + * + * You may link the code of this Program with Non-GPL Code and convey + * linked combinations including the two, provided that such Non-GPL + * Code only links to the code of this Program through those well + * defined interfaces identified in the file named EXCEPTION found in + * the source code files (the "Approved Interfaces"). The files of + * Non-GPL Code may instantiate templates or use macros or inline + * functions from the Approved Interfaces without causing the resulting + * work to be covered by the GPL. Only the copyright holders of this + * Program may make changes or additions to the list of Approved + * Interfaces. + * + * Authors: + * Simo Sorce <[email protected]> + * + * Copyright (C) 2011 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +#include "ipa_cldap.h" + +void *ipa_cldap_worker(struct ipa_cldap_ctx *ctx) +{ + + while (!ctx->stop) { + sleep(1); + } +} diff --git a/freeipa.spec.in b/freeipa.spec.in index 6531cf5dde55bcbf8f57125dfdc8b1e53c7d6e3d..2da5d41768f3e04555c0807819aaa9b28c1f2d8f 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -24,11 +24,7 @@ Source0: freeipa-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %if ! %{ONLY_CLIENT} -%if 0%{?fedora} >= 16 -BuildRequires: 389-ds-base-devel >= 1.2.10 -%else -BuildRequires: 389-ds-base-devel >= 1.2.9 -%endif +BuildRequires: 389-ds-base-devel >= 1.2.10-0.5.a5 BuildRequires: svrcore-devel BuildRequires: /usr/share/selinux/devel/Makefile BuildRequires: policycoreutils >= %{POLICYCOREUTILSVER} @@ -93,7 +89,7 @@ Requires: %{name}-python = %{version}-%{release} Requires: %{name}-client = %{version}-%{release} Requires: %{name}-admintools = %{version}-%{release} Requires: %{name}-server-selinux = %{version}-%{release} -Requires(pre): 389-ds-base >= 1.2.10-0.4.a4 +Requires(pre): 389-ds-base >= 1.2.10-0.5.a5 Requires: openldap-clients Requires: nss Requires: nss-tools @@ -330,6 +326,7 @@ rm %{buildroot}/%{plugin_dir}/libipa_repl_version.la rm %{buildroot}/%{plugin_dir}/libipa_uuid.la rm %{buildroot}/%{plugin_dir}/libipa_modrdn.la rm %{buildroot}/%{plugin_dir}/libipa_lockout.la +rm %{buildroot}/%{plugin_dir}/libipa_cldap.la rm %{buildroot}/%{_libdir}/krb5/plugins/kdb/ipadb.la # Some user-modifiable HTML files are provided. Move these to /etc @@ -541,6 +538,7 @@ fi %attr(755,root,root) %{plugin_dir}/libipa_uuid.so %attr(755,root,root) %{plugin_dir}/libipa_modrdn.so %attr(755,root,root) %{plugin_dir}/libipa_lockout.so +%attr(755,root,root) %{plugin_dir}/libipa_cldap.so %dir %{_localstatedir}/lib/ipa %attr(700,root,root) %dir %{_localstatedir}/lib/ipa/sysrestore %dir %{_localstatedir}/cache/ipa @@ -618,6 +616,11 @@ fi %ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/default.conf %changelog +* Wed Nov 17 2011 Simo Sorce <[email protected]> - 2.99.0-12 +- Add CLDAP plugin +- Set min nvr of 389-ds-base to 1.2.10-0.5.a5 for SLAPI_PLUGIN_CONFIG_ENTRY + support + * Wed Nov 14 2011 Endi S. Dewata <[email protected]> - 2.99.0-11 - Make sure changes to extension.js are not removed. -- 1.7.7.1
>From 7d4c69e59a5d0724977b5720489a0fa7cf35c51e Mon Sep 17 00:00:00 2001 From: Simo Sorce <[email protected]> Date: Mon, 14 Nov 2011 17:38:53 -0500 Subject: [PATCH 3/6] ipa-cldap: Implement worker thread. --- .../ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c | 72 +++++++++++++++++++- 1 files changed, 71 insertions(+), 1 deletions(-) diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c index d90f0e16bc6ea51cb7e5250ef9b952224105211b..3ca767e946eb7e251c0ea019ef65e4961f1871db 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c @@ -38,11 +38,81 @@ * END COPYRIGHT BLOCK **/ #include "ipa_cldap.h" +#include <poll.h> + +#define MAX_DG_SIZE 4096 + +struct ipa_cldap_req { + int fd; + + struct sockaddr_storage ss; + socklen_t ss_len; + + char dgram[MAX_DG_SIZE]; + size_t dgsize; +}; + +static void ipa_cldap_process(struct ipa_cldap_ctx *ctx, + struct ipa_cldap_req *req) +{ + free(req); + return; +} + +static struct ipa_cldap_req *ipa_cldap_recv_dgram(struct ipa_cldap_ctx *ctx) +{ + struct ipa_cldap_req *req; + + req = malloc(sizeof(struct ipa_cldap_req)); + if (!req) { + LOG("Failed to allocate memory for req"); + return NULL; + } + + req->fd = ctx->sd; + req->ss_len = sizeof(struct sockaddr_storage); + + req->dgsize = recvfrom(req->fd, req->dgram, MAX_DG_SIZE, 0, + (struct sockaddr *)&req->ss, &req->ss_len); + if (req->dgsize == -1) { + LOG_TRACE("Failed to get datagram\n"); + free(req); + return NULL; + } + + return req; +} void *ipa_cldap_worker(struct ipa_cldap_ctx *ctx) { + struct ipa_cldap_req *req; + struct pollfd fds; + int ret; while (!ctx->stop) { - sleep(1); + + fds.fd = ctx->sd; + fds.events = POLLIN; + fds.revents = 0; + + /* wait until a request comes in */ + ret = poll(&fds, 1, -1); + if (ret == -1) { + if (errno == EINTR) { + /* restart polling */ + continue; + } + } + if (ret == 0) { + continue; + } + + if (ret > 0 && fds.revents & POLLIN) { + req = ipa_cldap_recv_dgram(ctx); + if (req) { + ipa_cldap_process(ctx, req); + } + } } + return NULL; } -- 1.7.7.1
>From 77f93850bb5cbb152df9cda500083409eadabaf9 Mon Sep 17 00:00:00 2001 From: Simo Sorce <[email protected]> Date: Mon, 14 Nov 2011 23:09:50 -0500 Subject: [PATCH 4/6] ipa-cldap: Decode CLDAP request. --- daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h | 27 +++ .../ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c | 181 +++++++++++++++++++- 2 files changed, 199 insertions(+), 9 deletions(-) diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h index fa86501dd37fcf604474a3390d9725fa85197c56..23cc94fb74a01dc7c9112aec34fef5c68d285edc 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h @@ -58,6 +58,7 @@ #define IPA_PLUGIN_NAME IPA_CLDAP_PLUGIN_NAME #define CLDAP_PORT 389 +#define MAX_DG_SIZE 4096 struct ipa_cldap_ctx { Slapi_ComponentId *plugin_id; @@ -67,6 +68,32 @@ struct ipa_cldap_ctx { int sd; }; +struct kvp { + struct berval attr; + struct berval value; +}; + +struct kvp_list { + struct kvp *pairs; + int allocated; + int top; +}; + +struct ipa_cldap_req { + int fd; + + struct sockaddr_storage ss; + socklen_t ss_len; + + char dgram[MAX_DG_SIZE]; + size_t dgsize; + + ber_int_t id; + + /* filter members */ + struct kvp_list kvps; +}; + void *ipa_cldap_worker(struct ipa_cldap_ctx *ctx); #endif /* _IPA_CLDAP_H_ */ diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c index 3ca767e946eb7e251c0ea019ef65e4961f1871db..35fc3653bcce9437113c22d944c7d28286db3e4c 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c @@ -39,22 +39,185 @@ #include "ipa_cldap.h" #include <poll.h> +#include <lber.h> -#define MAX_DG_SIZE 4096 +/* pre allocate some space for answers, default to increment 3 at a time */ +static int ipa_cldap_more_kvps(struct kvp_list *kvps) +{ + struct kvp *pairs; -struct ipa_cldap_req { - int fd; + if (kvps->allocated - kvps->top > 0) { + return 0; + } - struct sockaddr_storage ss; - socklen_t ss_len; + pairs = realloc(kvps->pairs, (kvps->allocated + 3) * sizeof(struct kvp)); + if (!pairs) { + return ENOMEM; + } + kvps->pairs = pairs; + kvps->allocated += 3; - char dgram[MAX_DG_SIZE]; - size_t dgsize; -}; + return 0; +} + +static void ipa_cldap_free_kvps(struct kvp_list *kvps) +{ + free(kvps->pairs); + kvps->pairs = NULL; + kvps->allocated = 0; + kvps->top = 0; +} + +static int ipa_cldap_get_kvp(BerElement *be, struct kvp_list *kvps) +{ + ber_tag_t tag; + int ret; + + ret = ipa_cldap_more_kvps(kvps); + if (ret) { + return ret; + } + + tag = ber_scanf(be, "{mm}", + &(kvps->pairs[kvps->top].attr), + &(kvps->pairs[kvps->top].value)); + if (tag == LBER_ERROR) { + LOG_TRACE("Invalid filter\n"); + ret = EINVAL; + } else { + kvps->top++; + } + + return ret; +} + +static int ipa_cldap_get_tree(BerElement *be, struct kvp_list *kvps) +{ + ber_tag_t tag; + ber_tag_t len; + char *cookie; + int ret; + + tag = ber_first_element(be, &len, &cookie); + while (tag != LBER_DEFAULT) { + tag = ber_peek_tag(be, &len); + switch (tag) { + case LDAP_FILTER_EQUALITY: + ret = ipa_cldap_get_kvp(be, kvps); + break; + case LDAP_FILTER_AND: + ret = ipa_cldap_get_tree(be, kvps); + break; + default: + LOG_TRACE("Unsupported filter\n"); + ret = EINVAL; + break; + } + + if (ret) { + return ret; + } + + tag = ber_next_element(be, &len, cookie); + } + + return 0; +} + +static int ipa_cldap_decode(struct ipa_cldap_req *req) +{ + struct berval bv; + BerElement *be; + ber_tag_t tag; + ber_len_t len; + ber_int_t scope; + ber_int_t deref; + ber_int_t sizelimit; + ber_int_t timelimit; + ber_int_t typesonly; + struct berval base; + struct berval attr; + int ret = EINVAL; + + bv.bv_val = req->dgram; + bv.bv_len = req->dgsize; + + be = ber_alloc_t(0); + if (!be) { + LOG_FATAL("Out of memory!\n"); + goto done; + } + + ber_init2(be, &bv, 0); + + tag = ber_skip_tag(be, &len); + if (tag != LDAP_TAG_MESSAGE) { + LOG_TRACE("Invalid message (%d)\n", (int)tag); + goto done; + } + + tag = ber_get_int(be, &req->id); + if (tag != LDAP_TAG_MSGID) { + LOG_TRACE("Failed to get id\n"); + goto done; + } + + tag = ber_peek_tag(be, &len); + if (tag != LDAP_REQ_SEARCH) { + LOG_TRACE("Unexpected message type (%d)\n", (int)tag); + goto done; + } + + tag = ber_scanf(be, "{meeiib", + &base, &scope, &deref, &sizelimit, &timelimit, &typesonly); + if (tag == LBER_ERROR) { + LOG_TRACE("Failed to parse message\n"); + goto done; + } + + if ((base.bv_len != 0) || + (scope != 0) || + (typesonly != 0)){ + LOG_TRACE("Unexpected request\n"); + goto done; + } + + ret = ipa_cldap_get_tree(be, &req->kvps); + if (ret) { + LOG_TRACE("Failed to parse filter\n"); + goto done; + } + + tag = ber_scanf(be, "{m}}", &attr); + if (tag == LBER_ERROR) { + LOG_TRACE("Failed to parse message\n"); + goto done; + } + + if (strncasecmp(attr.bv_val, "netlogon", attr.bv_len) != 0) { + LOG_TRACE("Unexpected request\n"); + goto done; + } + +done: + ber_free(be, 0); + return ret; +} static void ipa_cldap_process(struct ipa_cldap_ctx *ctx, struct ipa_cldap_req *req) { + int ret; + + ret = ipa_cldap_decode(req); + if (ret) { + goto done; + } + + LOG("Nice message!"); + +done: + ipa_cldap_free_kvps(&req->kvps); free(req); return; } @@ -63,7 +226,7 @@ static struct ipa_cldap_req *ipa_cldap_recv_dgram(struct ipa_cldap_ctx *ctx) { struct ipa_cldap_req *req; - req = malloc(sizeof(struct ipa_cldap_req)); + req = calloc(1, sizeof(struct ipa_cldap_req)); if (!req) { LOG("Failed to allocate memory for req"); return NULL; -- 1.7.7.1
>From be79336c92610d09b9d447a97a711a788328e113 Mon Sep 17 00:00:00 2001 From: Simo Sorce <[email protected]> Date: Tue, 15 Nov 2011 18:33:26 -0500 Subject: [PATCH 5/6] ipa-cldap: Create netlogon blob --- daemons/ipa-slapi-plugins/ipa-cldap/Makefile.am | 1 + daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h | 8 + .../ipa-cldap/ipa_cldap_netlogon.c | 329 ++++++++++++++++++++ .../ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c | 10 +- 4 files changed, 347 insertions(+), 1 deletions(-) create mode 100644 daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_netlogon.c diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/Makefile.am b/daemons/ipa-slapi-plugins/ipa-cldap/Makefile.am index b563e98763d78298b64de92c59716bacd8c822a4..27f53e9aa129ff2ef31c909f2b55069fae7b64da 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/Makefile.am +++ b/daemons/ipa-slapi-plugins/ipa-cldap/Makefile.am @@ -24,6 +24,7 @@ plugin_LTLIBRARIES = \ $(NULL) libipa_cldap_la_SOURCES = \ + ipa_cldap_netlogon.c \ ipa_cldap_worker.c \ ipa_cldap.c \ $(NULL) diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h index 23cc94fb74a01dc7c9112aec34fef5c68d285edc..ee3da879c65d3c9715c46fad583f8ad1de8f65fd 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h @@ -60,6 +60,10 @@ #define CLDAP_PORT 389 #define MAX_DG_SIZE 4096 +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + struct ipa_cldap_ctx { Slapi_ComponentId *plugin_id; pthread_t tid; @@ -96,4 +100,8 @@ struct ipa_cldap_req { void *ipa_cldap_worker(struct ipa_cldap_ctx *ctx); +int ipa_cldap_netlogon(struct ipa_cldap_ctx *ctx, + struct ipa_cldap_req *req, + struct berval *reply); + #endif /* _IPA_CLDAP_H_ */ diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_netlogon.c b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_netlogon.c new file mode 100644 index 0000000000000000000000000000000000000000..6eb7eb9b1b88bb190a75feeab39a2fe5ff2719bf --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_netlogon.c @@ -0,0 +1,329 @@ +/** BEGIN COPYRIGHT BLOCK + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Additional permission under GPLv3 section 7: + * + * In the following paragraph, "GPL" means the GNU General Public + * License, version 3 or any later version, and "Non-GPL Code" means + * code that is governed neither by the GPL nor a license + * compatible with the GPL. + * + * You may link the code of this Program with Non-GPL Code and convey + * linked combinations including the two, provided that such Non-GPL + * Code only links to the code of this Program through those well + * defined interfaces identified in the file named EXCEPTION found in + * the source code files (the "Approved Interfaces"). The files of + * Non-GPL Code may instantiate templates or use macros or inline + * functions from the Approved Interfaces without causing the resulting + * work to be covered by the GPL. Only the copyright holders of this + * Program may make changes or additions to the list of Approved + * Interfaces. + * + * Authors: + * Simo Sorce <[email protected]> + * + * Copyright (C) 2011 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +#include "ipa_cldap.h" +#include <endian.h> +#include <talloc.h> +#include <ctype.h> +#include "gen_ndr/ndr_nbt.h" +#include "gen_ndr/netlogon.h" + +static int string_to_guid(char *str, struct GUID *guid) +{ + unsigned int time_low; + unsigned int time_mid; + unsigned int time_hi; + unsigned int seq[2]; + unsigned int node[6]; + int ret; + + ret = sscanf(str, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + &time_low, &time_mid, &time_hi, &seq[0], &seq[1], + &node[0], &node[1], &node[2], &node[3], &node[4], &node[5]); + if (ret != 11) { + return EINVAL; + } + + guid->time_low = time_low; + guid->time_mid = time_mid; + guid->time_hi_and_version = time_hi; + guid->clock_seq[0] = seq[0]; + guid->clock_seq[1] = seq[1]; + guid->node[0] = node[0]; + guid->node[1] = node[1]; + guid->node[2] = node[2]; + guid->node[3] = node[3]; + guid->node[4] = node[4]; + guid->node[5] = node[5]; + + return 0; +} + +static int ipa_cldap_get_domain_entry(struct ipa_cldap_ctx *ctx, + char *domain, + char **guid, char **sid, char **name) +{ + Slapi_PBlock *pb; + Slapi_Entry **e = NULL; + char *filter; + int ret; + + pb = slapi_pblock_new(); + if (!pb) { + return ENOMEM; + } + + ret = asprintf(&filter, "(&(cn=%s)(objectclass=ipaNTDomainAttrs))", domain); + if (ret == -1) { + ret = ENOMEM; + goto done; + } + + slapi_search_internal_set_pb(pb, ctx->base_dn, + LDAP_SCOPE_SUBTREE, filter, + NULL, 0, NULL, NULL, ctx->plugin_id, 0); + + slapi_search_internal_pb(pb); + slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret); + + if (ret) { + ret = ENOENT; + goto done; + } + + slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &e); + if (!e || !e[0] || e[1]) { + /* no matches or too many matches */ + ret = ENOENT; + goto done; + } + + *guid = slapi_entry_attr_get_charptr(e[0], "ipaNTDomainGUID"); + *sid = slapi_entry_attr_get_charptr(e[0], "ipaNTSecurityIdentifier"); + *name = slapi_entry_attr_get_charptr(e[0], "ipaNTFlatName"); + + ret = 0; + +done: + slapi_free_search_results_internal(pb); + slapi_pblock_destroy(pb); + free(filter); + return ret; +} + +#define NETLOGON_SAM_LOGON_RESPONSE_EX_pusher \ + (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX + +static int ipa_cldap_encode_netlogon(char *hostname, char *domain, + char *guid, char *sid, char *name, + uint32_t ntver, struct berval *reply) +{ + struct NETLOGON_SAM_LOGON_RESPONSE_EX *nlr; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + char *pdc_name; + char *p; + int ret; + + nlr = talloc_zero(NULL, struct NETLOGON_SAM_LOGON_RESPONSE_EX); + if (!nlr) { + return ENOMEM; + } + + if (!(ntver & NETLOGON_NT_VERSION_5EX)) { + ret = EINVAL; + goto done; + } + + nlr->command = LOGON_SAM_LOGON_RESPONSE_EX; + /* nlr->sbz */ + nlr->server_type = DS_SERVER_PDC | + DS_SERVER_GC | + DS_SERVER_LDAP | + DS_SERVER_DS | + DS_SERVER_KDC | + DS_SERVER_TIMESERV | + DS_SERVER_CLOSEST | + DS_SERVER_WRITABLE | + DS_SERVER_GOOD_TIMESERV; + string_to_guid(guid, &nlr->domain_uuid); + nlr->forest = domain; + nlr->dns_domain = domain; + nlr->pdc_dns_name = talloc_asprintf(nlr, "%s.%s", hostname, domain); + if (!nlr->pdc_dns_name) { + ret = ENOMEM; + goto done; + } + nlr->domain_name = name; + pdc_name = talloc_asprintf(nlr, "\\\\%s", hostname); + for (p = pdc_name; *p; p++) { + *p = toupper(*p); + } + nlr->pdc_name = pdc_name; + nlr->user_name = ""; + nlr->server_site = "Default-First-Site-Name"; + nlr->client_site = "Default-First-Site-Name"; + /* nlr->sockaddr_size (filled in by ndr_push) */ + nlr->sockaddr.sockaddr_family = 2; + nlr->sockaddr.pdc_ip = "127.0.0.1"; + nlr->sockaddr.remaining.length = 8; + nlr->sockaddr.remaining.data = talloc_zero_size(nlr, 8); + /* nlr->next_closest_site */ + nlr->nt_version = NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_1; + nlr->lmnt_token = 0xFFFF; + nlr->lm20_token = 0xFFFF; + + ndr_err = ndr_push_struct_blob(&blob, nlr, nlr, + NETLOGON_SAM_LOGON_RESPONSE_EX_pusher); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + ret = EFAULT; + goto done; + } + + reply->bv_val = malloc(blob.length); + if (!reply->bv_val) { + ret = ENOMEM; + goto done; + } + memcpy(reply->bv_val, blob.data, blob.length); + reply->bv_len = blob.length; + ret = 0; + +done: + talloc_free(nlr); + return ret; +} + +int ipa_cldap_netlogon(struct ipa_cldap_ctx *ctx, + struct ipa_cldap_req *req, + struct berval *reply) +{ + char hostname[MAXHOSTNAMELEN + 1]; /* NOTE: lenght hardcoded in kernel */ + char *domain = NULL; + char *guid = NULL; + char *sid = NULL; + char *name = NULL; + uint32_t ntver = 0; + uint32_t t; + char *p; + int ret; + int len; + int i; + + /* determine request type */ + + for (i = 0; i < req->kvps.top; i++) { + if (strncasecmp("DnsDomain", + req->kvps.pairs[i].attr.bv_val, + req->kvps.pairs[i].attr.bv_len) == 0) { + /* remove trailing dot if any */ + len = req->kvps.pairs[i].value.bv_len; + if (req->kvps.pairs[i].value.bv_val[len-1] == '.') { + len--; + } + domain = strndup(req->kvps.pairs[i].value.bv_val, len); + if (!domain) { + ret = ENOMEM; + goto done; + } + continue; + } + if (strncasecmp("Host", + req->kvps.pairs[i].attr.bv_val, + req->kvps.pairs[i].attr.bv_len) == 0) { + /* we ignore Host for now */ + continue; + } + if (strncasecmp("DomainGUID", + req->kvps.pairs[i].attr.bv_val, + req->kvps.pairs[i].attr.bv_len) == 0) { + /* we ignore DomainGUID for now */ + continue; + } + if (strncasecmp("DomainSID", + req->kvps.pairs[i].attr.bv_val, + req->kvps.pairs[i].attr.bv_len) == 0) { + /* we ignore DomainSID for now */ + continue; + } + if (strncasecmp("User", + req->kvps.pairs[i].attr.bv_val, + req->kvps.pairs[i].attr.bv_len) == 0) { + /* we ignore User for now */ + continue; + } + if (strncasecmp("AAC", + req->kvps.pairs[i].attr.bv_val, + req->kvps.pairs[i].attr.bv_len) == 0) { + /* we ignore AAC for now */ + continue; + } + if (strncasecmp("NTver", + req->kvps.pairs[i].attr.bv_val, + req->kvps.pairs[i].attr.bv_len) == 0) { + if (req->kvps.pairs[i].value.bv_len != 4) { + ret = EINVAL; + goto done; + } + memcpy(&t, req->kvps.pairs[i].value.bv_val, 4); + ntver = le32toh(t); + continue; + } + LOG_TRACE("Unknown filter attribute: %s\n", + req->kvps.pairs[i].attr.bv_val); + } + + if (!domain || !ntver) { + ret = EINVAL; + goto done; + } + + /* FIXME: we support only NETLOGON_NT_VERSION_5EX for now */ + if (!(ntver & NETLOGON_NT_VERSION_5EX)) { + ret = EINVAL; + goto done; + } + + ret = ipa_cldap_get_domain_entry(ctx, domain, &guid, &sid, &name); + if (ret) { + goto done; + } + + ret = gethostname(hostname, MAXHOSTNAMELEN); + if (ret == -1) { + ret = errno; + goto done; + } + hostname[MAXHOSTNAMELEN] = '\0'; + p = strchr(hostname, '.'); + if (p) { + *p = '\0'; + } + + ret = ipa_cldap_encode_netlogon(hostname, domain, + guid, sid, name, + ntver, reply); + +done: + free(domain); + free(guid); + free(sid); + free(name); + return ret; +} diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c index 35fc3653bcce9437113c22d944c7d28286db3e4c..01ba047afec2d4fd154a26213c0fbea475f4dc91 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c @@ -207,6 +207,7 @@ done: static void ipa_cldap_process(struct ipa_cldap_ctx *ctx, struct ipa_cldap_req *req) { + struct berval reply; int ret; ret = ipa_cldap_decode(req); @@ -214,7 +215,14 @@ static void ipa_cldap_process(struct ipa_cldap_ctx *ctx, goto done; } - LOG("Nice message!"); + LOG_TRACE("CLDAP Request received"); + + ret = ipa_cldap_netlogon(ctx, req, &reply); + if (ret) { + goto done; + } + + /* ipa_cldap_respond(ctx, req, &reply); */ done: ipa_cldap_free_kvps(&req->kvps); -- 1.7.7.1
>From b030a1809ff53334d4048e2c0395dd589d2efd80 Mon Sep 17 00:00:00 2001 From: Simo Sorce <[email protected]> Date: Thu, 17 Nov 2011 11:51:05 -0500 Subject: [PATCH 6/6] ipa-cldap: send cldap reply --- .../ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c | 48 +++++++++++++++++++- 1 files changed, 47 insertions(+), 1 deletions(-) diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c index 01ba047afec2d4fd154a26213c0fbea475f4dc91..ff31378d71cf36f4dc10a7c019a9b41071ea9fdd 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c @@ -204,6 +204,52 @@ done: return ret; } +static void ipa_cldap_respond(struct ipa_cldap_ctx *ctx, + struct ipa_cldap_req *req, + struct berval *nbtblob) +{ + struct berval *bv = NULL; + BerElement *be; + int ret; + + be = ber_alloc_t(0); + if (!be) { + LOG_OOM(); + return; + } + + /* result */ + ret = ber_printf(be, "{it{s{{s[O]}}}}", req->id, + LDAP_RES_SEARCH_ENTRY, "", "netlogon", nbtblob); + if (ret == LBER_ERROR) { + LOG("Failed to encode CLDAP reply\n"); + goto done; + } + /* done */ + ret = ber_printf(be, "{it{ess}}", req->id, + LDAP_RES_SEARCH_RESULT, 0, "", ""); + if (ret == LBER_ERROR) { + LOG("Failed to encode CLDAP reply\n"); + goto done; + } + /* get data blob */ + ret = ber_flatten(be, &bv); + if (ret == LBER_ERROR) { + LOG("Failed to encode CLDAP reply\n"); + goto done; + } + + ret = sendto(ctx->sd, bv->bv_val, bv->bv_len, 0, + (struct sockaddr *)&req->ss, req->ss_len); + if (ret == -1) { + LOG("Failed to send CLDAP reply (%d, %s)\n", errno, strerror(errno)); + } + +done: + ber_bvfree(bv); + ber_free(be, 1); +} + static void ipa_cldap_process(struct ipa_cldap_ctx *ctx, struct ipa_cldap_req *req) { @@ -222,7 +268,7 @@ static void ipa_cldap_process(struct ipa_cldap_ctx *ctx, goto done; } - /* ipa_cldap_respond(ctx, req, &reply); */ + ipa_cldap_respond(ctx, req, &reply); done: ipa_cldap_free_kvps(&req->kvps); -- 1.7.7.1
_______________________________________________ Freeipa-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/freeipa-devel
