nops.c revision 1.1.1.1
1/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/nops/nops.c,v 1.1.2.1 2008/05/27 20:00:51 quanah Exp $ */ 2/* nops.c - Overlay to filter idempotent operations */ 3/* 4 * Copyright 2008 Emmanuel Dreyfus 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted only as authorized by the OpenLDAP 9 * Public License. 10 * 11 * A copy of this license is available in the file LICENSE in the 12 * top-level directory of the distribution or, alternatively, at 13 * <http://www.OpenLDAP.org/license.html>. 14 */ 15#include "portable.h" 16 17#ifdef SLAPD_OVER_NOPS 18 19#include <stdio.h> 20 21#include <ac/string.h> 22#include <ac/socket.h> 23 24#include "lutil.h" 25#include "slap.h" 26#include "config.h" 27 28static ConfigDriver nops_cf_gen; 29 30static int nops_cf_gen( ConfigArgs *c ) { return 0; } 31 32static void 33nops_rm_mod( Modifications **mods, Modifications *mod ) { 34 Modifications *next, *m; 35 36 next = mod->sml_next; 37 if (*mods == mod) { 38 *mods = next; 39 } else { 40 Modifications *m; 41 42 for (m = *mods; m; m = m->sml_next) { 43 if (m->sml_next == mod) { 44 m->sml_next = next; 45 break; 46 } 47 } 48 } 49 50 for (m = *mods; m; m = m->sml_next) 51 mod->sml_next = NULL; 52 slap_mods_free(mod, 1); 53 54 return; 55} 56 57static int 58nops_modify( Operation *op, SlapReply *rs ) 59{ 60 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; 61 Backend *be = op->o_bd; 62 Entry *target_entry = NULL; 63 Modifications *m; 64 int rc; 65 66 if ((m = op->orm_modlist) == NULL) { 67 op->o_bd->bd_info = (BackendInfo *)(on->on_info); 68 send_ldap_error(op, rs, LDAP_INVALID_SYNTAX, 69 "nops() got null orm_modlist"); 70 return(rs->sr_err); 71 } 72 73 op->o_bd = on->on_info->oi_origdb; 74 rc = be_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &target_entry); 75 op->o_bd = be; 76 77 if (rc != 0 || target_entry == NULL) 78 return 0; 79 80 /* 81 * For each attribute modification, check if the 82 * modification and the old entry are the same. 83 */ 84 while (m) { 85 int i, j; 86 int found; 87 Attribute *a; 88 BerVarray bm; 89 BerVarray bt; 90 Modifications *mc; 91 92 mc = m; 93 m = m->sml_next; 94 95 /* Check only replace sub-operations */ 96 if ((mc->sml_op & LDAP_MOD_OP) != LDAP_MOD_REPLACE) 97 continue; 98 99 /* If there is no values, skip */ 100 if (((bm = mc->sml_values ) == NULL ) || (bm[0].bv_val == NULL)) 101 continue; 102 103 /* If the attribute does not exist in old entry, skip */ 104 if ((a = attr_find(target_entry->e_attrs, mc->sml_desc)) == NULL) 105 continue; 106 if ((bt = a->a_vals) == NULL) 107 continue; 108 109 /* For each value replaced, do we find it in old entry? */ 110 found = 0; 111 for (i = 0; bm[i].bv_val; i++) { 112 for (j = 0; bt[j].bv_val; j++) { 113 if (bm[i].bv_len != bt[j].bv_len) 114 continue; 115 if (memcmp(bm[i].bv_val, bt[j].bv_val, bt[j].bv_len) != 0) 116 continue; 117 118 found++; 119 break; 120 } 121 } 122 123 /* Did we find as many values as we had in old entry? */ 124 if (i != a->a_numvals || found != a->a_numvals) 125 continue; 126 127 /* This is a nop, remove it */ 128 Debug(LDAP_DEBUG_TRACE, "removing nop on %s%s%s", 129 a->a_desc->ad_cname.bv_val, "", ""); 130 131 nops_rm_mod(&op->orm_modlist, mc); 132 } 133 if (target_entry) { 134 op->o_bd = on->on_info->oi_origdb; 135 be_entry_release_r(op, target_entry); 136 op->o_bd = be; 137 } 138 139 if ((m = op->orm_modlist) == NULL) { 140 op->o_bd->bd_info = (BackendInfo *)(on->on_info); 141 send_ldap_error(op, rs, LDAP_SUCCESS, ""); 142 return(rs->sr_err); 143 return (rs->sr_err); 144 } 145 146 return SLAP_CB_CONTINUE; 147} 148 149static slap_overinst nops_ovl; 150 151#if SLAPD_OVER_NOPS == SLAPD_MOD_DYNAMIC 152static 153#endif 154int 155nops_initialize( void ) { 156 nops_ovl.on_bi.bi_type = "nops"; 157 nops_ovl.on_bi.bi_op_modify = nops_modify; 158 return overlay_register( &nops_ovl ); 159} 160 161#if SLAPD_OVER_NOPS == SLAPD_MOD_DYNAMIC 162int init_module(int argc, char *argv[]) { 163 return nops_initialize(); 164} 165#endif 166 167#endif /* defined(SLAPD_OVER_NOPS) */ 168 169