entries.c revision 290931
1290931Srodrigc/* $OpenBSD: entries.c,v 1.3 2015/01/16 06:40:22 deraadt Exp $ */ 2290931Srodrigc/* $FreeBSD: head/usr.sbin/ypldap/entries.c 290931 2015-11-16 16:48:43Z rodrigc $ */ 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> 20290931Srodrigc#include <sys/queue.h> 21290931Srodrigc#include <sys/socket.h> 22290931Srodrigc#include <sys/tree.h> 23290931Srodrigc 24290931Srodrigc#include <netinet/in.h> 25290931Srodrigc#include <arpa/inet.h> 26290931Srodrigc 27290931Srodrigc#include <errno.h> 28290931Srodrigc#include <event.h> 29290931Srodrigc#include <fcntl.h> 30290931Srodrigc#include <unistd.h> 31290931Srodrigc#include <pwd.h> 32290931Srodrigc#include <stdio.h> 33290931Srodrigc#include <stdlib.h> 34290931Srodrigc#include <string.h> 35290931Srodrigc#include <limits.h> 36290931Srodrigc 37290931Srodrigc#include "ypldap.h" 38290931Srodrigc 39290931Srodrigcvoid 40290931Srodrigcflatten_entries(struct env *env) 41290931Srodrigc{ 42290931Srodrigc size_t wrlen; 43290931Srodrigc size_t len; 44290931Srodrigc char *linep; 45290931Srodrigc char *endp; 46290931Srodrigc char *tmp; 47290931Srodrigc struct userent *ue; 48290931Srodrigc struct groupent *ge; 49290931Srodrigc 50290931Srodrigc log_debug("flattening trees"); 51290931Srodrigc /* 52290931Srodrigc * This takes all the line pointers in RB elements and 53290931Srodrigc * concatenates them in a single string, to be able to 54290931Srodrigc * implement next element lookup without tree traversal. 55290931Srodrigc * 56290931Srodrigc * An extra octet is alloced to make space for an additional NUL. 57290931Srodrigc */ 58290931Srodrigc wrlen = env->sc_user_line_len; 59290931Srodrigc if ((linep = calloc(1, env->sc_user_line_len + 1)) == NULL) { 60290931Srodrigc /* 61290931Srodrigc * XXX: try allocating a smaller chunk of memory 62290931Srodrigc */ 63290931Srodrigc fatal("out of memory"); 64290931Srodrigc } 65290931Srodrigc endp = linep; 66290931Srodrigc 67290931Srodrigc RB_FOREACH(ue, user_name_tree, env->sc_user_names) { 68290931Srodrigc /* 69290931Srodrigc * we convert the first nul back to a column, 70290931Srodrigc * copy the string and then convert it back to a nul. 71290931Srodrigc */ 72290931Srodrigc ue->ue_line[strlen(ue->ue_line)] = ':'; 73290931Srodrigc log_debug("pushing line: %s", ue->ue_line); 74290931Srodrigc len = strlen(ue->ue_line) + 1; 75290931Srodrigc memcpy(endp, ue->ue_line, len); 76290931Srodrigc endp[strcspn(endp, ":")] = '\0'; 77290931Srodrigc free(ue->ue_line); 78290931Srodrigc ue->ue_line = endp; 79290931Srodrigc endp += len; 80290931Srodrigc wrlen -= len; 81290931Srodrigc 82290931Srodrigc /* 83290931Srodrigc * To save memory strdup(3) the netid_line which originally used 84290931Srodrigc * LINE_WIDTH bytes 85290931Srodrigc */ 86290931Srodrigc tmp = ue->ue_netid_line; 87290931Srodrigc ue->ue_netid_line = strdup(tmp); 88290931Srodrigc if (ue->ue_netid_line == NULL) { 89290931Srodrigc fatal("out of memory"); 90290931Srodrigc } 91290931Srodrigc free(tmp); 92290931Srodrigc } 93290931Srodrigc env->sc_user_lines = linep; 94290931Srodrigc 95290931Srodrigc wrlen = env->sc_group_line_len; 96290931Srodrigc if ((linep = calloc(1, env->sc_group_line_len + 1)) == NULL) { 97290931Srodrigc /* 98290931Srodrigc * XXX: try allocating a smaller chunk of memory 99290931Srodrigc */ 100290931Srodrigc fatal("out of memory"); 101290931Srodrigc } 102290931Srodrigc endp = linep; 103290931Srodrigc RB_FOREACH(ge, group_name_tree, env->sc_group_names) { 104290931Srodrigc /* 105290931Srodrigc * we convert the first nul back to a column, 106290931Srodrigc * copy the string and then convert it back to a nul. 107290931Srodrigc */ 108290931Srodrigc ge->ge_line[strlen(ge->ge_line)] = ':'; 109290931Srodrigc log_debug("pushing line: %s", ge->ge_line); 110290931Srodrigc len = strlen(ge->ge_line) + 1; 111290931Srodrigc memcpy(endp, ge->ge_line, len); 112290931Srodrigc endp[strcspn(endp, ":")] = '\0'; 113290931Srodrigc free(ge->ge_line); 114290931Srodrigc ge->ge_line = endp; 115290931Srodrigc endp += len; 116290931Srodrigc wrlen -= len; 117290931Srodrigc } 118290931Srodrigc env->sc_group_lines = linep; 119290931Srodrigc} 120290931Srodrigc 121290931Srodrigcint 122290931Srodrigcuserent_name_cmp(struct userent *ue1, struct userent *ue2) 123290931Srodrigc{ 124290931Srodrigc return (strcmp(ue1->ue_line, ue2->ue_line)); 125290931Srodrigc} 126290931Srodrigc 127290931Srodrigcint 128290931Srodrigcuserent_uid_cmp(struct userent *ue1, struct userent *ue2) 129290931Srodrigc{ 130290931Srodrigc return (ue1->ue_uid - ue2->ue_uid); 131290931Srodrigc} 132290931Srodrigc 133290931Srodrigcint 134290931Srodrigcgroupent_name_cmp(struct groupent *ge1, struct groupent *ge2) 135290931Srodrigc{ 136290931Srodrigc return (strcmp(ge1->ge_line, ge2->ge_line)); 137290931Srodrigc} 138290931Srodrigc 139290931Srodrigcint 140290931Srodrigcgroupent_gid_cmp(struct groupent *ge1, struct groupent *ge2) 141290931Srodrigc{ 142290931Srodrigc return (ge1->ge_gid - ge2->ge_gid); 143290931Srodrigc} 144290931Srodrigc 145290931SrodrigcRB_GENERATE(user_name_tree, userent, ue_name_node, userent_name_cmp); 146290931SrodrigcRB_GENERATE(user_uid_tree, userent, ue_uid_node, userent_uid_cmp); 147290931SrodrigcRB_GENERATE(group_name_tree, groupent, ge_name_node, groupent_name_cmp); 148290931SrodrigcRB_GENERATE(group_gid_tree, groupent, ge_gid_node, groupent_gid_cmp); 149