1290931Srodrigc/* $OpenBSD: entries.c,v 1.3 2015/01/16 06:40:22 deraadt Exp $ */ 2290931Srodrigc/* $FreeBSD: stable/11/usr.sbin/ypldap/entries.c 322882 2017-08-25 08:24:29Z araujo $ */ 3290931Srodrigc/* 4290931Srodrigc * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> 5290931Srodrigc * 6290931Srodrigc * Permission to use, copy, modify, and distribute this software for any 7290931Srodrigc * purpose with or without fee is hereby granted, provided that the above 8290931Srodrigc * copyright notice and this permission notice appear in all copies. 9290931Srodrigc * 10290931Srodrigc * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11290931Srodrigc * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12290931Srodrigc * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13290931Srodrigc * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14290931Srodrigc * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15290931Srodrigc * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16290931Srodrigc * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17290931Srodrigc */ 18290931Srodrigc 19290931Srodrigc#include <sys/types.h> 20290937Srodrigc#include <sys/param.h> 21290931Srodrigc#include <sys/queue.h> 22290931Srodrigc#include <sys/socket.h> 23290931Srodrigc#include <sys/tree.h> 24290931Srodrigc 25290931Srodrigc#include <netinet/in.h> 26290931Srodrigc#include <arpa/inet.h> 27290931Srodrigc 28290931Srodrigc#include <errno.h> 29290931Srodrigc#include <event.h> 30290931Srodrigc#include <fcntl.h> 31290931Srodrigc#include <unistd.h> 32290931Srodrigc#include <pwd.h> 33290931Srodrigc#include <stdio.h> 34290931Srodrigc#include <stdlib.h> 35290931Srodrigc#include <string.h> 36290931Srodrigc#include <limits.h> 37290931Srodrigc 38290931Srodrigc#include "ypldap.h" 39290931Srodrigc 40290931Srodrigcvoid 41290931Srodrigcflatten_entries(struct env *env) 42290931Srodrigc{ 43290931Srodrigc size_t wrlen; 44290931Srodrigc size_t len; 45290931Srodrigc char *linep; 46290931Srodrigc char *endp; 47290931Srodrigc char *tmp; 48290931Srodrigc struct userent *ue; 49290931Srodrigc struct groupent *ge; 50290931Srodrigc 51290931Srodrigc log_debug("flattening trees"); 52290931Srodrigc /* 53290931Srodrigc * This takes all the line pointers in RB elements and 54290931Srodrigc * concatenates them in a single string, to be able to 55290931Srodrigc * implement next element lookup without tree traversal. 56290931Srodrigc * 57290931Srodrigc * An extra octet is alloced to make space for an additional NUL. 58290931Srodrigc */ 59290931Srodrigc wrlen = env->sc_user_line_len; 60290931Srodrigc if ((linep = calloc(1, env->sc_user_line_len + 1)) == NULL) { 61290931Srodrigc /* 62290931Srodrigc * XXX: try allocating a smaller chunk of memory 63290931Srodrigc */ 64290931Srodrigc fatal("out of memory"); 65290931Srodrigc } 66290931Srodrigc endp = linep; 67290931Srodrigc 68290931Srodrigc RB_FOREACH(ue, user_name_tree, env->sc_user_names) { 69290931Srodrigc /* 70290931Srodrigc * we convert the first nul back to a column, 71290931Srodrigc * copy the string and then convert it back to a nul. 72290931Srodrigc */ 73290931Srodrigc ue->ue_line[strlen(ue->ue_line)] = ':'; 74290931Srodrigc log_debug("pushing line: %s", ue->ue_line); 75290931Srodrigc len = strlen(ue->ue_line) + 1; 76290931Srodrigc memcpy(endp, ue->ue_line, len); 77290931Srodrigc endp[strcspn(endp, ":")] = '\0'; 78290931Srodrigc free(ue->ue_line); 79290931Srodrigc ue->ue_line = endp; 80290931Srodrigc endp += len; 81290931Srodrigc wrlen -= len; 82290931Srodrigc 83290931Srodrigc /* 84290931Srodrigc * To save memory strdup(3) the netid_line which originally used 85290931Srodrigc * LINE_WIDTH bytes 86290931Srodrigc */ 87290931Srodrigc tmp = ue->ue_netid_line; 88290931Srodrigc ue->ue_netid_line = strdup(tmp); 89290931Srodrigc if (ue->ue_netid_line == NULL) { 90290931Srodrigc fatal("out of memory"); 91290931Srodrigc } 92290931Srodrigc free(tmp); 93290931Srodrigc } 94290931Srodrigc env->sc_user_lines = linep; 95322882Saraujo log_debug("done pushing users"); 96290931Srodrigc 97290931Srodrigc wrlen = env->sc_group_line_len; 98290931Srodrigc if ((linep = calloc(1, env->sc_group_line_len + 1)) == NULL) { 99290931Srodrigc /* 100290931Srodrigc * XXX: try allocating a smaller chunk of memory 101290931Srodrigc */ 102290931Srodrigc fatal("out of memory"); 103290931Srodrigc } 104290931Srodrigc endp = linep; 105290931Srodrigc RB_FOREACH(ge, group_name_tree, env->sc_group_names) { 106290931Srodrigc /* 107290931Srodrigc * we convert the first nul back to a column, 108290931Srodrigc * copy the string and then convert it back to a nul. 109290931Srodrigc */ 110290931Srodrigc ge->ge_line[strlen(ge->ge_line)] = ':'; 111290931Srodrigc log_debug("pushing line: %s", ge->ge_line); 112290931Srodrigc len = strlen(ge->ge_line) + 1; 113290931Srodrigc memcpy(endp, ge->ge_line, len); 114290931Srodrigc endp[strcspn(endp, ":")] = '\0'; 115290931Srodrigc free(ge->ge_line); 116290931Srodrigc ge->ge_line = endp; 117290931Srodrigc endp += len; 118290931Srodrigc wrlen -= len; 119290931Srodrigc } 120290931Srodrigc env->sc_group_lines = linep; 121322882Saraujo log_debug("done pushing groups"); 122290931Srodrigc} 123290931Srodrigc 124290931Srodrigcint 125290931Srodrigcuserent_name_cmp(struct userent *ue1, struct userent *ue2) 126290931Srodrigc{ 127290931Srodrigc return (strcmp(ue1->ue_line, ue2->ue_line)); 128290931Srodrigc} 129290931Srodrigc 130290931Srodrigcint 131290931Srodrigcuserent_uid_cmp(struct userent *ue1, struct userent *ue2) 132290931Srodrigc{ 133290931Srodrigc return (ue1->ue_uid - ue2->ue_uid); 134290931Srodrigc} 135290931Srodrigc 136290931Srodrigcint 137290931Srodrigcgroupent_name_cmp(struct groupent *ge1, struct groupent *ge2) 138290931Srodrigc{ 139290931Srodrigc return (strcmp(ge1->ge_line, ge2->ge_line)); 140290931Srodrigc} 141290931Srodrigc 142290931Srodrigcint 143290931Srodrigcgroupent_gid_cmp(struct groupent *ge1, struct groupent *ge2) 144290931Srodrigc{ 145290931Srodrigc return (ge1->ge_gid - ge2->ge_gid); 146290931Srodrigc} 147290931Srodrigc 148290931SrodrigcRB_GENERATE(user_name_tree, userent, ue_name_node, userent_name_cmp); 149290931SrodrigcRB_GENERATE(user_uid_tree, userent, ue_uid_node, userent_uid_cmp); 150290931SrodrigcRB_GENERATE(group_name_tree, groupent, ge_name_node, groupent_name_cmp); 151290931SrodrigcRB_GENERATE(group_gid_tree, groupent, ge_gid_node, groupent_gid_cmp); 152