ldap_op.c 26.4 KB
Newer Older
1
/* $OpenLDAP$ */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
2
/*
Kurt Zeilenga's avatar
Kurt Zeilenga committed
3
 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
4
5
 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Copyright (c) 1996 Regents of the University of Michigan.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that this notice is preserved and that due credit is given
 * to the University of Michigan at Ann Arbor. The name of the University
 * may not be used to endorse or promote products derived from this
 * software without specific prior written permission. This software
 * is provided ``as is'' without express or implied warranty.
 */

/*
 * ldap_op.c - routines to perform LDAP operations
 */

Kurt Zeilenga's avatar
Kurt Zeilenga committed
22
23
#include "portable.h"

Kurt Zeilenga's avatar
Kurt Zeilenga committed
24
#include <stdio.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
25
26

#include <ac/stdlib.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
27
28
29

#include <ac/errno.h>
#include <ac/string.h>
Hallvard Furuseth's avatar
Hallvard Furuseth committed
30
#include <ac/ctype.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
31
#include <ac/time.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
32
#include <ac/unistd.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
33

Kurt Zeilenga's avatar
Kurt Zeilenga committed
34
#include <ldap.h>
35
#include "lutil_ldap.h"
Kurt Zeilenga's avatar
Kurt Zeilenga committed
36
37
38
#include "slurp.h"

/* Forward references */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
39
40
41
42
43
static struct berval **make_singlevalued_berval LDAP_P(( char	*, int ));
static int op_ldap_add LDAP_P(( Ri *, Re *, char ** ));
static int op_ldap_modify LDAP_P(( Ri *, Re *, char ** ));
static int op_ldap_delete LDAP_P(( Ri *, Re *, char ** ));
static int op_ldap_modrdn LDAP_P(( Ri *, Re *, char ** ));
44
static LDAPMod *alloc_ldapmod LDAP_P(( void ));
Kurt Zeilenga's avatar
Kurt Zeilenga committed
45
46
47
48
49
50
static void free_ldapmod LDAP_P(( LDAPMod * ));
static void free_ldmarr LDAP_P(( LDAPMod ** ));
static int getmodtype LDAP_P(( char * ));
static void dump_ldm_array LDAP_P(( LDAPMod ** ));
static int do_bind LDAP_P(( Ri *, int * ));
static int do_unbind LDAP_P(( Ri * ));
Kurt Zeilenga's avatar
Kurt Zeilenga committed
51
52
53
54
55


/*
 * Determine the type of ldap operation being performed and call the
 * appropriate routine.
56
 * - If successful, returns DO_LDAP_OK
Kurt Zeilenga's avatar
Kurt Zeilenga committed
57
58
59
60
61
62
63
64
 * - If a retryable error occurs, ERR_DO_LDAP_RETRYABLE is returned.
 *   The caller should wait a while and retry the operation.
 * - If a fatal error occurs, ERR_DO_LDAP_FATAL is returned.  The caller
 *   should reject the operation and continue with the next replication
 *   entry.
 */
