1 /* $OpenBSD: table_getpwnam.c,v 1.16 2024/05/14 13:30:37 op Exp $ */
2
3 /*
4 * Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <errno.h>
20 #include <pwd.h>
21
22 #include "smtpd.h"
23
24 /* getpwnam(3) backend */
25 static int table_getpwnam_config(struct table *);
26 static int table_getpwnam_lookup(struct table *, enum table_service, const char *,
27 char **);
28
29 struct table_backend table_backend_getpwnam = {
30 .name = "getpwnam",
31 .services = K_USERINFO,
32 .config = table_getpwnam_config,
33 .add = NULL,
34 .dump = NULL,
35 .open = NULL,
36 .update = NULL,
37 .close = NULL,
38 .lookup = table_getpwnam_lookup,
39 .fetch = NULL,
40 };
41
42
43 static int
table_getpwnam_config(struct table * table)44 table_getpwnam_config(struct table *table)
45 {
46 if (table->t_config[0])
47 return 0;
48 return 1;
49 }
50
51 static int
table_getpwnam_lookup(struct table * table,enum table_service kind,const char * key,char ** dst)52 table_getpwnam_lookup(struct table *table, enum table_service kind, const char *key,
53 char **dst)
54 {
55 struct passwd *pw;
56
57 if (kind != K_USERINFO)
58 return -1;
59
60 errno = 0;
61 do {
62 pw = getpwnam(key);
63 } while (pw == NULL && errno == EINTR);
64
65 if (pw == NULL) {
66 if (errno)
67 return -1;
68 return 0;
69 }
70 if (dst == NULL)
71 return 1;
72
73 if (asprintf(dst, "%d:%d:%s",
74 pw->pw_uid,
75 pw->pw_gid,
76 pw->pw_dir) == -1) {
77 *dst = NULL;
78 return -1;
79 }
80
81 return (1);
82 }
83