xref: /openbsd-src/usr.sbin/ypldap/entries.c (revision 73492e0c7abc13d0fcf5a83c7f5cd157534d380a)
1*73492e0cSclaudio /*	$OpenBSD: entries.c,v 1.6 2023/07/18 13:06:33 claudio Exp $ */
2f6242408Spyr /*
3f6242408Spyr  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
4f6242408Spyr  *
5f6242408Spyr  * Permission to use, copy, modify, and distribute this software for any
6f6242408Spyr  * purpose with or without fee is hereby granted, provided that the above
7f6242408Spyr  * copyright notice and this permission notice appear in all copies.
8f6242408Spyr  *
9f6242408Spyr  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10f6242408Spyr  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11f6242408Spyr  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12f6242408Spyr  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13f6242408Spyr  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14f6242408Spyr  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15f6242408Spyr  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16f6242408Spyr  */
17f6242408Spyr 
18f6242408Spyr #include <sys/types.h>
19f6242408Spyr #include <sys/queue.h>
20f6242408Spyr #include <sys/socket.h>
21f6242408Spyr #include <sys/tree.h>
22f6242408Spyr 
23f6242408Spyr #include <netinet/in.h>
24f6242408Spyr #include <arpa/inet.h>
25f6242408Spyr 
26f6242408Spyr #include <errno.h>
27f6242408Spyr #include <event.h>
28f6242408Spyr #include <fcntl.h>
29f6242408Spyr #include <unistd.h>
30f6242408Spyr #include <pwd.h>
31f6242408Spyr #include <stdio.h>
32f6242408Spyr #include <stdlib.h>
33f6242408Spyr #include <string.h>
34b9fc9a72Sderaadt #include <limits.h>
35f6242408Spyr 
36f6242408Spyr #include "ypldap.h"
37*73492e0cSclaudio #include "log.h"
38f6242408Spyr 
39f6242408Spyr void
flatten_entries(struct env * env)40f6242408Spyr flatten_entries(struct env *env)
41f6242408Spyr {
42f6242408Spyr 	size_t		 len;
43f6242408Spyr 	char		*linep;
44f6242408Spyr 	char		*endp;
4533318bf8Saschrijver 	char		*tmp;
46f6242408Spyr 	struct userent	*ue;
47f6242408Spyr 	struct groupent	*ge;
48f6242408Spyr 
49f6242408Spyr 	log_debug("flattening trees");
50f6242408Spyr 	/*
51f6242408Spyr 	 * This takes all the line pointers in RB elements and
52f6242408Spyr 	 * concatenates them in a single string, to be able to
53f6242408Spyr 	 * implement next element lookup without tree traversal.
54f6242408Spyr 	 *
55f6242408Spyr 	 * An extra octet is alloced to make space for an additional NUL.
56f6242408Spyr 	 */
57f6242408Spyr 	if ((linep = calloc(1, env->sc_user_line_len + 1)) == NULL) {
58f6242408Spyr 		/*
59f6242408Spyr 		 * XXX: try allocating a smaller chunk of memory
60f6242408Spyr 		 */
61f6242408Spyr 		fatal("out of memory");
62f6242408Spyr 	}
63f6242408Spyr 	endp = linep;
64f6242408Spyr 
65f6242408Spyr 	RB_FOREACH(ue, user_name_tree, env->sc_user_names) {
66f6242408Spyr 		/*
67f6242408Spyr 		 * we convert the first nul back to a column,
68f6242408Spyr 		 * copy the string and then convert it back to a nul.
69f6242408Spyr 		 */
70f6242408Spyr 		ue->ue_line[strlen(ue->ue_line)] = ':';
71f6242408Spyr 		log_debug("pushing line: %s", ue->ue_line);
72f6242408Spyr 		len = strlen(ue->ue_line) + 1;
73f6242408Spyr 		memcpy(endp, ue->ue_line, len);
74f6242408Spyr 		endp[strcspn(endp, ":")] = '\0';
75f6242408Spyr 		free(ue->ue_line);
76f6242408Spyr 		ue->ue_line = endp;
77f6242408Spyr 		endp += len;
7833318bf8Saschrijver 
7933318bf8Saschrijver 		/*
8033318bf8Saschrijver 		 * To save memory strdup(3) the netid_line which originally used
8133318bf8Saschrijver 		 * LINE_WIDTH bytes
8233318bf8Saschrijver 		 */
8333318bf8Saschrijver 		tmp = ue->ue_netid_line;
8433318bf8Saschrijver 		ue->ue_netid_line = strdup(tmp);
8533318bf8Saschrijver 		if (ue->ue_netid_line == NULL) {
8633318bf8Saschrijver 			fatal("out of memory");
8733318bf8Saschrijver 		}
8833318bf8Saschrijver 		free(tmp);
89f6242408Spyr 	}
90f6242408Spyr 	env->sc_user_lines = linep;
91820c8f07Sjca 	log_debug("done pushing users");
92f6242408Spyr 
93f6242408Spyr 	if ((linep = calloc(1, env->sc_group_line_len + 1)) == NULL) {
94f6242408Spyr 		/*
95f6242408Spyr 		 * XXX: try allocating a smaller chunk of memory
96f6242408Spyr 		 */
97f6242408Spyr 		fatal("out of memory");
98f6242408Spyr 	}
99f6242408Spyr 	endp = linep;
100f6242408Spyr 	RB_FOREACH(ge, group_name_tree, env->sc_group_names) {
101f6242408Spyr 		/*
102f6242408Spyr 		 * we convert the first nul back to a column,
103f6242408Spyr 		 * copy the string and then convert it back to a nul.
104f6242408Spyr 		 */
105f6242408Spyr 		ge->ge_line[strlen(ge->ge_line)] = ':';
106f6242408Spyr 		log_debug("pushing line: %s", ge->ge_line);
107f6242408Spyr 		len = strlen(ge->ge_line) + 1;
108f6242408Spyr 		memcpy(endp, ge->ge_line, len);
109f6242408Spyr 		endp[strcspn(endp, ":")] = '\0';
110f6242408Spyr 		free(ge->ge_line);
111f6242408Spyr 		ge->ge_line = endp;
112f6242408Spyr 		endp += len;
113f6242408Spyr 	}
114f6242408Spyr 	env->sc_group_lines = linep;
115820c8f07Sjca 	log_debug("done pushing groups");
116f6242408Spyr }
117f6242408Spyr 
118f6242408Spyr int
userent_name_cmp(struct userent * ue1,struct userent * ue2)119f6242408Spyr userent_name_cmp(struct userent *ue1, struct userent *ue2)
120f6242408Spyr {
121f6242408Spyr 	return (strcmp(ue1->ue_line, ue2->ue_line));
122f6242408Spyr }
123f6242408Spyr 
124f6242408Spyr int
userent_uid_cmp(struct userent * ue1,struct userent * ue2)125f6242408Spyr userent_uid_cmp(struct userent *ue1, struct userent *ue2)
126f6242408Spyr {
127f6242408Spyr 	return (ue1->ue_uid - ue2->ue_uid);
128f6242408Spyr }
129f6242408Spyr 
130f6242408Spyr int
groupent_name_cmp(struct groupent * ge1,struct groupent * ge2)131f6242408Spyr groupent_name_cmp(struct groupent *ge1, struct groupent *ge2)
132f6242408Spyr {
133f6242408Spyr 	return (strcmp(ge1->ge_line, ge2->ge_line));
134f6242408Spyr }
135f6242408Spyr 
136f6242408Spyr int
groupent_gid_cmp(struct groupent * ge1,struct groupent * ge2)137f6242408Spyr groupent_gid_cmp(struct groupent *ge1, struct groupent *ge2)
138f6242408Spyr {
139f6242408Spyr 	return (ge1->ge_gid - ge2->ge_gid);
140f6242408Spyr }
141f6242408Spyr 
142f6242408Spyr RB_GENERATE(user_name_tree, userent, ue_name_node, userent_name_cmp);
143f6242408Spyr RB_GENERATE(user_uid_tree, userent, ue_uid_node, userent_uid_cmp);
144f6242408Spyr RB_GENERATE(group_name_tree, groupent, ge_name_node, groupent_name_cmp);
145f6242408Spyr RB_GENERATE(group_gid_tree, groupent, ge_gid_node, groupent_gid_cmp);
146