2 ** Copyright 1998 - 2007 Double Precision, Inc.
3 ** See COPYING for distribution information.
16 #include <sys/types.h>
22 static struct dbobj d
;
26 static int initialized
=0;
27 int userdb_debug_level
=0;
29 /* Open userdb.dat, if already opened, see if it changed, if so reopen */
31 void userdb_init(const char *n
)
37 if (stat(n
, &stat_buf
) ||
38 stat_buf
.st_mtime
!= dt
||
39 stat_buf
.st_ino
!= di
)
47 else if (stat(n
, &stat_buf
))
49 if (userdb_debug_level
)
51 "DEBUG: userdb: unable to stat %s: %s\n",
63 if (dbobj_open(&d
, n
, "R"))
65 if (userdb_debug_level
)
67 "DEBUG: userdb: failed to open %s\n",
71 if (userdb_debug_level
)
72 fprintf(stderr
, "DEBUG: userdb: opened %s\n", n
);
87 void userdb_set_debug(int lvl
)
89 userdb_debug_level
= lvl
;
92 /* Fetch a record from userdb.dat */
94 char *userdb(const char *u
)
105 q
=dbobj_fetch(&d
, u
, strlen(u
), &l
, "");
108 if (userdb_debug_level
)
109 fprintf(stderr
, "DEBUG: userdb: entry not found\n");
121 if (l
) memcpy(p
, q
, l
);
127 /* Return a pointer to a specific field in this record */
129 const char *userdb_get(const char *u
, const char *n
, int *l
)
135 if (memcmp(u
, n
, nl
) == 0 &&
136 (u
[nl
] == 0 || u
[nl
] == '=' || u
[nl
] == '|'))
143 while ( u
[*l
] && u
[*l
] != '|')
154 /* Extract field as an unsigned int */
156 unsigned userdb_getu(const char *u
, const char *n
, unsigned defnum
)
161 if ((p
=userdb_get(u
, n
, &l
)) != 0)
164 while (l
&& *p
>= '0' && *p
<= '9')
166 defnum
= defnum
* 10 + (*p
++ - '0');
173 /* Extract a field into a dynamically allocated buffer */
175 char *userdb_gets(const char *u
, const char *n
)
181 if ((p
=userdb_get(u
, n
, &l
)) != 0)
187 if (l
) memcpy(q
, p
, l
);
195 /* Create a userdbs structure based upon a uid (reverse lookup) */
197 struct userdbs
*userdb_createsuid(uid_t u
)
200 char *p
=buf
+sizeof(buf
)-1, *q
;
203 /* Lookup uid= record */
209 *--p
= "0123456789"[u
% 10];
215 /* Have account name, now look it up. */
232 static struct userdbs
*userdb_enum(char *key
, size_t keylen
,
233 char *val
, size_t vallen
)
237 char *valz
=malloc(vallen
+1);
241 struct userdbs
*udbs
;
243 memcpy(valz
, val
, vallen
);
246 udbs
=userdb_creates(valz
);
250 if ((udbs
->udb_name
=malloc(keylen
+1)) != NULL
)
252 memcpy(udbs
->udb_name
, key
, keylen
);
253 udbs
->udb_name
[keylen
]=0;
266 struct userdbs
*userdb_enum_first()
271 char *key
=dbobj_firstkey(&d
, &keylen
, &val
, &vallen
);
275 struct userdbs
*udbs
=userdb_enum(key
, keylen
, val
, vallen
);
282 /* Could be a reverse UID entry */
284 return userdb_enum_next();
289 struct userdbs
*userdb_enum_next()
296 while ((key
=dbobj_nextkey(&d
, &keylen
, &val
, &vallen
)) != NULL
)
298 struct userdbs
*udbs
=userdb_enum(key
, keylen
, val
, vallen
);
308 /* Extracted a userdb.dat record, convert it to a userdbs structure */
310 struct userdbs
*userdb_creates(const char *u
)
312 struct userdbs
*udbs
=(struct userdbs
*)malloc(sizeof(struct userdbs
));
315 if (!udbs
) return (0);
316 memset((char *)udbs
, 0, sizeof(*udbs
));
318 if ((udbs
->udb_dir
=userdb_gets(u
, "home")) == 0)
320 if (userdb_debug_level
)
322 "DEBUG: userdb: required value 'home' is missing\n");
327 if ((s
=userdb_gets(u
, "uid")) != 0)
329 udbs
->udb_uid
=atol(s
);
331 if ((s
=userdb_gets(u
, "gid")) != 0)
333 udbs
->udb_gid
=atol(s
);
336 if ((s
=userdb_gets(u
, "shell")) != 0)
338 else if (errno
!= ENOENT
)
344 if ((s
=userdb_gets(u
, "mail")) != 0)
346 else if (errno
!= ENOENT
)
351 if ((s
=userdb_gets(u
, "quota")) != 0)
353 else if (errno
!= ENOENT
)
358 if ((s
=userdb_gets(u
, "gecos")) != 0)
360 else if (errno
!= ENOENT
)
365 if ((s
=userdb_gets(u
, "options")) != 0)
367 else if (errno
!= ENOENT
)
372 udbs
->udb_source
=userdb_gets(u
, "_");
373 if (userdb_debug_level
)
375 "DEBUG: userdb: home=%s, uid=%ld, gid=%ld, shell=%s, "
376 "mail=%s, quota=%s, gecos=%s, options=%s\n",
377 udbs
->udb_dir
? udbs
->udb_dir
: "<unset>",
378 (long)udbs
->udb_uid
, (long)udbs
->udb_gid
,
379 udbs
->udb_shell
? udbs
->udb_shell
: "<unset>",
380 udbs
->udb_mailbox
? udbs
->udb_mailbox
: "<unset>",
381 udbs
->udb_quota
? udbs
->udb_quota
: "<unset>",
382 udbs
->udb_gecos
? udbs
->udb_gecos
: "<unset>",
383 udbs
->udb_options
? udbs
->udb_options
: "<unset>");
387 if (userdb_debug_level
)
389 "DEBUG: userdb: required value 'gid' is missing\n");
392 if (userdb_debug_level
)
394 "DEBUG: userdb: required value 'uid' is missing\n");
399 void userdb_frees(struct userdbs
*u
)
401 if (u
->udb_options
) free(u
->udb_options
);
402 if (u
->udb_name
) free(u
->udb_name
);
403 if (u
->udb_gecos
) free(u
->udb_gecos
);
404 if (u
->udb_dir
) free(u
->udb_dir
);
405 if (u
->udb_shell
) free(u
->udb_shell
);
406 if (u
->udb_mailbox
) free(u
->udb_mailbox
);
407 if (u
->udb_quota
) free(u
->udb_quota
);
408 if (u
->udb_source
) free(u
->udb_source
);