From d7a49100c03a5e68e09213d2723c44baaa49c4b1 Mon Sep 17 00:00:00 2001 From: William Brown Date: May 11 2017 22:00:35 +0000 Subject: Ticket 48123 - create contrib section Bug Description: Create a contrib section for plugins that are *not* maintained by the DS team. Fix Description: Create the section, and move back-ldif to it. https://pagure.io/389-ds-base/issue/48123 Author: wibrown Review by: mreynolds (Thanks!) --- diff --git a/ldap/servers/slapd/back-ldif/add.c b/ldap/servers/slapd/back-ldif/add.c deleted file mode 100644 index e107515..0000000 --- a/ldap/servers/slapd/back-ldif/add.c +++ /dev/null @@ -1,204 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: add.c - * - * Functions: - * - * ldif_back_add() - ldap ldif back-end add routine - * ldifentry_init() - takes an Entry and makes an ldif_Entry - * - */ - -#include "back-ldif.h" -ldif_Entry * ldifentry_init(Slapi_Entry *); - -/* - * Function: ldif_back_add - * - * Returns: returns 0 if good, -1 else. - * - * Description: For changetype: add, this function adds the entry - */ -int -ldif_back_add( Slapi_PBlock *pb ) -{ - LDIF *db; /*Stores the ldif database*/ - char *dn = NULL, *parentdn = NULL; - Slapi_Entry *e; /*The new entry to add*/ - ldif_Entry *new, *old; /*Used for various accounting purposes*/ - ldif_Entry *prev; /*Used to add new ldif_Entry to db*/ - ldif_Entry *tprev; /*Dummy pointer for traversing the list*/ - char *errbuf = NULL; - - prev = NULL; - tprev = NULL; - - /*Turn on tracing to see this printed out*/ - slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_add\n", 0, 0, 0 ); - - /*Get the database, the dn and the entry to add*/ - if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || - slapi_pblock_get( pb, SLAPI_ADD_TARGET, &dn ) < 0 || - slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e ) < 0){ - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - /*Check to make sure the entry passes the schema check*/ - if ( slapi_entry_schema_check( pb, e ) != 0 ) { - slapi_log_err(SLAPI_LOG_TRACE, "entry failed schema check\n", 0, 0, 0 ); - slapi_send_ldap_result( pb, LDAP_OBJECT_CLASS_VIOLATION, NULL, NULL, 0, NULL ); - return( -1 ); - } - - /* Check if the attribute values in the entry obey the syntaxes */ - if ( slapi_entry_syntax_check( pb, e, 0 ) != 0 ) { - slapi_log_err(SLAPI_LOG_TRACE, "entry failed syntax_check\n", 0, 0, 0 ); - slapi_send_ldap_result( pb, LDAP_INVALID_SYNTAX, NULL, NULL, 0, NULL ); - return( -1 ); - } - - prev = NULL; - - /*Lock the database*/ - PR_Lock( db->ldif_lock ); - - /* - * Attempt to find this dn in db. If there is no such dn, - * ldif_find_entry should return NULL, and prev should point - * to the last element in the list. - */ - if ((old = (ldif_Entry *)ldif_find_entry(pb, db, dn, &prev)) != NULL) { - - /* - * If we've reached this code, there is an entry in db - * whose dn matches dn, so release the db lock, - * tell the user and return - */ - PR_Unlock( db->ldif_lock ); - slapi_send_ldap_result( pb, LDAP_ALREADY_EXISTS, NULL, NULL, 0, NULL ); - return( -1 ); - } - - - /* - * Get the parent dn and see if the corresponding entry exists. - * If the parent does not exist, only allow the "root" user to - * add the entry. - */ - if ( (parentdn = slapi_dn_beparent( pb, dn )) != NULL ) { - int rc; - if ((old = (ldif_Entry *)ldif_find_entry( pb, db, parentdn, &tprev)) == NULL ) { - slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); - slapi_log_err(SLAPI_LOG_TRACE, "parent does not exist\n", 0, 0, 0 ); - goto error_return; - } - rc= slapi_access_allowed( pb, e, NULL, NULL, SLAPI_ACL_ADD ); - if ( rc!=LDAP_SUCCESS ) { - slapi_log_err(SLAPI_LOG_TRACE, "no access to parent\n", 0,0, 0 ); - slapi_send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); - goto error_return; - } - } else { /* no parent */ - int isroot; - slapi_pblock_get( pb, SLAPI_REQUESTOR_ISROOT, &isroot ); - if ( !isroot ) { - slapi_log_err(SLAPI_LOG_TRACE, "no parent & not root\n", 0, 0, 0 ); - slapi_send_ldap_result( pb, LDAP_INSUFFICIENT_ACCESS, NULL, NULL, 0, NULL ); - goto error_return; - } - - } - - /* - * Before we add the entry, find out if the syntax of the aci - * aci attribute values are correct or not. We don't want to add - * the entry if the syntax is incorrect. - */ - if ( slapi_acl_verify_aci_syntax(pb, e, &errbuf) != 0 ) { - slapi_send_ldap_result( pb, LDAP_INVALID_SYNTAX, NULL, errbuf, 0, NULL ); - if (errbuf) free(errbuf); - goto error_return; - } - - /*Make a new element for the linked list*/ - if ( (new = (ldif_Entry *)ldifentry_init( e )) == NULL){ - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - goto error_return; - - } - - /*Add the new element to the end of the list of entries in db*/ - if ( update_db(pb, db, new, prev, LDIF_DB_ADD) != 0) - { - ldifentry_free( new ); - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - goto error_return; - - } - - /*We have been sucessful. Tell the user*/ - slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); - - /*Release the database lock*/ - PR_Unlock( db->ldif_lock ); - - /*Free the parentdn, and return*/ - if ( parentdn != NULL ){ - free( (void *)parentdn ); - } - slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_add\n", 0, 0, 0 ); - return( 0 ); - - error_return:; - if ( parentdn != NULL ){ - free( (void *)parentdn ); - } - - PR_Unlock( db->ldif_lock ); - return( -1 ); -} - -/* - * Function: ldifentry_init - * - * Returns: a pointer to an ldif_Entry, or NULL - * - * Description: Takes a pointer to an Entry, and sticks - * it into an ldif_Entry structure. - * Note, uses Malloc. - */ -ldif_Entry * -ldifentry_init(Slapi_Entry *e) -{ - ldif_Entry *new; - - /*Alloc a new ldif_entry*/ - new = (ldif_Entry *) malloc(sizeof(ldif_Entry)); - - /*Did it work? if not, return NULL*/ - if (new == NULL) { - return (NULL); - } - /*If it did work, then fill it*/ - new->lde_e = e; - new->next = NULL; - - /*Send it*/ - return (new); -} - - - diff --git a/ldap/servers/slapd/back-ldif/back-ldif.h b/ldap/servers/slapd/back-ldif/back-ldif.h deleted file mode 100644 index 3d64fba..0000000 --- a/ldap/servers/slapd/back-ldif/back-ldif.h +++ /dev/null @@ -1,90 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: back-ldif.h - * - * Description: This header file contains the definitions - * for the data structures used in the ldif backend database - */ - -#include -#include -#include -#include "prlock.h" -#include "portable.h" -#include "slap.h" -#include - - -/*Defines*/ -#define LDIF_DB_ADD 0 -#define LDIF_DB_DELETE 1 -#define LDIF_DB_REPLACE 2 - - -/*This structure basically allows the entries to be linked listed*/ -struct ldif_entry{ - Slapi_Entry *lde_e; /*ptr to the Entry datatype, but you knew that*/ - struct ldif_entry *next; /*ptr to the next list element.*/ -}; -typedef struct ldif_entry ldif_Entry; - - -/*Holds the data from the ldif file*/ -struct ldif { - long ldif_n; /*The number of entries in the database*/ - long ldif_tries; /*The number of accesses to the database*/ - long ldif_hits; /*The number of succesful searches to the db*/ - char *ldif_file; /*From where we read the ldif data*/ - PRLock *ldif_lock; /*Write & read lock.(a simple locking model)*/ - ldif_Entry *ldif_entries; /*The linked list of entries*/ -}; -typedef struct ldif LDIF; - - -/*Prototypes*/ - int ldif_back_modify( Slapi_PBlock * ); - int update_db(Slapi_PBlock *, LDIF *, ldif_Entry *, ldif_Entry *, int); - int db2disk(Slapi_PBlock *, LDIF *); - void ldifentry_free(ldif_Entry *); - ldif_Entry *ldifentry_dup(ldif_Entry *); - ldif_Entry *ldif_find_entry(Slapi_PBlock *, LDIF *, char *, ldif_Entry **); - int apply_mods( Slapi_Entry *, LDAPMod ** ); - - int ldif_back_add( Slapi_PBlock *); - ldif_Entry *ldifentry_init(Slapi_Entry *); - int ldif_back_config( Slapi_PBlock *); - static char * ldif_read_one_record( FILE *); - int ldif_back_delete( Slapi_PBlock *); - int has_children(LDIF *, ldif_Entry *); - int ldif_back_init( Slapi_PBlock *); - - int ldif_back_search( Slapi_PBlock * ); - - int ldif_back_modrdn( Slapi_PBlock * ); - static int rdn2typeval(char *, char **, struct berval *); - void add_mod( LDAPMod ***, int, char *, struct berval ** ); - - int ldif_back_bind( Slapi_PBlock * ); - int ldif_back_unbind( Slapi_PBlock * ); - - int ldif_back_start( Slapi_PBlock * ); - void ldif_back_close( Slapi_PBlock * ); - void ldif_back_flush( Slapi_PBlock * ); - void ldif_free_db(LDIF *); - - int ldif_back_compare( Slapi_PBlock * ); - - char * get_monitordn(Slapi_PBlock * ); - int ldif_back_monitor_info( Slapi_PBlock *pb, LDIF *db); diff --git a/ldap/servers/slapd/back-ldif/bind.c b/ldap/servers/slapd/back-ldif/bind.c deleted file mode 100644 index 06a0049..0000000 --- a/ldap/servers/slapd/back-ldif/bind.c +++ /dev/null @@ -1,116 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: bind.c - * - * Functions: - * - * ldif_back_bind() - ldap ldif back-end bind routine - * - */ - -#include "back-ldif.h" - -/* - * Function: ldif_back_bind - * - * Returns: returns 0|1 if good, -1 else. - * - * Description: performs an ldap bind. - */ -int -ldif_back_bind( Slapi_PBlock *pb ) -{ - char *dn; /*Storage for the dn*/ - ber_tag_t method; /*Storage for the bind method*/ - struct berval *cred; /*Storage for the bind credentials*/ - struct berval **bvals; - LDIF *db; /*The database*/ - ldif_Entry *e, *prev; /*Used for searching the db*/ - int rc, syntax; /*Storage for error return values*/ - Slapi_Attr *attr; - - slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_bind\n", 0, 0, 0 ); - - prev = NULL; - - /*Get the parameters*/ - if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || - slapi_pblock_get( pb, SLAPI_BIND_TARGET, &dn ) < 0 || - slapi_pblock_get( pb, SLAPI_BIND_METHOD, &method ) < 0 || - slapi_pblock_get( pb, SLAPI_BIND_CREDENTIALS, &cred ) < 0){ - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - /*Lock the database*/ - PR_Lock( db->ldif_lock ); - - - /*Find the entry that the person is attempting to bind as*/ - if ( (e = (ldif_Entry *)ldif_find_entry( pb, db, dn, &prev )) == NULL ) { - - /* Allow noauth binds */ - if ((method == LDAP_AUTH_SIMPLE) && (cred->bv_len == 0)) { - rc = SLAPI_BIND_ANONYMOUS; - } else { - slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); - rc = SLAPI_BIND_FAIL; - } - - /*Unlock the database*/ - PR_Unlock( db->ldif_lock ); - - return( rc ); - } - - switch ( method ) { - case LDAP_AUTH_SIMPLE: - if ( cred->bv_len == 0 ) { - PR_Unlock( db->ldif_lock ); - return( SLAPI_BIND_ANONYMOUS ); - } - - if ( slapi_entry_attr_find( e->lde_e, "userpassword", &attr ) != 0 ) { - slapi_send_ldap_result( pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( SLAPI_BIND_FAIL ); - } - /* - * XXXmcs: slapi_attr_get_values() is deprecated and should be avoided - * See XXXmcs comments in ../attr.c for detailed information. - */ - slapi_attr_get_values( attr, &bvals ); - - if ( slapi_pw_find( bvals, cred ) != 0 ) { - slapi_send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( SLAPI_BIND_FAIL ); - } - break; - - default: - slapi_send_ldap_result( pb, LDAP_STRONG_AUTH_NOT_SUPPORTED, NULL, - "auth method not supported", 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( SLAPI_BIND_FAIL ); - } - - PR_Unlock( db->ldif_lock ); - - slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_bind\n", 0, 0, 0 ); - - /* success: front end will send result */ - return( SLAPI_BIND_SUCCESS ); -} diff --git a/ldap/servers/slapd/back-ldif/close.c b/ldap/servers/slapd/back-ldif/close.c deleted file mode 100644 index 64402e6..0000000 --- a/ldap/servers/slapd/back-ldif/close.c +++ /dev/null @@ -1,87 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: close.c - * - * Functions: - * - * ldif_back_close() - ldap ldif back-end close routine - * - */ - -#include "back-ldif.h" - -/* - * Function: ldif_free_db - * - * Returns: void - * - * Description: frees up the ldif database - */ -void -ldif_free_db(LDIF *db) -{ - ldif_Entry *cur; /*Used for walking down the list*/ - - /*If db is null, there is nothing to do*/ - if (db == NULL) { - return; - } - - /*Walk down the list, freeing up the ldif_entries*/ - for (cur = db->ldif_entries; cur != NULL; cur = cur->next){ - ldifentry_free(cur); - } - - /*Free the ldif_file string, and then the db itself*/ - free ((void *)db->ldif_file); - free((void *) db); -} - - - -/* - * Function: ldif_back_close - * - * Returns: void - * - * Description: closes the ldif backend, frees up the database - */ -void -ldif_back_close( Slapi_PBlock *pb ) -{ - LDIF *db; - - slapi_log_err(SLAPI_LOG_TRACE, "ldif backend syncing\n", 0, 0, 0 ); - slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ); - ldif_free_db(db); - slapi_log_err(SLAPI_LOG_TRACE, "ldif backend done syncing\n", 0, 0, 0 ); -} - -/* - * Function: ldif_back_flush - * - * Returns: void - * - * Description: does nothing - */ -void -ldif_back_flush( Slapi_PBlock *pb ) -{ - slapi_log_err(SLAPI_LOG_TRACE, "ldif backend flushing\n", 0, 0, 0 ); - slapi_log_err(SLAPI_LOG_TRACE, "ldif backend done flushing\n", 0, 0, 0 ); - return; -} - - diff --git a/ldap/servers/slapd/back-ldif/compare.c b/ldap/servers/slapd/back-ldif/compare.c deleted file mode 100644 index 51c362e..0000000 --- a/ldap/servers/slapd/back-ldif/compare.c +++ /dev/null @@ -1,90 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: compare.c - * - * Functions: - * - * ldif_back_compare() - ldap ldif back-end compare routine - * - */ - -#include "back-ldif.h" - -/* - * Function: ldif_back_compare - * - * Returns: -1, 0 or 1 - * - * Description: compares entries in the ldif backend - */ -int -ldif_back_compare( Slapi_PBlock *pb ) -{ - LDIF *db; /*The Database*/ - ldif_Entry *e, *prev; /*Used for searching the database*/ - char *dn, *type; /*The dn and the type*/ - struct berval *bval; - Slapi_Attr *attr; - int rc; - - slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_compare\n", 0, 0, 0 ); - prev = NULL; - - if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || - slapi_pblock_get( pb, SLAPI_COMPARE_TARGET, &dn ) < 0 || - slapi_pblock_get( pb, SLAPI_COMPARE_TYPE, &type ) < 0 || - slapi_pblock_get( pb, SLAPI_COMPARE_VALUE, &bval ) < 0){ - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - /*Lock the database*/ - PR_Lock( db->ldif_lock ); - - - /*Find the entry for comparison*/ - if ( (e = (ldif_Entry*) ldif_find_entry( pb, db, dn, &prev )) == NULL ) { - slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( 1 ); - } - - /*Check the access*/ - rc= slapi_access_allowed( pb, e->lde_e, type, bval, SLAPI_ACL_COMPARE ); - if ( rc!=LDAP_SUCCESS ) { - slapi_send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( 1 ); - } - - /*find the attribute*/ - if ( slapi_entry_attr_find( e->lde_e, type, &attr ) != 0 ) { - slapi_send_ldap_result( pb, LDAP_NO_SUCH_ATTRIBUTE, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( 1 ); - } - - if ( slapi_attr_value_find( attr, bval ) == 0 ) { - slapi_send_ldap_result( pb, LDAP_COMPARE_TRUE, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( 0 ); - } - - slapi_send_ldap_result( pb, LDAP_COMPARE_FALSE, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_compare\n", 0, 0, 0 ); - return( 0 ); -} - diff --git a/ldap/servers/slapd/back-ldif/config.c b/ldap/servers/slapd/back-ldif/config.c deleted file mode 100644 index f656f54..0000000 --- a/ldap/servers/slapd/back-ldif/config.c +++ /dev/null @@ -1,211 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: config.c - * - * Functions: - * - * ldif_back_config() - Reads in and stores ldif file for ldif backend - * ldif_read_one_record() - Reads in one record from ldif file as a string - * - */ - -#include "back-ldif.h" -#define LDAPMOD_MAXLINE 4096 -#define safe_realloc( ptr, size ) ( ptr == NULL ? malloc( size ) : \ - realloc( ptr, size )) -static char *ldif_read_one_record(); - - -/* - * Function: ldif_back_config - * - * Returns: 0 if success, -1 if not - * - * Description: Reads the data in the ldif file specified in ldif.conf - * stores it in db - */ -int -ldif_back_config( Slapi_PBlock *pb ) -{ - LDIF *db; /*The ldif file will be read into this structure*/ - char *fname; /*Config file name*/ - int lineno, argc; /*Config file stuff*/ - char **argv; /*More config file stuff*/ - FILE *fp; /*Pointer to ldif file*/ - char *buf; /*Tmp storage for ldif entries*/ - int first; /*Boolean to determine if db is empty*/ - ldif_Entry *cur; /*For db manipulation*/ - ldif_Entry *new; /*For db manipulation*/ - Slapi_Entry *tmp; /*Used for initialization purposes*/ - - - slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_config\n", 0, 0, 0 ); - - /* - * Get the private_info structure you created in ldif_back_init(). - * Also get the config file name, current line number, and arguments - * from the current line, broken out into an argv. - */ - if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || - slapi_pblock_get( pb, SLAPI_CONFIG_FILENAME, &fname ) < 0 || - slapi_pblock_get( pb, SLAPI_CONFIG_LINENO, &lineno ) < 0 || - slapi_pblock_get( pb, SLAPI_CONFIG_ARGC, &argc ) < 0 || - slapi_pblock_get( pb, SLAPI_CONFIG_ARGV, &argv ) < 0 ){ - slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to get data from front end\n", 0, 0, 0); - return(-1); - } - - - /* - * Process the config info. For example, if the config file - * contains a line like this: - * - * file /path/to/ldif/file - * - * then argv[0] would be "file", and argv[1] would be the file - * name. - */ - - /*Check for the correct number of arguments*/ - if (argc != 2){ - slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: Unable to configure; invalid ldif input file specification line format (file: %s, line: %d)\n", - fname, lineno, 0); - return(-1); - } - - /*Check for the right format*/ - if (strcmp(argv[0], "file") != 0){ - slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to configure; invalid parameter \"%s\" in config file (file: %s, line: %d)\n", - argv[0], fname, lineno ); - return(-1); - } - - /*Now we fopen the file and grab up the contents*/ - fp = fopen (argv[1], "r"); - if (fp == NULL){ - slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to read ldif file %s\n", argv[1], 0, 0); - fp = fopen (argv[1], "w"); - if(fp == NULL){ - slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to create ldif file %s\n", argv[1], 0, 0); - return -1; - } - } - - first = 1; - - /* Lock the database first, just to be safe*/ - PR_Lock( db->ldif_lock ); - - /*Save the filename, for modifications to the file later*/ - if ((db->ldif_file = strdup(argv[1])) == NULL){ - slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: out of memory\n", 0, 0, 0); - PR_Unlock( db->ldif_lock ); - fclose(fp); - return(-1); - } - - /* - * Loop through the entries in the file, and add them to the end - * of the linked list - */ - while ((buf = ldif_read_one_record(fp)) != NULL){ - - /*Create a new element for the linked list of entries*/ - tmp = (Slapi_Entry *) slapi_str2entry(buf, - SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF); - new = (ldif_Entry *) ldifentry_init(tmp); - if (new == NULL){ - slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to read in ldif file; out of memory\n",0 ,0 ,0 ); - PR_Unlock( db->ldif_lock ); - fclose(fp); - return(-1); - } - - /* - * If this is the first entry we are adding, - * we have to make it the first element in the list - */ - if (first){ - db->ldif_entries = new; - first = 0; - } else{ - cur->next = new; - } - - /*Reset the pointer to the last element in the list*/ - cur = new; - - /*Increment the number of entries*/ - db->ldif_n++; - - /*Free the buffer*/ - free ((void *) buf ); - - } - - /*By now, the database should be read in*/ - PR_Unlock( db->ldif_lock ); - fclose(fp); - - slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_config\n", 0, 0, 0 ); - return( 0 ); -} - - - -/* - * Function: ldif_read_one_record - * - * Returns: a long string representing an ldif record - * - * Description: Returns a huge string comprised of 1 ldif record - * read from fp. - * - */ -static char * -ldif_read_one_record( FILE *fp ) -{ - int len, gotnothing; - char *buff, line[ LDAPMOD_MAXLINE ]; - int lcur, lmax; - - lcur = lmax = 0; - buff = NULL; - gotnothing = 1; - - while ( fgets( line, sizeof(line), fp ) != NULL ) { - if ( (len = strlen( line )) < 2 ) { - if ( gotnothing ) { - continue; - } else { - break; - } - } - gotnothing = 0; - if ( lcur + len + 1 > lmax ) { - lmax = LDAPMOD_MAXLINE - * (( lcur + len + 1 ) / LDAPMOD_MAXLINE + 1 ); - if (( buff = (char *)safe_realloc( buff, lmax )) == NULL ) { - perror( "safe_realloc" ); - exit( LDAP_NO_MEMORY ); - } - } - strcpy( buff + lcur, line ); - lcur += len; - } - - return( buff ); -} - diff --git a/ldap/servers/slapd/back-ldif/delete.c b/ldap/servers/slapd/back-ldif/delete.c deleted file mode 100644 index 6b7e36a..0000000 --- a/ldap/servers/slapd/back-ldif/delete.c +++ /dev/null @@ -1,144 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: delete.c - * - * Functions: - * - * ldif_back_delete() - ldap ldif back-end delete routine - * has_children() - determines if an entry has any children - * - */ - -#include "back-ldif.h" - -/* - * Function: ldif_back_delete - * - * Returns: returns 0 if good, -1 else. - * - * Description: For changetype: delete, this function deletes the entry - */ -int -ldif_back_delete( Slapi_PBlock *pb ) -{ - LDIF *db; /*The database*/ - ldif_Entry *bye, *prev; /*"bye" is the record to be deleted*/ - char *dn; /*Storage for the dn*/ - int rc; - - slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_delete\n", 0, 0, 0 ); - - prev = NULL; - - /*Get the database and the dn to delete*/ - if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || - slapi_pblock_get( pb, SLAPI_DELETE_TARGET, &dn ) < 0){ - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - /*Lock the database*/ - PR_Lock( db->ldif_lock ); - - /* Find the entry we're about to delete*/ - bye = (ldif_Entry *) ldif_find_entry(pb, db, dn, &prev); - if (bye == NULL) { - slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); - slapi_log_err(SLAPI_LOG_TRACE, "entry for delete does not exist\n", 0, 0, 0 ); - PR_Unlock( db->ldif_lock ); - return(-1); - } - - /*Make sure that we are trying to delete a leaf.*/ - if ( has_children( db, bye ) ) { - slapi_send_ldap_result( pb, LDAP_NOT_ALLOWED_ON_NONLEAF, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( -1 ); - } - - /*Check the access*/ - rc= slapi_access_allowed( pb, bye->lde_e, "entry", NULL, SLAPI_ACL_DELETE ); - if ( rc!=LDAP_SUCCESS) { - slapi_send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( -1 ); - } - - /* Delete from disk and database */ - if ( update_db(pb, db, NULL, prev, LDIF_DB_DELETE) != 0){ - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return(-1); - - } - - /*Success*/ - slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_delete\n", 0, 0, 0 ); - return( 0 ); -} - -/* - * Function: has_children - * - * Returns: returns 1 if the entry has kids, 0 else. - * - * Description: Determines if the entry has children - */ -int -has_children(LDIF *db, ldif_Entry *p) -{ - char *parentdn; /*Basically the dn of p (copied)*/ - char *childdn; /*Will be used to test if p has any children*/ - ldif_Entry *cur; /*Used to walk down the list*/ - int has_kid = 0; /*Flag to return*/ - - slapi_log_err(SLAPI_LOG_TRACE, "=> has_children\n", 0, 0, 0); - - /*If there is no p or db, then there can be no children*/ - if (p == NULL || db == NULL){ - return(0); - } - - /*Get a copy of p's dn, and normalize it (squeeze any unneeded spaces out)*/ - parentdn = strdup( slapi_entry_get_dn(p->lde_e) ); - (void) slapi_dn_normalize( parentdn ); - - /*Walk down the list, seeing if each entry has p as a parent*/ - for (cur = db->ldif_entries; cur != NULL; cur = cur->next){ - childdn = strdup(slapi_entry_get_dn(cur->lde_e)); - (void) slapi_dn_normalize(childdn); - - /*Test to see if this childdn is a child of the parentdn*/ - if (slapi_dn_issuffix( childdn, parentdn ) && strlen(childdn) > strlen(parentdn)) - { - has_kid = 1; - free( (void *) childdn); - break; - } - free( (void *) childdn); - - } - - free( (void *) parentdn ); - - slapi_log_err(SLAPI_LOG_TRACE, "<= has_children %d\n", has_kid, 0, 0); - return( has_kid ); -} - - - - diff --git a/ldap/servers/slapd/back-ldif/init.c b/ldap/servers/slapd/back-ldif/init.c deleted file mode 100644 index 1cd5064..0000000 --- a/ldap/servers/slapd/back-ldif/init.c +++ /dev/null @@ -1,114 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: init.c - * - * Functions: - * - * ldif_back_init() - ldap ldif back-end initialize routine - * - */ - -#include "back-ldif.h" - -static Slapi_PluginDesc pdesc = { "ldif-backend", "Netscape", DS_PACKAGE_VERSION, - "LDIF backend database plugin" }; - - -/* - * Function: ldif_back_init - * - * Returns: returns 0 if good, -1 else. - * - * Description: Allocates a database for filling by ldif_back_config - */ -int -ldif_back_init( Slapi_PBlock *pb ) -{ - LDIF *db; /*This will hold the ldif file in memory*/ - int rc; - - slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_init\n", 0, 0, 0 ); - - /* - * Allocate and initialize db with everything we - * need to keep track of in this backend. In ldif_back_config(), - * we will fill in db with things like the name - * of the ldif file containing the database, and any other - * options we allow people to set through the config file. - */ - - /*Allocate memory for our database and check if success*/ - db = (LDIF *) malloc( sizeof(LDIF) ); - if (db == NULL) { - slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to initialize; out of memory\n", 0, 0, 0); - return(-1); - } - - /*Fill with initial values, including the mutex*/ - db->ldif_n = 0; - db->ldif_entries = NULL; - db->ldif_tries = 0; - db->ldif_hits = 0; - db->ldif_file = NULL; - db->ldif_lock = PR_NewLock(); - if (&db->ldif_lock == NULL) { - slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: Lock creation failed\n", 0, 0, 0); - return(-1); - } - - - /* - * set SLAPI_PLUGIN_PRIVATE field in pb, so it's available - * later in ldif_back_config(), ldif_back_search(), etc. - */ - rc = slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, (void *) db ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *) &pdesc ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, - (void *) SLAPI_PLUGIN_VERSION_01 ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_BIND_FN, - (void *) ldif_back_bind ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_UNBIND_FN, - (void *) ldif_back_unbind ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_SEARCH_FN, - (void *) ldif_back_search ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_COMPARE_FN, - (void *) ldif_back_compare ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_MODIFY_FN, - (void *) ldif_back_modify ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_MODRDN_FN, - (void *) ldif_back_modrdn ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ADD_FN, - (void *) ldif_back_add ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_DELETE_FN, - (void *) ldif_back_delete ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_CONFIG_FN, - (void *) ldif_back_config ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN, - (void *) ldif_back_close ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_FLUSH_FN, - (void *) ldif_back_flush ); - rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN, - (void *) ldif_back_start ); - if (rc != 0) { - slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to pass database information to front end\n",0 ,0 ,0); - return(-1); - } - - slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_init\n", 0, 0, 0 ); - - return( 0 ); -} - - diff --git a/ldap/servers/slapd/back-ldif/modify.c b/ldap/servers/slapd/back-ldif/modify.c deleted file mode 100644 index a9f9c76..0000000 --- a/ldap/servers/slapd/back-ldif/modify.c +++ /dev/null @@ -1,572 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: modify.c - * - * Functions: - * - * ldif_back_modify() - ldif backend modify function - * update_db() - updates memory and disk db to reflect changes - * db2disk() - writes out ldif database to disk - * ldifentry_free() - frees an ldif_Entry - * ldifentry_dup() - copies an ldif_Entry - * ldif_find_entry() - searches an ldif DB for a particular dn - * apply_mods() - applies the modifications to an Entry - * - */ - -#include "back-ldif.h" - -/*Prototypes*/ -void ldifentry_free(ldif_Entry *); -ldif_Entry * ldifentry_dup(ldif_Entry *); -int apply_mods( Slapi_Entry *, LDAPMod ** ); -ldif_Entry * ldif_find_entry(Slapi_PBlock *, LDIF *, char *, ldif_Entry **); -int db2disk(Slapi_PBlock *, LDIF *); -int update_db(Slapi_PBlock *, LDIF *, ldif_Entry *, ldif_Entry *, int ); - -/* - * Function: ldif_back_modify - * - * Returns: returns 0 if good, -1 else. - * - * Description: For changetype: modify, this makes the changes - */ -int -ldif_back_modify( Slapi_PBlock *pb ) -{ - LDIF *db; /*The ldif file is stored here*/ - ldif_Entry *entry, *entry2,*prev; /*For db manipulation*/ - int err; /*House keeping stuff*/ - LDAPMod **mods; /*Used to apply the modifications*/ - char *dn; /*Storage for the dn*/ - char *errbuf = NULL; /* To get error back */ - - slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_modify\n", 0, 0, 0 ); - prev = NULL; - - /*Get the database, the dn and the mods*/ - if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || - slapi_pblock_get( pb, SLAPI_MODIFY_TARGET, &dn ) < 0 || - slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods ) < 0){ - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - /*Lock the database*/ - PR_Lock( db->ldif_lock ); - - /* - * Find the entry we are about to modify. - * prev will point to the previous element in the list, - * NULL if there is no previous element. - */ - if ( (entry = (ldif_Entry *)ldif_find_entry( pb, db, dn, &prev)) == NULL ) { - slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( -1 ); - } - - /*Check acl, note that entry is not an Entry, but a ldif_Entry*/ - if ( (err = slapi_acl_check_mods( pb, entry->lde_e, mods, &errbuf )) != LDAP_SUCCESS ) { - slapi_send_ldap_result( pb, err, NULL, errbuf, 0, NULL ); - if (errbuf) free (errbuf); - PR_Unlock( db->ldif_lock ); - goto error_return; - } - - /* Create a copy of the entry and apply the changes to it */ - if ( (entry2 = (ldif_Entry *) ldifentry_dup( entry )) == NULL ) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - goto error_return; - } - - /*Actually apply the modifications*/ - if ( (err = apply_mods( entry2->lde_e, mods )) != 0 ) { - slapi_send_ldap_result( pb, err, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - goto error_return; - } - - /* Check for abandon */ - if ( slapi_op_abandoned( pb ) ) { - PR_Unlock( db->ldif_lock ); - goto error_return; - } - - /* Check that the entry still obeys the schema */ - if ( slapi_entry_schema_check( pb, entry2->lde_e ) != 0 ) { - slapi_send_ldap_result( pb, LDAP_OBJECT_CLASS_VIOLATION, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - goto error_return; - } - - /* Check if the attribute values in the mods obey the syntaxes */ - if ( slapi_mods_syntax_check( pb, mods, 0 ) != 0 ) { - slapi_send_ldap_result( pb, LDAP_INVALID_SYNTAX, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - goto error_return; - } - - /* Check for abandon again */ - if ( slapi_op_abandoned( pb ) ) { - PR_Unlock( db->ldif_lock ); - goto error_return; - } - - /* Change the entry itself both on disk and in the cache */ - if ( update_db(pb, db, entry2, prev, LDIF_DB_REPLACE) != 0) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - goto error_return; - } - - slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_modify\n", 0, 0, 0 ); - return( 0 ); - - error_return:; - if ( entry2 != NULL ) { - ldifentry_free( entry2 ); - } - - return( -1 ); -} - -/* - * Function: update_db - * - * Returns: returns 0 if good, -1 else. - * - * Description: Will update the database in memory, and on disk - * if prev == NULL, then the element to be deleted/replaced - * is the first in the list. - * mode = LDIF_DB_ADD | LDIF_DB_REPLACE | LDIF_DB_DELETE - * The database should be locked when this function is called. - * Note that on replaces and deletes, the old ldif_Entry's - * are freed. - */ -int -update_db(Slapi_PBlock *pb, LDIF *db, ldif_Entry *new, ldif_Entry *prev, int mode) -{ - ldif_Entry *tmp; /*Used to free the removed/replaced entries*/ - char *buf; /*Used to convert entries to strings for output to file*/ - FILE *fp; /*File ptr to the ldif file*/ - int len; /*Used by slapi_entry2str*/ - int db_updated=0; /*Flag to designate if db in memory has been updated*/ - - /*Make sure that the database is not null. Everything else can be, though*/ - if (db == NULL){ - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - /* - * If we are adding an entry, then prev should be pointing - * to the last element in the list, or null if the list is empty, - * and new should not be null. - */ - if (mode == LDIF_DB_ADD) { - - /*Make sure there is something to add*/ - if ( new == NULL ) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - /*If prev is null, then there had better be no entries in the list*/ - if (prev == NULL){ - if( db->ldif_entries != NULL) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - /*There are no elements, so let's add the new one*/ - db->ldif_entries = new; - db->ldif_n++; - - /*Set a flag*/ - db_updated = 1; - - } - /* - * Last error case to test for is if prev is not null, and prev->next - * points to something. This means that we are not at the end of the list - */ - if (prev != NULL) { - if (prev->next != NULL) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - /*We're at the end of the list, so tack the new entry onto the end*/ - prev->next = new; - db->ldif_n++; - - db_updated = 1; - - } - - /*If the database has been updated in memory, update the disk*/ - if (db_updated && db->ldif_file!=NULL) { - - /*Update the disk by appending to the ldif file*/ - fp = fopen(db->ldif_file, "a"); - if (fp == NULL) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - /*This is s pretty serious problem, so we exit*/ - exit(-1); - } - - /*Convert the entry to ldif format*/ - buf = slapi_entry2str(new->lde_e, &len); - fprintf(fp, "%s\n", buf); - free ( (void *) buf); - fclose(fp); - return(0); - } else { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - fclose(fp); - return(-1); - - } - - } else if (mode == LDIF_DB_DELETE){ - - /*We're not deleting the first entry in the list*/ - if (prev != NULL){ - /*Make sure there is something to delete*/ - if (prev->next == NULL) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - tmp = prev->next; - prev->next = tmp->next; - db->ldif_n--; - ldifentry_free(tmp); - - db_updated = 1; - - } else { /*We are deleting the first entry in the list*/ - - /*Make sure there is something to delete*/ - if (db->ldif_entries == NULL) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - tmp = db->ldif_entries; - db->ldif_entries = tmp->next; - db->ldif_n--; - - /*Free the entry, and set the flag*/ - ldifentry_free(tmp); - db_updated = 1; - } - - /* - * Update the disk by rewriting entire ldif file - * I know, I know, but simplicity is the key here. - */ - if (db_updated) { - return(db2disk(pb, db)); - } else { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - - } - - } else if (mode == LDIF_DB_REPLACE) { - - /*Make sure there is something to replace with*/ - if ( new == NULL ) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - - /*We're not replacing the first element in the list*/ - if (prev != NULL){ - - /*Make sure there is something to replace*/ - if (prev->next == NULL) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - /*Splice out the old entry, and put in the new*/ - tmp = prev->next; - prev->next = new; - new->next = tmp->next; - - /*Free it*/ - ldifentry_free(tmp); - db_updated = 1; - } else { /*We are replacing the first entry in the list*/ - - /*Make sure there is something to replace*/ - if (db->ldif_entries == NULL) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - /*Splice out the old entry, and put in the new*/ - tmp = db->ldif_entries; - db->ldif_entries = new; - new->next = tmp->next; - - /*Free it*/ - ldifentry_free(tmp); - db_updated = 1; - } - - /*Update the disk by rewriting entire ldif file*/ - if (db_updated) { - return(db2disk(pb, db)); - } else { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - } -} - -/* - * Function: db2disk - * - * Returns: returns 0 if good, exits else - * - * Description: Takes an ldif database, db, and writes it out to disk - * if it can't open the file, there's trouble, so we exit - * because this function is usually called after the db - * in memory has been updated. - * - */ -int -db2disk(Slapi_PBlock *pb, LDIF *db) -{ - ldif_Entry *cur; /*Used for walking down the list*/ - char *buf; /*temp storage for Entry->ldif converter*/ - FILE *fp; /*File pointer to ldif target file*/ - int len; /*length returned by slapi_entry2str*/ - - /*Open the file*/ - fp = fopen(db->ldif_file, "w"); - if (fp == NULL) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - /*This is s pretty serious problem, so we exit*/ - exit(-1); - } - - /* - * Walk down the list, converting each entry to a string, - * writing the string out to fp - */ - for (cur = db->ldif_entries; cur != NULL; cur = cur->next){ - buf = slapi_entry2str(cur->lde_e, &len); - fprintf(fp, "%s\n",buf); - free ( (void *) buf); - } - - fclose(fp); - return(0); - -} - - -/* - * Function: ldifentry_free - * - * Returns: void - * - * Description: Frees an ldif_Entry - */ -void -ldifentry_free(ldif_Entry *e) -{ - - /*Make sure that there is actually something to free*/ - if (e == NULL){ - return; - } - - /*Free the entry*/ - slapi_entry_free(e->lde_e); - - /*Free the entire thing*/ - free ((void *) e); -} - -/* - * Function: ldifentry_dup - * - * Returns: a pointer to the new ldif_entry, or NULL - * - * Description: Copies and returns a pointer to a new - * ldif_Entry whose contents are a copy of e's contents - * Note: uses malloc - */ -ldif_Entry * -ldifentry_dup(ldif_Entry *e) -{ - ldif_Entry *new; - - /*Let's make sure that e is not null*/ - if (e == NULL){ - return(NULL); - } - - /*Allocate a new ldif_entry, and return it if it is null*/ - new = (ldif_Entry *) malloc( (sizeof(ldif_Entry))); - if (new == NULL) { - return(new); - } - - /*Copy the Entry in e*/ - new->lde_e = slapi_entry_dup(e->lde_e); - new->next = NULL; - - return(new); - - -} - -/* - * Function: ldif_find_entry - * - * Returns: A pointer to the matched ldif_Entry, or Null - * - * Description: Goes down the list of entries in db to find the entry - * matching dn. Returns a pointer to the entry, - * and sets prev to point to the entry before the match. - * If there is no match, prev points to the last - * entry in the list, and null is returned. - * If the first element matches, prev points to NULL - */ -ldif_Entry * -ldif_find_entry(Slapi_PBlock *pb, LDIF *db, char *dn, ldif_Entry **prev) -{ - ldif_Entry *cur; /*Used for walking down the list*/ - char *finddn, *targetdn; /*Copies of dns for searching */ - int found_it = 0; /*A flag to denote a successful search*/ - - /*Set cur to the start of the list*/ - cur =db->ldif_entries; - - /*Increase the number of accesses*/ - db->ldif_tries++; - - /*Make a copy of the target dn, and normalize it*/ - targetdn = strdup(dn); - (void) slapi_dn_normalize(targetdn); - - - /*Go down the list until we find the entry*/ - while(cur != NULL) { - finddn = strdup(slapi_entry_get_dn(cur->lde_e)); - (void) slapi_dn_normalize(finddn); - - - /*Test to see if we got the entry matching the dn*/ - if (strcasecmp(targetdn, finddn) == 0) - { - found_it = 1; - free ((void *)finddn); - db->ldif_hits++; - break; - } - - /*Udpate the pointers*/ - *prev = cur; - cur = cur->next; - free ((void *)finddn); - - } - - free ((void *)targetdn); - - - /* - * If we didn't find a matching entry, we should - * return, and let the caller handle this (possible) error - */ - if (!found_it){ - return(NULL); - } - - /* - * If the first entry matches, we have to set prev to null, - * so the caller knows. - */ - if (*prev == cur){ - *prev = NULL; - } - - return( cur ); -} - -/* - * Function: apply_mods - * - * Returns: LDAP_SUCCESS if success - * - * Description: Applies the modifications specified in mods to e. - */ -int -apply_mods( Slapi_Entry *e, LDAPMod **mods ) -{ - int err, i, j; - - slapi_log_err(SLAPI_LOG_TRACE, "=> apply_mods\n", 0, 0, 0 ); - - err = LDAP_SUCCESS; - for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ ) { - switch ( mods[j]->mod_op & ~LDAP_MOD_BVALUES ) { - case LDAP_MOD_ADD: - slapi_log_err(SLAPI_LOG_ARGS, " add: %s\n", - mods[j]->mod_type, 0, 0 ); - err = slapi_entry_add_values( e, mods[j]->mod_type, - mods[j]->mod_bvalues ); - break; - - case LDAP_MOD_DELETE: - slapi_log_err(SLAPI_LOG_ARGS, " delete: %s\n", - mods[j]->mod_type, 0, 0 ); - err = slapi_entry_delete_values( e, mods[j]->mod_type, - mods[j]->mod_bvalues ); - break; - - case LDAP_MOD_REPLACE: - slapi_log_err(SLAPI_LOG_ARGS, " replace: %s\n", - mods[j]->mod_type, 0, 0 ); - err = entry_replace_values( e, mods[j]->mod_type, - mods[j]->mod_bvalues ); - break; - } - for ( i = 0; mods[j]->mod_bvalues != NULL && - mods[j]->mod_bvalues[i] != NULL; i++ ) { - slapi_log_err(SLAPI_LOG_ARGS, " %s: %s\n", - mods[j]->mod_type, mods[j]->mod_bvalues[i]->bv_val, - 0 ); - } - slapi_log_err(SLAPI_LOG_ARGS, " -\n", 0, 0, 0 ); - - if ( err != LDAP_SUCCESS ) { - break; - } - } - - slapi_log_err(SLAPI_LOG_TRACE, "<= apply_mods %d\n", err, 0, 0 ); - return( err ); -} diff --git a/ldap/servers/slapd/back-ldif/modrdn.c b/ldap/servers/slapd/back-ldif/modrdn.c deleted file mode 100644 index 0e53ede..0000000 --- a/ldap/servers/slapd/back-ldif/modrdn.c +++ /dev/null @@ -1,290 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: modrdn.c - * - * Functions: - * - * ldif_back_modrdn() - ldap ldif back-end modrdn routine - * rdn2typval() - rdn to typval converter - * ldif_add_mod() - Adds a modification to be performed. - * - */ - -#include "back-ldif.h" -int rdn2typval(char *, char **, struct berval *); -void ldif_add_mod( LDAPMod ***, int, char *, struct berval ** ); - -/* - * Function: ldif_back_modrdn - * - * Returns: returns 0 if good, -1 else. - * - * Description: For changetype: modrdn, this modifies the rdn of the entry - */ -int -ldif_back_modrdn( Slapi_PBlock *pb ) -{ - LDIF *db; /*ldif backend database*/ - ldif_Entry *prev, *tprev, *entry, *entry2, *test; - char *pdn, *newdn; /*Used for dn manipulation*/ - char *dn, *newrdn, *type; /*Used for dn manipulation*/ - int i; /*A counter*/ - char **rdns, **dns; /*Used for dn manipulation*/ - int deleteoldrdn; /*Flag from user to delete old rdn*/ - struct berval bv; - struct berval *bvps[2]; - LDAPMod **mods; /*Holds the list of modifications*/ - int rc; - - slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_modrdn\n", 0, 0, 0 ); - - prev = NULL; - - /*Get the information from the front end, including the database*/ - if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db )< 0 || - slapi_pblock_get( pb, SLAPI_MODRDN_TARGET, &dn ) < 0 || - slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn ) < 0 || - slapi_pblock_get( pb, SLAPI_MODRDN_DELOLDRDN, &deleteoldrdn ) <0){ - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - - } - - /*Lock the database*/ - PR_Lock( db->ldif_lock ); - - /* - * Find the entry we are about to modify - * prev will point to the previous element in the list, - * NULL if there is no previous element - */ - if ( (entry = (ldif_Entry *)ldif_find_entry( pb, db, dn, &prev)) == NULL ) { - slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( -1 ); - } - - /*Make sure that we are trying to modify the rdn of a leaf.*/ - if ( has_children( db, entry ) ) { - slapi_send_ldap_result( pb, LDAP_NOT_ALLOWED_ON_NONLEAF, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( -1 ); - } - - - /* Create a copy of the entry and apply the changes to it */ - if ( (entry2 = (ldif_Entry *)ldifentry_dup( entry )) == NULL ) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - PR_Unlock( db->ldif_lock ); - return( -1 ); - } - - /*Check the access*/ - rc= slapi_access_allowed( pb, entry2->lde_e, NULL, NULL, SLAPI_ACL_WRITE ); - if ( rc!=LDAP_SUCCESS ) { - slapi_send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); - ldifentry_free( entry2 ); - PR_Unlock( db->ldif_lock ); - return( -1 ); - } - - /* Construct the new dn */ - if ( (pdn = slapi_dn_beparent( pb, dn )) != NULL ) { - - /* parent + rdn + separator(s) + null */ - newdn = (char *) malloc( strlen( pdn ) + strlen( newrdn ) + 3 ); - if (newdn == NULL){ - slapi_log_err(SLAPI_LOG_ERR,"malloc failed", 0, 0, 0 ); - exit(1); - } - - strcpy( newdn, newrdn ); - strcat( newdn, ", " ); - strcat( newdn, pdn ); - } else { - newdn = strdup( newrdn ); - } - free( pdn ); - - /*Normalize the newdn, that is, squeeze out all unnecessary spaces*/ - (void) slapi_dn_normalize( newdn ); - - - /* Add the new dn to our working copy of the entry */ - slapi_entry_set_dn( entry2->lde_e, newdn ); - - - /* See if an entry with the new name already exists */ - if ( (test = (ldif_Entry *)ldif_find_entry( pb, db, newdn, &tprev )) != NULL ) { - slapi_send_ldap_result( pb, LDAP_ALREADY_EXISTS, NULL, NULL, 0, NULL ); - - goto error_return; - } - - - /* - * Delete old rdn values from the entry if deleteoldrdn is set. - * Add new rdn values to the entry. - */ - mods = NULL; - bvps[0] = &bv; - bvps[1] = NULL; - if ( (dns = slapi_ldap_explode_dn( dn, 0 )) != NULL ) { - if ( (rdns = slapi_ldap_explode_rdn( dns[0], 0 )) != NULL ) { - for ( i = 0; rdns[i] != NULL; i++ ) { - - /* Delete from entry attributes */ - if ( deleteoldrdn && rdn2typval( rdns[i], &type, &bv ) == 0 ) { - ldif_add_mod( &mods, LDAP_MOD_DELETE, type, bvps ); - } - } - slapi_ldap_value_free( rdns ); - } - slapi_ldap_value_free( dns ); - } - if ( dns == NULL || rdns == NULL ) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - goto error_return; - } - /* Add new rdn values to the entry */ - if ( (rdns = slapi_ldap_explode_rdn( newrdn, 0 )) != NULL ) { - for ( i = 0; rdns[i] != NULL; i++ ) { - /* Add to entry */ - if ( rdn2typval( rdns[i], &type, &bv ) == 0 ) { - ldif_add_mod( &mods, LDAP_MOD_ADD, type, bvps ); - } - } - slapi_ldap_value_free( rdns ); - } else { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - goto error_return; - } - bv.bv_val = newdn; - bv.bv_len = strlen( newdn ); - ldif_add_mod( &mods, LDAP_MOD_REPLACE, "entrydn", bvps ); - - /* Check for abandon */ - if ( slapi_op_abandoned( pb ) ) { - goto error_return; - } - - /* Apply the mods we built above to the copy of the entry */ - if ( apply_mods( entry2->lde_e, mods ) != 0 ) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - - goto error_return; - } - - /* Update the database and the disk */ - if ( update_db(pb, db, entry2, prev, LDIF_DB_REPLACE) != 0) { - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - - goto error_return; - } - - /*Unlock the database, and tell the user the good news*/ - PR_Unlock( db->ldif_lock ); - slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); - slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_modrdn\n", 0, 0, 0 ); - return( 0 ); - -error_return:; - - /* Result already sent above - just free stuff */ - PR_Unlock( db->ldif_lock ); - ldifentry_free( entry2 ); - - return( -1 ); -} - -/* - * Function: rdn2typval - * - * Returns: returns 0 if good, -1 else. - * - * Description: converts an rdn to a typeval - */ -int -rdn2typval(char *rdn, char **type, struct berval *bv) -{ - char *s; - - if ( (s = strchr( rdn, '=' )) == NULL ) { - return( -1 ); - } - *s++ = '\0'; - - *type = rdn; - bv->bv_val = s; - bv->bv_len = strlen( s ); - - return( 0 ); -} - -/* - * Function: ldif_add_mod - * - * Returns: void - * - * Description: Adds a modification (add, delete, etc) to the list - * of modifications that will eventually be made to some entry - */ -void -ldif_add_mod( LDAPMod ***modlist, int modtype, char *type, struct berval **bvps ) -{ - int i; - - for ( i = 0; modlist[i] != NULL; i++ ) { - ; /* NULL */ - } - - *modlist = (LDAPMod **) realloc( (char *) *modlist, - (i + 2) * sizeof(LDAPMod *) ); - - if (*modlist == NULL){ - slapi_log_err(SLAPI_LOG_ERR, "realloc failed", 0, 0, 0 ); - exit(1); - } - (*modlist)[i] = (LDAPMod *) malloc( sizeof(LDAPMod) ); - - if ((*modlist)[i] == NULL){ - slapi_log_err(SLAPI_LOG_ERR,"malloc failed", 0, 0, 0 ); - exit(1); - } - - (*modlist)[i]->mod_type = (char *) strdup( type ); - if ((*modlist)[i]->mod_type == NULL){ - slapi_log_err(SLAPI_LOG_ERR,"strdup failed", 0, 0, 0 ); - exit(1); - } - - - (*modlist)[i]->mod_op = modtype; - (*modlist)[i]->mod_bvalues = (struct berval **) malloc(2*sizeof(struct berval *)); - if ((*modlist)[i]->mod_bvalues == NULL){ - slapi_log_err(SLAPI_LOG_ERR,"malloc failed",0, 0, 0 ); - exit(1); - } - (*modlist)[i]->mod_bvalues[0] = ber_bvdup( bvps[0] ); - (*modlist)[i]->mod_bvalues[1] = NULL; - (*modlist)[i+1] = NULL; -} - - - - - - - diff --git a/ldap/servers/slapd/back-ldif/monitor.c b/ldap/servers/slapd/back-ldif/monitor.c deleted file mode 100644 index e677fe8..0000000 --- a/ldap/servers/slapd/back-ldif/monitor.c +++ /dev/null @@ -1,132 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: monitor.c - * - * Functions: - * - * ldif_back_monitor_info() - ldap ldif back-end initialize routine - * - * get_monitordn() - gets the monitor dn for this backend - * - */ - -#include "back-ldif.h" - -extern char Versionstr[]; - - -/* - * Function: ldif_back_monitor_info - * - * Returns: returns 1 - * - * Description: This function wraps up backend specific monitor information - * and returns it to the client as an entry. This function - * is usually called by ldif_back_search upon receipt of - * the monitor dn for this backend. - */ -int -ldif_back_monitor_info( Slapi_PBlock *pb, LDIF *db) -{ - Slapi_Entry *e; /*Entry*/ - char buf[BUFSIZ]; /*Buffer for getting the attrs*/ - struct berval val; /*More attribute storage*/ - struct berval *vals[2]; /*Even more*/ - char *type; /*Database name (type) */ - - vals[0] = &val; - vals[1] = NULL; - - /*Alloc the entry and set the monitordn*/ - e = slapi_entry_alloc(); - slapi_entry_set_dn(e, (char *) get_monitordn(pb)); - - /* Get the database name (be_type) */ - slapi_pblock_get( pb, SLAPI_BE_TYPE, &type); - PR_snprintf( buf, sizeof(buf), "%s", type ); - val.bv_val = buf; - val.bv_len = strlen( buf ); - slapi_entry_attr_merge( e, "database", vals ); - - /*Lock the database*/ - PR_Lock( db->ldif_lock ); - - /*Get the number of database hits */ - sprintf( buf, "%ld", db->ldif_hits); - val.bv_val = buf; - val.bv_len = strlen( buf ); - slapi_entry_attr_merge( e, "entrycachehits", vals ); - - /*Get the number of database tries */ - sprintf( buf, "%ld", db->ldif_tries); - val.bv_val = buf; - val.bv_len = strlen( buf ); - slapi_entry_attr_merge( e, "entrycachetries", vals ); - - /*Get the current size of the entrycache (db) */ - sprintf( buf, "%ld", db->ldif_n); - val.bv_val = buf; - val.bv_len = strlen( buf ); - slapi_entry_attr_merge( e, "currententrycachesize", vals ); - - - /* - * Get the maximum size of the entrycache (db) - * in this database, there is no max, so return the current size - */ - val.bv_val = buf; - val.bv_len = strlen( buf ); - slapi_entry_attr_merge( e, "maxentrycachesize", vals ); - - /* Release the lock*/ - PR_Unlock( db->ldif_lock ); - - /*Send the results back to the client*/ - slapi_send_ldap_search_entry( pb, e, NULL, NULL, 0 ); - slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 1, NULL ); - - slapi_entry_free( e ); - - return(1); - - -} - - -/* - * Function: get_monitordn - * - * Returns: returns ptr to string if success, NULL else - * - * Description: get_monitordn takes a pblock and extracts the - * monitor dn of this backend. The monitordn is a special - * signal to the backend to return backend specific monitor - * information (usually called by back_ldif_search()). - */ -char * -get_monitordn(Slapi_PBlock *pb ) -{ - char *mdn; - - slapi_pblock_get( pb, SLAPI_BE_MONITORDN, &mdn ); - - if (mdn == NULL) { - return(NULL); - - } - - return(strdup(mdn)); - -} diff --git a/ldap/servers/slapd/back-ldif/search.c b/ldap/servers/slapd/back-ldif/search.c deleted file mode 100644 index 1cb2a40..0000000 --- a/ldap/servers/slapd/back-ldif/search.c +++ /dev/null @@ -1,205 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: search.c - * - * Functions: - * - * ldif_back_search() - ldif backend search function - * - */ - -#include "back-ldif.h" - -/* - * Function: ldif_back_search - * - * Returns: returns 0 if good, -1 else. - * - * Description: Searches the database for entries satisfying the - * user's criteria - */ -int -ldif_back_search( Slapi_PBlock *pb ) -{ - LDIF *db; /*The database*/ - char *base; /*Base of the search*/ - int scope; /*Scope of the search*/ - int deref; /*Should we dereference aliases?*/ - int slimit; /*Size limit of the search*/ - int tlimit; /*Time limit of the search*/ - Slapi_Filter *filter; /*The filter*/ - time_t dummy=0; /*Used for time()*/ - char **attrs; /*Attributes*/ - int attrsonly; /*Should we just return the attributes found?*/ - time_t optime; /*Time the operation started*/ - int nentries; /*Number of entries found thus far*/ - ldif_Entry *cur; /*Used for traversing the list of entries*/ - int hitflag=0; /*Used to test if we found the entry in the db*/ - char *freeme; /*Tmp storage for monitordn*/ - time_t currtime; /*The current time*/ - - slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_search\n", 0, 0, 0 ); - - /* - * Get private information created in the init routine. - * Also get the parameters of the search operation. These come - * more or less directly from the client. - */ - if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || - slapi_pblock_get( pb, SLAPI_SEARCH_TARGET, &base ) < 0 || - slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope ) < 0 || - slapi_pblock_get( pb, SLAPI_SEARCH_DEREF, &deref ) < 0 || - slapi_pblock_get( pb, SLAPI_SEARCH_SIZELIMIT, &slimit ) < 0 || - slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit ) < 0 || - slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter ) < 0 || - slapi_pblock_get( pb, SLAPI_SEARCH_ATTRS, &attrs ) < 0 || - slapi_pblock_get( pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly ) <0 || - slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime ) < 0){ - slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); - return(-1); - } - - - /* - * If we get a search request for the backend monitor dn, - * call ldif_back_monitor_info(), which packages up the - * backend database analysis info and sends it back to the - * client - */ - if ( scope == LDAP_SCOPE_BASE ) { - - /*Get the backend's monitor dn*/ - freeme = (char *) get_monitordn(pb); - - if (freeme != NULL){ - - /* - * Compare the monitor dn with the base, - * if they match, call monitor_info, which - * will return all the relevant info to the client - */ - if ( strcasecmp( base, freeme) == 0 ) { - ldif_back_monitor_info( pb, db ); - free ((void *) freeme); - return(-1); - } - free ((void *) freeme); - } - } - - - /* - * First we lock the whole database (clumsy, inefficient and - * inelegant, but simple) - */ - PR_Lock( db->ldif_lock ); - - /*Increase the number of accesses*/ - db->ldif_tries++; - - /* - * Look through each entry in the ldif file and see if it matches - * the filter and scope of the search. Do this by calling the - * slapi_filter_test() routine. - */ - nentries = 0; - for (cur=db->ldif_entries; cur != NULL; cur = cur->next ) { - - /*Make sure we're not exceeding our time limit...*/ - currtime = time(&dummy); - if ((tlimit > 0) && ((currtime - optime) > (time_t)tlimit)){ - slapi_send_ldap_result( pb, LDAP_TIMELIMIT_EXCEEDED, NULL, NULL, nentries, NULL); - - /*We "hit" the cache*/ - if (hitflag) - { - db->ldif_hits++; - } - - PR_Unlock( db->ldif_lock ); - return(-1); - } - - /*...or that we haven't been abandoned*/ - if ( slapi_op_abandoned( pb ) ) { - - /*We "hit" the cache*/ - if (hitflag) - { - db->ldif_hits++; - } - - PR_Unlock( db->ldif_lock ); - return( -1 ); - } - - /*Test for exceedence of size limit*/ - if ((slimit > -1) && (nentries >= slimit)){ - slapi_send_ldap_result( pb, LDAP_SIZELIMIT_EXCEEDED, NULL, NULL, nentries, NULL); - - /*We hit the "cache"*/ - if (hitflag) - { - db->ldif_hits++; - } - PR_Unlock( db->ldif_lock ); - return(-1); - } - - - - /*Test if this entry matches the filter*/ - if ( slapi_vattr_filter_test( pb, cur->lde_e, filter, 1 /* verify access */ ) == 0 ) { - - /* Entry matches - send it */ - hitflag = 1; - - switch ( slapi_send_ldap_search_entry( pb, cur->lde_e, NULL, attrs, - attrsonly ) ) { - case 0: /* Entry sent ok */ - nentries++; - break; - case 1: /* Entry not sent - because of acl, etc. */ - break; - case -1:/* Connection closed */ - /* Clean up and return */ - - /*We "hit" the cache*/ - if (hitflag) - { - db->ldif_hits++; - } - PR_Unlock( db->ldif_lock ); - return( -1 ); - } - - - } - } - - /*If we succeeded, we should update the ldif_hits entry of db*/ - if (hitflag) - { - db->ldif_hits++; - } - - - /* Search is done, send LDAP_SUCCESS */ - slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, nentries, NULL ); - PR_Unlock( db->ldif_lock ); - slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_search\n", 0, 0, 0 ); - return( -1 ); - -} diff --git a/ldap/servers/slapd/back-ldif/start.c b/ldap/servers/slapd/back-ldif/start.c deleted file mode 100644 index ab7d29c..0000000 --- a/ldap/servers/slapd/back-ldif/start.c +++ /dev/null @@ -1,39 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: start.c - * - * Functions: - * - * ldif_back_start() - ldap ldif back-end start routine - * - */ -#include "back-ldif.h" - -/* - * Function: ldif_back_start - * - * Returns: returns 0 - * - * Description: After the config file is read, the backend start function is called. - * This allows the backend writer to start any threads or perform any - * operations that need to be done after the config file has been read in. - * The ldif backend requires no such operations to be performed. - * - */ -int -ldif_back_start( Slapi_PBlock *pb ) -{ - return( 0 ); -} diff --git a/ldap/servers/slapd/back-ldif/unbind.c b/ldap/servers/slapd/back-ldif/unbind.c deleted file mode 100644 index 50f79c1..0000000 --- a/ldap/servers/slapd/back-ldif/unbind.c +++ /dev/null @@ -1,35 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * File: unbind.c - * - * Functions: - * - * ldif_back_unbind() - ldap ldif back-end unbind routine - * - */ -#include "back-ldif.h" - -/* - * Function: ldif_back_unbind - * - * Returns: returns 0 - * - * Description: performs an ldap unbind. - */ -int -ldif_back_unbind( Slapi_PBlock *pb ) -{ - return( 0 ); -} diff --git a/src/contrib/README.md b/src/contrib/README.md new file mode 100644 index 0000000..6f22837 --- /dev/null +++ b/src/contrib/README.md @@ -0,0 +1,6 @@ +389 Directory Server - Contrib +============================== + +This folder contains contributed modules that are not as "well supported" by the Directory Server team. + +These modules or plugins may or may not work at any point in time. diff --git a/src/contrib/back-ldif/add.c b/src/contrib/back-ldif/add.c new file mode 100644 index 0000000..e107515 --- /dev/null +++ b/src/contrib/back-ldif/add.c @@ -0,0 +1,204 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: add.c + * + * Functions: + * + * ldif_back_add() - ldap ldif back-end add routine + * ldifentry_init() - takes an Entry and makes an ldif_Entry + * + */ + +#include "back-ldif.h" +ldif_Entry * ldifentry_init(Slapi_Entry *); + +/* + * Function: ldif_back_add + * + * Returns: returns 0 if good, -1 else. + * + * Description: For changetype: add, this function adds the entry + */ +int +ldif_back_add( Slapi_PBlock *pb ) +{ + LDIF *db; /*Stores the ldif database*/ + char *dn = NULL, *parentdn = NULL; + Slapi_Entry *e; /*The new entry to add*/ + ldif_Entry *new, *old; /*Used for various accounting purposes*/ + ldif_Entry *prev; /*Used to add new ldif_Entry to db*/ + ldif_Entry *tprev; /*Dummy pointer for traversing the list*/ + char *errbuf = NULL; + + prev = NULL; + tprev = NULL; + + /*Turn on tracing to see this printed out*/ + slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_add\n", 0, 0, 0 ); + + /*Get the database, the dn and the entry to add*/ + if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || + slapi_pblock_get( pb, SLAPI_ADD_TARGET, &dn ) < 0 || + slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e ) < 0){ + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + /*Check to make sure the entry passes the schema check*/ + if ( slapi_entry_schema_check( pb, e ) != 0 ) { + slapi_log_err(SLAPI_LOG_TRACE, "entry failed schema check\n", 0, 0, 0 ); + slapi_send_ldap_result( pb, LDAP_OBJECT_CLASS_VIOLATION, NULL, NULL, 0, NULL ); + return( -1 ); + } + + /* Check if the attribute values in the entry obey the syntaxes */ + if ( slapi_entry_syntax_check( pb, e, 0 ) != 0 ) { + slapi_log_err(SLAPI_LOG_TRACE, "entry failed syntax_check\n", 0, 0, 0 ); + slapi_send_ldap_result( pb, LDAP_INVALID_SYNTAX, NULL, NULL, 0, NULL ); + return( -1 ); + } + + prev = NULL; + + /*Lock the database*/ + PR_Lock( db->ldif_lock ); + + /* + * Attempt to find this dn in db. If there is no such dn, + * ldif_find_entry should return NULL, and prev should point + * to the last element in the list. + */ + if ((old = (ldif_Entry *)ldif_find_entry(pb, db, dn, &prev)) != NULL) { + + /* + * If we've reached this code, there is an entry in db + * whose dn matches dn, so release the db lock, + * tell the user and return + */ + PR_Unlock( db->ldif_lock ); + slapi_send_ldap_result( pb, LDAP_ALREADY_EXISTS, NULL, NULL, 0, NULL ); + return( -1 ); + } + + + /* + * Get the parent dn and see if the corresponding entry exists. + * If the parent does not exist, only allow the "root" user to + * add the entry. + */ + if ( (parentdn = slapi_dn_beparent( pb, dn )) != NULL ) { + int rc; + if ((old = (ldif_Entry *)ldif_find_entry( pb, db, parentdn, &tprev)) == NULL ) { + slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); + slapi_log_err(SLAPI_LOG_TRACE, "parent does not exist\n", 0, 0, 0 ); + goto error_return; + } + rc= slapi_access_allowed( pb, e, NULL, NULL, SLAPI_ACL_ADD ); + if ( rc!=LDAP_SUCCESS ) { + slapi_log_err(SLAPI_LOG_TRACE, "no access to parent\n", 0,0, 0 ); + slapi_send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); + goto error_return; + } + } else { /* no parent */ + int isroot; + slapi_pblock_get( pb, SLAPI_REQUESTOR_ISROOT, &isroot ); + if ( !isroot ) { + slapi_log_err(SLAPI_LOG_TRACE, "no parent & not root\n", 0, 0, 0 ); + slapi_send_ldap_result( pb, LDAP_INSUFFICIENT_ACCESS, NULL, NULL, 0, NULL ); + goto error_return; + } + + } + + /* + * Before we add the entry, find out if the syntax of the aci + * aci attribute values are correct or not. We don't want to add + * the entry if the syntax is incorrect. + */ + if ( slapi_acl_verify_aci_syntax(pb, e, &errbuf) != 0 ) { + slapi_send_ldap_result( pb, LDAP_INVALID_SYNTAX, NULL, errbuf, 0, NULL ); + if (errbuf) free(errbuf); + goto error_return; + } + + /*Make a new element for the linked list*/ + if ( (new = (ldif_Entry *)ldifentry_init( e )) == NULL){ + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + goto error_return; + + } + + /*Add the new element to the end of the list of entries in db*/ + if ( update_db(pb, db, new, prev, LDIF_DB_ADD) != 0) + { + ldifentry_free( new ); + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + goto error_return; + + } + + /*We have been sucessful. Tell the user*/ + slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); + + /*Release the database lock*/ + PR_Unlock( db->ldif_lock ); + + /*Free the parentdn, and return*/ + if ( parentdn != NULL ){ + free( (void *)parentdn ); + } + slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_add\n", 0, 0, 0 ); + return( 0 ); + + error_return:; + if ( parentdn != NULL ){ + free( (void *)parentdn ); + } + + PR_Unlock( db->ldif_lock ); + return( -1 ); +} + +/* + * Function: ldifentry_init + * + * Returns: a pointer to an ldif_Entry, or NULL + * + * Description: Takes a pointer to an Entry, and sticks + * it into an ldif_Entry structure. + * Note, uses Malloc. + */ +ldif_Entry * +ldifentry_init(Slapi_Entry *e) +{ + ldif_Entry *new; + + /*Alloc a new ldif_entry*/ + new = (ldif_Entry *) malloc(sizeof(ldif_Entry)); + + /*Did it work? if not, return NULL*/ + if (new == NULL) { + return (NULL); + } + /*If it did work, then fill it*/ + new->lde_e = e; + new->next = NULL; + + /*Send it*/ + return (new); +} + + + diff --git a/src/contrib/back-ldif/back-ldif.h b/src/contrib/back-ldif/back-ldif.h new file mode 100644 index 0000000..3d64fba --- /dev/null +++ b/src/contrib/back-ldif/back-ldif.h @@ -0,0 +1,90 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: back-ldif.h + * + * Description: This header file contains the definitions + * for the data structures used in the ldif backend database + */ + +#include +#include +#include +#include "prlock.h" +#include "portable.h" +#include "slap.h" +#include + + +/*Defines*/ +#define LDIF_DB_ADD 0 +#define LDIF_DB_DELETE 1 +#define LDIF_DB_REPLACE 2 + + +/*This structure basically allows the entries to be linked listed*/ +struct ldif_entry{ + Slapi_Entry *lde_e; /*ptr to the Entry datatype, but you knew that*/ + struct ldif_entry *next; /*ptr to the next list element.*/ +}; +typedef struct ldif_entry ldif_Entry; + + +/*Holds the data from the ldif file*/ +struct ldif { + long ldif_n; /*The number of entries in the database*/ + long ldif_tries; /*The number of accesses to the database*/ + long ldif_hits; /*The number of succesful searches to the db*/ + char *ldif_file; /*From where we read the ldif data*/ + PRLock *ldif_lock; /*Write & read lock.(a simple locking model)*/ + ldif_Entry *ldif_entries; /*The linked list of entries*/ +}; +typedef struct ldif LDIF; + + +/*Prototypes*/ + int ldif_back_modify( Slapi_PBlock * ); + int update_db(Slapi_PBlock *, LDIF *, ldif_Entry *, ldif_Entry *, int); + int db2disk(Slapi_PBlock *, LDIF *); + void ldifentry_free(ldif_Entry *); + ldif_Entry *ldifentry_dup(ldif_Entry *); + ldif_Entry *ldif_find_entry(Slapi_PBlock *, LDIF *, char *, ldif_Entry **); + int apply_mods( Slapi_Entry *, LDAPMod ** ); + + int ldif_back_add( Slapi_PBlock *); + ldif_Entry *ldifentry_init(Slapi_Entry *); + int ldif_back_config( Slapi_PBlock *); + static char * ldif_read_one_record( FILE *); + int ldif_back_delete( Slapi_PBlock *); + int has_children(LDIF *, ldif_Entry *); + int ldif_back_init( Slapi_PBlock *); + + int ldif_back_search( Slapi_PBlock * ); + + int ldif_back_modrdn( Slapi_PBlock * ); + static int rdn2typeval(char *, char **, struct berval *); + void add_mod( LDAPMod ***, int, char *, struct berval ** ); + + int ldif_back_bind( Slapi_PBlock * ); + int ldif_back_unbind( Slapi_PBlock * ); + + int ldif_back_start( Slapi_PBlock * ); + void ldif_back_close( Slapi_PBlock * ); + void ldif_back_flush( Slapi_PBlock * ); + void ldif_free_db(LDIF *); + + int ldif_back_compare( Slapi_PBlock * ); + + char * get_monitordn(Slapi_PBlock * ); + int ldif_back_monitor_info( Slapi_PBlock *pb, LDIF *db); diff --git a/src/contrib/back-ldif/bind.c b/src/contrib/back-ldif/bind.c new file mode 100644 index 0000000..06a0049 --- /dev/null +++ b/src/contrib/back-ldif/bind.c @@ -0,0 +1,116 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: bind.c + * + * Functions: + * + * ldif_back_bind() - ldap ldif back-end bind routine + * + */ + +#include "back-ldif.h" + +/* + * Function: ldif_back_bind + * + * Returns: returns 0|1 if good, -1 else. + * + * Description: performs an ldap bind. + */ +int +ldif_back_bind( Slapi_PBlock *pb ) +{ + char *dn; /*Storage for the dn*/ + ber_tag_t method; /*Storage for the bind method*/ + struct berval *cred; /*Storage for the bind credentials*/ + struct berval **bvals; + LDIF *db; /*The database*/ + ldif_Entry *e, *prev; /*Used for searching the db*/ + int rc, syntax; /*Storage for error return values*/ + Slapi_Attr *attr; + + slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_bind\n", 0, 0, 0 ); + + prev = NULL; + + /*Get the parameters*/ + if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || + slapi_pblock_get( pb, SLAPI_BIND_TARGET, &dn ) < 0 || + slapi_pblock_get( pb, SLAPI_BIND_METHOD, &method ) < 0 || + slapi_pblock_get( pb, SLAPI_BIND_CREDENTIALS, &cred ) < 0){ + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + /*Lock the database*/ + PR_Lock( db->ldif_lock ); + + + /*Find the entry that the person is attempting to bind as*/ + if ( (e = (ldif_Entry *)ldif_find_entry( pb, db, dn, &prev )) == NULL ) { + + /* Allow noauth binds */ + if ((method == LDAP_AUTH_SIMPLE) && (cred->bv_len == 0)) { + rc = SLAPI_BIND_ANONYMOUS; + } else { + slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); + rc = SLAPI_BIND_FAIL; + } + + /*Unlock the database*/ + PR_Unlock( db->ldif_lock ); + + return( rc ); + } + + switch ( method ) { + case LDAP_AUTH_SIMPLE: + if ( cred->bv_len == 0 ) { + PR_Unlock( db->ldif_lock ); + return( SLAPI_BIND_ANONYMOUS ); + } + + if ( slapi_entry_attr_find( e->lde_e, "userpassword", &attr ) != 0 ) { + slapi_send_ldap_result( pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( SLAPI_BIND_FAIL ); + } + /* + * XXXmcs: slapi_attr_get_values() is deprecated and should be avoided + * See XXXmcs comments in ../attr.c for detailed information. + */ + slapi_attr_get_values( attr, &bvals ); + + if ( slapi_pw_find( bvals, cred ) != 0 ) { + slapi_send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( SLAPI_BIND_FAIL ); + } + break; + + default: + slapi_send_ldap_result( pb, LDAP_STRONG_AUTH_NOT_SUPPORTED, NULL, + "auth method not supported", 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( SLAPI_BIND_FAIL ); + } + + PR_Unlock( db->ldif_lock ); + + slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_bind\n", 0, 0, 0 ); + + /* success: front end will send result */ + return( SLAPI_BIND_SUCCESS ); +} diff --git a/src/contrib/back-ldif/close.c b/src/contrib/back-ldif/close.c new file mode 100644 index 0000000..64402e6 --- /dev/null +++ b/src/contrib/back-ldif/close.c @@ -0,0 +1,87 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: close.c + * + * Functions: + * + * ldif_back_close() - ldap ldif back-end close routine + * + */ + +#include "back-ldif.h" + +/* + * Function: ldif_free_db + * + * Returns: void + * + * Description: frees up the ldif database + */ +void +ldif_free_db(LDIF *db) +{ + ldif_Entry *cur; /*Used for walking down the list*/ + + /*If db is null, there is nothing to do*/ + if (db == NULL) { + return; + } + + /*Walk down the list, freeing up the ldif_entries*/ + for (cur = db->ldif_entries; cur != NULL; cur = cur->next){ + ldifentry_free(cur); + } + + /*Free the ldif_file string, and then the db itself*/ + free ((void *)db->ldif_file); + free((void *) db); +} + + + +/* + * Function: ldif_back_close + * + * Returns: void + * + * Description: closes the ldif backend, frees up the database + */ +void +ldif_back_close( Slapi_PBlock *pb ) +{ + LDIF *db; + + slapi_log_err(SLAPI_LOG_TRACE, "ldif backend syncing\n", 0, 0, 0 ); + slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ); + ldif_free_db(db); + slapi_log_err(SLAPI_LOG_TRACE, "ldif backend done syncing\n", 0, 0, 0 ); +} + +/* + * Function: ldif_back_flush + * + * Returns: void + * + * Description: does nothing + */ +void +ldif_back_flush( Slapi_PBlock *pb ) +{ + slapi_log_err(SLAPI_LOG_TRACE, "ldif backend flushing\n", 0, 0, 0 ); + slapi_log_err(SLAPI_LOG_TRACE, "ldif backend done flushing\n", 0, 0, 0 ); + return; +} + + diff --git a/src/contrib/back-ldif/compare.c b/src/contrib/back-ldif/compare.c new file mode 100644 index 0000000..51c362e --- /dev/null +++ b/src/contrib/back-ldif/compare.c @@ -0,0 +1,90 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: compare.c + * + * Functions: + * + * ldif_back_compare() - ldap ldif back-end compare routine + * + */ + +#include "back-ldif.h" + +/* + * Function: ldif_back_compare + * + * Returns: -1, 0 or 1 + * + * Description: compares entries in the ldif backend + */ +int +ldif_back_compare( Slapi_PBlock *pb ) +{ + LDIF *db; /*The Database*/ + ldif_Entry *e, *prev; /*Used for searching the database*/ + char *dn, *type; /*The dn and the type*/ + struct berval *bval; + Slapi_Attr *attr; + int rc; + + slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_compare\n", 0, 0, 0 ); + prev = NULL; + + if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || + slapi_pblock_get( pb, SLAPI_COMPARE_TARGET, &dn ) < 0 || + slapi_pblock_get( pb, SLAPI_COMPARE_TYPE, &type ) < 0 || + slapi_pblock_get( pb, SLAPI_COMPARE_VALUE, &bval ) < 0){ + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + /*Lock the database*/ + PR_Lock( db->ldif_lock ); + + + /*Find the entry for comparison*/ + if ( (e = (ldif_Entry*) ldif_find_entry( pb, db, dn, &prev )) == NULL ) { + slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( 1 ); + } + + /*Check the access*/ + rc= slapi_access_allowed( pb, e->lde_e, type, bval, SLAPI_ACL_COMPARE ); + if ( rc!=LDAP_SUCCESS ) { + slapi_send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( 1 ); + } + + /*find the attribute*/ + if ( slapi_entry_attr_find( e->lde_e, type, &attr ) != 0 ) { + slapi_send_ldap_result( pb, LDAP_NO_SUCH_ATTRIBUTE, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( 1 ); + } + + if ( slapi_attr_value_find( attr, bval ) == 0 ) { + slapi_send_ldap_result( pb, LDAP_COMPARE_TRUE, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( 0 ); + } + + slapi_send_ldap_result( pb, LDAP_COMPARE_FALSE, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_compare\n", 0, 0, 0 ); + return( 0 ); +} + diff --git a/src/contrib/back-ldif/config.c b/src/contrib/back-ldif/config.c new file mode 100644 index 0000000..f656f54 --- /dev/null +++ b/src/contrib/back-ldif/config.c @@ -0,0 +1,211 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: config.c + * + * Functions: + * + * ldif_back_config() - Reads in and stores ldif file for ldif backend + * ldif_read_one_record() - Reads in one record from ldif file as a string + * + */ + +#include "back-ldif.h" +#define LDAPMOD_MAXLINE 4096 +#define safe_realloc( ptr, size ) ( ptr == NULL ? malloc( size ) : \ + realloc( ptr, size )) +static char *ldif_read_one_record(); + + +/* + * Function: ldif_back_config + * + * Returns: 0 if success, -1 if not + * + * Description: Reads the data in the ldif file specified in ldif.conf + * stores it in db + */ +int +ldif_back_config( Slapi_PBlock *pb ) +{ + LDIF *db; /*The ldif file will be read into this structure*/ + char *fname; /*Config file name*/ + int lineno, argc; /*Config file stuff*/ + char **argv; /*More config file stuff*/ + FILE *fp; /*Pointer to ldif file*/ + char *buf; /*Tmp storage for ldif entries*/ + int first; /*Boolean to determine if db is empty*/ + ldif_Entry *cur; /*For db manipulation*/ + ldif_Entry *new; /*For db manipulation*/ + Slapi_Entry *tmp; /*Used for initialization purposes*/ + + + slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_config\n", 0, 0, 0 ); + + /* + * Get the private_info structure you created in ldif_back_init(). + * Also get the config file name, current line number, and arguments + * from the current line, broken out into an argv. + */ + if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || + slapi_pblock_get( pb, SLAPI_CONFIG_FILENAME, &fname ) < 0 || + slapi_pblock_get( pb, SLAPI_CONFIG_LINENO, &lineno ) < 0 || + slapi_pblock_get( pb, SLAPI_CONFIG_ARGC, &argc ) < 0 || + slapi_pblock_get( pb, SLAPI_CONFIG_ARGV, &argv ) < 0 ){ + slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to get data from front end\n", 0, 0, 0); + return(-1); + } + + + /* + * Process the config info. For example, if the config file + * contains a line like this: + * + * file /path/to/ldif/file + * + * then argv[0] would be "file", and argv[1] would be the file + * name. + */ + + /*Check for the correct number of arguments*/ + if (argc != 2){ + slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: Unable to configure; invalid ldif input file specification line format (file: %s, line: %d)\n", + fname, lineno, 0); + return(-1); + } + + /*Check for the right format*/ + if (strcmp(argv[0], "file") != 0){ + slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to configure; invalid parameter \"%s\" in config file (file: %s, line: %d)\n", + argv[0], fname, lineno ); + return(-1); + } + + /*Now we fopen the file and grab up the contents*/ + fp = fopen (argv[1], "r"); + if (fp == NULL){ + slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to read ldif file %s\n", argv[1], 0, 0); + fp = fopen (argv[1], "w"); + if(fp == NULL){ + slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to create ldif file %s\n", argv[1], 0, 0); + return -1; + } + } + + first = 1; + + /* Lock the database first, just to be safe*/ + PR_Lock( db->ldif_lock ); + + /*Save the filename, for modifications to the file later*/ + if ((db->ldif_file = strdup(argv[1])) == NULL){ + slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: out of memory\n", 0, 0, 0); + PR_Unlock( db->ldif_lock ); + fclose(fp); + return(-1); + } + + /* + * Loop through the entries in the file, and add them to the end + * of the linked list + */ + while ((buf = ldif_read_one_record(fp)) != NULL){ + + /*Create a new element for the linked list of entries*/ + tmp = (Slapi_Entry *) slapi_str2entry(buf, + SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF); + new = (ldif_Entry *) ldifentry_init(tmp); + if (new == NULL){ + slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to read in ldif file; out of memory\n",0 ,0 ,0 ); + PR_Unlock( db->ldif_lock ); + fclose(fp); + return(-1); + } + + /* + * If this is the first entry we are adding, + * we have to make it the first element in the list + */ + if (first){ + db->ldif_entries = new; + first = 0; + } else{ + cur->next = new; + } + + /*Reset the pointer to the last element in the list*/ + cur = new; + + /*Increment the number of entries*/ + db->ldif_n++; + + /*Free the buffer*/ + free ((void *) buf ); + + } + + /*By now, the database should be read in*/ + PR_Unlock( db->ldif_lock ); + fclose(fp); + + slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_config\n", 0, 0, 0 ); + return( 0 ); +} + + + +/* + * Function: ldif_read_one_record + * + * Returns: a long string representing an ldif record + * + * Description: Returns a huge string comprised of 1 ldif record + * read from fp. + * + */ +static char * +ldif_read_one_record( FILE *fp ) +{ + int len, gotnothing; + char *buff, line[ LDAPMOD_MAXLINE ]; + int lcur, lmax; + + lcur = lmax = 0; + buff = NULL; + gotnothing = 1; + + while ( fgets( line, sizeof(line), fp ) != NULL ) { + if ( (len = strlen( line )) < 2 ) { + if ( gotnothing ) { + continue; + } else { + break; + } + } + gotnothing = 0; + if ( lcur + len + 1 > lmax ) { + lmax = LDAPMOD_MAXLINE + * (( lcur + len + 1 ) / LDAPMOD_MAXLINE + 1 ); + if (( buff = (char *)safe_realloc( buff, lmax )) == NULL ) { + perror( "safe_realloc" ); + exit( LDAP_NO_MEMORY ); + } + } + strcpy( buff + lcur, line ); + lcur += len; + } + + return( buff ); +} + diff --git a/src/contrib/back-ldif/delete.c b/src/contrib/back-ldif/delete.c new file mode 100644 index 0000000..6b7e36a --- /dev/null +++ b/src/contrib/back-ldif/delete.c @@ -0,0 +1,144 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: delete.c + * + * Functions: + * + * ldif_back_delete() - ldap ldif back-end delete routine + * has_children() - determines if an entry has any children + * + */ + +#include "back-ldif.h" + +/* + * Function: ldif_back_delete + * + * Returns: returns 0 if good, -1 else. + * + * Description: For changetype: delete, this function deletes the entry + */ +int +ldif_back_delete( Slapi_PBlock *pb ) +{ + LDIF *db; /*The database*/ + ldif_Entry *bye, *prev; /*"bye" is the record to be deleted*/ + char *dn; /*Storage for the dn*/ + int rc; + + slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_delete\n", 0, 0, 0 ); + + prev = NULL; + + /*Get the database and the dn to delete*/ + if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || + slapi_pblock_get( pb, SLAPI_DELETE_TARGET, &dn ) < 0){ + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + /*Lock the database*/ + PR_Lock( db->ldif_lock ); + + /* Find the entry we're about to delete*/ + bye = (ldif_Entry *) ldif_find_entry(pb, db, dn, &prev); + if (bye == NULL) { + slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); + slapi_log_err(SLAPI_LOG_TRACE, "entry for delete does not exist\n", 0, 0, 0 ); + PR_Unlock( db->ldif_lock ); + return(-1); + } + + /*Make sure that we are trying to delete a leaf.*/ + if ( has_children( db, bye ) ) { + slapi_send_ldap_result( pb, LDAP_NOT_ALLOWED_ON_NONLEAF, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( -1 ); + } + + /*Check the access*/ + rc= slapi_access_allowed( pb, bye->lde_e, "entry", NULL, SLAPI_ACL_DELETE ); + if ( rc!=LDAP_SUCCESS) { + slapi_send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( -1 ); + } + + /* Delete from disk and database */ + if ( update_db(pb, db, NULL, prev, LDIF_DB_DELETE) != 0){ + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return(-1); + + } + + /*Success*/ + slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_delete\n", 0, 0, 0 ); + return( 0 ); +} + +/* + * Function: has_children + * + * Returns: returns 1 if the entry has kids, 0 else. + * + * Description: Determines if the entry has children + */ +int +has_children(LDIF *db, ldif_Entry *p) +{ + char *parentdn; /*Basically the dn of p (copied)*/ + char *childdn; /*Will be used to test if p has any children*/ + ldif_Entry *cur; /*Used to walk down the list*/ + int has_kid = 0; /*Flag to return*/ + + slapi_log_err(SLAPI_LOG_TRACE, "=> has_children\n", 0, 0, 0); + + /*If there is no p or db, then there can be no children*/ + if (p == NULL || db == NULL){ + return(0); + } + + /*Get a copy of p's dn, and normalize it (squeeze any unneeded spaces out)*/ + parentdn = strdup( slapi_entry_get_dn(p->lde_e) ); + (void) slapi_dn_normalize( parentdn ); + + /*Walk down the list, seeing if each entry has p as a parent*/ + for (cur = db->ldif_entries; cur != NULL; cur = cur->next){ + childdn = strdup(slapi_entry_get_dn(cur->lde_e)); + (void) slapi_dn_normalize(childdn); + + /*Test to see if this childdn is a child of the parentdn*/ + if (slapi_dn_issuffix( childdn, parentdn ) && strlen(childdn) > strlen(parentdn)) + { + has_kid = 1; + free( (void *) childdn); + break; + } + free( (void *) childdn); + + } + + free( (void *) parentdn ); + + slapi_log_err(SLAPI_LOG_TRACE, "<= has_children %d\n", has_kid, 0, 0); + return( has_kid ); +} + + + + diff --git a/src/contrib/back-ldif/init.c b/src/contrib/back-ldif/init.c new file mode 100644 index 0000000..1cd5064 --- /dev/null +++ b/src/contrib/back-ldif/init.c @@ -0,0 +1,114 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: init.c + * + * Functions: + * + * ldif_back_init() - ldap ldif back-end initialize routine + * + */ + +#include "back-ldif.h" + +static Slapi_PluginDesc pdesc = { "ldif-backend", "Netscape", DS_PACKAGE_VERSION, + "LDIF backend database plugin" }; + + +/* + * Function: ldif_back_init + * + * Returns: returns 0 if good, -1 else. + * + * Description: Allocates a database for filling by ldif_back_config + */ +int +ldif_back_init( Slapi_PBlock *pb ) +{ + LDIF *db; /*This will hold the ldif file in memory*/ + int rc; + + slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_init\n", 0, 0, 0 ); + + /* + * Allocate and initialize db with everything we + * need to keep track of in this backend. In ldif_back_config(), + * we will fill in db with things like the name + * of the ldif file containing the database, and any other + * options we allow people to set through the config file. + */ + + /*Allocate memory for our database and check if success*/ + db = (LDIF *) malloc( sizeof(LDIF) ); + if (db == NULL) { + slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to initialize; out of memory\n", 0, 0, 0); + return(-1); + } + + /*Fill with initial values, including the mutex*/ + db->ldif_n = 0; + db->ldif_entries = NULL; + db->ldif_tries = 0; + db->ldif_hits = 0; + db->ldif_file = NULL; + db->ldif_lock = PR_NewLock(); + if (&db->ldif_lock == NULL) { + slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: Lock creation failed\n", 0, 0, 0); + return(-1); + } + + + /* + * set SLAPI_PLUGIN_PRIVATE field in pb, so it's available + * later in ldif_back_config(), ldif_back_search(), etc. + */ + rc = slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, (void *) db ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *) &pdesc ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, + (void *) SLAPI_PLUGIN_VERSION_01 ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_BIND_FN, + (void *) ldif_back_bind ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_UNBIND_FN, + (void *) ldif_back_unbind ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_SEARCH_FN, + (void *) ldif_back_search ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_COMPARE_FN, + (void *) ldif_back_compare ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_MODIFY_FN, + (void *) ldif_back_modify ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_MODRDN_FN, + (void *) ldif_back_modrdn ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ADD_FN, + (void *) ldif_back_add ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_DELETE_FN, + (void *) ldif_back_delete ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_CONFIG_FN, + (void *) ldif_back_config ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN, + (void *) ldif_back_close ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_FLUSH_FN, + (void *) ldif_back_flush ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN, + (void *) ldif_back_start ); + if (rc != 0) { + slapi_log_err(SLAPI_LOG_ERR, "Ldif Backend: unable to pass database information to front end\n",0 ,0 ,0); + return(-1); + } + + slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_init\n", 0, 0, 0 ); + + return( 0 ); +} + + diff --git a/src/contrib/back-ldif/modify.c b/src/contrib/back-ldif/modify.c new file mode 100644 index 0000000..a9f9c76 --- /dev/null +++ b/src/contrib/back-ldif/modify.c @@ -0,0 +1,572 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: modify.c + * + * Functions: + * + * ldif_back_modify() - ldif backend modify function + * update_db() - updates memory and disk db to reflect changes + * db2disk() - writes out ldif database to disk + * ldifentry_free() - frees an ldif_Entry + * ldifentry_dup() - copies an ldif_Entry + * ldif_find_entry() - searches an ldif DB for a particular dn + * apply_mods() - applies the modifications to an Entry + * + */ + +#include "back-ldif.h" + +/*Prototypes*/ +void ldifentry_free(ldif_Entry *); +ldif_Entry * ldifentry_dup(ldif_Entry *); +int apply_mods( Slapi_Entry *, LDAPMod ** ); +ldif_Entry * ldif_find_entry(Slapi_PBlock *, LDIF *, char *, ldif_Entry **); +int db2disk(Slapi_PBlock *, LDIF *); +int update_db(Slapi_PBlock *, LDIF *, ldif_Entry *, ldif_Entry *, int ); + +/* + * Function: ldif_back_modify + * + * Returns: returns 0 if good, -1 else. + * + * Description: For changetype: modify, this makes the changes + */ +int +ldif_back_modify( Slapi_PBlock *pb ) +{ + LDIF *db; /*The ldif file is stored here*/ + ldif_Entry *entry, *entry2,*prev; /*For db manipulation*/ + int err; /*House keeping stuff*/ + LDAPMod **mods; /*Used to apply the modifications*/ + char *dn; /*Storage for the dn*/ + char *errbuf = NULL; /* To get error back */ + + slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_modify\n", 0, 0, 0 ); + prev = NULL; + + /*Get the database, the dn and the mods*/ + if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || + slapi_pblock_get( pb, SLAPI_MODIFY_TARGET, &dn ) < 0 || + slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods ) < 0){ + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + /*Lock the database*/ + PR_Lock( db->ldif_lock ); + + /* + * Find the entry we are about to modify. + * prev will point to the previous element in the list, + * NULL if there is no previous element. + */ + if ( (entry = (ldif_Entry *)ldif_find_entry( pb, db, dn, &prev)) == NULL ) { + slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( -1 ); + } + + /*Check acl, note that entry is not an Entry, but a ldif_Entry*/ + if ( (err = slapi_acl_check_mods( pb, entry->lde_e, mods, &errbuf )) != LDAP_SUCCESS ) { + slapi_send_ldap_result( pb, err, NULL, errbuf, 0, NULL ); + if (errbuf) free (errbuf); + PR_Unlock( db->ldif_lock ); + goto error_return; + } + + /* Create a copy of the entry and apply the changes to it */ + if ( (entry2 = (ldif_Entry *) ldifentry_dup( entry )) == NULL ) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + goto error_return; + } + + /*Actually apply the modifications*/ + if ( (err = apply_mods( entry2->lde_e, mods )) != 0 ) { + slapi_send_ldap_result( pb, err, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + goto error_return; + } + + /* Check for abandon */ + if ( slapi_op_abandoned( pb ) ) { + PR_Unlock( db->ldif_lock ); + goto error_return; + } + + /* Check that the entry still obeys the schema */ + if ( slapi_entry_schema_check( pb, entry2->lde_e ) != 0 ) { + slapi_send_ldap_result( pb, LDAP_OBJECT_CLASS_VIOLATION, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + goto error_return; + } + + /* Check if the attribute values in the mods obey the syntaxes */ + if ( slapi_mods_syntax_check( pb, mods, 0 ) != 0 ) { + slapi_send_ldap_result( pb, LDAP_INVALID_SYNTAX, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + goto error_return; + } + + /* Check for abandon again */ + if ( slapi_op_abandoned( pb ) ) { + PR_Unlock( db->ldif_lock ); + goto error_return; + } + + /* Change the entry itself both on disk and in the cache */ + if ( update_db(pb, db, entry2, prev, LDIF_DB_REPLACE) != 0) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + goto error_return; + } + + slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_modify\n", 0, 0, 0 ); + return( 0 ); + + error_return:; + if ( entry2 != NULL ) { + ldifentry_free( entry2 ); + } + + return( -1 ); +} + +/* + * Function: update_db + * + * Returns: returns 0 if good, -1 else. + * + * Description: Will update the database in memory, and on disk + * if prev == NULL, then the element to be deleted/replaced + * is the first in the list. + * mode = LDIF_DB_ADD | LDIF_DB_REPLACE | LDIF_DB_DELETE + * The database should be locked when this function is called. + * Note that on replaces and deletes, the old ldif_Entry's + * are freed. + */ +int +update_db(Slapi_PBlock *pb, LDIF *db, ldif_Entry *new, ldif_Entry *prev, int mode) +{ + ldif_Entry *tmp; /*Used to free the removed/replaced entries*/ + char *buf; /*Used to convert entries to strings for output to file*/ + FILE *fp; /*File ptr to the ldif file*/ + int len; /*Used by slapi_entry2str*/ + int db_updated=0; /*Flag to designate if db in memory has been updated*/ + + /*Make sure that the database is not null. Everything else can be, though*/ + if (db == NULL){ + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + /* + * If we are adding an entry, then prev should be pointing + * to the last element in the list, or null if the list is empty, + * and new should not be null. + */ + if (mode == LDIF_DB_ADD) { + + /*Make sure there is something to add*/ + if ( new == NULL ) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + /*If prev is null, then there had better be no entries in the list*/ + if (prev == NULL){ + if( db->ldif_entries != NULL) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + /*There are no elements, so let's add the new one*/ + db->ldif_entries = new; + db->ldif_n++; + + /*Set a flag*/ + db_updated = 1; + + } + /* + * Last error case to test for is if prev is not null, and prev->next + * points to something. This means that we are not at the end of the list + */ + if (prev != NULL) { + if (prev->next != NULL) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + /*We're at the end of the list, so tack the new entry onto the end*/ + prev->next = new; + db->ldif_n++; + + db_updated = 1; + + } + + /*If the database has been updated in memory, update the disk*/ + if (db_updated && db->ldif_file!=NULL) { + + /*Update the disk by appending to the ldif file*/ + fp = fopen(db->ldif_file, "a"); + if (fp == NULL) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + /*This is s pretty serious problem, so we exit*/ + exit(-1); + } + + /*Convert the entry to ldif format*/ + buf = slapi_entry2str(new->lde_e, &len); + fprintf(fp, "%s\n", buf); + free ( (void *) buf); + fclose(fp); + return(0); + } else { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + fclose(fp); + return(-1); + + } + + } else if (mode == LDIF_DB_DELETE){ + + /*We're not deleting the first entry in the list*/ + if (prev != NULL){ + /*Make sure there is something to delete*/ + if (prev->next == NULL) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + tmp = prev->next; + prev->next = tmp->next; + db->ldif_n--; + ldifentry_free(tmp); + + db_updated = 1; + + } else { /*We are deleting the first entry in the list*/ + + /*Make sure there is something to delete*/ + if (db->ldif_entries == NULL) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + tmp = db->ldif_entries; + db->ldif_entries = tmp->next; + db->ldif_n--; + + /*Free the entry, and set the flag*/ + ldifentry_free(tmp); + db_updated = 1; + } + + /* + * Update the disk by rewriting entire ldif file + * I know, I know, but simplicity is the key here. + */ + if (db_updated) { + return(db2disk(pb, db)); + } else { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + + } + + } else if (mode == LDIF_DB_REPLACE) { + + /*Make sure there is something to replace with*/ + if ( new == NULL ) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + + /*We're not replacing the first element in the list*/ + if (prev != NULL){ + + /*Make sure there is something to replace*/ + if (prev->next == NULL) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + /*Splice out the old entry, and put in the new*/ + tmp = prev->next; + prev->next = new; + new->next = tmp->next; + + /*Free it*/ + ldifentry_free(tmp); + db_updated = 1; + } else { /*We are replacing the first entry in the list*/ + + /*Make sure there is something to replace*/ + if (db->ldif_entries == NULL) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + /*Splice out the old entry, and put in the new*/ + tmp = db->ldif_entries; + db->ldif_entries = new; + new->next = tmp->next; + + /*Free it*/ + ldifentry_free(tmp); + db_updated = 1; + } + + /*Update the disk by rewriting entire ldif file*/ + if (db_updated) { + return(db2disk(pb, db)); + } else { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + } +} + +/* + * Function: db2disk + * + * Returns: returns 0 if good, exits else + * + * Description: Takes an ldif database, db, and writes it out to disk + * if it can't open the file, there's trouble, so we exit + * because this function is usually called after the db + * in memory has been updated. + * + */ +int +db2disk(Slapi_PBlock *pb, LDIF *db) +{ + ldif_Entry *cur; /*Used for walking down the list*/ + char *buf; /*temp storage for Entry->ldif converter*/ + FILE *fp; /*File pointer to ldif target file*/ + int len; /*length returned by slapi_entry2str*/ + + /*Open the file*/ + fp = fopen(db->ldif_file, "w"); + if (fp == NULL) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + /*This is s pretty serious problem, so we exit*/ + exit(-1); + } + + /* + * Walk down the list, converting each entry to a string, + * writing the string out to fp + */ + for (cur = db->ldif_entries; cur != NULL; cur = cur->next){ + buf = slapi_entry2str(cur->lde_e, &len); + fprintf(fp, "%s\n",buf); + free ( (void *) buf); + } + + fclose(fp); + return(0); + +} + + +/* + * Function: ldifentry_free + * + * Returns: void + * + * Description: Frees an ldif_Entry + */ +void +ldifentry_free(ldif_Entry *e) +{ + + /*Make sure that there is actually something to free*/ + if (e == NULL){ + return; + } + + /*Free the entry*/ + slapi_entry_free(e->lde_e); + + /*Free the entire thing*/ + free ((void *) e); +} + +/* + * Function: ldifentry_dup + * + * Returns: a pointer to the new ldif_entry, or NULL + * + * Description: Copies and returns a pointer to a new + * ldif_Entry whose contents are a copy of e's contents + * Note: uses malloc + */ +ldif_Entry * +ldifentry_dup(ldif_Entry *e) +{ + ldif_Entry *new; + + /*Let's make sure that e is not null*/ + if (e == NULL){ + return(NULL); + } + + /*Allocate a new ldif_entry, and return it if it is null*/ + new = (ldif_Entry *) malloc( (sizeof(ldif_Entry))); + if (new == NULL) { + return(new); + } + + /*Copy the Entry in e*/ + new->lde_e = slapi_entry_dup(e->lde_e); + new->next = NULL; + + return(new); + + +} + +/* + * Function: ldif_find_entry + * + * Returns: A pointer to the matched ldif_Entry, or Null + * + * Description: Goes down the list of entries in db to find the entry + * matching dn. Returns a pointer to the entry, + * and sets prev to point to the entry before the match. + * If there is no match, prev points to the last + * entry in the list, and null is returned. + * If the first element matches, prev points to NULL + */ +ldif_Entry * +ldif_find_entry(Slapi_PBlock *pb, LDIF *db, char *dn, ldif_Entry **prev) +{ + ldif_Entry *cur; /*Used for walking down the list*/ + char *finddn, *targetdn; /*Copies of dns for searching */ + int found_it = 0; /*A flag to denote a successful search*/ + + /*Set cur to the start of the list*/ + cur =db->ldif_entries; + + /*Increase the number of accesses*/ + db->ldif_tries++; + + /*Make a copy of the target dn, and normalize it*/ + targetdn = strdup(dn); + (void) slapi_dn_normalize(targetdn); + + + /*Go down the list until we find the entry*/ + while(cur != NULL) { + finddn = strdup(slapi_entry_get_dn(cur->lde_e)); + (void) slapi_dn_normalize(finddn); + + + /*Test to see if we got the entry matching the dn*/ + if (strcasecmp(targetdn, finddn) == 0) + { + found_it = 1; + free ((void *)finddn); + db->ldif_hits++; + break; + } + + /*Udpate the pointers*/ + *prev = cur; + cur = cur->next; + free ((void *)finddn); + + } + + free ((void *)targetdn); + + + /* + * If we didn't find a matching entry, we should + * return, and let the caller handle this (possible) error + */ + if (!found_it){ + return(NULL); + } + + /* + * If the first entry matches, we have to set prev to null, + * so the caller knows. + */ + if (*prev == cur){ + *prev = NULL; + } + + return( cur ); +} + +/* + * Function: apply_mods + * + * Returns: LDAP_SUCCESS if success + * + * Description: Applies the modifications specified in mods to e. + */ +int +apply_mods( Slapi_Entry *e, LDAPMod **mods ) +{ + int err, i, j; + + slapi_log_err(SLAPI_LOG_TRACE, "=> apply_mods\n", 0, 0, 0 ); + + err = LDAP_SUCCESS; + for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ ) { + switch ( mods[j]->mod_op & ~LDAP_MOD_BVALUES ) { + case LDAP_MOD_ADD: + slapi_log_err(SLAPI_LOG_ARGS, " add: %s\n", + mods[j]->mod_type, 0, 0 ); + err = slapi_entry_add_values( e, mods[j]->mod_type, + mods[j]->mod_bvalues ); + break; + + case LDAP_MOD_DELETE: + slapi_log_err(SLAPI_LOG_ARGS, " delete: %s\n", + mods[j]->mod_type, 0, 0 ); + err = slapi_entry_delete_values( e, mods[j]->mod_type, + mods[j]->mod_bvalues ); + break; + + case LDAP_MOD_REPLACE: + slapi_log_err(SLAPI_LOG_ARGS, " replace: %s\n", + mods[j]->mod_type, 0, 0 ); + err = entry_replace_values( e, mods[j]->mod_type, + mods[j]->mod_bvalues ); + break; + } + for ( i = 0; mods[j]->mod_bvalues != NULL && + mods[j]->mod_bvalues[i] != NULL; i++ ) { + slapi_log_err(SLAPI_LOG_ARGS, " %s: %s\n", + mods[j]->mod_type, mods[j]->mod_bvalues[i]->bv_val, + 0 ); + } + slapi_log_err(SLAPI_LOG_ARGS, " -\n", 0, 0, 0 ); + + if ( err != LDAP_SUCCESS ) { + break; + } + } + + slapi_log_err(SLAPI_LOG_TRACE, "<= apply_mods %d\n", err, 0, 0 ); + return( err ); +} diff --git a/src/contrib/back-ldif/modrdn.c b/src/contrib/back-ldif/modrdn.c new file mode 100644 index 0000000..0e53ede --- /dev/null +++ b/src/contrib/back-ldif/modrdn.c @@ -0,0 +1,290 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: modrdn.c + * + * Functions: + * + * ldif_back_modrdn() - ldap ldif back-end modrdn routine + * rdn2typval() - rdn to typval converter + * ldif_add_mod() - Adds a modification to be performed. + * + */ + +#include "back-ldif.h" +int rdn2typval(char *, char **, struct berval *); +void ldif_add_mod( LDAPMod ***, int, char *, struct berval ** ); + +/* + * Function: ldif_back_modrdn + * + * Returns: returns 0 if good, -1 else. + * + * Description: For changetype: modrdn, this modifies the rdn of the entry + */ +int +ldif_back_modrdn( Slapi_PBlock *pb ) +{ + LDIF *db; /*ldif backend database*/ + ldif_Entry *prev, *tprev, *entry, *entry2, *test; + char *pdn, *newdn; /*Used for dn manipulation*/ + char *dn, *newrdn, *type; /*Used for dn manipulation*/ + int i; /*A counter*/ + char **rdns, **dns; /*Used for dn manipulation*/ + int deleteoldrdn; /*Flag from user to delete old rdn*/ + struct berval bv; + struct berval *bvps[2]; + LDAPMod **mods; /*Holds the list of modifications*/ + int rc; + + slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_modrdn\n", 0, 0, 0 ); + + prev = NULL; + + /*Get the information from the front end, including the database*/ + if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db )< 0 || + slapi_pblock_get( pb, SLAPI_MODRDN_TARGET, &dn ) < 0 || + slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn ) < 0 || + slapi_pblock_get( pb, SLAPI_MODRDN_DELOLDRDN, &deleteoldrdn ) <0){ + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + + } + + /*Lock the database*/ + PR_Lock( db->ldif_lock ); + + /* + * Find the entry we are about to modify + * prev will point to the previous element in the list, + * NULL if there is no previous element + */ + if ( (entry = (ldif_Entry *)ldif_find_entry( pb, db, dn, &prev)) == NULL ) { + slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( -1 ); + } + + /*Make sure that we are trying to modify the rdn of a leaf.*/ + if ( has_children( db, entry ) ) { + slapi_send_ldap_result( pb, LDAP_NOT_ALLOWED_ON_NONLEAF, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( -1 ); + } + + + /* Create a copy of the entry and apply the changes to it */ + if ( (entry2 = (ldif_Entry *)ldifentry_dup( entry )) == NULL ) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + PR_Unlock( db->ldif_lock ); + return( -1 ); + } + + /*Check the access*/ + rc= slapi_access_allowed( pb, entry2->lde_e, NULL, NULL, SLAPI_ACL_WRITE ); + if ( rc!=LDAP_SUCCESS ) { + slapi_send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); + ldifentry_free( entry2 ); + PR_Unlock( db->ldif_lock ); + return( -1 ); + } + + /* Construct the new dn */ + if ( (pdn = slapi_dn_beparent( pb, dn )) != NULL ) { + + /* parent + rdn + separator(s) + null */ + newdn = (char *) malloc( strlen( pdn ) + strlen( newrdn ) + 3 ); + if (newdn == NULL){ + slapi_log_err(SLAPI_LOG_ERR,"malloc failed", 0, 0, 0 ); + exit(1); + } + + strcpy( newdn, newrdn ); + strcat( newdn, ", " ); + strcat( newdn, pdn ); + } else { + newdn = strdup( newrdn ); + } + free( pdn ); + + /*Normalize the newdn, that is, squeeze out all unnecessary spaces*/ + (void) slapi_dn_normalize( newdn ); + + + /* Add the new dn to our working copy of the entry */ + slapi_entry_set_dn( entry2->lde_e, newdn ); + + + /* See if an entry with the new name already exists */ + if ( (test = (ldif_Entry *)ldif_find_entry( pb, db, newdn, &tprev )) != NULL ) { + slapi_send_ldap_result( pb, LDAP_ALREADY_EXISTS, NULL, NULL, 0, NULL ); + + goto error_return; + } + + + /* + * Delete old rdn values from the entry if deleteoldrdn is set. + * Add new rdn values to the entry. + */ + mods = NULL; + bvps[0] = &bv; + bvps[1] = NULL; + if ( (dns = slapi_ldap_explode_dn( dn, 0 )) != NULL ) { + if ( (rdns = slapi_ldap_explode_rdn( dns[0], 0 )) != NULL ) { + for ( i = 0; rdns[i] != NULL; i++ ) { + + /* Delete from entry attributes */ + if ( deleteoldrdn && rdn2typval( rdns[i], &type, &bv ) == 0 ) { + ldif_add_mod( &mods, LDAP_MOD_DELETE, type, bvps ); + } + } + slapi_ldap_value_free( rdns ); + } + slapi_ldap_value_free( dns ); + } + if ( dns == NULL || rdns == NULL ) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + goto error_return; + } + /* Add new rdn values to the entry */ + if ( (rdns = slapi_ldap_explode_rdn( newrdn, 0 )) != NULL ) { + for ( i = 0; rdns[i] != NULL; i++ ) { + /* Add to entry */ + if ( rdn2typval( rdns[i], &type, &bv ) == 0 ) { + ldif_add_mod( &mods, LDAP_MOD_ADD, type, bvps ); + } + } + slapi_ldap_value_free( rdns ); + } else { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + goto error_return; + } + bv.bv_val = newdn; + bv.bv_len = strlen( newdn ); + ldif_add_mod( &mods, LDAP_MOD_REPLACE, "entrydn", bvps ); + + /* Check for abandon */ + if ( slapi_op_abandoned( pb ) ) { + goto error_return; + } + + /* Apply the mods we built above to the copy of the entry */ + if ( apply_mods( entry2->lde_e, mods ) != 0 ) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + + goto error_return; + } + + /* Update the database and the disk */ + if ( update_db(pb, db, entry2, prev, LDIF_DB_REPLACE) != 0) { + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + + goto error_return; + } + + /*Unlock the database, and tell the user the good news*/ + PR_Unlock( db->ldif_lock ); + slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL ); + slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_modrdn\n", 0, 0, 0 ); + return( 0 ); + +error_return:; + + /* Result already sent above - just free stuff */ + PR_Unlock( db->ldif_lock ); + ldifentry_free( entry2 ); + + return( -1 ); +} + +/* + * Function: rdn2typval + * + * Returns: returns 0 if good, -1 else. + * + * Description: converts an rdn to a typeval + */ +int +rdn2typval(char *rdn, char **type, struct berval *bv) +{ + char *s; + + if ( (s = strchr( rdn, '=' )) == NULL ) { + return( -1 ); + } + *s++ = '\0'; + + *type = rdn; + bv->bv_val = s; + bv->bv_len = strlen( s ); + + return( 0 ); +} + +/* + * Function: ldif_add_mod + * + * Returns: void + * + * Description: Adds a modification (add, delete, etc) to the list + * of modifications that will eventually be made to some entry + */ +void +ldif_add_mod( LDAPMod ***modlist, int modtype, char *type, struct berval **bvps ) +{ + int i; + + for ( i = 0; modlist[i] != NULL; i++ ) { + ; /* NULL */ + } + + *modlist = (LDAPMod **) realloc( (char *) *modlist, + (i + 2) * sizeof(LDAPMod *) ); + + if (*modlist == NULL){ + slapi_log_err(SLAPI_LOG_ERR, "realloc failed", 0, 0, 0 ); + exit(1); + } + (*modlist)[i] = (LDAPMod *) malloc( sizeof(LDAPMod) ); + + if ((*modlist)[i] == NULL){ + slapi_log_err(SLAPI_LOG_ERR,"malloc failed", 0, 0, 0 ); + exit(1); + } + + (*modlist)[i]->mod_type = (char *) strdup( type ); + if ((*modlist)[i]->mod_type == NULL){ + slapi_log_err(SLAPI_LOG_ERR,"strdup failed", 0, 0, 0 ); + exit(1); + } + + + (*modlist)[i]->mod_op = modtype; + (*modlist)[i]->mod_bvalues = (struct berval **) malloc(2*sizeof(struct berval *)); + if ((*modlist)[i]->mod_bvalues == NULL){ + slapi_log_err(SLAPI_LOG_ERR,"malloc failed",0, 0, 0 ); + exit(1); + } + (*modlist)[i]->mod_bvalues[0] = ber_bvdup( bvps[0] ); + (*modlist)[i]->mod_bvalues[1] = NULL; + (*modlist)[i+1] = NULL; +} + + + + + + + diff --git a/src/contrib/back-ldif/monitor.c b/src/contrib/back-ldif/monitor.c new file mode 100644 index 0000000..e677fe8 --- /dev/null +++ b/src/contrib/back-ldif/monitor.c @@ -0,0 +1,132 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: monitor.c + * + * Functions: + * + * ldif_back_monitor_info() - ldap ldif back-end initialize routine + * + * get_monitordn() - gets the monitor dn for this backend + * + */ + +#include "back-ldif.h" + +extern char Versionstr[]; + + +/* + * Function: ldif_back_monitor_info + * + * Returns: returns 1 + * + * Description: This function wraps up backend specific monitor information + * and returns it to the client as an entry. This function + * is usually called by ldif_back_search upon receipt of + * the monitor dn for this backend. + */ +int +ldif_back_monitor_info( Slapi_PBlock *pb, LDIF *db) +{ + Slapi_Entry *e; /*Entry*/ + char buf[BUFSIZ]; /*Buffer for getting the attrs*/ + struct berval val; /*More attribute storage*/ + struct berval *vals[2]; /*Even more*/ + char *type; /*Database name (type) */ + + vals[0] = &val; + vals[1] = NULL; + + /*Alloc the entry and set the monitordn*/ + e = slapi_entry_alloc(); + slapi_entry_set_dn(e, (char *) get_monitordn(pb)); + + /* Get the database name (be_type) */ + slapi_pblock_get( pb, SLAPI_BE_TYPE, &type); + PR_snprintf( buf, sizeof(buf), "%s", type ); + val.bv_val = buf; + val.bv_len = strlen( buf ); + slapi_entry_attr_merge( e, "database", vals ); + + /*Lock the database*/ + PR_Lock( db->ldif_lock ); + + /*Get the number of database hits */ + sprintf( buf, "%ld", db->ldif_hits); + val.bv_val = buf; + val.bv_len = strlen( buf ); + slapi_entry_attr_merge( e, "entrycachehits", vals ); + + /*Get the number of database tries */ + sprintf( buf, "%ld", db->ldif_tries); + val.bv_val = buf; + val.bv_len = strlen( buf ); + slapi_entry_attr_merge( e, "entrycachetries", vals ); + + /*Get the current size of the entrycache (db) */ + sprintf( buf, "%ld", db->ldif_n); + val.bv_val = buf; + val.bv_len = strlen( buf ); + slapi_entry_attr_merge( e, "currententrycachesize", vals ); + + + /* + * Get the maximum size of the entrycache (db) + * in this database, there is no max, so return the current size + */ + val.bv_val = buf; + val.bv_len = strlen( buf ); + slapi_entry_attr_merge( e, "maxentrycachesize", vals ); + + /* Release the lock*/ + PR_Unlock( db->ldif_lock ); + + /*Send the results back to the client*/ + slapi_send_ldap_search_entry( pb, e, NULL, NULL, 0 ); + slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 1, NULL ); + + slapi_entry_free( e ); + + return(1); + + +} + + +/* + * Function: get_monitordn + * + * Returns: returns ptr to string if success, NULL else + * + * Description: get_monitordn takes a pblock and extracts the + * monitor dn of this backend. The monitordn is a special + * signal to the backend to return backend specific monitor + * information (usually called by back_ldif_search()). + */ +char * +get_monitordn(Slapi_PBlock *pb ) +{ + char *mdn; + + slapi_pblock_get( pb, SLAPI_BE_MONITORDN, &mdn ); + + if (mdn == NULL) { + return(NULL); + + } + + return(strdup(mdn)); + +} diff --git a/src/contrib/back-ldif/search.c b/src/contrib/back-ldif/search.c new file mode 100644 index 0000000..1cb2a40 --- /dev/null +++ b/src/contrib/back-ldif/search.c @@ -0,0 +1,205 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: search.c + * + * Functions: + * + * ldif_back_search() - ldif backend search function + * + */ + +#include "back-ldif.h" + +/* + * Function: ldif_back_search + * + * Returns: returns 0 if good, -1 else. + * + * Description: Searches the database for entries satisfying the + * user's criteria + */ +int +ldif_back_search( Slapi_PBlock *pb ) +{ + LDIF *db; /*The database*/ + char *base; /*Base of the search*/ + int scope; /*Scope of the search*/ + int deref; /*Should we dereference aliases?*/ + int slimit; /*Size limit of the search*/ + int tlimit; /*Time limit of the search*/ + Slapi_Filter *filter; /*The filter*/ + time_t dummy=0; /*Used for time()*/ + char **attrs; /*Attributes*/ + int attrsonly; /*Should we just return the attributes found?*/ + time_t optime; /*Time the operation started*/ + int nentries; /*Number of entries found thus far*/ + ldif_Entry *cur; /*Used for traversing the list of entries*/ + int hitflag=0; /*Used to test if we found the entry in the db*/ + char *freeme; /*Tmp storage for monitordn*/ + time_t currtime; /*The current time*/ + + slapi_log_err(SLAPI_LOG_TRACE, "=> ldif_back_search\n", 0, 0, 0 ); + + /* + * Get private information created in the init routine. + * Also get the parameters of the search operation. These come + * more or less directly from the client. + */ + if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &db ) < 0 || + slapi_pblock_get( pb, SLAPI_SEARCH_TARGET, &base ) < 0 || + slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope ) < 0 || + slapi_pblock_get( pb, SLAPI_SEARCH_DEREF, &deref ) < 0 || + slapi_pblock_get( pb, SLAPI_SEARCH_SIZELIMIT, &slimit ) < 0 || + slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit ) < 0 || + slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter ) < 0 || + slapi_pblock_get( pb, SLAPI_SEARCH_ATTRS, &attrs ) < 0 || + slapi_pblock_get( pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly ) <0 || + slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime ) < 0){ + slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL ); + return(-1); + } + + + /* + * If we get a search request for the backend monitor dn, + * call ldif_back_monitor_info(), which packages up the + * backend database analysis info and sends it back to the + * client + */ + if ( scope == LDAP_SCOPE_BASE ) { + + /*Get the backend's monitor dn*/ + freeme = (char *) get_monitordn(pb); + + if (freeme != NULL){ + + /* + * Compare the monitor dn with the base, + * if they match, call monitor_info, which + * will return all the relevant info to the client + */ + if ( strcasecmp( base, freeme) == 0 ) { + ldif_back_monitor_info( pb, db ); + free ((void *) freeme); + return(-1); + } + free ((void *) freeme); + } + } + + + /* + * First we lock the whole database (clumsy, inefficient and + * inelegant, but simple) + */ + PR_Lock( db->ldif_lock ); + + /*Increase the number of accesses*/ + db->ldif_tries++; + + /* + * Look through each entry in the ldif file and see if it matches + * the filter and scope of the search. Do this by calling the + * slapi_filter_test() routine. + */ + nentries = 0; + for (cur=db->ldif_entries; cur != NULL; cur = cur->next ) { + + /*Make sure we're not exceeding our time limit...*/ + currtime = time(&dummy); + if ((tlimit > 0) && ((currtime - optime) > (time_t)tlimit)){ + slapi_send_ldap_result( pb, LDAP_TIMELIMIT_EXCEEDED, NULL, NULL, nentries, NULL); + + /*We "hit" the cache*/ + if (hitflag) + { + db->ldif_hits++; + } + + PR_Unlock( db->ldif_lock ); + return(-1); + } + + /*...or that we haven't been abandoned*/ + if ( slapi_op_abandoned( pb ) ) { + + /*We "hit" the cache*/ + if (hitflag) + { + db->ldif_hits++; + } + + PR_Unlock( db->ldif_lock ); + return( -1 ); + } + + /*Test for exceedence of size limit*/ + if ((slimit > -1) && (nentries >= slimit)){ + slapi_send_ldap_result( pb, LDAP_SIZELIMIT_EXCEEDED, NULL, NULL, nentries, NULL); + + /*We hit the "cache"*/ + if (hitflag) + { + db->ldif_hits++; + } + PR_Unlock( db->ldif_lock ); + return(-1); + } + + + + /*Test if this entry matches the filter*/ + if ( slapi_vattr_filter_test( pb, cur->lde_e, filter, 1 /* verify access */ ) == 0 ) { + + /* Entry matches - send it */ + hitflag = 1; + + switch ( slapi_send_ldap_search_entry( pb, cur->lde_e, NULL, attrs, + attrsonly ) ) { + case 0: /* Entry sent ok */ + nentries++; + break; + case 1: /* Entry not sent - because of acl, etc. */ + break; + case -1:/* Connection closed */ + /* Clean up and return */ + + /*We "hit" the cache*/ + if (hitflag) + { + db->ldif_hits++; + } + PR_Unlock( db->ldif_lock ); + return( -1 ); + } + + + } + } + + /*If we succeeded, we should update the ldif_hits entry of db*/ + if (hitflag) + { + db->ldif_hits++; + } + + + /* Search is done, send LDAP_SUCCESS */ + slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, nentries, NULL ); + PR_Unlock( db->ldif_lock ); + slapi_log_err(SLAPI_LOG_TRACE, "<= ldif_back_search\n", 0, 0, 0 ); + return( -1 ); + +} diff --git a/src/contrib/back-ldif/start.c b/src/contrib/back-ldif/start.c new file mode 100644 index 0000000..ab7d29c --- /dev/null +++ b/src/contrib/back-ldif/start.c @@ -0,0 +1,39 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: start.c + * + * Functions: + * + * ldif_back_start() - ldap ldif back-end start routine + * + */ +#include "back-ldif.h" + +/* + * Function: ldif_back_start + * + * Returns: returns 0 + * + * Description: After the config file is read, the backend start function is called. + * This allows the backend writer to start any threads or perform any + * operations that need to be done after the config file has been read in. + * The ldif backend requires no such operations to be performed. + * + */ +int +ldif_back_start( Slapi_PBlock *pb ) +{ + return( 0 ); +} diff --git a/src/contrib/back-ldif/unbind.c b/src/contrib/back-ldif/unbind.c new file mode 100644 index 0000000..50f79c1 --- /dev/null +++ b/src/contrib/back-ldif/unbind.c @@ -0,0 +1,35 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2005 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * File: unbind.c + * + * Functions: + * + * ldif_back_unbind() - ldap ldif back-end unbind routine + * + */ +#include "back-ldif.h" + +/* + * Function: ldif_back_unbind + * + * Returns: returns 0 + * + * Description: performs an ldap unbind. + */ +int +ldif_back_unbind( Slapi_PBlock *pb ) +{ + return( 0 ); +}