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