1/* 2 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 3 * Portions Copyright (c) 1996 by Internet Software Consortium. 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 ISC DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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 15 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18#if defined(LIBC_SCCS) && !defined(lint) 19static const char rcsid[] = "$Id: irp_pw.c,v 1.4 2005/04/27 04:56:29 sra Exp $"; 20#endif /* LIBC_SCCS and not lint */ 21 22/* Extern */ 23 24#include "port_before.h" 25 26#ifndef WANT_IRS_PW 27static int __bind_irs_pw_unneeded; 28#else 29 30#include <syslog.h> 31#include <sys/param.h> 32 33#include <db.h> 34#include <errno.h> 35#include <fcntl.h> 36#include <limits.h> 37#include <pwd.h> 38#include <stdlib.h> 39#include <string.h> 40#include <syslog.h> 41#include <utmp.h> 42#include <unistd.h> 43 44#include <irs.h> 45#include <irp.h> 46#include <isc/memcluster.h> 47#include <isc/irpmarshall.h> 48 49#include "port_after.h" 50 51#include "irs_p.h" 52#include "irp_p.h" 53 54 55/* Types */ 56 57struct pvt { 58 struct irp_p *girpdata; /*%< global IRP data */ 59 int warned; 60 struct passwd passwd; /*%< password structure */ 61}; 62 63/* Forward */ 64 65static void pw_close(struct irs_pw *); 66static struct passwd * pw_next(struct irs_pw *); 67static struct passwd * pw_byname(struct irs_pw *, const char *); 68static struct passwd * pw_byuid(struct irs_pw *, uid_t); 69static void pw_rewind(struct irs_pw *); 70static void pw_minimize(struct irs_pw *); 71 72static void free_passwd(struct passwd *pw); 73 74/* Public */ 75struct irs_pw * 76irs_irp_pw(struct irs_acc *this) { 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, 0, sizeof *pw); 85 86 if (!(pvt = memget(sizeof *pvt))) { 87 memput(pw, sizeof *pw); 88 errno = ENOMEM; 89 return (NULL); 90 } 91 memset(pvt, 0, sizeof *pvt); 92 pvt->girpdata = this->private; 93 94 pw->private = pvt; 95 pw->close = pw_close; 96 pw->next = pw_next; 97 pw->byname = pw_byname; 98 pw->byuid = pw_byuid; 99 pw->rewind = pw_rewind; 100 pw->minimize = pw_minimize; 101 102 return (pw); 103} 104 105/* Methods */ 106 107/*% 108 * void pw_close(struct irs_pw *this) 109 * 110 */ 111 112static void 113pw_close(struct irs_pw *this) { 114 struct pvt *pvt = (struct pvt *)this->private; 115 116 pw_minimize(this); 117 118 free_passwd(&pvt->passwd); 119 120 memput(pvt, sizeof *pvt); 121 memput(this, sizeof *this); 122} 123 124/*% 125 * struct passwd * pw_next(struct irs_pw *this) 126 * 127 */ 128 129static struct passwd * 130pw_next(struct irs_pw *this) { 131 struct pvt *pvt = (struct pvt *)this->private; 132 struct passwd *pw = &pvt->passwd; 133 char *body; 134 size_t bodylen; 135 int code; 136 char text[256]; 137 138 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 139 return (NULL); 140 } 141 142 if (irs_irp_send_command(pvt->girpdata, "getpwent") != 0) { 143 return (NULL); 144 } 145 146 if (irs_irp_get_full_response(pvt->girpdata, &code, 147 text, sizeof text, 148 &body, &bodylen) != 0) { 149 return (NULL); 150 } 151 152 if (code == IRPD_GETUSER_OK) { 153 free_passwd(pw); 154 if (irp_unmarshall_pw(pw, body) != 0) { 155 pw = NULL; 156 } 157 } else { 158 pw = NULL; 159 } 160 161 if (body != NULL) { 162 memput(body, bodylen); 163 } 164 165 return (pw); 166} 167 168/*% 169 * struct passwd * pw_byname(struct irs_pw *this, const char *name) 170 * 171 */ 172 173static struct passwd * 174pw_byname(struct irs_pw *this, const char *name) { 175 struct pvt *pvt = (struct pvt *)this->private; 176 struct passwd *pw = &pvt->passwd; 177 char *body = NULL; 178 char text[256]; 179 size_t bodylen; 180 int code; 181 182 if (pw->pw_name != NULL && strcmp(name, pw->pw_name) == 0) { 183 return (pw); 184 } 185 186 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 187 return (NULL); 188 } 189 190 if (irs_irp_send_command(pvt->girpdata, "getpwnam %s", name) != 0) { 191 return (NULL); 192 } 193 194 if (irs_irp_get_full_response(pvt->girpdata, &code, 195 text, sizeof text, 196 &body, &bodylen) != 0) { 197 return (NULL); 198 } 199 200 if (code == IRPD_GETUSER_OK) { 201 free_passwd(pw); 202 if (irp_unmarshall_pw(pw, body) != 0) { 203 pw = NULL; 204 } 205 } else { 206 pw = NULL; 207 } 208 209 if (body != NULL) { 210 memput(body, bodylen); 211 } 212 213 return (pw); 214} 215 216/*% 217 * struct passwd * pw_byuid(struct irs_pw *this, uid_t uid) 218 * 219 */ 220 221static struct passwd * 222pw_byuid(struct irs_pw *this, uid_t uid) { 223 struct pvt *pvt = (struct pvt *)this->private; 224 char *body; 225 char text[256]; 226 size_t bodylen; 227 int code; 228 struct passwd *pw = &pvt->passwd; 229 230 if (pw->pw_name != NULL && pw->pw_uid == uid) { 231 return (pw); 232 } 233 234 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 235 return (NULL); 236 } 237 238 if (irs_irp_send_command(pvt->girpdata, "getpwuid %d", uid) != 0) { 239 return (NULL); 240 } 241 242 if (irs_irp_get_full_response(pvt->girpdata, &code, 243 text, sizeof text, 244 &body, &bodylen) != 0) { 245 return (NULL); 246 } 247 248 if (code == IRPD_GETUSER_OK) { 249 free_passwd(pw); 250 if (irp_unmarshall_pw(pw, body) != 0) { 251 pw = NULL; 252 } 253 } else { 254 pw = NULL; 255 } 256 257 if (body != NULL) { 258 memput(body, bodylen); 259 } 260 261 return (pw); 262} 263 264/*% 265 * void pw_rewind(struct irs_pw *this) 266 * 267 */ 268 269static void 270pw_rewind(struct irs_pw *this) { 271 struct pvt *pvt = (struct pvt *)this->private; 272 char text[256]; 273 int code; 274 275 if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { 276 return; 277 } 278 279 if (irs_irp_send_command(pvt->girpdata, "setpwent") != 0) { 280 return; 281 } 282 283 code = irs_irp_read_response(pvt->girpdata, text, sizeof text); 284 if (code != IRPD_GETUSER_SETOK) { 285 if (irp_log_errors) { 286 syslog(LOG_WARNING, "setpwent failed: %s", text); 287 } 288 } 289 290 return; 291} 292 293/*% 294 * void pw_minimize(struct irs_pw *this) 295 * 296 */ 297 298static void 299pw_minimize(struct irs_pw *this) { 300 struct pvt *pvt = (struct pvt *)this->private; 301 302 irs_irp_disconnect(pvt->girpdata); 303} 304 305 306/* Private. */ 307 308/*% 309 * Deallocate all the memory irp_unmarshall_pw allocated. 310 * 311 */ 312 313static void 314free_passwd(struct passwd *pw) { 315 if (pw == NULL) 316 return; 317 318 if (pw->pw_name != NULL) 319 free(pw->pw_name); 320 321 if (pw->pw_passwd != NULL) 322 free(pw->pw_passwd); 323 324#ifdef HAVE_PW_CLASS 325 if (pw->pw_class != NULL) 326 free(pw->pw_class); 327#endif 328 329 if (pw->pw_gecos != NULL) 330 free(pw->pw_gecos); 331 332 if (pw->pw_dir != NULL) 333 free(pw->pw_dir); 334 335 if (pw->pw_shell != NULL) 336 free(pw->pw_shell); 337} 338 339#endif /* WANT_IRS_PW */ 340/*! \file */ 341