2 ** Copyright 1998 - 2007 Double Precision, Inc.
3 ** See COPYING for distribution information.
16 #include <sys/types.h>
21 static const char rcsid
[]="$Id: userdb.c,v 1.10 2007/04/14 03:02:46 mrsam Exp $";
23 static struct dbobj d
;
27 static int initialized
=0;
28 int userdb_debug_level
=0;
30 /* Open userdb.dat, if already opened, see if it changed, if so reopen */
32 void userdb_init(const char *n
)
38 if (stat(n
, &stat_buf
) ||
39 stat_buf
.st_mtime
!= dt
||
40 stat_buf
.st_ino
!= di
)
48 else if (stat(n
, &stat_buf
))
50 if (userdb_debug_level
)
52 "DEBUG: userdb: unable to stat %s: %s\n",
64 if (dbobj_open(&d
, n
, "R"))
66 if (userdb_debug_level
)
68 "DEBUG: userdb: failed to open %s\n",
72 if (userdb_debug_level
)
73 fprintf(stderr
, "DEBUG: userdb: opened %s\n", n
);
88 void userdb_set_debug(int lvl
)
90 userdb_debug_level
= lvl
;
93 /* Fetch a record from userdb.dat */
95 char *userdb(const char *u
)
106 q
=dbobj_fetch(&d
, u
, strlen(u
), &l
, "");
109 if (userdb_debug_level
)
110 fprintf(stderr
, "DEBUG: userdb: entry not found\n");
122 if (l
) memcpy(p
, q
, l
);
128 /* Return a pointer to a specific field in this record */
130 const char *userdb_get(const char *u
, const char *n
, int *l
)
136 if (memcmp(u
, n
, nl
) == 0 &&
137 (u
[nl
] == 0 || u
[nl
] == '=' || u
[nl
] == '|'))
144 while ( u
[*l
] && u
[*l
] != '|')
155 /* Extract field as an unsigned int */
157 unsigned userdb_getu(const char *u
, const char *n
, unsigned defnum
)
162 if ((p
=userdb_get(u
, n
, &l
)) != 0)
165 while (l
&& *p
>= '0' && *p
<= '9')
167 defnum
= defnum
* 10 + (*p
++ - '0');
174 /* Extract a field into a dynamically allocated buffer */
176 char *userdb_gets(const char *u
, const char *n
)
182 if ((p
=userdb_get(u
, n
, &l
)) != 0)
188 if (l
) memcpy(q
, p
, l
);
196 /* Create a userdbs structure based upon a uid (reverse lookup) */
198 struct userdbs
*userdb_createsuid(uid_t u
)
201 char *p
=buf
+sizeof(buf
)-1, *q
;
204 /* Lookup uid= record */
210 *--p
= "0123456789"[u
% 10];
216 /* Have account name, now look it up. */
233 static struct userdbs
*userdb_enum(char *key
, size_t keylen
,
234 char *val
, size_t vallen
)
238 char *valz
=malloc(vallen
+1);
242 struct userdbs
*udbs
;
244 memcpy(valz
, val
, vallen
);
247 udbs
=userdb_creates(valz
);
251 if ((udbs
->udb_name
=malloc(keylen
+1)) != NULL
)
253 memcpy(udbs
->udb_name
, key
, keylen
);
254 udbs
->udb_name
[keylen
]=0;
267 struct userdbs
*userdb_enum_first()
272 char *key
=dbobj_firstkey(&d
, &keylen
, &val
, &vallen
);
276 struct userdbs
*udbs
=userdb_enum(key
, keylen
, val
, vallen
);
283 /* Could be a reverse UID entry */
285 return userdb_enum_next();
290 struct userdbs
*userdb_enum_next()
297 while ((key
=dbobj_nextkey(&d
, &keylen
, &val
, &vallen
)) != NULL
)
299 struct userdbs
*udbs
=userdb_enum(key
, keylen
, val
, vallen
);
309 /* Extracted a userdb.dat record, convert it to a userdbs structure */
311 struct userdbs
*userdb_creates(const char *u
)
313 struct userdbs
*udbs
=(struct userdbs
*)malloc(sizeof(struct userdbs
));
316 if (!udbs
) return (0);
317 memset((char *)udbs
, 0, sizeof(*udbs
));
319 if ((udbs
->udb_dir
=userdb_gets(u
, "home")) == 0)
321 if (userdb_debug_level
)
323 "DEBUG: userdb: required value 'home' is missing\n");
328 if ((s
=userdb_gets(u
, "uid")) != 0)
330 udbs
->udb_uid
=atol(s
);
332 if ((s
=userdb_gets(u
, "gid")) != 0)
334 udbs
->udb_gid
=atol(s
);
337 if ((s
=userdb_gets(u
, "shell")) != 0)
339 else if (errno
!= ENOENT
)
345 if ((s
=userdb_gets(u
, "mail")) != 0)
347 else if (errno
!= ENOENT
)
352 if ((s
=userdb_gets(u
, "quota")) != 0)
354 else if (errno
!= ENOENT
)
359 if ((s
=userdb_gets(u
, "gecos")) != 0)
361 else if (errno
!= ENOENT
)
366 if ((s
=userdb_gets(u
, "options")) != 0)
368 else if (errno
!= ENOENT
)
373 udbs
->udb_source
=userdb_gets(u
, "_");
374 if (userdb_debug_level
)
376 "DEBUG: userdb: home=%s, uid=%ld, gid=%ld, shell=%s, "
377 "mail=%s, quota=%s, gecos=%s, options=%s\n",
378 udbs
->udb_dir
? udbs
->udb_dir
: "<unset>",
379 (long)udbs
->udb_uid
, (long)udbs
->udb_gid
,
380 udbs
->udb_shell
? udbs
->udb_shell
: "<unset>",
381 udbs
->udb_mailbox
? udbs
->udb_mailbox
: "<unset>",
382 udbs
->udb_quota
? udbs
->udb_quota
: "<unset>",
383 udbs
->udb_gecos
? udbs
->udb_gecos
: "<unset>",
384 udbs
->udb_options
? udbs
->udb_options
: "<unset>");
388 if (userdb_debug_level
)
390 "DEBUG: userdb: required value 'gid' is missing\n");
393 if (userdb_debug_level
)
395 "DEBUG: userdb: required value 'uid' is missing\n");
400 void userdb_frees(struct userdbs
*u
)
402 if (u
->udb_options
) free(u
->udb_options
);
403 if (u
->udb_name
) free(u
->udb_name
);
404 if (u
->udb_gecos
) free(u
->udb_gecos
);
405 if (u
->udb_dir
) free(u
->udb_dir
);
406 if (u
->udb_shell
) free(u
->udb_shell
);
407 if (u
->udb_mailbox
) free(u
->udb_mailbox
);
408 if (u
->udb_quota
) free(u
->udb_quota
);
409 if (u
->udb_source
) free(u
->udb_source
);