GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ldapd/attributes.c Lines: 0 114 0.0 %
Date: 2017-11-07 Branches: 0 100 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: attributes.c,v 1.5 2017/02/11 20:40:03 guenther 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
22
#include <assert.h>
23
#include <string.h>
24
#include <time.h>
25
26
#include "ldapd.h"
27
#include "log.h"
28
29
struct ber_element *
30
ldap_get_attribute(struct ber_element *entry, const char *attr)
31
{
32
	char			*s;
33
	struct ber_element	*elm, *a;
34
35
	assert(entry);
36
	assert(attr);
37
	if (entry->be_encoding != BER_TYPE_SEQUENCE)
38
		return NULL;
39
40
	for (elm = entry->be_sub; elm != NULL; elm = elm->be_next) {
41
		a = elm->be_sub;
42
		if (a && ber_get_string(a, &s) == 0 && strcasecmp(s, attr) == 0)
43
			return a;
44
	}
45
46
	return NULL;
47
}
48
49
struct ber_element *
50
ldap_find_attribute(struct ber_element *entry, struct attr_type *at)
51
{
52
	struct ber_element	*elm = NULL;
53
	struct name		*an;
54
55
	SLIST_FOREACH(an, at->names, next) {
56
		if ((elm = ldap_get_attribute(entry, an->name)) != NULL)
57
			return elm;
58
	}
59
	if (an == NULL)
60
		elm = ldap_get_attribute(entry, at->oid);
61
62
	return elm;
63
}
64
65
struct ber_element *
66
ldap_find_value(struct ber_element *elm, const char *value)
67
{
68
	char			*s;
69
	struct ber_element	*a;
70
71
	if (elm == NULL)
72
		return NULL;
73
74
	for (a = elm->be_sub; a != NULL; a = a->be_next) {
75
		if (ber_get_string(a, &s) == 0 && strcasecmp(s, value) == 0)
76
			return a;
77
	}
78
79
	return NULL;
80
}
81
82
struct ber_element *
83
ldap_add_attribute(struct ber_element *entry, const char *attr,
84
	struct ber_element *value_set)
85
{
86
	struct ber_element	*elm, *a, *last;
87
88
	assert(entry);
89
	assert(attr);
90
	assert(value_set);
91
92
	if (entry->be_encoding != BER_TYPE_SEQUENCE) {
93
		log_warnx("entries should be a sequence");
94
		return NULL;
95
	}
96
97
	if (value_set->be_type != BER_TYPE_SET) {
98
		log_warnx("values should be a set");
99
		return NULL;
100
	}
101
102
	last = entry->be_sub;
103
	if (last == NULL)
104
		last = entry;
105
	else while (last != NULL && last->be_next != NULL)
106
		last = last->be_next;
107
108
	if ((elm = ber_add_sequence(last)) == NULL)
109
		return NULL;
110
	if ((a = ber_add_string(elm, attr)) == NULL) {
111
		ber_free_elements(elm);
112
		return NULL;
113
	}
114
	ber_link_elements(a, value_set);
115
116
	return elm;
117
}
118
119
int
120
ldap_set_values(struct ber_element *elm, struct ber_element *vals)
121
{
122
	char			*attr;
123
	struct ber_element	*old_vals;
124
125
	assert(elm);
126
	assert(vals);
127
	assert(vals->be_sub);
128
129
	if (ber_scanf_elements(elm, "se(", &attr, &old_vals) != 0) {
130
		log_warnx("failed to parse element");
131
		return -1;
132
	}
133
134
	ber_free_elements(old_vals->be_sub);
135
	old_vals->be_sub = NULL;
136
	ber_link_elements(old_vals, vals->be_sub);
137
138
	vals->be_sub = NULL;
139
	ber_free_elements(vals);
140
141
	return 0;
142
}
143
144
int
145
ldap_merge_values(struct ber_element *elm, struct ber_element *vals)
146
{
147
	char			*attr;
148
	struct ber_element	*old_vals, *last;
149
150
	assert(elm);
151
	assert(vals);
152
	assert(vals->be_type == BER_TYPE_SET);
153
	assert(vals->be_sub);
154
155
	if (ber_scanf_elements(elm, "se(", &attr, &old_vals) != 0) {
156
		log_warnx("failed to parse element");
157
		return -1;
158
	}
159
160
	last = old_vals->be_sub;
161
	while (last && last->be_next)
162
		last = last->be_next;
163
164
	ber_link_elements(last, vals->be_sub);
165
166
	vals->be_sub = NULL;
167
	ber_free_elements(vals);
168
169
	return 0;
170
}
171
172
173
int
174
ldap_del_attribute(struct ber_element *entry, const char *attrdesc)
175
{
176
	struct ber_element	*attr, *prev = NULL;
177
	char			*s;
178
179
	assert(entry);
180
	assert(attrdesc);
181
182
	attr = entry->be_sub;
183
	while (attr) {
184
		if (ber_scanf_elements(attr, "{s(", &s) != 0) {
185
			log_warnx("failed to parse attribute");
186
			return -1;
187
		}
188
189
		if (strcasecmp(s, attrdesc) == 0) {
190
			if (prev == NULL)
191
				entry->be_sub = attr->be_next;
192
			else
193
				prev->be_next = attr->be_next;
194
			attr->be_next = NULL;
195
			ber_free_elements(attr);
196
			break;
197
		}
198
199
		prev = attr;
200
		attr = attr->be_next;
201
	}
202
203
	return 0;
204
}
205
206
int
207
ldap_del_values(struct ber_element *elm, struct ber_element *vals)
208
{
209
	char			*attr;
210
	struct ber_element	*old_vals, *v, *x, *prev, *next;
211
	struct ber_element	*removed;
212
	int			removed_p;
213
	assert(elm);
214
	assert(vals);
215
	assert(vals->be_sub);
216
217
	if (ber_scanf_elements(elm, "se(", &attr, &old_vals) != 0) {
218
		log_warnx("failed to parse element");
219
		return -1;
220
	}
221
222
	prev = old_vals;
223
	removed_p = 0;
224
	for (v = old_vals->be_sub; v; v = next) {
225
		next = v->be_next;
226
227
		for (x = vals->be_sub; x; x = x->be_next) {
228
			if (x && v->be_len == x->be_len &&
229
			    memcmp(v->be_val, x->be_val, x->be_len) == 0) {
230
				removed = ber_unlink_elements(prev);
231
				ber_link_elements(prev, removed->be_next);
232
				ber_free_element(removed);
233
				removed_p = 1;
234
				break;
235
			}
236
		}
237
		if (removed_p) {
238
			removed_p = 0;
239
		} else {
240
			prev = v;
241
		}
242
	}
243
244
	return 0;
245
}
246
247
char *
248
ldap_strftime(time_t tm)
249
{
250
	static char	 tmbuf[16];
251
	struct tm	*gmt = gmtime(&tm);
252
253
	strftime(tmbuf, sizeof(tmbuf), "%Y%m%d%H%M%SZ", gmt);
254
	return tmbuf;
255
}
256
257
char *
258
ldap_now(void)
259
{
260
	return ldap_strftime(time(0));
261
}
262