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