1 /* $OpenBSD: entries.c,v 1.1 2008/06/26 15:10:01 pyr 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 36 #include "ypldap.h" 37 38 void 39 flatten_entries(struct env *env) 40 { 41 size_t wrlen; 42 size_t len; 43 char *linep; 44 char *endp; 45 struct userent *ue; 46 struct groupent *ge; 47 48 log_debug("flattening trees"); 49 /* 50 * This takes all the line pointers in RB elements and 51 * concatenates them in a single string, to be able to 52 * implement next element lookup without tree traversal. 53 * 54 * An extra octet is alloced to make space for an additional NUL. 55 */ 56 wrlen = env->sc_user_line_len; 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 wrlen -= len; 79 } 80 env->sc_user_lines = linep; 81 82 wrlen = env->sc_group_line_len; 83 if ((linep = calloc(1, env->sc_group_line_len + 1)) == NULL) { 84 /* 85 * XXX: try allocating a smaller chunk of memory 86 */ 87 fatal("out of memory"); 88 } 89 endp = linep; 90 RB_FOREACH(ge, group_name_tree, env->sc_group_names) { 91 /* 92 * we convert the first nul back to a column, 93 * copy the string and then convert it back to a nul. 94 */ 95 ge->ge_line[strlen(ge->ge_line)] = ':'; 96 log_debug("pushing line: %s", ge->ge_line); 97 len = strlen(ge->ge_line) + 1; 98 memcpy(endp, ge->ge_line, len); 99 endp[strcspn(endp, ":")] = '\0'; 100 free(ge->ge_line); 101 ge->ge_line = endp; 102 endp += len; 103 wrlen -= len; 104 } 105 env->sc_group_lines = linep; 106 } 107 108 int 109 userent_name_cmp(struct userent *ue1, struct userent *ue2) 110 { 111 return (strcmp(ue1->ue_line, ue2->ue_line)); 112 } 113 114 int 115 userent_uid_cmp(struct userent *ue1, struct userent *ue2) 116 { 117 return (ue1->ue_uid - ue2->ue_uid); 118 } 119 120 int 121 groupent_name_cmp(struct groupent *ge1, struct groupent *ge2) 122 { 123 return (strcmp(ge1->ge_line, ge2->ge_line)); 124 } 125 126 int 127 groupent_gid_cmp(struct groupent *ge1, struct groupent *ge2) 128 { 129 return (ge1->ge_gid - ge2->ge_gid); 130 } 131 132 RB_GENERATE(user_name_tree, userent, ue_name_node, userent_name_cmp); 133 RB_GENERATE(user_uid_tree, userent, ue_uid_node, userent_uid_cmp); 134 RB_GENERATE(group_name_tree, groupent, ge_name_node, groupent_name_cmp); 135 RB_GENERATE(group_gid_tree, groupent, ge_gid_node, groupent_gid_cmp); 136