1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  *
3*0Sstevel@tonic-gate  * Copyright %G% Sun Microsystems, Inc.
4*0Sstevel@tonic-gate  * All Rights Reserved
5*0Sstevel@tonic-gate  *
6*0Sstevel@tonic-gate  *
7*0Sstevel@tonic-gate  * Comments:
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  */
10*0Sstevel@tonic-gate 
11*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
12*0Sstevel@tonic-gate 
13*0Sstevel@tonic-gate #include <stdio.h>
14*0Sstevel@tonic-gate #include <string.h>
15*0Sstevel@tonic-gate 
16*0Sstevel@tonic-gate #include "lber.h"
17*0Sstevel@tonic-gate #include "ldap.h"
18*0Sstevel@tonic-gate #include "ldap-private.h"
19*0Sstevel@tonic-gate #include "ldap-int.h"
20*0Sstevel@tonic-gate 
21*0Sstevel@tonic-gate 
22*0Sstevel@tonic-gate int ldap_create_virtuallist_control(LDAP *ld, LDAPVirtualList *ldvlistp,
23*0Sstevel@tonic-gate 	LDAPControl **ctrlp)
24*0Sstevel@tonic-gate {
25*0Sstevel@tonic-gate 	BerElement *ber;
26*0Sstevel@tonic-gate 	int rc;
27*0Sstevel@tonic-gate 
28*0Sstevel@tonic-gate 	if (NULL == ld)
29*0Sstevel@tonic-gate 		return (LDAP_PARAM_ERROR);
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate 	if (NULL == ctrlp || NULL == ldvlistp)
32*0Sstevel@tonic-gate 		return (LDAP_PARAM_ERROR);
33*0Sstevel@tonic-gate 
34*0Sstevel@tonic-gate 	if ((ber = alloc_ber_with_options(ld)) == NULLBER) {
35*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_NO_MEMORY;
36*0Sstevel@tonic-gate 		return (LDAP_NO_MEMORY);
37*0Sstevel@tonic-gate 	}
38*0Sstevel@tonic-gate 
39*0Sstevel@tonic-gate 	if (ber_printf(ber, "{ii", ldvlistp->ldvlist_before_count,
40*0Sstevel@tonic-gate 		ldvlistp->ldvlist_after_count) == -1) {
41*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_ENCODING_ERROR;
42*0Sstevel@tonic-gate 		ber_free(ber, 1);
43*0Sstevel@tonic-gate 		return (LDAP_ENCODING_ERROR);
44*0Sstevel@tonic-gate 	}
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate 	if (NULL == ldvlistp->ldvlist_attrvalue) {
47*0Sstevel@tonic-gate 		if (ber_printf(ber, "t{ii}}", LDAP_TAG_VLV_BY_INDEX,
48*0Sstevel@tonic-gate 			ldvlistp->ldvlist_index,
49*0Sstevel@tonic-gate 			ldvlistp->ldvlist_size) == -1) {
50*0Sstevel@tonic-gate 			ld->ld_errno = LDAP_ENCODING_ERROR;
51*0Sstevel@tonic-gate 			ber_free(ber, 1);
52*0Sstevel@tonic-gate 			return (LDAP_ENCODING_ERROR);
53*0Sstevel@tonic-gate 		}
54*0Sstevel@tonic-gate 	} else {
55*0Sstevel@tonic-gate 		if (ber_printf(ber, "to}", LDAP_TAG_VLV_BY_VALUE,
56*0Sstevel@tonic-gate 			ldvlistp->ldvlist_attrvalue,
57*0Sstevel@tonic-gate 			strlen(ldvlistp->ldvlist_attrvalue)) == -1) {
58*0Sstevel@tonic-gate 			ld->ld_errno = LDAP_ENCODING_ERROR;
59*0Sstevel@tonic-gate 			ber_free(ber, 1);
60*0Sstevel@tonic-gate 			return (LDAP_ENCODING_ERROR);
61*0Sstevel@tonic-gate 		}
62*0Sstevel@tonic-gate 	}
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate 	rc = ldap_build_control(LDAP_CONTROL_VLVREQUEST, ber, 1, 1, ctrlp);
65*0Sstevel@tonic-gate 	ld->ld_errno = rc;
66*0Sstevel@tonic-gate 	return (rc);
67*0Sstevel@tonic-gate }
68*0Sstevel@tonic-gate 
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate int ldap_parse_virtuallist_control(LDAP *ld, LDAPControl **ctrls,
71*0Sstevel@tonic-gate 	unsigned long *target_posp, unsigned long *list_sizep, int *errcodep)
72*0Sstevel@tonic-gate {
73*0Sstevel@tonic-gate 	BerElement *ber;
74*0Sstevel@tonic-gate 	int i, foundListControl;
75*0Sstevel@tonic-gate 	LDAPControl *listCtrlp;
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate 	if (NULL == ld)
78*0Sstevel@tonic-gate 		return (LDAP_PARAM_ERROR);
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate 	/* only ldapv3 or higher can do virtual lists. */
81*0Sstevel@tonic-gate 	if (ld->ld_version != LDAP_VERSION3) {
82*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_NOT_SUPPORTED;
83*0Sstevel@tonic-gate 		return (LDAP_NOT_SUPPORTED);
84*0Sstevel@tonic-gate 	}
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate 	/* find the listControl in the list of controls if it exists */
87*0Sstevel@tonic-gate 	if (ctrls == NULL) {
88*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_NOT_SUPPORTED;
89*0Sstevel@tonic-gate 		return (LDAP_NOT_SUPPORTED);
90*0Sstevel@tonic-gate 	}
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate 	foundListControl = 0;
93*0Sstevel@tonic-gate 	for (i = 0; ((ctrls[i] != NULL) && (!foundListControl)); i++) {
94*0Sstevel@tonic-gate 		foundListControl = !(strcmp(ctrls[i]->ldctl_oid,
95*0Sstevel@tonic-gate 			LDAP_CONTROL_VLVRESPONSE));
96*0Sstevel@tonic-gate 	}
97*0Sstevel@tonic-gate 	if (!foundListControl) {
98*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
99*0Sstevel@tonic-gate 		return (LDAP_CONTROL_NOT_FOUND);
100*0Sstevel@tonic-gate 	} else {
101*0Sstevel@tonic-gate 		/* let local var point to the listControl */
102*0Sstevel@tonic-gate 		listCtrlp = ctrls[i-1];
103*0Sstevel@tonic-gate 	}
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate 	/* allocate a Ber element with the contents of the list_control's */
106*0Sstevel@tonic-gate 	/* struct berval */
107*0Sstevel@tonic-gate 	if ((ber = ber_init(&listCtrlp->ldctl_value)) == NULL) {
108*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_NO_MEMORY;
109*0Sstevel@tonic-gate 		return (LDAP_NO_MEMORY);
110*0Sstevel@tonic-gate 	}
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate 	/* decode the result from the Berelement */
113*0Sstevel@tonic-gate 	if (LBER_ERROR == ber_scanf(ber, "{iie}", target_posp, list_sizep,
114*0Sstevel@tonic-gate 		errcodep)) {
115*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_DECODING_ERROR;
116*0Sstevel@tonic-gate 		ber_free(ber, 1);
117*0Sstevel@tonic-gate 		return (LDAP_DECODING_ERROR);
118*0Sstevel@tonic-gate 	}
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate 	/* the ber encoding is no longer needed */
121*0Sstevel@tonic-gate 	ber_free(ber, 1);
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate 	return (LDAP_SUCCESS);
124*0Sstevel@tonic-gate }
125