aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2004-07-15 12:53:49 +0000
committerandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2004-07-15 12:53:49 +0000
commit48fb8b8392bda5c2a944489eb35572e5a9942bfa (patch)
tree863532a14dd40a1009cee3dac1dfa7fdd8bea653
parent8d067d680796f811a61decb8bbd6f63bf05c1f41 (diff)
downloadbusybox-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_.h113
-rw-r--r--include/pwd_.h105
-rw-r--r--include/shadow_.h162
-rw-r--r--libpwdgrp/Makefile.in31
-rw-r--r--libpwdgrp/__getgrent.c203
-rw-r--r--libpwdgrp/__getpwent.c115
-rw-r--r--libpwdgrp/fgetgrent.c35
-rw-r--r--libpwdgrp/fgetpwent.c35
-rw-r--r--libpwdgrp/getgrgid.c44
-rw-r--r--libpwdgrp/getgrnam.c50
-rw-r--r--libpwdgrp/getpw.c47
-rw-r--r--libpwdgrp/getpwnam.c51
-rw-r--r--libpwdgrp/getpwuid.c44
-rw-r--r--libpwdgrp/grent.c54
-rw-r--r--libpwdgrp/initgroups.c115
-rw-r--r--libpwdgrp/putpwent.c39
-rw-r--r--libpwdgrp/pwd_grp.c1116
-rw-r--r--libpwdgrp/pwent.c58
-rw-r--r--libpwdgrp/setgroups.c40
-rw-r--r--libpwdgrp/shadow.c300
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. */
15struct group 39struct 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
23extern void setgrent __P ((void));
24extern void endgrent __P ((void));
25extern struct group * getgrent __P ((void));
26 47
27extern struct group * getgrgid __P ((__const gid_t gid)); 48/* Rewind the group-file stream. */
28extern struct group * getgrnam __P ((__const char * name)); 49extern void setgrent (void);
50
51/* Close the group-file stream. */
52extern void endgrent (void);
53
54/* Read an entry from the group-file stream, opening it if necessary. */
55extern struct group *getgrent (void);
56
57/* Read a group entry from STREAM. */
58extern struct group *fgetgrent (FILE *__stream);
59
60/* Write the given entry onto the given stream. */
61extern int putgrent (__const struct group *__restrict __p,
62 FILE *__restrict __f);
63
64/* Search for an entry with a matching group ID. */
65extern struct group *getgrgid (gid_t __gid);
66
67/* Search for an entry with a matching group name. */
68extern 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
78extern 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. */
83extern 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. */
88extern 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. */
95extern 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
30extern struct group * fgetgrent __P ((FILE * file)); 100/* Set the group set for the current user to GROUPS (N of them). */
101extern int setgroups (size_t __n, __const gid_t *__groups);
31 102
32extern int setgroups __P ((size_t n, __const gid_t * groups)); 103/* Store at most *NGROUPS members of the group set for USER into
33extern 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. */
106extern int getgrouplist (__const char *__user, gid_t __group,
107 gid_t *__groups, int *__ngroups);
34 108
35extern 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. */
112extern 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. */
14struct passwd 36struct 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
25extern void setpwent __P ((void));
26extern void endpwent __P ((void));
27extern struct passwd * getpwent __P ((void));
28 47
29extern int putpwent __P ((__const struct passwd * __p, FILE * __f)); 48/* Rewind the password-file stream. */
30extern int getpw __P ((uid_t uid, char *buf)); 49extern void setpwent (void);
50
51/* Close the password-file stream. */
52extern void endpwent (void);
53
54/* Read an entry from the password-file stream, opening it if necessary. */
55extern struct passwd *getpwent (void);
56
57/* Read an entry from STREAM. */
58extern struct passwd *fgetpwent (FILE *__stream);
59
60/* Write the given entry onto the given stream. */
61extern int putpwent (__const struct passwd *__restrict __p,
62 FILE *__restrict __f);
63
64/* Search for an entry with a matching user ID. */
65extern struct passwd *getpwuid (uid_t __uid);
66
67/* Search for an entry with a matching username. */
68extern 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
78extern int getpwent_r (struct passwd *__restrict __resultbuf,
79 char *__restrict __buffer, size_t __buflen,
80 struct passwd **__restrict __result);
81
82extern 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
32extern struct passwd * fgetpwent __P ((FILE * file)); 87extern 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
34extern struct passwd * getpwuid __P ((__const uid_t));
35extern struct passwd * getpwnam __P ((__const char *));
36 92
37extern struct passwd * __getpwent __P ((__const int passwd_fd)); 93/* Read an entry from STREAM. This function is not standardized and
94 probably never will. */
95extern 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. */
103extern 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
45typedef 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. */
51struct spwd { 38struct 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. */
56extern void setspent (void);
57
58/* Close database. */
59extern void endspent (void);
60
61/* Get next entry from database, perhaps after opening the file. */
62extern struct spwd *getspent (void);
63
64/* Get shadow entry matching NAME. */
65extern struct spwd *getspnam (__const char *__name);
66
67/* Read shadow entry from STRING. */
68extern struct spwd *sgetspent (__const char *__string);
69
70/* Read next shadow entry from STREAM. */
71extern struct spwd *fgetspent (FILE *__stream);
72
73/* Write line containing shadow password entry to stream. */
74extern int putspent (__const struct spwd *__p, FILE *__stream);
75
76/* Reentrant versions of some of the functions above. */
77extern int getspent_r (struct spwd *__result_buf, char *__buffer,
78 size_t __buflen, struct spwd **__result);
79
80extern int getspnam_r (__const char *__name, struct spwd *__result_buf,
81 char *__buffer, size_t __buflen,
82 struct spwd **__result)__THROW;
83
84extern int sgetspent_r (__const char *__string, struct spwd *__result_buf,
85 char *__buffer, size_t __buflen,
86 struct spwd **__result);
70 87
71extern struct spwd *getspent(void); 88extern int fgetspent_r (FILE *__stream, struct spwd *__result_buf,
72extern struct spwd *sgetspent(const char *); 89 char *__buffer, size_t __buflen,
73extern struct spwd *fgetspent(FILE *); 90 struct spwd **__result);
74extern void setspent(void); 91/* Protect password file against multi writers. */
75extern void endspent(void); 92extern int lckpwdf (void);
76extern int putspent(const struct spwd *, FILE *);
77extern struct spwd *getspnam(const char *name);
78extern struct spwd *pwd_to_spwd(const struct passwd *pw);
79 93
80#endif /* USE_LOCAL_SHADOW */ 94/* Unlock password file. */
95extern 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)
22LIBPWDGRP_DIR:=$(TOPDIR)libpwdgrp/ 22LIBPWDGRP_DIR:=$(TOPDIR)libpwdgrp/
23endif 23endif
24 24
25LIBPWDGRP-y:= 25
26LIBPWDGRP-$(CONFIG_USE_BB_PWD_GRP) += __getgrent.o __getgrent.o __getpwent.o\ 26LIBPWDGRP_MSRC0:=$(LIBPWDGRP_DIR)pwd_grp.c
27 fgetgrent.o fgetpwent.o getgrgid.o getgrnam.o getpw.o getpwnam.o \ 27LIBPWDGRP_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 \
29LIBPWDGRP-$(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
32LIBPWDGRP_MOBJS0=$(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP_MOBJ0-y))
33
34LIBPWDGRP_MSRC1:=$(LIBPWDGRP_DIR)pwd_grp.c
35LIBPWDGRP_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
39LIBPWDGRP_MOBJS1=$(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP_MOBJ1-y))
30 40
31libraries-y+=$(LIBPWDGRP_DIR)$(LIBPWDGRP_AR) 41libraries-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 */
74struct 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
37struct 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
27struct 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
27struct 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
28struct 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
29struct 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
28int 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
30struct 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
28struct 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
33static int grp_fd = -1;
34
35void setgrent(void)
36{
37 if (grp_fd != -1)
38 close(grp_fd);
39 grp_fd = open(bb_path_group_file, O_RDONLY);
40}
41
42void endgrent(void)
43{
44 if (grp_fd != -1)
45 close(grp_fd);
46 grp_fd = -1;
47}
48
49struct 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
68int 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
27int 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
67extern int __parsepwent(void *pw, char *line);
68extern int __parsegrent(void *gr, char *line);
69extern int __parsespent(void *sp, char *line);
70
71extern 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
91int 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
110int 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
129int 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
152struct 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
166struct 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
180extern int fgetspent_r(FILE *__restrict stream, struct spwd *__restrict resultbuf,
181 char *__restrict buffer, size_t buflen,
182 struct spwd **__restrict result);
183struct 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
197int 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
280int 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
318struct 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
332struct 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
350int 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
374struct 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
388struct 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
402struct 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
416struct 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
430int 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
457static FILE *pwf /*= NULL*/;
458void setpwent(void)
459{
460 if (pwf) {
461 rewind(pwf);
462 }
463}
464
465void endpwent(void)
466{
467 if (pwf) {
468 fclose(pwf);
469 pwf = NULL;
470 }
471}
472
473
474int 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
502static FILE *grf /*= NULL*/;
503void setgrent(void)
504{
505 if (grf) {
506 rewind(grf);
507 }
508}
509
510void endgrent(void)
511{
512 if (grf) {
513 fclose(grf);
514 grf = NULL;
515 }
516}
517
518int 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
546static FILE *spf /*= NULL*/;
547void setspent(void)
548{
549 if (spf) {
550 rewind(spf);
551 }
552}
553
554void endspent(void)
555{
556 if (spf) {
557 fclose(spf);
558 spf = NULL;
559 }
560}
561
562int 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
589struct 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
603struct 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
617struct 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
631struct 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
645int 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
701int 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
726int 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
771static 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
780int 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
813DO_UNLOCK:
814 return rv;
815}
816
817#endif
818/**********************************************************************/
819/* Internal uClibc functions. */
820/**********************************************************************/
821#ifdef L___parsepwent
822
823static 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
833int __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
882static 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
888int __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
980static 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
992int __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
1058int __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 */
36static int pw_fd = -1;
37
38void 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
46void endpwent(void)
47{
48 if (pw_fd != -1)
49 close(pw_fd);
50 pw_fd = -1;
51}
52
53struct 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
35int 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
44static FILE *shadow;
45static char spwbuf[BUFSIZ];
46static struct spwd spwd;
47
48#define FIELDS 9
49#define OFIELDS 5
50
51/* setspent - initialize access to shadow text and DBM files */
52void 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 */
62void 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 */
70struct spwd *getspent(void)
71{
72 if (!shadow)
73 setspent();
74 return (fgetspent(shadow));
75}
76
77/* getspnam - get a shadow entry by name */
78struct 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 */
97struct 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 */
250struct 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 */
275int 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