1/* $NetBSD$ */ 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(LINT) && !defined(CODECENTER) 21static const char rcsid[] = "Id: gen_pw.c,v 1.3 2005/04/27 04:56:24 sra Exp"; 22#endif 23 24/* Imports */ 25 26#include "port_before.h" 27 28#ifndef WANT_IRS_PW 29static int __bind_irs_pw_unneeded; 30#else 31 32#include <sys/types.h> 33#include <netinet/in.h> 34#include <arpa/nameser.h> 35#include <resolv.h> 36 37#include <errno.h> 38#include <pwd.h> 39#include <stdlib.h> 40#include <string.h> 41 42#include <isc/memcluster.h> 43#include <irs.h> 44 45#include "port_after.h" 46 47#include "irs_p.h" 48#include "gen_p.h" 49 50/* Types */ 51 52struct pvt { 53 struct irs_rule * rules; 54 struct irs_rule * rule; 55 struct __res_state * res; 56 void (*free_res)(void *); 57}; 58 59/* Forward */ 60 61static void pw_close(struct irs_pw *); 62static struct passwd * pw_next(struct irs_pw *); 63static struct passwd * pw_byname(struct irs_pw *, const char *); 64static struct passwd * pw_byuid(struct irs_pw *, uid_t); 65static void pw_rewind(struct irs_pw *); 66static void pw_minimize(struct irs_pw *); 67static struct __res_state * pw_res_get(struct irs_pw *); 68static void pw_res_set(struct irs_pw *, 69 struct __res_state *, 70 void (*)(void *)); 71 72/* Public */ 73 74struct irs_pw * 75irs_gen_pw(struct irs_acc *this) { 76 struct gen_p *accpvt = (struct gen_p *)this->private; 77 struct irs_pw *pw; 78 struct pvt *pvt; 79 80 if (!(pw = memget(sizeof *pw))) { 81 errno = ENOMEM; 82 return (NULL); 83 } 84 memset(pw, 0x5e, sizeof *pw); 85 if (!(pvt = memget(sizeof *pvt))) { 86 memput(pw, sizeof *pvt); 87 errno = ENOMEM; 88 return (NULL); 89 } 90 memset(pvt, 0, sizeof *pvt); 91 pvt->rules = accpvt->map_rules[irs_pw]; 92 pvt->rule = pvt->rules; 93 pw->private = pvt; 94 pw->close = pw_close; 95 pw->next = pw_next; 96 pw->byname = pw_byname; 97 pw->byuid = pw_byuid; 98 pw->rewind = pw_rewind; 99 pw->minimize = pw_minimize; 100 pw->res_get = pw_res_get; 101 pw->res_set = pw_res_set; 102 return (pw); 103} 104 105/* Methods */ 106 107static void 108pw_close(struct irs_pw *this) { 109 struct pvt *pvt = (struct pvt *)this->private; 110 111 memput(pvt, sizeof *pvt); 112 memput(this, sizeof *this); 113} 114 115static struct passwd * 116pw_next(struct irs_pw *this) { 117 struct pvt *pvt = (struct pvt *)this->private; 118 struct passwd *rval; 119 struct irs_pw *pw; 120 121 while (pvt->rule) { 122 pw = pvt->rule->inst->pw; 123 rval = (*pw->next)(pw); 124 if (rval) 125 return (rval); 126 if (!(pvt->rule->flags & IRS_CONTINUE)) 127 break; 128 pvt->rule = pvt->rule->next; 129 if (pvt->rule) { 130 pw = pvt->rule->inst->pw; 131 (*pw->rewind)(pw); 132 } 133 } 134 return (NULL); 135} 136 137static void 138pw_rewind(struct irs_pw *this) { 139 struct pvt *pvt = (struct pvt *)this->private; 140 struct irs_pw *pw; 141 142 pvt->rule = pvt->rules; 143 if (pvt->rule) { 144 pw = pvt->rule->inst->pw; 145 (*pw->rewind)(pw); 146 } 147} 148 149static struct passwd * 150pw_byname(struct irs_pw *this, const char *name) { 151 struct pvt *pvt = (struct pvt *)this->private; 152 struct irs_rule *rule; 153 struct passwd *rval; 154 struct irs_pw *pw; 155 156 rval = NULL; 157 for (rule = pvt->rules; rule; rule = rule->next) { 158 pw = rule->inst->pw; 159 rval = (*pw->byname)(pw, name); 160 if (rval || !(rule->flags & IRS_CONTINUE)) 161 break; 162 } 163 return (rval); 164} 165 166static struct passwd * 167pw_byuid(struct irs_pw *this, uid_t uid) { 168 struct pvt *pvt = (struct pvt *)this->private; 169 struct irs_rule *rule; 170 struct passwd *rval; 171 struct irs_pw *pw; 172 173 rval = NULL; 174 for (rule = pvt->rules; rule; rule = rule->next) { 175 pw = rule->inst->pw; 176 rval = (*pw->byuid)(pw, uid); 177 if (rval || !(rule->flags & IRS_CONTINUE)) 178 break; 179 } 180 return (rval); 181} 182 183static void 184pw_minimize(struct irs_pw *this) { 185 struct pvt *pvt = (struct pvt *)this->private; 186 struct irs_rule *rule; 187 188 for (rule = pvt->rules; rule != NULL; rule = rule->next) { 189 struct irs_pw *pw = rule->inst->pw; 190 191 (*pw->minimize)(pw); 192 } 193} 194 195static struct __res_state * 196pw_res_get(struct irs_pw *this) { 197 struct pvt *pvt = (struct pvt *)this->private; 198 199 if (!pvt->res) { 200 struct __res_state *res; 201 res = (struct __res_state *)malloc(sizeof *res); 202 if (!res) { 203 errno = ENOMEM; 204 return (NULL); 205 } 206 memset(res, 0, sizeof *res); 207 pw_res_set(this, res, free); 208 } 209 210 return (pvt->res); 211} 212 213static void 214pw_res_set(struct irs_pw *this, struct __res_state *res, 215 void (*free_res)(void *)) { 216 struct pvt *pvt = (struct pvt *)this->private; 217 struct irs_rule *rule; 218 219 if (pvt->res && pvt->free_res) { 220 res_nclose(pvt->res); 221 (*pvt->free_res)(pvt->res); 222 } 223 224 pvt->res = res; 225 pvt->free_res = free_res; 226 227 for (rule = pvt->rules; rule != NULL; rule = rule->next) { 228 struct irs_pw *pw = rule->inst->pw; 229 230 if (pw->res_set) 231 (*pw->res_set)(pw, pvt->res, NULL); 232 } 233} 234 235#endif /* WANT_IRS_PW */ 236/*! \file */ 237