int
do_ldap(
65
66
67
	Ri		*ri,
	Re		*re,
	char	**errmsg
Kurt Zeilenga's avatar
Kurt Zeilenga committed
68
69
)
{
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
	int	retry = 2;
	*errmsg = NULL;

	do {
		int lderr;
		if ( ri->ri_ldp == NULL ) {
			lderr = do_bind( ri, &lderr );

			if ( lderr != BIND_OK ) {
				return DO_LDAP_ERR_RETRYABLE;
			}
		}

		switch ( re->re_changetype ) {
		case T_ADDCT:
			lderr = op_ldap_add( ri, re, errmsg );
			if ( lderr != LDAP_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
87
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
88
				LDAP_LOG ( OPERATION, ERR, "do_ldap: "
Julius Enarusai's avatar
   
Julius Enarusai committed
89
					"Error: ldap_add_s failed adding \"%s\": %s\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
90
91
					*errmsg ? *errmsg : ldap_err2string( lderr ), 
					re->re_dn, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
92
#else
93
94
95
96
				Debug( LDAP_DEBUG_ANY,
					"Error: ldap_add_s failed adding \"%s\": %s\n",
					*errmsg ? *errmsg : ldap_err2string( lderr ),
					re->re_dn, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
97
#endif
98
99
100
101
102
103
			}
			break;

		case T_MODIFYCT:
			lderr = op_ldap_modify( ri, re, errmsg );
			if ( lderr != LDAP_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
104
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
105
				LDAP_LOG ( OPERATION, ERR, "do_ldap: "
Julius Enarusai's avatar
   
Julius Enarusai committed
106
					"Error: ldap_modify_s failed modifying \"%s\": %s\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
107
108
					*errmsg ? *errmsg : ldap_err2string( lderr ), 
					re->re_dn, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
109
#else
110
111
112
113
				Debug( LDAP_DEBUG_ANY,
					"Error: ldap_modify_s failed modifying \"%s\": %s\n",
					*errmsg ? *errmsg : ldap_err2string( lderr ),
					re->re_dn, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
114
#endif
115
116
117
118
119
120
			}
			break;

		case T_DELETECT:
			lderr = op_ldap_delete( ri, re, errmsg );
			if ( lderr != LDAP_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
121
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
122
				LDAP_LOG ( OPERATION, ERR, "do_ldap: "
Julius Enarusai's avatar
   
Julius Enarusai committed
123
					"Error: ldap_delete_s failed deleting \"%s\": %s\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
124
125
					*errmsg ? *errmsg : ldap_err2string( lderr ), 
					re->re_dn, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
126
#else
127
128
129
130
				Debug( LDAP_DEBUG_ANY,
					"Error: ldap_delete_s failed deleting \"%s\": %s\n",
					*errmsg ? *errmsg : ldap_err2string( lderr ),
					re->re_dn, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
131
#endif
132
133
134
135
136
137
			}
			break;

		case T_MODRDNCT:
			lderr = op_ldap_modrdn( ri, re, errmsg );
			if ( lderr != LDAP_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
138
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
139
				LDAP_LOG ( OPERATION, ERR, "do_ldap: "
Julius Enarusai's avatar
   
Julius Enarusai committed
140
					"Error: ldap_modrdn_s failed modifying %s: %s\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
141
142
					*errmsg ? *errmsg : ldap_err2string( lderr ), 
					re->re_dn, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
143
#else
144
145
146
147
				Debug( LDAP_DEBUG_ANY,
					"Error: ldap_modrdn_s failed modifying %s: %s\n",
					*errmsg ? *errmsg : ldap_err2string( lderr ),
					re->re_dn, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
148
#endif
149
150
151
152
			}
			break;

		default:
Julius Enarusai's avatar
   
Julius Enarusai committed
153
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
154
			LDAP_LOG ( OPERATION, ERR, "do_ldap: "
Julius Enarusai's avatar
   
Julius Enarusai committed
155
				"Error: bad op \"%d\", dn = \"%s\"\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
156
				re->re_changetype, re->re_dn, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
157
#else
158
159
160
			Debug( LDAP_DEBUG_ANY,
				"Error: do_ldap: bad op \"%d\", dn = \"%s\"\n",
				re->re_changetype, re->re_dn, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
161
#endif
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
			return DO_LDAP_ERR_FATAL;
		}

		/*
		 * Analyze return code. If ok, just return. If LDAP_SERVER_DOWN,
		 * we may have been idle long enough that the remote slapd timed
		 * us out. Rebind and try again.
		 */
		switch( lderr ) {
		case LDAP_SUCCESS:
			return DO_LDAP_OK;
	
		default:
			return DO_LDAP_ERR_FATAL;

		case LDAP_SERVER_DOWN: /* server went down */
			(void) do_unbind( ri );
 			retry--;
		}
	} while ( retry > 0 );

	return DO_LDAP_ERR_RETRYABLE;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
}



/*
 * Perform an ldap add operation.
 */
static int
op_ldap_add(
    Ri		*ri,
    Re		*re,
    char	**errmsg
)
{
    Mi		*mi;
    int		nattrs, rc = 0, i;
    LDAPMod	*ldm, **ldmarr;
    int		lderr = 0;

    nattrs = i = 0;
    ldmarr = NULL;

    /*
     * Construct a null-terminated array of LDAPMod structs.
     */
    mi = re->re_mods;
    while ( mi[ i ].mi_type != NULL ) {
	ldm = alloc_ldapmod();
	ldmarr = ( LDAPMod ** ) ch_realloc( ldmarr,
		( nattrs + 2 ) * sizeof( LDAPMod * ));
	ldmarr[ nattrs ] = ldm;
	ldm->mod_op = LDAP_MOD_BVALUES;
	ldm->mod_type = mi[ i ].mi_type;
	ldm->mod_bvalues =
		make_singlevalued_berval( mi[ i ].mi_val, mi[ i ].mi_len );
	i++;
	nattrs++;
    }

    if ( ldmarr != NULL ) {
	ldmarr[ nattrs ] = NULL;

	/* Perform the operation */
Julius Enarusai's avatar
   
Julius Enarusai committed
227
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
228
	LDAP_LOG ( OPERATION, ARGS, 
Julius Enarusai's avatar
   
Julius Enarusai committed
229
		"op_ldap_add: replica %s:%d - add dn \"%s\"\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
230
		ri->ri_hostname, ri->ri_port, re->re_dn );
Julius Enarusai's avatar
   
Julius Enarusai committed
231
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
232
233
	Debug( LDAP_DEBUG_ARGS, "replica %s:%d - add dn \"%s\"\n",
		ri->ri_hostname, ri->ri_port, re->re_dn );
Julius Enarusai's avatar
   
Julius Enarusai committed
234
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
235
	rc = ldap_add_s( ri->ri_ldp, re->re_dn, ldmarr );
236
237
238

	ldap_get_option( ri->ri_ldp, LDAP_OPT_ERROR_NUMBER, &lderr);

Kurt Zeilenga's avatar
Kurt Zeilenga committed
239
240
    } else {
	*errmsg = "No modifications to do";
Julius Enarusai's avatar
   
Julius Enarusai committed
241
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
242
243
	LDAP_LOG ( OPERATION, ERR, 
		"op_ldap_add: Error: no mods to do (%s)!\n", re->re_dn, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
244
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
245
	Debug( LDAP_DEBUG_ANY,
246
	       "Error: op_ldap_add: no mods to do (%s)!\n", re->re_dn, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
247
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
    }
    free_ldmarr( ldmarr );
    return( lderr ); 
}




/*
 * Perform an ldap modify operation.
 */
#define	AWAITING_OP -1
static int
op_ldap_modify(
    Ri		*ri,
    Re		*re,
    char	**errmsg
)
{
    Mi		*mi;
    int		state;	/* This code is a simple-minded state machine */
    int		nvals;	/* Number of values we're modifying */
    int		nops;	/* Number of LDAPMod structs in ldmarr */
271
    LDAPMod	*ldm = NULL, **ldmarr;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
272
273
274
275
276
277
278
279
280
281
282
    int		i, len;
    char	*type, *value;
    int		rc = 0;

    state = AWAITING_OP;
    nvals = 0;
    nops = 0;
    ldmarr = NULL;

    if ( re->re_mods == NULL ) {
	*errmsg = "No arguments given";
Julius Enarusai's avatar
   
Julius Enarusai committed
283
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
284
285
	LDAP_LOG ( OPERATION, ERR, 
		"op_ldap_modify: Error: no arguments\n" , 0, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
286
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
287
288
	Debug( LDAP_DEBUG_ANY, "Error: op_ldap_modify: no arguments\n",
		0, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
289
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
	    return -1;
    }

    /*
     * Construct a null-terminated array of LDAPMod structs.
     */
    for ( mi = re->re_mods, i = 0; mi[ i ].mi_type != NULL; i++ ) {
	type = mi[ i ].mi_type;
	value = mi[ i ].mi_val;
	len = mi[ i ].mi_len;
	switch ( getmodtype( type )) {
	case T_MODSEP:
	    state = T_MODSEP; /* Got a separator line "-\n" */
	    continue;
	case T_MODOPADD:
	    state = T_MODOPADD;
	    ldmarr = ( LDAPMod ** )
		    ch_realloc(ldmarr, (( nops + 2 ) * ( sizeof( LDAPMod * ))));
	    ldmarr[ nops ] = ldm = alloc_ldapmod();
	    ldm->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
	    ldm->mod_type = value;
	    nvals = 0;
	    nops++;
	    break;
	case T_MODOPREPLACE:
	    state = T_MODOPREPLACE;
	    ldmarr = ( LDAPMod ** )
		    ch_realloc(ldmarr, (( nops + 2 ) * ( sizeof( LDAPMod * ))));
	    ldmarr[ nops ] = ldm = alloc_ldapmod();
	    ldm->mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
	    ldm->mod_type = value;
	    nvals = 0;
	    nops++;
	    break;
	case T_MODOPDELETE:
	    state = T_MODOPDELETE;
	    ldmarr = ( LDAPMod ** )
		    ch_realloc(ldmarr, (( nops + 2 ) * ( sizeof( LDAPMod * ))));
	    ldmarr[ nops ] = ldm = alloc_ldapmod();
	    ldm->mod_op = LDAP_MOD_DELETE | LDAP_MOD_BVALUES;
	    ldm->mod_type = value;
	    nvals = 0;
	    nops++;
	    break;
	default:
	    if ( state == AWAITING_OP ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
336
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
337
338
		LDAP_LOG ( OPERATION, ERR, 
			"op_ldap_modify: Error: unknown mod type \"%s\"\n", type, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
339
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
340
341
342
		Debug( LDAP_DEBUG_ANY,
			"Error: op_ldap_modify: unknown mod type \"%s\"\n",
			type, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
343
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
344
345
346
		continue;
	    }

347
348
	    assert( ldm );

Kurt Zeilenga's avatar
Kurt Zeilenga committed
349
350
351
352
353
	    /*
	     * We should have an attribute: value pair here.
	     * Construct the mod_bvalues part of the ldapmod struct.
	     */
	    if ( strcasecmp( type, ldm->mod_type )) {
Julius Enarusai's avatar
   
Julius Enarusai committed
354
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
355
		LDAP_LOG ( OPERATION, ERR, 
Julius Enarusai's avatar
   
Julius Enarusai committed
356
357
			"op_ldap_modify: Error: "
			"malformed modify op, %s: %s (expecting \"%s\")\n", 
Julius Enarusai's avatar
   
Julius Enarusai committed
358
			type, value, ldm->mod_type );
Julius Enarusai's avatar
   
Julius Enarusai committed
359
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
360
361
362
		Debug( LDAP_DEBUG_ANY,
			"Error: malformed modify op, %s: %s (expecting %s:)\n",
			type, value, ldm->mod_type );
Julius Enarusai's avatar
   
Julius Enarusai committed
363
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
		continue;
	    }
	    ldm->mod_bvalues = ( struct berval ** )
		    ch_realloc( ldm->mod_bvalues,
		    ( nvals + 2 ) * sizeof( struct berval * ));
	    ldm->mod_bvalues[ nvals + 1 ] = NULL;
	    ldm->mod_bvalues[ nvals ] = ( struct berval * )
		    ch_malloc( sizeof( struct berval ));
	    ldm->mod_bvalues[ nvals ]->bv_val = value;
	    ldm->mod_bvalues[ nvals ]->bv_len = len;
	    nvals++;
	}
    }
    ldmarr[ nops ] = NULL;

    if ( nops > 0 ) {
	/* Actually perform the LDAP operation */
Julius Enarusai's avatar
   
Julius Enarusai committed
381
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
382
	LDAP_LOG ( OPERATION, DETAIL1, 
Julius Enarusai's avatar
   
Julius Enarusai committed
383
		"op_ldap_modify: replica %s:%d - modify dn \"%s\"\n", 
Julius Enarusai's avatar
   
Julius Enarusai committed
384
		ri->ri_hostname, ri->ri_port, re->re_dn );
Julius Enarusai's avatar
   
Julius Enarusai committed
385
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
386
387
	Debug( LDAP_DEBUG_ARGS, "replica %s:%d - modify dn \"%s\"\n",
		ri->ri_hostname, ri->ri_port, re->re_dn );
Julius Enarusai's avatar
   
Julius Enarusai committed
388
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
	rc = ldap_modify_s( ri->ri_ldp, re->re_dn, ldmarr );
    }
    free_ldmarr( ldmarr );
    return( rc );
}




/*
 * Perform an ldap delete operation.
 */
static int
op_ldap_delete(
    Ri		*ri,
    Re		*re,
    char	**errmsg
)
{
    int		rc;

Julius Enarusai's avatar
   
Julius Enarusai committed
410
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
411
	LDAP_LOG ( OPERATION, ARGS, 
Julius Enarusai's avatar
   
Julius Enarusai committed
412
		"op_ldap_delete: replica %s:%d - delete dn \"%s\"\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
413
	    ri->ri_hostname, ri->ri_port, re->re_dn );
Julius Enarusai's avatar
   
Julius Enarusai committed
414
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
415
416
    Debug( LDAP_DEBUG_ARGS, "replica %s:%d - delete dn \"%s\"\n",
	    ri->ri_hostname, ri->ri_port, re->re_dn );
Julius Enarusai's avatar
   
Julius Enarusai committed
417
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
418
419
420
421
422
423
424
425
426
427
428
    rc = ldap_delete_s( ri->ri_ldp, re->re_dn );

    return( rc );
}




/*
 * Perform an ldap modrdn operation.
 */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
429
430
431
432
433
434
#define	GOT_NEWRDN		0x1
#define	GOT_DELOLDRDN	0x2
#define GOT_NEWSUP		0x4

#define GOT_MODDN_REQ	(GOT_NEWRDN|GOT_DELOLDRDN)
#define	GOT_ALL_MODDN(f)	(((f) & GOT_MODDN_REQ) == GOT_MODDN_REQ)
Kurt Zeilenga's avatar
Kurt Zeilenga committed
435
436
437
438
439
440
441
442
443
444
static int
op_ldap_modrdn(
    Ri		*ri,
    Re		*re,
    char	**errmsg
)
{
    int		rc = 0;
    Mi		*mi;
    int		i;
445
	int		lderr = 0;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
446
447
    int		state = 0;
    int		drdnflag = -1;
448
    char	*newrdn = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
449
	char	*newsup = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
450
451
452

    if ( re->re_mods == NULL ) {
	*errmsg = "No arguments given";
Julius Enarusai's avatar
   
Julius Enarusai committed
453
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
454
455
	LDAP_LOG ( OPERATION, ERR, 
		"op_ldap_modrdn: Error: no arguments\n" , 0, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
456
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
457
458
	Debug( LDAP_DEBUG_ANY, "Error: op_ldap_modrdn: no arguments\n",
		0, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
459
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
460
461
462
463
464
465
466
467
	    return -1;
    }

    /*
     * Get the arguments: should see newrdn: and deleteoldrdn: args.
     */
    for ( mi = re->re_mods, i = 0; mi[ i ].mi_type != NULL; i++ ) {
	if ( !strcmp( mi[ i ].mi_type, T_NEWRDNSTR )) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
468
		if( state & GOT_NEWRDN ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
469
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
470
		LDAP_LOG ( OPERATION, ERR, 
Julius Enarusai's avatar
   
Julius Enarusai committed
471
			"op_ldap_modrdn: Error: multiple newrdn arg \"%s\"\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
472
			mi[ i ].mi_val, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
473
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
474
475
476
		Debug( LDAP_DEBUG_ANY,
			"Error: op_ldap_modrdn: multiple newrdn arg \"%s\"\n",
			mi[ i ].mi_val, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
477
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
478
479
480
481
		*errmsg = "Multiple newrdn argument";
		return -1;
		}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
482
483
	    newrdn = mi[ i ].mi_val;
	    state |= GOT_NEWRDN;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
484
485
486

	} else if ( !strcmp( mi[ i ].mi_type, T_DELOLDRDNSTR )) {
		if( state & GOT_DELOLDRDN ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
487
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
488
		LDAP_LOG ( OPERATION, ERR, 
Julius Enarusai's avatar
   
Julius Enarusai committed
489
			"op_ldap_modrdn: Error: multiple deleteoldrdn arg \"%s\"\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
490
			mi[ i ].mi_val, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
491
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
492
493
494
		Debug( LDAP_DEBUG_ANY,
			"Error: op_ldap_modrdn: multiple deleteoldrdn arg \"%s\"\n",
			mi[ i ].mi_val, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
495
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
496
497
498
499
500
		*errmsg = "Multiple newrdn argument";
		return -1;
		}

	    state |= GOT_DELOLDRDN;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
501
502
503
504
505
	    if ( !strcmp( mi[ i ].mi_val, "0" )) {
		drdnflag = 0;
	    } else if ( !strcmp( mi[ i ].mi_val, "1" )) {
		drdnflag = 1;
	    } else {
Julius Enarusai's avatar
   
Julius Enarusai committed
506
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
507
		LDAP_LOG ( OPERATION, ERR, 
Julius Enarusai's avatar
   
Julius Enarusai committed
508
			"op_ldap_modrdn: Error: bad deleteoldrdn arg \"%s\"\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
509
			mi[ i ].mi_val, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
510
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
511
512
513
		Debug( LDAP_DEBUG_ANY,
			"Error: op_ldap_modrdn: bad deleteoldrdn arg \"%s\"\n",
			mi[ i ].mi_val, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
514
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
515
516
517
		*errmsg = "Incorrect argument to deleteoldrdn";
		return -1;
	    }
Kurt Zeilenga's avatar
Kurt Zeilenga committed
518
519
520

	} else if ( !strcmp( mi[ i ].mi_type, T_NEWSUPSTR )) {
		if( state & GOT_NEWSUP ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
521
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
522
		LDAP_LOG ( OPERATION, ERR, 
Julius Enarusai's avatar
   
Julius Enarusai committed
523
			"op_ldap_modrdn: Error: multiple newsuperior arg \"%s\"\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
524
			mi[ i ].mi_val, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
525
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
526
527
528
		Debug( LDAP_DEBUG_ANY,
			"Error: op_ldap_modrdn: multiple newsuperior arg \"%s\"\n",
			mi[ i ].mi_val, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
529
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
530
		*errmsg = "Multiple newsuperior argument";
Kurt Zeilenga's avatar
Kurt Zeilenga committed
531
532
533
		return -1;
		}

534
		newsup = mi[ i ].mi_val;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
535
536
	    state |= GOT_NEWSUP;

Kurt Zeilenga's avatar
Kurt Zeilenga committed
537
	} else {
Julius Enarusai's avatar
   
Julius Enarusai committed
538
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
539
		LDAP_LOG ( OPERATION, ERR, 
Julius Enarusai's avatar
   
Julius Enarusai committed
540
			"op_ldap_modrdn: Error: bad type \"%s\"\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
541
			mi[ i ].mi_type, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
542
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
543
544
	    Debug( LDAP_DEBUG_ANY, "Error: op_ldap_modrdn: bad type \"%s\"\n",
		    mi[ i ].mi_type, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
545
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
546
547
548
549
550
551
552
553
	    *errmsg = "Bad value in replication log entry";
	    return -1;
	}
    }

    /*
     * Punt if we don't have all the args.
     */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
554
    if ( !GOT_ALL_MODDN(state) ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
555
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
556
557
		LDAP_LOG ( OPERATION, ERR, 
			"op_ldap_modrdn: Error: missing arguments\n" , 0, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
558
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
559
560
	Debug( LDAP_DEBUG_ANY, "Error: op_ldap_modrdn: missing arguments\n",
		0, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
561
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
562
563
564
565
566
567
568
569
	*errmsg = "Missing argument: requires \"newrdn\" and \"deleteoldrdn\"";
	return -1;
    }

#ifdef LDAP_DEBUG
    if ( ldap_debug & LDAP_DEBUG_ARGS ) {
	char buf[ 256 ];
	char *buf2;
570
571
572
573
574
575
576
	int buf2len = strlen( re->re_dn ) + strlen( mi->mi_val ) + 11;

	snprintf( buf, sizeof(buf), "%s:%d", ri->ri_hostname, ri->ri_port );

	buf2 = (char *) ch_malloc( buf2len );
	snprintf( buf2, buf2len, "(\"%s\" -> \"%s\")", re->re_dn, mi->mi_val );

Julius Enarusai's avatar
   
Julius Enarusai committed
577
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
578
	LDAP_LOG ( OPERATION, ARGS, 
Julius Enarusai's avatar
   
Julius Enarusai committed
579
		"op_ldap_modrdn: replica %s - modify rdn %s (flag: %d)\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
580
		buf, buf2, drdnflag );
Julius Enarusai's avatar
   
Julius Enarusai committed
581
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
582
583
584
	Debug( LDAP_DEBUG_ARGS,
		"replica %s - modify rdn %s (flag: %d)\n",
		buf, buf2, drdnflag );
Julius Enarusai's avatar
   
Julius Enarusai committed
585
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
586
587
588
589
	free( buf2 );
    }
#endif /* LDAP_DEBUG */

590
591
    assert( newrdn );

Kurt Zeilenga's avatar
Kurt Zeilenga committed
592
    /* Do the modrdn */
593
    rc = ldap_rename2_s( ri->ri_ldp, re->re_dn, newrdn, newsup, drdnflag );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
594

595
596
	ldap_get_option( ri->ri_ldp, LDAP_OPT_ERROR_NUMBER, &lderr);
    return( lderr );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
597
598
599
600
601
602
603
604
}



/*
 * Allocate and initialize an ldapmod struct.
 */
static LDAPMod *
605
alloc_ldapmod( void )
Kurt Zeilenga's avatar
Kurt Zeilenga committed
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
{
    LDAPMod	*ldm;

    ldm = ( struct ldapmod * ) ch_malloc( sizeof ( struct ldapmod ));
    ldm->mod_type = NULL;
    ldm->mod_bvalues = ( struct berval ** ) NULL;
    return( ldm );
}



/*
 * Free an ldapmod struct associated mod_bvalues.  NOTE - it is assumed
 * that mod_bvalues and mod_type contain pointers to the same block of memory
 * pointed to by the repl struct.  Therefore, it's not freed here.
 */
static void
free_ldapmod(
LDAPMod *ldm )
{
    int		i;

    if ( ldm == NULL ) {
	return;
    }
    if ( ldm->mod_bvalues != NULL ) {
	for ( i = 0; ldm->mod_bvalues[ i ] != NULL; i++ ) {
	    free( ldm->mod_bvalues[ i ] );
	}
	free( ldm->mod_bvalues );
    }
    free( ldm );
    return;
}


/*
 * Free an an array of LDAPMod pointers and the LDAPMod structs they point
 * to.
 */
static void
free_ldmarr(
LDAPMod **ldmarr )
{
    int	i;

    for ( i = 0; ldmarr[ i ] != NULL; i++ ) {
	free_ldapmod( ldmarr[ i ] );
    }
    free( ldmarr );
}


/*
 * Create a berval with a single value. 
 */
static struct berval **
make_singlevalued_berval( 
char	*value,
int	len )
{
    struct berval **p;

    p = ( struct berval ** ) ch_malloc( 2 * sizeof( struct berval * ));
    p[ 0 ] = ( struct berval * ) ch_malloc( sizeof( struct berval ));
    p[ 1 ] = NULL;
    p[ 0 ]->bv_val = value;
    p[ 0 ]->bv_len = len;
    return( p );
}


/*
 * Given a modification type (string), return an enumerated type.
 * Avoids ugly copy in op_ldap_modify - lets us use a switch statement
 * there.
 */
static int
getmodtype( 
char *type )
{
    if ( !strcmp( type, T_MODSEPSTR )) {
	return( T_MODSEP );
    }
    if ( !strcmp( type, T_MODOPADDSTR )) {
	return( T_MODOPADD );
    }
    if ( !strcmp( type, T_MODOPREPLACESTR )) {
	return( T_MODOPREPLACE );
    }
    if ( !strcmp( type, T_MODOPDELETESTR )) {
	return( T_MODOPDELETE );
    }
    return( T_ERR );
}


/*
 * Perform an LDAP unbind operation.  If replica is NULL, or the
 * repl_ldp is NULL, just return LDAP_SUCCESS.  Otherwise, unbind,
 * set the ldp to NULL, and return the result of the unbind call.
 */
static int
do_unbind(
    Ri	*ri
)
{
    int		rc = LDAP_SUCCESS;

    if (( ri != NULL ) && ( ri->ri_ldp != NULL )) {
	rc = ldap_unbind( ri->ri_ldp );
	if ( rc != LDAP_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
718
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
719
		LDAP_LOG ( OPERATION, ERR, 
Julius Enarusai's avatar
   
Julius Enarusai committed
720
			"do_unbind: ldap_unbind failed for %s:%d: %s\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
721
		    ri->ri_hostname, ri->ri_port, ldap_err2string( rc ) );
Julius Enarusai's avatar
   
Julius Enarusai committed
722
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
723
724
	    Debug( LDAP_DEBUG_ANY,
		    "Error: do_unbind: ldap_unbind failed for %s:%d: %s\n",
725
		    ri->ri_hostname, ri->ri_port, ldap_err2string( rc ) );
Julius Enarusai's avatar
   
Julius Enarusai committed
726
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
	}
	ri->ri_ldp = NULL;
    }
    return rc;
}



/*
 * Perform an LDAP bind operation to the replication site given
 * by replica.  If replica->repl_ldp is non-NULL, then we unbind
 * from the replica before rebinding.  It should be safe to call
 * this to re-connect if the replica's connection goes away
 * for some reason.
 *
 * Returns 0 on success, -1 if an LDAP error occurred, and a return
 * code > 0 if some other error occurred, e.g. invalid bind method.
 * If an LDAP error occurs, the LDAP error is returned in lderr.
 */
static int
do_bind( 
    Ri	*ri,
    int	*lderr
)
{
    int		ldrc;

    *lderr = 0;

    if ( ri == NULL ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
757
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
758
	LDAP_LOG ( OPERATION, ERR, "do_bind: null ri ptr\n" , 0, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
759
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
760
	Debug( LDAP_DEBUG_ANY, "Error: do_bind: null ri ptr\n", 0, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
761
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
762
763
764
	return( BIND_ERR_BADRI );
    }

765
retry:
Kurt Zeilenga's avatar
Kurt Zeilenga committed
766
767
768
    if ( ri->ri_ldp != NULL ) {
	ldrc = ldap_unbind( ri->ri_ldp );
	if ( ldrc != LDAP_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
769
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
770
771
		LDAP_LOG ( OPERATION, ERR, 
			"do_bind: ldap_unbind failed: %s\n", ldap_err2string( ldrc ), 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
772
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
773
774
775
	    Debug( LDAP_DEBUG_ANY,
		    "Error: do_bind: ldap_unbind failed: %s\n",
		    ldap_err2string( ldrc ), 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
776
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
777
778
779
780
	}
	ri->ri_ldp = NULL;
    }

Julius Enarusai's avatar
   
Julius Enarusai committed
781
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
782
	LDAP_LOG ( OPERATION, ARGS, 
Julius Enarusai's avatar
   
Julius Enarusai committed
783
		"do_bind: Initializing session to %s:%d\n", 
Julius Enarusai's avatar
   
Julius Enarusai committed
784
	    ri->ri_hostname, ri->ri_port, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
785
#else
786
    Debug( LDAP_DEBUG_ARGS, "Initializing session to %s:%d\n",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
787
	    ri->ri_hostname, ri->ri_port, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
788
#endif
789

790
    ri->ri_ldp = ldap_init( ri->ri_hostname, ri->ri_port );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
791
    if ( ri->ri_ldp == NULL ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
792
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
793
		LDAP_LOG ( OPERATION, ERR, 
Julius Enarusai's avatar
   
Julius Enarusai committed
794
			"do_bind: ldap_init (%s, %d) failed: %s\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
795
			ri->ri_hostname, ri->ri_port, sys_errlist[ errno ] );
Julius Enarusai's avatar
   
Julius Enarusai committed
796
#else
797
798
		Debug( LDAP_DEBUG_ANY, "Error: ldap_init(%s, %d) failed: %s\n",
			ri->ri_hostname, ri->ri_port, sys_errlist[ errno ] );
Julius Enarusai's avatar
   
Julius Enarusai committed
799
#endif
800
		return( BIND_ERR_OPEN );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
801
802
    }

803
804
805
806
807
808
	{	/* set version 3 */
		int err, version = 3;
		err = ldap_set_option(ri->ri_ldp,
			LDAP_OPT_PROTOCOL_VERSION, &version);

		if( err != LDAP_OPT_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
809
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
810
			LDAP_LOG ( OPERATION, ERR, "do_bind: "
Julius Enarusai's avatar
   
Julius Enarusai committed
811
				"Error: ldap_set_option(%s, LDAP_OPT_VERSION, 3) failed!\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
812
				ri->ri_hostname, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
813
#else
814
815
816
			Debug( LDAP_DEBUG_ANY,
				"Error: ldap_set_option(%s, LDAP_OPT_VERSION, 3) failed!\n",
				ri->ri_hostname, NULL, NULL );
Julius Enarusai's avatar
   
Julius Enarusai committed
817
#endif
818
819
820
821
822
823

			ldap_unbind( ri->ri_ldp );
			ri->ri_ldp = NULL;
			return BIND_ERR_VERSION;
		}
	}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
824

Kurt Zeilenga's avatar
Kurt Zeilenga committed
825
826
827
828
    /*
     * Set ldap library options to (1) not follow referrals, and 
     * (2) restart the select() system call.
     */
829
830
831
832
833
	{
		int err;
		err = ldap_set_option(ri->ri_ldp, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);

		if( err != LDAP_OPT_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
834
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
835
			LDAP_LOG ( OPERATION, ERR, "do_bind: "
Julius Enarusai's avatar
   
Julius Enarusai committed
836
				"Error: ldap_set_option(%s, REFERRALS, OFF) failed!\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
837
				ri->ri_hostname, 0, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
838
#else
839
840
841
			Debug( LDAP_DEBUG_ANY,
				"Error: ldap_set_option(%s,REFERRALS, OFF) failed!\n",
				ri->ri_hostname, NULL, NULL );
Julius Enarusai's avatar
   
Julius Enarusai committed
842
#endif
843
844
845
846
847
			ldap_unbind( ri->ri_ldp );
			ri->ri_ldp = NULL;
			return BIND_ERR_REFERRALS;
		}
	}
848
	ldap_set_option(ri->ri_ldp, LDAP_OPT_RESTART, LDAP_OPT_ON);
Kurt Zeilenga's avatar
Kurt Zeilenga committed
849

850
	if( ri->ri_tls ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
851
		int err = ldap_start_tls_s(ri->ri_ldp, NULL, NULL);
852
853

		if( err != LDAP_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
854
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
855
			LDAP_LOG ( OPERATION, ERR, "do_bind: "
Julius Enarusai's avatar
   
Julius Enarusai committed
856
857
				"%s: ldap_start_tls failed: %s (%d)\n",
				ri->ri_tls == TLS_CRITICAL ? "Error" : "Warning",
Julius Enarusai's avatar
   
Julius Enarusai committed
858
				ldap_err2string( err ), err );
Julius Enarusai's avatar
   
Julius Enarusai committed
859
#else
860
861
			Debug( LDAP_DEBUG_ANY,
				"%s: ldap_start_tls failed: %s (%d)\n",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
862
				ri->ri_tls == TLS_CRITICAL ? "Error" : "Warning",
863
				ldap_err2string( err ), err );
Julius Enarusai's avatar
   
Julius Enarusai committed
864
#endif
865

Kurt Zeilenga's avatar
Kurt Zeilenga committed
866
			if( ri->ri_tls == TLS_CRITICAL ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
867
				*lderr = err;
868
869
870
871
				ldap_unbind( ri->ri_ldp );
				ri->ri_ldp = NULL;
				return BIND_ERR_TLS_FAILED;
			}
872
873
			ri->ri_tls = TLS_OFF;
			goto retry;
874
875
876
		}
	}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
877
878
879
880
881
    switch ( ri->ri_bind_method ) {
    case AUTH_SIMPLE:
	/*
	 * Bind with a plaintext password.
	 */
Julius Enarusai's avatar
   
Julius Enarusai committed
882
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
883
	LDAP_LOG ( OPERATION, ARGS, 
Julius Enarusai's avatar
   
Julius Enarusai committed
884
		"do_bind: bind to %s:%d as %s (simple)\n", 
Julius Enarusai's avatar
   
Julius Enarusai committed
885
		ri->ri_hostname, ri->ri_port, ri->ri_bind_dn );
Julius Enarusai's avatar
   
Julius Enarusai committed
886
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
887
888
	Debug( LDAP_DEBUG_ARGS, "bind to %s:%d as %s (simple)\n",
		ri->ri_hostname, ri->ri_port, ri->ri_bind_dn );
Julius Enarusai's avatar
   
Julius Enarusai committed
889
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
890
891
892
	ldrc = ldap_simple_bind_s( ri->ri_ldp, ri->ri_bind_dn,
		ri->ri_password );
	if ( ldrc != LDAP_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
893
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
894
		LDAP_LOG ( OPERATION, ERR, "do_bind: "
Julius Enarusai's avatar
   
Julius Enarusai committed
895
		    "Error: ldap_simple_bind_s for %s:%d failed: %s\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
896
		    ri->ri_hostname, ri->ri_port, ldap_err2string( ldrc ) );
Julius Enarusai's avatar
   
Julius Enarusai committed
897
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
898
899
900
	    Debug( LDAP_DEBUG_ANY,
		    "Error: ldap_simple_bind_s for %s:%d failed: %s\n",
		    ri->ri_hostname, ri->ri_port, ldap_err2string( ldrc ));
Julius Enarusai's avatar
   
Julius Enarusai committed
901
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
902
	    *lderr = ldrc;
903
904
		ldap_unbind( ri->ri_ldp );
		ri->ri_ldp = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
905
906
907
	    return( BIND_ERR_SIMPLE_FAILED );
	}
	break;
908
909

	case AUTH_SASL:
Julius Enarusai's avatar
   
Julius Enarusai committed
910
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
911
	LDAP_LOG ( OPERATION, ARGS, 
Julius Enarusai's avatar
   
Julius Enarusai committed
912
		"do_bind: bind to %s as %s via %s (SASL)\n", 
Kurt Zeilenga's avatar
Kurt Zeilenga committed
913
914
		ri->ri_hostname,
		ri->ri_authcId ? ri->ri_authcId : "-",
Julius Enarusai's avatar
   
Julius Enarusai committed
915
		ri->ri_saslmech );
Julius Enarusai's avatar
   
Julius Enarusai committed
916
#else
917
	Debug( LDAP_DEBUG_ARGS, "bind to %s as %s via %s (SASL)\n",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
918
919
920
		ri->ri_hostname,
		ri->ri_authcId ? ri->ri_authcId : "-",
		ri->ri_saslmech );
Julius Enarusai's avatar
   
Julius Enarusai committed
921
#endif
922

923
#ifdef HAVE_CYRUS_SASL
924
	if( ri->ri_secprops != NULL ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
925
926
		int err = ldap_set_option(ri->ri_ldp,
			LDAP_OPT_X_SASL_SECPROPS, ri->ri_secprops);
927
928

		if( err != LDAP_OPT_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
929
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
930
			LDAP_LOG ( OPERATION, ERR, "do_bind: "
Julius Enarusai's avatar
   
Julius Enarusai committed
931
				"Error: ldap_set_option(%s,SECPROPS,\"%s\") failed!\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
932
				ri->ri_hostname, ri->ri_secprops, 0 );
Julius Enarusai's avatar
   
Julius Enarusai committed
933
#else
934
935
936
			Debug( LDAP_DEBUG_ANY,
				"Error: ldap_set_option(%s,SECPROPS,\"%s\") failed!\n",
				ri->ri_hostname, ri->ri_secprops, NULL );
Julius Enarusai's avatar
   
Julius Enarusai committed
937
#endif
938
939
940
941
942
943
			ldap_unbind( ri->ri_ldp );
			ri->ri_ldp = NULL;
			return BIND_ERR_SASL_FAILED;
		}
	}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
944
945
	{
		void *defaults = lutil_sasl_defaults( ri->ri_ldp, ri->ri_saslmech,
Howard Chu's avatar
Howard Chu committed
946
		    ri->ri_realm, ri->ri_authcId, ri->ri_password, ri->ri_authzId );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
947
948
949
950

		ldrc = ldap_sasl_interactive_bind_s( ri->ri_ldp, ri->ri_bind_dn,
		    ri->ri_saslmech, NULL, NULL,
		    LDAP_SASL_QUIET, lutil_sasl_interact, defaults );
Howard Chu's avatar
Howard Chu committed
951
952

		lutil_sasl_freedefs( defaults );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
953
		if ( ldrc != LDAP_SUCCESS ) {
Julius Enarusai's avatar
   
Julius Enarusai committed
954
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
955
			LDAP_LOG ( OPERATION, ERR, "do_bind: "
Julius Enarusai's avatar
   
Julius Enarusai committed
956
				"Error: LDAP SASL for %s:%d failed: %s\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
957
			    ri->ri_hostname, ri->ri_port, ldap_err2string( ldrc ) );
Julius Enarusai's avatar
   
Julius Enarusai committed
958
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
959
960
			Debug( LDAP_DEBUG_ANY, "Error: LDAP SASL for %s:%d failed: %s\n",
			    ri->ri_hostname, ri->ri_port, ldap_err2string( ldrc ));
Julius Enarusai's avatar
   
Julius Enarusai committed
961
#endif
Kurt Zeilenga's avatar
Kurt Zeilenga committed
962
963
964
965
966
			*lderr = ldrc;
			ldap_unbind( ri->ri_ldp );
			ri->ri_ldp = NULL;
			return( BIND_ERR_SASL_FAILED );
		}
967
968
	}
	break;
Julius Enarusai's avatar
   
Julius Enarusai committed
969
970
#else
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
971
	LDAP_LOG ( OPERATION, ERR, "do_bind: "
Julius Enarusai's avatar
   
Julius Enarusai committed
972
		"Error: do_bind: SASL not supported %s:%d\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
973
		ri->ri_hostname, ri->ri_port, 0 );
974
975
976
977
#else
	Debug( LDAP_DEBUG_ANY,
		"Error: do_bind: SASL not supported %s:%d\n",
		 ri->ri_hostname, ri->ri_port, NULL );
Julius Enarusai's avatar
   
Julius Enarusai committed
978
#endif
979
980
981
982
983
	ldap_unbind( ri->ri_ldp );
	ri->ri_ldp = NULL;
	return( BIND_ERR_BAD_ATYPE );
#endif

Kurt Zeilenga's avatar
Kurt Zeilenga committed
984
    default:
Julius Enarusai's avatar
   
Julius Enarusai committed
985
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
986
	LDAP_LOG ( OPERATION, ERR, "do_bind: "
Julius Enarusai's avatar
   
Julius Enarusai committed
987
		"Error: do_bind: unknown auth type \"%d\" for %s:%d\n",
Julius Enarusai's avatar
   
Julius Enarusai committed
988
		ri->ri_bind_method, ri->ri_hostname, ri->ri_port );
Julius Enarusai's avatar
   
Julius Enarusai committed
989
#else
Kurt Zeilenga's avatar
Kurt Zeilenga committed
990
991
992
	Debug(  LDAP_DEBUG_ANY,
		"Error: do_bind: unknown auth type \"%d\" for %s:%d\n",
		ri->ri_bind_method, ri->ri_hostname, ri->ri_port );
Julius Enarusai's avatar
   
Julius Enarusai committed
993
#endif
994
995
	ldap_unbind( ri->ri_ldp );
	ri->ri_ldp = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
996
997
	return( BIND_ERR_BAD_ATYPE );
    }
998
999
1000

	{
		int err;
For faster browsing, not all history is shown. View entire blame