]>
Commit | Line | Data |
---|---|---|
d67281a7 UD |
1 | /* Copyright (C) 1998 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 Library General Public License as | |
7 | published by the Free Software Foundation; either version 2 of the | |
8 | 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 | Library General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Library General Public | |
16 | License along with the GNU C Library; see the file COPYING.LIB. If not, | |
17 | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
18 | Boston, MA 02111-1307, USA. */ | |
19 | ||
20 | #include <errno.h> | |
21 | #include <grp.h> | |
22 | #include <stdio.h> | |
23 | #include <stdlib.h> | |
24 | #include <string.h> | |
25 | #include <unistd.h> | |
26 | #include <sys/socket.h> | |
27 | #include <sys/un.h> | |
28 | ||
29 | #include "nscd.h" | |
30 | #include "nscd_proto.h" | |
31 | ||
32 | static int __nscd_getgr_r (const char *key, request_type type, | |
33 | struct group *resultbuf, char *buffer, | |
34 | size_t buflen); | |
35 | ||
36 | int | |
37 | __nscd_getgrnam_r (const char *name, struct group *resultbuf, char *buffer, | |
38 | size_t buflen) | |
39 | { | |
40 | if (name == NULL) | |
41 | return 1; | |
42 | ||
43 | return __nscd_getgr_r (name, GETGRBYNAME, resultbuf, buffer, buflen); | |
44 | } | |
45 | ||
46 | int | |
47 | __nscd_getgrgid_r (gid_t gid, struct group *resultbuf, char *buffer, | |
48 | size_t buflen) | |
49 | { | |
50 | char *p = buffer; | |
51 | char plen; | |
52 | ||
53 | plen = snprintf (buffer, buflen, "%d", gid); | |
54 | if (plen == -1) | |
55 | { | |
56 | __set_errno (ERANGE); | |
57 | return -1; | |
58 | } | |
59 | p = buffer + plen + 1; | |
60 | ||
61 | return __nscd_getgr_r (buffer, GETGRBYGID, resultbuf, p, buflen - plen -1); | |
62 | } | |
63 | ||
64 | /* Create a socket connected to a name. */ | |
65 | static int | |
66 | nscd_open_socket (void) | |
67 | { | |
68 | struct sockaddr_un addr; | |
69 | int sock; | |
70 | ||
71 | sock = socket (PF_UNIX, SOCK_STREAM, 0); | |
72 | if (sock < 0) | |
73 | return -1; | |
74 | ||
75 | addr.sun_family = AF_UNIX; | |
76 | strcpy (addr.sun_path, _PATH_NSCDSOCKET); | |
77 | if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)) < 0) | |
78 | { | |
79 | close (sock); | |
80 | return -1; | |
81 | } | |
82 | ||
83 | return sock; | |
84 | } | |
85 | ||
86 | static int | |
87 | __nscd_getgr_r (const char *key, request_type type, struct group *resultbuf, | |
88 | char *buffer, size_t buflen) | |
89 | { | |
90 | int sock = nscd_open_socket (); | |
91 | request_header req; | |
92 | gr_response_header gr_resp; | |
93 | ssize_t nbytes; | |
94 | ||
95 | if (sock == -1) | |
96 | return 1; | |
97 | ||
98 | req.version = NSCD_VERSION; | |
99 | req.type = type; | |
100 | req.key_len = strlen (key); | |
101 | nbytes = write (sock, &req, sizeof (request_header)); | |
102 | if (nbytes != sizeof (request_header)) | |
103 | { | |
104 | close (sock); | |
105 | return 1; | |
106 | } | |
107 | ||
108 | nbytes = write (sock, key, req.key_len); | |
109 | if (nbytes != req.key_len) | |
110 | { | |
111 | close (sock); | |
112 | return 1; | |
113 | } | |
114 | ||
115 | nbytes = read (sock, &gr_resp, sizeof (gr_response_header)); | |
116 | if (nbytes != sizeof (gr_response_header)) | |
117 | { | |
118 | close (sock); | |
119 | return 1; | |
120 | } | |
121 | ||
122 | if (gr_resp.found == -1) | |
123 | { | |
124 | close (sock); | |
125 | return 1; | |
126 | } | |
127 | ||
128 | if (gr_resp.found == 1) | |
129 | { | |
130 | size_t i; | |
131 | char *p = buffer; | |
132 | ||
133 | if (buflen < gr_resp.gr_name_len + 1) | |
134 | { | |
135 | __set_errno (ERANGE); | |
136 | close (sock); | |
137 | return -1; | |
138 | } | |
139 | resultbuf->gr_name = p; | |
140 | p += gr_resp.gr_name_len + 1; | |
141 | buflen -= (gr_resp.gr_name_len + 1); | |
142 | nbytes = read (sock, resultbuf->gr_name, gr_resp.gr_name_len); | |
143 | if (nbytes != gr_resp.gr_name_len) | |
144 | { | |
145 | close (sock); | |
146 | return 1; | |
147 | } | |
148 | resultbuf->gr_name[gr_resp.gr_name_len] = '\0'; | |
149 | ||
150 | if (buflen < gr_resp.gr_passwd_len + 1) | |
151 | { | |
152 | __set_errno (ERANGE); | |
153 | close (sock); | |
154 | return -1; | |
155 | } | |
156 | resultbuf->gr_passwd = p; | |
157 | p += gr_resp.gr_passwd_len + 1; | |
158 | buflen -= (gr_resp.gr_passwd_len + 1); | |
159 | nbytes = read (sock, resultbuf->gr_passwd, gr_resp.gr_passwd_len); | |
160 | if (nbytes != gr_resp.gr_passwd_len) | |
161 | { | |
162 | close (sock); | |
163 | return 1; | |
164 | } | |
165 | resultbuf->gr_passwd[gr_resp.gr_passwd_len] = '\0'; | |
166 | ||
167 | resultbuf->gr_gid = gr_resp.gr_gid; | |
168 | ||
169 | if (buflen < ((gr_resp.gr_mem_len + 1) * sizeof (char *))) | |
170 | { | |
171 | __set_errno (ERANGE); | |
172 | close (sock); | |
173 | return -1; | |
174 | } | |
175 | resultbuf->gr_mem = (char **)p; | |
176 | p += ((gr_resp.gr_mem_len + 1) * sizeof (char *)); | |
177 | buflen -= ((gr_resp.gr_mem_len + 1) * sizeof (char *)); | |
178 | ||
179 | resultbuf->gr_mem[gr_resp.gr_mem_len] = NULL; | |
180 | ||
181 | for (i = 0; i < gr_resp.gr_mem_len; ++i) | |
182 | { | |
183 | size_t len; | |
184 | nbytes = read (sock, &len, sizeof (len)); | |
185 | if (nbytes != sizeof (len)) | |
186 | { | |
187 | close (sock); | |
188 | return 1; | |
189 | } | |
190 | ||
191 | if (buflen < (len + 1)) | |
192 | { | |
193 | __set_errno (ERANGE); | |
194 | close (sock); | |
195 | return -1; | |
196 | } | |
197 | resultbuf->gr_mem[i] = p; | |
198 | p += len + 1; | |
199 | buflen -= (len + 1); | |
200 | nbytes = read (sock, resultbuf->gr_mem[i], len); | |
201 | resultbuf->gr_mem[i][len] = '\0'; | |
202 | if (nbytes != len) | |
203 | { | |
204 | close (sock); | |
205 | return 1; | |
206 | } | |
207 | } | |
208 | } | |
209 | close (sock); | |
210 | return 0; | |
211 | } |