10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * 3*3857Sstevel * Copyright 1999 Sun Microsystems, Inc. All rights reserved. 4*3857Sstevel * Use is subject to license terms. 50Sstevel@tonic-gate * 60Sstevel@tonic-gate * 70Sstevel@tonic-gate * Comments: 80Sstevel@tonic-gate * 90Sstevel@tonic-gate */ 100Sstevel@tonic-gate 110Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 120Sstevel@tonic-gate 130Sstevel@tonic-gate #include <stdio.h> 140Sstevel@tonic-gate #include <string.h> 150Sstevel@tonic-gate #include <sys/time.h> 160Sstevel@tonic-gate #include <sys/types.h> 170Sstevel@tonic-gate #include <sys/socket.h> 180Sstevel@tonic-gate #include <sys/errno.h> 190Sstevel@tonic-gate #include "portable.h" 200Sstevel@tonic-gate #include "lber.h" 210Sstevel@tonic-gate #include "ldap.h" 220Sstevel@tonic-gate #include "ldap-private.h" 230Sstevel@tonic-gate #include "ldap-int.h" 240Sstevel@tonic-gate 250Sstevel@tonic-gate static BerElement * 260Sstevel@tonic-gate re_encode_request( LDAP *ld, BerElement *origber, int msgid, LDAPURLDesc *urldesc ); 270Sstevel@tonic-gate static void addFollowedRef(LDAPRequest *lr, char *ref); 280Sstevel@tonic-gate static void addToFollowRef(LDAPRequest *lr, char *ref); 290Sstevel@tonic-gate static int addUnFollowedRef(LDAP *ld, LDAPRequest *lr, char *ref); 300Sstevel@tonic-gate 310Sstevel@tonic-gate char ** ldap_errormsg2referrals(char *errmsg) { 320Sstevel@tonic-gate char ** refs; 330Sstevel@tonic-gate int count; 340Sstevel@tonic-gate size_t len; 350Sstevel@tonic-gate char *p, *ref; 360Sstevel@tonic-gate 370Sstevel@tonic-gate if (errmsg == NULL){ 380Sstevel@tonic-gate return (NULL); 390Sstevel@tonic-gate } 400Sstevel@tonic-gate len = strlen( errmsg ); 410Sstevel@tonic-gate for ( p = errmsg; len >= LDAP_REF_STR_LEN; ++p, --len ) { 420Sstevel@tonic-gate if (( *p == 'R' || *p == 'r' ) && strncasecmp( p, 430Sstevel@tonic-gate LDAP_REF_STR, LDAP_REF_STR_LEN ) == 0 ) { 440Sstevel@tonic-gate *p = '\0'; 450Sstevel@tonic-gate p += LDAP_REF_STR_LEN; 460Sstevel@tonic-gate break; 470Sstevel@tonic-gate } 480Sstevel@tonic-gate } 490Sstevel@tonic-gate 500Sstevel@tonic-gate if ( len < LDAP_REF_STR_LEN ) { 510Sstevel@tonic-gate return( NULL); 520Sstevel@tonic-gate } 530Sstevel@tonic-gate count = 1; 540Sstevel@tonic-gate ref = p; 550Sstevel@tonic-gate while ((ref = strchr(ref, '\n')) != NULL) 560Sstevel@tonic-gate count++; 570Sstevel@tonic-gate 580Sstevel@tonic-gate if ((refs = (char **)calloc(count + 1, sizeof(char *))) == NULL){ 590Sstevel@tonic-gate return (NULL); 600Sstevel@tonic-gate } 610Sstevel@tonic-gate 620Sstevel@tonic-gate count = 0; 630Sstevel@tonic-gate for (ref = p; ref != NULL; ref= p){ 640Sstevel@tonic-gate if ((p = strchr(ref, '\n')) != NULL){ 650Sstevel@tonic-gate *p = '\0'; 660Sstevel@tonic-gate } 670Sstevel@tonic-gate refs[count++] = strdup(ref); 680Sstevel@tonic-gate if (p != NULL) 690Sstevel@tonic-gate *p++ = '\n'; 700Sstevel@tonic-gate } 710Sstevel@tonic-gate return (refs); 720Sstevel@tonic-gate } 730Sstevel@tonic-gate 740Sstevel@tonic-gate char *ldap_referral2error_msg(char ** refs) 750Sstevel@tonic-gate { 760Sstevel@tonic-gate int i; 770Sstevel@tonic-gate size_t len = 0; 780Sstevel@tonic-gate char *msg = NULL; 790Sstevel@tonic-gate 800Sstevel@tonic-gate if (refs == NULL) 810Sstevel@tonic-gate return (msg); 820Sstevel@tonic-gate 830Sstevel@tonic-gate for (i = 0; refs[i] != NULL; i++){ 840Sstevel@tonic-gate len += strlen (refs[i]) + 1; 850Sstevel@tonic-gate } 860Sstevel@tonic-gate 870Sstevel@tonic-gate if ((len > 0) && ((msg = (char *)malloc(len + LDAP_REF_STR_LEN + 2)) != NULL)) { 880Sstevel@tonic-gate strncpy(msg, LDAP_REF_STR, LDAP_REF_STR_LEN); 890Sstevel@tonic-gate for (i = 0; refs[i] != NULL; i++) { 900Sstevel@tonic-gate strcat(msg, refs[i]); 910Sstevel@tonic-gate strcat(msg, "\n"); 920Sstevel@tonic-gate } 930Sstevel@tonic-gate } 940Sstevel@tonic-gate return (msg); 950Sstevel@tonic-gate } 960Sstevel@tonic-gate 970Sstevel@tonic-gate 980Sstevel@tonic-gate int 990Sstevel@tonic-gate chase_referrals( LDAP *ld, LDAPRequest *lr, char **refs, int *count, int samerequest ) 1000Sstevel@tonic-gate { 1010Sstevel@tonic-gate int rc, len, newdn, i, j, refcnt, errCode; 1020Sstevel@tonic-gate char *p, *ports, *ref, *tmpref, *refdn; 1030Sstevel@tonic-gate LDAPRequest *origreq; 1040Sstevel@tonic-gate LDAPServer *srv; 1050Sstevel@tonic-gate BerElement *ber; 1060Sstevel@tonic-gate LDAPURLDesc *ludp; 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 215, "=> chase_referrals\n"), 0, 0, 0 ); 1100Sstevel@tonic-gate 1110Sstevel@tonic-gate ld->ld_errno = LDAP_SUCCESS; /* optimistic */ 1120Sstevel@tonic-gate *count = 0; 1130Sstevel@tonic-gate if ( refs == NULL ) { 1140Sstevel@tonic-gate return( LDAP_SUCCESS ); 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate #ifdef _REENTRANT 1180Sstevel@tonic-gate LOCK_LDAP(ld); 1190Sstevel@tonic-gate #endif 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate if ( lr->lr_parentcnt >= ld->ld_refhoplimit ) { 1220Sstevel@tonic-gate Debug( LDAP_DEBUG_ANY, 1230Sstevel@tonic-gate catgets(slapdcat, 1, 216, "more than %d referral hops (dropping)\n"), 1240Sstevel@tonic-gate ld->ld_refhoplimit, 0, 0 ); 1250Sstevel@tonic-gate /* XXX report as error in ld->ld_errno? */ 1260Sstevel@tonic-gate rc = ld->ld_errno = (ld->ld_version >= LDAP_VERSION3) ? LDAP_REFERRAL_LIMIT_EXCEEDED : LDAP_OTHER; 1270Sstevel@tonic-gate #ifdef _REENTRANT 1280Sstevel@tonic-gate UNLOCK_LDAP(ld); 1290Sstevel@tonic-gate #endif 1300Sstevel@tonic-gate return( rc ); 1310Sstevel@tonic-gate } 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate /* find original request */ 1340Sstevel@tonic-gate for ( origreq = lr; origreq->lr_parent != NULL; 1350Sstevel@tonic-gate origreq = origreq->lr_parent ) { 1360Sstevel@tonic-gate ; 1370Sstevel@tonic-gate } 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate for (refcnt = 0; refs[refcnt] != NULL; refcnt++) 1400Sstevel@tonic-gate ; /* Count number of referrals */ 1410Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 1277, "%d possible referrals to chase\n"), refcnt, 0,0); 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate rc = 0; 1440Sstevel@tonic-gate /* parse out & follow referrals */ 1450Sstevel@tonic-gate for (i = 0; rc == 0 && refs[i] != NULL; i++) { 1460Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, -1, "Try to chase %s\n"), refs[i], 0,0); 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate /* Parse URL */ 1490Sstevel@tonic-gate if (ldap_url_parse(refs[i], &ludp) != 0){ 1500Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, -1, "Bad URL for referral %s\n"), refs[i], 0,0); 1510Sstevel@tonic-gate errCode = LDAP_PARAM_ERROR; 1520Sstevel@tonic-gate addUnFollowedRef(ld, lr, refs[i]); 1530Sstevel@tonic-gate /* try next URL */ 1540Sstevel@tonic-gate continue; 1550Sstevel@tonic-gate } 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate /* Encode previous request with new URL */ 1580Sstevel@tonic-gate if (( ber = re_encode_request( ld, origreq->lr_ber, ++ld->ld_msgid, ludp )) == NULL ) { 1590Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, -1, "Error while encoding request for referral\n"), 0, 0,0); 1600Sstevel@tonic-gate ldap_free_urldesc(ludp); 1610Sstevel@tonic-gate errCode = ld->ld_errno; 1620Sstevel@tonic-gate addUnFollowedRef(ld, lr, refs[i]); 1630Sstevel@tonic-gate /* try next URL */ 1640Sstevel@tonic-gate continue; 1650Sstevel@tonic-gate } 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate if (( srv = (LDAPServer *)calloc( 1, sizeof( LDAPServer ))) == NULL ) { 1680Sstevel@tonic-gate ldap_free_urldesc(ludp); 1690Sstevel@tonic-gate ber_free( ber, 1 ); 1700Sstevel@tonic-gate rc = ld->ld_errno = LDAP_NO_MEMORY; 1710Sstevel@tonic-gate #ifdef _REENTRANT 1720Sstevel@tonic-gate UNLOCK_LDAP(ld); 1730Sstevel@tonic-gate #endif 1740Sstevel@tonic-gate return( rc ); 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate if (( srv->lsrv_host = strdup( ludp->lud_host ? ludp->lud_host : ld->ld_defhost)) == NULL ) { 1780Sstevel@tonic-gate ldap_free_urldesc(ludp); 1790Sstevel@tonic-gate free( (char *)srv ); 1800Sstevel@tonic-gate ber_free( ber, 1 ); 1810Sstevel@tonic-gate rc = ld->ld_errno = LDAP_NO_MEMORY; 1820Sstevel@tonic-gate #ifdef _REENTRANT 1830Sstevel@tonic-gate UNLOCK_LDAP(ld); 1840Sstevel@tonic-gate #endif 1850Sstevel@tonic-gate return( rc ); 1860Sstevel@tonic-gate } 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate srv->lsrv_port = ludp->lud_port ? ludp->lud_port : LDAP_PORT; 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate if ( srv != NULL && send_server_request( ld, ber, ld->ld_msgid, 1910Sstevel@tonic-gate lr, srv, NULL, 1 ) >= 0 ) { 1920Sstevel@tonic-gate ++*count; 1930Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, -1, "Request has been forwarded to %s\n"), refs[i], 0,0); 1940Sstevel@tonic-gate addFollowedRef(lr, refs[i]); 1950Sstevel@tonic-gate for (j = i+1; refs[j] != NULL; j++){ 1960Sstevel@tonic-gate addToFollowRef(lr, refs[j]); 1970Sstevel@tonic-gate } 1980Sstevel@tonic-gate ldap_free_urldesc(ludp); 1990Sstevel@tonic-gate break; 2000Sstevel@tonic-gate } else { 2010Sstevel@tonic-gate Debug( LDAP_DEBUG_ANY, 2020Sstevel@tonic-gate catgets(slapdcat, 1, 220, "Unable to chase referral (%s)\n"), 2030Sstevel@tonic-gate ldap_err2string( ld->ld_errno ), 0, 0 ); 2040Sstevel@tonic-gate addUnFollowedRef(ld, lr, refs[i]); 2050Sstevel@tonic-gate errCode = ld->ld_errno; 2060Sstevel@tonic-gate } 2070Sstevel@tonic-gate ldap_free_urldesc(ludp); /* So far spawn all requests */ 2080Sstevel@tonic-gate } 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate #ifdef _REENTRANT 2110Sstevel@tonic-gate UNLOCK_LDAP(ld); 2120Sstevel@tonic-gate #endif 2130Sstevel@tonic-gate if (refs[i] != NULL) { 2140Sstevel@tonic-gate rc = LDAP_SUCCESS; 2150Sstevel@tonic-gate } else { 2160Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, -1, "No referral was successfully chased (last error %d)\n"), errCode, 0, 0); 2170Sstevel@tonic-gate rc = errCode; 2180Sstevel@tonic-gate } 2190Sstevel@tonic-gate Debug ( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 1278, "<= chase_referrals --- \n"), 0,0,0); 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate return( rc ); 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate static void addFollowedRef(LDAPRequest *lr, char *ref) 2250Sstevel@tonic-gate { 2260Sstevel@tonic-gate int i; 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate if (lr->lr_ref_followed == NULL){ 2290Sstevel@tonic-gate if ((lr->lr_ref_followed = (char **)calloc(2, sizeof(char*))) == NULL) 2300Sstevel@tonic-gate return; 2310Sstevel@tonic-gate i = 0; 2320Sstevel@tonic-gate } else { 2330Sstevel@tonic-gate for (i = 0; lr->lr_ref_followed[i] != NULL; i++); 2340Sstevel@tonic-gate if ((lr->lr_ref_followed = (char **)realloc((char *)lr->lr_ref_followed, (i+2) * sizeof(char *))) == NULL){ 2350Sstevel@tonic-gate return; 2360Sstevel@tonic-gate } 2370Sstevel@tonic-gate } 2380Sstevel@tonic-gate lr->lr_ref_followed[i++] = strdup(ref); 2390Sstevel@tonic-gate lr->lr_ref_followed[i] = NULL; 2400Sstevel@tonic-gate return; 2410Sstevel@tonic-gate } 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate static void addToFollowRef(LDAPRequest *lr, char *ref) 2440Sstevel@tonic-gate { 2450Sstevel@tonic-gate int i; 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate if (lr->lr_ref_tofollow == NULL){ 2480Sstevel@tonic-gate if ((lr->lr_ref_tofollow = (char **)calloc(2, sizeof(char*))) == NULL) 2490Sstevel@tonic-gate return; 2500Sstevel@tonic-gate i = 0; 2510Sstevel@tonic-gate } else { 2520Sstevel@tonic-gate for (i = 0; lr->lr_ref_tofollow[i] != NULL; i++); 2530Sstevel@tonic-gate if ((lr->lr_ref_tofollow = (char **)realloc((char *)lr->lr_ref_tofollow, (i+2) * sizeof(char *))) == NULL){ 2540Sstevel@tonic-gate return; 2550Sstevel@tonic-gate } 2560Sstevel@tonic-gate } 2570Sstevel@tonic-gate lr->lr_ref_tofollow[i++] = strdup(ref); 2580Sstevel@tonic-gate lr->lr_ref_tofollow[i] = NULL; 2590Sstevel@tonic-gate return; 2600Sstevel@tonic-gate } 2610Sstevel@tonic-gate 2620Sstevel@tonic-gate static int addUnFollowedRef(LDAP *ld, LDAPRequest *lr, char *ref) 2630Sstevel@tonic-gate { 2640Sstevel@tonic-gate int i; 2650Sstevel@tonic-gate 2660Sstevel@tonic-gate if (lr->lr_ref_unfollowed == NULL){ 2670Sstevel@tonic-gate if ((lr->lr_ref_unfollowed = (char **)calloc(2, sizeof(char*))) == NULL){ 2680Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 2690Sstevel@tonic-gate return (-1); 2700Sstevel@tonic-gate } 2710Sstevel@tonic-gate i = 0; 2720Sstevel@tonic-gate } else { 2730Sstevel@tonic-gate for (i = 0; lr->lr_ref_unfollowed[i] != NULL; i++); 2740Sstevel@tonic-gate if ((lr->lr_ref_unfollowed = (char **)realloc((char *)lr->lr_ref_unfollowed, (i+2) * sizeof(char *))) == NULL){ 2750Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 2760Sstevel@tonic-gate return (-1); 2770Sstevel@tonic-gate } 2780Sstevel@tonic-gate } 2790Sstevel@tonic-gate lr->lr_ref_unfollowed[i++] = strdup(ref); 2800Sstevel@tonic-gate lr->lr_ref_unfollowed[i] = NULL; 2810Sstevel@tonic-gate return (0); 2820Sstevel@tonic-gate } 2830Sstevel@tonic-gate 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate int 2860Sstevel@tonic-gate append_referral( LDAP *ld, char **referralsp, char *s ) 2870Sstevel@tonic-gate { 2880Sstevel@tonic-gate int first; 2890Sstevel@tonic-gate 2900Sstevel@tonic-gate if ( *referralsp == NULL ) { 2910Sstevel@tonic-gate first = 1; 2920Sstevel@tonic-gate *referralsp = (char *)malloc( strlen( s ) + LDAP_REF_STR_LEN 2930Sstevel@tonic-gate + 1 ); 2940Sstevel@tonic-gate } else { 2950Sstevel@tonic-gate first = 0; 2960Sstevel@tonic-gate *referralsp = (char *)realloc( *referralsp, 2970Sstevel@tonic-gate strlen( *referralsp ) + strlen( s ) + 2 ); 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate if ( *referralsp == NULL ) { 3010Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 3020Sstevel@tonic-gate return( -1 ); 3030Sstevel@tonic-gate } 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate if ( first ) { 3060Sstevel@tonic-gate strcpy( *referralsp, LDAP_REF_STR ); 3070Sstevel@tonic-gate } else { 3080Sstevel@tonic-gate strcat( *referralsp, "\n" ); 3090Sstevel@tonic-gate } 3100Sstevel@tonic-gate strcat( *referralsp, s ); 3110Sstevel@tonic-gate 3120Sstevel@tonic-gate return( 0 ); 3130Sstevel@tonic-gate } 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate static BerElement * 3180Sstevel@tonic-gate re_encode_request( LDAP *ld, BerElement *origber, int msgid, LDAPURLDesc *urldesc ) 3190Sstevel@tonic-gate { 3200Sstevel@tonic-gate /* 3210Sstevel@tonic-gate * XXX this routine knows way too much about how the lber library works! 3220Sstevel@tonic-gate */ 3230Sstevel@tonic-gate unsigned int along, tag, len; 3240Sstevel@tonic-gate int ver, scope, deref, sizelimit, timelimit, attrsonly; 3250Sstevel@tonic-gate int rc, hasCtrls; 3260Sstevel@tonic-gate BerElement tmpber, *ber; 3270Sstevel@tonic-gate char *dn, *seqstart; 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, 3300Sstevel@tonic-gate catgets(slapdcat, 1, 221, "re_encode_request: new msgid %1$d, new dn <%2$s>\n"), 3310Sstevel@tonic-gate msgid, ( urldesc->lud_dn == NULL ) ? "NONE" : urldesc->lud_dn, 0 ); 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate tmpber = *origber; 3340Sstevel@tonic-gate 3350Sstevel@tonic-gate /* 3360Sstevel@tonic-gate * all LDAP requests are sequences that start with a message id, 3370Sstevel@tonic-gate * followed by a sequence that is tagged with the operation code 3380Sstevel@tonic-gate */ 3390Sstevel@tonic-gate /* Bad assumption : delete op is not a sequence. 3400Sstevel@tonic-gate * So we have a special processing for it : it's much simpler 3410Sstevel@tonic-gate */ 3420Sstevel@tonic-gate if ( ber_scanf( &tmpber, "{i", &along ) != LDAP_TAG_MSGID || 3430Sstevel@tonic-gate ( tag = ber_peek_tag( &tmpber, &along )) == LBER_DEFAULT ) { 3440Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 3450Sstevel@tonic-gate return( NULL ); 3460Sstevel@tonic-gate } 3470Sstevel@tonic-gate 3480Sstevel@tonic-gate /* Special case : delete request is not a sequence of... */ 3490Sstevel@tonic-gate if (tag == LDAP_REQ_EXTENDED){ 3500Sstevel@tonic-gate /* return error, I don't know how to do it automatically */ 3510Sstevel@tonic-gate ld->ld_errno = LDAP_NOT_SUPPORTED; 3520Sstevel@tonic-gate return (NULL); 3530Sstevel@tonic-gate } 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { 3560Sstevel@tonic-gate return (NULL); 3570Sstevel@tonic-gate } 3580Sstevel@tonic-gate 3590Sstevel@tonic-gate if (tag == LDAP_REQ_DELETE) { 3600Sstevel@tonic-gate if ( ber_get_stringa( &tmpber, &dn ) == LBER_DEFAULT ) { 3610Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 3620Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, 3630Sstevel@tonic-gate catgets(slapdcat, 1, 1279,"Error in decoding delete DN"),0,0,0); 3640Sstevel@tonic-gate ber_free( ber, 1); 3650Sstevel@tonic-gate return( NULL ); 3660Sstevel@tonic-gate } 3670Sstevel@tonic-gate /* Check if controls */ 3680Sstevel@tonic-gate hasCtrls = 0; 3690Sstevel@tonic-gate if (ber_peek_tag(&tmpber, &len) == LDAP_TAG_CONTROL_LIST){ 3700Sstevel@tonic-gate hasCtrls = 1; 3710Sstevel@tonic-gate } 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate if ( urldesc->lud_dn && *urldesc->lud_dn ) { 3740Sstevel@tonic-gate free( dn ); 3750Sstevel@tonic-gate dn = urldesc->lud_dn; 3760Sstevel@tonic-gate } 3770Sstevel@tonic-gate if ( ber_printf( ber, "{its", msgid, tag, dn ) == -1 ) { 3780Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, "Error in re_encoding delete request",0,0,0); 3790Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 3800Sstevel@tonic-gate ber_free( ber, 1 ); 3810Sstevel@tonic-gate return (NULL); 3820Sstevel@tonic-gate } 3830Sstevel@tonic-gate /* Now add controls if any */ 3840Sstevel@tonic-gate if (hasCtrls && ber_write( ber, tmpber.ber_ptr, len, 0 ) != len ) { 3850Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 3860Sstevel@tonic-gate ber_free( ber, 1 ); 3870Sstevel@tonic-gate return( NULL ); 3880Sstevel@tonic-gate } 3890Sstevel@tonic-gate if (ber_printf( ber, "}" ) == -1 ) { 3900Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 3910Sstevel@tonic-gate ber_free( ber, 1 ); 3920Sstevel@tonic-gate return( NULL ); 3930Sstevel@tonic-gate } 3940Sstevel@tonic-gate 3950Sstevel@tonic-gate #ifdef LDAP_DEBUG 3960Sstevel@tonic-gate if ( ldap_debug & LDAP_DEBUG_PACKETS ) { 3970Sstevel@tonic-gate Debug( LDAP_DEBUG_ANY, catgets(slapdcat, 1, 222, "re_encode_request new request is:\n"), 3980Sstevel@tonic-gate 0, 0, 0 ); 3990Sstevel@tonic-gate ber_dump( ber, 0 ); 4000Sstevel@tonic-gate } 4010Sstevel@tonic-gate #endif /* LDAP_DEBUG */ 4020Sstevel@tonic-gate return (ber); 4030Sstevel@tonic-gate } 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate if (( tag = ber_skip_tag( &tmpber, &along )) == LBER_DEFAULT ) { 4060Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 4070Sstevel@tonic-gate return( NULL ); 4080Sstevel@tonic-gate } 4090Sstevel@tonic-gate /* Keep length and pointer */ 4100Sstevel@tonic-gate seqstart = tmpber.ber_ptr; 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate /* bind requests have a version number before the DN & other stuff */ 4130Sstevel@tonic-gate if ( tag == LDAP_REQ_BIND && ber_get_int( &tmpber, &ver ) == 4140Sstevel@tonic-gate LBER_DEFAULT ) { 4150Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 4160Sstevel@tonic-gate ber_free( ber, 1 ); 4170Sstevel@tonic-gate return( NULL ); 4180Sstevel@tonic-gate } 4190Sstevel@tonic-gate 4200Sstevel@tonic-gate /* the rest of the request is the DN followed by other stuff */ 4210Sstevel@tonic-gate if ( ber_get_stringa( &tmpber, &dn ) == LBER_DEFAULT ) { 4220Sstevel@tonic-gate ber_free( ber, 1 ); 4230Sstevel@tonic-gate return( NULL ); 4240Sstevel@tonic-gate } 4250Sstevel@tonic-gate if ( urldesc->lud_dn != NULL ) { 4260Sstevel@tonic-gate free( dn ); 4270Sstevel@tonic-gate dn = urldesc->lud_dn; 4280Sstevel@tonic-gate } 4290Sstevel@tonic-gate 4300Sstevel@tonic-gate /* see what to do with CONTROLS */ 4310Sstevel@tonic-gate 4320Sstevel@tonic-gate if ( tag == LDAP_REQ_BIND ) { 4330Sstevel@tonic-gate rc = ber_printf( ber, "{it{is", msgid, tag, ver, dn ); 4340Sstevel@tonic-gate } else { 4350Sstevel@tonic-gate rc = ber_printf( ber, "{it{s", msgid, tag, dn ); 4360Sstevel@tonic-gate } 4370Sstevel@tonic-gate 4380Sstevel@tonic-gate if ( rc == -1 ) { 4390Sstevel@tonic-gate ber_free( ber, 1 ); 4400Sstevel@tonic-gate return( NULL ); 4410Sstevel@tonic-gate } 4420Sstevel@tonic-gate 4430Sstevel@tonic-gate if (tag == LDAP_REQ_SEARCH) { 4440Sstevel@tonic-gate /* Now for SEARCH, decode more of the request */ 4450Sstevel@tonic-gate if (ber_scanf(&tmpber, "iiiib", &scope, &deref, &sizelimit, &timelimit, &attrsonly) == LBER_DEFAULT){ 4460Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 4470Sstevel@tonic-gate ber_free( ber, 1 ); 4480Sstevel@tonic-gate return( NULL ); 4490Sstevel@tonic-gate } 4500Sstevel@tonic-gate if (ber_printf(ber, "iiiib", urldesc->lud_scope == LDAP_SCOPE_UNKNOWN ? scope : urldesc->lud_scope, 4510Sstevel@tonic-gate deref, sizelimit, timelimit, attrsonly) == -1) { 4520Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 4530Sstevel@tonic-gate ber_free( ber, 1 ); 4540Sstevel@tonic-gate return( NULL ); 4550Sstevel@tonic-gate } 4560Sstevel@tonic-gate /* We should then decode and check the filter as opposed to ludp->lud_filter */ 4570Sstevel@tonic-gate /* Same for attributes */ 4580Sstevel@tonic-gate /* Later */ 4590Sstevel@tonic-gate } 4600Sstevel@tonic-gate /* The rest is the same for all requests */ 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate /* Copy Buffer from tmpber.ber_ptr for along - (tmpber.ber_ptr - seqstart) */ 4630Sstevel@tonic-gate /* It's the rest of the request */ 4640Sstevel@tonic-gate len = along - ( tmpber.ber_ptr - seqstart); 4650Sstevel@tonic-gate if ( ber_write( ber, tmpber.ber_ptr, len, 0) != len || 4660Sstevel@tonic-gate ber_printf( ber, "}" ) == -1 ) { 4670Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 4680Sstevel@tonic-gate ber_free( ber, 1 ); 4690Sstevel@tonic-gate return( NULL ); 4700Sstevel@tonic-gate } 4710Sstevel@tonic-gate 4720Sstevel@tonic-gate if (seqstart + along < tmpber.ber_end){ /* there's probably some controls, copy them also */ 4730Sstevel@tonic-gate len = tmpber.ber_end - seqstart - along; 4740Sstevel@tonic-gate if ( ber_write( ber, seqstart + along, len, 0) != len ){ 4750Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 4760Sstevel@tonic-gate ber_free( ber, 1 ); 4770Sstevel@tonic-gate return( NULL ); 4780Sstevel@tonic-gate } 4790Sstevel@tonic-gate } 4800Sstevel@tonic-gate 4810Sstevel@tonic-gate if ( ber_printf(ber, "}") == -1) { 4820Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 4830Sstevel@tonic-gate ber_free( ber, 1 ); 4840Sstevel@tonic-gate return( NULL ); 4850Sstevel@tonic-gate } 4860Sstevel@tonic-gate 4870Sstevel@tonic-gate #ifdef LDAP_DEBUG 4880Sstevel@tonic-gate if ( ldap_debug & LDAP_DEBUG_PACKETS ) { 4890Sstevel@tonic-gate Debug( LDAP_DEBUG_ANY, catgets(slapdcat, 1, 222, "re_encode_request new request is:\n"), 4900Sstevel@tonic-gate 0, 0, 0 ); 4910Sstevel@tonic-gate ber_dump( ber, 0 ); 4920Sstevel@tonic-gate } 4930Sstevel@tonic-gate #endif /* LDAP_DEBUG */ 4940Sstevel@tonic-gate 4950Sstevel@tonic-gate return( ber ); 4960Sstevel@tonic-gate } 4970Sstevel@tonic-gate 4980Sstevel@tonic-gate 4990Sstevel@tonic-gate LDAPRequest * 5000Sstevel@tonic-gate find_request_by_msgid( LDAP *ld, int msgid ) 5010Sstevel@tonic-gate { 5020Sstevel@tonic-gate LDAPRequest *lr; 5030Sstevel@tonic-gate 5040Sstevel@tonic-gate for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) { 5050Sstevel@tonic-gate if ( msgid == lr->lr_msgid ) { 5060Sstevel@tonic-gate break; 5070Sstevel@tonic-gate } 5080Sstevel@tonic-gate } 5090Sstevel@tonic-gate 5100Sstevel@tonic-gate return( lr ); 5110Sstevel@tonic-gate } 512