1/* $NetBSD: dns_pw.c,v 1.1.1.2 2012/09/09 16:07:57 christos Exp $ */ 2 3/* 4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (c) 1996,1999 by Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20#if defined(LIBC_SCCS) && !defined(lint) 21static const char rcsid[] = "Id: dns_pw.c,v 1.3 2005/04/27 04:56:22 sra Exp "; 22#endif 23 24#include "port_before.h" 25 26#ifndef WANT_IRS_PW 27static int __bind_irs_pw_unneeded; 28#else 29 30#include <stdio.h> 31#include <stdlib.h> 32#include <errno.h> 33#include <string.h> 34 35#include <sys/types.h> 36#include <netinet/in.h> 37#include <arpa/nameser.h> 38#include <resolv.h> 39 40#include <isc/memcluster.h> 41 42#include <irs.h> 43 44#include "port_after.h" 45 46#include "irs_p.h" 47#include "hesiod.h" 48#include "dns_p.h" 49 50/* Types. */ 51 52struct pvt { 53 struct dns_p * dns; 54 struct passwd passwd; 55 char * pwbuf; 56}; 57 58/* Forward. */ 59 60static void pw_close(struct irs_pw *); 61static struct passwd * pw_byname(struct irs_pw *, const char *); 62static struct passwd * pw_byuid(struct irs_pw *, uid_t); 63static struct passwd * pw_next(struct irs_pw *); 64static void pw_rewind(struct irs_pw *); 65static void pw_minimize(struct irs_pw *); 66static struct __res_state * pw_res_get(struct irs_pw *); 67static void pw_res_set(struct irs_pw *, 68 struct __res_state *, 69 void (*)(void *)); 70 71static struct passwd * getpwcommon(struct irs_pw *, const char *, 72 const char *); 73 74/* Public. */ 75 76struct irs_pw * 77irs_dns_pw(struct irs_acc *this) { 78 struct dns_p *dns = (struct dns_p *)this->private; 79 struct irs_pw *pw; 80 struct pvt *pvt; 81 82 if (!dns || !dns->hes_ctx) { 83 errno = ENODEV; 84 return (NULL); 85 } 86 if (!(pvt = memget(sizeof *pvt))) { 87 errno = ENOMEM; 88 return (NULL); 89 } 90 memset(pvt, 0, sizeof *pvt); 91 pvt->dns = dns; 92 if (!(pw = memget(sizeof *pw))) { 93 memput(pvt, sizeof *pvt); 94 errno = ENOMEM; 95 return (NULL); 96 } 97 memset(pw, 0x5e, sizeof *pw); 98 pw->private = pvt; 99 pw->close = pw_close; 100 pw->byname = pw_byname; 101 pw->byuid = pw_byuid; 102 pw->next = pw_next; 103 pw->rewind = pw_rewind; 104 pw->minimize = pw_minimize; 105 pw->res_get = pw_res_get; 106 pw->res_set = pw_res_set; 107 return (pw); 108} 109 110/* Methods. */ 111 112static void 113pw_close(struct irs_pw *this) { 114 struct pvt *pvt = (struct pvt *)this->private; 115 116 if (pvt->pwbuf) 117 free(pvt->pwbuf); 118 119 memput(pvt, sizeof *pvt); 120 memput(this, sizeof *this); 121} 122 123static struct passwd * 124pw_byname(struct irs_pw *this, const char *nam) { 125 return (getpwcommon(this, nam, "passwd")); 126} 127 128static struct passwd * 129pw_byuid(struct irs_pw *this, uid_t uid) { 130 char uidstr[16]; 131 132 sprintf(uidstr, "%lu", (u_long)uid); 133 return (getpwcommon(this, uidstr, "uid")); 134} 135 136static struct passwd * 137pw_next(struct irs_pw *this) { 138 UNUSED(this); 139 errno = ENODEV; 140 return (NULL); 141} 142 143static void 144pw_rewind(struct irs_pw *this) { 145 UNUSED(this); 146 /* NOOP */ 147} 148 149static void 150pw_minimize(struct irs_pw *this) { 151 UNUSED(this); 152 /* NOOP */ 153} 154 155static struct __res_state * 156pw_res_get(struct irs_pw *this) { 157 struct pvt *pvt = (struct pvt *)this->private; 158 struct dns_p *dns = pvt->dns; 159 160 return (__hesiod_res_get(dns->hes_ctx)); 161} 162 163static void 164pw_res_set(struct irs_pw *this, struct __res_state * res, 165 void (*free_res)(void *)) { 166 struct pvt *pvt = (struct pvt *)this->private; 167 struct dns_p *dns = pvt->dns; 168 169 __hesiod_res_set(dns->hes_ctx, res, free_res); 170} 171 172/* Private. */ 173 174static struct passwd * 175getpwcommon(struct irs_pw *this, const char *arg, const char *type) { 176 struct pvt *pvt = (struct pvt *)this->private; 177 char **hes_list, *cp; 178 179 if (!(hes_list = hesiod_resolve(pvt->dns->hes_ctx, arg, type))) 180 return (NULL); 181 if (!*hes_list) { 182 hesiod_free_list(pvt->dns->hes_ctx, hes_list); 183 errno = ENOENT; 184 return (NULL); 185 } 186 187 memset(&pvt->passwd, 0, sizeof pvt->passwd); 188 if (pvt->pwbuf) 189 free(pvt->pwbuf); 190 pvt->pwbuf = strdup(*hes_list); 191 hesiod_free_list(pvt->dns->hes_ctx, hes_list); 192 193 cp = pvt->pwbuf; 194 pvt->passwd.pw_name = cp; 195 if (!(cp = strchr(cp, ':'))) 196 goto cleanup; 197 *cp++ = '\0'; 198 199 pvt->passwd.pw_passwd = cp; 200 if (!(cp = strchr(cp, ':'))) 201 goto cleanup; 202 *cp++ = '\0'; 203 204 pvt->passwd.pw_uid = atoi(cp); 205 if (!(cp = strchr(cp, ':'))) 206 goto cleanup; 207 *cp++ = '\0'; 208 209 pvt->passwd.pw_gid = atoi(cp); 210 if (!(cp = strchr(cp, ':'))) 211 goto cleanup; 212 *cp++ = '\0'; 213 214 pvt->passwd.pw_gecos = cp; 215 if (!(cp = strchr(cp, ':'))) 216 goto cleanup; 217 *cp++ = '\0'; 218 219 pvt->passwd.pw_dir = cp; 220 if (!(cp = strchr(cp, ':'))) 221 goto cleanup; 222 *cp++ = '\0'; 223 224 pvt->passwd.pw_shell = cp; 225 return (&pvt->passwd); 226 227 cleanup: 228 free(pvt->pwbuf); 229 pvt->pwbuf = NULL; 230 return (NULL); 231} 232 233#endif /* WANT_IRS_PW */ 234/*! \file */ 235