diff options
author | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2004-07-15 12:53:49 +0000 |
---|---|---|
committer | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2004-07-15 12:53:49 +0000 |
commit | 48fb8b8392bda5c2a944489eb35572e5a9942bfa (patch) | |
tree | 863532a14dd40a1009cee3dac1dfa7fdd8bea653 | |
parent | 8d067d680796f811a61decb8bbd6f63bf05c1f41 (diff) | |
download | busybox-w32-48fb8b8392bda5c2a944489eb35572e5a9942bfa.tar.gz busybox-w32-48fb8b8392bda5c2a944489eb35572e5a9942bfa.tar.bz2 busybox-w32-48fb8b8392bda5c2a944489eb35572e5a9942bfa.zip |
Replace the old and somewhat buggy pwd_grp stuff with the shiny
new stuff mjn3 wrote for uClibc
git-svn-id: svn://busybox.net/trunk/busybox@8956 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | include/grp_.h | 113 | ||||
-rw-r--r-- | include/pwd_.h | 105 | ||||
-rw-r--r-- | include/shadow_.h | 162 | ||||
-rw-r--r-- | libpwdgrp/Makefile.in | 31 | ||||
-rw-r--r-- | libpwdgrp/__getgrent.c | 203 | ||||
-rw-r--r-- | libpwdgrp/__getpwent.c | 115 | ||||
-rw-r--r-- | libpwdgrp/fgetgrent.c | 35 | ||||
-rw-r--r-- | libpwdgrp/fgetpwent.c | 35 | ||||
-rw-r--r-- | libpwdgrp/getgrgid.c | 44 | ||||
-rw-r--r-- | libpwdgrp/getgrnam.c | 50 | ||||
-rw-r--r-- | libpwdgrp/getpw.c | 47 | ||||
-rw-r--r-- | libpwdgrp/getpwnam.c | 51 | ||||
-rw-r--r-- | libpwdgrp/getpwuid.c | 44 | ||||
-rw-r--r-- | libpwdgrp/grent.c | 54 | ||||
-rw-r--r-- | libpwdgrp/initgroups.c | 115 | ||||
-rw-r--r-- | libpwdgrp/putpwent.c | 39 | ||||
-rw-r--r-- | libpwdgrp/pwd_grp.c | 1116 | ||||
-rw-r--r-- | libpwdgrp/pwent.c | 58 | ||||
-rw-r--r-- | libpwdgrp/setgroups.c | 40 | ||||
-rw-r--r-- | libpwdgrp/shadow.c | 300 |
20 files changed, 1409 insertions, 1348 deletions
diff --git a/include/grp_.h b/include/grp_.h index 7cb0d4af6..b212b0b4a 100644 --- a/include/grp_.h +++ b/include/grp_.h | |||
@@ -1,39 +1,116 @@ | |||
1 | #ifndef __CONFIG_GRP_H | 1 | /* Copyright (C) 1991,92,95,96,97,98,99,2000,01 Free Software Foundation, Inc. |
2 | #define __CONFIG_GRP_H | 2 | This file is part of the GNU C Library. |
3 | |||
4 | The GNU C Library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 2.1 of the License, or (at your option) any later version. | ||
8 | |||
9 | The GNU C Library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General Public | ||
15 | License along with the GNU C Library; if not, write to the Free | ||
16 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
17 | 02111-1307 USA. */ | ||
18 | |||
19 | /* | ||
20 | * POSIX Standard: 9.2.1 Group Database Access <grp.h> | ||
21 | */ | ||
22 | |||
3 | 23 | ||
4 | #if !defined CONFIG_USE_BB_PWD_GRP | 24 | #if !defined CONFIG_USE_BB_PWD_GRP |
5 | #include <grp.h> | 25 | #include <grp.h> |
6 | 26 | ||
7 | #else | 27 | #else |
8 | 28 | ||
29 | #ifndef _GRP_H | ||
30 | #define _GRP_H 1 | ||
31 | |||
32 | |||
9 | #include <sys/types.h> | 33 | #include <sys/types.h> |
10 | #include <features.h> | 34 | #include <features.h> |
11 | #include <stdio.h> | 35 | #include <stdio.h> |
12 | 36 | ||
13 | 37 | ||
14 | /* The group structure */ | 38 | /* The group structure. */ |
15 | struct group | 39 | struct group |
16 | { | 40 | { |
17 | char *gr_name; /* Group name. */ | 41 | char *gr_name; /* Group name. */ |
18 | char *gr_passwd; /* Password. */ | 42 | char *gr_passwd; /* Password. */ |
19 | gid_t gr_gid; /* Group ID. */ | 43 | gid_t gr_gid; /* Group ID. */ |
20 | char **gr_mem; /* Member list. */ | 44 | char **gr_mem; /* Member list. */ |
21 | }; | 45 | }; |
22 | 46 | ||
23 | extern void setgrent __P ((void)); | ||
24 | extern void endgrent __P ((void)); | ||
25 | extern struct group * getgrent __P ((void)); | ||
26 | 47 | ||
27 | extern struct group * getgrgid __P ((__const gid_t gid)); | 48 | /* Rewind the group-file stream. */ |
28 | extern struct group * getgrnam __P ((__const char * name)); | 49 | extern void setgrent (void); |
50 | |||
51 | /* Close the group-file stream. */ | ||
52 | extern void endgrent (void); | ||
53 | |||
54 | /* Read an entry from the group-file stream, opening it if necessary. */ | ||
55 | extern struct group *getgrent (void); | ||
56 | |||
57 | /* Read a group entry from STREAM. */ | ||
58 | extern struct group *fgetgrent (FILE *__stream); | ||
59 | |||
60 | /* Write the given entry onto the given stream. */ | ||
61 | extern int putgrent (__const struct group *__restrict __p, | ||
62 | FILE *__restrict __f); | ||
63 | |||
64 | /* Search for an entry with a matching group ID. */ | ||
65 | extern struct group *getgrgid (gid_t __gid); | ||
66 | |||
67 | /* Search for an entry with a matching group name. */ | ||
68 | extern struct group *getgrnam (__const char *__name); | ||
69 | |||
70 | /* Reentrant versions of some of the functions above. | ||
71 | |||
72 | PLEASE NOTE: the `getgrent_r' function is not (yet) standardized. | ||
73 | The interface may change in later versions of this library. But | ||
74 | the interface is designed following the principals used for the | ||
75 | other reentrant functions so the chances are good this is what the | ||
76 | POSIX people would choose. */ | ||
77 | |||
78 | extern int getgrent_r (struct group *__restrict __resultbuf, | ||
79 | char *__restrict __buffer, size_t __buflen, | ||
80 | struct group **__restrict __result); | ||
81 | |||
82 | /* Search for an entry with a matching group ID. */ | ||
83 | extern int getgrgid_r (gid_t __gid, struct group *__restrict __resultbuf, | ||
84 | char *__restrict __buffer, size_t __buflen, | ||
85 | struct group **__restrict __result); | ||
86 | |||
87 | /* Search for an entry with a matching group name. */ | ||
88 | extern int getgrnam_r (__const char *__restrict __name, | ||
89 | struct group *__restrict __resultbuf, | ||
90 | char *__restrict __buffer, size_t __buflen, | ||
91 | struct group **__restrict __result); | ||
92 | |||
93 | /* Read a group entry from STREAM. This function is not standardized | ||
94 | an probably never will. */ | ||
95 | extern int fgetgrent_r (FILE *__restrict __stream, | ||
96 | struct group *__restrict __resultbuf, | ||
97 | char *__restrict __buffer, size_t __buflen, | ||
98 | struct group **__restrict __result); | ||
29 | 99 | ||
30 | extern struct group * fgetgrent __P ((FILE * file)); | 100 | /* Set the group set for the current user to GROUPS (N of them). */ |
101 | extern int setgroups (size_t __n, __const gid_t *__groups); | ||
31 | 102 | ||
32 | extern int setgroups __P ((size_t n, __const gid_t * groups)); | 103 | /* Store at most *NGROUPS members of the group set for USER into |
33 | extern int initgroups __P ((__const char * user, gid_t gid)); | 104 | *GROUPS. Also include GROUP. The actual number of groups found is |
105 | returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */ | ||
106 | extern int getgrouplist (__const char *__user, gid_t __group, | ||
107 | gid_t *__groups, int *__ngroups); | ||
34 | 108 | ||
35 | extern struct group * bb_getgrent __P ((int grp_fd)); | 109 | /* Initialize the group set for the current user |
110 | by reading the group database and using all groups | ||
111 | of which USER is a member. Also include GROUP. */ | ||
112 | extern int initgroups (__const char *__user, gid_t __group); | ||
36 | 113 | ||
37 | #endif /* USE_SYSTEM_PWD_GRP */ | ||
38 | #endif /* __CONFIG_GRP_H */ | ||
39 | 114 | ||
115 | #endif /* grp.h */ | ||
116 | #endif | ||
diff --git a/include/pwd_.h b/include/pwd_.h index 3f081e872..72151203e 100644 --- a/include/pwd_.h +++ b/include/pwd_.h | |||
@@ -1,11 +1,33 @@ | |||
1 | #ifndef __CONFIG_PWD_H | 1 | /* Copyright (C) 1991,92,95,96,97,98,99,2001 Free Software Foundation, Inc. |
2 | #define __CONFIG_PWD_H | 2 | This file is part of the GNU C Library. |
3 | |||
4 | The GNU C Library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 2.1 of the License, or (at your option) any later version. | ||
8 | |||
9 | The GNU C Library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General Public | ||
15 | License along with the GNU C Library; if not, write to the Free | ||
16 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
17 | 02111-1307 USA. */ | ||
18 | |||
19 | /* | ||
20 | * POSIX Standard: 9.2.2 User Database Access <pwd.h> | ||
21 | */ | ||
3 | 22 | ||
4 | #if !defined CONFIG_USE_BB_PWD_GRP | 23 | #if !defined CONFIG_USE_BB_PWD_GRP |
5 | #include <pwd.h> | 24 | #include <pwd.h> |
6 | 25 | ||
7 | #else | 26 | #else |
8 | 27 | ||
28 | #ifndef _PWD_H | ||
29 | #define _PWD_H 1 | ||
30 | |||
9 | #include <sys/types.h> | 31 | #include <sys/types.h> |
10 | #include <features.h> | 32 | #include <features.h> |
11 | #include <stdio.h> | 33 | #include <stdio.h> |
@@ -13,29 +35,72 @@ | |||
13 | /* The passwd structure. */ | 35 | /* The passwd structure. */ |
14 | struct passwd | 36 | struct passwd |
15 | { | 37 | { |
16 | char *pw_name; /* Username. */ | 38 | char *pw_name; /* Username. */ |
17 | char *pw_passwd; /* Password. */ | 39 | char *pw_passwd; /* Password. */ |
18 | uid_t pw_uid; /* User ID. */ | 40 | uid_t pw_uid; /* User ID. */ |
19 | gid_t pw_gid; /* Group ID. */ | 41 | gid_t pw_gid; /* Group ID. */ |
20 | char *pw_gecos; /* Real name. */ | 42 | char *pw_gecos; /* Real name. */ |
21 | char *pw_dir; /* Home directory. */ | 43 | char *pw_dir; /* Home directory. */ |
22 | char *pw_shell; /* Shell program. */ | 44 | char *pw_shell; /* Shell program. */ |
23 | }; | 45 | }; |
24 | 46 | ||
25 | extern void setpwent __P ((void)); | ||
26 | extern void endpwent __P ((void)); | ||
27 | extern struct passwd * getpwent __P ((void)); | ||
28 | 47 | ||
29 | extern int putpwent __P ((__const struct passwd * __p, FILE * __f)); | 48 | /* Rewind the password-file stream. */ |
30 | extern int getpw __P ((uid_t uid, char *buf)); | 49 | extern void setpwent (void); |
50 | |||
51 | /* Close the password-file stream. */ | ||
52 | extern void endpwent (void); | ||
53 | |||
54 | /* Read an entry from the password-file stream, opening it if necessary. */ | ||
55 | extern struct passwd *getpwent (void); | ||
56 | |||
57 | /* Read an entry from STREAM. */ | ||
58 | extern struct passwd *fgetpwent (FILE *__stream); | ||
59 | |||
60 | /* Write the given entry onto the given stream. */ | ||
61 | extern int putpwent (__const struct passwd *__restrict __p, | ||
62 | FILE *__restrict __f); | ||
63 | |||
64 | /* Search for an entry with a matching user ID. */ | ||
65 | extern struct passwd *getpwuid (uid_t __uid); | ||
66 | |||
67 | /* Search for an entry with a matching username. */ | ||
68 | extern struct passwd *getpwnam (__const char *__name); | ||
69 | |||
70 | /* Reentrant versions of some of the functions above. | ||
71 | |||
72 | PLEASE NOTE: the `getpwent_r' function is not (yet) standardized. | ||
73 | The interface may change in later versions of this library. But | ||
74 | the interface is designed following the principals used for the | ||
75 | other reentrant functions so the chances are good this is what the | ||
76 | POSIX people would choose. */ | ||
77 | |||
78 | extern int getpwent_r (struct passwd *__restrict __resultbuf, | ||
79 | char *__restrict __buffer, size_t __buflen, | ||
80 | struct passwd **__restrict __result); | ||
81 | |||
82 | extern int getpwuid_r (uid_t __uid, | ||
83 | struct passwd *__restrict __resultbuf, | ||
84 | char *__restrict __buffer, size_t __buflen, | ||
85 | struct passwd **__restrict __result); | ||
31 | 86 | ||
32 | extern struct passwd * fgetpwent __P ((FILE * file)); | 87 | extern int getpwnam_r (__const char *__restrict __name, |
88 | struct passwd *__restrict __resultbuf, | ||
89 | char *__restrict __buffer, size_t __buflen, | ||
90 | struct passwd **__restrict __result); | ||
33 | 91 | ||
34 | extern struct passwd * getpwuid __P ((__const uid_t)); | ||
35 | extern struct passwd * getpwnam __P ((__const char *)); | ||
36 | 92 | ||
37 | extern struct passwd * __getpwent __P ((__const int passwd_fd)); | 93 | /* Read an entry from STREAM. This function is not standardized and |
94 | probably never will. */ | ||
95 | extern int fgetpwent_r (FILE *__restrict __stream, | ||
96 | struct passwd *__restrict __resultbuf, | ||
97 | char *__restrict __buffer, size_t __buflen, | ||
98 | struct passwd **__restrict __result); | ||
38 | 99 | ||
39 | #endif /* USE_SYSTEM_PWD_GRP */ | 100 | /* Re-construct the password-file line for the given uid |
40 | #endif /* __CONFIG_PWD_H */ | 101 | in the given buffer. This knows the format that the caller |
102 | will expect, but this need not be the format of the password file. */ | ||
103 | extern int getpw (uid_t __uid, char *__buffer); | ||
41 | 104 | ||
105 | #endif /* pwd.h */ | ||
106 | #endif | ||
diff --git a/include/shadow_.h b/include/shadow_.h index a677d5262..1b14f0a7b 100644 --- a/include/shadow_.h +++ b/include/shadow_.h | |||
@@ -1,82 +1,98 @@ | |||
1 | /* | 1 | /* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. |
2 | * Copyright 1988 - 1994, Julianne Frances Haugh <jockgrrl@austin.rr.com> | 2 | This file is part of the GNU C Library. |
3 | * All rights reserved. | 3 | |
4 | * | 4 | The GNU C Library is free software; you can redistribute it and/or |
5 | * Redistribution and use in source and binary forms, with or without | 5 | modify it under the terms of the GNU Lesser General Public |
6 | * modification, are permitted provided that the following conditions | 6 | License as published by the Free Software Foundation; either |
7 | * are met: | 7 | version 2.1 of the License, or (at your option) any later version. |
8 | * 1. Redistributions of source code must retain the above copyright | 8 | |
9 | * notice, this list of conditions and the following disclaimer. | 9 | The GNU C Library is distributed in the hope that it will be useful, |
10 | * 2. Redistributions in binary form must reproduce the above copyright | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * notice, this list of conditions and the following disclaimer in the | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * documentation and/or other materials provided with the distribution. | 12 | Lesser General Public License for more details. |
13 | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors | 13 | |
14 | * may be used to endorse or promote products derived from this software | 14 | You should have received a copy of the GNU Lesser General Public |
15 | * without specific prior written permission. | 15 | License along with the GNU C Library; if not, write to the Free |
16 | * | 16 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
17 | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND | 17 | 02111-1307 USA. */ |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 18 | |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 19 | /* Declaration of types and functions for shadow password suite. */ |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE | 20 | |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 21 | #if !defined CONFIG_USE_BB_SHADOW |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | #ifndef _H_SHADOW | ||
31 | #define _H_SHADOW | ||
32 | |||
33 | |||
34 | #ifdef USE_SYSTEM_SHADOW | ||
35 | #include <shadow.h> | 22 | #include <shadow.h> |
36 | #else | 23 | #else |
37 | 24 | ||
38 | /* | 25 | #ifndef _SHADOW_H |
39 | * This information is not derived from AT&T licensed sources. Posted | 26 | #define _SHADOW_H 1 |
40 | * to the USENET 11/88, and updated 11/90 with information from SVR4. | 27 | |
41 | * | 28 | #include <stdio.h> |
42 | * $Id: shadow_.h,v 1.1 2002/06/23 04:24:20 andersen Exp $ | 29 | |
43 | */ | 30 | /* Paths to the user database files. */ |
44 | 31 | #ifndef _PATH_SHADOW | |
45 | typedef long sptime; | 32 | #define _PATH_SHADOW "/etc/shadow" |
46 | 33 | #endif | |
47 | /* | 34 | #define SHADOW _PATH_SHADOW |
48 | * Shadow password security file structure. | 35 | |
49 | */ | 36 | |
50 | 37 | /* Structure of the password file. */ | |
51 | struct spwd { | 38 | struct spwd |
52 | char *sp_namp; /* login name */ | 39 | { |
53 | char *sp_pwdp; /* encrypted password */ | 40 | char *sp_namp; /* Login name. */ |
54 | sptime sp_lstchg; /* date of last change */ | 41 | char *sp_pwdp; /* Encrypted password. */ |
55 | sptime sp_min; /* minimum number of days between changes */ | 42 | long int sp_lstchg; /* Date of last change. */ |
56 | sptime sp_max; /* maximum number of days between changes */ | 43 | long int sp_min; /* Minimum number of days between changes. */ |
57 | sptime sp_warn; /* number of days of warning before password | 44 | long int sp_max; /* Maximum number of days between changes. */ |
58 | expires */ | 45 | long int sp_warn; /* Number of days to warn user to change |
59 | sptime sp_inact; /* number of days after password expires | 46 | the password. */ |
60 | until the account becomes unusable. */ | 47 | long int sp_inact; /* Number of days the account may be |
61 | sptime sp_expire; /* days since 1/1/70 until account expires */ | 48 | inactive. */ |
62 | unsigned long sp_flag; /* reserved for future use */ | 49 | long int sp_expire; /* Number of days since 1970-01-01 until |
50 | account expires. */ | ||
51 | unsigned long int sp_flag; /* Reserved. */ | ||
63 | }; | 52 | }; |
64 | 53 | ||
65 | /* | ||
66 | * Shadow password security file functions. | ||
67 | */ | ||
68 | 54 | ||
69 | #include <stdio.h> /* for FILE */ | 55 | /* Open database for reading. */ |
56 | extern void setspent (void); | ||
57 | |||
58 | /* Close database. */ | ||
59 | extern void endspent (void); | ||
60 | |||
61 | /* Get next entry from database, perhaps after opening the file. */ | ||
62 | extern struct spwd *getspent (void); | ||
63 | |||
64 | /* Get shadow entry matching NAME. */ | ||
65 | extern struct spwd *getspnam (__const char *__name); | ||
66 | |||
67 | /* Read shadow entry from STRING. */ | ||
68 | extern struct spwd *sgetspent (__const char *__string); | ||
69 | |||
70 | /* Read next shadow entry from STREAM. */ | ||
71 | extern struct spwd *fgetspent (FILE *__stream); | ||
72 | |||
73 | /* Write line containing shadow password entry to stream. */ | ||
74 | extern int putspent (__const struct spwd *__p, FILE *__stream); | ||
75 | |||
76 | /* Reentrant versions of some of the functions above. */ | ||
77 | extern int getspent_r (struct spwd *__result_buf, char *__buffer, | ||
78 | size_t __buflen, struct spwd **__result); | ||
79 | |||
80 | extern int getspnam_r (__const char *__name, struct spwd *__result_buf, | ||
81 | char *__buffer, size_t __buflen, | ||
82 | struct spwd **__result)__THROW; | ||
83 | |||
84 | extern int sgetspent_r (__const char *__string, struct spwd *__result_buf, | ||
85 | char *__buffer, size_t __buflen, | ||
86 | struct spwd **__result); | ||
70 | 87 | ||
71 | extern struct spwd *getspent(void); | 88 | extern int fgetspent_r (FILE *__stream, struct spwd *__result_buf, |
72 | extern struct spwd *sgetspent(const char *); | 89 | char *__buffer, size_t __buflen, |
73 | extern struct spwd *fgetspent(FILE *); | 90 | struct spwd **__result); |
74 | extern void setspent(void); | 91 | /* Protect password file against multi writers. */ |
75 | extern void endspent(void); | 92 | extern int lckpwdf (void); |
76 | extern int putspent(const struct spwd *, FILE *); | ||
77 | extern struct spwd *getspnam(const char *name); | ||
78 | extern struct spwd *pwd_to_spwd(const struct passwd *pw); | ||
79 | 93 | ||
80 | #endif /* USE_LOCAL_SHADOW */ | 94 | /* Unlock password file. */ |
95 | extern int ulckpwdf (void); | ||
81 | 96 | ||
82 | #endif /* _H_SHADOW */ | 97 | #endif /* shadow.h */ |
98 | #endif | ||
diff --git a/libpwdgrp/Makefile.in b/libpwdgrp/Makefile.in index cb7cbde76..a79820252 100644 --- a/libpwdgrp/Makefile.in +++ b/libpwdgrp/Makefile.in | |||
@@ -22,14 +22,31 @@ ifndef $(LIBPWDGRP_DIR) | |||
22 | LIBPWDGRP_DIR:=$(TOPDIR)libpwdgrp/ | 22 | LIBPWDGRP_DIR:=$(TOPDIR)libpwdgrp/ |
23 | endif | 23 | endif |
24 | 24 | ||
25 | LIBPWDGRP-y:= | 25 | |
26 | LIBPWDGRP-$(CONFIG_USE_BB_PWD_GRP) += __getgrent.o __getgrent.o __getpwent.o\ | 26 | LIBPWDGRP_MSRC0:=$(LIBPWDGRP_DIR)pwd_grp.c |
27 | fgetgrent.o fgetpwent.o getgrgid.o getgrnam.o getpw.o getpwnam.o \ | 27 | LIBPWDGRP_MOBJ0-$(CONFIG_USE_BB_PWD_GRP):= fgetpwent_r.o fgetgrent_r.o \ |
28 | getpwuid.o grent.o initgroups.o putpwent.o pwent.o setgroups.o | 28 | fgetpwent.o fgetgrent.o getpwnam_r.o getgrnam_r.o getpwuid_r.o \ |
29 | LIBPWDGRP-$(CONFIG_USE_BB_SHADOW) += shadow.o | 29 | getgrgid_r.o getpwuid.o getgrgid.o getpwnam.o getgrnam.o getpw.o \ |
30 | getpwent_r.o getgrent_r.o getpwent.o getgrent.o \ | ||
31 | initgroups.o putpwent.o putgrent.o | ||
32 | LIBPWDGRP_MOBJS0=$(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP_MOBJ0-y)) | ||
33 | |||
34 | LIBPWDGRP_MSRC1:=$(LIBPWDGRP_DIR)pwd_grp.c | ||
35 | LIBPWDGRP_MOBJ1-$(CONFIG_USE_BB_PWD_GRP):= __parsepwent.o __parsegrent.o \ | ||
36 | __pgsreader.o fgetspent_r.o fgetspent.o sgetspent_r.o getspnam_r.o \ | ||
37 | getspnam.o getspent_r.o getspent.o sgetspent.o \ | ||
38 | putspent.o __parsespent.o # getspuid_r.o getspuid.o | ||
39 | LIBPWDGRP_MOBJS1=$(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP_MOBJ1-y)) | ||
30 | 40 | ||
31 | libraries-y+=$(LIBPWDGRP_DIR)$(LIBPWDGRP_AR) | 41 | libraries-y+=$(LIBPWDGRP_DIR)$(LIBPWDGRP_AR) |
32 | 42 | ||
33 | $(LIBPWDGRP_DIR)$(LIBPWDGRP_AR): $(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP-y)) | 43 | $(LIBPWDGRP_DIR)$(LIBPWDGRP_AR): $(LIBPWDGRP_MOBJS0) $(LIBPWDGRP_MOBJS1) |
34 | $(AR) -ro $@ $(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP-y)) | 44 | $(AR) -ro $@ $(LIBPWDGRP_MOBJS0) $(LIBPWDGRP_MOBJS1) |
45 | |||
46 | $(LIBPWDGRP_MOBJS0): $(LIBPWDGRP_MSRC0) | ||
47 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DL_$(notdir $*) -c $< -o $@ | ||
48 | |||
49 | $(LIBPWDGRP_MOBJS1): $(LIBPWDGRP_MSRC1) | ||
50 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DL_$(notdir $*) -c $< -o $@ | ||
51 | |||
35 | 52 | ||
diff --git a/libpwdgrp/__getgrent.c b/libpwdgrp/__getgrent.c deleted file mode 100644 index 3b54b9eec..000000000 --- a/libpwdgrp/__getgrent.c +++ /dev/null | |||
@@ -1,203 +0,0 @@ | |||
1 | /* | ||
2 | * __getgrent.c - This file is part of the libc-8086/grp package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <unistd.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <string.h> | ||
24 | |||
25 | #include "busybox.h" | ||
26 | #include "grp_.h" | ||
27 | |||
28 | /* | ||
29 | * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer | ||
30 | * so that lines of any length can be used. On very very small systems, | ||
31 | * you may want to leave this undefined because it will make the grp functions | ||
32 | * somewhat larger (because of the inclusion of malloc and the code necessary). | ||
33 | * On larger systems, you will want to define this, because grp will _not_ | ||
34 | * deal with long lines gracefully (they will be skipped). | ||
35 | */ | ||
36 | #undef GR_SCALE_DYNAMIC | ||
37 | |||
38 | #ifndef GR_SCALE_DYNAMIC | ||
39 | /* | ||
40 | * If scaling is not dynamic, the buffers will be statically allocated, and | ||
41 | * maximums must be chosen. GR_MAX_LINE_LEN is the maximum number of | ||
42 | * characters per line in the group file. GR_MAX_MEMBERS is the maximum | ||
43 | * number of members of any given group. | ||
44 | */ | ||
45 | #define GR_MAX_LINE_LEN 128 | ||
46 | /* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */ | ||
47 | #define GR_MAX_MEMBERS 11 | ||
48 | |||
49 | #endif /* !GR_SCALE_DYNAMIC */ | ||
50 | |||
51 | |||
52 | /* | ||
53 | * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate | ||
54 | * space for it's GID array before calling setgroups(). This is probably | ||
55 | * unnecessary scalage, so it's undefined by default. | ||
56 | */ | ||
57 | #undef GR_DYNAMIC_GROUP_LIST | ||
58 | |||
59 | #ifndef GR_DYNAMIC_GROUP_LIST | ||
60 | /* | ||
61 | * GR_MAX_GROUPS is the size of the static array initgroups() uses for | ||
62 | * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined. | ||
63 | */ | ||
64 | #define GR_MAX_GROUPS 64 | ||
65 | |||
66 | #endif /* !GR_DYNAMIC_GROUP_LIST */ | ||
67 | |||
68 | |||
69 | /* | ||
70 | * This is the core group-file read function. It behaves exactly like | ||
71 | * getgrent() except that it is passed a file descriptor. getgrent() | ||
72 | * is just a wrapper for this function. | ||
73 | */ | ||
74 | struct group *bb_getgrent(int grp_fd) | ||
75 | { | ||
76 | #ifndef GR_SCALE_DYNAMIC | ||
77 | static char line_buff[GR_MAX_LINE_LEN]; | ||
78 | static char *members[GR_MAX_MEMBERS]; | ||
79 | #else | ||
80 | static char *line_buff = NULL; | ||
81 | static char **members = NULL; | ||
82 | short line_index; | ||
83 | short buff_size; | ||
84 | #endif | ||
85 | static struct group group; | ||
86 | register char *ptr; | ||
87 | char *field_begin; | ||
88 | short member_num; | ||
89 | char *endptr; | ||
90 | int line_len; | ||
91 | |||
92 | |||
93 | /* We use the restart label to handle malformatted lines */ | ||
94 | restart: | ||
95 | #ifdef GR_SCALE_DYNAMIC | ||
96 | line_index = 0; | ||
97 | buff_size = 256; | ||
98 | #endif | ||
99 | |||
100 | #ifndef GR_SCALE_DYNAMIC | ||
101 | /* Read the line into the static buffer */ | ||
102 | if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) | ||
103 | return NULL; | ||
104 | field_begin = strchr(line_buff, '\n'); | ||
105 | if (field_begin != NULL) | ||
106 | lseek(grp_fd, (long) (1 + field_begin - (line_buff + line_len)), | ||
107 | SEEK_CUR); | ||
108 | else { /* The line is too long - skip it :-\ */ | ||
109 | |||
110 | do { | ||
111 | if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) | ||
112 | return NULL; | ||
113 | } while (!(field_begin = strchr(line_buff, '\n'))); | ||
114 | lseek(grp_fd, (long) ((field_begin - line_buff) - line_len + 1), | ||
115 | SEEK_CUR); | ||
116 | goto restart; | ||
117 | } | ||
118 | if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' || | ||
119 | *line_buff == '\t') | ||
120 | goto restart; | ||
121 | *field_begin = '\0'; | ||
122 | |||
123 | #else /* !GR_SCALE_DYNAMIC */ | ||
124 | line_buff = realloc(line_buff, buff_size); | ||
125 | while (1) { | ||
126 | if ((line_len = read(grp_fd, line_buff + line_index, | ||
127 | buff_size - line_index)) <= 0) | ||
128 | return NULL; | ||
129 | field_begin = strchr(line_buff, '\n'); | ||
130 | if (field_begin != NULL) { | ||
131 | lseek(grp_fd, | ||
132 | (long) (1 + field_begin - | ||
133 | (line_len + line_index + line_buff)), SEEK_CUR); | ||
134 | *field_begin = '\0'; | ||
135 | if (*line_buff == '#' || *line_buff == ' ' | ||
136 | || *line_buff == '\n' || *line_buff == '\t') | ||
137 | goto restart; | ||
138 | break; | ||
139 | } else { /* Allocate some more space */ | ||
140 | |||
141 | line_index = buff_size; | ||
142 | buff_size += 256; | ||
143 | line_buff = realloc(line_buff, buff_size); | ||
144 | } | ||
145 | } | ||
146 | #endif /* GR_SCALE_DYNAMIC */ | ||
147 | |||
148 | /* Now parse the line */ | ||
149 | group.gr_name = line_buff; | ||
150 | ptr = strchr(line_buff, ':'); | ||
151 | if (ptr == NULL) | ||
152 | goto restart; | ||
153 | *ptr++ = '\0'; | ||
154 | |||
155 | group.gr_passwd = ptr; | ||
156 | ptr = strchr(ptr, ':'); | ||
157 | if (ptr == NULL) | ||
158 | goto restart; | ||
159 | *ptr++ = '\0'; | ||
160 | |||
161 | field_begin = ptr; | ||
162 | ptr = strchr(ptr, ':'); | ||
163 | if (ptr == NULL) | ||
164 | goto restart; | ||
165 | *ptr++ = '\0'; | ||
166 | |||
167 | group.gr_gid = (gid_t) strtoul(field_begin, &endptr, 10); | ||
168 | if (*endptr != '\0') | ||
169 | goto restart; | ||
170 | |||
171 | member_num = 0; | ||
172 | field_begin = ptr; | ||
173 | |||
174 | #ifndef GR_SCALE_DYNAMIC | ||
175 | while ((ptr = strchr(ptr, ',')) != NULL) { | ||
176 | *ptr = '\0'; | ||
177 | ptr++; | ||
178 | members[member_num] = field_begin; | ||
179 | field_begin = ptr; | ||
180 | member_num++; | ||
181 | } | ||
182 | if (*field_begin == '\0') | ||
183 | members[member_num] = NULL; | ||
184 | else { | ||
185 | members[member_num] = field_begin; | ||
186 | members[member_num + 1] = NULL; | ||
187 | } | ||
188 | #else /* !GR_SCALE_DYNAMIC */ | ||
189 | free(members); | ||
190 | members = (char **) malloc((member_num + 1) * sizeof(char *)); | ||
191 | for ( ; field_begin && *field_begin != '\0'; field_begin = ptr) { | ||
192 | if ((ptr = strchr(field_begin, ',')) != NULL) | ||
193 | *ptr++ = '\0'; | ||
194 | members[member_num++] = field_begin; | ||
195 | members = (char **) realloc(members, | ||
196 | (member_num + 1) * sizeof(char *)); | ||
197 | } | ||
198 | members[member_num] = NULL; | ||
199 | #endif /* GR_SCALE_DYNAMIC */ | ||
200 | |||
201 | group.gr_mem = members; | ||
202 | return &group; | ||
203 | } | ||
diff --git a/libpwdgrp/__getpwent.c b/libpwdgrp/__getpwent.c deleted file mode 100644 index 09ed63139..000000000 --- a/libpwdgrp/__getpwent.c +++ /dev/null | |||
@@ -1,115 +0,0 @@ | |||
1 | /* | ||
2 | * __getpwent.c - This file is part of the libc-8086/pwd package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <stdlib.h> | ||
22 | #include <unistd.h> | ||
23 | #include <string.h> | ||
24 | #include <fcntl.h> | ||
25 | |||
26 | #include "pwd_.h" | ||
27 | #include "busybox.h" | ||
28 | |||
29 | #define PWD_BUFFER_SIZE 256 | ||
30 | |||
31 | /* This isn't as flash as my previous version -- it doesn't dynamically | ||
32 | scale down the gecos on too-long lines, but it also makes fewer syscalls, | ||
33 | so it's probably nicer. Write me if you want the old version. Maybe I | ||
34 | should include it as a build-time option... ? | ||
35 | -Nat <ndf@linux.mit.edu> */ | ||
36 | |||
37 | struct passwd *__getpwent(int pwd_fd) | ||
38 | { | ||
39 | static char line_buff[PWD_BUFFER_SIZE]; | ||
40 | static struct passwd passwd; | ||
41 | char *field_begin; | ||
42 | char *endptr; | ||
43 | char *gid_ptr=NULL; | ||
44 | char *uid_ptr=NULL; | ||
45 | int line_len; | ||
46 | int i; | ||
47 | |||
48 | /* We use the restart label to handle malformatted lines */ | ||
49 | restart: | ||
50 | /* Read the passwd line into the static buffer using a minimal of | ||
51 | syscalls. */ | ||
52 | if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0) | ||
53 | return NULL; | ||
54 | field_begin = strchr(line_buff, '\n'); | ||
55 | if (field_begin != NULL) | ||
56 | lseek(pwd_fd, (long) (1 + field_begin - (line_buff + line_len)), | ||
57 | SEEK_CUR); | ||
58 | else { /* The line is too long - skip it. :-\ */ | ||
59 | |||
60 | do { | ||
61 | if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0) | ||
62 | return NULL; | ||
63 | } while (!(field_begin = strchr(line_buff, '\n'))); | ||
64 | lseek(pwd_fd, (long) (field_begin - line_buff) - line_len + 1, | ||
65 | SEEK_CUR); | ||
66 | goto restart; | ||
67 | } | ||
68 | if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' || | ||
69 | *line_buff == '\t') | ||
70 | goto restart; | ||
71 | *field_begin = '\0'; | ||
72 | |||
73 | /* We've read the line; now parse it. */ | ||
74 | field_begin = line_buff; | ||
75 | for (i = 0; i < 7; i++) { | ||
76 | switch (i) { | ||
77 | case 0: | ||
78 | passwd.pw_name = field_begin; | ||
79 | break; | ||
80 | case 1: | ||
81 | passwd.pw_passwd = field_begin; | ||
82 | break; | ||
83 | case 2: | ||
84 | uid_ptr = field_begin; | ||
85 | break; | ||
86 | case 3: | ||
87 | gid_ptr = field_begin; | ||
88 | break; | ||
89 | case 4: | ||
90 | passwd.pw_gecos = field_begin; | ||
91 | break; | ||
92 | case 5: | ||
93 | passwd.pw_dir = field_begin; | ||
94 | break; | ||
95 | case 6: | ||
96 | passwd.pw_shell = field_begin; | ||
97 | break; | ||
98 | } | ||
99 | if (i < 6) { | ||
100 | field_begin = strchr(field_begin, ':'); | ||
101 | if (field_begin == NULL) | ||
102 | goto restart; | ||
103 | *field_begin++ = '\0'; | ||
104 | } | ||
105 | } | ||
106 | passwd.pw_gid = (gid_t) strtoul(gid_ptr, &endptr, 10); | ||
107 | if (*endptr != '\0') | ||
108 | goto restart; | ||
109 | |||
110 | passwd.pw_uid = (uid_t) strtoul(uid_ptr, &endptr, 10); | ||
111 | if (*endptr != '\0') | ||
112 | goto restart; | ||
113 | |||
114 | return &passwd; | ||
115 | } | ||
diff --git a/libpwdgrp/fgetgrent.c b/libpwdgrp/fgetgrent.c deleted file mode 100644 index 77c2884ed..000000000 --- a/libpwdgrp/fgetgrent.c +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* | ||
2 | * fgetgrent.c - This file is part of the libc-8086/grp package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "busybox.h" | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <errno.h> | ||
25 | #include "grp_.h" | ||
26 | |||
27 | struct group *fgetgrent(FILE * file) | ||
28 | { | ||
29 | if (file == NULL) { | ||
30 | errno = EINTR; | ||
31 | return NULL; | ||
32 | } | ||
33 | |||
34 | return bb_getgrent(fileno(file)); | ||
35 | } | ||
diff --git a/libpwdgrp/fgetpwent.c b/libpwdgrp/fgetpwent.c deleted file mode 100644 index 74bf922d7..000000000 --- a/libpwdgrp/fgetpwent.c +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* | ||
2 | * fgetpwent.c - This file is part of the libc-8086/pwd package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "busybox.h" | ||
22 | |||
23 | #include <errno.h> | ||
24 | #include <stdio.h> | ||
25 | #include "pwd_.h" | ||
26 | |||
27 | struct passwd *fgetpwent(FILE * file) | ||
28 | { | ||
29 | if (file == NULL) { | ||
30 | errno = EINTR; | ||
31 | return NULL; | ||
32 | } | ||
33 | |||
34 | return __getpwent(fileno(file)); | ||
35 | } | ||
diff --git a/libpwdgrp/getgrgid.c b/libpwdgrp/getgrgid.c deleted file mode 100644 index 4502e2b42..000000000 --- a/libpwdgrp/getgrgid.c +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | /* | ||
2 | * getgrgid.c - This file is part of the libc-8086/grp package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "busybox.h" | ||
22 | |||
23 | #include <sys/types.h> | ||
24 | #include <unistd.h> | ||
25 | #include <fcntl.h> | ||
26 | #include "grp_.h" | ||
27 | |||
28 | struct group *getgrgid(const gid_t gid) | ||
29 | { | ||
30 | struct group *group; | ||
31 | int grp_fd; | ||
32 | |||
33 | if ((grp_fd = open(bb_path_group_file, O_RDONLY)) < 0) | ||
34 | return NULL; | ||
35 | |||
36 | while ((group = bb_getgrent(grp_fd)) != NULL) | ||
37 | if (group->gr_gid == gid) { | ||
38 | close(grp_fd); | ||
39 | return group; | ||
40 | } | ||
41 | |||
42 | close(grp_fd); | ||
43 | return NULL; | ||
44 | } | ||
diff --git a/libpwdgrp/getgrnam.c b/libpwdgrp/getgrnam.c deleted file mode 100644 index 766b7bc5d..000000000 --- a/libpwdgrp/getgrnam.c +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | /* | ||
2 | * getgrnam.c - This file is part of the libc-8086/grp package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "busybox.h" | ||
22 | |||
23 | #include <unistd.h> | ||
24 | #include <string.h> | ||
25 | #include <errno.h> | ||
26 | #include <fcntl.h> | ||
27 | #include "grp_.h" | ||
28 | |||
29 | struct group *getgrnam(const char *name) | ||
30 | { | ||
31 | int grp_fd; | ||
32 | struct group *group; | ||
33 | |||
34 | if (name == NULL) { | ||
35 | errno = EINVAL; | ||
36 | return NULL; | ||
37 | } | ||
38 | |||
39 | if ((grp_fd = open(bb_path_group_file, O_RDONLY)) < 0) | ||
40 | return NULL; | ||
41 | |||
42 | while ((group = bb_getgrent(grp_fd)) != NULL) | ||
43 | if (!strcmp(group->gr_name, name)) { | ||
44 | close(grp_fd); | ||
45 | return group; | ||
46 | } | ||
47 | |||
48 | close(grp_fd); | ||
49 | return NULL; | ||
50 | } | ||
diff --git a/libpwdgrp/getpw.c b/libpwdgrp/getpw.c deleted file mode 100644 index 8494a6ae9..000000000 --- a/libpwdgrp/getpw.c +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* | ||
2 | * getpw.c - This file is part of the libc-8086/pwd package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "busybox.h" | ||
22 | |||
23 | #include <sys/types.h> | ||
24 | #include <errno.h> | ||
25 | #include <stdio.h> | ||
26 | #include "pwd_.h" | ||
27 | |||
28 | int getpw(uid_t uid, char *buf) | ||
29 | { | ||
30 | struct passwd *passwd; | ||
31 | |||
32 | if (buf == NULL) { | ||
33 | errno = EINVAL; | ||
34 | return -1; | ||
35 | } | ||
36 | if ((passwd = getpwuid(uid)) == NULL) | ||
37 | return -1; | ||
38 | |||
39 | if (sprintf (buf, "%s:%s:%u:%u:%s:%s:%s", passwd->pw_name, passwd->pw_passwd, | ||
40 | passwd->pw_gid, passwd->pw_uid, passwd->pw_gecos, passwd->pw_dir, | ||
41 | passwd->pw_shell) < 0) { | ||
42 | errno = ENOBUFS; | ||
43 | return -1; | ||
44 | } | ||
45 | |||
46 | return 0; | ||
47 | } | ||
diff --git a/libpwdgrp/getpwnam.c b/libpwdgrp/getpwnam.c deleted file mode 100644 index f4caeeab1..000000000 --- a/libpwdgrp/getpwnam.c +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /* | ||
2 | * getpwnam.c - This file is part of the libc-8086/pwd package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "busybox.h" | ||
22 | |||
23 | #include <unistd.h> | ||
24 | #include <string.h> | ||
25 | #include <errno.h> | ||
26 | #include <fcntl.h> | ||
27 | #include "pwd_.h" | ||
28 | |||
29 | |||
30 | struct passwd *getpwnam(const char *name) | ||
31 | { | ||
32 | int passwd_fd; | ||
33 | struct passwd *passwd; | ||
34 | |||
35 | if (name == NULL) { | ||
36 | errno = EINVAL; | ||
37 | return NULL; | ||
38 | } | ||
39 | |||
40 | if ((passwd_fd = open(bb_path_passwd_file, O_RDONLY)) < 0) | ||
41 | return NULL; | ||
42 | |||
43 | while ((passwd = __getpwent(passwd_fd)) != NULL) | ||
44 | if (!strcmp(passwd->pw_name, name)) { | ||
45 | close(passwd_fd); | ||
46 | return passwd; | ||
47 | } | ||
48 | |||
49 | close(passwd_fd); | ||
50 | return NULL; | ||
51 | } | ||
diff --git a/libpwdgrp/getpwuid.c b/libpwdgrp/getpwuid.c deleted file mode 100644 index 7fa7ed956..000000000 --- a/libpwdgrp/getpwuid.c +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | /* | ||
2 | * getpwuid.c - This file is part of the libc-8086/pwd package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <stdlib.h> | ||
22 | #include <unistd.h> | ||
23 | #include <fcntl.h> | ||
24 | |||
25 | #include "busybox.h" | ||
26 | #include "pwd_.h" | ||
27 | |||
28 | struct passwd *getpwuid(uid_t uid) | ||
29 | { | ||
30 | int passwd_fd; | ||
31 | struct passwd *passwd; | ||
32 | |||
33 | if ((passwd_fd = open(bb_path_passwd_file, O_RDONLY)) < 0) | ||
34 | return NULL; | ||
35 | |||
36 | while ((passwd = __getpwent(passwd_fd)) != NULL) | ||
37 | if (passwd->pw_uid == uid) { | ||
38 | close(passwd_fd); | ||
39 | return passwd; | ||
40 | } | ||
41 | |||
42 | close(passwd_fd); | ||
43 | return NULL; | ||
44 | } | ||
diff --git a/libpwdgrp/grent.c b/libpwdgrp/grent.c deleted file mode 100644 index 753026c29..000000000 --- a/libpwdgrp/grent.c +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * grent.c - This file is part of the libc-8086/grp package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | * setgrent(), endgrent(), and getgrent() are mutually-dependent functions, | ||
23 | * so they are all included in the same object file, and thus all linked | ||
24 | * in together. | ||
25 | */ | ||
26 | |||
27 | #include "busybox.h" | ||
28 | |||
29 | #include <unistd.h> | ||
30 | #include <fcntl.h> | ||
31 | #include "grp_.h" | ||
32 | |||
33 | static int grp_fd = -1; | ||
34 | |||
35 | void setgrent(void) | ||
36 | { | ||
37 | if (grp_fd != -1) | ||
38 | close(grp_fd); | ||
39 | grp_fd = open(bb_path_group_file, O_RDONLY); | ||
40 | } | ||
41 | |||
42 | void endgrent(void) | ||
43 | { | ||
44 | if (grp_fd != -1) | ||
45 | close(grp_fd); | ||
46 | grp_fd = -1; | ||
47 | } | ||
48 | |||
49 | struct group *getgrent(void) | ||
50 | { | ||
51 | if (grp_fd == -1) | ||
52 | return NULL; | ||
53 | return bb_getgrent(grp_fd); | ||
54 | } | ||
diff --git a/libpwdgrp/initgroups.c b/libpwdgrp/initgroups.c deleted file mode 100644 index 6577ec62f..000000000 --- a/libpwdgrp/initgroups.c +++ /dev/null | |||
@@ -1,115 +0,0 @@ | |||
1 | /* | ||
2 | * initgroups.c - This file is part of the libc-8086/grp package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "busybox.h" | ||
22 | |||
23 | #include <unistd.h> | ||
24 | #include <string.h> | ||
25 | #include <fcntl.h> | ||
26 | #include "grp_.h" | ||
27 | |||
28 | /* | ||
29 | * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer | ||
30 | * so that lines of any length can be used. On very very small systems, | ||
31 | * you may want to leave this undefined because it will make the grp functions | ||
32 | * somewhat larger (because of the inclusion of malloc and the code necessary). | ||
33 | * On larger systems, you will want to define this, because grp will _not_ | ||
34 | * deal with long lines gracefully (they will be skipped). | ||
35 | */ | ||
36 | #undef GR_SCALE_DYNAMIC | ||
37 | |||
38 | #ifndef GR_SCALE_DYNAMIC | ||
39 | /* | ||
40 | * If scaling is not dynamic, the buffers will be statically allocated, and | ||
41 | * maximums must be chosen. GR_MAX_LINE_LEN is the maximum number of | ||
42 | * characters per line in the group file. GR_MAX_MEMBERS is the maximum | ||
43 | * number of members of any given group. | ||
44 | */ | ||
45 | #define GR_MAX_LINE_LEN 128 | ||
46 | /* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */ | ||
47 | #define GR_MAX_MEMBERS 11 | ||
48 | |||
49 | #endif /* !GR_SCALE_DYNAMIC */ | ||
50 | |||
51 | |||
52 | /* | ||
53 | * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate | ||
54 | * space for it's GID array before calling setgroups(). This is probably | ||
55 | * unnecessary scalage, so it's undefined by default. | ||
56 | */ | ||
57 | #undef GR_DYNAMIC_GROUP_LIST | ||
58 | |||
59 | #ifndef GR_DYNAMIC_GROUP_LIST | ||
60 | /* | ||
61 | * GR_MAX_GROUPS is the size of the static array initgroups() uses for | ||
62 | * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined. | ||
63 | */ | ||
64 | #define GR_MAX_GROUPS 64 | ||
65 | |||
66 | #endif /* !GR_DYNAMIC_GROUP_LIST */ | ||
67 | |||
68 | int initgroups(__const char *user, gid_t gid) | ||
69 | { | ||
70 | register struct group *group; | ||
71 | |||
72 | #ifndef GR_DYNAMIC_GROUP_LIST | ||
73 | gid_t group_list[GR_MAX_GROUPS]; | ||
74 | #else | ||
75 | gid_t *group_list = NULL; | ||
76 | #endif | ||
77 | register char **tmp_mem; | ||
78 | int num_groups; | ||
79 | int grp_fd; | ||
80 | |||
81 | |||
82 | if ((grp_fd = open(bb_path_group_file, O_RDONLY)) < 0) | ||
83 | return -1; | ||
84 | |||
85 | num_groups = 0; | ||
86 | #ifdef GR_DYNAMIC_GROUP_LIST | ||
87 | group_list = (gid_t *) realloc(group_list, 1); | ||
88 | #endif | ||
89 | group_list[num_groups] = gid; | ||
90 | #ifndef GR_DYNAMIC_GROUP_LIST | ||
91 | while (num_groups < GR_MAX_GROUPS && | ||
92 | (group = bb_getgrent(grp_fd)) != NULL) | ||
93 | #else | ||
94 | while ((group = bb_getgrent(grp_fd)) != NULL) | ||
95 | #endif | ||
96 | { | ||
97 | if (group->gr_gid != gid) | ||
98 | { | ||
99 | tmp_mem = group->gr_mem; | ||
100 | while (*tmp_mem != NULL) { | ||
101 | if (!strcmp(*tmp_mem, user)) { | ||
102 | num_groups++; | ||
103 | #ifdef GR_DYNAMIC_GROUP_LIST | ||
104 | group_list = (gid_t *) realloc(group_list, num_groups * | ||
105 | sizeof(gid_t *)); | ||
106 | #endif | ||
107 | group_list[num_groups-1] = group->gr_gid; | ||
108 | } | ||
109 | tmp_mem++; | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | close(grp_fd); | ||
114 | return setgroups(num_groups, group_list); | ||
115 | } | ||
diff --git a/libpwdgrp/putpwent.c b/libpwdgrp/putpwent.c deleted file mode 100644 index 0710ff5b2..000000000 --- a/libpwdgrp/putpwent.c +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | /* | ||
2 | * putpwent.c - This file is part of the libc-8086/pwd package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "busybox.h" | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <errno.h> | ||
25 | #include "pwd_.h" | ||
26 | |||
27 | int putpwent(const struct passwd *passwd, FILE * f) | ||
28 | { | ||
29 | if (passwd == NULL || f == NULL) { | ||
30 | errno = EINVAL; | ||
31 | return -1; | ||
32 | } | ||
33 | if (fprintf (f, "%s:%s:%u:%u:%s:%s:%s\n", passwd->pw_name, passwd->pw_passwd, | ||
34 | passwd->pw_uid, passwd->pw_gid, passwd->pw_gecos, passwd->pw_dir, | ||
35 | passwd->pw_shell) < 0) | ||
36 | return -1; | ||
37 | |||
38 | return 0; | ||
39 | } | ||
diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c new file mode 100644 index 000000000..9412faeb4 --- /dev/null +++ b/libpwdgrp/pwd_grp.c | |||
@@ -0,0 +1,1116 @@ | |||
1 | /* Copyright (C) 2003 Manuel Novoa III | ||
2 | * | ||
3 | * This library is free software; you can redistribute it and/or | ||
4 | * modify it under the terms of the GNU Library General Public | ||
5 | * License as published by the Free Software Foundation; either | ||
6 | * version 2 of the License, or (at your option) any later version. | ||
7 | * | ||
8 | * This library is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * Library General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU Library General Public | ||
14 | * License along with this library; if not, write to the Free | ||
15 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
16 | */ | ||
17 | |||
18 | /* Nov 6, 2003 Initial version. | ||
19 | * | ||
20 | * NOTE: This implementation is quite strict about requiring all | ||
21 | * field seperators. It also does not allow leading whitespace | ||
22 | * except when processing the numeric fields. glibc is more | ||
23 | * lenient. See the various glibc difference comments below. | ||
24 | * | ||
25 | * TODO: | ||
26 | * Move to dynamic allocation of (currently staticly allocated) | ||
27 | * buffers; especially for the group-related functions since | ||
28 | * large group member lists will cause error returns. | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <features.h> | ||
33 | #include <stdio.h> | ||
34 | #include <stdlib.h> | ||
35 | #include <stdint.h> | ||
36 | #include <string.h> | ||
37 | #include <stddef.h> | ||
38 | #include <errno.h> | ||
39 | #include <assert.h> | ||
40 | #include <ctype.h> | ||
41 | #include "busybox.h" | ||
42 | #include "pwd_.h" | ||
43 | #include "grp_.h" | ||
44 | #include "shadow_.h" | ||
45 | |||
46 | #ifndef _PATH_SHADOW | ||
47 | #define _PATH_SHADOW "/etc/shadow" | ||
48 | #endif | ||
49 | #ifndef _PATH_PASSWD | ||
50 | #define _PATH_PASSWD "/etc/passwd" | ||
51 | #endif | ||
52 | #ifndef _PATH_GROUP | ||
53 | #define _PATH_GROUP "/etc/group" | ||
54 | #endif | ||
55 | |||
56 | /**********************************************************************/ | ||
57 | /* Sizes for staticly allocated buffers. */ | ||
58 | |||
59 | /* If you change these values, also change _SC_GETPW_R_SIZE_MAX and | ||
60 | * _SC_GETGR_R_SIZE_MAX in libc/unistd/sysconf.c to match */ | ||
61 | #define PWD_BUFFER_SIZE 256 | ||
62 | #define GRP_BUFFER_SIZE 256 | ||
63 | |||
64 | /**********************************************************************/ | ||
65 | /* Prototypes for internal functions. */ | ||
66 | |||
67 | extern int __parsepwent(void *pw, char *line); | ||
68 | extern int __parsegrent(void *gr, char *line); | ||
69 | extern int __parsespent(void *sp, char *line); | ||
70 | |||
71 | extern int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data, | ||
72 | char *__restrict line_buff, size_t buflen, FILE *f); | ||
73 | |||
74 | /**********************************************************************/ | ||
75 | /* For the various fget??ent_r funcs, return | ||
76 | * | ||
77 | * 0: success | ||
78 | * ENOENT: end-of-file encountered | ||
79 | * ERANGE: buflen too small | ||
80 | * other error values possible. See __pgsreader. | ||
81 | * | ||
82 | * Also, *result == resultbuf on success and NULL on failure. | ||
83 | * | ||
84 | * NOTE: glibc difference - For the ENOENT case, glibc also sets errno. | ||
85 | * We do not, as it really isn't an error if we reach the end-of-file. | ||
86 | * Doing so is analogous to having fgetc() set errno on EOF. | ||
87 | */ | ||
88 | /**********************************************************************/ | ||
89 | #ifdef L_fgetpwent_r | ||
90 | |||
91 | int fgetpwent_r(FILE *__restrict stream, struct passwd *__restrict resultbuf, | ||
92 | char *__restrict buffer, size_t buflen, | ||
93 | struct passwd **__restrict result) | ||
94 | { | ||
95 | int rv; | ||
96 | |||
97 | *result = NULL; | ||
98 | |||
99 | if (!(rv = __pgsreader(__parsepwent, resultbuf, buffer, buflen, stream))) { | ||
100 | *result = resultbuf; | ||
101 | } | ||
102 | |||
103 | return rv; | ||
104 | } | ||
105 | |||
106 | #endif | ||
107 | /**********************************************************************/ | ||
108 | #ifdef L_fgetgrent_r | ||
109 | |||
110 | int fgetgrent_r(FILE *__restrict stream, struct group *__restrict resultbuf, | ||
111 | char *__restrict buffer, size_t buflen, | ||
112 | struct group **__restrict result) | ||
113 | { | ||
114 | int rv; | ||
115 | |||
116 | *result = NULL; | ||
117 | |||
118 | if (!(rv = __pgsreader(__parsegrent, resultbuf, buffer, buflen, stream))) { | ||
119 | *result = resultbuf; | ||
120 | } | ||
121 | |||
122 | return rv; | ||
123 | } | ||
124 | |||
125 | #endif | ||
126 | /**********************************************************************/ | ||
127 | #ifdef L_fgetspent_r | ||
128 | |||
129 | int fgetspent_r(FILE *__restrict stream, struct spwd *__restrict resultbuf, | ||
130 | char *__restrict buffer, size_t buflen, | ||
131 | struct spwd **__restrict result) | ||
132 | { | ||
133 | int rv; | ||
134 | |||
135 | *result = NULL; | ||
136 | |||
137 | if (!(rv = __pgsreader(__parsespent, resultbuf, buffer, buflen, stream))) { | ||
138 | *result = resultbuf; | ||
139 | } | ||
140 | |||
141 | return rv; | ||
142 | } | ||
143 | |||
144 | #endif | ||
145 | /**********************************************************************/ | ||
146 | /* For the various fget??ent funcs, return NULL on failure and a | ||
147 | * pointer to the appropriate struct (staticly allocated) on success. | ||
148 | */ | ||
149 | /**********************************************************************/ | ||
150 | #ifdef L_fgetpwent | ||
151 | |||
152 | struct passwd *fgetpwent(FILE *stream) | ||
153 | { | ||
154 | static char buffer[PWD_BUFFER_SIZE]; | ||
155 | static struct passwd resultbuf; | ||
156 | struct passwd *result; | ||
157 | |||
158 | fgetpwent_r(stream, &resultbuf, buffer, sizeof(buffer), &result); | ||
159 | return result; | ||
160 | } | ||
161 | |||
162 | #endif | ||
163 | /**********************************************************************/ | ||
164 | #ifdef L_fgetgrent | ||
165 | |||
166 | struct group *fgetgrent(FILE *stream) | ||
167 | { | ||
168 | static char buffer[GRP_BUFFER_SIZE]; | ||
169 | static struct group resultbuf; | ||
170 | struct group *result; | ||
171 | |||
172 | fgetgrent_r(stream, &resultbuf, buffer, sizeof(buffer), &result); | ||
173 | return result; | ||
174 | } | ||
175 | |||
176 | #endif | ||
177 | /**********************************************************************/ | ||
178 | #ifdef L_fgetspent | ||
179 | |||
180 | extern int fgetspent_r(FILE *__restrict stream, struct spwd *__restrict resultbuf, | ||
181 | char *__restrict buffer, size_t buflen, | ||
182 | struct spwd **__restrict result); | ||
183 | struct spwd *fgetspent(FILE *stream) | ||
184 | { | ||
185 | static char buffer[PWD_BUFFER_SIZE]; | ||
186 | static struct spwd resultbuf; | ||
187 | struct spwd *result; | ||
188 | |||
189 | fgetspent_r(stream, &resultbuf, buffer, sizeof(buffer), &result); | ||
190 | return result; | ||
191 | } | ||
192 | |||
193 | #endif | ||
194 | /**********************************************************************/ | ||
195 | #ifdef L_sgetspent_r | ||
196 | |||
197 | int sgetspent_r(const char *string, struct spwd *result_buf, | ||
198 | char *buffer, size_t buflen, struct spwd **result) | ||
199 | { | ||
200 | int rv = ERANGE; | ||
201 | |||
202 | *result = NULL; | ||
203 | |||
204 | if (buflen < PWD_BUFFER_SIZE) { | ||
205 | DO_ERANGE: | ||
206 | errno=rv; | ||
207 | goto DONE; | ||
208 | } | ||
209 | |||
210 | if (string != buffer) { | ||
211 | if (strlen(string) >= buflen) { | ||
212 | goto DO_ERANGE; | ||
213 | } | ||
214 | strcpy(buffer, string); | ||
215 | } | ||
216 | |||
217 | if (!(rv = __parsespent(result_buf, buffer))) { | ||
218 | *result = result_buf; | ||
219 | } | ||
220 | |||
221 | DONE: | ||
222 | return rv; | ||
223 | } | ||
224 | |||
225 | #endif | ||
226 | /**********************************************************************/ | ||
227 | |||
228 | #ifdef GETXXKEY_R_FUNC | ||
229 | #error GETXXKEY_R_FUNC is already defined! | ||
230 | #endif | ||
231 | |||
232 | #ifdef L_getpwnam_r | ||
233 | #define GETXXKEY_R_FUNC getpwnam_r | ||
234 | #define GETXXKEY_R_PARSER __parsepwent | ||
235 | #define GETXXKEY_R_ENTTYPE struct passwd | ||
236 | #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->pw_name, key)) | ||
237 | #define DO_GETXXKEY_R_KEYTYPE const char *__restrict | ||
238 | #define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD | ||
239 | #endif | ||
240 | |||
241 | #ifdef L_getgrnam_r | ||
242 | #define GETXXKEY_R_FUNC getgrnam_r | ||
243 | #define GETXXKEY_R_PARSER __parsegrent | ||
244 | #define GETXXKEY_R_ENTTYPE struct group | ||
245 | #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->gr_name, key)) | ||
246 | #define DO_GETXXKEY_R_KEYTYPE const char *__restrict | ||
247 | #define DO_GETXXKEY_R_PATHNAME _PATH_GROUP | ||
248 | #endif | ||
249 | |||
250 | #ifdef L_getspnam_r | ||
251 | #define GETXXKEY_R_FUNC getspnam_r | ||
252 | #define GETXXKEY_R_PARSER __parsespent | ||
253 | #define GETXXKEY_R_ENTTYPE struct spwd | ||
254 | #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->sp_namp, key)) | ||
255 | #define DO_GETXXKEY_R_KEYTYPE const char *__restrict | ||
256 | #define DO_GETXXKEY_R_PATHNAME _PATH_SHADOW | ||
257 | #endif | ||
258 | |||
259 | #ifdef L_getpwuid_r | ||
260 | #define GETXXKEY_R_FUNC getpwuid_r | ||
261 | #define GETXXKEY_R_PARSER __parsepwent | ||
262 | #define GETXXKEY_R_ENTTYPE struct passwd | ||
263 | #define GETXXKEY_R_TEST(ENT) ((ENT)->pw_uid == key) | ||
264 | #define DO_GETXXKEY_R_KEYTYPE uid_t | ||
265 | #define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD | ||
266 | #endif | ||
267 | |||
268 | #ifdef L_getgrgid_r | ||
269 | #define GETXXKEY_R_FUNC getgrgid_r | ||
270 | #define GETXXKEY_R_PARSER __parsegrent | ||
271 | #define GETXXKEY_R_ENTTYPE struct group | ||
272 | #define GETXXKEY_R_TEST(ENT) ((ENT)->gr_gid == key) | ||
273 | #define DO_GETXXKEY_R_KEYTYPE gid_t | ||
274 | #define DO_GETXXKEY_R_PATHNAME _PATH_GROUP | ||
275 | #endif | ||
276 | |||
277 | /**********************************************************************/ | ||
278 | #ifdef GETXXKEY_R_FUNC | ||
279 | |||
280 | int GETXXKEY_R_FUNC(DO_GETXXKEY_R_KEYTYPE key, | ||
281 | GETXXKEY_R_ENTTYPE *__restrict resultbuf, | ||
282 | char *__restrict buffer, size_t buflen, | ||
283 | GETXXKEY_R_ENTTYPE **__restrict result) | ||
284 | { | ||
285 | FILE *stream; | ||
286 | int rv; | ||
287 | |||
288 | *result = NULL; | ||
289 | |||
290 | if (!(stream = fopen(DO_GETXXKEY_R_PATHNAME, "r"))) { | ||
291 | rv = errno; | ||
292 | } else { | ||
293 | do { | ||
294 | if (!(rv = __pgsreader(GETXXKEY_R_PARSER, resultbuf, | ||
295 | buffer, buflen, stream)) | ||
296 | ) { | ||
297 | if (GETXXKEY_R_TEST(resultbuf)) { /* Found key? */ | ||
298 | *result = resultbuf; | ||
299 | break; | ||
300 | } | ||
301 | } else { | ||
302 | if (rv == ENOENT) { /* end-of-file encountered. */ | ||
303 | rv = 0; | ||
304 | } | ||
305 | break; | ||
306 | } | ||
307 | } while (1); | ||
308 | fclose(stream); | ||
309 | } | ||
310 | |||
311 | return rv; | ||
312 | } | ||
313 | |||
314 | #endif | ||
315 | /**********************************************************************/ | ||
316 | #ifdef L_getpwuid | ||
317 | |||
318 | struct passwd *getpwuid(uid_t uid) | ||
319 | { | ||
320 | static char buffer[PWD_BUFFER_SIZE]; | ||
321 | static struct passwd resultbuf; | ||
322 | struct passwd *result; | ||
323 | |||
324 | getpwuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result); | ||
325 | return result; | ||
326 | } | ||
327 | |||
328 | #endif | ||
329 | /**********************************************************************/ | ||
330 | #ifdef L_getgrgid | ||
331 | |||
332 | struct group *getgrgid(gid_t gid) | ||
333 | { | ||
334 | static char buffer[GRP_BUFFER_SIZE]; | ||
335 | static struct group resultbuf; | ||
336 | struct group *result; | ||
337 | |||
338 | getgrgid_r(gid, &resultbuf, buffer, sizeof(buffer), &result); | ||
339 | return result; | ||
340 | } | ||
341 | |||
342 | #endif | ||
343 | /**********************************************************************/ | ||
344 | #ifdef L_getspuid_r | ||
345 | |||
346 | /* This function is non-standard and is currently not built. It seems | ||
347 | * to have been created as a reentrant version of the non-standard | ||
348 | * functions getspuid. Why getspuid was added, I do not know. */ | ||
349 | |||
350 | int getspuid_r(uid_t uid, struct spwd *__restrict resultbuf, | ||
351 | char *__restrict buffer, size_t buflen, | ||
352 | struct spwd **__restrict result) | ||
353 | { | ||
354 | int rv; | ||
355 | struct passwd *pp; | ||
356 | struct passwd password; | ||
357 | char pwd_buff[PWD_BUFFER_SIZE]; | ||
358 | |||
359 | *result = NULL; | ||
360 | if (!(rv = getpwuid_r(uid, &password, pwd_buff, sizeof(pwd_buff), &pp))) { | ||
361 | rv = getspnam_r(password.pw_name, resultbuf, buffer, buflen, result); | ||
362 | } | ||
363 | |||
364 | return rv; | ||
365 | } | ||
366 | |||
367 | #endif | ||
368 | /**********************************************************************/ | ||
369 | #ifdef L_getspuid | ||
370 | |||
371 | /* This function is non-standard and is currently not built. | ||
372 | * Why it was added, I do not know. */ | ||
373 | |||
374 | struct spwd *getspuid(uid_t uid) | ||
375 | { | ||
376 | static char buffer[PWD_BUFFER_SIZE]; | ||
377 | static struct spwd resultbuf; | ||
378 | struct spwd *result; | ||
379 | |||
380 | getspuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result); | ||
381 | return result; | ||
382 | } | ||
383 | |||
384 | #endif | ||
385 | /**********************************************************************/ | ||
386 | #ifdef L_getpwnam | ||
387 | |||
388 | struct passwd *getpwnam(const char *name) | ||
389 | { | ||
390 | static char buffer[PWD_BUFFER_SIZE]; | ||
391 | static struct passwd resultbuf; | ||
392 | struct passwd *result; | ||
393 | |||
394 | getpwnam_r(name, &resultbuf, buffer, sizeof(buffer), &result); | ||
395 | return result; | ||
396 | } | ||
397 | |||
398 | #endif | ||
399 | /**********************************************************************/ | ||
400 | #ifdef L_getgrnam | ||
401 | |||
402 | struct group *getgrnam(const char *name) | ||
403 | { | ||
404 | static char buffer[GRP_BUFFER_SIZE]; | ||
405 | static struct group resultbuf; | ||
406 | struct group *result; | ||
407 | |||
408 | getgrnam_r(name, &resultbuf, buffer, sizeof(buffer), &result); | ||
409 | return result; | ||
410 | } | ||
411 | |||
412 | #endif | ||
413 | /**********************************************************************/ | ||
414 | #ifdef L_getspnam | ||
415 | |||
416 | struct spwd *getspnam(const char *name) | ||
417 | { | ||
418 | static char buffer[PWD_BUFFER_SIZE]; | ||
419 | static struct spwd resultbuf; | ||
420 | struct spwd *result; | ||
421 | |||
422 | getspnam_r(name, &resultbuf, buffer, sizeof(buffer), &result); | ||
423 | return result; | ||
424 | } | ||
425 | |||
426 | #endif | ||
427 | /**********************************************************************/ | ||
428 | #ifdef L_getpw | ||
429 | |||
430 | int getpw(uid_t uid, char *buf) | ||
431 | { | ||
432 | struct passwd resultbuf; | ||
433 | struct passwd *result; | ||
434 | char buffer[PWD_BUFFER_SIZE]; | ||
435 | |||
436 | if (!buf) { | ||
437 | errno=EINVAL; | ||
438 | } else if (!getpwuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result)) { | ||
439 | if (sprintf(buf, "%s:%s:%lu:%lu:%s:%s:%s\n", | ||
440 | resultbuf.pw_name, resultbuf.pw_passwd, | ||
441 | (unsigned long)(resultbuf.pw_uid), | ||
442 | (unsigned long)(resultbuf.pw_gid), | ||
443 | resultbuf.pw_gecos, resultbuf.pw_dir, | ||
444 | resultbuf.pw_shell) >= 0 | ||
445 | ) { | ||
446 | return 0; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | return -1; | ||
451 | } | ||
452 | |||
453 | #endif | ||
454 | /**********************************************************************/ | ||
455 | #ifdef L_getpwent_r | ||
456 | |||
457 | static FILE *pwf /*= NULL*/; | ||
458 | void setpwent(void) | ||
459 | { | ||
460 | if (pwf) { | ||
461 | rewind(pwf); | ||
462 | } | ||
463 | } | ||
464 | |||
465 | void endpwent(void) | ||
466 | { | ||
467 | if (pwf) { | ||
468 | fclose(pwf); | ||
469 | pwf = NULL; | ||
470 | } | ||
471 | } | ||
472 | |||
473 | |||
474 | int getpwent_r(struct passwd *__restrict resultbuf, | ||
475 | char *__restrict buffer, size_t buflen, | ||
476 | struct passwd **__restrict result) | ||
477 | { | ||
478 | int rv; | ||
479 | |||
480 | *result = NULL; /* In case of error... */ | ||
481 | |||
482 | if (!pwf) { | ||
483 | if (!(pwf = fopen(_PATH_PASSWD, "r"))) { | ||
484 | rv = errno; | ||
485 | goto ERR; | ||
486 | } | ||
487 | } | ||
488 | |||
489 | if (!(rv = __pgsreader(__parsepwent, resultbuf, | ||
490 | buffer, buflen, pwf))) { | ||
491 | *result = resultbuf; | ||
492 | } | ||
493 | |||
494 | ERR: | ||
495 | return rv; | ||
496 | } | ||
497 | |||
498 | #endif | ||
499 | /**********************************************************************/ | ||
500 | #ifdef L_getgrent_r | ||
501 | |||
502 | static FILE *grf /*= NULL*/; | ||
503 | void setgrent(void) | ||
504 | { | ||
505 | if (grf) { | ||
506 | rewind(grf); | ||
507 | } | ||
508 | } | ||
509 | |||
510 | void endgrent(void) | ||
511 | { | ||
512 | if (grf) { | ||
513 | fclose(grf); | ||
514 | grf = NULL; | ||
515 | } | ||
516 | } | ||
517 | |||
518 | int getgrent_r(struct group *__restrict resultbuf, | ||
519 | char *__restrict buffer, size_t buflen, | ||
520 | struct group **__restrict result) | ||
521 | { | ||
522 | int rv; | ||
523 | |||
524 | *result = NULL; /* In case of error... */ | ||
525 | |||
526 | if (!grf) { | ||
527 | if (!(grf = fopen(_PATH_GROUP, "r"))) { | ||
528 | rv = errno; | ||
529 | goto ERR; | ||
530 | } | ||
531 | } | ||
532 | |||
533 | if (!(rv = __pgsreader(__parsegrent, resultbuf, | ||
534 | buffer, buflen, grf))) { | ||
535 | *result = resultbuf; | ||
536 | } | ||
537 | |||
538 | ERR: | ||
539 | return rv; | ||
540 | } | ||
541 | |||
542 | #endif | ||
543 | /**********************************************************************/ | ||
544 | #ifdef L_getspent_r | ||
545 | |||
546 | static FILE *spf /*= NULL*/; | ||
547 | void setspent(void) | ||
548 | { | ||
549 | if (spf) { | ||
550 | rewind(spf); | ||
551 | } | ||
552 | } | ||
553 | |||
554 | void endspent(void) | ||
555 | { | ||
556 | if (spf) { | ||
557 | fclose(spf); | ||
558 | spf = NULL; | ||
559 | } | ||
560 | } | ||
561 | |||
562 | int getspent_r(struct spwd *resultbuf, char *buffer, | ||
563 | size_t buflen, struct spwd **result) | ||
564 | { | ||
565 | int rv; | ||
566 | |||
567 | *result = NULL; /* In case of error... */ | ||
568 | |||
569 | if (!spf) { | ||
570 | if (!(spf = fopen(_PATH_SHADOW, "r"))) { | ||
571 | rv = errno; | ||
572 | goto ERR; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | if (!(rv = __pgsreader(__parsespent, resultbuf, | ||
577 | buffer, buflen, spf))) { | ||
578 | *result = resultbuf; | ||
579 | } | ||
580 | |||
581 | ERR: | ||
582 | return rv; | ||
583 | } | ||
584 | |||
585 | #endif | ||
586 | /**********************************************************************/ | ||
587 | #ifdef L_getpwent | ||
588 | |||
589 | struct passwd *getpwent(void) | ||
590 | { | ||
591 | static char line_buff[PWD_BUFFER_SIZE]; | ||
592 | static struct passwd pwd; | ||
593 | struct passwd *result; | ||
594 | |||
595 | getpwent_r(&pwd, line_buff, sizeof(line_buff), &result); | ||
596 | return result; | ||
597 | } | ||
598 | |||
599 | #endif | ||
600 | /**********************************************************************/ | ||
601 | #ifdef L_getgrent | ||
602 | |||
603 | struct group *getgrent(void) | ||
604 | { | ||
605 | static char line_buff[GRP_BUFFER_SIZE]; | ||
606 | static struct group gr; | ||
607 | struct group *result; | ||
608 | |||
609 | getgrent_r(&gr, line_buff, sizeof(line_buff), &result); | ||
610 | return result; | ||
611 | } | ||
612 | |||
613 | #endif | ||
614 | /**********************************************************************/ | ||
615 | #ifdef L_getspent | ||
616 | |||
617 | struct spwd *getspent(void) | ||
618 | { | ||
619 | static char line_buff[PWD_BUFFER_SIZE]; | ||
620 | static struct spwd spwd; | ||
621 | struct spwd *result; | ||
622 | |||
623 | getspent_r(&spwd, line_buff, sizeof(line_buff), &result); | ||
624 | return result; | ||
625 | } | ||
626 | |||
627 | #endif | ||
628 | /**********************************************************************/ | ||
629 | #ifdef L_sgetspent | ||
630 | |||
631 | struct spwd *sgetspent(const char *string) | ||
632 | { | ||
633 | static char line_buff[PWD_BUFFER_SIZE]; | ||
634 | static struct spwd spwd; | ||
635 | struct spwd *result; | ||
636 | |||
637 | sgetspent_r(string, &spwd, line_buff, sizeof(line_buff), &result); | ||
638 | return result; | ||
639 | } | ||
640 | |||
641 | #endif | ||
642 | /**********************************************************************/ | ||
643 | #ifdef L_initgroups | ||
644 | |||
645 | int initgroups(const char *user, gid_t gid) | ||
646 | { | ||
647 | FILE *grf; | ||
648 | gid_t *group_list; | ||
649 | int num_groups, rv; | ||
650 | char **m; | ||
651 | struct group group; | ||
652 | char buff[PWD_BUFFER_SIZE]; | ||
653 | |||
654 | rv = -1; | ||
655 | |||
656 | /* We alloc space for 8 gids at a time. */ | ||
657 | if (((group_list = (gid_t *) malloc(8*sizeof(gid_t *))) != NULL) | ||
658 | && ((grf = fopen(_PATH_GROUP, "r")) != NULL) | ||
659 | ) { | ||
660 | |||
661 | *group_list = gid; | ||
662 | num_groups = 1; | ||
663 | |||
664 | while (!__pgsreader(__parsegrent, &group, buff, sizeof(buff), grf)) { | ||
665 | assert(group.gr_mem); /* Must have at least a NULL terminator. */ | ||
666 | if (group.gr_gid != gid) { | ||
667 | for (m=group.gr_mem ; *m ; m++) { | ||
668 | if (!strcmp(*m, user)) { | ||
669 | if (!(num_groups & 7)) { | ||
670 | gid_t *tmp = (gid_t *) | ||
671 | realloc(group_list, | ||
672 | (num_groups+8) * sizeof(gid_t *)); | ||
673 | if (!tmp) { | ||
674 | rv = -1; | ||
675 | goto DO_CLOSE; | ||
676 | } | ||
677 | group_list = tmp; | ||
678 | } | ||
679 | group_list[num_groups++] = group.gr_gid; | ||
680 | break; | ||
681 | } | ||
682 | } | ||
683 | } | ||
684 | } | ||
685 | |||
686 | rv = setgroups(num_groups, group_list); | ||
687 | DO_CLOSE: | ||
688 | fclose(grf); | ||
689 | } | ||
690 | |||
691 | /* group_list will be NULL if initial malloc failed, which may trigger | ||
692 | * warnings from various malloc debuggers. */ | ||
693 | free(group_list); | ||
694 | return rv; | ||
695 | } | ||
696 | |||
697 | #endif | ||
698 | /**********************************************************************/ | ||
699 | #ifdef L_putpwent | ||
700 | |||
701 | int putpwent(const struct passwd *__restrict p, FILE *__restrict f) | ||
702 | { | ||
703 | int rv = -1; | ||
704 | |||
705 | if (!p || !f) { | ||
706 | errno=EINVAL; | ||
707 | } else { | ||
708 | /* No extra thread locking is needed above what fprintf does. */ | ||
709 | if (fprintf(f, "%s:%s:%lu:%lu:%s:%s:%s\n", | ||
710 | p->pw_name, p->pw_passwd, | ||
711 | (unsigned long)(p->pw_uid), | ||
712 | (unsigned long)(p->pw_gid), | ||
713 | p->pw_gecos, p->pw_dir, p->pw_shell) >= 0 | ||
714 | ) { | ||
715 | rv = 0; | ||
716 | } | ||
717 | } | ||
718 | |||
719 | return rv; | ||
720 | } | ||
721 | |||
722 | #endif | ||
723 | /**********************************************************************/ | ||
724 | #ifdef L_putgrent | ||
725 | |||
726 | int putgrent(const struct group *__restrict p, FILE *__restrict f) | ||
727 | { | ||
728 | static const char format[] = ",%s"; | ||
729 | char **m; | ||
730 | const char *fmt; | ||
731 | int rv = -1; | ||
732 | |||
733 | if (!p || !f) { /* Sigh... glibc checks. */ | ||
734 | errno=EINVAL; | ||
735 | } else { | ||
736 | if (fprintf(f, "%s:%s:%lu:", | ||
737 | p->gr_name, p->gr_passwd, | ||
738 | (unsigned long)(p->gr_gid)) >= 0 | ||
739 | ) { | ||
740 | |||
741 | fmt = format + 1; | ||
742 | |||
743 | assert(p->gr_mem); | ||
744 | m = p->gr_mem; | ||
745 | |||
746 | do { | ||
747 | if (!*m) { | ||
748 | if (fputc_unlocked('\n', f) >= 0) { | ||
749 | rv = 0; | ||
750 | } | ||
751 | break; | ||
752 | } | ||
753 | if (fprintf(f, fmt, *m) < 0) { | ||
754 | break; | ||
755 | } | ||
756 | ++m; | ||
757 | fmt = format; | ||
758 | } while (1); | ||
759 | |||
760 | } | ||
761 | |||
762 | } | ||
763 | |||
764 | return rv; | ||
765 | } | ||
766 | |||
767 | #endif | ||
768 | /**********************************************************************/ | ||
769 | #ifdef L_putspent | ||
770 | |||
771 | static const unsigned char sp_off[] = { | ||
772 | offsetof(struct spwd, sp_lstchg), /* 2 - not a char ptr */ | ||
773 | offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ | ||
774 | offsetof(struct spwd, sp_max), /* 4 - not a char ptr */ | ||
775 | offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ | ||
776 | offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ | ||
777 | offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ | ||
778 | }; | ||
779 | |||
780 | int putspent(const struct spwd *p, FILE *stream) | ||
781 | { | ||
782 | static const char ld_format[] = "%ld:"; | ||
783 | const char *f; | ||
784 | long int x; | ||
785 | int i; | ||
786 | int rv = -1; | ||
787 | |||
788 | /* Unlike putpwent and putgrent, glibc does not check the args. */ | ||
789 | if (fprintf(stream, "%s:%s:", p->sp_namp, | ||
790 | (p->sp_pwdp ? p->sp_pwdp : "")) < 0 | ||
791 | ) { | ||
792 | goto DO_UNLOCK; | ||
793 | } | ||
794 | |||
795 | for (i=0 ; i < sizeof(sp_off) ; i++) { | ||
796 | f = ld_format; | ||
797 | if ((x = *(const long int *)(((const char *) p) + sp_off[i])) == -1) { | ||
798 | f += 3; | ||
799 | } | ||
800 | if (fprintf(stream, f, x) < 0) { | ||
801 | goto DO_UNLOCK; | ||
802 | } | ||
803 | } | ||
804 | |||
805 | if ((p->sp_flag != ~0UL) && (fprintf(stream, "%lu", p->sp_flag) < 0)) { | ||
806 | goto DO_UNLOCK; | ||
807 | } | ||
808 | |||
809 | if (fputc_unlocked('\n', stream) > 0) { | ||
810 | rv = 0; | ||
811 | } | ||
812 | |||
813 | DO_UNLOCK: | ||
814 | return rv; | ||
815 | } | ||
816 | |||
817 | #endif | ||
818 | /**********************************************************************/ | ||
819 | /* Internal uClibc functions. */ | ||
820 | /**********************************************************************/ | ||
821 | #ifdef L___parsepwent | ||
822 | |||
823 | static const unsigned char pw_off[] = { | ||
824 | offsetof(struct passwd, pw_name), /* 0 */ | ||
825 | offsetof(struct passwd, pw_passwd), /* 1 */ | ||
826 | offsetof(struct passwd, pw_uid), /* 2 - not a char ptr */ | ||
827 | offsetof(struct passwd, pw_gid), /* 3 - not a char ptr */ | ||
828 | offsetof(struct passwd, pw_gecos), /* 4 */ | ||
829 | offsetof(struct passwd, pw_dir), /* 5 */ | ||
830 | offsetof(struct passwd, pw_shell) /* 6 */ | ||
831 | }; | ||
832 | |||
833 | int __parsepwent(void *data, char *line) | ||
834 | { | ||
835 | char *endptr; | ||
836 | char *p; | ||
837 | int i; | ||
838 | |||
839 | i = 0; | ||
840 | do { | ||
841 | p = ((char *) ((struct passwd *) data)) + pw_off[i]; | ||
842 | |||
843 | if ((i & 6) ^ 2) { /* i!=2 and i!=3 */ | ||
844 | *((char **) p) = line; | ||
845 | if (i==6) { | ||
846 | return 0; | ||
847 | } | ||
848 | /* NOTE: glibc difference - glibc allows omission of | ||
849 | * ':' seperators after the gid field if all remaining | ||
850 | * entries are empty. We require all separators. */ | ||
851 | if (!(line = strchr(line, ':'))) { | ||
852 | break; | ||
853 | } | ||
854 | } else { | ||
855 | unsigned long t = strtoul(line, &endptr, 10); | ||
856 | /* Make sure we had at least one digit, and that the | ||
857 | * failing char is the next field seperator ':'. See | ||
858 | * glibc difference note above. */ | ||
859 | /* TODO: Also check for leading whitespace? */ | ||
860 | if ((endptr == line) || (*endptr != ':')) { | ||
861 | break; | ||
862 | } | ||
863 | line = endptr; | ||
864 | if (i & 1) { /* i == 3 -- gid */ | ||
865 | *((gid_t *) p) = t; | ||
866 | } else { /* i == 2 -- uid */ | ||
867 | *((uid_t *) p) = t; | ||
868 | } | ||
869 | } | ||
870 | |||
871 | *line++ = 0; | ||
872 | ++i; | ||
873 | } while (1); | ||
874 | |||
875 | return -1; | ||
876 | } | ||
877 | |||
878 | #endif | ||
879 | /**********************************************************************/ | ||
880 | #ifdef L___parsegrent | ||
881 | |||
882 | static const unsigned char gr_off[] = { | ||
883 | offsetof(struct group, gr_name), /* 0 */ | ||
884 | offsetof(struct group, gr_passwd), /* 1 */ | ||
885 | offsetof(struct group, gr_gid) /* 2 - not a char ptr */ | ||
886 | }; | ||
887 | |||
888 | int __parsegrent(void *data, char *line) | ||
889 | { | ||
890 | char *endptr; | ||
891 | char *p; | ||
892 | int i; | ||
893 | char **members; | ||
894 | char *end_of_buf; | ||
895 | |||
896 | end_of_buf = ((struct group *) data)->gr_name; /* Evil hack! */ | ||
897 | i = 0; | ||
898 | do { | ||
899 | p = ((char *) ((struct group *) data)) + gr_off[i]; | ||
900 | |||
901 | if (i < 2) { | ||
902 | *((char **) p) = line; | ||
903 | if (!(line = strchr(line, ':'))) { | ||
904 | break; | ||
905 | } | ||
906 | *line++ = 0; | ||
907 | ++i; | ||
908 | } else { | ||
909 | *((gid_t *) p) = strtoul(line, &endptr, 10); | ||
910 | |||
911 | /* NOTE: glibc difference - glibc allows omission of the | ||
912 | * trailing colon when there is no member list. We treat | ||
913 | * this as an error. */ | ||
914 | |||
915 | /* Make sure we had at least one digit, and that the | ||
916 | * failing char is the next field seperator ':'. See | ||
917 | * glibc difference note above. */ | ||
918 | if ((endptr == line) || (*endptr != ':')) { | ||
919 | break; | ||
920 | } | ||
921 | |||
922 | i = 1; /* Count terminating NULL ptr. */ | ||
923 | p = endptr; | ||
924 | |||
925 | if (p[1]) { /* We have a member list to process. */ | ||
926 | /* Overwrite the last ':' with a ',' before counting. | ||
927 | * This allows us to test for initial ',' and adds | ||
928 | * one ',' so that the ',' count equals the member | ||
929 | * count. */ | ||
930 | *p = ','; | ||
931 | do { | ||
932 | /* NOTE: glibc difference - glibc allows and trims leading | ||
933 | * (but not trailing) space. We treat this as an error. */ | ||
934 | /* NOTE: glibc difference - glibc allows consecutive and | ||
935 | * trailing commas, and ignores "empty string" users. We | ||
936 | * treat this as an error. */ | ||
937 | if (*p == ',') { | ||
938 | ++i; | ||
939 | *p = 0; /* nul-terminate each member string. */ | ||
940 | if (!*++p || (*p == ',') || isspace(*p)) { | ||
941 | goto ERR; | ||
942 | } | ||
943 | } | ||
944 | } while (*++p); | ||
945 | } | ||
946 | |||
947 | /* Now align (p+1), rounding up. */ | ||
948 | /* Assumes sizeof(char **) is a power of 2. */ | ||
949 | members = (char **)( (((intptr_t) p) + sizeof(char **)) | ||
950 | & ~((intptr_t)(sizeof(char **) - 1)) ); | ||
951 | |||
952 | if (((char *)(members + i)) > end_of_buf) { /* No space. */ | ||
953 | break; | ||
954 | } | ||
955 | |||
956 | ((struct group *) data)->gr_mem = members; | ||
957 | |||
958 | if (--i) { | ||
959 | p = endptr; /* Pointing to char prior to first member. */ | ||
960 | do { | ||
961 | *members++ = ++p; | ||
962 | if (!--i) break; | ||
963 | while (*++p) {} | ||
964 | } while (1); | ||
965 | } | ||
966 | *members = NULL; | ||
967 | |||
968 | return 0; | ||
969 | } | ||
970 | } while (1); | ||
971 | |||
972 | ERR: | ||
973 | return -1; | ||
974 | } | ||
975 | |||
976 | #endif | ||
977 | /**********************************************************************/ | ||
978 | #ifdef L___parsespent | ||
979 | |||
980 | static const unsigned char sp_off[] = { | ||
981 | offsetof(struct spwd, sp_namp), /* 0 */ | ||
982 | offsetof(struct spwd, sp_pwdp), /* 1 */ | ||
983 | offsetof(struct spwd, sp_lstchg), /* 2 - not a char ptr */ | ||
984 | offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ | ||
985 | offsetof(struct spwd, sp_max), /* 4 - not a char ptr */ | ||
986 | offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ | ||
987 | offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ | ||
988 | offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ | ||
989 | offsetof(struct spwd, sp_flag) /* 8 - not a char ptr */ | ||
990 | }; | ||
991 | |||
992 | int __parsespent(void *data, char * line) | ||
993 | { | ||
994 | char *endptr; | ||
995 | char *p; | ||
996 | int i; | ||
997 | |||
998 | i = 0; | ||
999 | do { | ||
1000 | p = ((char *) ((struct spwd *) data)) + sp_off[i]; | ||
1001 | if (i < 2) { | ||
1002 | *((char **) p) = line; | ||
1003 | if (!(line = strchr(line, ':'))) { | ||
1004 | break; | ||
1005 | } | ||
1006 | } else { | ||
1007 | #if 0 | ||
1008 | if (i==5) { /* Support for old format. */ | ||
1009 | while (isspace(*line)) ++line; /* glibc eats space here. */ | ||
1010 | if (!*line) { | ||
1011 | ((struct spwd *) data)->sp_warn = -1; | ||
1012 | ((struct spwd *) data)->sp_inact = -1; | ||
1013 | ((struct spwd *) data)->sp_expire = -1; | ||
1014 | ((struct spwd *) data)->sp_flag = ~0UL; | ||
1015 | return 0; | ||
1016 | } | ||
1017 | } | ||
1018 | #endif | ||
1019 | |||
1020 | *((long *) p) = (long) strtoul(line, &endptr, 10); | ||
1021 | |||
1022 | if (endptr == line) { | ||
1023 | *((long *) p) = ((i != 8) ? -1L : ((long)(~0UL))); | ||
1024 | } | ||
1025 | |||
1026 | line = endptr; | ||
1027 | |||
1028 | if (i == 8) { | ||
1029 | if (!*endptr) { | ||
1030 | return 0; | ||
1031 | } | ||
1032 | break; | ||
1033 | } | ||
1034 | |||
1035 | if (*endptr != ':') { | ||
1036 | break; | ||
1037 | } | ||
1038 | |||
1039 | } | ||
1040 | |||
1041 | *line++ = 0; | ||
1042 | ++i; | ||
1043 | } while (1); | ||
1044 | |||
1045 | return EINVAL; | ||
1046 | } | ||
1047 | |||
1048 | #endif | ||
1049 | /**********************************************************************/ | ||
1050 | #ifdef L___pgsreader | ||
1051 | |||
1052 | /* Reads until if EOF, or until if finds a line which fits in the buffer | ||
1053 | * and for which the parser function succeeds. | ||
1054 | * | ||
1055 | * Returns 0 on success and ENOENT for end-of-file (glibc concession). | ||
1056 | */ | ||
1057 | |||
1058 | int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data, | ||
1059 | char *__restrict line_buff, size_t buflen, FILE *f) | ||
1060 | { | ||
1061 | int line_len; | ||
1062 | int skip; | ||
1063 | int rv = ERANGE; | ||
1064 | |||
1065 | if (buflen < PWD_BUFFER_SIZE) { | ||
1066 | errno=rv; | ||
1067 | } else { | ||
1068 | skip = 0; | ||
1069 | do { | ||
1070 | if (!fgets_unlocked(line_buff, buflen, f)) { | ||
1071 | if (feof_unlocked(f)) { | ||
1072 | rv = ENOENT; | ||
1073 | } | ||
1074 | break; | ||
1075 | } | ||
1076 | |||
1077 | line_len = strlen(line_buff) - 1; /* strlen() must be > 0. */ | ||
1078 | if (line_buff[line_len] == '\n') { | ||
1079 | line_buff[line_len] = 0; | ||
1080 | } else if (line_len + 2 == buflen) { /* line too long */ | ||
1081 | ++skip; | ||
1082 | continue; | ||
1083 | } | ||
1084 | |||
1085 | if (skip) { | ||
1086 | --skip; | ||
1087 | continue; | ||
1088 | } | ||
1089 | |||
1090 | /* NOTE: glibc difference - glibc strips leading whitespace from | ||
1091 | * records. We do not allow leading whitespace. */ | ||
1092 | |||
1093 | /* Skip empty lines, comment lines, and lines with leading | ||
1094 | * whitespace. */ | ||
1095 | if (*line_buff && (*line_buff != '#') && !isspace(*line_buff)) { | ||
1096 | if (__parserfunc == __parsegrent) { /* Do evil group hack. */ | ||
1097 | /* The group entry parsing function needs to know where | ||
1098 | * the end of the buffer is so that it can construct the | ||
1099 | * group member ptr table. */ | ||
1100 | ((struct group *) data)->gr_name = line_buff + buflen; | ||
1101 | } | ||
1102 | |||
1103 | if (!__parserfunc(data, line_buff)) { | ||
1104 | rv = 0; | ||
1105 | break; | ||
1106 | } | ||
1107 | } | ||
1108 | } while (1); | ||
1109 | |||
1110 | } | ||
1111 | |||
1112 | return rv; | ||
1113 | } | ||
1114 | |||
1115 | #endif | ||
1116 | /**********************************************************************/ | ||
diff --git a/libpwdgrp/pwent.c b/libpwdgrp/pwent.c deleted file mode 100644 index 1cdb2d454..000000000 --- a/libpwdgrp/pwent.c +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | /* | ||
2 | * pwent.c - This file is part of the libc-8086/pwd package for ELKS, | ||
3 | * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This 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 this library; if not, write to the Free | ||
17 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <unistd.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <errno.h> | ||
24 | #include <fcntl.h> | ||
25 | |||
26 | #include "busybox.h" | ||
27 | #include "pwd_.h" | ||
28 | |||
29 | /* | ||
30 | * setpwent(), endpwent(), and getpwent() are included in the same object | ||
31 | * file, since one cannot be used without the other two, so it makes sense to | ||
32 | * link them all in together. | ||
33 | */ | ||
34 | |||
35 | /* file descriptor for the password file currently open */ | ||
36 | static int pw_fd = -1; | ||
37 | |||
38 | void setpwent(void) | ||
39 | { | ||
40 | if (pw_fd != -1) | ||
41 | close(pw_fd); | ||
42 | |||
43 | pw_fd = open(bb_path_passwd_file, O_RDONLY); | ||
44 | } | ||
45 | |||
46 | void endpwent(void) | ||
47 | { | ||
48 | if (pw_fd != -1) | ||
49 | close(pw_fd); | ||
50 | pw_fd = -1; | ||
51 | } | ||
52 | |||
53 | struct passwd *getpwent(void) | ||
54 | { | ||
55 | if (pw_fd != -1) | ||
56 | return (__getpwent(pw_fd)); | ||
57 | return NULL; | ||
58 | } | ||
diff --git a/libpwdgrp/setgroups.c b/libpwdgrp/setgroups.c deleted file mode 100644 index 15a16f4e6..000000000 --- a/libpwdgrp/setgroups.c +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Taken from the set of syscalls for uClibc | ||
4 | * | ||
5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU Library General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License | ||
15 | * for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Library General Public License | ||
18 | * along with this program; if not, write to the Free Software Foundation, | ||
19 | * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include "busybox.h" | ||
24 | |||
25 | #include <errno.h> | ||
26 | #include <unistd.h> | ||
27 | #include <features.h> | ||
28 | #include <sys/types.h> | ||
29 | /* Kernel headers before 2.1.mumble need this on the Alpha to get | ||
30 | _syscall* defined. */ | ||
31 | #define __LIBRARY__ | ||
32 | #include <sys/syscall.h> | ||
33 | #include "grp_.h" | ||
34 | |||
35 | int setgroups(size_t size, const gid_t * list) | ||
36 | { | ||
37 | return(syscall(__NR_setgroups, size, list)); | ||
38 | } | ||
39 | |||
40 | |||
diff --git a/libpwdgrp/shadow.c b/libpwdgrp/shadow.c deleted file mode 100644 index b3a4901f5..000000000 --- a/libpwdgrp/shadow.c +++ /dev/null | |||
@@ -1,300 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright 1989 - 1994, Julianne Frances Haugh | ||
4 | * <jockgrrl@austin.rr.com>, <jfh@austin.ibm.com> | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors | ||
16 | * may be used to endorse or promote products derived from this software | ||
17 | * without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* TODO: fgetspent_r.c getspent_r.c getspnam_r.c sgetspent_r.c | ||
33 | * lckpwdf ulckpwdf | ||
34 | */ | ||
35 | |||
36 | #include <stdio.h> | ||
37 | #include <stdlib.h> | ||
38 | #include <string.h> | ||
39 | #include <unistd.h> | ||
40 | |||
41 | #include "busybox.h" | ||
42 | #include "shadow_.h" | ||
43 | |||
44 | static FILE *shadow; | ||
45 | static char spwbuf[BUFSIZ]; | ||
46 | static struct spwd spwd; | ||
47 | |||
48 | #define FIELDS 9 | ||
49 | #define OFIELDS 5 | ||
50 | |||
51 | /* setspent - initialize access to shadow text and DBM files */ | ||
52 | void setspent(void) | ||
53 | { | ||
54 | if (shadow) { | ||
55 | rewind(shadow); | ||
56 | } else { | ||
57 | shadow = bb_xfopen(bb_path_shadow_file, "r"); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | /* endspent - terminate access to shadow text and DBM files */ | ||
62 | void endspent(void) | ||
63 | { | ||
64 | if (shadow) | ||
65 | (void) fclose(shadow); | ||
66 | shadow = (FILE *) 0; | ||
67 | } | ||
68 | |||
69 | /* getspent - get a (struct spwd *) from the current shadow file */ | ||
70 | struct spwd *getspent(void) | ||
71 | { | ||
72 | if (!shadow) | ||
73 | setspent(); | ||
74 | return (fgetspent(shadow)); | ||
75 | } | ||
76 | |||
77 | /* getspnam - get a shadow entry by name */ | ||
78 | struct spwd *getspnam(const char *name) | ||
79 | { | ||
80 | struct spwd *sp; | ||
81 | |||
82 | if (!name || !strlen(name)) | ||
83 | return NULL; | ||
84 | |||
85 | setspent(); | ||
86 | while ((sp = getspent()) != NULL) { | ||
87 | if (strcmp(name, sp->sp_namp) == 0) | ||
88 | break; | ||
89 | } | ||
90 | endspent(); | ||
91 | return (sp); | ||
92 | } | ||
93 | |||
94 | |||
95 | /* sgetspent - convert string in shadow file format to (struct spwd *) */ | ||
96 | /* returns NULL on error */ | ||
97 | struct spwd *sgetspent(const char *string) | ||
98 | { | ||
99 | char *fields[FIELDS]; | ||
100 | char *cp; | ||
101 | char *cpp; | ||
102 | int i; | ||
103 | |||
104 | /* | ||
105 | * Copy string to local buffer. It has to be tokenized and we | ||
106 | * have to do that to our private copy. | ||
107 | */ | ||
108 | |||
109 | if (strlen(string) >= sizeof spwbuf) | ||
110 | /* return 0; */ | ||
111 | return NULL; | ||
112 | strcpy(spwbuf, string); | ||
113 | |||
114 | if ((cp = strrchr(spwbuf, '\n'))) | ||
115 | *cp = '\0'; | ||
116 | |||
117 | /* | ||
118 | * Tokenize the string into colon separated fields. Allow up to | ||
119 | * FIELDS different fields. | ||
120 | */ | ||
121 | |||
122 | for (cp = spwbuf, i = 0; *cp && i < FIELDS; i++) { | ||
123 | fields[i] = cp; | ||
124 | while (*cp && *cp != ':') | ||
125 | cp++; | ||
126 | |||
127 | if (*cp) | ||
128 | *cp++ = '\0'; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * It is acceptable for the last SVR4 field to be blank. This | ||
133 | * results in the loop being terminated early. In which case, | ||
134 | * we just make the last field be blank and be done with it. | ||
135 | */ | ||
136 | |||
137 | if (i == (FIELDS - 1)) | ||
138 | fields[i++] = cp; | ||
139 | |||
140 | if ((cp && *cp) || (i != FIELDS && i != OFIELDS)) | ||
141 | /* return 0; */ | ||
142 | return NULL; | ||
143 | |||
144 | /* | ||
145 | * Start populating the structure. The fields are all in | ||
146 | * static storage, as is the structure we pass back. If we | ||
147 | * ever see a name with '+' as the first character, we try | ||
148 | * to turn on NIS processing. | ||
149 | */ | ||
150 | |||
151 | spwd.sp_namp = fields[0]; | ||
152 | spwd.sp_pwdp = fields[1]; | ||
153 | |||
154 | /* | ||
155 | * Get the last changed date. For all of the integer fields, | ||
156 | * we check for proper format. It is an error to have an | ||
157 | * incorrectly formatted number, unless we are using NIS. | ||
158 | */ | ||
159 | |||
160 | if ((spwd.sp_lstchg = strtol(fields[2], &cpp, 10)) == 0 && *cpp) { | ||
161 | /* return 0; */ | ||
162 | return NULL; | ||
163 | } else if (fields[2][0] == '\0') | ||
164 | spwd.sp_lstchg = -1; | ||
165 | |||
166 | /* | ||
167 | * Get the minimum period between password changes. | ||
168 | */ | ||
169 | |||
170 | if ((spwd.sp_min = strtol(fields[3], &cpp, 10)) == 0 && *cpp) { | ||
171 | /* return 0; */ | ||
172 | return NULL; | ||
173 | } else if (fields[3][0] == '\0') | ||
174 | spwd.sp_min = -1; | ||
175 | |||
176 | /* | ||
177 | * Get the maximum number of days a password is valid. | ||
178 | */ | ||
179 | |||
180 | if ((spwd.sp_max = strtol(fields[4], &cpp, 10)) == 0 && *cpp) { | ||
181 | /* return 0; */ | ||
182 | return NULL; | ||
183 | } else if (fields[4][0] == '\0') | ||
184 | spwd.sp_max = -1; | ||
185 | |||
186 | /* | ||
187 | * If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow | ||
188 | * formatted file), initialize the other field members to -1. | ||
189 | */ | ||
190 | |||
191 | if (i == OFIELDS) { | ||
192 | spwd.sp_warn = spwd.sp_inact = spwd.sp_expire = spwd.sp_flag = -1; | ||
193 | |||
194 | return &spwd; | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * The rest of the fields are mandatory for SVR4, but optional | ||
199 | * for anything else. However, if one is present the others | ||
200 | * must be as well. | ||
201 | */ | ||
202 | |||
203 | /* | ||
204 | * Get the number of days of password expiry warning. | ||
205 | */ | ||
206 | |||
207 | if ((spwd.sp_warn = strtol(fields[5], &cpp, 10)) == 0 && *cpp) { | ||
208 | /* return 0; */ | ||
209 | return NULL; | ||
210 | } else if (fields[5][0] == '\0') | ||
211 | spwd.sp_warn = -1; | ||
212 | |||
213 | /* | ||
214 | * Get the number of days of inactivity before an account is | ||
215 | * disabled. | ||
216 | */ | ||
217 | |||
218 | if ((spwd.sp_inact = strtol(fields[6], &cpp, 10)) == 0 && *cpp) { | ||
219 | /* return 0; */ | ||
220 | return NULL; | ||
221 | } else if (fields[6][0] == '\0') | ||
222 | spwd.sp_inact = -1; | ||
223 | |||
224 | /* | ||
225 | * Get the number of days after the epoch before the account is | ||
226 | * set to expire. | ||
227 | */ | ||
228 | |||
229 | if ((spwd.sp_expire = strtol(fields[7], &cpp, 10)) == 0 && *cpp) { | ||
230 | /* return 0; */ | ||
231 | return NULL; | ||
232 | } else if (fields[7][0] == '\0') | ||
233 | spwd.sp_expire = -1; | ||
234 | |||
235 | /* | ||
236 | * This field is reserved for future use. But it isn't supposed | ||
237 | * to have anything other than a valid integer in it. | ||
238 | */ | ||
239 | |||
240 | if ((spwd.sp_flag = strtol(fields[8], &cpp, 10)) == 0 && *cpp) { | ||
241 | /* return 0; */ | ||
242 | return NULL; | ||
243 | } else if (fields[8][0] == '\0') | ||
244 | spwd.sp_flag = -1; | ||
245 | |||
246 | return (&spwd); | ||
247 | } | ||
248 | |||
249 | /* fgetspent - get an entry from an /etc/shadow formatted stream */ | ||
250 | struct spwd *fgetspent(FILE *fp) | ||
251 | { | ||
252 | char buf[BUFSIZ]; | ||
253 | char *cp; | ||
254 | |||
255 | if (!fp) | ||
256 | /* return (0); */ | ||
257 | return NULL; | ||
258 | |||
259 | if (fgets(buf, sizeof buf, fp) != (char *) 0) { | ||
260 | if ((cp = strchr(buf, '\n'))) | ||
261 | *cp = '\0'; | ||
262 | return (sgetspent(buf)); | ||
263 | } | ||
264 | /* return 0; */ | ||
265 | return NULL; | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * putspent - put a (struct spwd *) into the (FILE *) you provide. | ||
270 | * | ||
271 | * this was described in shadow_.h but not implemented, so here | ||
272 | * I go. -beppu | ||
273 | * | ||
274 | */ | ||
275 | int putspent(const struct spwd *sp, FILE *fp) | ||
276 | { | ||
277 | int ret; | ||
278 | |||
279 | /* seek to end */ | ||
280 | ret = fseek(fp, 0, SEEK_END); | ||
281 | if (ret == -1) { | ||
282 | /* return -1; */ | ||
283 | return 1; | ||
284 | } | ||
285 | |||
286 | /* powered by fprintf */ | ||
287 | fprintf(fp, "%s:%s:%ld:%ld:%ld:%ld:%ld:%ld:%s\n", sp->sp_namp, /* login name */ | ||
288 | sp->sp_pwdp, /* encrypted password */ | ||
289 | sp->sp_lstchg, /* date of last change */ | ||
290 | sp->sp_min, /* minimum number of days between changes */ | ||
291 | sp->sp_max, /* maximum number of days between changes */ | ||
292 | sp->sp_warn, /* number of days of warning before password expires */ | ||
293 | sp->sp_inact, /* number of days after password expires until | ||
294 | the account becomes unusable */ | ||
295 | sp->sp_expire, /* days since 1/1/70 until account expires */ | ||
296 | ""); | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | |||