]>
sourceware.org Git - glibc.git/blob - nis/nss_compat/compat-pwd.c
1 /* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
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.
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.
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. */
27 #include <bits/libc-lock.h>
28 #include <rpcsvc/yp.h>
29 #include <rpcsvc/ypclnt.h>
30 #include <rpcsvc/nis.h>
34 #include "nss-nisplus.h"
35 #include "nisplus-parser.h"
37 static service_user
*ni
= NULL
;
38 static bool_t use_nisplus
= FALSE
; /* default: passwd_compat: nis */
39 static nis_name pwdtable
= NULL
; /* Name of the pwd table */
40 static size_t pwdtablelen
= 0;
42 /* Get the declaration of the parser function. */
44 #define STRUCTURE passwd
46 #include "../../nss/nss_files/files-parse.c"
48 /* Structure for remembering -@netgroup and -user members ... */
49 #define BLACKLIST_INITIAL_SIZE 512
50 #define BLACKLIST_INCREMENT 256
67 struct blacklist_t blacklist
;
69 struct __netgrent netgrdata
;
71 typedef struct ent_t ent_t
;
73 static ent_t ext_ent
= {0, 0, 0, NULL
, 0, NULL
, NULL
, {NULL
, 0, 0},
74 {NULL
, NULL
, 0, 0, NULL
, NULL
, NULL
}};
76 /* Protect global state against multiple changers. */
77 __libc_lock_define_initialized (static, lock
)
79 /* Prototypes for local functions. */
80 static void blacklist_store_name (const char *, ent_t
*);
81 static int in_blacklist (const char *, int, ent_t
*);
84 give_pwd_free (struct passwd
*pwd
)
86 if (pwd
->pw_name
!= NULL
)
88 if (pwd
->pw_passwd
!= NULL
)
89 free (pwd
->pw_passwd
);
90 if (pwd
->pw_gecos
!= NULL
)
92 if (pwd
->pw_dir
!= NULL
)
94 if (pwd
->pw_shell
!= NULL
)
97 memset (pwd
, '\0', sizeof (struct passwd
));
101 pwd_need_buflen (struct passwd
*pwd
)
105 if (pwd
->pw_passwd
!= NULL
)
106 len
+= strlen (pwd
->pw_passwd
) + 1;
108 if (pwd
->pw_gecos
!= NULL
)
109 len
+= strlen (pwd
->pw_gecos
) + 1;
111 if (pwd
->pw_dir
!= NULL
)
112 len
+= strlen (pwd
->pw_dir
) + 1;
114 if (pwd
->pw_shell
!= NULL
)
115 len
+= strlen (pwd
->pw_shell
) + 1;
121 copy_pwd_changes (struct passwd
*dest
, struct passwd
*src
,
122 char *buffer
, size_t buflen
)
124 if (src
->pw_passwd
!= NULL
&& strlen (src
->pw_passwd
))
127 dest
->pw_passwd
= strdup (src
->pw_passwd
);
128 else if (dest
->pw_passwd
&&
129 strlen (dest
->pw_passwd
) >= strlen (src
->pw_passwd
))
130 strcpy (dest
->pw_passwd
, src
->pw_passwd
);
133 dest
->pw_passwd
= buffer
;
134 strcpy (dest
->pw_passwd
, src
->pw_passwd
);
135 buffer
+= strlen (dest
->pw_passwd
) + 1;
136 buflen
= buflen
- (strlen (dest
->pw_passwd
) + 1);
140 if (src
->pw_gecos
!= NULL
&& strlen (src
->pw_gecos
))
143 dest
->pw_gecos
= strdup (src
->pw_gecos
);
144 else if (dest
->pw_gecos
&&
145 strlen (dest
->pw_gecos
) >= strlen (src
->pw_gecos
))
146 strcpy (dest
->pw_gecos
, src
->pw_gecos
);
149 dest
->pw_gecos
= buffer
;
150 strcpy (dest
->pw_gecos
, src
->pw_gecos
);
151 buffer
+= strlen (dest
->pw_gecos
) + 1;
152 buflen
= buflen
- (strlen (dest
->pw_gecos
) + 1);
155 if (src
->pw_dir
!= NULL
&& strlen (src
->pw_dir
))
158 dest
->pw_dir
= strdup (src
->pw_dir
);
159 else if (dest
->pw_dir
&&
160 strlen (dest
->pw_dir
) >= strlen (src
->pw_dir
))
161 strcpy (dest
->pw_dir
, src
->pw_dir
);
164 dest
->pw_dir
= buffer
;
165 strcpy (dest
->pw_dir
, src
->pw_dir
);
166 buffer
+= strlen (dest
->pw_dir
) + 1;
167 buflen
= buflen
- (strlen (dest
->pw_dir
) + 1);
171 if (src
->pw_shell
!= NULL
&& strlen (src
->pw_shell
))
174 dest
->pw_shell
= strdup (src
->pw_shell
);
175 else if (dest
->pw_shell
&&
176 strlen (dest
->pw_shell
) >= strlen (src
->pw_shell
))
177 strcpy (dest
->pw_shell
, src
->pw_shell
);
180 dest
->pw_shell
= buffer
;
181 strcpy (dest
->pw_shell
, src
->pw_shell
);
182 buffer
+= strlen (dest
->pw_shell
) + 1;
183 buflen
= buflen
- (strlen (dest
->pw_shell
) + 1);
188 static enum nss_status
189 internal_setpwent (ent_t
*ent
)
191 enum nss_status status
= NSS_STATUS_SUCCESS
;
193 ent
->nis
= ent
->first
= ent
->netgroup
= 0;
195 /* If something was left over free it. */
197 __internal_endnetgrent (&ent
->netgrdata
);
199 if (ent
->oldkey
!= NULL
)
206 if (ent
->result
!= NULL
)
208 nis_freeresult (ent
->result
);
212 if (pwdtable
== NULL
)
214 char buf
[20 + strlen (nis_local_directory ())];
217 p
= stpcpy (buf
, "passwd.org_dir.");
218 p
= stpcpy (p
, nis_local_directory ());
219 pwdtable
= strdup (buf
);
220 if (pwdtable
== NULL
)
221 return NSS_STATUS_TRYAGAIN
;
222 pwdtablelen
= strlen (pwdtable
);
225 ent
->blacklist
.current
= 0;
226 if (ent
->blacklist
.data
!= NULL
)
227 ent
->blacklist
.data
[0] = '\0';
229 if (ent
->stream
== NULL
)
231 ent
->stream
= fopen ("/etc/passwd", "r");
233 if (ent
->stream
== NULL
)
234 status
= errno
== EAGAIN
? NSS_STATUS_TRYAGAIN
: NSS_STATUS_UNAVAIL
;
237 /* We have to make sure the file is `closed on exec'. */
240 result
= flags
= fcntl (fileno (ent
->stream
), F_GETFD
, 0);
244 result
= fcntl (fileno (ent
->stream
), F_SETFD
, flags
);
248 /* Something went wrong. Close the stream and return a
250 fclose (ent
->stream
);
252 status
= NSS_STATUS_UNAVAIL
;
257 rewind (ent
->stream
);
259 give_pwd_free (&ent
->pwd
);
266 _nss_compat_setpwent (void)
268 enum nss_status result
;
270 __libc_lock_lock (lock
);
274 __nss_database_lookup ("passwd_compat", NULL
, "nis", &ni
);
275 use_nisplus
= (strcmp (ni
->name
, "nisplus") == 0);
278 result
= internal_setpwent (&ext_ent
);
280 __libc_lock_unlock (lock
);
286 static enum nss_status
287 internal_endpwent (ent_t
*ent
)
289 if (ent
->stream
!= NULL
)
291 fclose (ent
->stream
);
296 __internal_endnetgrent (&ent
->netgrdata
);
298 ent
->nis
= ent
->first
= ent
->netgroup
= 0;
300 if (ent
->oldkey
!= NULL
)
307 if (ent
->result
!= NULL
)
309 nis_freeresult (ent
->result
);
313 ent
->blacklist
.current
= 0;
314 if (ent
->blacklist
.data
!= NULL
)
315 ent
->blacklist
.data
[0] = '\0';
317 give_pwd_free (&ent
->pwd
);
319 return NSS_STATUS_SUCCESS
;
323 _nss_compat_endpwent (void)
325 enum nss_status result
;
327 __libc_lock_lock (lock
);
329 result
= internal_endpwent (&ext_ent
);
331 __libc_lock_unlock (lock
);
336 static enum nss_status
337 getpwent_next_nis_netgr (struct passwd
*result
, ent_t
*ent
, char *group
,
338 char *buffer
, size_t buflen
)
340 struct parser_data
*data
= (void *) buffer
;
341 char *ypdomain
, *host
, *user
, *domain
, *outval
, *p
, *p2
;
342 int status
, outvallen
;
345 if (yp_get_default_domain (&ypdomain
) != YPERR_SUCCESS
)
349 give_pwd_free (&ent
->pwd
);
350 return NSS_STATUS_UNAVAIL
;
353 if (ent
->first
== TRUE
)
355 memset (&ent
->netgrdata
, 0, sizeof (struct __netgrent
));
356 __internal_setnetgrent (group
, &ent
->netgrdata
);
365 saved_cursor
= ent
->netgrdata
.cursor
;
366 status
= __internal_getnetgrent_r (&host
, &user
, &domain
,
367 &ent
->netgrdata
, buffer
, buflen
);
370 __internal_endnetgrent (&ent
->netgrdata
);
372 give_pwd_free (&ent
->pwd
);
373 return NSS_STATUS_RETURN
;
376 if (user
== NULL
|| user
[0] == '-')
379 if (domain
!= NULL
&& strcmp (ypdomain
, domain
) != 0)
382 if (yp_match (ypdomain
, "passwd.byname", user
,
383 strlen (user
), &outval
, &outvallen
)
387 p2len
= pwd_need_buflen (&ent
->pwd
);
390 __set_errno (ERANGE
);
391 return NSS_STATUS_TRYAGAIN
;
393 p2
= buffer
+ (buflen
- p2len
);
395 p
= strncpy (buffer
, outval
, buflen
);
399 if ((parse_res
= _nss_files_parse_pwent (p
, result
, data
, buflen
)) == -1)
401 ent
->netgrdata
.cursor
= saved_cursor
;
402 return NSS_STATUS_TRYAGAIN
;
407 copy_pwd_changes (result
, &ent
->pwd
, p2
, p2len
);
412 return NSS_STATUS_SUCCESS
;
415 static enum nss_status
416 getpwent_next_nisplus_netgr (struct passwd
*result
, ent_t
*ent
, char *group
,
417 char *buffer
, size_t buflen
)
419 char *ypdomain
, *host
, *user
, *domain
, *p2
;
420 int status
, parse_res
;
424 /* Maybe we should use domainname here ? We need the current
425 domainname for the domain field in netgroups */
426 if (yp_get_default_domain (&ypdomain
) != YPERR_SUCCESS
)
430 give_pwd_free (&ent
->pwd
);
431 return NSS_STATUS_UNAVAIL
;
434 if (ent
->first
== TRUE
)
436 bzero (&ent
->netgrdata
, sizeof (struct __netgrent
));
437 __internal_setnetgrent (group
, &ent
->netgrdata
);
445 saved_cursor
= ent
->netgrdata
.cursor
;
446 status
= __internal_getnetgrent_r (&host
, &user
, &domain
,
447 &ent
->netgrdata
, buffer
, buflen
);
450 __internal_endnetgrent (&ent
->netgrdata
);
452 give_pwd_free (&ent
->pwd
);
453 return NSS_STATUS_RETURN
;
456 if (user
== NULL
|| user
[0] == '-')
459 if (domain
!= NULL
&& strcmp (ypdomain
, domain
) != 0)
462 p2len
= pwd_need_buflen (&ent
->pwd
);
465 __set_errno (ERANGE
);
466 return NSS_STATUS_TRYAGAIN
;
468 p2
= buffer
+ (buflen
- p2len
);
471 char buf
[strlen (user
) + 30 + pwdtablelen
];
472 sprintf(buf
, "[name=%s],%s", user
, pwdtable
);
473 nisres
= nis_list(buf
, FOLLOW_PATH
| FOLLOW_LINKS
, NULL
, NULL
);
475 if (niserr2nss (nisres
->status
) != NSS_STATUS_SUCCESS
)
477 nis_freeresult (nisres
);
480 if ((parse_res
= _nss_nisplus_parse_pwent (nisres
, result
, buffer
,
483 nis_freeresult (nisres
);
484 ent
->netgrdata
.cursor
= saved_cursor
;
485 return NSS_STATUS_TRYAGAIN
;
487 nis_freeresult (nisres
);
491 copy_pwd_changes (result
, &ent
->pwd
, p2
, p2len
);
496 return NSS_STATUS_SUCCESS
;
499 static enum nss_status
500 getpwent_next_netgr (struct passwd
*result
, ent_t
*ent
, char *group
,
501 char *buffer
, size_t buflen
)
504 return getpwent_next_nisplus_netgr (result
, ent
, group
, buffer
, buflen
);
506 return getpwent_next_nis_netgr (result
, ent
, group
, buffer
, buflen
);
509 static enum nss_status
510 getpwent_next_nisplus (struct passwd
*result
, ent_t
*ent
, char *buffer
,
517 p2len
= pwd_need_buflen (&ent
->pwd
);
520 __set_errno (ERANGE
);
521 return NSS_STATUS_TRYAGAIN
;
523 p2
= buffer
+ (buflen
- p2len
);
528 nis_result
*saved_res
;
533 saved_res
= ent
->result
;
535 ent
->result
= nis_first_entry(pwdtable
);
536 if (niserr2nss (ent
->result
->status
) != NSS_STATUS_SUCCESS
)
539 give_pwd_free (&ent
->pwd
);
540 return niserr2nss (ent
->result
->status
);
548 res
= nis_next_entry(pwdtable
, &ent
->result
->cookie
);
549 saved_res
= ent
->result
;
552 if (niserr2nss (ent
->result
->status
) != NSS_STATUS_SUCCESS
)
555 nis_freeresult (saved_res
);
556 give_pwd_free (&ent
->pwd
);
557 return niserr2nss (ent
->result
->status
);
560 if ((parse_res
= _nss_nisplus_parse_pwent (ent
->result
, result
, buffer
,
563 nis_freeresult (ent
->result
);
564 ent
->result
= saved_res
;
565 ent
->first
= saved_first
;
566 __set_errno (ERANGE
);
567 return NSS_STATUS_TRYAGAIN
;
572 nis_freeresult (saved_res
);
576 in_blacklist (result
->pw_name
, strlen (result
->pw_name
), ent
))
577 parse_res
= 0; /* if result->pw_name in blacklist,search next entry */
581 copy_pwd_changes (result
, &ent
->pwd
, p2
, p2len
);
583 return NSS_STATUS_SUCCESS
;
586 static enum nss_status
587 getpwent_next_nis (struct passwd
*result
, ent_t
*ent
, char *buffer
,
590 struct parser_data
*data
= (void *) buffer
;
591 char *domain
, *outkey
, *outval
, *p
, *p2
;
592 int outkeylen
, outvallen
, parse_res
;
595 if (yp_get_default_domain (&domain
) != YPERR_SUCCESS
)
598 give_pwd_free (&ent
->pwd
);
599 return NSS_STATUS_UNAVAIL
;
602 p2len
= pwd_need_buflen (&ent
->pwd
);
605 __set_errno (ERANGE
);
606 return NSS_STATUS_TRYAGAIN
;
608 p2
= buffer
+ (buflen
- p2len
);
618 if (yp_first (domain
, "passwd.byname", &outkey
, &outkeylen
,
619 &outval
, &outvallen
) != YPERR_SUCCESS
)
622 give_pwd_free (&ent
->pwd
);
623 return NSS_STATUS_UNAVAIL
;
627 saved_oldkey
= ent
->oldkey
;
628 saved_oldlen
= ent
->oldkeylen
;
629 ent
->oldkey
= outkey
;
630 ent
->oldkeylen
= outkeylen
;
635 if (yp_next (domain
, "passwd.byname", ent
->oldkey
, ent
->oldkeylen
,
636 &outkey
, &outkeylen
, &outval
, &outvallen
)
640 give_pwd_free (&ent
->pwd
);
641 return NSS_STATUS_NOTFOUND
;
645 saved_oldkey
= ent
->oldkey
;
646 saved_oldlen
= ent
->oldkeylen
;
647 ent
->oldkey
= outkey
;
648 ent
->oldkeylen
= outkeylen
;
651 /* Copy the found data to our buffer */
652 p
= strncpy (buffer
, outval
, buflen
);
654 /* ...and free the data. */
659 if ((parse_res
= _nss_files_parse_pwent (p
, result
, data
, buflen
)) == -1)
662 ent
->oldkey
= saved_oldkey
;
663 ent
->oldkeylen
= saved_oldlen
;
664 ent
->first
= saved_first
;
665 __set_errno (ERANGE
);
666 return NSS_STATUS_TRYAGAIN
;
674 in_blacklist (result
->pw_name
, strlen (result
->pw_name
), ent
))
679 copy_pwd_changes (result
, &ent
->pwd
, p2
, p2len
);
681 return NSS_STATUS_SUCCESS
;
684 /* This function handle the +user entrys in /etc/passwd */
685 static enum nss_status
686 getpwent_next_file_plususer (struct passwd
*result
, char *buffer
,
689 struct parser_data
*data
= (void *) buffer
;
695 memset (&pwd
, '\0', sizeof (struct passwd
));
697 copy_pwd_changes (&pwd
, result
, NULL
, 0);
699 plen
= pwd_need_buflen (&pwd
);
702 __set_errno (ERANGE
);
703 return NSS_STATUS_TRYAGAIN
;
705 p
= buffer
+ (buflen
- plen
);
708 if (use_nisplus
) /* Do the NIS+ query here */
711 char buf
[strlen (result
->pw_name
) + 24 + pwdtablelen
];
713 sprintf(buf
, "[name=%s],%s", &result
->pw_name
[1], pwdtable
);
714 res
= nis_list(buf
, FOLLOW_PATH
| FOLLOW_LINKS
, NULL
, NULL
);
715 if (niserr2nss (res
->status
) != NSS_STATUS_SUCCESS
)
717 enum nss_status status
= niserr2nss (res
->status
);
719 nis_freeresult (res
);
722 if ((parse_res
= _nss_nisplus_parse_pwent (res
, result
, buffer
,
725 nis_freeresult (res
);
726 __set_errno (ERANGE
);
727 return NSS_STATUS_TRYAGAIN
;
729 nis_freeresult (res
);
737 if (yp_get_default_domain (&domain
) != YPERR_SUCCESS
)
738 return NSS_STATUS_TRYAGAIN
;
740 if (yp_match (domain
, "passwd.byname", &result
->pw_name
[1],
741 strlen (result
->pw_name
) - 1, &outval
, &outvallen
)
743 return NSS_STATUS_TRYAGAIN
;
744 p
= strncpy (buffer
, outval
,
745 buflen
< (size_t) outvallen
? buflen
: (size_t) outvallen
);
749 if ((parse_res
= _nss_files_parse_pwent (p
, result
, data
, buflen
)) == -1)
751 __set_errno (ERANGE
);
752 return NSS_STATUS_TRYAGAIN
;
758 copy_pwd_changes (result
, &pwd
, p
, plen
);
759 give_pwd_free (&pwd
);
760 /* We found the entry. */
761 return NSS_STATUS_SUCCESS
;
765 /* Give buffer the old len back */
767 give_pwd_free (&pwd
);
769 return NSS_STATUS_RETURN
;
772 static enum nss_status
773 getpwent_next_file (struct passwd
*result
, ent_t
*ent
,
774 char *buffer
, size_t buflen
)
776 struct parser_data
*data
= (void *) buffer
;
785 fgetpos (ent
->stream
, &pos
);
786 p
= fgets (buffer
, buflen
, ent
->stream
);
788 return NSS_STATUS_NOTFOUND
;
790 /* Terminate the line for any case. */
791 buffer
[buflen
- 1] = '\0';
793 /* Skip leading blanks. */
797 while (*p
== '\0' || *p
== '#' || /* Ignore empty and comment lines. */
798 /* Parse the line. If it is invalid, loop to
799 get the next line of the file to parse. */
800 !(parse_res
= _nss_files_parse_pwent (p
, result
, data
, buflen
)));
804 /* The parser ran out of space. */
805 fsetpos (ent
->stream
, &pos
);
806 __set_errno (ERANGE
);
807 return NSS_STATUS_TRYAGAIN
;
810 if (result
->pw_name
[0] != '+' && result
->pw_name
[0] != '-')
811 /* This is a real entry. */
815 if (result
->pw_name
[0] == '-' && result
->pw_name
[1] == '@'
816 && result
->pw_name
[2] != '\0')
819 char *user
, *host
, *domain
;
820 struct __netgrent netgrdata
;
822 bzero (&netgrdata
, sizeof (struct __netgrent
));
823 __internal_setnetgrent (&result
->pw_name
[2], &netgrdata
);
824 while (__internal_getnetgrent_r (&host
, &user
, &domain
,
825 &netgrdata
, buf2
, sizeof (buf2
)))
827 if (user
!= NULL
&& user
[0] != '-')
828 blacklist_store_name (user
, ent
);
830 __internal_endnetgrent (&netgrdata
);
835 if (result
->pw_name
[0] == '+' && result
->pw_name
[1] == '@'
836 && result
->pw_name
[2] != '\0')
840 ent
->netgroup
= TRUE
;
842 copy_pwd_changes (&ent
->pwd
, result
, NULL
, 0);
844 status
= getpwent_next_netgr (result
, ent
, &result
->pw_name
[2],
846 if (status
== NSS_STATUS_RETURN
)
853 if (result
->pw_name
[0] == '-' && result
->pw_name
[1] != '\0'
854 && result
->pw_name
[1] != '@')
856 blacklist_store_name (&result
->pw_name
[1], ent
);
861 if (result
->pw_name
[0] == '+' && result
->pw_name
[1] != '\0'
862 && result
->pw_name
[1] != '@')
864 enum nss_status status
;
866 status
= getpwent_next_file_plususer (result
, buffer
, buflen
);
867 if (status
== NSS_STATUS_SUCCESS
) /* We found the entry. */
870 if (status
== NSS_STATUS_RETURN
) /* We couldn't parse the entry */
877 if (result
->pw_name
[0] == '+' && result
->pw_name
[1] == '\0')
881 copy_pwd_changes (&ent
->pwd
, result
, NULL
, 0);
884 return getpwent_next_nisplus (result
, ent
, buffer
, buflen
);
886 return getpwent_next_nis (result
, ent
, buffer
, buflen
);
890 return NSS_STATUS_SUCCESS
;
894 static enum nss_status
895 internal_getpwent_r (struct passwd
*pw
, ent_t
*ent
, char *buffer
,
902 /* We are searching members in a netgroup */
903 /* Since this is not the first call, we don't need the group name */
904 status
= getpwent_next_netgr (pw
, ent
, NULL
, buffer
, buflen
);
905 if (status
== NSS_STATUS_RETURN
)
906 return getpwent_next_file (pw
, ent
, buffer
, buflen
);
913 return getpwent_next_nisplus (pw
, ent
, buffer
, buflen
);
915 return getpwent_next_nis (pw
, ent
, buffer
, buflen
);
918 return getpwent_next_file (pw
, ent
, buffer
, buflen
);
922 _nss_compat_getpwent_r (struct passwd
*pwd
, char *buffer
,
925 enum nss_status status
= NSS_STATUS_SUCCESS
;
927 __libc_lock_lock (lock
);
931 __nss_database_lookup ("passwd_compat", NULL
, "nis", &ni
);
932 use_nisplus
= (strcmp (ni
->name
, "nisplus") == 0);
935 /* Be prepared that the setpwent function was not called before. */
936 if (ext_ent
.stream
== NULL
)
937 status
= internal_setpwent (&ext_ent
);
939 if (status
== NSS_STATUS_SUCCESS
)
940 status
= internal_getpwent_r (pwd
, &ext_ent
, buffer
, buflen
);
942 __libc_lock_unlock (lock
);
949 _nss_compat_getpwnam_r (const char *name
, struct passwd
*pwd
,
950 char *buffer
, size_t buflen
)
952 ent_t ent
= {0, 0, 0, NULL
, 0, NULL
, NULL
, {NULL
, 0, 0},
953 {NULL
, NULL
, 0, 0, NULL
, NULL
, NULL
}};
954 enum nss_status status
;
956 if (name
[0] == '-' || name
[0] == '+')
957 return NSS_STATUS_NOTFOUND
;
959 __libc_lock_lock (lock
);
963 __nss_database_lookup ("passwd_compat", NULL
, "nis", &ni
);
964 use_nisplus
= (strcmp (ni
->name
, "nisplus") == 0);
967 __libc_lock_unlock (lock
);
969 status
= internal_setpwent (&ent
);
970 if (status
!= NSS_STATUS_SUCCESS
)
973 while ((status
= internal_getpwent_r (pwd
, &ent
, buffer
, buflen
))
974 == NSS_STATUS_SUCCESS
)
975 if (strcmp (pwd
->pw_name
, name
) == 0)
978 internal_endpwent (&ent
);
984 _nss_compat_getpwuid_r (uid_t uid
, struct passwd
*pwd
,
985 char *buffer
, size_t buflen
)
987 ent_t ent
= {0, 0, 0, NULL
, 0, NULL
, NULL
, {NULL
, 0, 0},
988 {NULL
, NULL
, 0, 0, NULL
, NULL
, NULL
}};
989 enum nss_status status
;
991 __libc_lock_lock (lock
);
995 __nss_database_lookup ("passwd_compat", NULL
, "nis", &ni
);
996 use_nisplus
= (strcmp (ni
->name
, "nisplus") == 0);
999 __libc_lock_unlock (lock
);
1001 status
= internal_setpwent (&ent
);
1002 if (status
!= NSS_STATUS_SUCCESS
)
1005 while ((status
= internal_getpwent_r (pwd
, &ent
, buffer
, buflen
))
1006 == NSS_STATUS_SUCCESS
)
1007 if (pwd
->pw_uid
== uid
&& pwd
->pw_name
[0] != '+' && pwd
->pw_name
[0] != '-')
1010 internal_endpwent (&ent
);
1015 /* Support routines for remembering -@netgroup and -user entries.
1016 The names are stored in a single string with `|' as separator. */
1018 blacklist_store_name (const char *name
, ent_t
*ent
)
1020 int namelen
= strlen (name
);
1023 /* first call, setup cache */
1024 if (ent
->blacklist
.size
== 0)
1026 ent
->blacklist
.size
= MAX (BLACKLIST_INITIAL_SIZE
, 2 * namelen
);
1027 ent
->blacklist
.data
= malloc (ent
->blacklist
.size
);
1028 if (ent
->blacklist
.data
== NULL
)
1030 ent
->blacklist
.data
[0] = '|';
1031 ent
->blacklist
.data
[1] = '\0';
1032 ent
->blacklist
.current
= 1;
1036 if (in_blacklist (name
, namelen
, ent
))
1037 return; /* no duplicates */
1039 if (ent
->blacklist
.current
+ namelen
+ 1 >= ent
->blacklist
.size
)
1041 ent
->blacklist
.size
+= MAX (BLACKLIST_INCREMENT
, 2 * namelen
);
1042 tmp
= realloc (ent
->blacklist
.data
, ent
->blacklist
.size
);
1045 free (ent
->blacklist
.data
);
1046 ent
->blacklist
.size
= 0;
1049 ent
->blacklist
.data
= tmp
;
1053 tmp
= stpcpy (ent
->blacklist
.data
+ ent
->blacklist
.current
, name
);
1056 ent
->blacklist
.current
+= namelen
+ 1;
1061 /* returns TRUE if ent->blacklist contains name, else FALSE */
1063 in_blacklist (const char *name
, int namelen
, ent_t
*ent
)
1065 char buf
[namelen
+ 3];
1068 if (ent
->blacklist
.data
== NULL
)
1072 cp
= stpcpy (&buf
[1], name
);
1075 return strstr (ent
->blacklist
.data
, buf
) != NULL
;
This page took 0.094402 seconds and 6 git commands to generate.