back-sock by Brian Candler (B.Candler@pobox.com) ITS#4094 (untested)

This commit is contained in:
Howard Chu 2007-09-07 12:02:43 +00:00
parent 00ad93ac70
commit b6827c75a8
17 changed files with 1185 additions and 0 deletions

View file

@ -291,6 +291,7 @@ Backends="bdb \
perl \ perl \
relay \ relay \
shell \ shell \
sock \
sql" sql"
AC_ARG_ENABLE(xxslapbackends,[ AC_ARG_ENABLE(xxslapbackends,[
@ -320,6 +321,8 @@ OL_ARG_ENABLE(relay,[ --enable-relay enable relay backend],
yes, [no yes mod], ol_enable_backends)dnl yes, [no yes mod], ol_enable_backends)dnl
OL_ARG_ENABLE(shell,[ --enable-shell enable shell backend], OL_ARG_ENABLE(shell,[ --enable-shell enable shell backend],
no, [no yes mod], ol_enable_backends)dnl 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], OL_ARG_ENABLE(sql,[ --enable-sql enable sql backend],
no, [no yes mod], ol_enable_backends)dnl no, [no yes mod], ol_enable_backends)dnl
@ -462,6 +465,7 @@ elif test $ol_enable_modules != yes &&
test $ol_enable_perl = no && test $ol_enable_perl = no &&
test $ol_enable_relay = no && test $ol_enable_relay = no &&
test $ol_enable_shell = no && test $ol_enable_shell = no &&
test $ol_enable_sock = no &&
test $ol_enable_sql = no ; then test $ol_enable_sql = no ; then
dnl no slapd backend dnl no slapd backend
@ -519,6 +523,7 @@ BUILD_PASSWD=no
BUILD_PERL=no BUILD_PERL=no
BUILD_RELAY=no BUILD_RELAY=no
BUILD_SHELL=no BUILD_SHELL=no
BUILD_SOCK=no
BUILD_SQL=no BUILD_SQL=no
BUILD_ACCESSLOG=no BUILD_ACCESSLOG=no
@ -2634,6 +2639,19 @@ if test "$ol_enable_shell" != no ; then
AC_DEFINE_UNQUOTED(SLAPD_SHELL,$MFLAG,[define to support SHELL backend]) AC_DEFINE_UNQUOTED(SLAPD_SHELL,$MFLAG,[define to support SHELL backend])
fi 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 if test "$ol_link_sql" != no ; then
BUILD_SLAPD=yes BUILD_SLAPD=yes
BUILD_SQL=$ol_enable_sql BUILD_SQL=$ol_enable_sql
@ -2902,6 +2920,7 @@ dnl backends
AC_SUBST(BUILD_RELAY) AC_SUBST(BUILD_RELAY)
AC_SUBST(BUILD_PERL) AC_SUBST(BUILD_PERL)
AC_SUBST(BUILD_SHELL) AC_SUBST(BUILD_SHELL)
AC_SUBST(BUILD_SOCK)
AC_SUBST(BUILD_SQL) AC_SUBST(BUILD_SQL)
dnl overlays dnl overlays
AC_SUBST(BUILD_ACCESSLOG) AC_SUBST(BUILD_ACCESSLOG)
@ -3001,6 +3020,7 @@ AC_CONFIG_FILES([Makefile:build/top.mk:Makefile.in:build/dir.mk]
[servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/mod.mk] [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-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-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/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/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] [servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk]

View file

@ -0,0 +1,65 @@
/* 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 );
}

View file

@ -0,0 +1,52 @@
/* 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

View file

@ -0,0 +1,76 @@
/* 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 );
}

View file

@ -0,0 +1,80 @@
/* 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 );
}

View file

@ -0,0 +1,78 @@
/* 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;
}

View file

@ -0,0 +1,71 @@
/* 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 );
}

View file

@ -0,0 +1,92 @@
/* 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 */

View file

@ -0,0 +1,102 @@
/* 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 );
}

View file

@ -0,0 +1,77 @@
/* 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 );
}

View file

@ -0,0 +1,66 @@
/* 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 );
}

View file

@ -0,0 +1,42 @@
/* $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 */

View file

@ -0,0 +1,149 @@
/* 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 );
}
}

View file

@ -0,0 +1,70 @@
/* 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 );
}

View file

@ -0,0 +1,19 @@
# $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

View file

@ -0,0 +1,73 @@
#!/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;

View file

@ -0,0 +1,53 @@
/* 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;
}