diff options
Diffstat (limited to '')
-rw-r--r-- | servers/slapd/back-sock/Makefile.in | 47 | ||||
-rw-r--r-- | servers/slapd/back-sock/add.c | 69 | ||||
-rw-r--r-- | servers/slapd/back-sock/back-sock.h | 61 | ||||
-rw-r--r-- | servers/slapd/back-sock/bind.c | 80 | ||||
-rw-r--r-- | servers/slapd/back-sock/compare.c | 88 | ||||
-rw-r--r-- | servers/slapd/back-sock/config.c | 452 | ||||
-rw-r--r-- | servers/slapd/back-sock/delete.c | 75 | ||||
-rw-r--r-- | servers/slapd/back-sock/extended.c | 76 | ||||
-rw-r--r-- | servers/slapd/back-sock/init.c | 97 | ||||
-rw-r--r-- | servers/slapd/back-sock/modify.c | 117 | ||||
-rw-r--r-- | servers/slapd/back-sock/modrdn.c | 81 | ||||
-rw-r--r-- | servers/slapd/back-sock/opensock.c | 71 | ||||
-rw-r--r-- | servers/slapd/back-sock/proto-sock.h | 49 | ||||
-rw-r--r-- | servers/slapd/back-sock/result.c | 168 | ||||
-rw-r--r-- | servers/slapd/back-sock/search.c | 74 | ||||
-rw-r--r-- | servers/slapd/back-sock/searchexample.conf | 23 | ||||
-rw-r--r-- | servers/slapd/back-sock/searchexample.pl | 90 | ||||
-rw-r--r-- | servers/slapd/back-sock/unbind.c | 57 |
18 files changed, 1775 insertions, 0 deletions
diff --git a/servers/slapd/back-sock/Makefile.in b/servers/slapd/back-sock/Makefile.in new file mode 100644 index 0000000..1db07bf --- /dev/null +++ b/servers/slapd/back-sock/Makefile.in @@ -0,0 +1,47 @@ +# Makefile.in for back-sock +# $OpenLDAP$ +## This work is part of OpenLDAP Software <http://www.openldap.org/>. +## +## Copyright 2007-2022 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>. +## +## ACKNOWLEDGEMENTS: +## This work was initially developed by Brian Candler for inclusion +## in OpenLDAP Software. + +SRCS = init.c config.c opensock.c search.c bind.c unbind.c add.c \ + delete.c modify.c modrdn.c compare.c result.c extended.c +OBJS = init.lo config.lo opensock.lo search.lo bind.lo unbind.lo add.lo \ + delete.lo modify.lo modrdn.lo compare.lo result.lo extended.lo + +LDAP_INCDIR= ../../../include +LDAP_LIBDIR= ../../../libraries + +BUILD_OPT = "--enable-sock" +BUILD_MOD = @BUILD_SOCK@ + +mod_DEFS = -DSLAPD_IMPORT +MOD_DEFS = $(@BUILD_SOCK@_DEFS) + +shared_LDAP_LIBS = $(LDAP_LIBLDAP_LA) $(LDAP_LIBLBER_LA) +NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) +UNIX_LINK_LIBS = $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) + +LIBBASE = back_sock + +XINCPATH = -I.. -I$(srcdir)/.. +XDEFS = $(MODULES_CPPFLAGS) + +all-local-lib: ../.backend + +../.backend: lib$(LIBBASE).a + @touch $@ + diff --git a/servers/slapd/back-sock/add.c b/servers/slapd/back-sock/add.c new file mode 100644 index 0000000..0e96d95 --- /dev/null +++ b/servers/slapd/back-sock/add.c @@ -0,0 +1,69 @@ +/* add.c - sock backend add function */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#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 ); +} diff --git a/servers/slapd/back-sock/back-sock.h b/servers/slapd/back-sock/back-sock.h new file mode 100644 index 0000000..55dbe75 --- /dev/null +++ b/servers/slapd/back-sock/back-sock.h @@ -0,0 +1,61 @@ +/* sock.h - socket backend header file */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#ifndef SLAPD_SOCK_H +#define SLAPD_SOCK_H + +#include "proto-sock.h" + +LDAP_BEGIN_DECL + +struct sockinfo { + const char *si_sockpath; + slap_mask_t si_extensions; + slap_mask_t si_ops; /* overlay: operations to act on */ + slap_mask_t si_resps; /* overlay: responses to forward */ + regex_t si_dnpat; /* overlay: DN pattern to match */ + struct berval si_dnpatstr; +}; + +#define SOCK_EXT_BINDDN 1 +#define SOCK_EXT_PEERNAME 2 +#define SOCK_EXT_SSF 4 +#define SOCK_EXT_CONNID 8 + +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 diff --git a/servers/slapd/back-sock/bind.c b/servers/slapd/back-sock/bind.c new file mode 100644 index 0000000..8e8ec97 --- /dev/null +++ b/servers/slapd/back-sock/bind.c @@ -0,0 +1,80 @@ +/* bind.c - sock backend bind function */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#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 ); +} diff --git a/servers/slapd/back-sock/compare.c b/servers/slapd/back-sock/compare.c new file mode 100644 index 0000000..735e688 --- /dev/null +++ b/servers/slapd/back-sock/compare.c @@ -0,0 +1,88 @@ +/* compare.c - sock backend compare function */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 1998-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#include "portable.h" + +#include <stdio.h> + +#include <ac/string.h> +#include <ac/socket.h> + +#include "slap.h" +#include "back-sock.h" +#include "ldif.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; + char *text; + + 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_COMPARE, 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 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 ); + /* could be binary */ + text = ldif_put_wrap( LDIF_PUT_VALUE, + op->orc_ava->aa_desc->ad_cname.bv_val, + op->orc_ava->aa_value.bv_val, + op->orc_ava->aa_value.bv_len, LDIF_LINE_WIDTH_MAX ); + if ( text ) { + fprintf( fp, "%s\n", text ); + ber_memfree( text ); + } else { + fprintf( fp, "\n\n" ); + } + + /* read in the result and send it along */ + sock_read_and_send_results( op, rs, fp ); + + fclose( fp ); + return( 0 ); +} diff --git a/servers/slapd/back-sock/config.c b/servers/slapd/back-sock/config.c new file mode 100644 index 0000000..e6d3183 --- /dev/null +++ b/servers/slapd/back-sock/config.c @@ -0,0 +1,452 @@ +/* config.c - sock backend configuration file routine */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. Dynamic config support by Howard Chu. + */ + +#include "portable.h" + +#include <stdio.h> + +#include <ac/string.h> +#include <ac/socket.h> + +#include "slap.h" +#include "slap-config.h" +#include "back-sock.h" + +static ConfigDriver bs_cf_gen; +static int sock_over_setup(); +static slap_response sock_over_response; + +enum { + BS_EXT = 1, + BS_OPS, + BS_RESP, + BS_DNPAT +}; + +/* The number of overlay-only config attrs */ +#define NUM_OV_ATTRS 3 + +static ConfigTable bscfg[] = { + { "sockops", "ops", 2, 0, 0, ARG_MAGIC|BS_OPS, + bs_cf_gen, "( OLcfgDbAt:7.3 NAME 'olcOvSocketOps' " + "DESC 'Operation types to forward' " + "EQUALITY caseIgnoreMatch " + "SYNTAX OMsDirectoryString )", NULL, NULL }, + { "sockresps", "resps", 2, 0, 0, ARG_MAGIC|BS_RESP, + bs_cf_gen, "( OLcfgDbAt:7.4 NAME 'olcOvSocketResps' " + "DESC 'Response types to forward' " + "EQUALITY caseIgnoreMatch " + "SYNTAX OMsDirectoryString )", NULL, NULL }, + { "sockdnpat", "regexp", 2, 2, 0, ARG_MAGIC|BS_DNPAT, + bs_cf_gen, "( OLcfgDbAt:7.5 NAME 'olcOvSocketDNpat' " + "DESC 'DN pattern to match' " + "EQUALITY caseIgnoreMatch " + "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, + + { "socketpath", "pathname", 2, 2, 0, ARG_STRING|ARG_OFFSET, + (void *)offsetof(struct sockinfo, si_sockpath), + "( OLcfgDbAt:7.1 NAME 'olcDbSocketPath' " + "DESC 'Pathname for Unix domain socket' " + "EQUALITY caseExactMatch " + "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, + { "extensions", "ext", 2, 0, 0, ARG_MAGIC|BS_EXT, + bs_cf_gen, "( OLcfgDbAt:7.2 NAME 'olcDbSocketExtensions' " + "DESC 'binddn, peername, or ssf' " + "EQUALITY caseIgnoreMatch " + "SYNTAX OMsDirectoryString )", NULL, NULL }, + { NULL, NULL } +}; + +static ConfigOCs bsocs[] = { + { "( OLcfgDbOc:7.1 " + "NAME 'olcDbSocketConfig' " + "DESC 'Socket backend configuration' " + "SUP olcDatabaseConfig " + "MUST olcDbSocketPath " + "MAY olcDbSocketExtensions )", + Cft_Database, bscfg+NUM_OV_ATTRS }, + { NULL, 0, NULL } +}; + +static ConfigOCs osocs[] = { + { "( OLcfgDbOc:7.2 " + "NAME 'olcOvSocketConfig' " + "DESC 'Socket overlay configuration' " + "SUP olcOverlayConfig " + "MUST olcDbSocketPath " + "MAY ( olcDbSocketExtensions $ " + " olcOvSocketOps $ olcOvSocketResps $ " + " olcOvSocketDNpat ) )", + Cft_Overlay, bscfg }, + { NULL, 0, NULL } +}; + +#define SOCK_OP_BIND 0x001 +#define SOCK_OP_UNBIND 0x002 +#define SOCK_OP_SEARCH 0x004 +#define SOCK_OP_COMPARE 0x008 +#define SOCK_OP_MODIFY 0x010 +#define SOCK_OP_MODRDN 0x020 +#define SOCK_OP_ADD 0x040 +#define SOCK_OP_DELETE 0x080 +#define SOCK_OP_EXTENDED 0x100 + +#define SOCK_REP_RESULT 0x001 +#define SOCK_REP_SEARCH 0x002 + +static slap_verbmasks bs_exts[] = { + { BER_BVC("binddn"), SOCK_EXT_BINDDN }, + { BER_BVC("peername"), SOCK_EXT_PEERNAME }, + { BER_BVC("ssf"), SOCK_EXT_SSF }, + { BER_BVC("connid"), SOCK_EXT_CONNID }, + { BER_BVNULL, 0 } +}; + +static slap_verbmasks ov_ops[] = { + { BER_BVC("bind"), SOCK_OP_BIND }, + { BER_BVC("unbind"), SOCK_OP_UNBIND }, + { BER_BVC("search"), SOCK_OP_SEARCH }, + { BER_BVC("compare"), SOCK_OP_COMPARE }, + { BER_BVC("modify"), SOCK_OP_MODIFY }, + { BER_BVC("modrdn"), SOCK_OP_MODRDN }, + { BER_BVC("add"), SOCK_OP_ADD }, + { BER_BVC("delete"), SOCK_OP_DELETE }, + { BER_BVC("extended"), SOCK_OP_EXTENDED }, + { BER_BVNULL, 0 } +}; + +static slap_verbmasks ov_resps[] = { + { BER_BVC("result"), SOCK_REP_RESULT }, + { BER_BVC("search"), SOCK_REP_SEARCH }, + { BER_BVNULL, 0 } +}; + +static int +bs_cf_gen( ConfigArgs *c ) +{ + struct sockinfo *si; + int rc; + + if ( c->be && c->table == Cft_Database ) + si = c->be->be_private; + else if ( c->bi ) + si = c->bi->bi_private; + else + return ARG_BAD_CONF; + + if ( c->op == SLAP_CONFIG_EMIT ) { + switch( c->type ) { + case BS_EXT: + return mask_to_verbs( bs_exts, si->si_extensions, &c->rvalue_vals ); + case BS_OPS: + return mask_to_verbs( ov_ops, si->si_ops, &c->rvalue_vals ); + case BS_RESP: + return mask_to_verbs( ov_resps, si->si_resps, &c->rvalue_vals ); + case BS_DNPAT: + if ( BER_BVISEMPTY( &si->si_dnpatstr ) ) + return 1; + value_add_one( &c->rvalue_vals, &si->si_dnpatstr ); + return 0; + } + } else if ( c->op == LDAP_MOD_DELETE ) { + switch( c->type ) { + case BS_EXT: + if ( c->valx < 0 ) { + si->si_extensions = 0; + rc = 0; + } else { + slap_mask_t dels = 0; + rc = verbstring_to_mask( bs_exts, c->line, ' ', &dels ); + if ( rc == 0 ) + si->si_extensions &= ~dels; + } + return rc; + case BS_OPS: + if ( c->valx < 0 ) { + si->si_ops = 0; + rc = 0; + } else { + slap_mask_t dels = 0; + rc = verbstring_to_mask( ov_ops, c->line, ' ', &dels ); + if ( rc == 0 ) + si->si_ops &= ~dels; + } + return rc; + case BS_RESP: + if ( c->valx < 0 ) { + si->si_resps = 0; + rc = 0; + } else { + slap_mask_t dels = 0; + rc = verbstring_to_mask( ov_resps, c->line, ' ', &dels ); + if ( rc == 0 ) + si->si_resps &= ~dels; + } + return rc; + case BS_DNPAT: + regfree( &si->si_dnpat ); + ch_free( si->si_dnpatstr.bv_val ); + BER_BVZERO( &si->si_dnpatstr ); + return 0; + } + + } else { + switch( c->type ) { + case BS_EXT: { + slap_mask_t adds = 0; + if ( verbs_to_mask( c->argc, c->argv, bs_exts, &adds ) ) { + return LDAP_INVALID_SYNTAX; + } + /* Tolerate overlaps in slapd.conf */ + if ( c->op != SLAP_CONFIG_ADD && adds & si->si_extensions ) { + return LDAP_TYPE_OR_VALUE_EXISTS; + } + si->si_extensions |= adds; + return 0; + } + case BS_OPS: { + slap_mask_t adds = 0; + if ( verbs_to_mask( c->argc, c->argv, ov_ops, &adds ) ) { + return LDAP_INVALID_SYNTAX; + } + /* Tolerate overlaps in slapd.conf */ + if ( c->op != SLAP_CONFIG_ADD && adds & si->si_ops ) { + return LDAP_TYPE_OR_VALUE_EXISTS; + } + si->si_ops |= adds; + return 0; + } + case BS_RESP: { + slap_mask_t adds = 0; + if ( verbs_to_mask( c->argc, c->argv, ov_resps, &adds ) ) { + return LDAP_INVALID_SYNTAX; + } + /* Tolerate overlaps in slapd.conf */ + if ( c->op != SLAP_CONFIG_ADD && adds & si->si_resps ) { + return LDAP_TYPE_OR_VALUE_EXISTS; + } + si->si_resps |= adds; + return 0; + } + case BS_DNPAT: + if ( !regcomp( &si->si_dnpat, c->argv[1], REG_EXTENDED|REG_ICASE|REG_NOSUB )) { + ber_str2bv( c->argv[1], 0, 1, &si->si_dnpatstr ); + return 0; + } else { + return 1; + } + } + } + return 1; +} + +int +sock_back_init_cf( BackendInfo *bi ) +{ + int rc; + bi->bi_cf_ocs = bsocs; + + rc = config_register_schema( bscfg, bsocs ); + if ( !rc ) + rc = sock_over_setup(); + return rc; +} + +/* sock overlay wrapper */ +static slap_overinst sockover; + +static int sock_over_db_init( Backend *be, struct config_reply_s *cr ); +static int sock_over_db_destroy( Backend *be, struct config_reply_s *cr ); + +static BI_op_bind *sockfuncs[] = { + sock_back_bind, + sock_back_unbind, + sock_back_search, + sock_back_compare, + sock_back_modify, + sock_back_modrdn, + sock_back_add, + sock_back_delete, + 0, /* abandon not supported */ + sock_back_extended +}; + +static const int sockopflags[] = { + SOCK_OP_BIND, + SOCK_OP_UNBIND, + SOCK_OP_SEARCH, + SOCK_OP_COMPARE, + SOCK_OP_MODIFY, + SOCK_OP_MODRDN, + SOCK_OP_ADD, + SOCK_OP_DELETE, + 0, /* abandon not supported */ + SOCK_OP_EXTENDED +}; + +static int sock_over_op( + Operation *op, + SlapReply *rs +) +{ + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + void *private = op->o_bd->be_private; + slap_callback *sc; + struct sockinfo *si; + slap_operation_t which; + + switch (op->o_tag) { + case LDAP_REQ_BIND: which = op_bind; break; + case LDAP_REQ_UNBIND: which = op_unbind; break; + case LDAP_REQ_SEARCH: which = op_search; break; + case LDAP_REQ_COMPARE: which = op_compare; break; + case LDAP_REQ_MODIFY: which = op_modify; break; + case LDAP_REQ_MODRDN: which = op_modrdn; break; + case LDAP_REQ_ADD: which = op_add; break; + case LDAP_REQ_DELETE: which = op_delete; break; + case LDAP_REQ_EXTENDED: which = op_extended; break; + default: + return SLAP_CB_CONTINUE; + } + si = on->on_bi.bi_private; + if ( !(si->si_ops & sockopflags[which])) + return SLAP_CB_CONTINUE; + + if ( !BER_BVISEMPTY( &si->si_dnpatstr ) && + regexec( &si->si_dnpat, op->o_req_ndn.bv_val, 0, NULL, 0 )) + return SLAP_CB_CONTINUE; + + op->o_bd->be_private = si; + sc = op->o_callback; + op->o_callback = NULL; + sockfuncs[which]( op, rs ); + op->o_bd->be_private = private; + op->o_callback = sc; + return rs->sr_err; +} + +static int +sock_over_response( Operation *op, SlapReply *rs ) +{ + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + struct sockinfo *si = (struct sockinfo *)on->on_bi.bi_private; + FILE *fp; + + if ( rs->sr_type == REP_RESULT ) { + if ( !( si->si_resps & SOCK_REP_RESULT )) + return SLAP_CB_CONTINUE; + } else if ( rs->sr_type == REP_SEARCH ) { + if ( !( si->si_resps & SOCK_REP_SEARCH )) + return SLAP_CB_CONTINUE; + } else + return SLAP_CB_CONTINUE; + + if (( fp = opensock( si->si_sockpath )) == NULL ) + return SLAP_CB_CONTINUE; + + if ( rs->sr_type == REP_RESULT ) { + /* write out the result */ + fprintf( fp, "RESULT\n" ); + fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); + sock_print_conn( fp, op->o_conn, si ); + fprintf( fp, "code: %d\n", rs->sr_err ); + if ( rs->sr_matched ) + fprintf( fp, "matched: %s\n", rs->sr_matched ); + if (rs->sr_text ) + fprintf( fp, "info: %s\n", rs->sr_text ); + } else { + /* write out the search entry */ + int len; + fprintf( fp, "ENTRY\n" ); + fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); + sock_print_conn( fp, op->o_conn, si ); + ldap_pvt_thread_mutex_lock( &entry2str_mutex ); + fprintf( fp, "%s", entry2str( rs->sr_entry, &len ) ); + ldap_pvt_thread_mutex_unlock( &entry2str_mutex ); + } + fprintf( fp, "\n" ); + fclose( fp ); + + return SLAP_CB_CONTINUE; +} + +static int +sock_over_setup() +{ + int rc; + + sockover.on_bi.bi_type = "sock"; + sockover.on_bi.bi_db_init = sock_over_db_init; + sockover.on_bi.bi_db_destroy = sock_over_db_destroy; + + sockover.on_bi.bi_op_bind = sock_over_op; + sockover.on_bi.bi_op_unbind = sock_over_op; + sockover.on_bi.bi_op_search = sock_over_op; + sockover.on_bi.bi_op_compare = sock_over_op; + sockover.on_bi.bi_op_modify = sock_over_op; + sockover.on_bi.bi_op_modrdn = sock_over_op; + sockover.on_bi.bi_op_add = sock_over_op; + sockover.on_bi.bi_op_delete = sock_over_op; + sockover.on_bi.bi_extended = sock_over_op; + sockover.on_response = sock_over_response; + + sockover.on_bi.bi_cf_ocs = osocs; + + rc = config_register_schema( bscfg, osocs ); + if ( rc ) return rc; + + return overlay_register( &sockover ); +} + +static int +sock_over_db_init( + Backend *be, + struct config_reply_s *cr +) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + void *private = be->be_private; + void *cf_ocs = be->be_cf_ocs; + int rc; + + be->be_private = NULL; + rc = sock_back_db_init( be, cr ); + on->on_bi.bi_private = be->be_private; + be->be_private = private; + be->be_cf_ocs = cf_ocs; + return rc; +} + +static int +sock_over_db_destroy( + Backend *be, + struct config_reply_s *cr +) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + void *private = be->be_private; + int rc; + + be->be_private = on->on_bi.bi_private; + rc = sock_back_db_destroy( be, cr ); + on->on_bi.bi_private = be->be_private; + be->be_private = private; + return rc; +} diff --git a/servers/slapd/back-sock/delete.c b/servers/slapd/back-sock/delete.c new file mode 100644 index 0000000..89a268f --- /dev/null +++ b/servers/slapd/back-sock/delete.c @@ -0,0 +1,75 @@ +/* delete.c - sock backend delete function */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#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 ); +} diff --git a/servers/slapd/back-sock/extended.c b/servers/slapd/back-sock/extended.c new file mode 100644 index 0000000..e065761 --- /dev/null +++ b/servers/slapd/back-sock/extended.c @@ -0,0 +1,76 @@ +/* extended.c - sock backend extended routines */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2000-2022 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 "slap.h" +#include "back-sock.h" + +#include "lutil.h" + +int +sock_back_extended( Operation *op, SlapReply *rs ) +{ + int rc; + struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private; + FILE *fp; + struct berval b64; + + Debug( LDAP_DEBUG_ARGS, "==> sock_back_extended(%s, %s)\n", + op->ore_reqoid.bv_val, op->o_req_dn.bv_val ); + + 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 extended process */ + fprintf( fp, "EXTENDED\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, "oid: %s\n", op->ore_reqoid.bv_val ); + + if (op->ore_reqdata) { + + b64.bv_len = LUTIL_BASE64_ENCODE_LEN( op->ore_reqdata->bv_len ) + 1; + b64.bv_val = op->o_tmpalloc( b64.bv_len + 1, op->o_tmpmemctx ); + + rc = lutil_b64_ntop( + (unsigned char *) op->ore_reqdata->bv_val, op->ore_reqdata->bv_len, + b64.bv_val, b64.bv_len ); + + b64.bv_len = rc; + assert( strlen(b64.bv_val) == b64.bv_len ); + + fprintf( fp, "value: %s\n", b64.bv_val ); + + op->o_tmpfree( b64.bv_val, op->o_tmpmemctx ); + + } + + fprintf( fp, "\n" ); + + /* read in the results and send them along */ + rc = sock_read_and_send_results( op, rs, fp ); + fclose( fp ); + + return( rc ); +} diff --git a/servers/slapd/back-sock/init.c b/servers/slapd/back-sock/init.c new file mode 100644 index 0000000..02b7bc8 --- /dev/null +++ b/servers/slapd/back-sock/init.c @@ -0,0 +1,97 @@ +/* init.c - initialize sock backend */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#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 = 0; + 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 = sock_back_extended; + + bi->bi_chk_referrals = 0; + + bi->bi_connection_init = 0; + bi->bi_connection_destroy = 0; + + return sock_back_init_cf( bi ); +} + +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; + be->be_cf_ocs = be->bd_info->bi_cf_ocs; + + 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 */ diff --git a/servers/slapd/back-sock/modify.c b/servers/slapd/back-sock/modify.c new file mode 100644 index 0000000..a5ec012 --- /dev/null +++ b/servers/slapd/back-sock/modify.c @@ -0,0 +1,117 @@ +/* modify.c - sock backend modify function */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#include "portable.h" + +#include <stdio.h> + +#include <ac/string.h> +#include <ac/socket.h> + +#include "slap.h" +#include "back-sock.h" +#include "ldif.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; + + 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; + + case LDAP_MOD_INCREMENT: + fprintf( fp, "increment: %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++ ) { + char *text = ldif_put_wrap( LDIF_PUT_VALUE, + mod->sm_desc->ad_cname.bv_val, + mod->sm_values[i].bv_val, + mod->sm_values[i].bv_len, LDIF_LINE_WIDTH_MAX ); + if ( text ) { + fprintf( fp, "%s", text ); + ber_memfree( text ); + } else { + break; + } + } + } + + 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 ); +} diff --git a/servers/slapd/back-sock/modrdn.c b/servers/slapd/back-sock/modrdn.c new file mode 100644 index 0000000..c5a9195 --- /dev/null +++ b/servers/slapd/back-sock/modrdn.c @@ -0,0 +1,81 @@ +/* modrdn.c - sock backend modrdn function */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#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 ); +} diff --git a/servers/slapd/back-sock/opensock.c b/servers/slapd/back-sock/opensock.c new file mode 100644 index 0000000..9b4826d --- /dev/null +++ b/servers/slapd/back-sock/opensock.c @@ -0,0 +1,71 @@ +/* opensock.c - open a unix domain socket */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#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" ); + 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>" ); + close( fd ); + return( NULL ); + } + + if ( ( fp = fdopen( fd, "r+" ) ) == NULL ) { + Debug( LDAP_DEBUG_ANY, "fdopen failed\n" ); + close( fd ); + return( NULL ); + } + + return( fp ); +} diff --git a/servers/slapd/back-sock/proto-sock.h b/servers/slapd/back-sock/proto-sock.h new file mode 100644 index 0000000..0808329 --- /dev/null +++ b/servers/slapd/back-sock/proto-sock.h @@ -0,0 +1,49 @@ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#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_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; + +extern BI_op_extended sock_back_extended; + +extern int sock_back_init_cf( BackendInfo *bi ); + +LDAP_END_DECL + +#endif /* _PROTO_SOCK_H */ diff --git a/servers/slapd/back-sock/result.c b/servers/slapd/back-sock/result.c new file mode 100644 index 0000000..55a4060 --- /dev/null +++ b/servers/slapd/back-sock/result.c @@ -0,0 +1,168 @@ +/* result.c - sock backend result reading function */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#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]; + + (void) fflush(fp); + /* 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 ) { + int saved_errno = errno; + if ( errno == EINTR ) continue; + + Debug( LDAP_DEBUG_ANY, "sock: fgets failed: %s (%d)\n", + AC_STRERROR_R(saved_errno, ebuf, sizeof ebuf), saved_errno ); + break; + } + + Debug( LDAP_DEBUG_SHELL, "sock search reading line (%s)\n", + line ); + + /* ignore lines beginning with # (LDIFv1 comments) */ + if ( *line == '#' ) { + continue; + } + + /* ignore lines beginning with DEBUG: */ + if ( strncasecmp( line, "DEBUG:", 6 ) == 0 ) { + continue; + } + + if ( strncasecmp( line, "CONTINUE", 8 ) == 0 ) { + struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private; + /* Only valid when operating as an overlay! */ + assert( si->si_ops != 0 ); + rs->sr_err = SLAP_CB_CONTINUE; + goto skip; + } + + len = strlen( line ); + while ( bp + len + 1 - 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 ); + } 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 ); + rs->sr_attrs = NULL; + } + + 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 ); + } + +skip: + ch_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 ); + } + if( si->si_extensions & SOCK_EXT_CONNID ) { + fprintf( fp, "connid: %lu\n", conn->c_connid ); + } +} diff --git a/servers/slapd/back-sock/search.c b/servers/slapd/back-sock/search.c new file mode 100644 index 0000000..9812e99 --- /dev/null +++ b/servers/slapd/back-sock/search.c @@ -0,0 +1,74 @@ +/* search.c - sock backend search function */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#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 ); +} diff --git a/servers/slapd/back-sock/searchexample.conf b/servers/slapd/back-sock/searchexample.conf new file mode 100644 index 0000000..842d6aa --- /dev/null +++ b/servers/slapd/back-sock/searchexample.conf @@ -0,0 +1,23 @@ +# $OpenLDAP$ +## This work is part of OpenLDAP Software <http://www.openldap.org/>. +## +## Copyright 2007-2022 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>. +## +## ACKNOWLEDGEMENTS: +## This work was initially developed by Brian Candler for inclusion +## in OpenLDAP Software. + +include /usr/local/etc/openldap/schema/core.schema + +database sock +suffix "dc=example,dc=com" +socketpath /tmp/example.sock diff --git a/servers/slapd/back-sock/searchexample.pl b/servers/slapd/back-sock/searchexample.pl new file mode 100644 index 0000000..f867005 --- /dev/null +++ b/servers/slapd/back-sock/searchexample.pl @@ -0,0 +1,90 @@ +#!/usr/bin/perl -w -T +# $OpenLDAP$ +## This work is part of OpenLDAP Software <http://www.openldap.org/>. +## +## Copyright 2007-2022 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>. +## +## ACKNOWLEDGEMENTS: +## This work was initially developed by Brian Candler for inclusion +## in OpenLDAP Software. + +# See: http://search.cpan.org/dist/Net-Server/ + +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; diff --git a/servers/slapd/back-sock/unbind.c b/servers/slapd/back-sock/unbind.c new file mode 100644 index 0000000..0b349e1 --- /dev/null +++ b/servers/slapd/back-sock/unbind.c @@ -0,0 +1,57 @@ +/* unbind.c - sock backend unbind function */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2007-2022 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>. + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Brian Candler for inclusion + * in OpenLDAP Software. + */ + +#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; +} |