Logo Search packages:      
Sourcecode: ldapdiff version File versions  Download package

ldapmod.c

/*
    ldapdiff
    Copyright (C) 2000-2002 Thomas.Reith@rhoen.de

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <lber.h>
#include <ldap.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ldapdiff.h"

static void normalizeaddentry(struct s_modentry *smodentry, struct s_addmodentry **saddmodentry)
{
 struct s_modentry    *psmodentry;
 struct s_modentry    *tsmodentry;
 struct s_addmodentry *psaddmodentry;
 struct s_addmodentry *tsaddmodentry;

 psmodentry    = smodentry;
 psaddmodentry = *saddmodentry;
 tsaddmodentry = *saddmodentry;
 while(psaddmodentry != NULL){
  tsmodentry = psaddmodentry->attrlist;
  if(strcasecmp(tsmodentry->var,psmodentry->var) == 0){
   while(tsmodentry->next != NULL){
    tsmodentry = tsmodentry->next;
   }
   tsmodentry->next           = LDALLOC(1,sizeof(struct s_modentry));
   tsmodentry->next->var      = LDDUP(psmodentry->var);
   tsmodentry->next->val      = LDBINDUP(psmodentry->val,psmodentry->val_len);
   tsmodentry->next->val_len  = psmodentry->val_len;
   tsmodentry->next->val_type = psmodentry->val_type;
   tsmodentry->next->modtype  = psmodentry->modtype;
   tsmodentry->next->next     = NULL;
   psaddmodentry->count++;
   return;
  }
  tsaddmodentry = psaddmodentry;
  psaddmodentry = psaddmodentry->next;
 } 

 psaddmodentry                     = LDALLOC(1,sizeof(struct s_addmodentry));
 psaddmodentry->count              = 1;
 psaddmodentry->attrlist           = LDALLOC(1,sizeof(struct s_modentry));
 psaddmodentry->attrlist->var      = LDDUP(psmodentry->var);
 psaddmodentry->attrlist->val      = LDBINDUP(psmodentry->val,psmodentry->val_len);
 psaddmodentry->attrlist->val_len  = psmodentry->val_len;
 psaddmodentry->attrlist->val_type = psmodentry->val_type;
 psaddmodentry->attrlist->modtype  = psmodentry->modtype;
 psaddmodentry->attrlist->next     = NULL;

 if(tsaddmodentry == NULL){
  *saddmodentry = psaddmodentry;
 }
 else{
  tsaddmodentry->next = psaddmodentry;
 }
}

static int addentry(LDAP *ld,char *dnval,struct s_modentry *smodentry)
{
 LDAPMod              **lma;
 struct s_modentry     *psmodentry;
 struct s_addmodentry  *tsaddmodentry = NULL;
 struct s_addmodentry  *psaddmodentry;
 int                    rc;
 int                    numattr = 0;
 int                    count;
 int                    valcount;
 int                    retval = 0;

 /* 
 create a pointered list with one LDAPMod struct for multible values, 
 which is necessary for Openldap 2.0.22 and above
 */
 psmodentry = smodentry;
 while(psmodentry != NULL){
  normalizeaddentry(psmodentry,&tsaddmodentry);
  psmodentry = psmodentry->next;
 }

 psaddmodentry = tsaddmodentry;
 while(psaddmodentry != NULL){
  numattr++;
  ldiflog(LOG2,"normalized add %d values",psaddmodentry->count);
  ldiflogval(LOG2,"normalized add %s: %s",psaddmodentry->attrlist->var,psaddmodentry->attrlist->val,psaddmodentry->attrlist->val_len);
  psaddmodentry = psaddmodentry->next;
 }

 lma           = LDALLOC(numattr + 1,sizeof(LDAPMod*));
 count         = 0;
 psaddmodentry = tsaddmodentry;
 while(psaddmodentry != NULL){

  lma[count]                        = LDALLOC(1,sizeof(LDAPMod));
  lma[count]->mod_op                = LDAP_MOD_ADD|LDAP_MOD_BVALUES;
  lma[count]->mod_type              = LDDUP(psaddmodentry->attrlist->var);
  lma[count]->mod_vals.modv_bvals   = LDALLOC(psaddmodentry->count+1,sizeof(struct berval*));
  psmodentry = psaddmodentry->attrlist;
  valcount = 0;
  while( psmodentry != NULL){
   lma[count]->mod_vals.modv_bvals[valcount] = LDALLOC(1,sizeof(struct berval));
   lma[count]->mod_vals.modv_bvals[valcount]->bv_val = psmodentry->val;
   lma[count]->mod_vals.modv_bvals[valcount]->bv_len = psmodentry->val_len;
   valcount++;
   psmodentry = psmodentry->next;
  } 

  count++;
  psaddmodentry = psaddmodentry->next;
 }

 if((rc = ldap_add_s(ld,dnval,lma)) != LDAP_SUCCESS){
  ldiflog(LOG1,"error:   onlineadd    of %s",dnval);
  ldiflog(LOG1,"ldap_err2string(): %s",ldap_err2string(rc));
  retval = 1;
 } 
 else{
  ldiflog(LOG2,"success: onlineadd    of %s",dnval);
 }

 count = 0;
 psaddmodentry = tsaddmodentry;
 while(psaddmodentry != NULL){

  for(valcount=0;valcount<psaddmodentry->count;valcount++){
   free(lma[count]->mod_vals.modv_bvals[valcount]);
  }

  free(lma[count]->mod_vals.modv_bvals);
  free(lma[count]->mod_type);
  free(lma[count]);
 
  count++;
  psaddmodentry = psaddmodentry->next;
 }

 free(lma);

 return retval;
}

static int delentry(LDAP *ld,char *dnval)
{
 int rc;
 int retval = 0;

 if((rc = ldap_delete_s(ld,dnval)) != LDAP_SUCCESS){
  ldiflog(LOG1,"error:   onlinedelete of %s",dnval);
  ldiflog(LOG1,"ldap_err2string(): %s",ldap_err2string(rc));
  retval = 1;
 } 
 else{
  ldiflog(LOG2,"success:   onlinedelete of %s",dnval);
 }

 return retval;
}

static int modattr(LDAP *ld,char *dnval,char *var,char *val,size_t val_len,int mod_op)
{
 LDAPMod **lma;
 int       rc;
 int       retval = 0;
 
 switch(mod_op){
  case LDAP_MOD_REPLACE: /* no break */
  case LDAP_MOD_DELETE:  /* no break */
  case LDAP_MOD_ADD:
       if(var != NULL){
        lma    = LDALLOC(2,sizeof(LDAPMod*));
        lma[0] = LDALLOC(1,sizeof(LDAPMod));

        lma[0]->mod_op                          = mod_op|LDAP_MOD_BVALUES;
        lma[0]->mod_type                        = var;
        lma[0]->mod_vals.modv_bvals             = NULL;

        if(val != NULL){
         lma[0]->mod_vals.modv_bvals             = LDALLOC(2,sizeof(struct berval*));
         lma[0]->mod_vals.modv_bvals[0]          = LDALLOC(1,sizeof(struct berval));
         lma[0]->mod_vals.modv_bvals[0]->bv_val  = val;
         lma[0]->mod_vals.modv_bvals[0]->bv_len  = val_len;
        }

        if((rc = ldap_modify_s(ld,dnval,lma)) != LDAP_SUCCESS){
         ldiflog(LOG1,"error:   onlinemodify of %s",dnval);
         ldiflogval(LOG1,"                         %s: %s",var,val,val_len);
         ldiflog(LOG1,"ldap_err2string(): %s",ldap_err2string(rc));
         retval = 1;
        } 
        else{
         ldiflog(LOG2,"success: onlinemodify of %s",dnval);
         ldiflogval(LOG2,"                         %s: %s",var,val,val_len);
        }

        if(val != NULL){
         free(lma[0]->mod_vals.modv_bvals[0]);
         free(lma[0]->mod_vals.modv_bvals);
        }
        free(lma[0]);
        free(lma);
       }
       break;
 }

 return retval;
}

void ldifmodify(LDAP *ld,struct s_mod *smod,struct s_schema *sschema)
{
 struct s_mod      *psmod;
 struct s_modentry *psmodentry;
 int                errcount = 0;

 psmod = smod;

 while(psmod != NULL){
  switch(psmod->modtype){
   case MODADD:
        errcount += addentry(ld,psmod->dnval,psmod->attrlist);
        break;

   case MODMODIFY:
        psmodentry = psmod->attrlist;
        while(psmodentry != NULL){
         switch(psmodentry->modtype){
          case MODENTRYADD:
               errcount += modattr(ld,psmod->dnval,psmodentry->var,psmodentry->val,psmodentry->val_len,LDAP_MOD_ADD);
               break;
          case MODENTRYREPLACE:
               errcount += modattr(ld,psmod->dnval,psmodentry->var,psmodentry->val,psmodentry->val_len,LDAP_MOD_REPLACE);
               break;
          case MODENTRYDELETE:
               if(ldifschemaequal(sschema,psmodentry->var) == 1){
                errcount += modattr(ld,psmod->dnval,psmodentry->var,psmodentry->val,psmodentry->val_len,LDAP_MOD_DELETE);
               }
               else{
                errcount += modattr(ld,psmod->dnval,psmodentry->var,NULL,0,LDAP_MOD_DELETE);
               }
               break;
         } 
         psmodentry = psmodentry->next;
        }
        break;

   case MODDELETE:
        errcount += delentry(ld,psmod->dnval);
        break;

  }
  psmod = psmod->next;
 }

 ldiflog(LOG1,"write:      %10d online transactions failed",errcount); 
 
 if(errcount > 0 && strcmp(ldifgetgconf(CONFONLINEERRFATAL),"yes") == 0){
  exit(-1);
 } 
}

Generated by  Doxygen 1.6.0   Back to index