1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * 3*0Sstevel@tonic-gate * Copyright %G% Sun Microsystems, Inc. All Rights Reserved 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * 6*0Sstevel@tonic-gate * Comments: 7*0Sstevel@tonic-gate * 8*0Sstevel@tonic-gate */ 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 11*0Sstevel@tonic-gate 12*0Sstevel@tonic-gate #include <stdio.h> 13*0Sstevel@tonic-gate #include <string.h> 14*0Sstevel@tonic-gate #include <sys/time.h> 15*0Sstevel@tonic-gate #include <sys/types.h> 16*0Sstevel@tonic-gate #include <sys/socket.h> 17*0Sstevel@tonic-gate #include <sys/errno.h> 18*0Sstevel@tonic-gate #include "portable.h" 19*0Sstevel@tonic-gate #include "lber.h" 20*0Sstevel@tonic-gate #include "ldap.h" 21*0Sstevel@tonic-gate #include "ldap-private.h" 22*0Sstevel@tonic-gate #include "ldap-int.h" 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate static BerElement * 25*0Sstevel@tonic-gate re_encode_request( LDAP *ld, BerElement *origber, int msgid, LDAPURLDesc *urldesc ); 26*0Sstevel@tonic-gate static void addFollowedRef(LDAPRequest *lr, char *ref); 27*0Sstevel@tonic-gate static void addToFollowRef(LDAPRequest *lr, char *ref); 28*0Sstevel@tonic-gate static int addUnFollowedRef(LDAP *ld, LDAPRequest *lr, char *ref); 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate char ** ldap_errormsg2referrals(char *errmsg) { 31*0Sstevel@tonic-gate char ** refs; 32*0Sstevel@tonic-gate int count; 33*0Sstevel@tonic-gate size_t len; 34*0Sstevel@tonic-gate char *p, *ref; 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate if (errmsg == NULL){ 37*0Sstevel@tonic-gate return (NULL); 38*0Sstevel@tonic-gate } 39*0Sstevel@tonic-gate len = strlen( errmsg ); 40*0Sstevel@tonic-gate for ( p = errmsg; len >= LDAP_REF_STR_LEN; ++p, --len ) { 41*0Sstevel@tonic-gate if (( *p == 'R' || *p == 'r' ) && strncasecmp( p, 42*0Sstevel@tonic-gate LDAP_REF_STR, LDAP_REF_STR_LEN ) == 0 ) { 43*0Sstevel@tonic-gate *p = '\0'; 44*0Sstevel@tonic-gate p += LDAP_REF_STR_LEN; 45*0Sstevel@tonic-gate break; 46*0Sstevel@tonic-gate } 47*0Sstevel@tonic-gate } 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate if ( len < LDAP_REF_STR_LEN ) { 50*0Sstevel@tonic-gate return( NULL); 51*0Sstevel@tonic-gate } 52*0Sstevel@tonic-gate count = 1; 53*0Sstevel@tonic-gate ref = p; 54*0Sstevel@tonic-gate while ((ref = strchr(ref, '\n')) != NULL) 55*0Sstevel@tonic-gate count++; 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate if ((refs = (char **)calloc(count + 1, sizeof(char *))) == NULL){ 58*0Sstevel@tonic-gate return (NULL); 59*0Sstevel@tonic-gate } 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate count = 0; 62*0Sstevel@tonic-gate for (ref = p; ref != NULL; ref= p){ 63*0Sstevel@tonic-gate if ((p = strchr(ref, '\n')) != NULL){ 64*0Sstevel@tonic-gate *p = '\0'; 65*0Sstevel@tonic-gate } 66*0Sstevel@tonic-gate refs[count++] = strdup(ref); 67*0Sstevel@tonic-gate if (p != NULL) 68*0Sstevel@tonic-gate *p++ = '\n'; 69*0Sstevel@tonic-gate } 70*0Sstevel@tonic-gate return (refs); 71*0Sstevel@tonic-gate } 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate char *ldap_referral2error_msg(char ** refs) 74*0Sstevel@tonic-gate { 75*0Sstevel@tonic-gate int i; 76*0Sstevel@tonic-gate size_t len = 0; 77*0Sstevel@tonic-gate char *msg = NULL; 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate if (refs == NULL) 80*0Sstevel@tonic-gate return (msg); 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate for (i = 0; refs[i] != NULL; i++){ 83*0Sstevel@tonic-gate len += strlen (refs[i]) + 1; 84*0Sstevel@tonic-gate } 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate if ((len > 0) && ((msg = (char *)malloc(len + LDAP_REF_STR_LEN + 2)) != NULL)) { 87*0Sstevel@tonic-gate strncpy(msg, LDAP_REF_STR, LDAP_REF_STR_LEN); 88*0Sstevel@tonic-gate for (i = 0; refs[i] != NULL; i++) { 89*0Sstevel@tonic-gate strcat(msg, refs[i]); 90*0Sstevel@tonic-gate strcat(msg, "\n"); 91*0Sstevel@tonic-gate } 92*0Sstevel@tonic-gate } 93*0Sstevel@tonic-gate return (msg); 94*0Sstevel@tonic-gate } 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate int 98*0Sstevel@tonic-gate chase_referrals( LDAP *ld, LDAPRequest *lr, char **refs, int *count, int samerequest ) 99*0Sstevel@tonic-gate { 100*0Sstevel@tonic-gate int rc, len, newdn, i, j, refcnt, errCode; 101*0Sstevel@tonic-gate char *p, *ports, *ref, *tmpref, *refdn; 102*0Sstevel@tonic-gate LDAPRequest *origreq; 103*0Sstevel@tonic-gate LDAPServer *srv; 104*0Sstevel@tonic-gate BerElement *ber; 105*0Sstevel@tonic-gate LDAPURLDesc *ludp; 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 215, "=> chase_referrals\n"), 0, 0, 0 ); 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gate ld->ld_errno = LDAP_SUCCESS; /* optimistic */ 111*0Sstevel@tonic-gate *count = 0; 112*0Sstevel@tonic-gate if ( refs == NULL ) { 113*0Sstevel@tonic-gate return( LDAP_SUCCESS ); 114*0Sstevel@tonic-gate } 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate #ifdef _REENTRANT 117*0Sstevel@tonic-gate LOCK_LDAP(ld); 118*0Sstevel@tonic-gate #endif 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate if ( lr->lr_parentcnt >= ld->ld_refhoplimit ) { 121*0Sstevel@tonic-gate Debug( LDAP_DEBUG_ANY, 122*0Sstevel@tonic-gate catgets(slapdcat, 1, 216, "more than %d referral hops (dropping)\n"), 123*0Sstevel@tonic-gate ld->ld_refhoplimit, 0, 0 ); 124*0Sstevel@tonic-gate /* XXX report as error in ld->ld_errno? */ 125*0Sstevel@tonic-gate rc = ld->ld_errno = (ld->ld_version >= LDAP_VERSION3) ? LDAP_REFERRAL_LIMIT_EXCEEDED : LDAP_OTHER; 126*0Sstevel@tonic-gate #ifdef _REENTRANT 127*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 128*0Sstevel@tonic-gate #endif 129*0Sstevel@tonic-gate return( rc ); 130*0Sstevel@tonic-gate } 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gate /* find original request */ 133*0Sstevel@tonic-gate for ( origreq = lr; origreq->lr_parent != NULL; 134*0Sstevel@tonic-gate origreq = origreq->lr_parent ) { 135*0Sstevel@tonic-gate ; 136*0Sstevel@tonic-gate } 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate for (refcnt = 0; refs[refcnt] != NULL; refcnt++) 139*0Sstevel@tonic-gate ; /* Count number of referrals */ 140*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 1277, "%d possible referrals to chase\n"), refcnt, 0,0); 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate rc = 0; 143*0Sstevel@tonic-gate /* parse out & follow referrals */ 144*0Sstevel@tonic-gate for (i = 0; rc == 0 && refs[i] != NULL; i++) { 145*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, -1, "Try to chase %s\n"), refs[i], 0,0); 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate /* Parse URL */ 148*0Sstevel@tonic-gate if (ldap_url_parse(refs[i], &ludp) != 0){ 149*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, -1, "Bad URL for referral %s\n"), refs[i], 0,0); 150*0Sstevel@tonic-gate errCode = LDAP_PARAM_ERROR; 151*0Sstevel@tonic-gate addUnFollowedRef(ld, lr, refs[i]); 152*0Sstevel@tonic-gate /* try next URL */ 153*0Sstevel@tonic-gate continue; 154*0Sstevel@tonic-gate } 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gate /* Encode previous request with new URL */ 157*0Sstevel@tonic-gate if (( ber = re_encode_request( ld, origreq->lr_ber, ++ld->ld_msgid, ludp )) == NULL ) { 158*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, -1, "Error while encoding request for referral\n"), 0, 0,0); 159*0Sstevel@tonic-gate ldap_free_urldesc(ludp); 160*0Sstevel@tonic-gate errCode = ld->ld_errno; 161*0Sstevel@tonic-gate addUnFollowedRef(ld, lr, refs[i]); 162*0Sstevel@tonic-gate /* try next URL */ 163*0Sstevel@tonic-gate continue; 164*0Sstevel@tonic-gate } 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate if (( srv = (LDAPServer *)calloc( 1, sizeof( LDAPServer ))) == NULL ) { 167*0Sstevel@tonic-gate ldap_free_urldesc(ludp); 168*0Sstevel@tonic-gate ber_free( ber, 1 ); 169*0Sstevel@tonic-gate rc = ld->ld_errno = LDAP_NO_MEMORY; 170*0Sstevel@tonic-gate #ifdef _REENTRANT 171*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 172*0Sstevel@tonic-gate #endif 173*0Sstevel@tonic-gate return( rc ); 174*0Sstevel@tonic-gate } 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate if (( srv->lsrv_host = strdup( ludp->lud_host ? ludp->lud_host : ld->ld_defhost)) == NULL ) { 177*0Sstevel@tonic-gate ldap_free_urldesc(ludp); 178*0Sstevel@tonic-gate free( (char *)srv ); 179*0Sstevel@tonic-gate ber_free( ber, 1 ); 180*0Sstevel@tonic-gate rc = ld->ld_errno = LDAP_NO_MEMORY; 181*0Sstevel@tonic-gate #ifdef _REENTRANT 182*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 183*0Sstevel@tonic-gate #endif 184*0Sstevel@tonic-gate return( rc ); 185*0Sstevel@tonic-gate } 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate srv->lsrv_port = ludp->lud_port ? ludp->lud_port : LDAP_PORT; 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate if ( srv != NULL && send_server_request( ld, ber, ld->ld_msgid, 190*0Sstevel@tonic-gate lr, srv, NULL, 1 ) >= 0 ) { 191*0Sstevel@tonic-gate ++*count; 192*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, -1, "Request has been forwarded to %s\n"), refs[i], 0,0); 193*0Sstevel@tonic-gate addFollowedRef(lr, refs[i]); 194*0Sstevel@tonic-gate for (j = i+1; refs[j] != NULL; j++){ 195*0Sstevel@tonic-gate addToFollowRef(lr, refs[j]); 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate ldap_free_urldesc(ludp); 198*0Sstevel@tonic-gate break; 199*0Sstevel@tonic-gate } else { 200*0Sstevel@tonic-gate Debug( LDAP_DEBUG_ANY, 201*0Sstevel@tonic-gate catgets(slapdcat, 1, 220, "Unable to chase referral (%s)\n"), 202*0Sstevel@tonic-gate ldap_err2string( ld->ld_errno ), 0, 0 ); 203*0Sstevel@tonic-gate addUnFollowedRef(ld, lr, refs[i]); 204*0Sstevel@tonic-gate errCode = ld->ld_errno; 205*0Sstevel@tonic-gate } 206*0Sstevel@tonic-gate ldap_free_urldesc(ludp); /* So far spawn all requests */ 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate #ifdef _REENTRANT 210*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 211*0Sstevel@tonic-gate #endif 212*0Sstevel@tonic-gate if (refs[i] != NULL) { 213*0Sstevel@tonic-gate rc = LDAP_SUCCESS; 214*0Sstevel@tonic-gate } else { 215*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, -1, "No referral was successfully chased (last error %d)\n"), errCode, 0, 0); 216*0Sstevel@tonic-gate rc = errCode; 217*0Sstevel@tonic-gate } 218*0Sstevel@tonic-gate Debug ( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 1278, "<= chase_referrals --- \n"), 0,0,0); 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate return( rc ); 221*0Sstevel@tonic-gate } 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate static void addFollowedRef(LDAPRequest *lr, char *ref) 224*0Sstevel@tonic-gate { 225*0Sstevel@tonic-gate int i; 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate if (lr->lr_ref_followed == NULL){ 228*0Sstevel@tonic-gate if ((lr->lr_ref_followed = (char **)calloc(2, sizeof(char*))) == NULL) 229*0Sstevel@tonic-gate return; 230*0Sstevel@tonic-gate i = 0; 231*0Sstevel@tonic-gate } else { 232*0Sstevel@tonic-gate for (i = 0; lr->lr_ref_followed[i] != NULL; i++); 233*0Sstevel@tonic-gate if ((lr->lr_ref_followed = (char **)realloc((char *)lr->lr_ref_followed, (i+2) * sizeof(char *))) == NULL){ 234*0Sstevel@tonic-gate return; 235*0Sstevel@tonic-gate } 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate lr->lr_ref_followed[i++] = strdup(ref); 238*0Sstevel@tonic-gate lr->lr_ref_followed[i] = NULL; 239*0Sstevel@tonic-gate return; 240*0Sstevel@tonic-gate } 241*0Sstevel@tonic-gate 242*0Sstevel@tonic-gate static void addToFollowRef(LDAPRequest *lr, char *ref) 243*0Sstevel@tonic-gate { 244*0Sstevel@tonic-gate int i; 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate if (lr->lr_ref_tofollow == NULL){ 247*0Sstevel@tonic-gate if ((lr->lr_ref_tofollow = (char **)calloc(2, sizeof(char*))) == NULL) 248*0Sstevel@tonic-gate return; 249*0Sstevel@tonic-gate i = 0; 250*0Sstevel@tonic-gate } else { 251*0Sstevel@tonic-gate for (i = 0; lr->lr_ref_tofollow[i] != NULL; i++); 252*0Sstevel@tonic-gate if ((lr->lr_ref_tofollow = (char **)realloc((char *)lr->lr_ref_tofollow, (i+2) * sizeof(char *))) == NULL){ 253*0Sstevel@tonic-gate return; 254*0Sstevel@tonic-gate } 255*0Sstevel@tonic-gate } 256*0Sstevel@tonic-gate lr->lr_ref_tofollow[i++] = strdup(ref); 257*0Sstevel@tonic-gate lr->lr_ref_tofollow[i] = NULL; 258*0Sstevel@tonic-gate return; 259*0Sstevel@tonic-gate } 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gate static int addUnFollowedRef(LDAP *ld, LDAPRequest *lr, char *ref) 262*0Sstevel@tonic-gate { 263*0Sstevel@tonic-gate int i; 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate if (lr->lr_ref_unfollowed == NULL){ 266*0Sstevel@tonic-gate if ((lr->lr_ref_unfollowed = (char **)calloc(2, sizeof(char*))) == NULL){ 267*0Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 268*0Sstevel@tonic-gate return (-1); 269*0Sstevel@tonic-gate } 270*0Sstevel@tonic-gate i = 0; 271*0Sstevel@tonic-gate } else { 272*0Sstevel@tonic-gate for (i = 0; lr->lr_ref_unfollowed[i] != NULL; i++); 273*0Sstevel@tonic-gate if ((lr->lr_ref_unfollowed = (char **)realloc((char *)lr->lr_ref_unfollowed, (i+2) * sizeof(char *))) == NULL){ 274*0Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 275*0Sstevel@tonic-gate return (-1); 276*0Sstevel@tonic-gate } 277*0Sstevel@tonic-gate } 278*0Sstevel@tonic-gate lr->lr_ref_unfollowed[i++] = strdup(ref); 279*0Sstevel@tonic-gate lr->lr_ref_unfollowed[i] = NULL; 280*0Sstevel@tonic-gate return (0); 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate int 285*0Sstevel@tonic-gate append_referral( LDAP *ld, char **referralsp, char *s ) 286*0Sstevel@tonic-gate { 287*0Sstevel@tonic-gate int first; 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate if ( *referralsp == NULL ) { 290*0Sstevel@tonic-gate first = 1; 291*0Sstevel@tonic-gate *referralsp = (char *)malloc( strlen( s ) + LDAP_REF_STR_LEN 292*0Sstevel@tonic-gate + 1 ); 293*0Sstevel@tonic-gate } else { 294*0Sstevel@tonic-gate first = 0; 295*0Sstevel@tonic-gate *referralsp = (char *)realloc( *referralsp, 296*0Sstevel@tonic-gate strlen( *referralsp ) + strlen( s ) + 2 ); 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gate if ( *referralsp == NULL ) { 300*0Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 301*0Sstevel@tonic-gate return( -1 ); 302*0Sstevel@tonic-gate } 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate if ( first ) { 305*0Sstevel@tonic-gate strcpy( *referralsp, LDAP_REF_STR ); 306*0Sstevel@tonic-gate } else { 307*0Sstevel@tonic-gate strcat( *referralsp, "\n" ); 308*0Sstevel@tonic-gate } 309*0Sstevel@tonic-gate strcat( *referralsp, s ); 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate return( 0 ); 312*0Sstevel@tonic-gate } 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate 316*0Sstevel@tonic-gate static BerElement * 317*0Sstevel@tonic-gate re_encode_request( LDAP *ld, BerElement *origber, int msgid, LDAPURLDesc *urldesc ) 318*0Sstevel@tonic-gate { 319*0Sstevel@tonic-gate /* 320*0Sstevel@tonic-gate * XXX this routine knows way too much about how the lber library works! 321*0Sstevel@tonic-gate */ 322*0Sstevel@tonic-gate unsigned int along, tag, len; 323*0Sstevel@tonic-gate int ver, scope, deref, sizelimit, timelimit, attrsonly; 324*0Sstevel@tonic-gate int rc, hasCtrls; 325*0Sstevel@tonic-gate BerElement tmpber, *ber; 326*0Sstevel@tonic-gate char *dn, *seqstart; 327*0Sstevel@tonic-gate 328*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, 329*0Sstevel@tonic-gate catgets(slapdcat, 1, 221, "re_encode_request: new msgid %1$d, new dn <%2$s>\n"), 330*0Sstevel@tonic-gate msgid, ( urldesc->lud_dn == NULL ) ? "NONE" : urldesc->lud_dn, 0 ); 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate tmpber = *origber; 333*0Sstevel@tonic-gate 334*0Sstevel@tonic-gate /* 335*0Sstevel@tonic-gate * all LDAP requests are sequences that start with a message id, 336*0Sstevel@tonic-gate * followed by a sequence that is tagged with the operation code 337*0Sstevel@tonic-gate */ 338*0Sstevel@tonic-gate /* Bad assumption : delete op is not a sequence. 339*0Sstevel@tonic-gate * So we have a special processing for it : it's much simpler 340*0Sstevel@tonic-gate */ 341*0Sstevel@tonic-gate if ( ber_scanf( &tmpber, "{i", &along ) != LDAP_TAG_MSGID || 342*0Sstevel@tonic-gate ( tag = ber_peek_tag( &tmpber, &along )) == LBER_DEFAULT ) { 343*0Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 344*0Sstevel@tonic-gate return( NULL ); 345*0Sstevel@tonic-gate } 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate /* Special case : delete request is not a sequence of... */ 348*0Sstevel@tonic-gate if (tag == LDAP_REQ_EXTENDED){ 349*0Sstevel@tonic-gate /* return error, I don't know how to do it automatically */ 350*0Sstevel@tonic-gate ld->ld_errno = LDAP_NOT_SUPPORTED; 351*0Sstevel@tonic-gate return (NULL); 352*0Sstevel@tonic-gate } 353*0Sstevel@tonic-gate 354*0Sstevel@tonic-gate if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { 355*0Sstevel@tonic-gate return (NULL); 356*0Sstevel@tonic-gate } 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate if (tag == LDAP_REQ_DELETE) { 359*0Sstevel@tonic-gate if ( ber_get_stringa( &tmpber, &dn ) == LBER_DEFAULT ) { 360*0Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 361*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, 362*0Sstevel@tonic-gate catgets(slapdcat, 1, 1279,"Error in decoding delete DN"),0,0,0); 363*0Sstevel@tonic-gate ber_free( ber, 1); 364*0Sstevel@tonic-gate return( NULL ); 365*0Sstevel@tonic-gate } 366*0Sstevel@tonic-gate /* Check if controls */ 367*0Sstevel@tonic-gate hasCtrls = 0; 368*0Sstevel@tonic-gate if (ber_peek_tag(&tmpber, &len) == LDAP_TAG_CONTROL_LIST){ 369*0Sstevel@tonic-gate hasCtrls = 1; 370*0Sstevel@tonic-gate } 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gate if ( urldesc->lud_dn && *urldesc->lud_dn ) { 373*0Sstevel@tonic-gate free( dn ); 374*0Sstevel@tonic-gate dn = urldesc->lud_dn; 375*0Sstevel@tonic-gate } 376*0Sstevel@tonic-gate if ( ber_printf( ber, "{its", msgid, tag, dn ) == -1 ) { 377*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, "Error in re_encoding delete request",0,0,0); 378*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 379*0Sstevel@tonic-gate ber_free( ber, 1 ); 380*0Sstevel@tonic-gate return (NULL); 381*0Sstevel@tonic-gate } 382*0Sstevel@tonic-gate /* Now add controls if any */ 383*0Sstevel@tonic-gate if (hasCtrls && ber_write( ber, tmpber.ber_ptr, len, 0 ) != len ) { 384*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 385*0Sstevel@tonic-gate ber_free( ber, 1 ); 386*0Sstevel@tonic-gate return( NULL ); 387*0Sstevel@tonic-gate } 388*0Sstevel@tonic-gate if (ber_printf( ber, "}" ) == -1 ) { 389*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 390*0Sstevel@tonic-gate ber_free( ber, 1 ); 391*0Sstevel@tonic-gate return( NULL ); 392*0Sstevel@tonic-gate } 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate #ifdef LDAP_DEBUG 395*0Sstevel@tonic-gate if ( ldap_debug & LDAP_DEBUG_PACKETS ) { 396*0Sstevel@tonic-gate Debug( LDAP_DEBUG_ANY, catgets(slapdcat, 1, 222, "re_encode_request new request is:\n"), 397*0Sstevel@tonic-gate 0, 0, 0 ); 398*0Sstevel@tonic-gate ber_dump( ber, 0 ); 399*0Sstevel@tonic-gate } 400*0Sstevel@tonic-gate #endif /* LDAP_DEBUG */ 401*0Sstevel@tonic-gate return (ber); 402*0Sstevel@tonic-gate } 403*0Sstevel@tonic-gate 404*0Sstevel@tonic-gate if (( tag = ber_skip_tag( &tmpber, &along )) == LBER_DEFAULT ) { 405*0Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 406*0Sstevel@tonic-gate return( NULL ); 407*0Sstevel@tonic-gate } 408*0Sstevel@tonic-gate /* Keep length and pointer */ 409*0Sstevel@tonic-gate seqstart = tmpber.ber_ptr; 410*0Sstevel@tonic-gate 411*0Sstevel@tonic-gate /* bind requests have a version number before the DN & other stuff */ 412*0Sstevel@tonic-gate if ( tag == LDAP_REQ_BIND && ber_get_int( &tmpber, &ver ) == 413*0Sstevel@tonic-gate LBER_DEFAULT ) { 414*0Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 415*0Sstevel@tonic-gate ber_free( ber, 1 ); 416*0Sstevel@tonic-gate return( NULL ); 417*0Sstevel@tonic-gate } 418*0Sstevel@tonic-gate 419*0Sstevel@tonic-gate /* the rest of the request is the DN followed by other stuff */ 420*0Sstevel@tonic-gate if ( ber_get_stringa( &tmpber, &dn ) == LBER_DEFAULT ) { 421*0Sstevel@tonic-gate ber_free( ber, 1 ); 422*0Sstevel@tonic-gate return( NULL ); 423*0Sstevel@tonic-gate } 424*0Sstevel@tonic-gate if ( urldesc->lud_dn != NULL ) { 425*0Sstevel@tonic-gate free( dn ); 426*0Sstevel@tonic-gate dn = urldesc->lud_dn; 427*0Sstevel@tonic-gate } 428*0Sstevel@tonic-gate 429*0Sstevel@tonic-gate /* see what to do with CONTROLS */ 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate if ( tag == LDAP_REQ_BIND ) { 432*0Sstevel@tonic-gate rc = ber_printf( ber, "{it{is", msgid, tag, ver, dn ); 433*0Sstevel@tonic-gate } else { 434*0Sstevel@tonic-gate rc = ber_printf( ber, "{it{s", msgid, tag, dn ); 435*0Sstevel@tonic-gate } 436*0Sstevel@tonic-gate 437*0Sstevel@tonic-gate if ( rc == -1 ) { 438*0Sstevel@tonic-gate ber_free( ber, 1 ); 439*0Sstevel@tonic-gate return( NULL ); 440*0Sstevel@tonic-gate } 441*0Sstevel@tonic-gate 442*0Sstevel@tonic-gate if (tag == LDAP_REQ_SEARCH) { 443*0Sstevel@tonic-gate /* Now for SEARCH, decode more of the request */ 444*0Sstevel@tonic-gate if (ber_scanf(&tmpber, "iiiib", &scope, &deref, &sizelimit, &timelimit, &attrsonly) == LBER_DEFAULT){ 445*0Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 446*0Sstevel@tonic-gate ber_free( ber, 1 ); 447*0Sstevel@tonic-gate return( NULL ); 448*0Sstevel@tonic-gate } 449*0Sstevel@tonic-gate if (ber_printf(ber, "iiiib", urldesc->lud_scope == LDAP_SCOPE_UNKNOWN ? scope : urldesc->lud_scope, 450*0Sstevel@tonic-gate deref, sizelimit, timelimit, attrsonly) == -1) { 451*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 452*0Sstevel@tonic-gate ber_free( ber, 1 ); 453*0Sstevel@tonic-gate return( NULL ); 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate /* We should then decode and check the filter as opposed to ludp->lud_filter */ 456*0Sstevel@tonic-gate /* Same for attributes */ 457*0Sstevel@tonic-gate /* Later */ 458*0Sstevel@tonic-gate } 459*0Sstevel@tonic-gate /* The rest is the same for all requests */ 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate /* Copy Buffer from tmpber.ber_ptr for along - (tmpber.ber_ptr - seqstart) */ 462*0Sstevel@tonic-gate /* It's the rest of the request */ 463*0Sstevel@tonic-gate len = along - ( tmpber.ber_ptr - seqstart); 464*0Sstevel@tonic-gate if ( ber_write( ber, tmpber.ber_ptr, len, 0) != len || 465*0Sstevel@tonic-gate ber_printf( ber, "}" ) == -1 ) { 466*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 467*0Sstevel@tonic-gate ber_free( ber, 1 ); 468*0Sstevel@tonic-gate return( NULL ); 469*0Sstevel@tonic-gate } 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate if (seqstart + along < tmpber.ber_end){ /* there's probably some controls, copy them also */ 472*0Sstevel@tonic-gate len = tmpber.ber_end - seqstart - along; 473*0Sstevel@tonic-gate if ( ber_write( ber, seqstart + along, len, 0) != len ){ 474*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 475*0Sstevel@tonic-gate ber_free( ber, 1 ); 476*0Sstevel@tonic-gate return( NULL ); 477*0Sstevel@tonic-gate } 478*0Sstevel@tonic-gate } 479*0Sstevel@tonic-gate 480*0Sstevel@tonic-gate if ( ber_printf(ber, "}") == -1) { 481*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 482*0Sstevel@tonic-gate ber_free( ber, 1 ); 483*0Sstevel@tonic-gate return( NULL ); 484*0Sstevel@tonic-gate } 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate #ifdef LDAP_DEBUG 487*0Sstevel@tonic-gate if ( ldap_debug & LDAP_DEBUG_PACKETS ) { 488*0Sstevel@tonic-gate Debug( LDAP_DEBUG_ANY, catgets(slapdcat, 1, 222, "re_encode_request new request is:\n"), 489*0Sstevel@tonic-gate 0, 0, 0 ); 490*0Sstevel@tonic-gate ber_dump( ber, 0 ); 491*0Sstevel@tonic-gate } 492*0Sstevel@tonic-gate #endif /* LDAP_DEBUG */ 493*0Sstevel@tonic-gate 494*0Sstevel@tonic-gate return( ber ); 495*0Sstevel@tonic-gate } 496*0Sstevel@tonic-gate 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gate LDAPRequest * 499*0Sstevel@tonic-gate find_request_by_msgid( LDAP *ld, int msgid ) 500*0Sstevel@tonic-gate { 501*0Sstevel@tonic-gate LDAPRequest *lr; 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) { 504*0Sstevel@tonic-gate if ( msgid == lr->lr_msgid ) { 505*0Sstevel@tonic-gate break; 506*0Sstevel@tonic-gate } 507*0Sstevel@tonic-gate } 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gate return( lr ); 510*0Sstevel@tonic-gate } 511