Operation *op
)
{
- ber_int_t id;
+ ber_int_t id;
Operation *o;
- int rc;
+ int rc;
+#ifdef LDAP_CLIENT_UPDATE
+ int i;
+#endif
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY, "conn: %d do_abandon\n", conn->c_connid, 0, 0);
}
done:
+
+#if LDAP_CLIENT_UPDATE
+ for ( i = 0; i < nbackends; i++ ) {
+ if ( strncmp( backends[i].be_type, "bdb", 3 ) ) continue;
+ if ( bdb_abandon( &backends[i], conn, id ) == LDAP_SUCCESS ) {
+ break;
+ }
+ }
+#endif
+
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
#ifdef NEW_LOGGING
return LDAP_CONFIDENTIALITY_REQUIRED;
}
- if( op->o_ndn.bv_len == 0 ) {
+ if( !( global_allows & SLAP_ALLOW_UPDATE_ANON ) &&
+ op->o_ndn.bv_len == 0 )
+ {
*text = "modifications require authentication";
return LDAP_STRONG_AUTH_REQUIRED;
}
+
+#ifdef SLAP_X_LISTENER_MOD
+ if ( ! ( conn->c_listener->sl_perms & S_IWUSR ) ) {
+ /* no "w" mode means readonly */
+ *text = "modifications not allowed on this listener";
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+#endif /* SLAP_X_LISTENER_MOD */
}
}
return LDAP_OPERATIONS_ERROR;
}
}
+
+#ifdef SLAP_X_LISTENER_MOD
+ if ( !starttls && op->o_dn.bv_len == 0 ) {
+ if ( ! ( conn->c_listener->sl_perms & S_IXUSR ) ) {
+ /* no "x" mode means bind required */
+ *text = "bind required on this listener";
+ return LDAP_STRONG_AUTH_REQUIRED;
+ }
+ }
+
+ if ( !starttls && !updateop ) {
+ if ( ! ( conn->c_listener->sl_perms & S_IRUSR ) ) {
+ /* no "r" mode means no read */
+ *text = "read not allowed on this listener";
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+ }
+#endif /* SLAP_X_LISTENER_MOD */
+
}
if( restrictops & opflag ) {
} else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) {
allows |= SLAP_ALLOW_BIND_ANON_DN;
+ } else if( strcasecmp( cargv[i], "update_anon" ) == 0 ) {
+ allows |= SLAP_ALLOW_UPDATE_ANON;
+
} else if( strcasecmp( cargv[i], "none" ) != 0 ) {
#ifdef NEW_LOGGING
- LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: unknown feature %s in "
- "\"allow <features>\" line.\n",
- fname, lineno, cargv[1] );
+ LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
+ "unknown feature %s in \"allow <features>\" line.\n",
+ fname, lineno, cargv[1] );
#else
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: unknown feature %s in \"allow <features>\" line\n",
- fname, lineno, cargv[i] );
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "unknown feature %s in \"allow <features>\" line\n",
+ fname, lineno, cargv[i] );
#endif
return( 1 );
long connection_init(
ber_socket_t s,
- const char* url,
+ Listener *listener,
const char* dnsname,
const char* peername,
- const char* sockname,
int tls_udp_option,
slap_ssf_t ssf,
const char *authid )
assert( connections != NULL );
+ assert( listener != NULL );
assert( dnsname != NULL );
assert( peername != NULL );
- assert( sockname != NULL );
#ifndef HAVE_TLS
assert( tls_udp_option != 1 );
c->c_ndn.bv_len = 0;
c->c_groups = NULL;
- c->c_listener_url.bv_val = NULL;
- c->c_listener_url.bv_len = 0;
+ c->c_listener = NULL;
c->c_peer_domain.bv_val = NULL;
c->c_peer_domain.bv_len = 0;
c->c_peer_name.bv_val = NULL;
c->c_peer_name.bv_len = 0;
- c->c_sock_name.bv_val = NULL;
- c->c_sock_name.bv_len = 0;
LDAP_STAILQ_INIT(&c->c_ops);
LDAP_STAILQ_INIT(&c->c_pending_ops);
assert( c->c_dn.bv_val == NULL );
assert( c->c_ndn.bv_val == NULL );
assert( c->c_groups == NULL );
- assert( c->c_listener_url.bv_val == NULL );
+ assert( c->c_listener == NULL );
assert( c->c_peer_domain.bv_val == NULL );
assert( c->c_peer_name.bv_val == NULL );
- assert( c->c_sock_name.bv_val == NULL );
assert( LDAP_STAILQ_EMPTY(&c->c_ops) );
assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) );
assert( c->c_sasl_bind_mech.bv_val == NULL );
assert( c->c_sasl_bindop == NULL );
assert( c->c_currentber == NULL );
- ber_str2bv( url, 0, 1, &c->c_listener_url );
+ c->c_listener = listener;
ber_str2bv( dnsname, 0, 1, &c->c_peer_domain );
ber_str2bv( peername, 0, 1, &c->c_peer_name );
- ber_str2bv( sockname, 0, 1, &c->c_sock_name );
c->c_n_ops_received = 0;
c->c_n_ops_executing = 0;
c->c_activitytime = c->c_starttime = 0;
connection2anonymous( c );
-
- if(c->c_listener_url.bv_val != NULL) {
- free(c->c_listener_url.bv_val);
- c->c_listener_url.bv_val = NULL;
- }
- c->c_listener_url.bv_len = 0;
+ c->c_listener = NULL;
if(c->c_peer_domain.bv_val != NULL) {
free(c->c_peer_domain.bv_val);
}
c->c_peer_domain.bv_len = 0;
if(c->c_peer_name.bv_val != NULL) {
-#ifdef LDAP_PF_LOCAL
- /*
- * If peer was a domain socket, unlink. Mind you,
- * they may be un-named. Should we leave this to
- * the client?
- */
- if (strncmp(c->c_peer_name.bv_val, "PATH=",
- sizeof("PATH=") - 1) == 0) {
- char *path = c->c_peer_name.bv_val
- + sizeof("PATH=") - 1;
- if (path[0] != '\0') {
- (void)unlink(path);
- }
- }
-#endif /* LDAP_PF_LOCAL */
-
free(c->c_peer_name.bv_val);
c->c_peer_name.bv_val = NULL;
}
c->c_peer_name.bv_len = 0;
- if(c->c_sock_name.bv_val != NULL) {
- free(c->c_sock_name.bv_val);
- c->c_sock_name.bv_val = NULL;
- }
- c->c_sock_name.bv_len = 0;
c->c_sasl_bind_in_progress = 0;
if(c->c_sasl_bind_mech.bv_val != NULL) {
LDAP_STAILQ_REMOVE( &conn->c_ops, arg->co_op, slap_op, o_next);
LDAP_STAILQ_NEXT(arg->co_op, o_next) = NULL;
- slap_op_free( arg->co_op );
+#ifdef LDAP_CLIENT_UPDATE
+ if ( !( arg->co_op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
+#endif /* LDAP_CLIENT_UPDATE */
+ {
+ slap_op_free( arg->co_op );
+ }
arg->co_op = NULL;
arg->co_conn = NULL;
free( (char *) arg );
case LDAP_REQ_UNBIND:
tagmask = SLAP_CTRL_UNBIND;
break;
+ case LDAP_REQ_ABANDON:
+ tagmask = SLAP_CTRL_ABANDON;
+ break;
case LDAP_REQ_EXTENDED:
/* FIXME: check list of extended operations */
tagmask = ~0U;
#ifdef HAVE_TCPD
#include <tcpd.h>
+#define SLAP_STRING_UNKNOWN STRING_UNKNOWN
int allow_severity = LOG_INFO;
int deny_severity = LOG_NOTICE;
-#endif /* TCP Wrappers */
+#else /* ! TCP Wrappers */
+#define SLAP_STRING_UNKNOWN "unknown"
+#endif /* ! TCP Wrappers */
#ifdef LDAP_PF_LOCAL
#include <sys/stat.h>
ch_free(sal);
}
-#ifdef LDAP_PF_LOCAL
+#if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
static int get_url_perms(
char **exts,
mode_t *perms,
}
if ( strncasecmp( type, LDAPI_MOD_URLEXT "=", sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 ) {
- char *value = type + sizeof(LDAPI_MOD_URLEXT "=") - 1;
+ char *value = type
+ + ( sizeof(LDAPI_MOD_URLEXT "=") - 1 );
mode_t p = 0;
int j;
- if ( strlen(value) != 3 ) {
- return LDAP_OTHER;
- }
+ switch (strlen(value)) {
+ case 4:
+ /* skip leading '0' */
+ if ( value[ 0 ] != '0' ) {
+ return LDAP_OTHER;
+ }
+ value++;
- for ( j = 0; j < 3; j++ ) {
- static mode_t m[ 3 ]
- = { S_IRWXU, S_IRWXG, S_IRWXO };
+ case 3:
+ for ( j = 0; j < 3; j++) {
+ int v;
- switch ( value[ j ] ) {
- case 'w':
- p |= m[ j ];
- break;
- case '-':
- break;
- default:
- return LDAP_OTHER;
+ v = value[ j ] - '0';
+
+ if ( v < 0 || v > 7 ) {
+ return LDAP_OTHER;
+ }
+
+ p |= v << 3*(2-j);
+ }
+ break;
+
+ case 10:
+ for ( j = 1; j < 10; j++ ) {
+ static mode_t m[] = { 0,
+ S_IRUSR, S_IWUSR, S_IXUSR,
+ S_IRGRP, S_IWGRP, S_IXGRP,
+ S_IROTH, S_IWOTH, S_IXOTH
+ };
+ static char c[] = "-rwxrwxrwx";
+
+ if ( value[ j ] == c[ j ] ) {
+ p |= m[ j ];
+
+ } else if ( value[ j ] != '-' ) {
+ return LDAP_OTHER;
+ }
}
+ break;
+
+ default:
+ return LDAP_OTHER;
}
*crit = c;
return LDAP_OTHER;
}
-#endif /* LDAP_PF_LOCAL */
+#endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
/* port = 0 indicates AF_LOCAL */
static int slap_get_listener_addresses(
struct sockaddr **sal, **psal;
int socktype = SOCK_STREAM; /* default to COTS */
-#ifdef LDAP_PF_LOCAL
- mode_t perms = S_IRWXU;
+#if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
+ /*
+ * use safe defaults
+ */
int crit = 1;
-#endif
+#endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
rc = ldap_url_parse( url, &lud );
return rc;
}
- l.sl_url = NULL;
+ l.sl_url.bv_val = NULL;
#ifndef HAVE_TLS
if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
} else {
err = slap_get_listener_addresses(lud->lud_host, 0, &sal);
}
-
- if ( lud->lud_exts ) {
- err = get_url_perms( lud->lud_exts, &perms, &crit );
- }
#else
#ifdef NEW_LOGGING
}
}
+#if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
+ if ( lud->lud_exts ) {
+ err = get_url_perms( lud->lud_exts, &l.sl_perms, &crit );
+ } else {
+ l.sl_perms = S_IRWXU;
+ }
+#endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
+
ldap_free_urldesc( lud );
if ( err ) {
return -1;
#ifdef LDAP_PF_LOCAL
case AF_LOCAL: {
char *addr = ((struct sockaddr_un *)*sal)->sun_path;
- if ( chmod( addr, perms ) < 0 && crit ) {
+ if ( chmod( addr, l.sl_perms ) < 0 && crit ) {
int err = sock_errno();
#ifdef NEW_LOGGING
LDAP_LOG( CONNECTION, INFO,
slap_free_listener_addresses(psal);
return -1;
}
- l.sl_name = ch_malloc( strlen(addr) + sizeof("PATH=") );
- sprintf( l.sl_name, "PATH=%s", addr );
+ l.sl_name.bv_len = strlen(addr) + sizeof("PATH=") - 1;
+ l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len + 1 );
+ snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1,
+ "PATH=%s", addr );
} break;
#endif /* LDAP_PF_LOCAL */
s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr );
#endif
port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port );
- l.sl_name = ch_malloc( sizeof("IP=255.255.255.255:65535") );
- sprintf( l.sl_name, "IP=%s:%d",
- s != NULL ? s : "unknown" , port );
+ l.sl_name.bv_val = ber_memalloc( sizeof("IP=255.255.255.255:65535") );
+ snprintf( l.sl_name.bv_val, sizeof("IP=255.255.255.255:65535"),
+ "IP=%s:%d",
+ s != NULL ? s : SLAP_STRING_UNKNOWN, port );
+ l.sl_name.bv_len = strlen( l.sl_name.bv_val );
} break;
#ifdef LDAP_PF_INET6
inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr,
addr, sizeof addr);
port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
- l.sl_name = ch_malloc( strlen(addr) + sizeof("IP= 65535") );
- sprintf( l.sl_name, "IP=%s %d", addr, port );
+ l.sl_name.bv_len = strlen(addr) + sizeof("IP= 65535");
+ l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len );
+ snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=%s %d",
+ addr, port );
+ l.sl_name.bv_len = strlen( l.sl_name.bv_val );
} break;
#endif /* LDAP_PF_INET6 */
}
AC_MEMCPY(&l.sl_sa, *sal, addrlen);
- l.sl_url = ch_strdup( url );
+ ber_str2bv( url, 0, 1, &l.sl_url);
li = ch_malloc( sizeof( Listener ) );
*li = l;
slap_listeners[*cur] = li;
slap_free_listener_addresses(psal);
- if ( l.sl_url == NULL )
+ if ( l.sl_url.bv_val == NULL )
{
#ifdef NEW_LOGGING
LDAP_LOG( CONNECTION, RESULTS,
#ifdef NEW_LOGGING
LDAP_LOG( CONNECTION, RESULTS,
- "slap_open_listener: daemon initialized %s\n", l.sl_url, 0, 0 );
+ "slap_open_listener: daemon initialized %s\n",
+ l.sl_url.bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "daemon: initialized %s\n",
- l.sl_url, 0, 0 );
+ l.sl_url.bv_val, 0, 0 );
#endif
return 0;
}
#endif /* LDAP_PF_LOCAL */
slapd_close( slap_listeners[l]->sl_sd );
}
- if ( slap_listeners[l]->sl_url )
- free ( slap_listeners[l]->sl_url );
- if ( slap_listeners[l]->sl_name )
- free ( slap_listeners[l]->sl_name );
+ if ( slap_listeners[l]->sl_url.bv_val )
+ ber_memfree( slap_listeners[l]->sl_url.bv_val );
+ if ( slap_listeners[l]->sl_name.bv_val )
+ ber_memfree( slap_listeners[l]->sl_name.bv_val );
free ( slap_listeners[l] );
slap_listeners[l] = NULL;
}
#ifdef NEW_LOGGING
LDAP_LOG( CONNECTION, ERR,
"slapd_daemon_task: listen( %s, 5 ) failed errno=%d (%s)\n",
- slap_listeners[l]->sl_url, err, sock_errstr(err) );
+ slap_listeners[l]->sl_url.bv_val, err, sock_errstr(err) );
#else
Debug( LDAP_DEBUG_ANY,
"daemon: listen(%s, 5) failed errno=%d (%s)\n",
- slap_listeners[l]->sl_url, err,
+ slap_listeners[l]->sl_url.bv_val, err,
sock_errstr(err) );
#endif
return( (void*)-1 );
char *authid = NULL;
char *dnsname = NULL;
- char *peeraddr;
+ char *peeraddr = NULL;
#ifdef LDAP_PF_LOCAL
char peername[MAXPATHLEN + sizeof("PATH=")];
#elif defined(LDAP_PF_INET6)
*/
if ( slap_listeners[l]->sl_is_udp < 2 ) {
id = connection_init(
- slap_listeners[l]->sl_sd,
- slap_listeners[l]->sl_url, "", "",
- slap_listeners[l]->sl_name,
+ slap_listeners[l]->sl_sd,
+ slap_listeners[l], "", "",
2, ssf, authid );
slap_listeners[l]->sl_is_udp++;
}
peeraddr = inet_ntoa( *((struct in_addr *)
&from.sa_in6_addr.sin6_addr.s6_addr[12]) );
sprintf( peername, "IP=%s:%d",
- peeraddr != NULL ? peeraddr : "unknown",
+ peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
(unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
} else {
char addr[INET6_ADDRSTRLEN];
&from.sa_in6_addr.sin6_addr,
addr, sizeof addr );
sprintf( peername, "IP=%s %d",
- peeraddr != NULL ? peeraddr : "unknown",
+ peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
(unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
}
break;
case AF_INET:
peeraddr = inet_ntoa( from.sa_in_addr.sin_addr );
sprintf( peername, "IP=%s:%d",
- peeraddr != NULL ? peeraddr : "unknown",
+ peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
(unsigned) ntohs( from.sa_in_addr.sin_port ) );
break;
#ifdef HAVE_TCPD
if ( !hosts_ctl("slapd",
- dnsname != NULL ? dnsname : STRING_UNKNOWN,
- peeraddr != NULL ? peeraddr : STRING_UNKNOWN,
- STRING_UNKNOWN ))
+ dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
+ peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
+ SLAP_STRING_UNKNOWN ))
{
/* DENY ACCESS */
Statslog( LDAP_DEBUG_ANY,
"fd=%ld host access from %s (%s) denied.\n",
(long) s,
- dnsname != NULL ? dnsname : "unknown",
- peeraddr != NULL ? peeraddr : "unknown",
+ dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
+ peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
0, 0 );
slapd_close(s);
continue;
}
id = connection_init(s,
- slap_listeners[l]->sl_url,
- dnsname != NULL ? dnsname : "unknown",
+ slap_listeners[l],
+ dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
peername,
- slap_listeners[l]->sl_name,
#ifdef HAVE_TLS
slap_listeners[l]->sl_is_tls,
#else
if( id < 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONNECTION, INFO,
- "slapd_daemon_task: connection_init(%ld, %s, %s) failed.\n",
- (long)s, peername, slap_listeners[l]->sl_name );
+ "slapd_daemon_task: "
+ "connection_init(%ld, %s, %s) "
+ "failed.\n",
+ (long)s, peername,
+ slap_listeners[l]->sl_name.bv_val );
#else
Debug( LDAP_DEBUG_ANY,
- "daemon: connection_init(%ld, %s, %s) failed.\n",
+ "daemon: connection_init(%ld, %s, %s) "
+ "failed.\n",
(long) s,
peername,
- slap_listeners[l]->sl_name );
+ slap_listeners[l]->sl_name.bv_val );
#endif
slapd_close(s);
continue;
}
Statslog( LDAP_DEBUG_STATS,
- "daemon: conn=%ld fd=%ld connection from %s (%s) accepted.\n",
+ "daemon: conn=%ld fd=%ld connection from %s "
+ "(%s) accepted.\n",
id, (long) s,
peername,
- slap_listeners[l]->sl_name,
+ slap_listeners[l]->sl_name.bv_val,
0 );
slapd_add( s );
}
}
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+ if ( ava->aa_desc == slap_schema.si_ad_hasSubordinates
+ && be && be->be_has_subordinates ) {
+ int hasSubordinates;
+ struct berval hs;
+
+ /*
+ * No other match should be allowed ...
+ */
+ assert( type == LDAP_FILTER_EQUALITY );
+
+ if ( (*be->be_has_subordinates)( be, conn, op, e, &hasSubordinates ) ) {
+ return LDAP_OTHER;
+ }
+
+ if ( hasSubordinates == LDAP_COMPARE_TRUE ) {
+ hs.bv_val = "TRUE";
+ hs.bv_len = sizeof( "TRUE" ) - 1;
+
+ } else if ( hasSubordinates == LDAP_COMPARE_FALSE ) {
+ hs.bv_val = "FALSE";
+ hs.bv_len = sizeof( "FALSE" ) - 1;
+
+ } else {
+ return LDAP_OTHER;
+ }
+
+ if ( bvmatch( &ava->aa_value, &hs ) ) {
+ return LDAP_COMPARE_TRUE;
+ }
+
+ return LDAP_COMPARE_FALSE;
+ }
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
return( LDAP_COMPARE_FALSE );
}
AttributeDescription *desc
)
{
+ Attribute *a;
+
if ( !access_allowed( be, conn, op, e, desc, NULL, ACL_SEARCH, NULL ) )
{
return LDAP_INSUFFICIENT_ACCESS;
}
- return attrs_find( e->e_attrs, desc ) != NULL
- ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
+ a = attrs_find( e->e_attrs, desc );
+
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+ if ( a == NULL && desc == slap_schema.si_ad_hasSubordinates ) {
+
+ /*
+ * XXX: fairly optimistic: if the function is defined,
+ * then PRESENCE must succeed, because hasSubordinate
+ * is boolean-valued; I think we may live with this
+ * simplification by now
+ */
+ if ( be && be->be_has_subordinates ) {
+ return LDAP_COMPARE_TRUE;
+ }
+
+ return LDAP_COMPARE_FALSE;
+ }
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
+ return a != NULL ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
}
#elif defined(SLAPD_METAPHONE)
+/*
+ * Metaphone was originally developed by Lawrence Philips and
+ * published in the "Computer Language" magazine in 1990.
+ */
/*
* Metaphone copied from C Gazette, June/July 1991, pp 56-57,
* author Gary A. Parker, with changes by Bernard Tiffany of the
LDAP_SLAPD_F (long) connection_init LDAP_P((
ber_socket_t s,
- const char* url,
+ Listener* url,
const char* dnsname,
const char* peername,
- const char* sockname,
int use_tls,
slap_ssf_t ssf,
const char *id ));
LDAP_SLAPD_F (void) vrFilter_free LDAP_P(( ValuesReturnFilter *f ));
LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( ValuesReturnFilter *f, struct berval *fstr ));
-/*
- * define to honor hasSubordinates operational attribute in search filters
- */
-#undef SLAP_X_FILTER_HASSUBORDINATES
-
#ifdef SLAP_X_FILTER_HASSUBORDINATES
LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter ));
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
if (rc != sizeof(struct sockaddr)) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
- "send_search_entry: conn %lu ber_printf failed\n",
+ "send_search_entry: conn %lu ber_write failed\n",
conn ? conn->c_connid : 0, 0, 0 );
#else
- Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
+ Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
#endif
ber_free_buf( ber );
return( 1 );
}
if( sc == NULL ) {
- *text = "no structural object classes provided";
+ *text = "no structural object class provided";
return LDAP_OBJECT_CLASS_VIOLATION;
}
offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },
{ "entryUUID", "( 1.3.6.1.4.1.4203.666.1.6 NAME 'entryUUID' "
- "DESC 'LCUP/LDUP: universally unique identifier' "
+ "DESC 'LCUP/LDUP: UUID of the entry' "
"EQUALITY octetStringMatch "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} "
"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
NULL, NULL, NULL, NULL, NULL,
offsetof(struct slap_internal_schema, si_ad_entryUUID) },
{ "entryCSN", "( 1.3.6.1.4.1.4203.666.1.7 NAME 'entryCSN' "
- "DESC 'LCUP/LDUP: change sequence number' "
+ "DESC 'LCUP/LDUP: change sequence number of the entry' "
"EQUALITY octetStringMatch "
"ORDERING octetStringOrderingMatch "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} "
NULL, NULL, NULL, NULL, NULL,
offsetof(struct slap_internal_schema, si_ad_entryCSN) },
+ { "superiorUUID", "( 1.3.6.1.4.1.4203.666.1.11 NAME 'superiorUUID' "
+ "DESC 'LCUP/LDUP: UUID of the superior entry' "
+ "EQUALITY octetStringMatch "
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} "
+ "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
+ NULL, SLAP_AT_HIDE,
+ NULL, NULL, NULL, NULL, NULL,
+ offsetof(struct slap_internal_schema, si_ad_superiorUUID) },
+
/* root DSE attributes */
{ "altServer", "( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' "
"DESC 'RFC2252: alternative servers' "
}
return_results:;
- if( pbase.bv_val != NULL) free( pbase.bv_val );
- if( nbase.bv_val != NULL) free( nbase.bv_val );
+#ifdef LDAP_CLIENT_UPDATE
+ if ( !( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
+#endif /* LDAP_CLIENT_UPDATE */
+ {
+ if( pbase.bv_val != NULL) free( pbase.bv_val );
+ if( nbase.bv_val != NULL) free( nbase.bv_val );
- if( fstr.bv_val != NULL) free( fstr.bv_val );
- if( filter != NULL) filter_free( filter );
- if( an != NULL ) free( an );
+ if( fstr.bv_val != NULL) free( fstr.bv_val );
+ if( filter != NULL) filter_free( filter );
+ if( an != NULL ) free( an );
+ }
return rc;
}
AttributeDescription *si_ad_subschemaSubentry;
AttributeDescription *si_ad_entryUUID;
AttributeDescription *si_ad_entryCSN;
+ AttributeDescription *si_ad_superiorUUID;
/* root DSE attribute descriptions */
AttributeDescription *si_ad_altServer;
#define be_attribute bd_info->bi_acl_attribute
#define be_operational bd_info->bi_operational
+/*
+ * define to honor hasSubordinates operational attribute in search filters
+ * (in previous use there was a flaw with back-bdb and back-ldbm; now it
+ * is fixed).
+ */
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+#define be_has_subordinates bd_info->bi_has_subordinates
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
#define be_controls bd_info->bi_controls
#define be_connection_init bd_info->bi_connection_init
#define SLAP_ALLOW_BIND_V2 0x0001U /* LDAPv2 bind */
#define SLAP_ALLOW_BIND_ANON_CRED 0x0002U /* cred should be empty */
-#define SLAP_ALLOW_BIND_ANON_DN 0x0003U /* dn should be empty */
+#define SLAP_ALLOW_BIND_ANON_DN 0x0004U /* dn should be empty */
+
+#define SLAP_ALLOW_UPDATE_ANON 0x0008U /* allow anonymous updates */
#define SLAP_DISALLOW_BIND_ANON 0x0001U /* no anonymous */
#define SLAP_DISALLOW_BIND_SIMPLE 0x0002U /* simple authentication */
struct slap_conn *c, struct slap_op *o,
Entry *e, AttributeName *attrs, int opattrs, Attribute **a ));
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+typedef int (BI_has_subordinates) LDAP_P((Backend *bd,
+ struct slap_conn *c, struct slap_op *o,
+ Entry *e, int *has_subordinates ));
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
typedef int (BI_connection_init) LDAP_P((BackendDB *bd,
struct slap_conn *c));
typedef int (BI_connection_destroy) LDAP_P((BackendDB *bd,
BI_acl_attribute *bi_acl_attribute;
BI_operational *bi_operational;
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+ BI_has_subordinates *bi_has_subordinates;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
BI_connection_init *bi_connection_init;
BI_connection_destroy *bi_connection_destroy;
ID ps_id;
} PagedResultsState;
+
+#ifdef LDAP_CLIENT_UPDATE
+#define LCUP_PSEARCH_BY_ADD 0x01
+#define LCUP_PSEARCH_BY_DELETE 0x02
+#define LCUP_PSEARCH_BY_PREMODIFY 0x03
+#define LCUP_PSEARCH_BY_MODIFY 0x04
+#define LCUP_PSEARCH_BY_SCOPEOUT 0x05
+
+struct lcup_search_spec {
+ struct slap_op *op;
+ struct berval *base;
+ struct berval *nbase;
+ int scope;
+ int deref;
+ int slimit;
+ int tlimit;
+ Filter *filter;
+ struct berval *filterstr;
+ AttributeName *attrs;
+ int attrsonly;
+ struct lcup_entry *elist;
+ ldap_pvt_thread_mutex_t elist_mutex;
+ int entry_count;
+ LDAP_LIST_ENTRY(lcup_search_spec) link;
+};
+
+struct psid_entry {
+ struct lcup_search_spec* ps;
+ LDAP_LIST_ENTRY(psid_entry) link;
+};
+#endif /* LDAP_CLIENT_UPDATE */
+
+
/*
* represents an operation pending from an ldap client
*/
#define SLAP_LCUP_SYNC_AND_PERSIST (0x3)
ber_int_t o_clientupdate_interval;
struct berval o_clientupdate_state;
+ LDAP_LIST_HEAD(lss, lcup_search_spec) psearch_spec;
+ LDAP_LIST_HEAD(pe, psid_entry) premodify_list;
+ LDAP_LIST_ENTRY(slap_op) link;
#endif /* LDAP_CLIENT_UPDATE */
#ifdef LDAP_CONNECTIONLESS
char ga_ndn[1];
} GroupAssertion;
+typedef struct slap_listener Listener;
+
/*
* represents a connection from an ldap client
*/
time_t c_activitytime; /* when the connection was last used */
unsigned long c_connid; /* id of this connection for stats*/
- struct berval c_listener_url; /* listener URL */
struct berval c_peer_domain; /* DNS name of client */
struct berval c_peer_name; /* peer name (trans=addr:port) */
- struct berval c_sock_name; /* sock name (trans=addr:port) */
+ Listener *c_listener;
+#define c_listener_url c_listener->sl_url /* listener URL */
+#define c_sock_name c_listener->sl_name /* sock name (trans=addr:port) */
/* only can be changed by binding thread */
int c_sasl_bind_in_progress; /* multi-op bind in progress */
/*
* listener; need to access it from monitor backend
*/
-typedef struct slap_listener {
- char* sl_url;
- char* sl_name;
+struct slap_listener {
+ struct berval sl_url;
+ struct berval sl_name;
+ mode_t sl_perms;
#ifdef HAVE_TLS
int sl_is_tls;
#endif
ber_socket_t sl_sd;
Sockaddr sl_sa;
#define sl_addr sl_sa.sa_in_addr
-} Listener;
+};
#ifdef SLAPD_MONITOR
/*