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