1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2021 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in the file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15 
16 #include "portable.h"
17 
18 #include <ac/stdlib.h>
19 #include <ac/string.h>
20 #include <ac/stdarg.h>
21 #include "lber-int.h"
22 
23 char ber_pvt_opt_on;	/* used to get a non-NULL address for *_OPT_ON */
24 
25 struct lber_options ber_int_options = {
26 	LBER_UNINITIALIZED, 0, 0 };
27 
28 static BerMemoryFunctions	ber_int_memory_fns_datum;
29 
30 int
ber_get_option(void * item,int option,void * outvalue)31 ber_get_option(
32 	void	*item,
33 	int		option,
34 	void	*outvalue)
35 {
36 	const BerElement *ber;
37 	const Sockbuf *sb;
38 
39 	if(outvalue == NULL) {
40 		/* no place to get to */
41 		ber_errno = LBER_ERROR_PARAM;
42 		return LBER_OPT_ERROR;
43 	}
44 
45 	if(item == NULL) {
46 		switch ( option ) {
47 		case LBER_OPT_BER_DEBUG:
48 			* (int *) outvalue = ber_int_debug;
49 			return LBER_OPT_SUCCESS;
50 
51 		case LBER_OPT_MEMORY_INUSE:
52 			/* The memory inuse is a global variable on kernel implementations.
53 			 * This means that memory debug is shared by all LDAP processes
54 			 * so for this variable to have much meaning, only one LDAP process
55 			 * should be running and memory inuse should be initialized to zero
56 			 * using the lber_set_option() function during startup.
57 			 * The counter is not accurate for multithreaded ldap applications.
58 			 */
59 #ifdef LDAP_MEMORY_DEBUG
60 			* (int *) outvalue = ber_int_meminuse;
61 			return LBER_OPT_SUCCESS;
62 #else
63 			return LBER_OPT_ERROR;
64 #endif
65 
66 		case LBER_OPT_LOG_PRINT_FILE:
67 			*((FILE**)outvalue) = (FILE*)ber_pvt_err_file;
68 			return LBER_OPT_SUCCESS;
69 
70 		case LBER_OPT_LOG_PRINT_FN:
71 			*(BER_LOG_PRINT_FN *)outvalue = ber_pvt_log_print;
72 			return LBER_OPT_SUCCESS;
73 		}
74 
75 		ber_errno = LBER_ERROR_PARAM;
76 		return LBER_OPT_ERROR;
77 	}
78 
79 	ber = item;
80 	sb = item;
81 
82 	switch(option) {
83 	case LBER_OPT_BER_OPTIONS:
84 		assert( LBER_VALID( ber ) );
85 		* (int *) outvalue = ber->ber_options;
86 		return LBER_OPT_SUCCESS;
87 
88 	case LBER_OPT_BER_DEBUG:
89 		assert( LBER_VALID( ber ) );
90 		* (int *) outvalue = ber->ber_debug;
91 		return LBER_OPT_SUCCESS;
92 
93 	case LBER_OPT_BER_REMAINING_BYTES:
94 		assert( LBER_VALID( ber ) );
95 		*((ber_len_t *) outvalue) = ber_pvt_ber_remaining(ber);
96 		return LBER_OPT_SUCCESS;
97 
98 	case LBER_OPT_BER_TOTAL_BYTES:
99 		assert( LBER_VALID( ber ) );
100 		*((ber_len_t *) outvalue) = ber_pvt_ber_total(ber);
101 		return LBER_OPT_SUCCESS;
102 
103 	case LBER_OPT_BER_BYTES_TO_WRITE:
104 		assert( LBER_VALID( ber ) );
105 		*((ber_len_t *) outvalue) = ber_pvt_ber_write(ber);
106 		return LBER_OPT_SUCCESS;
107 
108 	case LBER_OPT_BER_MEMCTX:
109 		assert( LBER_VALID( ber ) );
110 		*((void **) outvalue) = ber->ber_memctx;
111 		return LBER_OPT_SUCCESS;
112 
113 	default:
114 		/* bad param */
115 		ber_errno = LBER_ERROR_PARAM;
116 		break;
117 	}
118 
119 	return LBER_OPT_ERROR;
120 }
121 
122 int
ber_set_option(void * item,int option,LDAP_CONST void * invalue)123 ber_set_option(
124 	void	*item,
125 	int		option,
126 	LDAP_CONST void	*invalue)
127 {
128 	BerElement *ber;
129 	Sockbuf *sb;
130 
131 	if(invalue == NULL) {
132 		/* no place to set from */
133 		ber_errno = LBER_ERROR_PARAM;
134 		return LBER_OPT_ERROR;
135 	}
136 
137 	if(item == NULL) {
138 		switch ( option ) {
139 		case LBER_OPT_BER_DEBUG:
140 			ber_int_debug = * (const int *) invalue;
141 			return LBER_OPT_SUCCESS;
142 
143 		case LBER_OPT_LOG_PRINT_FN:
144 			ber_pvt_log_print = (BER_LOG_PRINT_FN) invalue;
145 			return LBER_OPT_SUCCESS;
146 
147 		case LBER_OPT_LOG_PRINT_FILE:
148 			ber_pvt_err_file = (void *) invalue;
149 			return LBER_OPT_SUCCESS;
150 
151 		case LBER_OPT_MEMORY_INUSE:
152 			/* The memory inuse is a global variable on kernel implementations.
153 			 * This means that memory debug is shared by all LDAP processes
154 			 * so for this variable to have much meaning, only one LDAP process
155 			 * should be running and memory inuse should be initialized to zero
156 			 * using the lber_set_option() function during startup.
157 			 * The counter is not accurate for multithreaded applications.
158 			 */
159 #ifdef LDAP_MEMORY_DEBUG
160 			ber_int_meminuse = * (int *) invalue;
161 			return LBER_OPT_SUCCESS;
162 #else
163 			return LBER_OPT_ERROR;
164 #endif
165 		case LBER_OPT_MEMORY_FNS:
166 			if ( ber_int_memory_fns == NULL )
167 			{
168 				const BerMemoryFunctions *f =
169 					(const BerMemoryFunctions *) invalue;
170 				/* make sure all functions are provided */
171 				if(!( f->bmf_malloc && f->bmf_calloc
172 					&& f->bmf_realloc && f->bmf_free ))
173 				{
174 					ber_errno = LBER_ERROR_PARAM;
175 					return LBER_OPT_ERROR;
176 				}
177 
178 				ber_int_memory_fns = &ber_int_memory_fns_datum;
179 
180 				AC_MEMCPY(ber_int_memory_fns, f,
181 					 sizeof(BerMemoryFunctions));
182 
183 				return LBER_OPT_SUCCESS;
184 			}
185 			break;
186 
187 		case LBER_OPT_LOG_PROC:
188 			ber_int_log_proc = (BER_LOG_FN)invalue;
189 			return LBER_OPT_SUCCESS;
190 		}
191 
192 		ber_errno = LBER_ERROR_PARAM;
193 		return LBER_OPT_ERROR;
194 	}
195 
196 	ber = item;
197 	sb = item;
198 
199 	switch(option) {
200 	case LBER_OPT_BER_OPTIONS:
201 		assert( LBER_VALID( ber ) );
202 		ber->ber_options = * (const int *) invalue;
203 		return LBER_OPT_SUCCESS;
204 
205 	case LBER_OPT_BER_DEBUG:
206 		assert( LBER_VALID( ber ) );
207 		ber->ber_debug = * (const int *) invalue;
208 		return LBER_OPT_SUCCESS;
209 
210 	case LBER_OPT_BER_REMAINING_BYTES:
211 		assert( LBER_VALID( ber ) );
212 		ber->ber_end = &ber->ber_ptr[* (const ber_len_t *) invalue];
213 		return LBER_OPT_SUCCESS;
214 
215 	case LBER_OPT_BER_TOTAL_BYTES:
216 		assert( LBER_VALID( ber ) );
217 		ber->ber_end = &ber->ber_buf[* (const ber_len_t *) invalue];
218 		return LBER_OPT_SUCCESS;
219 
220 	case LBER_OPT_BER_BYTES_TO_WRITE:
221 		assert( LBER_VALID( ber ) );
222 		ber->ber_ptr = &ber->ber_buf[* (const ber_len_t *) invalue];
223 		return LBER_OPT_SUCCESS;
224 
225 	case LBER_OPT_BER_MEMCTX:
226 		assert( LBER_VALID( ber ) );
227 		ber->ber_memctx = *(void **)invalue;
228 		return LBER_OPT_SUCCESS;
229 
230 	default:
231 		/* bad param */
232 		ber_errno = LBER_ERROR_PARAM;
233 		break;
234 	}
235 
236 	return LBER_OPT_ERROR;
237 }
238