entries.c revision 290931
12052Sredestad/*	$OpenBSD: entries.c,v 1.3 2015/01/16 06:40:22 deraadt Exp $ */
22182Serikj/*	$FreeBSD: head/usr.sbin/ypldap/entries.c 290931 2015-11-16 16:48:43Z rodrigc $ */
31961Salanb/*
41961Salanb * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
51961Salanb *
61961Salanb * Permission to use, copy, modify, and distribute this software for any
71961Salanb * purpose with or without fee is hereby granted, provided that the above
81961Salanb * copyright notice and this permission notice appear in all copies.
91961Salanb *
101961Salanb * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
111961Salanb * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
121961Salanb * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
131961Salanb * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
141961Salanb * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
151961Salanb * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
161961Salanb * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
171961Salanb */
181961Salanb
191961Salanb#include <sys/types.h>
201961Salanb#include <sys/queue.h>
211961Salanb#include <sys/socket.h>
221961Salanb#include <sys/tree.h>
231961Salanb
241961Salanb#include <netinet/in.h>
251961Salanb#include <arpa/inet.h>
261961Salanb
271961Salanb#include <errno.h>
281961Salanb#include <event.h>
291961Salanb#include <fcntl.h>
301961Salanb#include <unistd.h>
311961Salanb#include <pwd.h>
321961Salanb#include <stdio.h>
331961Salanb#include <stdlib.h>
341961Salanb#include <string.h>
351961Salanb#include <limits.h>
361961Salanb
371961Salanb#include "ypldap.h"
382052Sredestad
392317Serikjvoid
402052Sredestadflatten_entries(struct env *env)
411961Salanb{
422264Serikj	size_t		 wrlen;
431961Salanb	size_t		 len;
442264Serikj	char		*linep;
451961Salanb	char		*endp;
461961Salanb	char		*tmp;
471961Salanb	struct userent	*ue;
482288Smchung	struct groupent	*ge;
492288Smchung
502288Smchung	log_debug("flattening trees");
512288Smchung	/*
521961Salanb	 * This takes all the line pointers in RB elements and
531961Salanb	 * concatenates them in a single string, to be able to
541961Salanb	 * implement next element lookup without tree traversal.
551961Salanb	 *
561961Salanb	 * An extra octet is alloced to make space for an additional NUL.
571961Salanb	 */
581961Salanb	wrlen = env->sc_user_line_len;
591961Salanb	if ((linep = calloc(1, env->sc_user_line_len + 1)) == NULL) {
601961Salanb		/*
611961Salanb		 * XXX: try allocating a smaller chunk of memory
621961Salanb		 */
631961Salanb		fatal("out of memory");
641961Salanb	}
651961Salanb	endp = linep;
661961Salanb
671961Salanb	RB_FOREACH(ue, user_name_tree, env->sc_user_names) {
681961Salanb		/*
691961Salanb		 * we convert the first nul back to a column,
701961Salanb		 * copy the string and then convert it back to a nul.
711961Salanb		 */
721961Salanb		ue->ue_line[strlen(ue->ue_line)] = ':';
732288Smchung		log_debug("pushing line: %s", ue->ue_line);
742288Smchung		len = strlen(ue->ue_line) + 1;
752288Smchung		memcpy(endp, ue->ue_line, len);
762288Smchung		endp[strcspn(endp, ":")] = '\0';
772288Smchung		free(ue->ue_line);
782288Smchung		ue->ue_line = endp;
792288Smchung		endp += len;
802288Smchung		wrlen -= len;
811961Salanb
822373Smchung		/*
832373Smchung		 * To save memory strdup(3) the netid_line which originally used
842373Smchung		 * LINE_WIDTH bytes
852373Smchung		 */
862373Smchung		tmp = ue->ue_netid_line;
872373Smchung		ue->ue_netid_line = strdup(tmp);
882373Smchung		if (ue->ue_netid_line == NULL) {
892373Smchung			fatal("out of memory");
902373Smchung		}
912373Smchung		free(tmp);
922385Salanb	}
932385Salanb	env->sc_user_lines = linep;
942385Salanb
952385Salanb	wrlen = env->sc_group_line_len;
962385Salanb	if ((linep = calloc(1, env->sc_group_line_len + 1)) == NULL) {
972046Salanb		/*
982046Salanb		 * XXX: try allocating a smaller chunk of memory
992046Salanb		 */
1002052Sredestad		fatal("out of memory");
1012052Sredestad	}
1022317Serikj	endp = linep;
1032317Serikj	RB_FOREACH(ge, group_name_tree, env->sc_group_names) {
1042317Serikj		/*
1052317Serikj		 * we convert the first nul back to a column,
1062317Serikj		 * copy the string and then convert it back to a nul.
1072046Salanb		 */
1082611Smchung		ge->ge_line[strlen(ge->ge_line)] = ':';
1092046Salanb		log_debug("pushing line: %s", ge->ge_line);
1102317Serikj		len = strlen(ge->ge_line) + 1;
1112611Smchung		memcpy(endp, ge->ge_line, len);
1122317Serikj		endp[strcspn(endp, ":")] = '\0';
1132052Sredestad		free(ge->ge_line);
1142046Salanb		ge->ge_line = endp;
1151961Salanb		endp += len;
1162182Serikj		wrlen -= len;
1172182Serikj	}
1182182Serikj	env->sc_group_lines = linep;
1192182Serikj}
1202112Serikj
1212112Serikjint
1222112Serikjuserent_name_cmp(struct userent *ue1, struct userent *ue2)
1232112Serikj{
1242317Serikj	return (strcmp(ue1->ue_line, ue2->ue_line));
1252317Serikj}
1262317Serikj
1272317Serikjint
1282317Serikjuserent_uid_cmp(struct userent *ue1, struct userent *ue2)
1292317Serikj{
1301961Salanb	return (ue1->ue_uid - ue2->ue_uid);
1311961Salanb}
1322052Sredestad
1332052Sredestadint
1342317Serikjgroupent_name_cmp(struct groupent *ge1, struct groupent *ge2)
1352317Serikj{
1361961Salanb	return (strcmp(ge1->ge_line, ge2->ge_line));
1371961Salanb}
1382568Salanb
1392212Smchungint
1402515Serikjgroupent_gid_cmp(struct groupent *ge1, struct groupent *ge2)
1412317Serikj{
1422317Serikj	return (ge1->ge_gid - ge2->ge_gid);
1431961Salanb}
1442317Serikj
1451961SalanbRB_GENERATE(user_name_tree, userent, ue_name_node, userent_name_cmp);
1461961SalanbRB_GENERATE(user_uid_tree, userent, ue_uid_node, userent_uid_cmp);
1471961SalanbRB_GENERATE(group_name_tree, groupent, ge_name_node, groupent_name_cmp);
1481961SalanbRB_GENERATE(group_gid_tree, groupent, ge_gid_node, groupent_gid_cmp);
1491961Salanb