1 /* Copyright (C) 1997,1999,2001,2002,2003,2005 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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.
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.
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
25 #include <bits/libc-lock.h>
26 #include <rpcsvc/nis.h>
28 #include "nss-nisplus.h"
29 #include "nisplus-parser.h"
31 __libc_lock_define_initialized (static, lock
)
33 static nis_result
*result
;
34 nis_name pwd_tablename_val attribute_hidden
;
35 size_t pwd_tablename_len attribute_hidden
;
38 _nss_pwd_create_tablename (int *errnop
)
40 if (pwd_tablename_val
== NULL
)
42 const char *local_dir
= nis_local_directory ();
43 size_t local_dir_len
= strlen (local_dir
);
44 static const char prefix
[] = "passwd.org_dir.";
46 char *p
= malloc (sizeof (prefix
) + local_dir_len
);
47 if (pwd_tablename_val
== NULL
)
50 return NSS_STATUS_TRYAGAIN
;
53 memcpy (__stpcpy (p
, prefix
), local_dir
, local_dir_len
+ 1);
55 pwd_tablename_len
= sizeof (prefix
) - 1 + local_dir_len
;
57 atomic_write_barrier ();
59 pwd_tablename_val
= p
;
62 return NSS_STATUS_SUCCESS
;
67 _nss_nisplus_setpwent (int stayopen
)
69 enum nss_status status
= NSS_STATUS_SUCCESS
;
71 __libc_lock_lock (lock
);
75 nis_freeresult (result
);
79 if (pwd_tablename_val
== NULL
)
82 status
= _nss_pwd_create_tablename (&err
);
85 __libc_lock_unlock (lock
);
91 _nss_nisplus_endpwent (void)
93 __libc_lock_lock (lock
);
97 nis_freeresult (result
);
101 __libc_lock_unlock (lock
);
103 return NSS_STATUS_SUCCESS
;
106 static enum nss_status
107 internal_nisplus_getpwent_r (struct passwd
*pw
, char *buffer
, size_t buflen
,
112 /* Get the next entry until we found a correct one. */
115 nis_result
*saved_res
;
120 if (pwd_tablename_val
== NULL
)
122 enum nss_status status
= _nss_pwd_create_tablename (errnop
);
124 if (status
!= NSS_STATUS_SUCCESS
)
128 result
= nis_first_entry (pwd_tablename_val
);
129 if (niserr2nss (result
->status
) != NSS_STATUS_SUCCESS
)
130 return niserr2nss (result
->status
);
135 result
= nis_next_entry (pwd_tablename_val
, &result
->cookie
);
136 if (niserr2nss (result
->status
) != NSS_STATUS_SUCCESS
)
138 nis_freeresult (saved_res
);
139 return niserr2nss (result
->status
);
143 parse_res
= _nss_nisplus_parse_pwent (result
, pw
, buffer
,
145 if (__builtin_expect (parse_res
== -1, 0))
147 nis_freeresult (result
);
150 return NSS_STATUS_TRYAGAIN
;
154 nis_freeresult (saved_res
);
158 return NSS_STATUS_SUCCESS
;
162 _nss_nisplus_getpwent_r (struct passwd
*result
, char *buffer
, size_t buflen
,
167 __libc_lock_lock (lock
);
169 status
= internal_nisplus_getpwent_r (result
, buffer
, buflen
, errnop
);
171 __libc_lock_unlock (lock
);
177 _nss_nisplus_getpwnam_r (const char *name
, struct passwd
*pw
,
178 char *buffer
, size_t buflen
, int *errnop
)
182 if (pwd_tablename_val
== NULL
)
184 __libc_lock_lock (lock
);
186 enum nss_status status
= _nss_pwd_create_tablename (errnop
);
188 __libc_lock_unlock (lock
);
190 if (status
!= NSS_STATUS_SUCCESS
)
197 return NSS_STATUS_UNAVAIL
;
201 char buf
[strlen (name
) + 9 + pwd_tablename_len
];
204 snprintf (buf
, sizeof (buf
), "[name=%s],%s", name
, pwd_tablename_val
);
206 result
= nis_list (buf
, FOLLOW_PATH
| FOLLOW_LINKS
, NULL
, NULL
);
211 return NSS_STATUS_TRYAGAIN
;
214 if (__builtin_expect (niserr2nss (result
->status
) != NSS_STATUS_SUCCESS
, 0))
216 enum nss_status status
= niserr2nss (result
->status
);
218 __set_errno (olderr
);
220 nis_freeresult (result
);
224 parse_res
= _nss_nisplus_parse_pwent (result
, pw
, buffer
, buflen
, errnop
);
226 nis_freeresult (result
);
228 if (__builtin_expect (parse_res
< 1, 0))
233 return NSS_STATUS_TRYAGAIN
;
237 __set_errno (olderr
);
238 return NSS_STATUS_NOTFOUND
;
242 return NSS_STATUS_SUCCESS
;
246 _nss_nisplus_getpwuid_r (const uid_t uid
, struct passwd
*pw
,
247 char *buffer
, size_t buflen
, int *errnop
)
249 if (pwd_tablename_val
== NULL
)
251 __libc_lock_lock (lock
);
253 enum nss_status status
= _nss_pwd_create_tablename (errnop
);
255 __libc_lock_unlock (lock
);
257 if (status
!= NSS_STATUS_SUCCESS
)
263 char buf
[8 + 3 * sizeof (unsigned long int) + pwd_tablename_len
];
266 snprintf (buf
, sizeof (buf
), "[uid=%lu],%s",
267 (unsigned long int) uid
, pwd_tablename_val
);
269 result
= nis_list (buf
, FOLLOW_PATH
| FOLLOW_LINKS
, NULL
, NULL
);
274 return NSS_STATUS_TRYAGAIN
;
277 if (__builtin_expect (niserr2nss (result
->status
) != NSS_STATUS_SUCCESS
, 0))
279 enum nss_status status
= niserr2nss (result
->status
);
281 __set_errno (olderr
);
283 nis_freeresult (result
);
287 parse_res
= _nss_nisplus_parse_pwent (result
, pw
, buffer
, buflen
, errnop
);
289 nis_freeresult (result
);
291 if (__builtin_expect (parse_res
< 1, 0))
296 return NSS_STATUS_TRYAGAIN
;
300 __set_errno (olderr
);
301 return NSS_STATUS_NOTFOUND
;
305 return NSS_STATUS_SUCCESS
;