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