]> git.ipfire.org Git - thirdparty/glibc.git/blame - nss/nss_test1.c
[powerpc] No need to enter "Ignore Exceptions Mode"
[thirdparty/glibc.git] / nss / nss_test1.c
CommitLineData
ae5c498d 1/* Template generic NSS service provider. See nss_test.h for usage.
04277e02 2 Copyright (C) 2017-2019 Free Software Foundation, Inc.
ae5c498d
DD
3 This file is part of the GNU C Library.
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
5a82c748 17 <https://www.gnu.org/licenses/>. */
ae5c498d 18
c3e2f19b
UD
19#include <errno.h>
20#include <nss.h>
21#include <pthread.h>
22#include <string.h>
ae5c498d
DD
23#include <stdio.h>
24#include <alloc_buffer.h>
c3e2f19b
UD
25
26
ae5c498d
DD
27/* We need to be able to handle NULLs "properly" within the testsuite,
28 to test known bad data. */
29#define alloc_buffer_maybe_copy_string(b,s) s ? alloc_buffer_copy_string (b, s) : NULL;
c3e2f19b 30
ae5c498d
DD
31/* This file is the master template. Other instances of this test
32 module should define NAME(x) to have their name instead of "test1",
33 then include this file.
34*/
35#define NAME_(x,n) _nss_##n##_##x
36#ifndef NAME
37#define NAME(x) NAME_(x,test1)
38#endif
39#define NAMESTR__(x) #x
40#define NAMESTR_(x) NAMESTR__(x)
41#define NAMESTR(x) NAMESTR_(NAME(x))
c3e2f19b 42
ae5c498d
DD
43#include "nss_test.h"
44
45/* -------------------------------------------------- */
46/* Default Data. */
c3e2f19b 47
ae5c498d 48static struct passwd default_pwd_data[] =
c3e2f19b
UD
49 {
50#define PWD(u) \
51 { .pw_name = (char *) "name" #u, .pw_passwd = (char *) "*", .pw_uid = u, \
52 .pw_gid = 100, .pw_gecos = (char *) "*", .pw_dir = (char *) "*", \
53 .pw_shell = (char *) "*" }
c3e2f19b 54 PWD (30),
ae5c498d 55 PWD (100),
c3e2f19b
UD
56 PWD (200),
57 PWD (60),
58 PWD (20000)
59 };
cb62108e
SE
60#define default_npwd_data \
61 (sizeof (default_pwd_data) / sizeof (default_pwd_data[0]))
ae5c498d
DD
62
63static struct passwd *pwd_data = default_pwd_data;
64static int npwd_data = default_npwd_data;
65
66static struct group *grp_data = NULL;
67static int ngrp_data = 0;
68
69/* This function will get called, and once per session, look back into
70 the test case's executable for an init hook function, and call
71 it. */
72
73static int initted = 0;
74static void
75init(void)
76{
77 test_tables t;
78 int i;
79
80 if (initted)
81 return;
82 if (NAME(init_hook))
83 {
c4f50205 84 memset (&t, 0, sizeof (t));
ae5c498d
DD
85 NAME(init_hook)(&t);
86
87 if (t.pwd_table)
88 {
89 pwd_data = t.pwd_table;
90 for (i=0; ! PWD_ISLAST(& pwd_data[i]); i++)
91 ;
92 npwd_data = i;
93 }
94
95 if (t.grp_table)
96 {
97 grp_data = t.grp_table;
98 for (i=0; ! GRP_ISLAST(& grp_data[i]); i++)
99 ;
100 ngrp_data = i;
101 }
102 }
103 initted = 1;
104}
105
106/* -------------------------------------------------- */
107/* Password handling. */
c3e2f19b
UD
108
109static size_t pwd_iter;
110#define CURPWD pwd_data[pwd_iter]
111
112static pthread_mutex_t pwd_lock = PTHREAD_MUTEX_INITIALIZER;
113
c3e2f19b 114enum nss_status
ae5c498d 115NAME(setpwent) (int stayopen)
c3e2f19b 116{
ae5c498d 117 init();
c3e2f19b
UD
118 pwd_iter = 0;
119 return NSS_STATUS_SUCCESS;
120}
121
122
123enum nss_status
ae5c498d 124NAME(endpwent) (void)
c3e2f19b 125{
ae5c498d 126 init();
c3e2f19b
UD
127 return NSS_STATUS_SUCCESS;
128}
129
ae5c498d
DD
130static enum nss_status
131copy_passwd (struct passwd *result, struct passwd *local,
132 char *buffer, size_t buflen, int *errnop)
133{
134 struct alloc_buffer buf = alloc_buffer_create (buffer, buflen);
135
136 result->pw_name = alloc_buffer_maybe_copy_string (&buf, local->pw_name);
137 result->pw_passwd = alloc_buffer_maybe_copy_string (&buf, local->pw_passwd);
138 result->pw_uid = local->pw_uid;
139 result->pw_gid = local->pw_gid;
140 result->pw_gecos = alloc_buffer_maybe_copy_string (&buf, local->pw_gecos);
141 result->pw_dir = alloc_buffer_maybe_copy_string (&buf, local->pw_dir);
142 result->pw_shell = alloc_buffer_maybe_copy_string (&buf, local->pw_shell);
143
144 if (alloc_buffer_has_failed (&buf))
145 {
146 *errnop = ERANGE;
147 return NSS_STATUS_TRYAGAIN;
148 }
149
150 return NSS_STATUS_SUCCESS;
151}
c3e2f19b
UD
152
153enum nss_status
ae5c498d 154NAME(getpwent_r) (struct passwd *result, char *buffer, size_t buflen,
c3e2f19b
UD
155 int *errnop)
156{
c3e2f19b
UD
157 int res = NSS_STATUS_SUCCESS;
158
ae5c498d 159 init();
c3e2f19b
UD
160 pthread_mutex_lock (&pwd_lock);
161
162 if (pwd_iter >= npwd_data)
163 res = NSS_STATUS_NOTFOUND;
164 else
165 {
ae5c498d 166 res = copy_passwd (result, &CURPWD, buffer, buflen, errnop);
c3e2f19b
UD
167 ++pwd_iter;
168 }
169
170 pthread_mutex_unlock (&pwd_lock);
171
172 return res;
173}
174
175
176enum nss_status
ae5c498d 177NAME(getpwuid_r) (uid_t uid, struct passwd *result, char *buffer,
c3e2f19b
UD
178 size_t buflen, int *errnop)
179{
ae5c498d 180 init();
c3e2f19b
UD
181 for (size_t idx = 0; idx < npwd_data; ++idx)
182 if (pwd_data[idx].pw_uid == uid)
ae5c498d 183 return copy_passwd (result, &pwd_data[idx], buffer, buflen, errnop);
c3e2f19b
UD
184
185 return NSS_STATUS_NOTFOUND;
186}
187
188
189enum nss_status
ae5c498d 190NAME(getpwnam_r) (const char *name, struct passwd *result, char *buffer,
c3e2f19b
UD
191 size_t buflen, int *errnop)
192{
ae5c498d 193 init();
c3e2f19b 194 for (size_t idx = 0; idx < npwd_data; ++idx)
ae5c498d
DD
195 if (strcmp (pwd_data[idx].pw_name, name) == 0)
196 return copy_passwd (result, &pwd_data[idx], buffer, buflen, errnop);
197
198 return NSS_STATUS_NOTFOUND;
199}
200
201/* -------------------------------------------------- */
202/* Group handling. */
203
204static size_t grp_iter;
205#define CURGRP grp_data[grp_iter]
206
207static pthread_mutex_t grp_lock = PTHREAD_MUTEX_INITIALIZER;
208
209enum nss_status
210NAME(setgrent) (int stayopen)
211{
212 init();
213 grp_iter = 0;
214 return NSS_STATUS_SUCCESS;
215}
216
217
218enum nss_status
219NAME(endgrent) (void)
220{
221 init();
222 return NSS_STATUS_SUCCESS;
223}
224
225static enum nss_status
226copy_group (struct group *result, struct group *local,
227 char *buffer, size_t buflen, int *errnop)
228{
229 struct alloc_buffer buf = alloc_buffer_create (buffer, buflen);
230 char **memlist;
231 int i;
232
233 if (local->gr_mem)
234 {
235 i = 0;
236 while (local->gr_mem[i])
237 ++i;
238
239 memlist = alloc_buffer_alloc_array (&buf, char *, i + 1);
240
241 if (memlist) {
242 for (i = 0; local->gr_mem[i]; ++i)
243 memlist[i] = alloc_buffer_maybe_copy_string (&buf, local->gr_mem[i]);
244 memlist[i] = NULL;
245 }
246
247 result->gr_mem = memlist;
248 }
249 else
250 result->gr_mem = NULL;
251
252 result->gr_name = alloc_buffer_maybe_copy_string (&buf, local->gr_name);
253 result->gr_passwd = alloc_buffer_maybe_copy_string (&buf, local->gr_passwd);
254 result->gr_gid = local->gr_gid;
255
256 if (alloc_buffer_has_failed (&buf))
257 {
258 *errnop = ERANGE;
259 return NSS_STATUS_TRYAGAIN;
260 }
261
262 return NSS_STATUS_SUCCESS;
263}
264
265
266enum nss_status
267NAME(getgrent_r) (struct group *result, char *buffer, size_t buflen,
268 int *errnop)
269{
270 int res = NSS_STATUS_SUCCESS;
271
272 init();
273 pthread_mutex_lock (&grp_lock);
274
275 if (grp_iter >= ngrp_data)
276 res = NSS_STATUS_NOTFOUND;
277 else
278 {
279 res = copy_group (result, &CURGRP, buffer, buflen, errnop);
280 ++grp_iter;
281 }
282
283 pthread_mutex_unlock (&pwd_lock);
284
285 return res;
286}
287
288
289enum nss_status
290NAME(getgrgid_r) (gid_t gid, struct group *result, char *buffer,
291 size_t buflen, int *errnop)
292{
293 init();
294 for (size_t idx = 0; idx < ngrp_data; ++idx)
295 if (grp_data[idx].gr_gid == gid)
296 return copy_group (result, &grp_data[idx], buffer, buflen, errnop);
297
298 return NSS_STATUS_NOTFOUND;
299}
300
301
302enum nss_status
303NAME(getgrnam_r) (const char *name, struct group *result, char *buffer,
304 size_t buflen, int *errnop)
305{
306 init();
307 for (size_t idx = 0; idx < ngrp_data; ++idx)
c3e2f19b
UD
308 if (strcmp (pwd_data[idx].pw_name, name) == 0)
309 {
ae5c498d 310 return copy_group (result, &grp_data[idx], buffer, buflen, errnop);
c3e2f19b
UD
311 }
312
313 return NSS_STATUS_NOTFOUND;
314}