mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
1304 lines
34 KiB
Plaintext
1304 lines
34 KiB
Plaintext
/*
|
|
* Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
|
|
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
|
*/
|
|
/*
|
|
* (C) Copyright IBM Corp. 1997,2002
|
|
* Redistribution and use in source and binary forms are permitted
|
|
* provided that this notice is preserved and that due credit is
|
|
* given to IBM Corporation. This software is provided ``as is''
|
|
* without express or implied warranty.
|
|
*/
|
|
|
|
#include "portable.h"
|
|
#include "slapi_common.h"
|
|
#include <slap.h>
|
|
#include <slapi.h>
|
|
#include <lber.h>
|
|
#include "../../../libraries/liblber/lber-int.h"
|
|
|
|
int
|
|
bvptr2obj( struct berval **bvptr,
|
|
struct berval **bvobj);
|
|
|
|
Slapi_PBlock *
|
|
slapi_simple_bind_internal( char *dn,
|
|
struct berval *cred,
|
|
int method,
|
|
int version);
|
|
|
|
|
|
Connection *
|
|
fakeConnection( char *DN,
|
|
int OpType)
|
|
{
|
|
Connection *pConn, *c;
|
|
|
|
if((pConn = (Connection *) slapi_ch_calloc(sizeof(Connection))) == NULL)
|
|
return (Connection *)NULL;
|
|
|
|
LDAP_STAILQ_INIT(&c->c_pending_ops);
|
|
LDAP_STAILQ_INIT(&c->c_ops);
|
|
|
|
if((pConn->c_pending_ops.stqh_first=(Operation *) slapi_ch_calloc(sizeof(Operation))) == NULL) {
|
|
slapi_ch_free( pConn );
|
|
return (Connection *)NULL;
|
|
}
|
|
|
|
if((pConn->c_pending_ops.stqh_first->o_pb=(Slapi_PBlock *) slapi_pblock_new()) == NULL) {
|
|
slapi_ch_free( pConn->c_pending_ops.stqh_first );
|
|
slapi_ch_free( pConn );
|
|
return (Connection *)NULL;
|
|
}
|
|
|
|
c = pConn;
|
|
|
|
c->c_ops->o_opid = 0;
|
|
c->c_ops->o_msgid = 0;
|
|
c->c_ops->o_next = NULL;
|
|
c->c_ops->o_tag = OpType;
|
|
i->c_ops->o_abandon = 0;
|
|
|
|
c->c_authmech.bv_val = NULL;
|
|
c->c_authmech.bv_len = 0;
|
|
c->c_dn.bv_val = NULL;
|
|
c->c_dn.bv_len = 0;
|
|
c->c_ndn.bv_val = NULL;
|
|
c->c_ndn.bv_len = 0;
|
|
c->c_cdn.bv_val = NULL;
|
|
c->c_cdn.bv_len = 0;
|
|
c->c_groups = NULL;
|
|
|
|
c->c_listener_url.bv_val = NULL;
|
|
c->c_listener_url.bv_len = 0;
|
|
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;
|
|
|
|
c->c_sasl_bind_mech.bv_val = NULL;
|
|
c->c_sasl_bind_mech.bv_len = 0;
|
|
c->c_sasl_context = NULL;
|
|
c->c_sasl_extra = NULL;
|
|
|
|
c->c_sb = ber_sockbuf_alloc( );
|
|
|
|
c->c_currentber = NULL;
|
|
|
|
c->c_struct_state = SLAP_C_UNUSED;
|
|
|
|
c->c_n_get = 0;
|
|
c->c_n_read = 0;
|
|
c->c_n_write = 0;
|
|
|
|
c->c_protocol = LDAP_VERSION3;
|
|
|
|
time(&pConn->c_pending_ops.stqh_first->o_time);
|
|
|
|
pConn->c_send_ldap_result_v3 = (SEND_LDAP_RESULT_V3) internal_result_v3;
|
|
pConn->c_send_search_entry = (SEND_SEARCH_ENTRY) internal_search_entry;
|
|
pConn->c_send_ldap_search_result = (SEND_LDAP_SEARCH_RESULT) internal_search_result;
|
|
pConn->c_send_ldap_result_ext = (SEND_LDAP_RESULT_EXT) internal_result_ext;
|
|
pConn->c_send_ldap_search_reference = (SEND_SEARCH_REFERENCE) internal_search_reference;
|
|
|
|
return pConn;
|
|
}
|
|
|
|
|
|
/* Function : slapi_delete_internal
|
|
*
|
|
* Description : Plugin functions call this routine to delete an entry
|
|
* in the backend directly
|
|
* Return values : LDAP_SUCCESS
|
|
* LDAP_OPERAITONS_ERROR
|
|
* LDAP_NO_MEMORY
|
|
* LDAP_OTHER
|
|
* LDAP_UNWILLING_TO_PERFORM
|
|
*/
|
|
Slapi_PBlock *
|
|
slapi_delete_internal( char *ldn,
|
|
LDAPControl **controls,
|
|
int log_change)
|
|
{
|
|
|
|
int rc=LDAP_SUCCESS;
|
|
Backend *be;
|
|
Slapi_PBlock *pPB=NULL;
|
|
Slapi_PBlock *pSavePB=NULL;
|
|
Connection *pConn=NULL;
|
|
Operation *op;
|
|
|
|
int manageDsaIt = 0;
|
|
int isCritical;
|
|
|
|
struct berval dn = { 0, NULL };
|
|
struct berval pdn = { 0, NULL };
|
|
struct berval ndn = { 0, NULL };
|
|
|
|
|
|
if ( ldn == NULL ) {
|
|
rc = LDAP_OPERATIONS_ERROR;
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
pConn = fakeConnection( NULL, LDAP_REQ_DELETE );
|
|
}
|
|
|
|
if ( pConn == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
|
|
op = (Operation *)pConn->c_pending_ops.stqh_first;
|
|
op->o_ctrls = controls;
|
|
|
|
op->o_ndn.bv_val = slapi_strdup(be->be_update_ndn.bv_val);
|
|
op->o_ndn.bv_len = be->be_update_ndn.bv_len;
|
|
pConn->c_dn.bv_val = slapi_strdup(be->be_update_ndn.bv_val);
|
|
pConn->c_dn.bv_len = be->be_update_ndn.bv_len;
|
|
}
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
dn.bv_val = slapi_strdup(ldn);
|
|
dn.bv_len = slapi_strlen(ldn);
|
|
|
|
rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
|
|
|
|
if( rc != LDAP_SUCCESS ) {
|
|
#ifdef NEW_LOGGING
|
|
LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
|
|
"do_delete: conn %d invalid dn (%s)\n",
|
|
conn->c_connid, dn.bv_val ));
|
|
#else
|
|
Debug( LDAP_DEBUG_ANY,
|
|
"do_delete: invalid dn (%s)\n", dn.bv_val, 0, 0 );
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if( ndn.bv_len == 0 ) {
|
|
#ifdef NEW_LOGGING
|
|
LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: conn %d: "
|
|
"Attempt to delete root DSE.\n", conn->c_connid ));
|
|
#else
|
|
Debug( LDAP_DEBUG_ANY, "Attempt to delete root DSE.\n", 0, 0, 0 );
|
|
#endif
|
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
|
|
|
#ifdef SLAPD_SCHEMA_DN
|
|
|
|
} else if ( strcasecmp( ndn.bv_val, SLAPD_SCHEMA_DN ) == 0 ) {
|
|
#ifdef NEW_LOGGING
|
|
LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: conn %d: "
|
|
"Attempt to delete subschema subentry.\n", conn->c_connid ));
|
|
#else
|
|
Debug( LDAP_DEBUG_ANY, "Attempt to delete subschema subentry.\n", 0, 0, 0 );
|
|
#endif
|
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
|
|
|
#endif
|
|
}
|
|
|
|
if ( rc = slapi_control_present( controls, LDAP_MANAGEDSAIT_OID, NULL, &isCritical)){
|
|
manageDsaIt = 1; /* turn off referral */
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
be = select_backend(&bv, manageDsaIt, 0);
|
|
if ( be == NULL ) rc = LDAP_PARTIAL_RESULTS;
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
rc = backend_check_referrals( be, conn, op, &pdn, &ndn );
|
|
}
|
|
|
|
suffix_alias( be, &ndn );
|
|
|
|
if ( be->be_delete ) {
|
|
/* do the update here */
|
|
int repl_user = be_isupdate( be, &op->o_ndn );
|
|
#ifndef SLAPD_MULTIMASTER
|
|
if ( !be->be_update_ndn.bv_len || repl_user )
|
|
#endif
|
|
{
|
|
if ( (*be->be_delete)( be, conn, op, &pdn, &ndn ) == 0 ) {
|
|
#ifdef SLAPD_MULTIMASTER
|
|
if ( !be->be_update_ndn.bv_len || !repl_user )
|
|
#endif
|
|
{
|
|
if (log_change) replog( be, op, &pdn, &ndn, NULL );
|
|
}
|
|
}
|
|
#ifndef SLAPD_MULTIMASTER
|
|
} else {
|
|
rc = LDAP_REFERRAL;
|
|
#endif
|
|
}
|
|
} else {
|
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
|
}
|
|
|
|
if ( pPB != NULL ) {
|
|
slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
|
|
}
|
|
if ( pConn != NULL ) {
|
|
if ( pConn->c_dn.bv_val )
|
|
slapi_ch_free( pConn->c_dn.bv_val );
|
|
if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
|
|
slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val );
|
|
if ( pConn->c_pending_ops.stqh_first )
|
|
slapi_ch_free( pConn->c_pending_ops.stqh_first );
|
|
if (dn.bv_val)
|
|
slapi_ch_free(dn.bv_val);
|
|
if (pdn.bv_val)
|
|
slapi_ch_free(pdn.bv_val);
|
|
if (ndn.bv_val)
|
|
slapi_ch_free(ndn_bv.val);
|
|
pSavePB = pPB;
|
|
free( pConn );
|
|
}
|
|
return( pSavePB );
|
|
}
|
|
|
|
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
|
|
|
|
int
|
|
internal_result_v3( Connection *conn,
|
|
Operation *op,
|
|
int err,
|
|
char *matched,
|
|
char *text,
|
|
char **referrals)
|
|
{
|
|
return LDAP_SUCCESS;
|
|
}
|
|
|
|
int
|
|
internal_result_ext( Connection *conn,
|
|
Operation *op,
|
|
int errnum,
|
|
char *respname,
|
|
struct berval *response )
|
|
{
|
|
return LDAP_SUCCESS;
|
|
}
|
|
|
|
int
|
|
internal_search_reference( Connection *conn,
|
|
Operation *op,
|
|
char **ref)
|
|
{
|
|
return LDAP_SUCCESS;
|
|
}
|
|
|
|
int
|
|
internal_search_result( Connection *conn,
|
|
Operation *op,
|
|
int err,
|
|
char *matched,
|
|
char *text,
|
|
int nentries)
|
|
{
|
|
slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_NENTRIES,(void *)nentries);
|
|
return LDAP_SUCCESS;
|
|
}
|
|
|
|
|
|
int
|
|
internal_search_entry( Backend *be,
|
|
Connection *conn,
|
|
Operation *op,
|
|
Entry *e,
|
|
char **attrs,
|
|
int attrsonly,
|
|
char **denied_attrs)
|
|
{
|
|
char *ent2str = NULL;
|
|
int nentries = 0, len = 0, i = 0;
|
|
Slapi_Entry **head = NULL, **tp;
|
|
|
|
if((ent2str=slapi_entry2str(e,&len)) == NULL) {
|
|
return SLAPD_NO_MEMORY;
|
|
}
|
|
|
|
slapi_pblock_get((Slapi_PBlock *)op->o_pb, SLAPI_NENTRIES, &nentries);
|
|
slapi_pblock_get((Slapi_PBlock *)op->o_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head);
|
|
i=nentries + 1;
|
|
if(nentries == 0 ) {
|
|
if((tp=(Slapi_Entry **)slapi_ch_malloc(2 * sizeof(Slapi_Entry *))) == NULL) {
|
|
return SLAPD_NO_MEMORY;
|
|
}
|
|
if((tp[0]=(Slapi_Entry *)str2entry(ent2str)) == NULL) {
|
|
return SLAPD_NO_MEMORY;
|
|
}
|
|
} else {
|
|
if((tp=(Slapi_Entry **)slapi_ch_realloc((char *)head,
|
|
(sizeof(Slapi_Entry *) * (i+1)))) == NULL) {
|
|
return SLAPD_NO_MEMORY;
|
|
}
|
|
if((tp[i-1]=(Slapi_Entry *)str2entry(ent2str)) == NULL) {
|
|
return SLAPD_NO_MEMORY;
|
|
}
|
|
}
|
|
tp[i] = NULL;
|
|
|
|
slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,(void *)tp);
|
|
slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_NENTRIES,(void *)i);
|
|
slapi_ch_free(ent2str);
|
|
return LDAP_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* Function : freeModList
|
|
* Free a list of LDAPMod structures which has the bvalue defined.
|
|
*/
|
|
static void
|
|
freeModList( LDAPMod *pMod )
|
|
{
|
|
LDAPMod *pNextMod;
|
|
|
|
while ( pMod != NULL ) {
|
|
pNextMod = pMod->mod_next;
|
|
free( pMod->mod_type );
|
|
ber_bvecfree( pMod->mod_bvalues );
|
|
free( pMod );
|
|
pMod = pNextMod;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Function : duplicateBVMod
|
|
* Duplicate a LDAPMod structure in which the bervals are defined.
|
|
* return code : LDAP_SUCEESS,
|
|
* LDAP_OTHER,
|
|
* LDAP_NO_MEMORY
|
|
*/
|
|
|
|
int
|
|
duplicateBVMod( LDAPMod *pMod,
|
|
LDAPMod **ppNewMod )
|
|
{
|
|
int rc = LDAP_SUCCESS;
|
|
int i;
|
|
struct berval **ppNewBV;
|
|
struct berval *pNewBV;
|
|
|
|
if ( pMod == NULL ) {
|
|
rc = LDAP_OTHER;
|
|
} else {
|
|
*ppNewMod = (LDAPMod *)slapi_ch_malloc(sizeof(LDAPMod));
|
|
if ( *ppNewMod == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
memset( (*ppNewMod),'\0',sizeof(LDAPMod) );
|
|
(*ppNewMod)->mod_op = pMod->mod_op;
|
|
(*ppNewMod)->mod_type = slapi_ch_strdup( pMod->mod_type);
|
|
if ( (*ppNewMod)->mod_type == NULL) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
if ( pMod->mod_bvalues == NULL ) {
|
|
(*ppNewMod)->mod_values = NULL;
|
|
} else {
|
|
for ( i=0; pMod->mod_bvalues[i] != NULL; i++ ) {
|
|
;
|
|
}
|
|
ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*sizeof(struct berval *));
|
|
if ( ppNewBV == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
for ( i=0; pMod->mod_bvalues[i] != NULL &&
|
|
rc == LDAP_SUCCESS; i++ ) {
|
|
pNewBV = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
|
|
if ( pNewBV == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
pNewBV->bv_val = slapi_ch_malloc(pMod->mod_bvalues[i]->bv_len+1);
|
|
if ( pNewBV->bv_val == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
memset(pNewBV->bv_val,'\0',pMod->mod_bvalues[i]->bv_len+1);
|
|
pNewBV->bv_len = pMod->mod_bvalues[i]->bv_len;
|
|
memcpy(pNewBV->bv_val,pMod->mod_bvalues[i]->bv_val,pNewBV->bv_len);
|
|
ppNewBV[i] = pNewBV;
|
|
}
|
|
}
|
|
} /* for each bvalue */
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
ppNewBV[i] = NULL;
|
|
(*ppNewMod)->mod_bvalues = ppNewBV;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return( rc );
|
|
}
|
|
|
|
/*
|
|
* Function : ValuestoBValues
|
|
* Convert an array of char ptrs to an array of berval ptrs.
|
|
* return value : LDAP_SUCCESS
|
|
* LDAP_NO_MEMORY
|
|
* LDAP_OTHER
|
|
*/
|
|
static int
|
|
ValuesToBValues( char **ppValue,
|
|
struct berval ***pppBV )
|
|
{
|
|
int rc = LDAP_SUCCESS;
|
|
int i;
|
|
struct berval *pTmpBV;
|
|
struct berval **ppNewBV;
|
|
|
|
/* count the number of char ptrs. */
|
|
for ( i=0; ppValue != NULL && ppValue[i] != NULL; i++ ) {
|
|
; /* NULL */
|
|
}
|
|
|
|
if ( i == 0 ) {
|
|
rc = LDAP_OTHER;
|
|
} else {
|
|
*pppBV = ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*(sizeof(struct berval *)) );
|
|
if ( *pppBV == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
while ( ppValue != NULL && *ppValue != NULL && rc == LDAP_SUCCESS ) {
|
|
pTmpBV = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
|
|
if ( pTmpBV == NULL) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
pTmpBV->bv_val = slapi_ch_strdup(*ppValue);
|
|
if ( pTmpBV->bv_val == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
pTmpBV->bv_len = strlen(*ppValue);
|
|
*ppNewBV = pTmpBV;
|
|
ppNewBV++;
|
|
}
|
|
ppValue++;
|
|
}
|
|
}
|
|
/* null terminate the array of berval ptrs */
|
|
*ppNewBV = NULL;
|
|
}
|
|
}
|
|
return( rc );
|
|
}
|
|
|
|
|
|
/*
|
|
* Function : LDAPModToEntry
|
|
* convert a dn plus an array of LDAPMod struct ptrs to an entry structure
|
|
* with a link list of the correspondent attributes.
|
|
* Return value : LDAP_SUCCESS
|
|
* LDAP_NO_MEMORY
|
|
* LDAP_OTHER
|
|
*/
|
|
Entry *
|
|
LDAPModToEntry( char *ldn,
|
|
LDAPMod **mods )
|
|
{
|
|
int rc=LDAP_SUCCESS;
|
|
LDAPMod *pMod;
|
|
Entry *pEntry=NULL;
|
|
int i,j;
|
|
struct berval **ppSaveBV;
|
|
struct berval **ppBV;
|
|
struct berval *pTmpBV;
|
|
char **ppValue;
|
|
|
|
|
|
AttributeDescription *ad;
|
|
struct berval *bv;
|
|
const char *text;
|
|
|
|
Modifications *modlist = NULL;
|
|
Modifications **modtail = &modlist;
|
|
Modifications tmp;
|
|
|
|
struct berval dn = { 0, NULL };
|
|
|
|
dn.ber_val = slapi_ch_strdup(ldn);
|
|
dn.ber_len = slapi_ch_strlen(ldn);
|
|
|
|
pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );
|
|
if ( pEntry == NULL) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
rc = dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
|
|
if( rc != LDAP_SUCCESS ) {
|
|
#ifdef NEW_LOGGING
|
|
LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
|
|
"LDAPModToEntry: invalid dn (%s)\n", dn.bv_val ));
|
|
#else
|
|
Debug( LDAP_DEBUG_ANY, "LDAPModToEntry: invalid dn (%s)\n", dn.bv_val, 0, 0 );
|
|
#endif
|
|
rc = LDAP_INVALID_DN_SYNTAX;
|
|
}
|
|
}
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {
|
|
Modifications *mod;
|
|
if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
|
|
/* attr values are in berval format */
|
|
/* convert an array of pointers to bervals to an array of bervals */
|
|
rc = bvptr2obj(pMod->mod_bvalues, &bv);
|
|
if (rc != LDAP_SUCCESS) break;
|
|
tmp.sml_type = pMod->mod_type;
|
|
tmp.sml_bvalues = bv;
|
|
|
|
mod = (Modifications *) ch_malloc( sizeof(Modifications) );
|
|
|
|
mod->sml_op = LDAP_MOD_ADD;
|
|
mod->sml_next = NULL;
|
|
mod->sml_desc = NULL;
|
|
mod->sml_type = tmp.sml_type;
|
|
mod->sml_bvalues = tmp.sml_bvalues;
|
|
|
|
*modtail = mod;
|
|
modtail = &mod->sml_next;
|
|
|
|
} else {
|
|
/* attr values are in string format, need to be converted */
|
|
/* to an array of bervals */
|
|
if ( pMod->mod_values == NULL ) {
|
|
rc = LDAP_OTHER;
|
|
} else {
|
|
rc = ValuesToBValues( pMod->mod_values, &ppBV );
|
|
if (rc != LDAP_SUCCESS) break;
|
|
rc = bvptr2obj(ppBV, &bv);
|
|
if (rc != LDAP_SUCCESS) break;
|
|
tmp.sml_type = pMod->mod_type;
|
|
tmp.sml_bvalues = bv;
|
|
|
|
mod = (Modifications *) ch_malloc( sizeof(Modifications) );
|
|
|
|
mod->sml_op = LDAP_MOD_ADD;
|
|
mod->sml_next = NULL;
|
|
mod->sml_desc = NULL;
|
|
mod->sml_type = tmp.sml_type;
|
|
mod->sml_bvalues = tmp.sml_bvalues;
|
|
|
|
*modtail = mod;
|
|
modtail = &mod->sml_next;
|
|
|
|
|
|
if ( ppBV != NULL ) {
|
|
ber_bvecfree( ppBV );
|
|
}
|
|
}
|
|
}
|
|
} /* for each LDAPMod */
|
|
}
|
|
|
|
if( e->e_nname.bv_len == 0 )
|
|
rc = LDAP_ALREADY_EXISTS;
|
|
|
|
/* check if ManageDsaIt control is set */
|
|
if ( rc = slapi_control_present( controls, LDAP_MANAGEDSAIT_OID, NULL, &isCritical)){
|
|
manageDsaIt = 1; /* turn off referral */
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
be = select_backend(&bv, manageDsaIt, 0);
|
|
if ( be == NULL ) rc = LDAP_PARTIAL_RESULTS;
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
rc = backend_check_referrals( be, conn, op, &pdn, &ndn );
|
|
}
|
|
|
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
|
if ( pEntry != NULL ) {
|
|
slapi_entry_free( pEntry );
|
|
}
|
|
pEntry = NULL;
|
|
}
|
|
return( pEntry );
|
|
}
|
|
|
|
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
|
|
|
|
Slapi_PBlock *
|
|
slapi_add_entry_internal( Slapi_Entry *e,
|
|
LDAPControl **controls,
|
|
int log_changes)
|
|
{
|
|
int rc=LDAP_SUCCESS, i;
|
|
Backend *be;
|
|
Connection *pConn=NULL;
|
|
Operation *op;
|
|
Slapi_PBlock *pPB=NULL, *pSavePB=NULL;
|
|
char *pDn=NULL;
|
|
int manageDsaIt = 0; /* referral is on */
|
|
int isCritical;
|
|
struct berval bv;
|
|
|
|
/* check if ManageDsaIt control is set */
|
|
if (slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical)) {
|
|
manageDsaIt = 1; /* turn off referral */
|
|
}
|
|
|
|
pConn = fakeConnection(NULL, LDAP_REQ_ADD);
|
|
if ( pConn == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
|
|
if (e == NULL) {
|
|
rc = LDAP_OPERATIONS_ERROR;
|
|
} else {
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
be = select_backend(&e->e_nname, manageDsaIt, 0);
|
|
if ( be == NULL ) {
|
|
rc = LDAP_PARTIAL_RESULTS;
|
|
} else if ( be->be_add == NULL) {
|
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
|
} else {
|
|
op = (Operation *)pConn->c_pending_ops.stqh_first;
|
|
op->o_ctrls = controls;
|
|
rc = (*be->be_add)( be, pConn, op, e );
|
|
if (rc == LDAP_SUCCESS)
|
|
Debug (LDAP_DEBUG_TRACE, " backend routine successful \n", 0, 0, 0);
|
|
else
|
|
Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ( pPB != NULL )
|
|
slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
|
|
if ( pDn != NULL )
|
|
slapi_ch_free( pDn );
|
|
if (bv.bv_val != NULL)
|
|
slapi_ch_free(bv.bv_val);
|
|
if ( pConn != NULL ) {
|
|
if ( pConn->c_dn.bv_val )
|
|
slapi_ch_free( pConn->c_dn.bv_val );
|
|
if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
|
|
slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val );
|
|
if ( pConn->c_pending_ops.stqh_first )
|
|
slapi_ch_free( pConn->c_pending_ops.stqh_first);
|
|
if (pConn->c_original_dn)
|
|
slapi_ch_free(pConn->c_original_dn);
|
|
pSavePB = pPB;
|
|
free( pConn );
|
|
}
|
|
return( pSavePB );
|
|
}
|
|
|
|
|
|
|
|
Slapi_PBlock *
|
|
slapi_add_internal( char *dn,
|
|
LDAPMod **mods,
|
|
LDAPControl **controls,
|
|
int log_changes )
|
|
{
|
|
LDAPMod *pMod=NULL;
|
|
Slapi_PBlock *pb=NULL;
|
|
Entry *pEntry=NULL;
|
|
int i, rc=LDAP_SUCCESS;
|
|
|
|
|
|
if(mods == NULL || *mods == NULL || dn == NULL || *dn == NULL)
|
|
rc = LDAP_OPERATIONS_ERROR ;
|
|
|
|
if (rc == LDAP_SUCCESS) {
|
|
for (i=0, pMod=mods[0]; pMod != NULL; pMod=mods[++i] ) {
|
|
if ((pMod->mod_op & ~LDAP_MOD_BVALUES) != LDAP_MOD_ADD) {
|
|
rc = LDAP_OTHER;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {
|
|
rc = LDAP_OTHER;
|
|
}
|
|
}
|
|
|
|
if(rc != LDAP_SUCCESS) {
|
|
pb = slapi_pblock_new();
|
|
slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
|
|
} else {
|
|
pb = slapi_add_entry_internal(pEntry, controls, log_changes);
|
|
}
|
|
|
|
if(pEntry)
|
|
slapi_entry_free(pEntry);
|
|
|
|
return(pb);
|
|
}
|
|
|
|
|
|
/*dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd*/
|
|
/* Function : slapi_modify_internal
|
|
*
|
|
* Description : Plugin functions call this routine to modify an entry in the backend directly
|
|
* Return values : LDAP_SUCCESS
|
|
* LDAP_OPERAITONS_ERROR
|
|
* LDAP_NO_MEMORY
|
|
* LDAP_OTHER
|
|
* LDAP_UNWILLING_TO_PERFORM
|
|
*/
|
|
Slapi_PBlock *
|
|
slapi_modify_internal( char *dn, LDAPMod **mods, LDAPControl **controls, int log_change)
|
|
{
|
|
int rc=LDAP_SUCCESS;
|
|
int i;
|
|
int dnBadChar;
|
|
LDAPMod *pMod;
|
|
LDAPMod *pNewMod;
|
|
LDAPMod *pTmpMod;
|
|
LDAPMod *pSaveMod;
|
|
LDAPMod *pModList=NULL;
|
|
Backend *be;
|
|
Slapi_PBlock *pPB=NULL;
|
|
Slapi_PBlock *pSavePB=NULL;
|
|
Connection *pConn=NULL;
|
|
|
|
int manageDsaIt = 0;
|
|
int isCritical;
|
|
struct berval bv;
|
|
struct berval *pbv;
|
|
AttributeDescription *ad;
|
|
const char *text;
|
|
Operation *op;
|
|
Modifications *modlist = NULL;
|
|
Modifications **modtail = &modlist;
|
|
struct berval pdn = { 0, NULL };
|
|
struct berval ndn = { 0, NULL };
|
|
|
|
|
|
|
|
pConn = fakeConnection( NULL, LDAP_REQ_MODIFY );
|
|
if ( pConn == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
|
|
if ( dn == NULL || mods == NULL || *mods == NULL ) {
|
|
rc = LDAP_OPERATIONS_ERROR;
|
|
}
|
|
}
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
dn_normalize( dn );
|
|
|
|
Debug(LDAP_DEBUG_TRACE,"slapi modifying object %s.\n", dn, 0, 0);
|
|
rc = dn_check(dn, &dnBadChar);
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
|
|
/* We could be serving multiple database backends. Select the
|
|
* appropriate one, or send a referral to our "referral server"
|
|
* if we don't hold it.
|
|
*/
|
|
|
|
/* check if ManageDsaIt control is set */
|
|
if ( slapi_control_present( controls,
|
|
LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
|
|
manageDsaIt = 1; /* turn off referral */
|
|
}
|
|
bv.bv_val = strdup(dn);
|
|
bv.bv_len = strlen(dn);
|
|
be = select_backend(&bv, manageDsaIt, 0);
|
|
if ( be == NULL ) {
|
|
rc = LDAP_PARTIAL_RESULTS;
|
|
} else if ( be->be_modify == NULL ) {
|
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
|
}
|
|
}
|
|
}
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
for ( i=0, pMod=mods[0]; pMod != NULL; pMod=mods[++i] ) {
|
|
if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
|
|
/* attr values are in berval format, merge them with the Entry's attr list */
|
|
rc = duplicateBVMod( pMod, &pNewMod );
|
|
} else {
|
|
pNewMod = (LDAPMod *)slapi_ch_malloc(sizeof(LDAPMod));
|
|
if ( pNewMod == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
memset( pNewMod, '\0', sizeof(LDAPMod) );
|
|
pNewMod->mod_op = pMod->mod_op | LDAP_MOD_BVALUES;
|
|
pNewMod->mod_type = slapi_ch_strdup( pMod->mod_type );
|
|
if ( pNewMod->mod_type == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE ) {
|
|
rc = ValuesToBValues( pMod->mod_values, &(pNewMod->mod_bvalues) );
|
|
} else {
|
|
if ( pMod->mod_values == NULL ) {
|
|
Debug(LDAP_DEBUG_TRACE,
|
|
"slapi_modify_internal:mod_values is null\n",0, 0, 0);
|
|
rc = LDAP_OTHER;
|
|
} else {
|
|
rc = ValuesToBValues( pMod->mod_values,
|
|
&(pNewMod->mod_bvalues) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
/* add the new mod to the end of mod list */
|
|
if ( pModList == NULL ) {
|
|
pModList = pNewMod;
|
|
} else {
|
|
pTmpMod = pModList;
|
|
while ( pTmpMod != NULL ) {
|
|
pSaveMod = pTmpMod;
|
|
pTmpMod = pTmpMod->mod_next;
|
|
}
|
|
pSaveMod->mod_next = pNewMod;
|
|
}
|
|
}
|
|
} /* for each LDAPMod */
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
/* convert LDAPModList to Modification list */
|
|
pTmpMod = pModList;
|
|
while (pTmpMod != NULL) {
|
|
Modifications *mod;
|
|
mod = (Modifications *) ch_malloc( sizeof(Modifications) );
|
|
mod->sml_type.bv_val = ch_strdup(pTmpMod->mod_type);
|
|
mod->sml_type.bv_len = strlen(pTmpMod->mod_type);
|
|
mod->sml_op = pTmpMod->mod_op;
|
|
pbv = NULL;
|
|
rc = bvptr2obj(pTmpMod->mod_bvalues, &pbv);
|
|
mod->sml_bvalues = pbv;
|
|
ad = NULL;
|
|
rc = slap_str2ad(pTmpMod->mod_type, &ad, &text );
|
|
mod->sml_desc = ad;
|
|
*modtail = mod;
|
|
modtail = &mod->sml_next;
|
|
pTmpMod = pTmpMod->mod_next;
|
|
}
|
|
*modtail = NULL;
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
op = (Operation *)pConn->c_pending_ops.stqh_first;
|
|
op->o_ctrls = controls;
|
|
Debug (LDAP_DEBUG_TRACE, "Calling backend routine \n", 0, 0, 0);
|
|
pdn.bv_val = ch_strdup(dn);
|
|
pdn.bv_len = strlen(dn);
|
|
ndn.bv_val = ch_strdup(dn);
|
|
ndn.bv_len = strlen(dn);
|
|
rc = (*be->be_modify)( be, pConn, op, &pdn, &ndn, modlist );
|
|
if (rc == LDAP_SUCCESS)
|
|
Debug (LDAP_DEBUG_TRACE, " backend routine successful \n", 0, 0, 0);
|
|
else
|
|
Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
|
|
|
|
} else {
|
|
rc = LDAP_OPERATIONS_ERROR;
|
|
}
|
|
|
|
if ( pPB != NULL ) {
|
|
slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
|
|
}
|
|
if (pModList != NULL) {
|
|
freeModList( pModList );
|
|
}
|
|
if ( pConn != NULL ) {
|
|
if ( pConn->c_dn.bv_val )
|
|
slapi_ch_free( pConn->c_dn.bv_val );
|
|
if ( pConn->c_original_dn )
|
|
slapi_ch_free( pConn->c_original_dn );
|
|
if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
|
|
slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val);
|
|
if ( pConn->c_pending_ops.stqh_first )
|
|
slapi_ch_free( pConn->c_pending_ops.stqh_first );
|
|
pSavePB = pPB;
|
|
free( pConn );
|
|
}
|
|
return( pSavePB );
|
|
}
|
|
|
|
|
|
/* Function : slapi_modrdn_internal
|
|
*
|
|
* Description : Plugin functions call this routine to modify the rdn
|
|
* of an entry in the backend directly
|
|
* Return values : LDAP_SUCCESS
|
|
* LDAP_OPERAITONS_ERROR
|
|
* LDAP_NO_MEMORY
|
|
* LDAP_OTHER
|
|
* LDAP_UNWILLING_TO_PERFORM
|
|
*/
|
|
Slapi_PBlock *
|
|
slapi_modrdn_internal( char *olddn,
|
|
char *newrdn,
|
|
int deloldrdn,
|
|
LDAPControl **controls,
|
|
int log_change)
|
|
{
|
|
|
|
int rc=LDAP_SUCCESS;
|
|
int dnBadChar;
|
|
Backend *be;
|
|
char *pDn=NULL;
|
|
Slapi_PBlock *pPB=NULL;
|
|
Slapi_PBlock *pSavePB=NULL;
|
|
Connection *pConn=NULL;
|
|
|
|
int manageDsaIt = 0;
|
|
int isCritical;
|
|
struct berval bv = { 0, NULL };
|
|
Operation *op;
|
|
|
|
struct berval dn = { 0, NULL };
|
|
struct berval ndn = { 0, NULL };
|
|
struct berval pdn = { 0, NULL };
|
|
|
|
struct berval newrdnO = { 0, NULL };
|
|
struct berval nnewrdnO = { 0, NULL };
|
|
struct berval pnewrdnO = { 0, NULL };
|
|
|
|
struct berval *nnewS = NULL;
|
|
struct berval *pnewS = NULL;
|
|
|
|
|
|
dn.bv_val = ch_strdup(olddn);
|
|
if (dn.bv_val == NULL) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
dn.bv_len = strlen(olddn);
|
|
}
|
|
|
|
if (rc == LDAP_SUCCESS) {
|
|
newrdnO.bv_val = ch_strdup(newrdn);
|
|
if (newrdnO.bv_val == NULL) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
newrdnO.bv_len = strlen(newrdn);
|
|
}
|
|
}
|
|
|
|
if (rc == LDAP_SUCCESS) {
|
|
rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
|
|
}
|
|
|
|
if (rc == LDAP_SUCCESS) {
|
|
rc = dnPrettyNormal( NULL, &newrdnO, &pnewrdnO, &nnewrdnO );
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
pConn = fakeConnection(NULL, LDAP_REQ_MODRDN );
|
|
}
|
|
|
|
if ( pConn == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
|
|
if ( olddn == NULL || newrdn == NULL ) {
|
|
rc = LDAP_OPERATIONS_ERROR;
|
|
}
|
|
}
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
Debug(LDAP_DEBUG_TRACE,"slapi modify rdn %s new RDN: %s.\n", olddn, newrdn, 0);
|
|
rc = dn_check(olddn, &dnBadChar);
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
|
|
/* We could be serving multiple database backends. Select the
|
|
* appropriate one, or send a referral to our "referral server"
|
|
* if we don't hold it. */
|
|
|
|
op = (Operation *)pConn->c_pending_ops.stqh_first;
|
|
op->o_ctrls = controls;
|
|
|
|
/* check if ManageDsaIt control is set */
|
|
if ( slapi_control_present( controls,
|
|
LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
|
|
manageDsaIt = 1; /* turn off referral */
|
|
}
|
|
be = select_backend(&bv, manageDsaIt, 0);
|
|
if ( be == NULL ) {
|
|
rc = LDAP_PARTIAL_RESULTS;
|
|
}
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
if ( be->be_modrdn == NULL ) {
|
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
|
} else {
|
|
Debug (LDAP_DEBUG_TRACE, "Calling backend routine \n", 0, 0, 0);
|
|
rc = (*be->be_modrdn)( be, pConn, op, &pdn, &ndn,
|
|
&pnewrdnO, &nnewrdnO, deloldrdn, pnewS, nnewS );
|
|
if (rc == LDAP_SUCCESS)
|
|
Debug (LDAP_DEBUG_TRACE, " backend routine successful \n", 0, 0, 0);
|
|
else
|
|
Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
if (dn.bv_val)
|
|
ch_free(dn.bv_val);
|
|
if (pdn.bv_val)
|
|
ch_free(pdn.bv_val);
|
|
if (ndn.bv_val)
|
|
ch_free(ndn.bv_val);
|
|
if (newrdnO.bv_val)
|
|
ch_free(newrdnO.bv_val);
|
|
if (pnewrdnO.bv_val)
|
|
ch_free(newrdnO.bv_val);
|
|
if (nnewrdnO.bv_val)
|
|
ch_free(newrdnO.bv_val);
|
|
|
|
if ( pPB != NULL ) {
|
|
slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
|
|
}
|
|
if ( pConn != NULL ) {
|
|
if ( pConn->c_dn.bv_val )
|
|
slapi_ch_free( pConn->c_dn.bv_val );
|
|
if (pConn->c_original_dn)
|
|
slapi_ch_free(pConn->c_original_dn);
|
|
if ( pConn->c_pending_ops.stqh_first->o_dn.bv_val )
|
|
slapi_ch_free( pConn->c_pending_ops.stqh_first->o_dn.bv_val );
|
|
if ( pConn->c_pending_ops.stqh_first )
|
|
slapi_ch_free( pConn->c_pending_ops.stqh_first );
|
|
pSavePB = pPB;
|
|
free( pConn );
|
|
}
|
|
return( pSavePB );
|
|
}
|
|
|
|
Slapi_PBlock *
|
|
slapi_search_internal( char *base, int scope, char *filStr,
|
|
LDAPControl **controls, char **attrs, int attrsonly )
|
|
{
|
|
return slapi_search_internal_bind(NULL,base,scope,filStr,controls, attrs,attrsonly);
|
|
}
|
|
|
|
Slapi_PBlock *
|
|
slapi_search_internal_bind( char *bindDN, char *b, int scope, char *filStr,
|
|
LDAPControl **controls, char **attrs, int attrsonly )
|
|
{
|
|
Slapi_PBlock *ptr;
|
|
Connection *c;
|
|
Backend *be;
|
|
Filter *filter=NULL;
|
|
int i, deref=0, sizelimit=-1, timelimit=-1, rc, dnCheckJunk=0;
|
|
int manageDsaIt = 0;
|
|
int isCritical;
|
|
struct berval bv;
|
|
Operation *op;
|
|
|
|
struct berval base = { 0, NULL };
|
|
struct berval pbase = { 0, NULL };
|
|
struct berval nbase = { 0, NULL };
|
|
AttributeName *an;
|
|
const char *text;
|
|
struct berval fstr = { 0, NULL };
|
|
|
|
|
|
|
|
c=fakeConnection(bindDN,LDAP_REQ_SEARCH);
|
|
|
|
if ( c == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
ptr = (Slapi_PBlock *)c->c_pending_ops.stqh_first->o_pb;
|
|
}
|
|
|
|
/* check if ManageDsaIt control is set */
|
|
if ( rc = slapi_control_present( controls,
|
|
LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
|
|
manageDsaIt = 1; /* turn off referral */
|
|
}
|
|
if ( scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL
|
|
&& scope != LDAP_SCOPE_SUBTREE ) {
|
|
slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PROTOCOL_ERROR);
|
|
return ptr;
|
|
}
|
|
|
|
dn_normalize( b );
|
|
rc=dn_check(b, &dnCheckJunk);
|
|
if(rc != LDAP_SUCCESS) {
|
|
slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)rc);
|
|
return ptr;
|
|
}
|
|
|
|
if ( attrs != NULL ) {
|
|
for ( i = 0; attrs[i] != NULL; i++ )
|
|
attr_normalize( attrs[i] );
|
|
}
|
|
if((filter=slapi_str2filter(filStr)) == NULL) {
|
|
slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PROTOCOL_ERROR);
|
|
return ptr;
|
|
}
|
|
bv.bv_val = ch_strdup(b);
|
|
bv.bv_len = strlen(b);
|
|
/* check if ManageDsaIt control is set */
|
|
if ( slapi_control_present( controls,
|
|
LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
|
|
manageDsaIt = 1; /* turn off referral */
|
|
}
|
|
|
|
if ((be = select_backend( &bv, manageDsaIt, 0 )) == NULL) {
|
|
if ( manageDsaIt == 1 ) { /* referral turned off */
|
|
slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_NO_SUCH_OBJECT);
|
|
} else {
|
|
slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PARTIAL_RESULTS);
|
|
}
|
|
return ptr;
|
|
} else if ( be->be_search == NULL ) {
|
|
slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_UNWILLING_TO_PERFORM);
|
|
return ptr;
|
|
} else {
|
|
|
|
base.bv_val = ch_strdup(b);
|
|
base.bv_len = strlen(b);
|
|
rc = dnPrettyNormal( NULL, &base, &pbase, &nbase );
|
|
for (i = 0; attrs[i] != 0; i++) {
|
|
an[i].an_desc = NULL;
|
|
an[i].an_name.bv_val = ch_strdup(attrs[i]);
|
|
an[i].an_name.bv_len = strlen(attrs[i]);
|
|
slap_bv2ad(&an[i].an_name, &an[i].an_desc, &text);
|
|
}
|
|
fstr.bv_val = ch_strdup(filStr);
|
|
fstr.bv_len = strlen(filStr);
|
|
rc = (*be->be_search)( be, c, op, &pbase, &nbase, scope, deref,
|
|
sizelimit, timelimit, filter, &fstr, an, attrsonly );
|
|
}
|
|
slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)rc);
|
|
if ( c->c_pending_ops.stqh_first ){
|
|
if(c->c_dn.bv_val)
|
|
slapi_ch_free(c->c_dn.bv_val);
|
|
if (c->c_original_dn)
|
|
slapi_ch_free(c->c_original_dn);
|
|
if(c->c_pending_ops.stqh_first->o_dn.bv_val)
|
|
slapi_ch_free(c->c_pending_ops.stqh_first->o_dn.bv_val);
|
|
slapi_ch_free( c->c_pending_ops.stqh_first );
|
|
}
|
|
slapi_ch_free((void **)c);
|
|
if (filter)
|
|
slapi_filter_free(filter,1);
|
|
return ptr;
|
|
}
|
|
|
|
/*
|
|
Function : slapi_get_supported_extended_ops
|
|
Description : This function returns a pointer points to an array of Null terminated char pointers.
|
|
Each char pointer points to an oid of an extended operation.
|
|
If there is no defined extended operaitons, this routine returns NULL.
|
|
Input : none
|
|
Output : pointer to an null terminated char pointer array or null.
|
|
Notes: The caller of this routine needs to free the retuned array pointer, but
|
|
should not free the pointers inside the array.
|
|
*/
|
|
char
|
|
**slapi_get_supported_extended_ops(void)
|
|
{
|
|
|
|
ExtendedOp *pTmpExtOp;
|
|
int numExtOps = 0;
|
|
int i=0;
|
|
char **ppExtOpOID = NULL;
|
|
|
|
if ( pGExtendedOps != NULL ) {
|
|
pTmpExtOp = pGExtendedOps;
|
|
while ( pTmpExtOp != NULL ) {
|
|
numExtOps++;
|
|
pTmpExtOp = pTmpExtOp->ext_next;
|
|
}
|
|
|
|
if ( numExtOps > 0 ) {
|
|
ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps+1) * sizeof(char *) );
|
|
if ( ppExtOpOID != NULL ) {
|
|
pTmpExtOp = pGExtendedOps;
|
|
while ( pTmpExtOp != NULL ) {
|
|
ppExtOpOID[i] = pTmpExtOp->ext_oid;
|
|
i++;
|
|
pTmpExtOp = pTmpExtOp->ext_next;
|
|
}
|
|
ppExtOpOID[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return( ppExtOpOID );
|
|
}
|
|
|
|
Slapi_PBlock *
|
|
slapi_simple_bind_internal( char *d, struct berval *cred, int method, int version)
|
|
{
|
|
|
|
int rc=LDAP_SUCCESS;
|
|
Connection *pConn=NULL;
|
|
Backend *be;
|
|
Slapi_PBlock *pPB=NULL;
|
|
int dnBadChar;
|
|
|
|
int isCritical;
|
|
struct berval bv;
|
|
struct berval dn = { 0, NULL };
|
|
struct berval pdn = { 0, NULL };
|
|
struct berval ndn = { 0, NULL };
|
|
Operation *op;
|
|
|
|
|
|
pConn = fakeConnection(NULL, LDAP_REQ_BIND );
|
|
|
|
if ( pConn == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
} else {
|
|
pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
|
|
pConn->c_version = version;
|
|
op = (Operation *)pConn->c_pending_ops.stqh_first;
|
|
}
|
|
|
|
if ( d == NULL ) {
|
|
rc = LDAP_OPERATIONS_ERROR;
|
|
} else {
|
|
dn.bv_val = ch_strdup (d);
|
|
dn.bv_len = strlen(d);
|
|
rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
|
|
}
|
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
be = select_backend(&ndn, 0, 0 );
|
|
if ( be == NULL ) {
|
|
rc = LDAP_PARTIAL_RESULTS;
|
|
} else if ( be->be_bind == NULL ) {
|
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
|
}
|
|
}
|
|
|
|
rc = (*be->be_bind)( be, pConn, op,
|
|
&pdn, &ndn, method, cred, NULL );
|
|
|
|
if (rc == LDAP_SUCCESS) {
|
|
pConn->c_version = version;
|
|
pConn->c_dn.bv_val = strdup( d );
|
|
pConn->c_dn.bv_len = strlen( d );
|
|
if (pConn->c_dn.bv_val == NULL) {
|
|
rc = LDAP_NO_MEMORY;
|
|
Debug (LDAP_DEBUG_TRACE, " backend routine successful, but has no more memory \n",0, 0, 0);
|
|
}
|
|
Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
|
|
}
|
|
|
|
if ( pPB != NULL )
|
|
slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
|
|
|
|
return(pPB);
|
|
|
|
}
|
|
|