1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * 3*0Sstevel@tonic-gate * Portions Copyright %G% Sun Microsystems, Inc. 4*0Sstevel@tonic-gate * All Rights Reserved 5*0Sstevel@tonic-gate * 6*0Sstevel@tonic-gate */ 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gate /* 11*0Sstevel@tonic-gate * Copyright (c) 1990 Regents of the University of Michigan. 12*0Sstevel@tonic-gate * All rights reserved. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * compare.c 15*0Sstevel@tonic-gate */ 16*0Sstevel@tonic-gate 17*0Sstevel@tonic-gate #ifndef lint 18*0Sstevel@tonic-gate static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n"; 19*0Sstevel@tonic-gate #endif 20*0Sstevel@tonic-gate 21*0Sstevel@tonic-gate #include <stdio.h> 22*0Sstevel@tonic-gate #include <string.h> 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate #ifdef MACOS 25*0Sstevel@tonic-gate #include "macos.h" 26*0Sstevel@tonic-gate #endif /* MACOS */ 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate #if !defined( MACOS ) && !defined( DOS ) 29*0Sstevel@tonic-gate #include <sys/types.h> 30*0Sstevel@tonic-gate #include <sys/socket.h> 31*0Sstevel@tonic-gate #endif 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #include "lber.h" 34*0Sstevel@tonic-gate #include "ldap.h" 35*0Sstevel@tonic-gate #include "ldap-private.h" 36*0Sstevel@tonic-gate #include "ldap-int.h" 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate BerElement * ldap_build_compare_req(LDAP *ld, char *dn, char *attr, 39*0Sstevel@tonic-gate struct berval *bvalue, LDAPControl **serverctrls) 40*0Sstevel@tonic-gate { 41*0Sstevel@tonic-gate BerElement *ber; 42*0Sstevel@tonic-gate int rc, rv; 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate /* The compare request looks like this: 45*0Sstevel@tonic-gate * CompareRequest ::= SEQUENCE { 46*0Sstevel@tonic-gate * entry DistinguishedName, 47*0Sstevel@tonic-gate * ava SEQUENCE { 48*0Sstevel@tonic-gate * type AttributeType, 49*0Sstevel@tonic-gate * value AttributeValue 50*0Sstevel@tonic-gate * } 51*0Sstevel@tonic-gate * } 52*0Sstevel@tonic-gate * and must be wrapped in an LDAPMessage. 53*0Sstevel@tonic-gate */ 54*0Sstevel@tonic-gate /* create a message to send */ 55*0Sstevel@tonic-gate if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { 56*0Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 57*0Sstevel@tonic-gate return( NULLBER ); 58*0Sstevel@tonic-gate } 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate if ( ber_printf( ber, "{it{s{so}}", ++ld->ld_msgid, LDAP_REQ_COMPARE, 61*0Sstevel@tonic-gate dn, attr, bvalue->bv_val, bvalue->bv_len ) == -1 ) { 62*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 63*0Sstevel@tonic-gate ber_free( ber, 1 ); 64*0Sstevel@tonic-gate return( NULLBER ); 65*0Sstevel@tonic-gate } 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate /* LDAPv3 */ 68*0Sstevel@tonic-gate /* Code controls if any */ 69*0Sstevel@tonic-gate if (serverctrls && serverctrls[0]) { 70*0Sstevel@tonic-gate if (ldap_controls_code(ber, serverctrls) != LDAP_SUCCESS){ 71*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 72*0Sstevel@tonic-gate return( NULLBER ); 73*0Sstevel@tonic-gate } 74*0Sstevel@tonic-gate } else if (ld->ld_srvctrls && ld->ld_srvctrls[0]) { 75*0Sstevel@tonic-gate /* Otherwise, is there any global server ctrls ? */ 76*0Sstevel@tonic-gate if (ldap_controls_code(ber, ld->ld_srvctrls) != LDAP_SUCCESS){ 77*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 78*0Sstevel@tonic-gate return( NULLBER ); 79*0Sstevel@tonic-gate } 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate if (ber_printf(ber, "}") == -1) { 82*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 83*0Sstevel@tonic-gate ber_free(ber, 1); 84*0Sstevel@tonic-gate return (NULLBER); 85*0Sstevel@tonic-gate } 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate return (ber); 88*0Sstevel@tonic-gate } 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate /* 91*0Sstevel@tonic-gate * ldap_compare - perform an ldap (and X.500) compare operation. The dn 92*0Sstevel@tonic-gate * of the entry to compare to and the attribute and value to compare (in 93*0Sstevel@tonic-gate * attr and value) are supplied. The msgid of the response is returned. 94*0Sstevel@tonic-gate * 95*0Sstevel@tonic-gate * Example: 96*0Sstevel@tonic-gate * ldap_compare( ld, "c=us@cn=bob", "userPassword", "secret" ) 97*0Sstevel@tonic-gate */ 98*0Sstevel@tonic-gate int 99*0Sstevel@tonic-gate ldap_compare( LDAP *ld, char *dn, char *attr, char *value ) 100*0Sstevel@tonic-gate { 101*0Sstevel@tonic-gate BerElement *ber; 102*0Sstevel@tonic-gate struct berval bv; 103*0Sstevel@tonic-gate int rv; 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate /* The compare request looks like this: 106*0Sstevel@tonic-gate * CompareRequest ::= SEQUENCE { 107*0Sstevel@tonic-gate * entry DistinguishedName, 108*0Sstevel@tonic-gate * ava SEQUENCE { 109*0Sstevel@tonic-gate * type AttributeType, 110*0Sstevel@tonic-gate * value AttributeValue 111*0Sstevel@tonic-gate * } 112*0Sstevel@tonic-gate * } 113*0Sstevel@tonic-gate * and must be wrapped in an LDAPMessage. 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 Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 128, "ldap_compare\n"), 0, 0, 0 ); 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate bv.bv_val = value; 122*0Sstevel@tonic-gate bv.bv_len = strlen(value); 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate if ((ber = ldap_build_compare_req(ld, dn, attr, &bv, NULL)) == NULLBER) { 125*0Sstevel@tonic-gate #ifdef _REENTRANT 126*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 127*0Sstevel@tonic-gate #endif 128*0Sstevel@tonic-gate return (-1); 129*0Sstevel@tonic-gate } 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate #ifndef NO_CACHE 132*0Sstevel@tonic-gate if ( ld->ld_cache != NULL ) { 133*0Sstevel@tonic-gate if ( check_cache( ld, LDAP_REQ_COMPARE, ber ) == 0 ) { 134*0Sstevel@tonic-gate ber_free( ber, 1 ); 135*0Sstevel@tonic-gate ld->ld_errno = LDAP_SUCCESS; 136*0Sstevel@tonic-gate #ifdef _REENTRANT 137*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 138*0Sstevel@tonic-gate #endif 139*0Sstevel@tonic-gate return( ld->ld_msgid ); 140*0Sstevel@tonic-gate } 141*0Sstevel@tonic-gate add_request_to_cache( ld, LDAP_REQ_COMPARE, ber ); 142*0Sstevel@tonic-gate } 143*0Sstevel@tonic-gate #endif /* NO_CACHE */ 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate /* send the message */ 146*0Sstevel@tonic-gate rv = send_initial_request( ld, LDAP_REQ_COMPARE, dn, ber ); 147*0Sstevel@tonic-gate #ifdef _REENTRANT 148*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 149*0Sstevel@tonic-gate #endif 150*0Sstevel@tonic-gate return (rv); 151*0Sstevel@tonic-gate } 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate int 154*0Sstevel@tonic-gate ldap_compare_s( LDAP *ld, char *dn, char *attr, char *value ) 155*0Sstevel@tonic-gate { 156*0Sstevel@tonic-gate int msgid; 157*0Sstevel@tonic-gate LDAPMessage *res; 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate if ( (msgid = ldap_compare( ld, dn, attr, value )) == -1 ) 160*0Sstevel@tonic-gate return( ld->ld_errno ); 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) 163*0Sstevel@tonic-gate return( ld->ld_errno ); 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate return( ldap_result2error( ld, res, 1 ) ); 166*0Sstevel@tonic-gate } 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate /* LDAPv3 API extensions */ 169*0Sstevel@tonic-gate int ldap_compare_ext(LDAP *ld, char *dn, char *attr, struct berval *bvalue, 170*0Sstevel@tonic-gate LDAPControl ** serverctrls, LDAPControl **clientctrls, int *msgidp) 171*0Sstevel@tonic-gate { 172*0Sstevel@tonic-gate BerElement *ber; 173*0Sstevel@tonic-gate struct berval bv; 174*0Sstevel@tonic-gate int rv; 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate /* The compare request looks like this: 177*0Sstevel@tonic-gate * CompareRequest ::= SEQUENCE { 178*0Sstevel@tonic-gate * entry DistinguishedName, 179*0Sstevel@tonic-gate * ava SEQUENCE { 180*0Sstevel@tonic-gate * type AttributeType, 181*0Sstevel@tonic-gate * value AttributeValue 182*0Sstevel@tonic-gate * } 183*0Sstevel@tonic-gate * } 184*0Sstevel@tonic-gate * and must be wrapped in an LDAPMessage. 185*0Sstevel@tonic-gate */ 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate #ifdef _REENTRANT 188*0Sstevel@tonic-gate LOCK_LDAP(ld); 189*0Sstevel@tonic-gate #endif 190*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 128, "ldap_compare\n"), 0, 0, 0 ); 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate if ((ber = ldap_build_compare_req(ld, dn, attr, bvalue, NULL)) == NULLBER) { 193*0Sstevel@tonic-gate rv = ld->ld_errno; 194*0Sstevel@tonic-gate if (rv == LDAP_SUCCESS) 195*0Sstevel@tonic-gate rv = LDAP_OTHER; 196*0Sstevel@tonic-gate #ifdef _REENTRANT 197*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 198*0Sstevel@tonic-gate #endif 199*0Sstevel@tonic-gate return (rv); 200*0Sstevel@tonic-gate } 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate #ifndef NO_CACHE 203*0Sstevel@tonic-gate if ( ld->ld_cache != NULL ) { 204*0Sstevel@tonic-gate if ( check_cache( ld, LDAP_REQ_COMPARE, ber ) == 0 ) { 205*0Sstevel@tonic-gate ber_free( ber, 1 ); 206*0Sstevel@tonic-gate ld->ld_errno = LDAP_SUCCESS; 207*0Sstevel@tonic-gate *msgidp = ld->ld_msgid; 208*0Sstevel@tonic-gate #ifdef _REENTRANT 209*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 210*0Sstevel@tonic-gate #endif 211*0Sstevel@tonic-gate return( LDAP_SUCCESS ); 212*0Sstevel@tonic-gate } 213*0Sstevel@tonic-gate add_request_to_cache( ld, LDAP_REQ_COMPARE, ber ); 214*0Sstevel@tonic-gate } 215*0Sstevel@tonic-gate #endif /* NO_CACHE */ 216*0Sstevel@tonic-gate 217*0Sstevel@tonic-gate /* send the message */ 218*0Sstevel@tonic-gate rv = send_initial_request( ld, LDAP_REQ_COMPARE, dn, ber ); 219*0Sstevel@tonic-gate if (rv == -1) { 220*0Sstevel@tonic-gate rv = ld->ld_errno; 221*0Sstevel@tonic-gate if (rv == LDAP_SUCCESS){ 222*0Sstevel@tonic-gate rv = LDAP_OTHER; 223*0Sstevel@tonic-gate } 224*0Sstevel@tonic-gate #ifdef _REENTRANT 225*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 226*0Sstevel@tonic-gate #endif 227*0Sstevel@tonic-gate return (rv); 228*0Sstevel@tonic-gate } 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate *msgidp = rv; 231*0Sstevel@tonic-gate #ifdef _REENTRANT 232*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 233*0Sstevel@tonic-gate #endif 234*0Sstevel@tonic-gate return (LDAP_SUCCESS); 235*0Sstevel@tonic-gate } 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate int ldap_compare_ext_s(LDAP *ld, char *dn, char *attr, struct berval *bvalue, 238*0Sstevel@tonic-gate LDAPControl ** serverctrls, LDAPControl **clientctrls) 239*0Sstevel@tonic-gate { 240*0Sstevel@tonic-gate int msgid, retcode = LDAP_SUCCESS; 241*0Sstevel@tonic-gate LDAPMessage *res; 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gate if ( (retcode = ldap_compare_ext( ld, dn, attr, bvalue, serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS ) 244*0Sstevel@tonic-gate return( retcode ); 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) 247*0Sstevel@tonic-gate return( ld->ld_errno ); 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate #ifdef _REENTRANT 250*0Sstevel@tonic-gate LOCK_LDAP(ld); 251*0Sstevel@tonic-gate #endif 252*0Sstevel@tonic-gate retcode = ldap_parse_result( ld, res, &ld->ld_errno, &ld->ld_matched, &ld->ld_error, 253*0Sstevel@tonic-gate &ld->ld_referrals, &ld->ld_ret_ctrls, 1); 254*0Sstevel@tonic-gate if (retcode == LDAP_SUCCESS) 255*0Sstevel@tonic-gate retcode = ld->ld_errno; 256*0Sstevel@tonic-gate #ifdef _REENTRANT 257*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 258*0Sstevel@tonic-gate #endif 259*0Sstevel@tonic-gate return (retcode); 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate 262