1 /* 2 * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1998, 1999, 2001, 2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <port_before.h> 19 #if !defined(_REENTRANT) || !defined(DO_PTHREADS) 20 static int getnetgrent_r_not_required = 0; 21 #else 22 #include <errno.h> 23 #include <string.h> 24 #include <stdio.h> 25 #include <sys/types.h> 26 #include <netinet/in.h> 27 #include <netdb.h> 28 #include <stdlib.h> 29 #include <port_after.h> 30 31 #ifdef NGR_R_RETURN 32 #ifndef NGR_R_PRIVATE 33 #define NGR_R_PRIVATE 0 34 #endif 35 36 static NGR_R_RETURN 37 copy_protoent(NGR_R_CONST char **, NGR_R_CONST char **, NGR_R_CONST char **, 38 const char *, const char *, const char *, NGR_R_COPY_ARGS); 39 40 NGR_R_RETURN 41 innetgr_r(const char *netgroup, const char *host, const char *user, 42 const char *domain) { 43 char *ng, *ho, *us, *dom; 44 45 DE_CONST(netgroup, ng); 46 DE_CONST(host, ho); 47 DE_CONST(user, us); 48 DE_CONST(domain, dom); 49 50 return (innetgr(ng, ho, us, dom)); 51 } 52 53 /*% 54 * These assume a single context is in operation per thread. 55 * If this is not the case we will need to call irs directly 56 * rather than through the base functions. 57 */ 58 59 NGR_R_RETURN 60 getnetgrent_r(NGR_R_CONST char **machinep, NGR_R_CONST char **userp, 61 NGR_R_CONST char **domainp, NGR_R_ARGS) 62 { 63 NGR_R_CONST char *mp, *up, *dp; 64 int res = getnetgrent(&mp, &up, &dp); 65 66 if (res != 1) 67 return (res); 68 69 return (copy_protoent(machinep, userp, domainp, 70 mp, up, dp, NGR_R_COPY)); 71 } 72 73 #if NGR_R_PRIVATE == 2 74 struct private { 75 char *buf; 76 }; 77 78 #endif 79 NGR_R_SET_RETURN 80 #ifdef NGR_R_SET_ARGS 81 setnetgrent_r(NGR_R_SET_CONST char *netgroup, NGR_R_SET_ARGS) 82 #else 83 setnetgrent_r(NGR_R_SET_CONST char *netgroup) 84 #endif 85 { 86 #if NGR_R_PRIVATE == 2 87 struct private *p; 88 #endif 89 char *tmp; 90 #if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0 91 UNUSED(buf); 92 UNUSED(buflen); 93 #endif 94 95 DE_CONST(netgroup, tmp); 96 setnetgrent(tmp); 97 98 #if NGR_R_PRIVATE == 1 99 *buf = NULL; 100 #elif NGR_R_PRIVATE == 2 101 *buf = p = malloc(sizeof(struct private)); 102 if (p == NULL) 103 #ifdef NGR_R_SET_RESULT 104 return (NGR_R_BAD); 105 #else 106 return; 107 #endif 108 p->buf = NULL; 109 #endif 110 #ifdef NGR_R_SET_RESULT 111 return (NGR_R_SET_RESULT); 112 #endif 113 } 114 115 NGR_R_END_RETURN 116 #ifdef NGR_R_END_ARGS 117 endnetgrent_r(NGR_R_END_ARGS) 118 #else 119 endnetgrent_r(void) 120 #endif 121 { 122 #if NGR_R_PRIVATE == 2 123 struct private *p = buf; 124 #endif 125 #if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0 126 UNUSED(buf); 127 UNUSED(buflen); 128 #endif 129 130 endnetgrent(); 131 #if NGR_R_PRIVATE == 1 132 if (*buf != NULL) 133 free(*buf); 134 *buf = NULL; 135 #elif NGR_R_PRIVATE == 2 136 if (p->buf != NULL) 137 free(p->buf); 138 free(p); 139 #endif 140 NGR_R_END_RESULT(NGR_R_OK); 141 } 142 143 /* Private */ 144 145 static int 146 copy_protoent(NGR_R_CONST char **machinep, NGR_R_CONST char **userp, 147 NGR_R_CONST char **domainp, const char *mp, const char *up, 148 const char *dp, NGR_R_COPY_ARGS) 149 { 150 #if NGR_R_PRIVATE == 2 151 struct private *p = buf; 152 #endif 153 char *cp; 154 int n; 155 int len; 156 157 /* Find out the amount of space required to store the answer. */ 158 len = 0; 159 if (mp != NULL) len += strlen(mp) + 1; 160 if (up != NULL) len += strlen(up) + 1; 161 if (dp != NULL) len += strlen(dp) + 1; 162 163 #if NGR_R_PRIVATE == 1 164 if (*buf != NULL) 165 free(*buf); 166 *buf = malloc(len); 167 if (*buf == NULL) 168 return(NGR_R_BAD); 169 cp = *buf; 170 #elif NGR_R_PRIVATE == 2 171 if (p->buf) 172 free(p->buf); 173 p->buf = malloc(len); 174 if (p->buf == NULL) 175 return(NGR_R_BAD); 176 cp = p->buf; 177 #else 178 if (len > (int)buflen) { 179 errno = ERANGE; 180 return (NGR_R_BAD); 181 } 182 cp = buf; 183 #endif 184 185 if (mp != NULL) { 186 n = strlen(mp) + 1; 187 strcpy(cp, mp); 188 *machinep = cp; 189 cp += n; 190 } else 191 *machinep = NULL; 192 193 if (up != NULL) { 194 n = strlen(up) + 1; 195 strcpy(cp, up); 196 *userp = cp; 197 cp += n; 198 } else 199 *userp = NULL; 200 201 if (dp != NULL) { 202 n = strlen(dp) + 1; 203 strcpy(cp, dp); 204 *domainp = cp; 205 cp += n; 206 } else 207 *domainp = NULL; 208 209 return (NGR_R_OK); 210 } 211 #else /* NGR_R_RETURN */ 212 static int getnetgrent_r_unknown_system = 0; 213 #endif /* NGR_R_RETURN */ 214 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ 215 /*! \file */ 216