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