GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ldapctl/../ldapd/util.c Lines: 0 89 0.0 %
Date: 2017-11-07 Branches: 0 40 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: util.c,v 1.8 2017/01/20 11:55:08 benno Exp $ */
2
3
/*
4
 * Copyright (c) 2009 Martin Hedenfalk <martin@bzero.se>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/queue.h>
20
#include <sys/types.h>
21
#include <sys/socket.h>
22
#include <sys/resource.h>
23
#include <netinet/in.h>
24
#include <arpa/inet.h>
25
26
#include <assert.h>
27
#include <ctype.h>
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <string.h>
31
#include <zlib.h>
32
#include <errno.h>
33
34
#include "ldapd.h"
35
#include "log.h"
36
37
int
38
bsnprintf(char *str, size_t size, const char *format, ...)
39
{
40
	int ret;
41
	va_list ap;
42
43
	va_start(ap, format);
44
	ret = vsnprintf(str, size, format, ap);
45
	va_end(ap);
46
	if (ret == -1 || ret >= (int)size)
47
		return 0;
48
49
	return 1;
50
}
51
52
/* Normalize a DN in preparation for searches.
53
 * Modifies its argument.
54
 * Currently only made lowercase, and spaces around comma is removed.
55
 * TODO: unescape backslash escapes, handle UTF-8.
56
 */
57
void
58
normalize_dn(char *dn)
59
{
60
	size_t		 n;
61
	char		*s, *p;
62
63
	for (s = p = dn; *s != '\0'; s++) {
64
		if (*s == ' ') {
65
			if (p == dn || p[-1] == ',')
66
				continue;
67
			n = strspn(s, " ");
68
			if (s[n] == '\0' || s[n] == ',')
69
				continue;
70
		}
71
		*p++ = tolower((unsigned char)*s);
72
	}
73
	*p = '\0';
74
}
75
76
/* Returns true (1) if key ends with suffix.
77
 */
78
int
79
has_suffix(struct btval *key, const char *suffix)
80
{
81
	size_t		slen;
82
83
	slen = strlen(suffix);
84
85
	if (key->size < slen)
86
		return 0;
87
	return (bcmp((char *)key->data + key->size - slen, suffix, slen) == 0);
88
}
89
90
/* Returns true (1) if key begins with prefix.
91
 */
92
int
93
has_prefix(struct btval *key, const char *prefix)
94
{
95
	size_t		 pfxlen;
96
97
	pfxlen = strlen(prefix);
98
	if (pfxlen > key->size)
99
		return 0;
100
	return (memcmp(key->data, prefix, pfxlen) == 0);
101
}
102
103
int
104
ber2db(struct ber_element *root, struct btval *val, int compression_level)
105
{
106
	int			 rc;
107
	ssize_t			 len;
108
	uLongf			 destlen;
109
	Bytef			*dest;
110
	void			*buf;
111
	struct ber		 ber;
112
113
	memset(val, 0, sizeof(*val));
114
115
	memset(&ber, 0, sizeof(ber));
116
	ber.fd = -1;
117
	ber_write_elements(&ber, root);
118
119
	if ((len = ber_get_writebuf(&ber, &buf)) == -1)
120
		return -1;
121
122
	if (compression_level > 0) {
123
		val->size = compressBound(len);
124
		val->data = malloc(val->size + sizeof(uint32_t));
125
		if (val->data == NULL) {
126
			log_warn("malloc(%u)", val->size + sizeof(uint32_t));
127
			ber_free(&ber);
128
			return -1;
129
		}
130
		dest = (char *)val->data + sizeof(uint32_t);
131
		destlen = val->size - sizeof(uint32_t);
132
		if ((rc = compress2(dest, &destlen, buf, len,
133
		    compression_level)) != Z_OK) {
134
			log_warn("compress returned %d", rc);
135
			free(val->data);
136
			ber_free(&ber);
137
			return -1;
138
		}
139
		log_debug("compressed entry from %u -> %u byte",
140
		    len, destlen + sizeof(uint32_t));
141
142
		*(uint32_t *)val->data = len;
143
		val->size = destlen + sizeof(uint32_t);
144
		val->free_data = 1;
145
	} else {
146
		val->data = buf;
147
		val->size = len;
148
		val->free_data = 1;	/* XXX: take over internal br_wbuf */
149
		ber.br_wbuf = NULL;
150
	}
151
152
	ber_free(&ber);
153
154
	return 0;
155
}
156
157
struct ber_element *
158
db2ber(struct btval *val, int compression_level)
159
{
160
	int			 rc;
161
	uLongf			 len;
162
	void			*buf;
163
	Bytef			*src;
164
	uLong			 srclen;
165
	struct ber_element	*elm;
166
	struct ber		 ber;
167
168
	assert(val != NULL);
169
170
	memset(&ber, 0, sizeof(ber));
171
	ber.fd = -1;
172
173
	if (compression_level > 0) {
174
		if (val->size < sizeof(uint32_t))
175
			return NULL;
176
177
		len = *(uint32_t *)val->data;
178
		if ((buf = malloc(len)) == NULL) {
179
			log_warn("malloc(%u)", len);
180
			return NULL;
181
		}
182
183
		src = (char *)val->data + sizeof(uint32_t);
184
		srclen = val->size - sizeof(uint32_t);
185
		rc = uncompress(buf, &len, src, srclen);
186
		if (rc != Z_OK) {
187
			log_warnx("dbt_to_ber: uncompress returned %d", rc);
188
			free(buf);
189
			return NULL;
190
		}
191
192
		log_debug("uncompressed entry from %u -> %u byte",
193
		    val->size, len);
194
195
		ber_set_readbuf(&ber, buf, len);
196
		elm = ber_read_elements(&ber, NULL);
197
		free(buf);
198
		return elm;
199
	} else {
200
		ber_set_readbuf(&ber, val->data, val->size);
201
		return ber_read_elements(&ber, NULL);
202
	}
203
}
204
205
int
206
accept_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
207
    int reserve)
208
{
209
	if (getdtablecount() + reserve >= getdtablesize()) {
210
		errno = EMFILE;
211
		return -1;
212
	}
213
214
	return accept4(sockfd, addr, addrlen, SOCK_NONBLOCK);
215
}