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 160Sstevel@tonic-gate #include "lber.h" 170Sstevel@tonic-gate #include "ldap.h" 180Sstevel@tonic-gate #include "ldap-private.h" 190Sstevel@tonic-gate #include "ldap-int.h" 200Sstevel@tonic-gate 210Sstevel@tonic-gate 220Sstevel@tonic-gate int ldap_create_virtuallist_control(LDAP *ld, LDAPVirtualList *ldvlistp, 230Sstevel@tonic-gate LDAPControl **ctrlp) 240Sstevel@tonic-gate { 250Sstevel@tonic-gate BerElement *ber; 260Sstevel@tonic-gate int rc; 270Sstevel@tonic-gate 280Sstevel@tonic-gate if (NULL == ld) 290Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 300Sstevel@tonic-gate 310Sstevel@tonic-gate if (NULL == ctrlp || NULL == ldvlistp) 320Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 330Sstevel@tonic-gate 340Sstevel@tonic-gate if ((ber = alloc_ber_with_options(ld)) == NULLBER) { 350Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 360Sstevel@tonic-gate return (LDAP_NO_MEMORY); 370Sstevel@tonic-gate } 380Sstevel@tonic-gate 390Sstevel@tonic-gate if (ber_printf(ber, "{ii", ldvlistp->ldvlist_before_count, 400Sstevel@tonic-gate ldvlistp->ldvlist_after_count) == -1) { 410Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 420Sstevel@tonic-gate ber_free(ber, 1); 430Sstevel@tonic-gate return (LDAP_ENCODING_ERROR); 440Sstevel@tonic-gate } 450Sstevel@tonic-gate 460Sstevel@tonic-gate if (NULL == ldvlistp->ldvlist_attrvalue) { 470Sstevel@tonic-gate if (ber_printf(ber, "t{ii}}", LDAP_TAG_VLV_BY_INDEX, 480Sstevel@tonic-gate ldvlistp->ldvlist_index, 490Sstevel@tonic-gate ldvlistp->ldvlist_size) == -1) { 500Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 510Sstevel@tonic-gate ber_free(ber, 1); 520Sstevel@tonic-gate return (LDAP_ENCODING_ERROR); 530Sstevel@tonic-gate } 540Sstevel@tonic-gate } else { 550Sstevel@tonic-gate if (ber_printf(ber, "to}", LDAP_TAG_VLV_BY_VALUE, 560Sstevel@tonic-gate ldvlistp->ldvlist_attrvalue, 570Sstevel@tonic-gate strlen(ldvlistp->ldvlist_attrvalue)) == -1) { 580Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 590Sstevel@tonic-gate ber_free(ber, 1); 600Sstevel@tonic-gate return (LDAP_ENCODING_ERROR); 610Sstevel@tonic-gate } 620Sstevel@tonic-gate } 630Sstevel@tonic-gate 640Sstevel@tonic-gate rc = ldap_build_control(LDAP_CONTROL_VLVREQUEST, ber, 1, 1, ctrlp); 650Sstevel@tonic-gate ld->ld_errno = rc; 660Sstevel@tonic-gate return (rc); 670Sstevel@tonic-gate } 680Sstevel@tonic-gate 690Sstevel@tonic-gate 700Sstevel@tonic-gate int ldap_parse_virtuallist_control(LDAP *ld, LDAPControl **ctrls, 710Sstevel@tonic-gate unsigned long *target_posp, unsigned long *list_sizep, int *errcodep) 720Sstevel@tonic-gate { 730Sstevel@tonic-gate BerElement *ber; 740Sstevel@tonic-gate int i, foundListControl; 750Sstevel@tonic-gate LDAPControl *listCtrlp; 760Sstevel@tonic-gate 770Sstevel@tonic-gate if (NULL == ld) 780Sstevel@tonic-gate return (LDAP_PARAM_ERROR); 790Sstevel@tonic-gate 800Sstevel@tonic-gate /* only ldapv3 or higher can do virtual lists. */ 810Sstevel@tonic-gate if (ld->ld_version != LDAP_VERSION3) { 820Sstevel@tonic-gate ld->ld_errno = LDAP_NOT_SUPPORTED; 830Sstevel@tonic-gate return (LDAP_NOT_SUPPORTED); 840Sstevel@tonic-gate } 850Sstevel@tonic-gate 860Sstevel@tonic-gate /* find the listControl in the list of controls if it exists */ 870Sstevel@tonic-gate if (ctrls == NULL) { 880Sstevel@tonic-gate ld->ld_errno = LDAP_NOT_SUPPORTED; 890Sstevel@tonic-gate return (LDAP_NOT_SUPPORTED); 900Sstevel@tonic-gate } 910Sstevel@tonic-gate 920Sstevel@tonic-gate foundListControl = 0; 930Sstevel@tonic-gate for (i = 0; ((ctrls[i] != NULL) && (!foundListControl)); i++) { 940Sstevel@tonic-gate foundListControl = !(strcmp(ctrls[i]->ldctl_oid, 950Sstevel@tonic-gate LDAP_CONTROL_VLVRESPONSE)); 960Sstevel@tonic-gate } 970Sstevel@tonic-gate if (!foundListControl) { 980Sstevel@tonic-gate ld->ld_errno = LDAP_CONTROL_NOT_FOUND; 990Sstevel@tonic-gate return (LDAP_CONTROL_NOT_FOUND); 1000Sstevel@tonic-gate } else { 1010Sstevel@tonic-gate /* let local var point to the listControl */ 1020Sstevel@tonic-gate listCtrlp = ctrls[i-1]; 1030Sstevel@tonic-gate } 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate /* allocate a Ber element with the contents of the list_control's */ 1060Sstevel@tonic-gate /* struct berval */ 1070Sstevel@tonic-gate if ((ber = ber_init(&listCtrlp->ldctl_value)) == NULL) { 1080Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 1090Sstevel@tonic-gate return (LDAP_NO_MEMORY); 1100Sstevel@tonic-gate } 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate /* decode the result from the Berelement */ 1130Sstevel@tonic-gate if (LBER_ERROR == ber_scanf(ber, "{iie}", target_posp, list_sizep, 1140Sstevel@tonic-gate errcodep)) { 1150Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR; 1160Sstevel@tonic-gate ber_free(ber, 1); 1170Sstevel@tonic-gate return (LDAP_DECODING_ERROR); 1180Sstevel@tonic-gate } 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate /* the ber encoding is no longer needed */ 1210Sstevel@tonic-gate ber_free(ber, 1); 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate return (LDAP_SUCCESS); 1240Sstevel@tonic-gate } 125