]> git.ipfire.org Git - thirdparty/glibc.git/blob - hesiod/nss_hesiod/hesiod-pwd.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / hesiod / nss_hesiod / hesiod-pwd.c
1 /* Copyright (C) 1997-2019 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <errno.h>
20 #include <hesiod.h>
21 #include <pwd.h>
22 #include <nss.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 /* Get the declaration of the parser function. */
28 #define ENTNAME pwent
29 #define STRUCTURE passwd
30 #define EXTERN_PARSER
31 #include <nss/nss_files/files-parse.c>
32
33 enum nss_status
34 _nss_hesiod_setpwent (int stayopen)
35 {
36 return NSS_STATUS_SUCCESS;
37 }
38
39 enum nss_status
40 _nss_hesiod_endpwent (void)
41 {
42 return NSS_STATUS_SUCCESS;
43 }
44
45 static enum nss_status
46 lookup (const char *name, const char *type, struct passwd *pwd,
47 char *buffer, size_t buflen, int *errnop)
48 {
49 struct parser_data *data = (void *) buffer;
50 size_t linebuflen;
51 void *context;
52 char **list;
53 int parse_res;
54 size_t len;
55 int olderr = errno;
56
57 if (hesiod_init (&context) < 0)
58 return NSS_STATUS_UNAVAIL;
59
60 list = hesiod_resolve (context, name, type);
61 if (list == NULL)
62 {
63 int err = errno;
64 hesiod_end (context);
65 __set_errno (olderr);
66 return err == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
67 }
68
69 linebuflen = buffer + buflen - data->linebuffer;
70 len = strlen (*list) + 1;
71 if (linebuflen < len)
72 {
73 hesiod_free_list (context, list);
74 hesiod_end (context);
75 *errnop = ERANGE;
76 return NSS_STATUS_TRYAGAIN;
77 }
78
79 memcpy (data->linebuffer, *list, len);
80 hesiod_free_list (context, list);
81 hesiod_end (context);
82
83 parse_res = _nss_files_parse_pwent (buffer, pwd, data, buflen, errnop);
84 if (parse_res < 1)
85 {
86 __set_errno (olderr);
87 return parse_res == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
88 }
89
90 return NSS_STATUS_SUCCESS;
91 }
92
93 enum nss_status
94 _nss_hesiod_getpwnam_r (const char *name, struct passwd *pwd,
95 char *buffer, size_t buflen, int *errnop)
96 {
97 return lookup (name, "passwd", pwd, buffer, buflen, errnop);
98 }
99
100 enum nss_status
101 _nss_hesiod_getpwuid_r (uid_t uid, struct passwd *pwd,
102 char *buffer, size_t buflen, int *errnop)
103 {
104 char uidstr[21]; /* We will probably never have a gid_t with more
105 than 64 bits. */
106
107 snprintf (uidstr, sizeof uidstr, "%d", uid);
108
109 return lookup (uidstr, "uid", pwd, buffer, buflen, errnop);
110 }