On Fri, 2011-11-18 at 16:07 +0100, Sumit Bose wrote: > On Thu, Nov 17, 2011 at 05:00:51PM -0500, Simo Sorce wrote: > > 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. > > The patch prevents dirsrv from shutting down cleanly, so NACK. But > otherwise it is working great. I will rebase my patches on top of yours, > fix some missing bits and send them here as well.
Ok here is a rebase/modified patchset. I reworked it to have even less churn between patches (you should see only additions and no deletions. I also added a pipe() to deal with the worker thread shutdown. This allows us to interrupt the poll() at any time and at the same time tell the worker thread it is time to end. I tested a dirsrv shutdown in gdb and it works as expected. Simo. -- Simo Sorce * Red Hat, Inc * New York
>From 9ffe37efbd18b5da084a8328766bacd6e3c31e0b Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> 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 2724eb2999af2af74d71a9c63af0a46099bca0ec Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> 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 | 238 ++++++++++++++++++++ daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h | 72 ++++++ .../ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c | 49 ++++ freeipa.spec.in | 15 +- 8 files changed, 436 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..d7a59d51229ca9fbf754a2600e42339dcc235698 --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.c @@ -0,0 +1,238 @@ +/** 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 <sso...@redhat.com> + * + * 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; + } + + /* send stop signal to terminate worker thread */ + write(ctx->stopfd[1], "", 1); + close(ctx->stopfd[1]); + + 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; + } + + /* create a stop pipe so the main DS thread can interrupt the poll() + * of the worker thread at any time and cause the worker thread to + * immediately exit without waiting for timeouts or such */ + ret = pipe(ctx->stopfd); + if (ret != 0) { + LOG_FATAL("Failed to stop pipe\n"); + ret = EIO; + goto done; + } + + 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..013dad2fd8143c2e60f1760e76e516ef183b26d2 --- /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 <sso...@redhat.com> + * + * 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; + int stopfd[2]; + 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..4bbba5359624e92a1c43ef30325fbac165840d06 --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c @@ -0,0 +1,49 @@ +/** 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 <sso...@redhat.com> + * + * 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) +{ + bool stop = false; + + while (!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 <s...@redhat.com> - 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 <edew...@redhat.com> - 2.99.0-11 - Make sure changes to extension.js are not removed. -- 1.7.7.1
>From 2f0987170788d98b5b4e13be1b1cfbee6ae3c61f Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> Date: Mon, 14 Nov 2011 17:38:53 -0500 Subject: [PATCH 3/6] ipa-cldap: Implement worker thread. --- daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h | 11 +++ .../ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c | 71 +++++++++++++++++++- 2 files changed, 81 insertions(+), 1 deletions(-) diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h index 013dad2fd8143c2e60f1760e76e516ef183b26d2..ff9818a64b186f7d20cb289b8ee829698459fb4d 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,16 @@ struct ipa_cldap_ctx { int sd; }; +struct ipa_cldap_req { + int fd; + + struct sockaddr_storage ss; + socklen_t ss_len; + + char dgram[MAX_DG_SIZE]; + size_t dgsize; +}; + 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 4bbba5359624e92a1c43ef30325fbac165840d06..474c5327c7b9229f9a24a81c68268f0e41ec79e8 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c @@ -38,12 +38,81 @@ * END COPYRIGHT BLOCK **/ #include "ipa_cldap.h" +#include <poll.h> + +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 = calloc(1, 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[2]; bool stop = false; + int ret; while (!stop) { - sleep(1); + + fds[0].fd = ctx->stopfd[0]; + fds[0].events = POLLIN; + fds[0].revents = 0; + fds[1].fd = ctx->sd; + fds[1].events = POLLIN; + fds[1].revents = 0; + + /* wait until a request comes in */ + ret = poll(fds, 2, -1); + if (ret == -1) { + if (errno != EINTR) { + LOG_FATAL("poll() failed with [%d, %s]. Can't continue.\n", + errno, strerror(errno)); + stop = true; + } + } + if (ret <= 0) { + continue; + } + + /* got a stop signal, exit the loop */ + if (fds[0].revents & POLLIN) { + stop = true; + continue; + } + + /* got a CLDAP packet, handle it */ + if (fds[1].revents & POLLIN) { + req = ipa_cldap_recv_dgram(ctx); + if (req) { + ipa_cldap_process(ctx, req); + } + } } + return NULL; } -- 1.7.7.1
>From c6f89d6544ffcc9fdddbbadb74a2ddfa00ce3030 Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> 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 | 16 ++ .../ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c | 175 ++++++++++++++++++++ 2 files changed, 191 insertions(+), 0 deletions(-) diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h index ff9818a64b186f7d20cb289b8ee829698459fb4d..8484749f51e8bbf3e6857901b2a525adf86c1623 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap.h @@ -68,6 +68,17 @@ 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; @@ -76,6 +87,11 @@ struct ipa_cldap_req { 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); 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 474c5327c7b9229f9a24a81c68268f0e41ec79e8..57c3ffce796ea3df36c17c418e4f1231ac649070 100644 --- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c +++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c @@ -39,10 +39,185 @@ #include "ipa_cldap.h" #include <poll.h> +#include <lber.h> + +/* 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; + + if (kvps->allocated - kvps->top > 0) { + return 0; + } + + pairs = realloc(kvps->pairs, (kvps->allocated + 3) * sizeof(struct kvp)); + if (!pairs) { + return ENOMEM; + } + kvps->pairs = pairs; + kvps->allocated += 3; + + 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_TRACE("CLDAP Request received"); + +done: + ipa_cldap_free_kvps(&req->kvps); free(req); return; } -- 1.7.7.1
>From 9ed34ba1449297c60c90b06ad9ba851b75bedba4 Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> 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 | 6 + 4 files changed, 344 insertions(+), 0 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 8484749f51e8bbf3e6857901b2a525adf86c1623..ae0b06fe677276a932c832e82b1578896ddafd51 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 <sso...@redhat.com> + * + * 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 57c3ffce796ea3df36c17c418e4f1231ac649070..90ea32e0326d04c59f8eba56be707bbcecab2956 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); @@ -216,6 +217,11 @@ static void ipa_cldap_process(struct ipa_cldap_ctx *ctx, LOG_TRACE("CLDAP Request received"); + ret = ipa_cldap_netlogon(ctx, req, &reply); + if (ret) { + goto done; + } + done: ipa_cldap_free_kvps(&req->kvps); free(req); -- 1.7.7.1
>From a87664798dc91a4685679a8f58f777bebfb896b5 Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> 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, 48 insertions(+), 0 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 90ea32e0326d04c59f8eba56be707bbcecab2956..307110c123c2d898c910371da9ebeb2edfa0f1b5 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,6 +268,8 @@ static void ipa_cldap_process(struct ipa_cldap_ctx *ctx, goto done; } + ipa_cldap_respond(ctx, req, &reply); + done: ipa_cldap_free_kvps(&req->kvps); free(req); -- 1.7.7.1
_______________________________________________ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel