~ubuntu-branches/ubuntu/saucy/389-ds-base/saucy

« back to all changes in this revision

Viewing changes to ldap/servers/plugins/referint/referint.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2013-02-06 18:06:31 UTC
  • mfrom: (11.1.1 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20130206180631-h6ldv3k506hmm46e
Tags: 1.3.0.2-0ubuntu2
debian/*: Fix time stamps due to clock skew (FTBFS).

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
#include <sys/stat.h>
59
59
#endif
60
60
 
61
 
#define REFERINT_PLUGIN_SUBSYSTEM   "referint-plugin"   /* used for logging */
62
 
 
63
61
#ifdef _WIN32
64
62
#define REFERINT_DEFAULT_FILE_MODE      0
65
63
#else
66
64
#define REFERINT_DEFAULT_FILE_MODE S_IRUSR | S_IWUSR
67
65
#endif
68
66
 
69
 
 
 
67
#define REFERINT_PLUGIN_SUBSYSTEM   "referint-plugin"   /* used for logging */
70
68
#define MAX_LINE 2048
71
69
#define READ_BUFSIZE  4096
72
70
#define MY_EOF   0 
78
76
int referint_postop_start( Slapi_PBlock *pb);
79
77
int referint_postop_close( Slapi_PBlock *pb);
80
78
int update_integrity(char **argv, Slapi_DN *sDN, char *newrDN, Slapi_DN *newsuperior, int logChanges);
 
79
int GetNextLine(char *dest, int size_dest, PRFileDesc *stream);
 
80
int my_fgetc(PRFileDesc *stream);
81
81
void referint_thread_func(void *arg);
82
 
int  GetNextLine(char *dest, int size_dest, PRFileDesc *stream);
83
82
void writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn, char *newrdn, Slapi_DN *newsuperior, Slapi_DN *requestorsdn);
84
 
int my_fgetc(PRFileDesc *stream);
85
83
 
86
84
/* global thread control stuff */
87
 
 
88
85
static PRLock           *referint_mutex = NULL;       
89
86
static PRThread         *referint_tid = NULL;
90
 
int keeprunning = 0;
91
 
 
92
 
static PRLock           *keeprunning_mutex = NULL; 
93
 
static PRCondVar        *keeprunning_cv = NULL; 
94
 
 
95
 
static Slapi_PluginDesc pdesc = { "referint", VENDOR, DS_PACKAGE_VERSION,
96
 
        "referential integrity plugin" };
97
 
 
 
87
static PRLock           *keeprunning_mutex = NULL;
 
88
static PRCondVar    *keeprunning_cv = NULL;
 
89
static int keeprunning = 0;
 
90
static int refint_started = 0;
 
91
 
 
92
static Slapi_PluginDesc pdesc = { "referint", VENDOR, DS_PACKAGE_VERSION, "referential integrity plugin" };
 
93
static int allow_repl = 0;
98
94
static void* referint_plugin_identity = NULL;
99
95
 
 
96
static int use_txn = 0;
 
97
 
100
98
#ifdef _WIN32
101
99
int *module_ldap_debug = 0;
102
100
 
106
104
}
107
105
#endif
108
106
 
 
107
static void
 
108
referint_lock()
 
109
{
 
110
    if (use_txn) { /* no lock if betxn is enabled */
 
111
        return;
 
112
    }
 
113
    if (NULL == referint_mutex) {
 
114
        referint_mutex = PR_NewLock();
 
115
    }
 
116
    if (referint_mutex) {
 
117
        PR_Lock(referint_mutex);
 
118
    }
 
119
}
 
120
 
 
121
static void
 
122
referint_unlock()
 
123
{
 
124
    if (use_txn) { /* no lock if betxn is enabled */
 
125
        return;
 
126
    }
 
127
    if (referint_mutex) {
 
128
        PR_Unlock(referint_mutex);
 
129
    }
 
130
}
 
131
 
109
132
int
110
133
referint_postop_init( Slapi_PBlock *pb )
111
134
{
112
 
        Slapi_Entry *plugin_entry = NULL;
113
 
        char *plugin_type = NULL;
114
 
        int delfn = SLAPI_PLUGIN_POST_DELETE_FN;
115
 
        int mdnfn = SLAPI_PLUGIN_POST_MODRDN_FN;
116
 
 
117
 
        /*
118
 
         * Get plugin identity and stored it for later use
119
 
         * Used for internal operations
120
 
         */
121
 
 
122
 
        slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &referint_plugin_identity);
123
 
        PR_ASSERT (referint_plugin_identity);
124
 
 
125
 
        /* get args */ 
126
 
        if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
127
 
                plugin_entry &&
128
 
                (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
129
 
                plugin_type && strstr(plugin_type, "betxn")) {
130
 
                delfn = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
131
 
                mdnfn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
132
 
        }
133
 
        slapi_ch_free_string(&plugin_type);
134
 
 
135
 
        if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
136
 
                                SLAPI_PLUGIN_VERSION_01 ) != 0 ||
137
 
          slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
138
 
                     (void *)&pdesc ) != 0 ||
139
 
         slapi_pblock_set( pb, delfn,
140
 
                     (void *) referint_postop_del ) != 0 ||
141
 
         slapi_pblock_set( pb, mdnfn,
142
 
                     (void *) referint_postop_modrdn ) != 0 ||
143
 
         slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
144
 
                         (void *) referint_postop_start ) != 0 ||
145
 
             slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
146
 
                                 (void *) referint_postop_close ) != 0)
147
 
        {
148
 
            slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
149
 
                             "referint_postop_init failed\n" );
150
 
            return( -1 );
 
135
    Slapi_Entry *plugin_entry = NULL;
 
136
    char *plugin_type = NULL;
 
137
    int delfn = SLAPI_PLUGIN_POST_DELETE_FN;
 
138
    int mdnfn = SLAPI_PLUGIN_POST_MODRDN_FN;
 
139
 
 
140
    /*
 
141
     *  Get plugin identity and stored it for later use.
 
142
     *  Used for internal operations.
 
143
     */
 
144
    slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &referint_plugin_identity);
 
145
    PR_ASSERT (referint_plugin_identity);
 
146
 
 
147
    /* get the args */
 
148
    if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
 
149
         plugin_entry &&
 
150
         (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
 
151
         plugin_type && strstr(plugin_type, "betxn"))
 
152
    {
 
153
        delfn = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
 
154
        mdnfn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
 
155
        use_txn = 1;
 
156
    }
 
157
    if(plugin_entry){
 
158
        char *allow_repl_updates;
 
159
 
 
160
        allow_repl_updates = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-pluginAllowReplUpdates");
 
161
        if(allow_repl_updates && strcasecmp(allow_repl_updates,"on")==0){
 
162
            allow_repl = 1;
151
163
        }
152
 
 
153
 
        return( 0 );
 
164
        slapi_ch_free_string(&allow_repl_updates);
 
165
    }
 
166
    slapi_ch_free_string(&plugin_type);
 
167
 
 
168
    if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 ||
 
169
         slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&pdesc ) != 0 ||
 
170
         slapi_pblock_set( pb, delfn, (void *) referint_postop_del ) != 0 ||
 
171
         slapi_pblock_set( pb, mdnfn, (void *) referint_postop_modrdn ) != 0 ||
 
172
         slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN, (void *) referint_postop_start ) != 0 ||
 
173
         slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN, (void *) referint_postop_close ) != 0)
 
174
    {
 
175
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_postop_init failed\n" );
 
176
        return( -1 );
 
177
    }
 
178
 
 
179
    return( 0 );
154
180
}
155
181
 
156
182
 
157
183
int
158
184
referint_postop_del( Slapi_PBlock *pb )
159
185
{
160
 
        Slapi_DN *sdn = NULL;
161
 
        int rc;
162
 
        int oprc;
163
 
        char **argv;
164
 
        int argc;
165
 
        int delay;
166
 
        int logChanges=0;
167
 
        int isrepop = 0;
168
 
 
169
 
        if ( slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION, &isrepop ) != 0  ||
170
 
             slapi_pblock_get( pb, SLAPI_DELETE_TARGET_SDN, &sdn ) != 0  ||
171
 
             slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0) 
172
 
        {
173
 
            slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
174
 
                             "referint_postop_del: could not get parameters\n" );
175
 
            return( -1 );
176
 
        }
177
 
 
178
 
        /* this plugin should only execute if the delete was successful
179
 
                   and this is not a replicated op
180
 
            */
181
 
        if(oprc != 0 || isrepop)
182
 
        {
183
 
            return( 0 );
184
 
        }
185
 
        /* get args */ 
186
 
        if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGC, &argc ) != 0) { 
187
 
          slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
188
 
                     "referint_postop failed to get argc\n" );
189
 
          return( -1 ); 
190
 
        } 
191
 
        if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0) { 
192
 
          slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
193
 
                     "referint_postop failed to get argv\n" );
194
 
          return( -1 ); 
195
 
        } 
196
 
        
197
 
        if(argv == NULL){
198
 
          slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
199
 
                     "referint_postop_del, args are NULL\n" );
200
 
          return( -1 ); 
201
 
        }
202
 
        
203
 
        if (argc >= 3) {
204
 
                /* argv[0] will be the delay */
205
 
                delay = atoi(argv[0]);
206
 
 
207
 
                /* argv[2] will be wether or not to log changes */
208
 
                logChanges = atoi(argv[2]);
209
 
 
210
 
                if(delay == -1){
211
 
                  /* integrity updating is off */
212
 
                  rc = 0;
213
 
                }else if(delay == 0){
214
 
                  /* no delay */
215
 
                  /* call function to update references to entry */
216
 
                  rc = update_integrity(argv, sdn, NULL, NULL, logChanges);
217
 
                }else{
218
 
                  /* write the entry to integrity log */
219
 
                  writeintegritylog(pb, argv[1], sdn, NULL, NULL, NULL /* slapi_get_requestor_sdn(pb) */);
220
 
                  rc = 0;
221
 
                }
222
 
        } else {
223
 
                slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
224
 
                     "referint_postop insufficient arguments supplied\n" );
225
 
                return( -1 ); 
226
 
        }
227
 
 
228
 
        return( rc );
229
 
 
 
186
    Slapi_DN *sdn = NULL;
 
187
    char **argv;
 
188
    int argc;
 
189
    int delay;
 
190
    int logChanges=0;
 
191
    int isrepop = 0;
 
192
    int oprc;
 
193
    int rc;
 
194
 
 
195
    if (0 == refint_started) {
 
196
        /* not initialized yet */
 
197
        return 0;
 
198
    }
 
199
 
 
200
    if ( slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION, &isrepop ) != 0  ||
 
201
         slapi_pblock_get( pb, SLAPI_DELETE_TARGET_SDN, &sdn ) != 0  ||
 
202
         slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0)
 
203
    {
 
204
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
205
            "referint_postop_del: could not get parameters\n" );
 
206
        return( -1 );
 
207
    }
 
208
    /*
 
209
     *  This plugin should only execute if the delete was successful
 
210
     *  and this is not a replicated op(unless its allowed)
 
211
     */
 
212
    if(oprc != 0 || (isrepop && !allow_repl)){
 
213
        return( 0 );
 
214
    }
 
215
    /* get the args */
 
216
    if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGC, &argc ) != 0) {
 
217
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
218
            "referint_postop failed to get argc\n" );
 
219
        return( -1 );
 
220
    }
 
221
    if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0) {
 
222
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
223
            "referint_postop failed to get argv\n" );
 
224
        return( -1 );
 
225
    }
 
226
        
 
227
    if(argv == NULL){
 
228
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
229
            "referint_postop_del, args are NULL\n" );
 
230
        return( -1 );
 
231
    }
 
232
        
 
233
    if (argc >= 3) {
 
234
        /* argv[0] will be the delay */
 
235
        delay = atoi(argv[0]);
 
236
 
 
237
        /* argv[2] will be wether or not to log changes */
 
238
        logChanges = atoi(argv[2]);
 
239
 
 
240
        if(delay == -1){
 
241
            /* integrity updating is off */
 
242
            rc = 0;
 
243
        } else if(delay == 0){ /* no delay */
 
244
            /* call function to update references to entry */
 
245
            rc = update_integrity(argv, sdn, NULL, NULL, logChanges);
 
246
        } else {
 
247
            /* write the entry to integrity log */
 
248
            writeintegritylog(pb, argv[1], sdn, NULL, NULL, NULL /* slapi_get_requestor_sdn(pb) */);
 
249
            rc = 0;
 
250
        }
 
251
    } else {
 
252
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
253
            "referint_postop insufficient arguments supplied\n" );
 
254
        return( -1 );
 
255
    }
 
256
 
 
257
    return( rc );
230
258
}
231
259
 
232
260
int
233
261
referint_postop_modrdn( Slapi_PBlock *pb )
234
262
{
235
 
        Slapi_DN *sdn = NULL;
236
 
        char    *newrdn;
237
 
        Slapi_DN *newsuperior;
238
 
        int oprc;
239
 
        int rc;
240
 
        char **argv;
241
 
        int argc = 0;
242
 
        int delay;
243
 
        int logChanges=0;
244
 
        int isrepop = 0;
245
 
 
246
 
        if ( slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION, &isrepop ) != 0  ||
247
 
                 slapi_pblock_get( pb, SLAPI_MODRDN_TARGET_SDN, &sdn ) != 0 ||
248
 
                 slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn ) != 0 ||
249
 
                 slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperior ) != 0 ||
250
 
                 slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0 ){
251
 
 
252
 
                slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
253
 
                    "referint_postop_modrdn: could not get parameters\n" );
254
 
                return( -1 );
255
 
        }
256
 
 
257
 
        /* this plugin should only execute if the delete was successful 
258
 
           and this is not a replicated op
259
 
        */
260
 
        if(oprc != 0 || isrepop){
261
 
          return( 0 );
262
 
        }
263
 
        /* get args */ 
264
 
        if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGC, &argc ) != 0) { 
265
 
          slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
266
 
                     "referint_postop failed to get argv\n" ); 
267
 
          return( -1 ); 
268
 
        } 
269
 
        if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0) { 
270
 
          slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
271
 
                     "referint_postop failed to get argv\n" );
272
 
          return( -1 ); 
273
 
        } 
274
 
        
275
 
        if(argv == NULL){
276
 
          slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
277
 
                     "referint_postop_modrdn, args are NULL\n" ); 
278
 
          return( -1 ); 
279
 
        }
280
 
 
281
 
        if (argc >= 3) {
282
 
                /* argv[0] will always be the delay */
283
 
                delay = atoi(argv[0]);
284
 
 
285
 
                /* argv[2] will be wether or not to log changes */
286
 
                logChanges = atoi(argv[2]);
287
 
        } else {
288
 
                slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
289
 
                     "referint_postop_modrdn insufficient arguments supplied\n" );
290
 
                return( -1 ); 
291
 
        }
292
 
 
293
 
        if(delay == -1){
294
 
          /* integrity updating is off */
295
 
          rc = 0;
296
 
        }else if(delay == 0){
297
 
          /* no delay */
298
 
          /* call function to update references to entry */
299
 
          rc = update_integrity(argv, sdn, newrdn, newsuperior, logChanges);
300
 
        }else{
301
 
          /* write the entry to integrity log */
302
 
          writeintegritylog(pb, argv[1], sdn, newrdn, newsuperior, NULL /* slapi_get_requestor_sdn(pb) */);
303
 
          rc = 0;
304
 
        }
305
 
 
306
 
        return( rc );
 
263
    Slapi_DN *sdn = NULL;
 
264
    Slapi_DN *newsuperior;
 
265
    char *newrdn;
 
266
    char **argv;
 
267
    int oprc;
 
268
    int rc;
 
269
    int argc = 0;
 
270
    int delay;
 
271
    int logChanges=0;
 
272
    int isrepop = 0;
 
273
 
 
274
    if ( slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION, &isrepop ) != 0  ||
 
275
         slapi_pblock_get( pb, SLAPI_MODRDN_TARGET_SDN, &sdn ) != 0 ||
 
276
         slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn ) != 0 ||
 
277
         slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperior ) != 0 ||
 
278
         slapi_pblock_get( pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0 )
 
279
    {
 
280
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
281
            "referint_postop_modrdn: could not get parameters\n" );
 
282
        return( -1 );
 
283
    }
 
284
    /*
 
285
     *  This plugin should only execute if the delete was successful
 
286
     *  and this is not a replicated op (unless its allowed)
 
287
     */
 
288
    if(oprc != 0 || (isrepop && !allow_repl)){
 
289
        return( 0 );
 
290
    }
 
291
    /* get the args */
 
292
    if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGC, &argc ) != 0) {
 
293
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
294
            "referint_postop failed to get argv\n" );
 
295
        return( -1 );
 
296
    }
 
297
    if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0) {
 
298
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
299
            "referint_postop failed to get argv\n" );
 
300
        return( -1 );
 
301
    }
 
302
    if(argv == NULL){
 
303
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
304
            "referint_postop_modrdn, args are NULL\n" );
 
305
        return( -1 );
 
306
    }
 
307
 
 
308
    if (argc >= 3) {
 
309
        /* argv[0] will always be the delay */
 
310
        delay = atoi(argv[0]);
 
311
 
 
312
        /* argv[2] will be wether or not to log changes */
 
313
        logChanges = atoi(argv[2]);
 
314
    } else {
 
315
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
316
            "referint_postop_modrdn insufficient arguments supplied\n" );
 
317
        return( -1 );
 
318
    }
 
319
 
 
320
    if(delay == -1){
 
321
        /* integrity updating is off */
 
322
        rc = 0;
 
323
    } else if(delay == 0){ /* no delay */
 
324
        /* call function to update references to entry */
 
325
        rc = update_integrity(argv, sdn, newrdn, newsuperior, logChanges);
 
326
    } else {
 
327
        /* write the entry to integrity log */
 
328
        writeintegritylog(pb, argv[1], sdn, newrdn, newsuperior, NULL /* slapi_get_requestor_sdn(pb) */);
 
329
        rc = 0;
 
330
    }
 
331
 
 
332
    return( rc );
307
333
}
308
334
 
309
335
int isFatalSearchError(int search_result)
310
336
{
311
 
 
312
337
    /*   Make sure search result is fatal 
313
338
     *   Some conditions that happen quite often are not fatal 
314
339
     *   for example if you have two suffixes and one is null, you will always
315
 
     *   get no such object, howerever this is not a fatal error. 
 
340
     *   get no such object, however this is not a fatal error.
316
341
     *   Add other conditions to the if statement as they are found
317
342
     */
318
 
 
319
 
        /* NPCTE fix for bugid 531225, esc 0. <P.R> <30-May-2001> */
320
 
        switch(search_result) {
321
 
                case LDAP_REFERRAL: 
322
 
                case LDAP_NO_SUCH_OBJECT: return 0 ;
323
 
        }
324
 
        return 1;
325
 
         /* end of NPCTE fix for bugid 531225 */
326
 
 
 
343
    switch(search_result) {
 
344
        case LDAP_REFERRAL:
 
345
        case LDAP_NO_SUCH_OBJECT: return 0 ;
 
346
    }
 
347
    return 1;
327
348
}
328
349
 
329
350
static int
333
354
 
334
355
    slapi_pblock_init(mod_pb);
335
356
 
336
 
    /* Use internal operation API */
337
 
    slapi_modify_internal_set_pb_ext(mod_pb, entrySDN, mods, NULL, NULL,
338
 
                                     referint_plugin_identity, 0);
 
357
    if(allow_repl){
 
358
        /* Must set as a replicated operation */
 
359
        slapi_modify_internal_set_pb_ext(mod_pb, entrySDN, mods, NULL, NULL,
 
360
                                         referint_plugin_identity, OP_FLAG_REPLICATED);
 
361
    } else {
 
362
        slapi_modify_internal_set_pb_ext(mod_pb, entrySDN, mods, NULL, NULL,
 
363
                                         referint_plugin_identity, 0);
 
364
    }
339
365
    slapi_modify_internal_pb(mod_pb);
340
366
    slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
341
367
    
354
380
                    const char *newsuperior, /* new superior from modrdn */
355
381
                    Slapi_PBlock *mod_pb)
356
382
{
 
383
    LDAPMod attribute1, attribute2;
357
384
    LDAPMod *list_of_mods[3];
358
385
    char *values_del[2];
359
386
    char *values_add[2];
361
388
    char **dnParts = NULL;
362
389
    char *sval = NULL;
363
390
    char *newvalue = NULL;
364
 
    LDAPMod attribute1, attribute2;
 
391
    char *p = NULL;
 
392
    size_t dnlen = 0;
365
393
    int rc = 0;
366
394
 
367
395
    if (NULL == newRDN && NULL == newsuperior) {
431
459
         * member: uid=A,ou=B,ou=C --> uid=A,ou=B',ou=C
432
460
         *         (sval)              (sval' + newDN)
433
461
         */
434
 
        for (nval = slapi_attr_first_value(attr, &v);
435
 
             nval != -1;
 
462
        for (nval = slapi_attr_first_value(attr, &v); nval != -1;
436
463
             nval = slapi_attr_next_value(attr, nval, &v)) {
437
 
            char *p = NULL;
438
 
            size_t dnlen = 0;
 
464
            p = NULL;
 
465
            dnlen = 0;
 
466
 
439
467
            /* DN syntax, which should be a string */
440
468
            sval = slapi_ch_strdup(slapi_value_get_string(v));
441
469
            rc = slapi_dn_normalize_case_ext(sval, 0,  &p, &dnlen);
536
564
    char **dnParts = NULL;
537
565
    char *sval = NULL;
538
566
    char *newvalue = NULL;
 
567
    char *p = NULL;
 
568
    size_t dnlen = 0;
539
569
    int rc = 0;
540
570
    int nval = 0;
541
571
 
619
649
        for (nval = slapi_attr_first_value(attr, &v);
620
650
             nval != -1;
621
651
             nval = slapi_attr_next_value(attr, nval, &v)) {
622
 
            char *p = NULL;
623
 
            size_t dnlen = 0;
 
652
            p = NULL;
 
653
            dnlen = 0;
 
654
 
624
655
            /* DN syntax, which should be a string */
625
656
            sval = slapi_ch_strdup(slapi_value_get_string(v));
626
657
            rc = slapi_dn_normalize_case_ext(sval, 0,  &p, &dnlen);
665
696
        slapi_ch_free_string(&newDN);
666
697
        slapi_mods_free(&smods);
667
698
    }
 
699
 
668
700
bail:
669
701
    return rc;
670
702
}
677
709
    Slapi_PBlock *search_result_pb = NULL;
678
710
    Slapi_PBlock *mod_pb = slapi_pblock_new();
679
711
    Slapi_Entry  **search_entries = NULL;
680
 
    int search_result;
681
712
    Slapi_DN *sdn = NULL;
 
713
    Slapi_Attr *attr = NULL;
682
714
    void *node = NULL;
 
715
    const char *origDN = slapi_sdn_get_dn(origSDN);
 
716
    const char *search_base = NULL;
 
717
    char *attrName = NULL;
683
718
    char *filter = NULL;
 
719
    char *attrs[2];
 
720
    int search_result;
 
721
    int nval = 0;
684
722
    int i, j;
685
 
    const char *search_base = NULL;
686
723
    int rc;
687
 
    size_t len = slapi_sdn_get_ndn_len(origSDN);
688
 
    const char *origDN = slapi_sdn_get_dn(origSDN);
689
 
   
690
 
    if ( argv == NULL ) {
 
724
 
 
725
    if ( argv == NULL ){
691
726
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
692
727
            "referint_postop required config file arguments missing\n" );
693
728
        rc = -1;
694
729
        goto free_and_return;
695
730
    } 
696
 
  
697
 
    /* for now, just putting attributes to keep integrity on in conf file,
698
 
       until resolve the other timing mode issue */
 
731
    /*
 
732
     *  For now, just putting attributes to keep integrity on in conf file,
 
733
     *  until resolve the other timing mode issue
 
734
     */
699
735
    search_result_pb = slapi_pblock_new();
700
736
 
701
737
    /* Search each namingContext in turn */
702
738
    for ( sdn = slapi_get_first_suffix( &node, 0 ); sdn != NULL;
703
739
          sdn = slapi_get_next_suffix( &node, 0 ))
704
740
    {
 
741
        Slapi_Backend *be = slapi_be_select(sdn);
705
742
        search_base = slapi_sdn_get_dn( sdn );
706
743
 
707
 
        for(i = 3; argv[i] != NULL; i++)
708
 
        {
709
 
            char buf[BUFSIZ];
710
 
            filter = slapi_ch_smprintf("(%s=*%s)", argv[i],
711
 
                                    escape_filter_value(origDN, len, buf));
 
744
        for(i = 3; argv[i] != NULL; i++){
 
745
            filter = slapi_filter_sprintf("(%s=*%s%s)", argv[i], ESC_NEXT_VAL, origDN);
712
746
            if ( filter ) {
713
747
                /* Need only the current attribute and its subtypes */
714
 
                char *attrs[2];
715
748
                attrs[0] = argv[i];
716
749
                attrs[1] = NULL;
717
750
 
718
751
                /* Use new search API */
719
752
                slapi_pblock_init(search_result_pb);
 
753
                slapi_pblock_set(search_result_pb, SLAPI_BACKEND, be);
720
754
                slapi_search_internal_set_pb(search_result_pb, search_base, 
721
755
                    LDAP_SCOPE_SUBTREE, filter, attrs, 0 /* attrs only */,
722
756
                    NULL, NULL, referint_plugin_identity, 0);
723
757
                slapi_search_internal_pb(search_result_pb);
724
758
  
725
 
                slapi_pblock_get( search_result_pb, SLAPI_PLUGIN_INTOP_RESULT, 
726
 
                                  &search_result);
 
759
                slapi_pblock_get( search_result_pb, SLAPI_PLUGIN_INTOP_RESULT, &search_result);
727
760
 
728
761
                /* if search successfull then do integrity update */
729
762
                if(search_result == LDAP_SUCCESS)
730
763
                {
731
 
                    slapi_pblock_get(search_result_pb,
732
 
                                     SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
 
764
                    slapi_pblock_get(search_result_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
733
765
                                     &search_entries);
734
766
 
735
 
                    for(j=0; search_entries[j] != NULL; j++)
736
 
                    {
737
 
                        Slapi_Attr *attr = NULL;
738
 
                        char *attrName = NULL;
739
 
 
740
 
                        /* Loop over all the attributes of the entry and search
741
 
                         * for the integrity attribute and its subtypes */
 
767
                    for(j = 0; search_entries[j] != NULL; j++){
 
768
                        attr = NULL;
 
769
                        attrName = NULL;
 
770
                        /*
 
771
                         *  Loop over all the attributes of the entry and search
 
772
                         *  for the integrity attribute and its subtypes
 
773
                         */
742
774
                        for (slapi_entry_first_attr(search_entries[j], &attr); attr; 
743
775
                             slapi_entry_next_attr(search_entries[j], attr, &attr))
744
776
                        {
745
 
                            /* Take into account only the subtypes of the attribute 
746
 
                             * in argv[i] having the necessary value  - origDN */
 
777
                            /*
 
778
                             *  Take into account only the subtypes of the attribute
 
779
                             *  in argv[i] having the necessary value  - origDN
 
780
                             */
747
781
                            slapi_attr_get_type(attr, &attrName);
748
782
                            if (slapi_attr_type_cmp(argv[i], attrName,
749
783
                                                    SLAPI_TYPE_CMP_SUBTYPE) == 0)
750
784
                            {
751
 
                                int nval = 0;
 
785
                                nval = 0;
752
786
                                slapi_attr_get_numvalues(attr, &nval);
753
 
 
754
787
                                /* 
755
788
                                 * We want to reduce the "modify" call as much as
756
789
                                 * possible. But if an entry contains 1000s of 
781
814
                        }
782
815
                    }
783
816
                } else {
784
 
                    if (isFatalSearchError(search_result))
785
 
                    {
786
 
                        /* NPCTE fix for bugid 531225, esc 0. <P.R> <30-May-2001> */
 
817
                    if (isFatalSearchError(search_result)){
787
818
                        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
788
819
                            "update_integrity search (base=%s filter=%s) returned "
789
820
                            "error %d\n", search_base, filter, search_result);
790
 
                        /* end of NPCTE fix for bugid 531225 */
791
821
                        rc = -1;
792
822
                        goto free_and_return;
793
823
                    }
794
824
                }
795
 
 
796
825
                slapi_ch_free_string(&filter);
797
826
            }
798
 
  
799
827
            slapi_free_search_results_internal(search_result_pb);
800
828
        }
801
829
    }
817
845
 
818
846
int referint_postop_start( Slapi_PBlock *pb)
819
847
{
820
 
 
821
848
    char **argv;
822
 
        int argc = 0;
 
849
    int argc = 0;
823
850
 
824
851
    /* get args */ 
825
852
    if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGC, &argc ) != 0 ) { 
826
 
          slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
827
 
                     "referint_postop failed to get argv\n" );
828
 
          return( -1 ); 
 
853
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
854
            "referint_postop failed to get argv\n" );
 
855
        return( -1 );
829
856
    } 
830
857
    if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0 ) { 
831
 
          slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
832
 
                     "referint_postop failed to get argv\n" );
833
 
          return( -1 ); 
 
858
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
859
            "referint_postop failed to get argv\n" );
 
860
        return( -1 );
834
861
    } 
835
 
 
836
862
    if(argv == NULL){
837
863
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
838
 
                  "args were null in referint_postop_start\n" );
839
 
        return( -1  );
 
864
            "args were null in referint_postop_start\n" );
 
865
        return( -1  );
840
866
    }
841
 
 
842
 
    /* only bother to start the thread if you are in delay mode. 
843
 
       0  = no delay,
844
 
       -1 = integrity off */
845
 
 
846
 
        if (argc >= 1) {
847
 
                if(atoi(argv[0]) > 0){
848
 
 
849
 
                  /* initialize  cv and lock */
850
 
                         
851
 
                  referint_mutex = PR_NewLock();
852
 
                  keeprunning_mutex = PR_NewLock();
853
 
                  keeprunning_cv = PR_NewCondVar(keeprunning_mutex);
854
 
                  keeprunning =1;
 
867
    /*
 
868
     *  Only bother to start the thread if you are in delay mode.
 
869
     *     0  = no delay,
 
870
     *     -1 = integrity off
 
871
     */
 
872
    if (argc >= 1) {
 
873
        if(atoi(argv[0]) > 0){
 
874
            /* initialize the cv and lock */
 
875
            if (!use_txn && (NULL == referint_mutex)) {
 
876
                referint_mutex = PR_NewLock();
 
877
            }
 
878
            keeprunning_mutex = PR_NewLock();
 
879
            keeprunning_cv = PR_NewCondVar(keeprunning_mutex);
 
880
            keeprunning =1;
855
881
                        
856
 
                  referint_tid = PR_CreateThread (PR_USER_THREAD, 
857
 
                                                        referint_thread_func, 
858
 
                                                        (void *)argv,
859
 
                                                        PR_PRIORITY_NORMAL, 
860
 
                                                        PR_GLOBAL_THREAD, 
861
 
                                                        PR_UNJOINABLE_THREAD, 
862
 
                                                        SLAPD_DEFAULT_THREAD_STACKSIZE);
863
 
                  if ( referint_tid == NULL ) {
864
 
                        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
865
 
                                   "referint_postop_start PR_CreateThread failed\n" );
866
 
                        exit( 1 );
867
 
                  }
868
 
                }
869
 
        } else {
870
 
                slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
871
 
                     "referint_postop_start insufficient arguments supplied\n" );
872
 
                return( -1 ); 
873
 
        }
 
882
            referint_tid = PR_CreateThread (PR_USER_THREAD,
 
883
                               referint_thread_func,
 
884
                               (void *)argv,
 
885
                               PR_PRIORITY_NORMAL,
 
886
                               PR_GLOBAL_THREAD,
 
887
                               PR_UNJOINABLE_THREAD,
 
888
                               SLAPD_DEFAULT_THREAD_STACKSIZE);
 
889
            if ( referint_tid == NULL ) {
 
890
                slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
891
                    "referint_postop_start PR_CreateThread failed\n" );
 
892
                exit( 1 );
 
893
            }
 
894
        }
 
895
    } else {
 
896
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
897
            "referint_postop_start insufficient arguments supplied\n" );
 
898
        return( -1 );
 
899
    }
874
900
 
 
901
    refint_started = 1;
875
902
    return(0);
876
 
 
877
903
}
878
904
 
879
905
int referint_postop_close( Slapi_PBlock *pb)
880
906
{
881
 
 
882
 
        /* signal the thread to exit */
883
 
        if (NULL != keeprunning_mutex) {
884
 
                PR_Lock(keeprunning_mutex);  
885
 
                keeprunning=0;
886
 
                if (NULL != keeprunning_cv) {
887
 
                        PR_NotifyCondVar(keeprunning_cv);
888
 
                }
889
 
                PR_Unlock(keeprunning_mutex);  
890
 
        }
891
 
 
892
 
        return(0);
 
907
    /* signal the thread to exit */
 
908
    if (NULL != keeprunning_mutex) {
 
909
        PR_Lock(keeprunning_mutex);
 
910
        keeprunning=0;
 
911
        if (NULL != keeprunning_cv) {
 
912
            PR_NotifyCondVar(keeprunning_cv);
 
913
        }
 
914
        PR_Unlock(keeprunning_mutex);
 
915
    }
 
916
 
 
917
    refint_started = 0;
 
918
    return(0);
893
919
}
894
920
 
895
921
void
896
922
referint_thread_func(void *arg)
897
923
{
 
924
    PRFileDesc *prfd;
898
925
    char **plugin_argv = (char **)arg;
899
 
    PRFileDesc *prfd;
900
926
    char *logfilename;
901
927
    char thisline[MAX_LINE];
902
 
    int delay;
903
 
    int no_changes;
904
928
    char delimiter[]="\t\n";
905
929
    char *ptoken;
906
 
        Slapi_DN *sdn = NULL;
907
930
    char *tmprdn;
 
931
    char *iter = NULL;
 
932
    Slapi_DN *sdn = NULL;
908
933
    Slapi_DN *tmpsuperior = NULL;
909
 
    int logChanges=0;
910
 
        char * iter = NULL;
 
934
    int logChanges = 0;
 
935
    int delay;
 
936
    int no_changes;
911
937
 
912
938
    if(plugin_argv == NULL){
913
 
      slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
914
 
                 "referint_thread_func not get args \n" );
915
 
      return;
 
939
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
940
            "referint_thread_func not get args \n" );
 
941
        return;
916
942
    }
917
943
 
918
 
    /* initialize the thread data index
919
 
    if(slapi_td_dn_init()){
920
 
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,"Failed to create thread data index\n");
921
 
 
922
 
    } */
923
 
 
924
944
    delay = atoi(plugin_argv[0]);
925
945
    logfilename = plugin_argv[1]; 
926
 
        logChanges = atoi(plugin_argv[2]);
927
 
 
928
 
    /* keep running this thread until plugin is signalled to close */
929
 
 
 
946
    logChanges = atoi(plugin_argv[2]);
 
947
    /*
 
948
     * keep running this thread until plugin is signaled to close
 
949
     */
930
950
    while(1){ 
931
 
 
932
951
        no_changes=1;
933
 
 
934
952
        while(no_changes){
935
 
 
936
 
            PR_Lock(keeprunning_mutex);
937
 
            if(keeprunning == 0){
938
 
                PR_Unlock(keeprunning_mutex);  
939
 
               break;
940
 
            }
941
 
            PR_Unlock(keeprunning_mutex);  
942
 
 
943
 
 
944
 
            PR_Lock(referint_mutex);
945
 
        if (( prfd = PR_Open( logfilename, PR_RDONLY,
946
 
                                  REFERINT_DEFAULT_FILE_MODE )) == NULL ) 
947
 
        {
948
 
            PR_Unlock(referint_mutex);  
949
 
            /* go back to sleep and wait for this file */
950
 
                PR_Lock(keeprunning_mutex);
951
 
            PR_WaitCondVar(keeprunning_cv, PR_SecondsToInterval(delay));
 
953
            PR_Lock(keeprunning_mutex);
 
954
            if(keeprunning == 0){
 
955
                PR_Unlock(keeprunning_mutex);
 
956
                break;
 
957
            }
952
958
            PR_Unlock(keeprunning_mutex);
953
 
            }else{
954
 
                no_changes = 0;
955
 
            }
956
 
        }
957
959
 
958
 
        /* check keep running here, because after break out of no
959
 
         * changes loop on shutdown, also need to break out of this
960
 
         * loop before trying to do the changes. The server
961
 
         * will pick them up on next startup as file still exists 
962
 
         */
 
960
            referint_lock();
 
961
            if (( prfd = PR_Open( logfilename, PR_RDONLY, REFERINT_DEFAULT_FILE_MODE )) == NULL ){
 
962
                referint_unlock();
 
963
                /* go back to sleep and wait for this file */
 
964
                PR_Lock(keeprunning_mutex);
 
965
                PR_WaitCondVar(keeprunning_cv, PR_SecondsToInterval(delay));
 
966
                PR_Unlock(keeprunning_mutex);
 
967
            } else {
 
968
                no_changes = 0;
 
969
            }
 
970
        }
 
971
        /*
 
972
         *  Check keep running here, because after break out of no
 
973
         *  changes loop on shutdown, also need to break out of this
 
974
         *  loop before trying to do the changes. The server
 
975
         *  will pick them up on next startup as file still exists
 
976
         */
963
977
        PR_Lock(keeprunning_mutex);
964
978
        if(keeprunning == 0){
965
 
            PR_Unlock(keeprunning_mutex);  
966
 
            break;
 
979
            PR_Unlock(keeprunning_mutex);
 
980
            break;
967
981
        }
968
982
        PR_Unlock(keeprunning_mutex);  
969
 
    
970
 
  
971
 
        while( GetNextLine(thisline, MAX_LINE, prfd) ){
972
 
            ptoken = ldap_utf8strtok_r(thisline, delimiter, &iter);
973
 
                sdn = slapi_sdn_new_normdn_byref(ptoken);
974
 
 
975
 
            ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter);
976
 
            if(!strcasecmp(ptoken, "NULL")) {
977
 
                tmprdn = NULL;
978
 
            } else {
979
 
                tmprdn = slapi_ch_smprintf("%s", ptoken);
980
 
            }
981
 
 
982
 
            ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter);
983
 
            if (!strcasecmp(ptoken, "NULL")) {
984
 
                tmpsuperior = NULL;
985
 
            } else {
986
 
                tmpsuperior = slapi_sdn_new_normdn_byref(ptoken);
987
 
            }
988
 
            ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter);
989
 
            if (strcasecmp(ptoken, "NULL") != 0) {
990
 
                /* Set the bind DN in the thread data */
991
 
                if(slapi_td_set_dn(slapi_ch_strdup(ptoken))){
992
 
                        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,"Failed to set thread data\n");
993
 
                }
994
 
            }
995
 
      
996
 
            update_integrity(plugin_argv, sdn, tmprdn,
997
 
                             tmpsuperior, logChanges);
998
 
      
999
 
            slapi_sdn_free(&sdn);
1000
 
            slapi_ch_free_string(&tmprdn);
1001
 
            slapi_sdn_free(&tmpsuperior);
1002
 
        }
1003
 
 
1004
 
        PR_Close(prfd);
1005
 
      
1006
 
    /* remove the original file */
1007
 
    if( PR_SUCCESS != PR_Delete(logfilename) )
1008
 
    {
1009
 
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
1010
 
                         "referint_postop_close could not delete \"%s\"\n",
1011
 
                          logfilename );
1012
 
    }
1013
 
 
1014
 
        /* unlock and let other writers back at the file */
1015
 
        PR_Unlock(referint_mutex);
1016
 
        
1017
 
        /* wait on condition here */
1018
 
        PR_Lock(keeprunning_mutex);
1019
 
        PR_WaitCondVar(keeprunning_cv, PR_SecondsToInterval(delay));
1020
 
        PR_Unlock(keeprunning_mutex);
1021
 
    }
1022
 
 
1023
 
        /* cleanup resources allocated in start  */
1024
 
        if (NULL != keeprunning_mutex) {
1025
 
                PR_DestroyLock(keeprunning_mutex);
1026
 
        }
1027
 
        if (NULL != referint_mutex) {
1028
 
                PR_DestroyLock(referint_mutex);
1029
 
        }
1030
 
        if (NULL != keeprunning_cv) {
1031
 
                PR_DestroyCondVar(keeprunning_cv);
1032
 
        }
1033
 
 
1034
 
 
 
983
 
 
984
        while( GetNextLine(thisline, MAX_LINE, prfd) ){
 
985
            ptoken = ldap_utf8strtok_r(thisline, delimiter, &iter);
 
986
            sdn = slapi_sdn_new_normdn_byref(ptoken);
 
987
            ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter);
 
988
 
 
989
            if(!strcasecmp(ptoken, "NULL")) {
 
990
                tmprdn = NULL;
 
991
            } else {
 
992
                tmprdn = slapi_ch_smprintf("%s", ptoken);
 
993
            }
 
994
 
 
995
            ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter);
 
996
            if (!strcasecmp(ptoken, "NULL")) {
 
997
                tmpsuperior = NULL;
 
998
            } else {
 
999
                tmpsuperior = slapi_sdn_new_normdn_byref(ptoken);
 
1000
            }
 
1001
            ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter);
 
1002
            if (strcasecmp(ptoken, "NULL") != 0) {
 
1003
                /* Set the bind DN in the thread data */
 
1004
                if(slapi_td_set_dn(slapi_ch_strdup(ptoken))){
 
1005
                    slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,"Failed to set thread data\n");
 
1006
                }
 
1007
            }
 
1008
 
 
1009
            update_integrity(plugin_argv, sdn, tmprdn, tmpsuperior, logChanges);
 
1010
 
 
1011
            slapi_sdn_free(&sdn);
 
1012
            slapi_ch_free_string(&tmprdn);
 
1013
            slapi_sdn_free(&tmpsuperior);
 
1014
        }
 
1015
 
 
1016
        PR_Close(prfd);
 
1017
 
 
1018
        /* remove the original file */
 
1019
        if( PR_SUCCESS != PR_Delete(logfilename) ){
 
1020
            slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
 
1021
                "referint_postop_close could not delete \"%s\"\n", logfilename );
 
1022
        }
 
1023
 
 
1024
        /* unlock and let other writers back at the file */
 
1025
        referint_unlock();
 
1026
 
 
1027
        /* wait on condition here */
 
1028
        PR_Lock(keeprunning_mutex);
 
1029
        PR_WaitCondVar(keeprunning_cv, PR_SecondsToInterval(delay));
 
1030
        PR_Unlock(keeprunning_mutex);
 
1031
    }
 
1032
 
 
1033
    /* cleanup resources allocated in start  */
 
1034
    if (NULL != keeprunning_mutex) {
 
1035
        PR_DestroyLock(keeprunning_mutex);
 
1036
    }
 
1037
    if (NULL != referint_mutex) {
 
1038
        PR_DestroyLock(referint_mutex);
 
1039
    }
 
1040
    if (NULL != keeprunning_cv) {
 
1041
        PR_DestroyCondVar(keeprunning_cv);
 
1042
    }
1035
1043
}
1036
1044
 
1037
1045
int my_fgetc(PRFileDesc *stream)
1042
1050
    int         err;
1043
1051
 
1044
1052
    /* check if we need to load the buffer */
1045
 
 
1046
1053
    if( READ_BUFSIZE == position )
1047
1054
    {
1048
1055
        memset(buf, '\0', READ_BUFSIZE);
1055
1062
            return err;
1056
1063
        }
1057
1064
    }
1058
 
        
 
1065
 
1059
1066
    /* try to read some data */
1060
1067
    if( '\0' == buf[position])
1061
1068
    {
1066
1073
        retval = buf[position];
1067
1074
        position++;
1068
1075
    }
1069
 
        
 
1076
 
1070
1077
    return retval;
1071
 
 
1072
1078
}       
1073
1079
 
1074
1080
int
1078
1084
    int  done     = 0;
1079
1085
    int  i        = 0;
1080
1086
        
1081
 
    while(!done)
1082
 
    {
1083
 
        if( ( nextchar = my_fgetc(stream) ) != 0)
1084
 
        {
1085
 
            if( i < (size_dest - 1) ) 
1086
 
            {
 
1087
    while(!done){
 
1088
        if( ( nextchar = my_fgetc(stream) ) != 0){
 
1089
            if( i < (size_dest - 1) ){
1087
1090
                dest[i] = nextchar;
1088
1091
                i++;
1089
 
 
1090
 
                if(nextchar == '\n')
1091
 
                {
 
1092
                if(nextchar == '\n'){
1092
1093
                    /* end of line reached */
1093
1094
                    done = 1;
1094
1095
                }
1095
 
                             
1096
 
            }else{
 
1096
            } else {
1097
1097
                /* no more room in buffer */
1098
1098
                done = 1;
1099
1099
            }
1100
 
                
1101
 
        }else{
 
1100
        } else {
1102
1101
            /* error or end of file */
1103
1102
            done = 1;
1104
1103
        }
1105
1104
    }
1106
 
 
1107
1105
    dest[i] =  '\0';
1108
1106
    
1109
1107
    /* return size of string read */
1110
1108
    return i;
1111
1109
}
1112
1110
 
 
1111
/*
 
1112
 *  Write this record to the log file
 
1113
 */
1113
1114
void
1114
1115
writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn,
1115
1116
                  char *newrdn, Slapi_DN *newsuperior, Slapi_DN *requestorsdn)
1121
1122
    const char *requestordn = NULL;
1122
1123
    const char *newsuperiordn = NULL;
1123
1124
    size_t reqdn_len = 0;
1124
 
    /* write this record to the file */
1125
 
 
1126
 
    /* use this lock to protect file data when update integrity is occuring */
1127
 
    /* should hopefully not be a big issue on concurrency */
1128
1125
    
1129
 
    PR_Lock(referint_mutex);
 
1126
    /*
 
1127
     * Use this lock to protect file data when update integrity is occuring.
 
1128
     * If betxn is enabled, this mutex is ignored; transaction itself takes
 
1129
     * the role.
 
1130
     */
 
1131
    referint_lock();
1130
1132
    if (( prfd = PR_Open( logfilename, PR_WRONLY | PR_CREATE_FILE | PR_APPEND,
1131
 
              REFERINT_DEFAULT_FILE_MODE )) == NULL ) 
 
1133
          REFERINT_DEFAULT_FILE_MODE )) == NULL ) 
1132
1134
    {
1133
1135
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
1134
 
               "referint_postop could not write integrity log \"%s\" "
1135
 
                SLAPI_COMPONENT_NAME_NSPR " %d (%s)\n",
1136
 
               logfilename, PR_GetError(), slapd_pr_strerror(PR_GetError()) );
1137
 
        
 
1136
            "referint_postop could not write integrity log \"%s\" "
 
1137
        SLAPI_COMPONENT_NAME_NSPR " %d (%s)\n",
 
1138
            logfilename, PR_GetError(), slapd_pr_strerror(PR_GetError()) );
 
1139
 
1138
1140
        PR_Unlock(referint_mutex);
1139
 
            return;
 
1141
        referint_unlock();
 
1142
        return;
1140
1143
    }
1141
 
 
1142
 
    /* make sure we have enough room in our buffer
1143
 
       before trying to write it 
 
1144
    /*
 
1145
     *  Make sure we have enough room in our buffer before trying to write it.
 
1146
     *  add length of dn +  5(three tabs, a newline, and terminating \0)
1144
1147
     */
1145
 
 
1146
 
        /* add length of dn +  5(three tabs, a newline, and terminating \0) */
1147
1148
    len_to_write = slapi_sdn_get_ndn_len(sdn) + 5;
1148
1149
 
1149
 
    if(newrdn == NULL)
1150
 
    {
 
1150
    if(newrdn == NULL){
1151
1151
        /* add the length of "NULL" */
1152
1152
        len_to_write += 4;
1153
 
    }else{
 
1153
    } else {
1154
1154
        /* add the length of the newrdn */
1155
1155
        len_to_write += strlen(newrdn);
1156
1156
    }
1159
1159
    {
1160
1160
        /* add the length of "NULL" */
1161
1161
        len_to_write += 4;
1162
 
    }else{
 
1162
    } else {
1163
1163
        /* add the length of the newsuperior */
1164
1164
        len_to_write += slapi_sdn_get_ndn_len(newsuperior);
1165
1165
    }
1171
1171
        len_to_write += 4; /* "NULL" */
1172
1172
    }
1173
1173
 
1174
 
    if(len_to_write > MAX_LINE )
1175
 
    {
 
1174
    if(len_to_write > MAX_LINE ){
1176
1175
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
1177
1176
                         "referint_postop could not write integrity log:"
1178
1177
                         " line length exceeded. It will not be able"
1179
1178
                         " to update references to this entry.\n");
1180
 
    }else{
1181
 
       PR_snprintf(buffer, MAX_LINE, "%s\t%s\t%s\t%s\t\n", 
1182
 
                                   slapi_sdn_get_dn(sdn),
1183
 
                                   (newrdn != NULL) ? newrdn : "NULL",
1184
 
                                   (newsuperiordn != NULL) ? newsuperiordn : "NULL",
1185
 
                   requestordn ? requestordn : "NULL");
 
1179
    } else {
 
1180
        PR_snprintf(buffer, MAX_LINE, "%s\t%s\t%s\t%s\t\n", slapi_sdn_get_dn(sdn),
 
1181
                    (newrdn != NULL) ? newrdn : "NULL",
 
1182
                    (newsuperiordn != NULL) ? newsuperiordn : "NULL",
 
1183
                    requestordn ? requestordn : "NULL");
1186
1184
        if (PR_Write(prfd,buffer,strlen(buffer)) < 0){
1187
 
           slapi_log_error(SLAPI_LOG_FATAL,REFERINT_PLUGIN_SUBSYSTEM,
1188
 
               " writeintegritylog: PR_Write failed : The disk"
1189
 
               " may be full or the file is unwritable :: NSPR error - %d\n",
1190
 
               PR_GetError());
1191
 
            }
1192
 
   }
 
1185
            slapi_log_error(SLAPI_LOG_FATAL,REFERINT_PLUGIN_SUBSYSTEM,
 
1186
                " writeintegritylog: PR_Write failed : The disk"
 
1187
                " may be full or the file is unwritable :: NSPR error - %d\n",
 
1188
            PR_GetError());
 
1189
        }
 
1190
    }
1193
1191
 
1194
1192
    /* If file descriptor is closed successfully, PR_SUCCESS */
1195
 
    
1196
1193
    rc = PR_Close(prfd);
1197
 
        if (rc != PR_SUCCESS)
1198
 
        {
1199
 
                slapi_log_error(SLAPI_LOG_FATAL,REFERINT_PLUGIN_SUBSYSTEM, 
1200
 
                                " writeintegritylog: failed to close the file"
1201
 
                                " descriptor prfd; NSPR error - %d\n",
1202
 
                                PR_GetError());
1203
 
        }
1204
 
    PR_Unlock(referint_mutex);    
1205
 
  }
 
1194
    if (rc != PR_SUCCESS){
 
1195
        slapi_log_error(SLAPI_LOG_FATAL,REFERINT_PLUGIN_SUBSYSTEM,
 
1196
            " writeintegritylog: failed to close the file descriptor prfd; NSPR error - %d\n",
 
1197
            PR_GetError());
 
1198
    }
 
1199
    referint_unlock();
 
1200
}