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