perl \
relay \
shell \
+ sock \
sql"
AC_ARG_ENABLE(xxslapbackends,[
yes, [no yes mod], ol_enable_backends)dnl
OL_ARG_ENABLE(shell,[ --enable-shell enable shell backend],
no, [no yes mod], ol_enable_backends)dnl
+OL_ARG_ENABLE(sock,[ --enable-sock enable sock backend],
+ no, [no yes mod], ol_enable_backends)dnl
OL_ARG_ENABLE(sql,[ --enable-sql enable sql backend],
no, [no yes mod], ol_enable_backends)dnl
test $ol_enable_perl = no &&
test $ol_enable_relay = no &&
test $ol_enable_shell = no &&
+ test $ol_enable_sock = no &&
test $ol_enable_sql = no ; then
dnl no slapd backend
BUILD_PERL=no
BUILD_RELAY=no
BUILD_SHELL=no
+BUILD_SOCK=no
BUILD_SQL=no
BUILD_ACCESSLOG=no
AC_DEFINE_UNQUOTED(SLAPD_SHELL,$MFLAG,[define to support SHELL backend])
fi
+if test "$ol_enable_sock" != no ; then
+ BUILD_SLAPD=yes
+ BUILD_SOCK=$ol_enable_sock
+ if test "$ol_enable_sock" = mod ; then
+ SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-sock"
+ MFLAG=SLAPD_MOD_DYNAMIC
+ else
+ SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-sock"
+ MFLAG=SLAPD_MOD_STATIC
+ fi
+ AC_DEFINE_UNQUOTED(SLAPD_SOCK,$MFLAG,[define to support SOCK backend])
+fi
+
if test "$ol_link_sql" != no ; then
BUILD_SLAPD=yes
BUILD_SQL=$ol_enable_sql
AC_SUBST(BUILD_RELAY)
AC_SUBST(BUILD_PERL)
AC_SUBST(BUILD_SHELL)
+ AC_SUBST(BUILD_SOCK)
AC_SUBST(BUILD_SQL)
dnl overlays
AC_SUBST(BUILD_ACCESSLOG)
[servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/mod.mk]
[servers/slapd/back-relay/Makefile:build/top.mk:servers/slapd/back-relay/Makefile.in:build/mod.mk]
[servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk]
+[servers/slapd/back-sock/Makefile:build/top.mk:servers/slapd/back-sock/Makefile.in:build/mod.mk]
[servers/slapd/back-sql/Makefile:build/top.mk:servers/slapd/back-sql/Makefile.in:build/mod.mk]
[servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk]
[servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk]
--- /dev/null
+/* add.c - sock backend add function */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+int
+sock_back_add(
+ Operation *op,
+ SlapReply *rs )
+{
+ struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private;
+ AttributeDescription *entry = slap_schema.si_ad_entry;
+ FILE *fp;
+ int len;
+
+ if ( ! access_allowed( op, op->oq_add.rs_e,
+ entry, NULL, ACL_WADD, NULL ) )
+ {
+ send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
+ return -1;
+ }
+
+ if ( (fp = opensock( si->si_sockpath )) == NULL ) {
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "could not open socket" );
+ return( -1 );
+ }
+
+ /* write out the request to the add process */
+ fprintf( fp, "ADD\n" );
+ fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
+ sock_print_conn( fp, op->o_conn, si );
+ sock_print_suffixes( fp, op->o_bd );
+ ldap_pvt_thread_mutex_lock( &entry2str_mutex );
+ fprintf( fp, "%s", entry2str( op->oq_add.rs_e, &len ) );
+ ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
+ fprintf (fp, "\n" );
+
+ /* read in the result and send it along */
+ sock_read_and_send_results( op, rs, fp );
+
+ fclose( fp );
+ return( 0 );
+}
--- /dev/null
+/* sock.h - socket backend header file */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#ifndef SLAPD_SOCK_H
+#define SLAPD_SOCK_H
+
+#include "proto-sock.h"
+
+LDAP_BEGIN_DECL
+
+struct sockinfo {
+ const char *si_sockpath;
+ int si_extensions;
+};
+
+#define SOCK_EXT_BINDDN 1
+#define SOCK_EXT_PEERNAME 2
+#define SOCK_EXT_SSF 4
+
+extern FILE *opensock LDAP_P((
+ const char *sockpath));
+
+extern void sock_print_suffixes LDAP_P((
+ FILE *fp,
+ BackendDB *bd));
+
+extern void sock_print_conn LDAP_P((
+ FILE *fp,
+ Connection *conn,
+ struct sockinfo *si));
+
+extern int sock_read_and_send_results LDAP_P((
+ Operation *op,
+ SlapReply *rs,
+ FILE *fp));
+
+LDAP_END_DECL
+
+#endif
--- /dev/null
+/* bind.c - sock backend bind function */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+int
+sock_back_bind(
+ Operation *op,
+ SlapReply *rs )
+{
+ struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private;
+ AttributeDescription *entry = slap_schema.si_ad_entry;
+ Entry e;
+ FILE *fp;
+ int rc;
+
+ e.e_id = NOID;
+ e.e_name = op->o_req_dn;
+ e.e_nname = op->o_req_ndn;
+ e.e_attrs = NULL;
+ e.e_ocflags = 0;
+ e.e_bv.bv_len = 0;
+ e.e_bv.bv_val = NULL;
+ e.e_private = NULL;
+
+ if ( ! access_allowed( op, &e,
+ entry, NULL, ACL_AUTH, NULL ) )
+ {
+ send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
+ return -1;
+ }
+
+ if ( (fp = opensock( si->si_sockpath )) == NULL ) {
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "could not open socket" );
+ return( -1 );
+ }
+
+ /* write out the request to the bind process */
+ fprintf( fp, "BIND\n" );
+ fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
+ sock_print_conn( fp, op->o_conn, si );
+ sock_print_suffixes( fp, op->o_bd );
+ fprintf( fp, "dn: %s\n", op->o_req_dn.bv_val );
+ fprintf( fp, "method: %d\n", op->oq_bind.rb_method );
+ fprintf( fp, "credlen: %lu\n", op->oq_bind.rb_cred.bv_len );
+ fprintf( fp, "cred: %s\n", op->oq_bind.rb_cred.bv_val ); /* XXX */
+ fprintf( fp, "\n" );
+
+ /* read in the results and send them along */
+ rc = sock_read_and_send_results( op, rs, fp );
+ fclose( fp );
+
+ return( rc );
+}
--- /dev/null
+/* compare.c - sock backend compare function */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+int
+sock_back_compare(
+ Operation *op,
+ SlapReply *rs )
+{
+ struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private;
+ AttributeDescription *entry = slap_schema.si_ad_entry;
+ Entry e;
+ FILE *fp;
+
+ e.e_id = NOID;
+ e.e_name = op->o_req_dn;
+ e.e_nname = op->o_req_ndn;
+ e.e_attrs = NULL;
+ e.e_ocflags = 0;
+ e.e_bv.bv_len = 0;
+ e.e_bv.bv_val = NULL;
+ e.e_private = NULL;
+
+ if ( ! access_allowed( op, &e,
+ entry, NULL, ACL_READ, NULL ) )
+ {
+ send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
+ return -1;
+ }
+
+ if ( (fp = opensock( si->si_sockpath )) == NULL ) {
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "could not open socket" );
+ return( -1 );
+ }
+
+ /*
+ * FIX ME: This should use LDIF routines so that binary
+ * values are properly dealt with
+ */
+
+ /* write out the request to the compare process */
+ fprintf( fp, "COMPARE\n" );
+ fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
+ sock_print_conn( fp, op->o_conn, si );
+ sock_print_suffixes( fp, op->o_bd );
+ fprintf( fp, "dn: %s\n", op->o_req_dn.bv_val );
+ fprintf( fp, "%s: %s\n",
+ op->oq_compare.rs_ava->aa_desc->ad_cname.bv_val,
+ op->oq_compare.rs_ava->aa_value.bv_val /* could be binary! */ );
+ fclose( fp );
+
+ /* read in the result and send it along */
+ sock_read_and_send_results( op, rs, fp );
+
+ fclose( fp );
+ return( 0 );
+}
--- /dev/null
+/* config.c - sock backend configuration file routine */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+int
+sock_back_db_config(
+ BackendDB *be,
+ const char *fname,
+ int lineno,
+ int argc,
+ char **argv
+)
+{
+ struct sockinfo *si = (struct sockinfo *) be->be_private;
+
+ if ( si == NULL ) {
+ fprintf( stderr, "%s: line %d: sock backend info is null!\n",
+ fname, lineno );
+ return( 1 );
+ }
+
+ /* socketpath */
+ if ( strcasecmp( argv[0], "socketpath" ) == 0 ) {
+ if ( argc != 2 ) {
+ fprintf( stderr,
+ "%s: line %d: exactly one parameter needed for \"socketpath\"\n",
+ fname, lineno );
+ return( 1 );
+ }
+ si->si_sockpath = ch_strdup( argv[1] );
+
+ /* extensions */
+ } else if ( strcasecmp( argv[0], "extensions" ) == 0 ) {
+ int i;
+ for ( i=1; i<argc; i++ ) {
+ if ( strcasecmp( argv[i], "binddn" ) == 0 )
+ si->si_extensions |= SOCK_EXT_BINDDN;
+ else if ( strcasecmp( argv[i], "peername" ) == 0 )
+ si->si_extensions |= SOCK_EXT_PEERNAME;
+ else if ( strcasecmp( argv[i], "ssf" ) == 0 )
+ si->si_extensions |= SOCK_EXT_SSF;
+ else {
+ fprintf( stderr,
+ "%s: line %d: unknown extension \"%s\"\n",
+ fname, lineno, argv[i] );
+ return( 1 );
+ }
+ }
+
+ /* anything else */
+ } else {
+ return SLAP_CONF_UNKNOWN;
+ }
+
+ return 0;
+}
--- /dev/null
+/* delete.c - sock backend delete function */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+int
+sock_back_delete(
+ Operation *op,
+ SlapReply *rs )
+{
+ struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private;
+ AttributeDescription *entry = slap_schema.si_ad_entry;
+ Entry e;
+ FILE *fp;
+
+ e.e_id = NOID;
+ e.e_name = op->o_req_dn;
+ e.e_nname = op->o_req_ndn;
+ e.e_attrs = NULL;
+ e.e_ocflags = 0;
+ e.e_bv.bv_len = 0;
+ e.e_bv.bv_val = NULL;
+ e.e_private = NULL;
+
+ if ( ! access_allowed( op, &e,
+ entry, NULL, ACL_WDEL, NULL ) )
+ {
+ send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
+ return -1;
+ }
+
+ if ( (fp = opensock( si->si_sockpath )) == NULL ) {
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "could not open socket" );
+ return( -1 );
+ }
+
+ /* write out the request to the delete process */
+ fprintf( fp, "DELETE\n" );
+ fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
+ sock_print_conn( fp, op->o_conn, si );
+ sock_print_suffixes( fp, op->o_bd );
+ fprintf( fp, "dn: %s\n", op->o_req_dn.bv_val );
+ fprintf( fp, "\n" );
+
+ /* read in the results and send them along */
+ sock_read_and_send_results( op, rs, fp );
+ fclose( fp );
+ return( 0 );
+}
--- /dev/null
+/* init.c - initialize sock backend */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+int
+sock_back_initialize(
+ BackendInfo *bi
+)
+{
+ bi->bi_open = 0;
+ bi->bi_config = 0;
+ bi->bi_close = 0;
+ bi->bi_destroy = 0;
+
+ bi->bi_db_init = sock_back_db_init;
+ bi->bi_db_config = sock_back_db_config;
+ bi->bi_db_open = 0;
+ bi->bi_db_close = 0;
+ bi->bi_db_destroy = sock_back_db_destroy;
+
+ bi->bi_op_bind = sock_back_bind;
+ bi->bi_op_unbind = sock_back_unbind;
+ bi->bi_op_search = sock_back_search;
+ bi->bi_op_compare = sock_back_compare;
+ bi->bi_op_modify = sock_back_modify;
+ bi->bi_op_modrdn = sock_back_modrdn;
+ bi->bi_op_add = sock_back_add;
+ bi->bi_op_delete = sock_back_delete;
+ bi->bi_op_abandon = 0;
+
+ bi->bi_extended = 0;
+
+ bi->bi_chk_referrals = 0;
+
+ bi->bi_connection_init = 0;
+ bi->bi_connection_destroy = 0;
+
+ return 0;
+}
+
+int
+sock_back_db_init(
+ Backend *be,
+ struct config_reply_s *cr
+)
+{
+ struct sockinfo *si;
+
+ si = (struct sockinfo *) ch_calloc( 1, sizeof(struct sockinfo) );
+
+ be->be_private = si;
+
+ return si == NULL;
+}
+
+int
+sock_back_db_destroy(
+ Backend *be,
+ struct config_reply_s *cr
+)
+{
+ free( be->be_private );
+ return 0;
+}
+
+#if SLAPD_SOCK == SLAPD_MOD_DYNAMIC
+
+/* conditionally define the init_module() function */
+SLAP_BACKEND_INIT_MODULE( sock )
+
+#endif /* SLAPD_SOCK == SLAPD_MOD_DYNAMIC */
--- /dev/null
+/* modify.c - sock backend modify function */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+int
+sock_back_modify(
+ Operation *op,
+ SlapReply *rs )
+{
+ Modification *mod;
+ struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private;
+ AttributeDescription *entry = slap_schema.si_ad_entry;
+ Modifications *ml = op->orm_modlist;
+ Entry e;
+ FILE *fp;
+ int i;
+
+ e.e_id = NOID;
+ e.e_name = op->o_req_dn;
+ e.e_nname = op->o_req_ndn;
+ e.e_attrs = NULL;
+ e.e_ocflags = 0;
+ e.e_bv.bv_len = 0;
+ e.e_bv.bv_val = NULL;
+ e.e_private = NULL;
+
+ if ( ! access_allowed( op, &e,
+ entry, NULL, ACL_WRITE, NULL ) )
+ {
+ send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
+ return -1;
+ }
+
+ if ( (fp = opensock( si->si_sockpath )) == NULL ) {
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "could not open socket" );
+ return( -1 );
+ }
+
+ /* write out the request to the modify process */
+ fprintf( fp, "MODIFY\n" );
+ fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
+ sock_print_conn( fp, op->o_conn, si );
+ sock_print_suffixes( fp, op->o_bd );
+ fprintf( fp, "dn: %s\n", op->o_req_dn.bv_val );
+ for ( ; ml != NULL; ml = ml->sml_next ) {
+ mod = &ml->sml_mod;
+
+ /* FIXME: should use LDIF routines to deal with binary data */
+
+ switch ( mod->sm_op ) {
+ case LDAP_MOD_ADD:
+ fprintf( fp, "add: %s\n", mod->sm_desc->ad_cname.bv_val );
+ break;
+
+ case LDAP_MOD_DELETE:
+ fprintf( fp, "delete: %s\n", mod->sm_desc->ad_cname.bv_val );
+ break;
+
+ case LDAP_MOD_REPLACE:
+ fprintf( fp, "replace: %s\n", mod->sm_desc->ad_cname.bv_val );
+ break;
+ }
+
+ if( mod->sm_values != NULL ) {
+ for ( i = 0; mod->sm_values[i].bv_val != NULL; i++ ) {
+ fprintf( fp, "%s: %s\n", mod->sm_desc->ad_cname.bv_val,
+ mod->sm_values[i].bv_val /* binary! */ );
+ }
+ }
+
+ fprintf( fp, "-\n" );
+ }
+ fprintf( fp, "\n" );
+
+ /* read in the results and send them along */
+ sock_read_and_send_results( op, rs, fp );
+ fclose( fp );
+ return( 0 );
+}
--- /dev/null
+/* modrdn.c - sock backend modrdn function */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+int
+sock_back_modrdn(
+ Operation *op,
+ SlapReply *rs )
+{
+ struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private;
+ AttributeDescription *entry = slap_schema.si_ad_entry;
+ Entry e;
+ FILE *fp;
+
+ e.e_id = NOID;
+ e.e_name = op->o_req_dn;
+ e.e_nname = op->o_req_ndn;
+ e.e_attrs = NULL;
+ e.e_ocflags = 0;
+ e.e_bv.bv_len = 0;
+ e.e_bv.bv_val = NULL;
+ e.e_private = NULL;
+
+ if ( ! access_allowed( op, &e, entry, NULL,
+ op->oq_modrdn.rs_newSup ? ACL_WDEL : ACL_WRITE,
+ NULL ) )
+ {
+ send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
+ return -1;
+ }
+
+ if ( (fp = opensock( si->si_sockpath )) == NULL ) {
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "could not open socket" );
+ return( -1 );
+ }
+
+ /* write out the request to the modrdn process */
+ fprintf( fp, "MODRDN\n" );
+ fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
+ sock_print_conn( fp, op->o_conn, si );
+ sock_print_suffixes( fp, op->o_bd );
+ fprintf( fp, "dn: %s\n", op->o_req_dn.bv_val );
+ fprintf( fp, "newrdn: %s\n", op->oq_modrdn.rs_newrdn.bv_val );
+ fprintf( fp, "deleteoldrdn: %d\n", op->oq_modrdn.rs_deleteoldrdn ? 1 : 0 );
+ if ( op->oq_modrdn.rs_newSup != NULL ) {
+ fprintf( fp, "newSuperior: %s\n", op->oq_modrdn.rs_newSup->bv_val );
+ }
+ fprintf( fp, "\n" );
+
+ /* read in the results and send them along */
+ sock_read_and_send_results( op, rs, fp );
+ fclose( fp );
+ return( 0 );
+}
--- /dev/null
+/* opensock.c - open a unix domain socket */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/errno.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+#include <ac/unistd.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+/*
+ * FIXME: count the number of concurrent open sockets (since each thread
+ * may open one). Perhaps block here if a soft limit is reached, and fail
+ * if a hard limit reached
+ */
+
+FILE *
+opensock(
+ const char *sockpath
+)
+{
+ int fd;
+ FILE *fp;
+ struct sockaddr_un sockun;
+
+ fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ if ( fd < 0 ) {
+ Debug( LDAP_DEBUG_ANY, "socket create failed\n", 0, 0, 0 );
+ return( NULL );
+ }
+
+ sockun.sun_family = AF_UNIX;
+ sprintf(sockun.sun_path, "%.*s", (int)(sizeof(sockun.sun_path)-1),
+ sockpath);
+ if ( connect( fd, (struct sockaddr *)&sockun, sizeof(sockun) ) < 0 ) {
+ Debug( LDAP_DEBUG_ANY, "socket connect(%s) failed\n",
+ sockpath ? sockpath : "<null>", 0, 0 );
+ return( NULL );
+ }
+
+ if ( ( fp = fdopen( fd, "r+" ) ) == NULL ) {
+ Debug( LDAP_DEBUG_ANY, "fdopen failed\n", 0, 0, 0 );
+ close( fd );
+ return( NULL );
+ }
+
+ return( fp );
+}
--- /dev/null
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#ifndef _PROTO_SOCK_H
+#define _PROTO_SOCK_H
+
+LDAP_BEGIN_DECL
+
+extern BI_init sock_back_initialize;
+
+extern BI_open sock_back_open;
+extern BI_close sock_back_close;
+extern BI_destroy sock_back_destroy;
+
+extern BI_db_init sock_back_db_init;
+extern BI_db_destroy sock_back_db_destroy;
+extern BI_db_config sock_back_db_config;
+
+extern BI_op_bind sock_back_bind;
+extern BI_op_unbind sock_back_unbind;
+extern BI_op_search sock_back_search;
+extern BI_op_compare sock_back_compare;
+extern BI_op_modify sock_back_modify;
+extern BI_op_modrdn sock_back_modrdn;
+extern BI_op_add sock_back_add;
+extern BI_op_delete sock_back_delete;
+
+LDAP_END_DECL
+
+#endif /* _PROTO_SOCK_H */
--- /dev/null
+/* result.c - sock backend result reading function */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/errno.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+#include <ac/unistd.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+/*
+ * FIXME: make a RESULT section compulsory from the socket response.
+ * Otherwise, a partial/aborted response is treated as 'success'.
+ * This is a divergence from the back-shell protocol, but makes things
+ * more robust.
+ */
+
+int
+sock_read_and_send_results(
+ Operation *op,
+ SlapReply *rs,
+ FILE *fp )
+{
+ int bsize, len;
+ char *buf, *bp;
+ char line[BUFSIZ];
+ char ebuf[128];
+
+ /* read in the result and send it along */
+ buf = (char *) ch_malloc( BUFSIZ );
+ buf[0] = '\0';
+ bsize = BUFSIZ;
+ bp = buf;
+ while ( !feof(fp) ) {
+ errno = 0;
+ if ( fgets( line, sizeof(line), fp ) == NULL ) {
+ if ( errno == EINTR ) continue;
+
+ Debug( LDAP_DEBUG_ANY, "sock: fgets failed: %s (%d)\n",
+ AC_STRERROR_R(errno, ebuf, sizeof ebuf), errno, 0 );
+ break;
+ }
+
+ Debug( LDAP_DEBUG_SHELL, "sock search reading line (%s)\n",
+ line, 0, 0 );
+
+ /* ignore lines beginning with # (LDIFv1 comments) */
+ if ( *line == '#' ) {
+ continue;
+ }
+
+ /* ignore lines beginning with DEBUG: */
+ if ( strncasecmp( line, "DEBUG:", 6 ) == 0 ) {
+ continue;
+ }
+
+ len = strlen( line );
+ while ( bp + len - buf > bsize ) {
+ size_t offset = bp - buf;
+ bsize += BUFSIZ;
+ buf = (char *) ch_realloc( buf, bsize );
+ bp = &buf[offset];
+ }
+ strcpy( bp, line );
+ bp += len;
+
+ /* line marked the end of an entry or result */
+ if ( *line == '\n' ) {
+ if ( strncasecmp( buf, "RESULT", 6 ) == 0 ) {
+ break;
+ }
+
+ if ( (rs->sr_entry = str2entry( buf )) == NULL ) {
+ Debug( LDAP_DEBUG_ANY, "str2entry(%s) failed\n",
+ buf, 0, 0 );
+ } else {
+ rs->sr_attrs = op->oq_search.rs_attrs;
+ rs->sr_flags = REP_ENTRY_MODIFIABLE;
+ send_search_entry( op, rs );
+ entry_free( rs->sr_entry );
+ }
+
+ bp = buf;
+ }
+ }
+ (void) str2result( buf, &rs->sr_err, (char **)&rs->sr_matched, (char **)&rs->sr_text );
+
+ /* otherwise, front end will send this result */
+ if ( rs->sr_err != 0 || op->o_tag != LDAP_REQ_BIND ) {
+ send_ldap_result( op, rs );
+ }
+
+ free( buf );
+
+ return( rs->sr_err );
+}
+
+void
+sock_print_suffixes(
+ FILE *fp,
+ Backend *be
+)
+{
+ int i;
+
+ for ( i = 0; be->be_suffix[i].bv_val != NULL; i++ ) {
+ fprintf( fp, "suffix: %s\n", be->be_suffix[i].bv_val );
+ }
+}
+
+void
+sock_print_conn(
+ FILE *fp,
+ Connection *conn,
+ struct sockinfo *si
+)
+{
+ if ( conn == NULL ) return;
+
+ if( si->si_extensions & SOCK_EXT_BINDDN ) {
+ fprintf( fp, "binddn: %s\n",
+ conn->c_dn.bv_len ? conn->c_dn.bv_val : "" );
+ }
+ if( si->si_extensions & SOCK_EXT_PEERNAME ) {
+ fprintf( fp, "peername: %s\n",
+ conn->c_peer_name.bv_len ? conn->c_peer_name.bv_val : "" );
+ }
+ if( si->si_extensions & SOCK_EXT_SSF ) {
+ fprintf( fp, "ssf: %d\n", conn->c_ssf );
+ }
+}
--- /dev/null
+/* search.c - sock backend search function */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+/*
+ * FIXME: add a filterSearchResults option like back-perl has
+ */
+
+int
+sock_back_search(
+ Operation *op,
+ SlapReply *rs )
+{
+ struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private;
+ FILE *fp;
+ AttributeName *an;
+
+ if ( (fp = opensock( si->si_sockpath )) == NULL ) {
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "could not open socket" );
+ return( -1 );
+ }
+
+ /* write out the request to the search process */
+ fprintf( fp, "SEARCH\n" );
+ fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
+ sock_print_conn( fp, op->o_conn, si );
+ sock_print_suffixes( fp, op->o_bd );
+ fprintf( fp, "base: %s\n", op->o_req_dn.bv_val );
+ fprintf( fp, "scope: %d\n", op->oq_search.rs_scope );
+ fprintf( fp, "deref: %d\n", op->oq_search.rs_deref );
+ fprintf( fp, "sizelimit: %d\n", op->oq_search.rs_slimit );
+ fprintf( fp, "timelimit: %d\n", op->oq_search.rs_tlimit );
+ fprintf( fp, "filter: %s\n", op->oq_search.rs_filterstr.bv_val );
+ fprintf( fp, "attrsonly: %d\n", op->oq_search.rs_attrsonly ? 1 : 0 );
+ fprintf( fp, "attrs:%s", op->oq_search.rs_attrs == NULL ? " all" : "" );
+ for ( an = op->oq_search.rs_attrs; an && an->an_name.bv_val; an++ ) {
+ fprintf( fp, " %s", an->an_name.bv_val );
+ }
+ fprintf( fp, "\n\n" ); /* end of attr line plus blank line */
+
+ /* read in the results and send them along */
+ rs->sr_attrs = op->oq_search.rs_attrs;
+ sock_read_and_send_results( op, rs, fp );
+
+ fclose( fp );
+ return( 0 );
+}
--- /dev/null
+# $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 2007 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+
+include /usr/local/etc/openldap/schema/core.schema
+
+database sock
+suffix "dc=example,dc=com"
+socketpath /tmp/example.sock
--- /dev/null
+#!/usr/bin/perl -w -T
+
+# See: http://seamons.com/net_server/net_server.html
+
+package ExampleDB;
+
+use strict;
+use vars qw(@ISA);
+use Net::Server::PreFork; # any personality will do
+
+@ISA = qw(Net::Server::PreFork);
+
+ExampleDB->run(
+ port=>"/tmp/example.sock|unix"
+ #conf_file=>"/etc/example.conf"
+);
+exit;
+
+### over-ridden subs below
+# The protocol is the same as back-shell
+
+sub process_request {
+ my $self = shift;
+
+ eval {
+
+ local $SIG{ALRM} = sub { die "Timed Out!\n" };
+ my $timeout = 30; # give the user 30 seconds to type a line
+ alarm($timeout);
+
+ my $request = <STDIN>;
+
+ if ($request eq "SEARCH\n") {
+ my %req = ();
+ while (my $line = <STDIN>) {
+ chomp($line);
+ last if $line eq "";
+ if ($line =~ /^([^:]+):\s*(.*)$/) { # FIXME: handle base64 encoded
+ $req{$1} = $2;
+ }
+ }
+ #sleep(2); # to test concurrency
+ print "dn: cn=test, dc=example, dc=com\n";
+ print "cn: test\n";
+ print "objectclass: cnobject\n";
+ print "\n";
+ print "RESULT\n";
+ print "code: 0\n";
+ print "info: answered by process $$\n";
+ }
+ else {
+ print "RESULT\n";
+ print "code: 53\n"; # unwillingToPerform
+ print "info: I don't implement $request";
+ }
+
+ };
+
+ return unless $@;
+ if( $@=~/timed out/i ){
+ print "RESULT\n";
+ print "code: 3\n"; # timeLimitExceeded
+ print "info: Timed out\n";
+ }
+ else {
+ print "RESULT\n";
+ print "code: 1\n"; # operationsError
+ print "info: $@\n"; # FIXME: remove CR/LF
+ }
+
+}
+
+1;
--- /dev/null
+/* unbind.c - sock backend unbind function */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-sock.h"
+
+int
+sock_back_unbind(
+ Operation *op,
+ SlapReply *rs
+)
+{
+ struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private;
+ FILE *fp;
+
+ if ( (fp = opensock( si->si_sockpath )) == NULL ) {
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "could not open socket" );
+ return( -1 );
+ }
+
+ /* write out the request to the unbind process */
+ fprintf( fp, "UNBIND\n" );
+ fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
+ sock_print_conn( fp, op->o_conn, si );
+ sock_print_suffixes( fp, op->o_bd );
+ fprintf( fp, "\n" );
+
+ /* no response to unbind */
+ fclose( fp );
+
+ return 0;
+}