]> git.ipfire.org Git - thirdparty/glibc.git/blob - nscd/nscd_getpw_r.c
Update.
[thirdparty/glibc.git] / nscd / nscd_getpw_r.c
1 /* Copyright (C) 1998, 1999, 2003, 2004 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20 #include <errno.h>
21 #include <pwd.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <sys/socket.h>
28 #include <sys/uio.h>
29 #include <sys/un.h>
30 #include <not-cancel.h>
31 #include <stdio-common/_itoa.h>
32
33 #include "nscd-client.h"
34 #include "nscd_proto.h"
35
36 int __nss_not_use_nscd_passwd;
37
38 static int nscd_getpw_r (const char *key, size_t keylen, request_type type,
39 struct passwd *resultbuf, char *buffer,
40 size_t buflen, struct passwd **result)
41 internal_function;
42
43 int
44 __nscd_getpwnam_r (const char *name, struct passwd *resultbuf, char *buffer,
45 size_t buflen, struct passwd **result)
46 {
47 if (name == NULL)
48 return -1;
49
50 return nscd_getpw_r (name, strlen (name) + 1, GETPWBYNAME, resultbuf,
51 buffer, buflen, result);
52 }
53
54 int
55 __nscd_getpwuid_r (uid_t uid, struct passwd *resultbuf, char *buffer,
56 size_t buflen, struct passwd **result)
57 {
58 char buf[3 * sizeof (uid_t)];
59 buf[sizeof (buf) - 1] = '\0';
60 char *cp = _itoa_word (uid, buf + sizeof (buf) - 1, 10, 0);
61
62 return nscd_getpw_r (cp, buf + sizeof (buf) - cp, GETPWBYUID, resultbuf,
63 buffer, buflen, result);
64 }
65
66
67 static int
68 internal_function
69 nscd_getpw_r (const char *key, size_t keylen, request_type type,
70 struct passwd *resultbuf, char *buffer, size_t buflen,
71 struct passwd **result)
72 {
73 pw_response_header pw_resp;
74 int sock = __nscd_open_socket (key, keylen, type, &pw_resp,
75 sizeof (pw_resp));
76 if (sock == -1)
77 {
78 __nss_not_use_nscd_passwd = 1;
79 return -1;
80 }
81
82 /* No value found so far. */
83 int retval = -1;
84 *result = NULL;
85
86 if (__builtin_expect (pw_resp.found == -1, 0))
87 {
88 /* The daemon does not cache this database. */
89 __nss_not_use_nscd_passwd = 1;
90 goto out;
91 }
92
93 if (pw_resp.found == 1)
94 {
95 char *p = buffer;
96 size_t total = (pw_resp.pw_name_len + pw_resp.pw_passwd_len
97 + pw_resp.pw_gecos_len + pw_resp.pw_dir_len
98 + pw_resp.pw_shell_len);
99
100 if (__builtin_expect (buflen < total, 0))
101 {
102 __set_errno (ERANGE);
103 retval = ERANGE;
104 goto out;
105 }
106
107 /* Set the information we already have. */
108 resultbuf->pw_uid = pw_resp.pw_uid;
109 resultbuf->pw_gid = pw_resp.pw_gid;
110
111 /* get pw_name */
112 resultbuf->pw_name = p;
113 p += pw_resp.pw_name_len;
114 /* get pw_passwd */
115 resultbuf->pw_passwd = p;
116 p += pw_resp.pw_passwd_len;
117 /* get pw_gecos */
118 resultbuf->pw_gecos = p;
119 p += pw_resp.pw_gecos_len;
120 /* get pw_dir */
121 resultbuf->pw_dir = p;
122 p += pw_resp.pw_dir_len;
123 /* get pw_pshell */
124 resultbuf->pw_shell = p;
125
126 ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, buffer, total));
127
128 if (nbytes == (ssize_t) total)
129 {
130 retval = 0;
131 *result = resultbuf;
132 }
133 }
134 else
135 {
136 /* The `errno' to some value != ERANGE. */
137 __set_errno (ENOENT);
138 /* Even though we have not found anything, the result is zero. */
139 retval = 0;
140 }
141
142 out:
143 close_not_cancel_no_status (sock);
144
145 return retval;
146 }