Replace the old and somewhat buggy pwd_grp stuff with the shiny new stuff mjn3 wrote for uClibc
No binary (build failed)
—
(log yok)
| @@ -1,39 +1,116 @@ | |
| - | #ifndef __CONFIG_GRP_H |
| - | #define __CONFIG_GRP_H |
| + | /* Copyright (C) 1991,92,95,96,97,98,99,2000,01 Free Software Foundation, Inc. |
| + | This file is part of the GNU C Library. |
| + | |
| + | The GNU C Library is free software; you can redistribute it and/or |
| + | modify it under the terms of the GNU Lesser General Public |
| + | License as published by the Free Software Foundation; either |
| + | version 2.1 of the License, or (at your option) any later version. |
| + | |
| + | The GNU C Library is distributed in the hope that it will be useful, |
| + | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + | Lesser General Public License for more details. |
| + | |
| + | You should have received a copy of the GNU Lesser General Public |
| + | License along with the GNU C Library; if not, write to the Free |
| + | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| + | 02111-1307 USA. */ |
| + | |
| + | /* |
| + | * POSIX Standard: 9.2.1 Group Database Access <grp.h> |
| + | */ |
| + | |
| #if !defined CONFIG_USE_BB_PWD_GRP | |
| #include <grp.h> | |
| #else | |
| + | #ifndef _GRP_H |
| + | #define _GRP_H 1 |
| + | |
| + | |
| #include <sys/types.h> | |
| #include <features.h> | |
| #include <stdio.h> | |
| - | /* The group structure */ |
| + | /* The group structure. */ |
| struct group | |
| { | |
| - | char *gr_name; /* Group name. */ |
| - | char *gr_passwd; /* Password. */ |
| - | gid_t gr_gid; /* Group ID. */ |
| - | char **gr_mem; /* Member list. */ |
| + | char *gr_name; /* Group name. */ |
| + | char *gr_passwd; /* Password. */ |
| + | gid_t gr_gid; /* Group ID. */ |
| + | char **gr_mem; /* Member list. */ |
| }; | |
| - | extern void setgrent __P ((void)); |
| - | extern void endgrent __P ((void)); |
| - | extern struct group * getgrent __P ((void)); |
| - | extern struct group * getgrgid __P ((__const gid_t gid)); |
| - | extern struct group * getgrnam __P ((__const char * name)); |
| + | /* Rewind the group-file stream. */ |
| + | extern void setgrent (void); |
| + | |
| + | /* Close the group-file stream. */ |
| + | extern void endgrent (void); |
| + | |
| + | /* Read an entry from the group-file stream, opening it if necessary. */ |
| + | extern struct group *getgrent (void); |
| + | |
| + | /* Read a group entry from STREAM. */ |
| + | extern struct group *fgetgrent (FILE *__stream); |
| + | |
| + | /* Write the given entry onto the given stream. */ |
| + | extern int putgrent (__const struct group *__restrict __p, |
| + | FILE *__restrict __f); |
| + | |
| + | /* Search for an entry with a matching group ID. */ |
| + | extern struct group *getgrgid (gid_t __gid); |
| + | |
| + | /* Search for an entry with a matching group name. */ |
| + | extern struct group *getgrnam (__const char *__name); |
| + | |
| + | /* Reentrant versions of some of the functions above. |
| + | |
| + | PLEASE NOTE: the `getgrent_r' function is not (yet) standardized. |
| + | The interface may change in later versions of this library. But |
| + | the interface is designed following the principals used for the |
| + | other reentrant functions so the chances are good this is what the |
| + | POSIX people would choose. */ |
| + | |
| + | extern int getgrent_r (struct group *__restrict __resultbuf, |
| + | char *__restrict __buffer, size_t __buflen, |
| + | struct group **__restrict __result); |
| + | |
| + | /* Search for an entry with a matching group ID. */ |
| + | extern int getgrgid_r (gid_t __gid, struct group *__restrict __resultbuf, |
| + | char *__restrict __buffer, size_t __buflen, |
| + | struct group **__restrict __result); |
| + | |
| + | /* Search for an entry with a matching group name. */ |
| + | extern int getgrnam_r (__const char *__restrict __name, |
| + | struct group *__restrict __resultbuf, |
| + | char *__restrict __buffer, size_t __buflen, |
| + | struct group **__restrict __result); |
| + | |
| + | /* Read a group entry from STREAM. This function is not standardized |
| + | an probably never will. */ |
| + | extern int fgetgrent_r (FILE *__restrict __stream, |
| + | struct group *__restrict __resultbuf, |
| + | char *__restrict __buffer, size_t __buflen, |
| + | struct group **__restrict __result); |
| - | extern struct group * fgetgrent __P ((FILE * file)); |
| + | /* Set the group set for the current user to GROUPS (N of them). */ |
| + | extern int setgroups (size_t __n, __const gid_t *__groups); |
| - | extern int setgroups __P ((size_t n, __const gid_t * groups)); |
| - | extern int initgroups __P ((__const char * user, gid_t gid)); |
| + | /* Store at most *NGROUPS members of the group set for USER into |
| + | *GROUPS. Also include GROUP. The actual number of groups found is |
| + | returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */ |
| + | extern int getgrouplist (__const char *__user, gid_t __group, |
| + | gid_t *__groups, int *__ngroups); |
| - | extern struct group * bb_getgrent __P ((int grp_fd)); |
| + | /* Initialize the group set for the current user |
| + | by reading the group database and using all groups |
| + | of which USER is a member. Also include GROUP. */ |
| + | extern int initgroups (__const char *__user, gid_t __group); |
| - | #endif /* USE_SYSTEM_PWD_GRP */ |
| - | #endif /* __CONFIG_GRP_H */ |
| + | #endif /* grp.h */ |
| + | #endif |
| @@ -1,11 +1,33 @@ | |
| - | #ifndef __CONFIG_PWD_H |
| - | #define __CONFIG_PWD_H |
| + | /* Copyright (C) 1991,92,95,96,97,98,99,2001 Free Software Foundation, Inc. |
| + | This file is part of the GNU C Library. |
| + | |
| + | The GNU C Library is free software; you can redistribute it and/or |
| + | modify it under the terms of the GNU Lesser General Public |
| + | License as published by the Free Software Foundation; either |
| + | version 2.1 of the License, or (at your option) any later version. |
| + | |
| + | The GNU C Library is distributed in the hope that it will be useful, |
| + | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + | Lesser General Public License for more details. |
| + | |
| + | You should have received a copy of the GNU Lesser General Public |
| + | License along with the GNU C Library; if not, write to the Free |
| + | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| + | 02111-1307 USA. */ |
| + | |
| + | /* |
| + | * POSIX Standard: 9.2.2 User Database Access <pwd.h> |
| + | */ |
| #if !defined CONFIG_USE_BB_PWD_GRP | |
| #include <pwd.h> | |
| #else | |
| + | #ifndef _PWD_H |
| + | #define _PWD_H 1 |
| + | |
| #include <sys/types.h> | |
| #include <features.h> | |
| #include <stdio.h> | |
| @@ -13,29 +35,72 @@ | |
| /* The passwd structure. */ | |
| struct passwd | |
| { | |
| - | char *pw_name; /* Username. */ |
| - | char *pw_passwd; /* Password. */ |
| - | uid_t pw_uid; /* User ID. */ |
| - | gid_t pw_gid; /* Group ID. */ |
| - | char *pw_gecos; /* Real name. */ |
| - | char *pw_dir; /* Home directory. */ |
| - | char *pw_shell; /* Shell program. */ |
| + | char *pw_name; /* Username. */ |
| + | char *pw_passwd; /* Password. */ |
| + | uid_t pw_uid; /* User ID. */ |
| + | gid_t pw_gid; /* Group ID. */ |
| + | char *pw_gecos; /* Real name. */ |
| + | char *pw_dir; /* Home directory. */ |
| + | char *pw_shell; /* Shell program. */ |
| }; | |
| - | extern void setpwent __P ((void)); |
| - | extern void endpwent __P ((void)); |
| - | extern struct passwd * getpwent __P ((void)); |
| - | extern int putpwent __P ((__const struct passwd * __p, FILE * __f)); |
| - | extern int getpw __P ((uid_t uid, char *buf)); |
| + | /* Rewind the password-file stream. */ |
| + | extern void setpwent (void); |
| + | |
| + | /* Close the password-file stream. */ |
| + | extern void endpwent (void); |
| + | |
| + | /* Read an entry from the password-file stream, opening it if necessary. */ |
| + | extern struct passwd *getpwent (void); |
| + | |
| + | /* Read an entry from STREAM. */ |
| + | extern struct passwd *fgetpwent (FILE *__stream); |
| + | |
| + | /* Write the given entry onto the given stream. */ |
| + | extern int putpwent (__const struct passwd *__restrict __p, |
| + | FILE *__restrict __f); |
| + | |
| + | /* Search for an entry with a matching user ID. */ |
| + | extern struct passwd *getpwuid (uid_t __uid); |
| + | |
| + | /* Search for an entry with a matching username. */ |
| + | extern struct passwd *getpwnam (__const char *__name); |
| + | |
| + | /* Reentrant versions of some of the functions above. |
| + | |
| + | PLEASE NOTE: the `getpwent_r' function is not (yet) standardized. |
| + | The interface may change in later versions of this library. But |
| + | the interface is designed following the principals used for the |
| + | other reentrant functions so the chances are good this is what the |
| + | POSIX people would choose. */ |
| + | |
| + | extern int getpwent_r (struct passwd *__restrict __resultbuf, |
| + | char *__restrict __buffer, size_t __buflen, |
| + | struct passwd **__restrict __result); |
| + | |
| + | extern int getpwuid_r (uid_t __uid, |
| + | struct passwd *__restrict __resultbuf, |
| + | char *__restrict __buffer, size_t __buflen, |
| + | struct passwd **__restrict __result); |
| - | extern struct passwd * fgetpwent __P ((FILE * file)); |
| + | extern int getpwnam_r (__const char *__restrict __name, |
| + | struct passwd *__restrict __resultbuf, |
| + | char *__restrict __buffer, size_t __buflen, |
| + | struct passwd **__restrict __result); |
| - | extern struct passwd * getpwuid __P ((__const uid_t)); |
| - | extern struct passwd * getpwnam __P ((__const char *)); |
| - | extern struct passwd * __getpwent __P ((__const int passwd_fd)); |
| + | /* Read an entry from STREAM. This function is not standardized and |
| + | probably never will. */ |
| + | extern int fgetpwent_r (FILE *__restrict __stream, |
| + | struct passwd *__restrict __resultbuf, |
| + | char *__restrict __buffer, size_t __buflen, |
| + | struct passwd **__restrict __result); |
| - | #endif /* USE_SYSTEM_PWD_GRP */ |
| - | #endif /* __CONFIG_PWD_H */ |
| + | /* Re-construct the password-file line for the given uid |
| + | in the given buffer. This knows the format that the caller |
| + | will expect, but this need not be the format of the password file. */ |
| + | extern int getpw (uid_t __uid, char *__buffer); |
| + | #endif /* pwd.h */ |
| + | #endif |
| @@ -1,82 +1,98 @@ | |
| - | /* |
| - | * Copyright 1988 - 1994, Julianne Frances Haugh <[email protected]> |
| - | * All rights reserved. |
| - | * |
| - | * Redistribution and use in source and binary forms, with or without |
| - | * modification, are permitted provided that the following conditions |
| - | * are met: |
| - | * 1. Redistributions of source code must retain the above copyright |
| - | * notice, this list of conditions and the following disclaimer. |
| - | * 2. Redistributions in binary form must reproduce the above copyright |
| - | * notice, this list of conditions and the following disclaimer in the |
| - | * documentation and/or other materials provided with the distribution. |
| - | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors |
| - | * may be used to endorse or promote products derived from this software |
| - | * without specific prior written permission. |
| - | * |
| - | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND |
| - | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| - | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| - | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE |
| - | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| - | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| - | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| - | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| - | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| - | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| - | * SUCH DAMAGE. |
| - | */ |
| - | |
| - | #ifndef _H_SHADOW |
| - | #define _H_SHADOW |
| - | |
| - | |
| - | #ifdef USE_SYSTEM_SHADOW |
| + | /* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. |
| + | This file is part of the GNU C Library. |
| + | |
| + | The GNU C Library is free software; you can redistribute it and/or |
| + | modify it under the terms of the GNU Lesser General Public |
| + | License as published by the Free Software Foundation; either |
| + | version 2.1 of the License, or (at your option) any later version. |
| + | |
| + | The GNU C Library is distributed in the hope that it will be useful, |
| + | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + | Lesser General Public License for more details. |
| + | |
| + | You should have received a copy of the GNU Lesser General Public |
| + | License along with the GNU C Library; if not, write to the Free |
| + | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| + | 02111-1307 USA. */ |
| + | |
| + | /* Declaration of types and functions for shadow password suite. */ |
| + | |
| + | #if !defined CONFIG_USE_BB_SHADOW |
| #include <shadow.h> | |
| #else | |
| - | /* |
| - | * This information is not derived from AT&T licensed sources. Posted |
| - | * to the USENET 11/88, and updated 11/90 with information from SVR4. |
| - | * |
| - | * $Id: shadow_.h,v 1.1 2002/06/23 04:24:20 andersen Exp $ |
| - | */ |
| - | |
| - | typedef long sptime; |
| - | |
| - | /* |
| - | * Shadow password security file structure. |
| - | */ |
| - | |
| - | struct spwd { |
| - | char *sp_namp; /* login name */ |
| - | char *sp_pwdp; /* encrypted password */ |
| - | sptime sp_lstchg; /* date of last change */ |
| - | sptime sp_min; /* minimum number of days between changes */ |
| - | sptime sp_max; /* maximum number of days between changes */ |
| - | sptime sp_warn; /* number of days of warning before password |
| - | expires */ |
| - | sptime sp_inact; /* number of days after password expires |
| - | until the account becomes unusable. */ |
| - | sptime sp_expire; /* days since 1/1/70 until account expires */ |
| - | unsigned long sp_flag; /* reserved for future use */ |
| + | #ifndef _SHADOW_H |
| + | #define _SHADOW_H 1 |
| + | |
| + | #include <stdio.h> |
| + | |
| + | /* Paths to the user database files. */ |
| + | #ifndef _PATH_SHADOW |
| + | #define _PATH_SHADOW "/etc/shadow" |
| + | #endif |
| + | #define SHADOW _PATH_SHADOW |
| + | |
| + | |
| + | /* Structure of the password file. */ |
| + | struct spwd |
| + | { |
| + | char *sp_namp; /* Login name. */ |
| + | char *sp_pwdp; /* Encrypted password. */ |
| + | long int sp_lstchg; /* Date of last change. */ |
| + | long int sp_min; /* Minimum number of days between changes. */ |
| + | long int sp_max; /* Maximum number of days between changes. */ |
| + | long int sp_warn; /* Number of days to warn user to change |
| + | the password. */ |
| + | long int sp_inact; /* Number of days the account may be |
| + | inactive. */ |
| + | long int sp_expire; /* Number of days since 1970-01-01 until |
| + | account expires. */ |
| + | unsigned long int sp_flag; /* Reserved. */ |
| }; | |
| - | /* |
| - | * Shadow password security file functions. |
| - | */ |
| - | #include <stdio.h> /* for FILE */ |
| + | /* Open database for reading. */ |
| + | extern void setspent (void); |
| + | |
| + | /* Close database. */ |
| + | extern void endspent (void); |
| + | |
| + | /* Get next entry from database, perhaps after opening the file. */ |
| + | extern struct spwd *getspent (void); |
| + | |
| + | /* Get shadow entry matching NAME. */ |
| + | extern struct spwd *getspnam (__const char *__name); |
| + | |
| + | /* Read shadow entry from STRING. */ |
| + | extern struct spwd *sgetspent (__const char *__string); |
| + | |
| + | /* Read next shadow entry from STREAM. */ |
| + | extern struct spwd *fgetspent (FILE *__stream); |
| + | |
| + | /* Write line containing shadow password entry to stream. */ |
| + | extern int putspent (__const struct spwd *__p, FILE *__stream); |
| + | |
| + | /* Reentrant versions of some of the functions above. */ |
| + | extern int getspent_r (struct spwd *__result_buf, char *__buffer, |
| + | size_t __buflen, struct spwd **__result); |
| + | |
| + | extern int getspnam_r (__const char *__name, struct spwd *__result_buf, |
| + | char *__buffer, size_t __buflen, |
| + | struct spwd **__result)__THROW; |
| + | |
| + | extern int sgetspent_r (__const char *__string, struct spwd *__result_buf, |
| + | char *__buffer, size_t __buflen, |
| + | struct spwd **__result); |
| - | extern struct spwd *getspent(void); |
| - | extern struct spwd *sgetspent(const char *); |
| - | extern struct spwd *fgetspent(FILE *); |
| - | extern void setspent(void); |
| - | extern void endspent(void); |
| - | extern int putspent(const struct spwd *, FILE *); |
| - | extern struct spwd *getspnam(const char *name); |
| - | extern struct spwd *pwd_to_spwd(const struct passwd *pw); |
| + | extern int fgetspent_r (FILE *__stream, struct spwd *__result_buf, |
| + | char *__buffer, size_t __buflen, |
| + | struct spwd **__result); |
| + | /* Protect password file against multi writers. */ |
| + | extern int lckpwdf (void); |
| - | #endif /* USE_LOCAL_SHADOW */ |
| + | /* Unlock password file. */ |
| + | extern int ulckpwdf (void); |
| - | #endif /* _H_SHADOW */ |
| + | #endif /* shadow.h */ |
| + | #endif |
| @@ -22,14 +22,31 @@ ifndef $(LIBPWDGRP_DIR) | |
| LIBPWDGRP_DIR:=$(TOPDIR)libpwdgrp/ | |
| endif | |
| - | LIBPWDGRP-y:= |
| - | LIBPWDGRP-$(CONFIG_USE_BB_PWD_GRP) += __getgrent.o __getgrent.o __getpwent.o\ |
| - | fgetgrent.o fgetpwent.o getgrgid.o getgrnam.o getpw.o getpwnam.o \ |
| - | getpwuid.o grent.o initgroups.o putpwent.o pwent.o setgroups.o |
| - | LIBPWDGRP-$(CONFIG_USE_BB_SHADOW) += shadow.o |
| + | |
| + | LIBPWDGRP_MSRC0:=$(LIBPWDGRP_DIR)pwd_grp.c |
| + | LIBPWDGRP_MOBJ0-$(CONFIG_USE_BB_PWD_GRP):= fgetpwent_r.o fgetgrent_r.o \ |
| + | fgetpwent.o fgetgrent.o getpwnam_r.o getgrnam_r.o getpwuid_r.o \ |
| + | getgrgid_r.o getpwuid.o getgrgid.o getpwnam.o getgrnam.o getpw.o \ |
| + | getpwent_r.o getgrent_r.o getpwent.o getgrent.o \ |
| + | initgroups.o putpwent.o putgrent.o |
| + | LIBPWDGRP_MOBJS0=$(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP_MOBJ0-y)) |
| + | |
| + | LIBPWDGRP_MSRC1:=$(LIBPWDGRP_DIR)pwd_grp.c |
| + | LIBPWDGRP_MOBJ1-$(CONFIG_USE_BB_PWD_GRP):= __parsepwent.o __parsegrent.o \ |
| + | __pgsreader.o fgetspent_r.o fgetspent.o sgetspent_r.o getspnam_r.o \ |
| + | getspnam.o getspent_r.o getspent.o sgetspent.o \ |
| + | putspent.o __parsespent.o # getspuid_r.o getspuid.o |
| + | LIBPWDGRP_MOBJS1=$(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP_MOBJ1-y)) |
| libraries-y+=$(LIBPWDGRP_DIR)$(LIBPWDGRP_AR) | |
| - | $(LIBPWDGRP_DIR)$(LIBPWDGRP_AR): $(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP-y)) |
| - | $(AR) -ro $@ $(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP-y)) |
| + | $(LIBPWDGRP_DIR)$(LIBPWDGRP_AR): $(LIBPWDGRP_MOBJS0) $(LIBPWDGRP_MOBJS1) |
| + | $(AR) -ro $@ $(LIBPWDGRP_MOBJS0) $(LIBPWDGRP_MOBJS1) |
| + | |
| + | $(LIBPWDGRP_MOBJS0): $(LIBPWDGRP_MSRC0) |
| + | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DL_$(notdir $*) -c $< -o $@ |
| + | |
| + | $(LIBPWDGRP_MOBJS1): $(LIBPWDGRP_MSRC1) |
| + | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DL_$(notdir $*) -c $< -o $@ |
| + | |
| @@ -1,203 +0,0 @@ | |
| - | /* |
| - | * __getgrent.c - This file is part of the libc-8086/grp package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include <unistd.h> |
| - | #include <stdlib.h> |
| - | #include <string.h> |
| - | |
| - | #include "busybox.h" |
| - | #include "grp_.h" |
| - | |
| - | /* |
| - | * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer |
| - | * so that lines of any length can be used. On very very small systems, |
| - | * you may want to leave this undefined because it will make the grp functions |
| - | * somewhat larger (because of the inclusion of malloc and the code necessary). |
| - | * On larger systems, you will want to define this, because grp will _not_ |
| - | * deal with long lines gracefully (they will be skipped). |
| - | */ |
| - | #undef GR_SCALE_DYNAMIC |
| - | |
| - | #ifndef GR_SCALE_DYNAMIC |
| - | /* |
| - | * If scaling is not dynamic, the buffers will be statically allocated, and |
| - | * maximums must be chosen. GR_MAX_LINE_LEN is the maximum number of |
| - | * characters per line in the group file. GR_MAX_MEMBERS is the maximum |
| - | * number of members of any given group. |
| - | */ |
| - | #define GR_MAX_LINE_LEN 128 |
| - | /* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */ |
| - | #define GR_MAX_MEMBERS 11 |
| - | |
| - | #endif /* !GR_SCALE_DYNAMIC */ |
| - | |
| - | |
| - | /* |
| - | * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate |
| - | * space for it's GID array before calling setgroups(). This is probably |
| - | * unnecessary scalage, so it's undefined by default. |
| - | */ |
| - | #undef GR_DYNAMIC_GROUP_LIST |
| - | |
| - | #ifndef GR_DYNAMIC_GROUP_LIST |
| - | /* |
| - | * GR_MAX_GROUPS is the size of the static array initgroups() uses for |
| - | * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined. |
| - | */ |
| - | #define GR_MAX_GROUPS 64 |
| - | |
| - | #endif /* !GR_DYNAMIC_GROUP_LIST */ |
| - | |
| - | |
| - | /* |
| - | * This is the core group-file read function. It behaves exactly like |
| - | * getgrent() except that it is passed a file descriptor. getgrent() |
| - | * is just a wrapper for this function. |
| - | */ |
| - | struct group *bb_getgrent(int grp_fd) |
| - | { |
| - | #ifndef GR_SCALE_DYNAMIC |
| - | static char line_buff[GR_MAX_LINE_LEN]; |
| - | static char *members[GR_MAX_MEMBERS]; |
| - | #else |
| - | static char *line_buff = NULL; |
| - | static char **members = NULL; |
| - | short line_index; |
| - | short buff_size; |
| - | #endif |
| - | static struct group group; |
| - | register char *ptr; |
| - | char *field_begin; |
| - | short member_num; |
| - | char *endptr; |
| - | int line_len; |
| - | |
| - | |
| - | /* We use the restart label to handle malformatted lines */ |
| - | restart: |
| - | #ifdef GR_SCALE_DYNAMIC |
| - | line_index = 0; |
| - | buff_size = 256; |
| - | #endif |
| - | |
| - | #ifndef GR_SCALE_DYNAMIC |
| - | /* Read the line into the static buffer */ |
| - | if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) |
| - | return NULL; |
| - | field_begin = strchr(line_buff, '\n'); |
| - | if (field_begin != NULL) |
| - | lseek(grp_fd, (long) (1 + field_begin - (line_buff + line_len)), |
| - | SEEK_CUR); |
| - | else { /* The line is too long - skip it :-\ */ |
| - | |
| - | do { |
| - | if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) |
| - | return NULL; |
| - | } while (!(field_begin = strchr(line_buff, '\n'))); |
| - | lseek(grp_fd, (long) ((field_begin - line_buff) - line_len + 1), |
| - | SEEK_CUR); |
| - | goto restart; |
| - | } |
| - | if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' || |
| - | *line_buff == '\t') |
| - | goto restart; |
| - | *field_begin = '\0'; |
| - | |
| - | #else /* !GR_SCALE_DYNAMIC */ |
| - | line_buff = realloc(line_buff, buff_size); |
| - | while (1) { |
| - | if ((line_len = read(grp_fd, line_buff + line_index, |
| - | buff_size - line_index)) <= 0) |
| - | return NULL; |
| - | field_begin = strchr(line_buff, '\n'); |
| - | if (field_begin != NULL) { |
| - | lseek(grp_fd, |
| - | (long) (1 + field_begin - |
| - | (line_len + line_index + line_buff)), SEEK_CUR); |
| - | *field_begin = '\0'; |
| - | if (*line_buff == '#' || *line_buff == ' ' |
| - | || *line_buff == '\n' || *line_buff == '\t') |
| - | goto restart; |
| - | break; |
| - | } else { /* Allocate some more space */ |
| - | |
| - | line_index = buff_size; |
| - | buff_size += 256; |
| - | line_buff = realloc(line_buff, buff_size); |
| - | } |
| - | } |
| - | #endif /* GR_SCALE_DYNAMIC */ |
| - | |
| - | /* Now parse the line */ |
| - | group.gr_name = line_buff; |
| - | ptr = strchr(line_buff, ':'); |
| - | if (ptr == NULL) |
| - | goto restart; |
| - | *ptr++ = '\0'; |
| - | |
| - | group.gr_passwd = ptr; |
| - | ptr = strchr(ptr, ':'); |
| - | if (ptr == NULL) |
| - | goto restart; |
| - | *ptr++ = '\0'; |
| - | |
| - | field_begin = ptr; |
| - | ptr = strchr(ptr, ':'); |
| - | if (ptr == NULL) |
| - | goto restart; |
| - | *ptr++ = '\0'; |
| - | |
| - | group.gr_gid = (gid_t) strtoul(field_begin, &endptr, 10); |
| - | if (*endptr != '\0') |
| - | goto restart; |
| - | |
| - | member_num = 0; |
| - | field_begin = ptr; |
| - | |
| - | #ifndef GR_SCALE_DYNAMIC |
| - | while ((ptr = strchr(ptr, ',')) != NULL) { |
| - | *ptr = '\0'; |
| - | ptr++; |
| - | members[member_num] = field_begin; |
| - | field_begin = ptr; |
| - | member_num++; |
| - | } |
| - | if (*field_begin == '\0') |
| - | members[member_num] = NULL; |
| - | else { |
| - | members[member_num] = field_begin; |
| - | members[member_num + 1] = NULL; |
| - | } |
| - | #else /* !GR_SCALE_DYNAMIC */ |
| - | free(members); |
| - | members = (char **) malloc((member_num + 1) * sizeof(char *)); |
| - | for ( ; field_begin && *field_begin != '\0'; field_begin = ptr) { |
| - | if ((ptr = strchr(field_begin, ',')) != NULL) |
| - | *ptr++ = '\0'; |
| - | members[member_num++] = field_begin; |
| - | members = (char **) realloc(members, |
| - | (member_num + 1) * sizeof(char *)); |
| - | } |
| - | members[member_num] = NULL; |
| - | #endif /* GR_SCALE_DYNAMIC */ |
| - | |
| - | group.gr_mem = members; |
| - | return &group; |
| - | } |
| @@ -1,115 +0,0 @@ | |
| - | /* |
| - | * __getpwent.c - This file is part of the libc-8086/pwd package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include <stdlib.h> |
| - | #include <unistd.h> |
| - | #include <string.h> |
| - | #include <fcntl.h> |
| - | |
| - | #include "pwd_.h" |
| - | #include "busybox.h" |
| - | |
| - | #define PWD_BUFFER_SIZE 256 |
| - | |
| - | /* This isn't as flash as my previous version -- it doesn't dynamically |
| - | scale down the gecos on too-long lines, but it also makes fewer syscalls, |
| - | so it's probably nicer. Write me if you want the old version. Maybe I |
| - | should include it as a build-time option... ? |
| - | -Nat <[email protected]> */ |
| - | |
| - | struct passwd *__getpwent(int pwd_fd) |
| - | { |
| - | static char line_buff[PWD_BUFFER_SIZE]; |
| - | static struct passwd passwd; |
| - | char *field_begin; |
| - | char *endptr; |
| - | char *gid_ptr=NULL; |
| - | char *uid_ptr=NULL; |
| - | int line_len; |
| - | int i; |
| - | |
| - | /* We use the restart label to handle malformatted lines */ |
| - | restart: |
| - | /* Read the passwd line into the static buffer using a minimal of |
| - | syscalls. */ |
| - | if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0) |
| - | return NULL; |
| - | field_begin = strchr(line_buff, '\n'); |
| - | if (field_begin != NULL) |
| - | lseek(pwd_fd, (long) (1 + field_begin - (line_buff + line_len)), |
| - | SEEK_CUR); |
| - | else { /* The line is too long - skip it. :-\ */ |
| - | |
| - | do { |
| - | if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0) |
| - | return NULL; |
| - | } while (!(field_begin = strchr(line_buff, '\n'))); |
| - | lseek(pwd_fd, (long) (field_begin - line_buff) - line_len + 1, |
| - | SEEK_CUR); |
| - | goto restart; |
| - | } |
| - | if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' || |
| - | *line_buff == '\t') |
| - | goto restart; |
| - | *field_begin = '\0'; |
| - | |
| - | /* We've read the line; now parse it. */ |
| - | field_begin = line_buff; |
| - | for (i = 0; i < 7; i++) { |
| - | switch (i) { |
| - | case 0: |
| - | passwd.pw_name = field_begin; |
| - | break; |
| - | case 1: |
| - | passwd.pw_passwd = field_begin; |
| - | break; |
| - | case 2: |
| - | uid_ptr = field_begin; |
| - | break; |
| - | case 3: |
| - | gid_ptr = field_begin; |
| - | break; |
| - | case 4: |
| - | passwd.pw_gecos = field_begin; |
| - | break; |
| - | case 5: |
| - | passwd.pw_dir = field_begin; |
| - | break; |
| - | case 6: |
| - | passwd.pw_shell = field_begin; |
| - | break; |
| - | } |
| - | if (i < 6) { |
| - | field_begin = strchr(field_begin, ':'); |
| - | if (field_begin == NULL) |
| - | goto restart; |
| - | *field_begin++ = '\0'; |
| - | } |
| - | } |
| - | passwd.pw_gid = (gid_t) strtoul(gid_ptr, &endptr, 10); |
| - | if (*endptr != '\0') |
| - | goto restart; |
| - | |
| - | passwd.pw_uid = (uid_t) strtoul(uid_ptr, &endptr, 10); |
| - | if (*endptr != '\0') |
| - | goto restart; |
| - | |
| - | return &passwd; |
| - | } |
| @@ -1,35 +0,0 @@ | |
| - | /* |
| - | * fgetgrent.c - This file is part of the libc-8086/grp package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #include <stdio.h> |
| - | #include <errno.h> |
| - | #include "grp_.h" |
| - | |
| - | struct group *fgetgrent(FILE * file) |
| - | { |
| - | if (file == NULL) { |
| - | errno = EINTR; |
| - | return NULL; |
| - | } |
| - | |
| - | return bb_getgrent(fileno(file)); |
| - | } |
| @@ -1,35 +0,0 @@ | |
| - | /* |
| - | * fgetpwent.c - This file is part of the libc-8086/pwd package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #include <errno.h> |
| - | #include <stdio.h> |
| - | #include "pwd_.h" |
| - | |
| - | struct passwd *fgetpwent(FILE * file) |
| - | { |
| - | if (file == NULL) { |
| - | errno = EINTR; |
| - | return NULL; |
| - | } |
| - | |
| - | return __getpwent(fileno(file)); |
| - | } |
| @@ -1,44 +0,0 @@ | |
| - | /* |
| - | * getgrgid.c - This file is part of the libc-8086/grp package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #include <sys/types.h> |
| - | #include <unistd.h> |
| - | #include <fcntl.h> |
| - | #include "grp_.h" |
| - | |
| - | struct group *getgrgid(const gid_t gid) |
| - | { |
| - | struct group *group; |
| - | int grp_fd; |
| - | |
| - | if ((grp_fd = open(bb_path_group_file, O_RDONLY)) < 0) |
| - | return NULL; |
| - | |
| - | while ((group = bb_getgrent(grp_fd)) != NULL) |
| - | if (group->gr_gid == gid) { |
| - | close(grp_fd); |
| - | return group; |
| - | } |
| - | |
| - | close(grp_fd); |
| - | return NULL; |
| - | } |
| @@ -1,50 +0,0 @@ | |
| - | /* |
| - | * getgrnam.c - This file is part of the libc-8086/grp package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #include <unistd.h> |
| - | #include <string.h> |
| - | #include <errno.h> |
| - | #include <fcntl.h> |
| - | #include "grp_.h" |
| - | |
| - | struct group *getgrnam(const char *name) |
| - | { |
| - | int grp_fd; |
| - | struct group *group; |
| - | |
| - | if (name == NULL) { |
| - | errno = EINVAL; |
| - | return NULL; |
| - | } |
| - | |
| - | if ((grp_fd = open(bb_path_group_file, O_RDONLY)) < 0) |
| - | return NULL; |
| - | |
| - | while ((group = bb_getgrent(grp_fd)) != NULL) |
| - | if (!strcmp(group->gr_name, name)) { |
| - | close(grp_fd); |
| - | return group; |
| - | } |
| - | |
| - | close(grp_fd); |
| - | return NULL; |
| - | } |
| @@ -1,47 +0,0 @@ | |
| - | /* |
| - | * getpw.c - This file is part of the libc-8086/pwd package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #include <sys/types.h> |
| - | #include <errno.h> |
| - | #include <stdio.h> |
| - | #include "pwd_.h" |
| - | |
| - | int getpw(uid_t uid, char *buf) |
| - | { |
| - | struct passwd *passwd; |
| - | |
| - | if (buf == NULL) { |
| - | errno = EINVAL; |
| - | return -1; |
| - | } |
| - | if ((passwd = getpwuid(uid)) == NULL) |
| - | return -1; |
| - | |
| - | if (sprintf (buf, "%s:%s:%u:%u:%s:%s:%s", passwd->pw_name, passwd->pw_passwd, |
| - | passwd->pw_gid, passwd->pw_uid, passwd->pw_gecos, passwd->pw_dir, |
| - | passwd->pw_shell) < 0) { |
| - | errno = ENOBUFS; |
| - | return -1; |
| - | } |
| - | |
| - | return 0; |
| - | } |
| @@ -1,51 +0,0 @@ | |
| - | /* |
| - | * getpwnam.c - This file is part of the libc-8086/pwd package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #include <unistd.h> |
| - | #include <string.h> |
| - | #include <errno.h> |
| - | #include <fcntl.h> |
| - | #include "pwd_.h" |
| - | |
| - | |
| - | struct passwd *getpwnam(const char *name) |
| - | { |
| - | int passwd_fd; |
| - | struct passwd *passwd; |
| - | |
| - | if (name == NULL) { |
| - | errno = EINVAL; |
| - | return NULL; |
| - | } |
| - | |
| - | if ((passwd_fd = open(bb_path_passwd_file, O_RDONLY)) < 0) |
| - | return NULL; |
| - | |
| - | while ((passwd = __getpwent(passwd_fd)) != NULL) |
| - | if (!strcmp(passwd->pw_name, name)) { |
| - | close(passwd_fd); |
| - | return passwd; |
| - | } |
| - | |
| - | close(passwd_fd); |
| - | return NULL; |
| - | } |
| @@ -1,44 +0,0 @@ | |
| - | /* |
| - | * getpwuid.c - This file is part of the libc-8086/pwd package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include <stdlib.h> |
| - | #include <unistd.h> |
| - | #include <fcntl.h> |
| - | |
| - | #include "busybox.h" |
| - | #include "pwd_.h" |
| - | |
| - | struct passwd *getpwuid(uid_t uid) |
| - | { |
| - | int passwd_fd; |
| - | struct passwd *passwd; |
| - | |
| - | if ((passwd_fd = open(bb_path_passwd_file, O_RDONLY)) < 0) |
| - | return NULL; |
| - | |
| - | while ((passwd = __getpwent(passwd_fd)) != NULL) |
| - | if (passwd->pw_uid == uid) { |
| - | close(passwd_fd); |
| - | return passwd; |
| - | } |
| - | |
| - | close(passwd_fd); |
| - | return NULL; |
| - | } |
| @@ -1,54 +0,0 @@ | |
| - | /* |
| - | * grent.c - This file is part of the libc-8086/grp package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | /* |
| - | * setgrent(), endgrent(), and getgrent() are mutually-dependent functions, |
| - | * so they are all included in the same object file, and thus all linked |
| - | * in together. |
| - | */ |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #include <unistd.h> |
| - | #include <fcntl.h> |
| - | #include "grp_.h" |
| - | |
| - | static int grp_fd = -1; |
| - | |
| - | void setgrent(void) |
| - | { |
| - | if (grp_fd != -1) |
| - | close(grp_fd); |
| - | grp_fd = open(bb_path_group_file, O_RDONLY); |
| - | } |
| - | |
| - | void endgrent(void) |
| - | { |
| - | if (grp_fd != -1) |
| - | close(grp_fd); |
| - | grp_fd = -1; |
| - | } |
| - | |
| - | struct group *getgrent(void) |
| - | { |
| - | if (grp_fd == -1) |
| - | return NULL; |
| - | return bb_getgrent(grp_fd); |
| - | } |
| @@ -1,115 +0,0 @@ | |
| - | /* |
| - | * initgroups.c - This file is part of the libc-8086/grp package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #include <unistd.h> |
| - | #include <string.h> |
| - | #include <fcntl.h> |
| - | #include "grp_.h" |
| - | |
| - | /* |
| - | * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer |
| - | * so that lines of any length can be used. On very very small systems, |
| - | * you may want to leave this undefined because it will make the grp functions |
| - | * somewhat larger (because of the inclusion of malloc and the code necessary). |
| - | * On larger systems, you will want to define this, because grp will _not_ |
| - | * deal with long lines gracefully (they will be skipped). |
| - | */ |
| - | #undef GR_SCALE_DYNAMIC |
| - | |
| - | #ifndef GR_SCALE_DYNAMIC |
| - | /* |
| - | * If scaling is not dynamic, the buffers will be statically allocated, and |
| - | * maximums must be chosen. GR_MAX_LINE_LEN is the maximum number of |
| - | * characters per line in the group file. GR_MAX_MEMBERS is the maximum |
| - | * number of members of any given group. |
| - | */ |
| - | #define GR_MAX_LINE_LEN 128 |
| - | /* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */ |
| - | #define GR_MAX_MEMBERS 11 |
| - | |
| - | #endif /* !GR_SCALE_DYNAMIC */ |
| - | |
| - | |
| - | /* |
| - | * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate |
| - | * space for it's GID array before calling setgroups(). This is probably |
| - | * unnecessary scalage, so it's undefined by default. |
| - | */ |
| - | #undef GR_DYNAMIC_GROUP_LIST |
| - | |
| - | #ifndef GR_DYNAMIC_GROUP_LIST |
| - | /* |
| - | * GR_MAX_GROUPS is the size of the static array initgroups() uses for |
| - | * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined. |
| - | */ |
| - | #define GR_MAX_GROUPS 64 |
| - | |
| - | #endif /* !GR_DYNAMIC_GROUP_LIST */ |
| - | |
| - | int initgroups(__const char *user, gid_t gid) |
| - | { |
| - | register struct group *group; |
| - | |
| - | #ifndef GR_DYNAMIC_GROUP_LIST |
| - | gid_t group_list[GR_MAX_GROUPS]; |
| - | #else |
| - | gid_t *group_list = NULL; |
| - | #endif |
| - | register char **tmp_mem; |
| - | int num_groups; |
| - | int grp_fd; |
| - | |
| - | |
| - | if ((grp_fd = open(bb_path_group_file, O_RDONLY)) < 0) |
| - | return -1; |
| - | |
| - | num_groups = 0; |
| - | #ifdef GR_DYNAMIC_GROUP_LIST |
| - | group_list = (gid_t *) realloc(group_list, 1); |
| - | #endif |
| - | group_list[num_groups] = gid; |
| - | #ifndef GR_DYNAMIC_GROUP_LIST |
| - | while (num_groups < GR_MAX_GROUPS && |
| - | (group = bb_getgrent(grp_fd)) != NULL) |
| - | #else |
| - | while ((group = bb_getgrent(grp_fd)) != NULL) |
| - | #endif |
| - | { |
| - | if (group->gr_gid != gid) |
| - | { |
| - | tmp_mem = group->gr_mem; |
| - | while (*tmp_mem != NULL) { |
| - | if (!strcmp(*tmp_mem, user)) { |
| - | num_groups++; |
| - | #ifdef GR_DYNAMIC_GROUP_LIST |
| - | group_list = (gid_t *) realloc(group_list, num_groups * |
| - | sizeof(gid_t *)); |
| - | #endif |
| - | group_list[num_groups-1] = group->gr_gid; |
| - | } |
| - | tmp_mem++; |
| - | } |
| - | } |
| - | } |
| - | close(grp_fd); |
| - | return setgroups(num_groups, group_list); |
| - | } |
| @@ -1,39 +0,0 @@ | |
| - | /* |
| - | * putpwent.c - This file is part of the libc-8086/pwd package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #include <stdio.h> |
| - | #include <errno.h> |
| - | #include "pwd_.h" |
| - | |
| - | int putpwent(const struct passwd *passwd, FILE * f) |
| - | { |
| - | if (passwd == NULL || f == NULL) { |
| - | errno = EINVAL; |
| - | return -1; |
| - | } |
| - | if (fprintf (f, "%s:%s:%u:%u:%s:%s:%s\n", passwd->pw_name, passwd->pw_passwd, |
| - | passwd->pw_uid, passwd->pw_gid, passwd->pw_gecos, passwd->pw_dir, |
| - | passwd->pw_shell) < 0) |
| - | return -1; |
| - | |
| - | return 0; |
| - | } |
| @@ -0,0 +1,1116 @@ | |
| + | /* Copyright (C) 2003 Manuel Novoa III |
| + | * |
| + | * This library is free software; you can redistribute it and/or |
| + | * modify it under the terms of the GNU Library General Public |
| + | * License as published by the Free Software Foundation; either |
| + | * version 2 of the License, or (at your option) any later version. |
| + | * |
| + | * This library is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + | * Library General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU Library General Public |
| + | * License along with this library; if not, write to the Free |
| + | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| + | */ |
| + | |
| + | /* Nov 6, 2003 Initial version. |
| + | * |
| + | * NOTE: This implementation is quite strict about requiring all |
| + | * field seperators. It also does not allow leading whitespace |
| + | * except when processing the numeric fields. glibc is more |
| + | * lenient. See the various glibc difference comments below. |
| + | * |
| + | * TODO: |
| + | * Move to dynamic allocation of (currently staticly allocated) |
| + | * buffers; especially for the group-related functions since |
| + | * large group member lists will cause error returns. |
| + | * |
| + | */ |
| + | |
| + | #include <features.h> |
| + | #include <stdio.h> |
| + | #include <stdlib.h> |
| + | #include <stdint.h> |
| + | #include <string.h> |
| + | #include <stddef.h> |
| + | #include <errno.h> |
| + | #include <assert.h> |
| + | #include <ctype.h> |
| + | #include "busybox.h" |
| + | #include "pwd_.h" |
| + | #include "grp_.h" |
| + | #include "shadow_.h" |
| + | |
| + | #ifndef _PATH_SHADOW |
| + | #define _PATH_SHADOW "/etc/shadow" |
| + | #endif |
| + | #ifndef _PATH_PASSWD |
| + | #define _PATH_PASSWD "/etc/passwd" |
| + | #endif |
| + | #ifndef _PATH_GROUP |
| + | #define _PATH_GROUP "/etc/group" |
| + | #endif |
| + | |
| + | /**********************************************************************/ |
| + | /* Sizes for staticly allocated buffers. */ |
| + | |
| + | /* If you change these values, also change _SC_GETPW_R_SIZE_MAX and |
| + | * _SC_GETGR_R_SIZE_MAX in libc/unistd/sysconf.c to match */ |
| + | #define PWD_BUFFER_SIZE 256 |
| + | #define GRP_BUFFER_SIZE 256 |
| + | |
| + | /**********************************************************************/ |
| + | /* Prototypes for internal functions. */ |
| + | |
| + | extern int __parsepwent(void *pw, char *line); |
| + | extern int __parsegrent(void *gr, char *line); |
| + | extern int __parsespent(void *sp, char *line); |
| + | |
| + | extern int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data, |
| + | char *__restrict line_buff, size_t buflen, FILE *f); |
| + | |
| + | /**********************************************************************/ |
| + | /* For the various fget??ent_r funcs, return |
| + | * |
| + | * 0: success |
| + | * ENOENT: end-of-file encountered |
| + | * ERANGE: buflen too small |
| + | * other error values possible. See __pgsreader. |
| + | * |
| + | * Also, *result == resultbuf on success and NULL on failure. |
| + | * |
| + | * NOTE: glibc difference - For the ENOENT case, glibc also sets errno. |
| + | * We do not, as it really isn't an error if we reach the end-of-file. |
| + | * Doing so is analogous to having fgetc() set errno on EOF. |
| + | */ |
| + | /**********************************************************************/ |
| + | #ifdef L_fgetpwent_r |
| + | |
| + | int fgetpwent_r(FILE *__restrict stream, struct passwd *__restrict resultbuf, |
| + | char *__restrict buffer, size_t buflen, |
| + | struct passwd **__restrict result) |
| + | { |
| + | int rv; |
| + | |
| + | *result = NULL; |
| + | |
| + | if (!(rv = __pgsreader(__parsepwent, resultbuf, buffer, buflen, stream))) { |
| + | *result = resultbuf; |
| + | } |
| + | |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_fgetgrent_r |
| + | |
| + | int fgetgrent_r(FILE *__restrict stream, struct group *__restrict resultbuf, |
| + | char *__restrict buffer, size_t buflen, |
| + | struct group **__restrict result) |
| + | { |
| + | int rv; |
| + | |
| + | *result = NULL; |
| + | |
| + | if (!(rv = __pgsreader(__parsegrent, resultbuf, buffer, buflen, stream))) { |
| + | *result = resultbuf; |
| + | } |
| + | |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_fgetspent_r |
| + | |
| + | int fgetspent_r(FILE *__restrict stream, struct spwd *__restrict resultbuf, |
| + | char *__restrict buffer, size_t buflen, |
| + | struct spwd **__restrict result) |
| + | { |
| + | int rv; |
| + | |
| + | *result = NULL; |
| + | |
| + | if (!(rv = __pgsreader(__parsespent, resultbuf, buffer, buflen, stream))) { |
| + | *result = resultbuf; |
| + | } |
| + | |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | /* For the various fget??ent funcs, return NULL on failure and a |
| + | * pointer to the appropriate struct (staticly allocated) on success. |
| + | */ |
| + | /**********************************************************************/ |
| + | #ifdef L_fgetpwent |
| + | |
| + | struct passwd *fgetpwent(FILE *stream) |
| + | { |
| + | static char buffer[PWD_BUFFER_SIZE]; |
| + | static struct passwd resultbuf; |
| + | struct passwd *result; |
| + | |
| + | fgetpwent_r(stream, &resultbuf, buffer, sizeof(buffer), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_fgetgrent |
| + | |
| + | struct group *fgetgrent(FILE *stream) |
| + | { |
| + | static char buffer[GRP_BUFFER_SIZE]; |
| + | static struct group resultbuf; |
| + | struct group *result; |
| + | |
| + | fgetgrent_r(stream, &resultbuf, buffer, sizeof(buffer), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_fgetspent |
| + | |
| + | extern int fgetspent_r(FILE *__restrict stream, struct spwd *__restrict resultbuf, |
| + | char *__restrict buffer, size_t buflen, |
| + | struct spwd **__restrict result); |
| + | struct spwd *fgetspent(FILE *stream) |
| + | { |
| + | static char buffer[PWD_BUFFER_SIZE]; |
| + | static struct spwd resultbuf; |
| + | struct spwd *result; |
| + | |
| + | fgetspent_r(stream, &resultbuf, buffer, sizeof(buffer), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_sgetspent_r |
| + | |
| + | int sgetspent_r(const char *string, struct spwd *result_buf, |
| + | char *buffer, size_t buflen, struct spwd **result) |
| + | { |
| + | int rv = ERANGE; |
| + | |
| + | *result = NULL; |
| + | |
| + | if (buflen < PWD_BUFFER_SIZE) { |
| + | DO_ERANGE: |
| + | errno=rv; |
| + | goto DONE; |
| + | } |
| + | |
| + | if (string != buffer) { |
| + | if (strlen(string) >= buflen) { |
| + | goto DO_ERANGE; |
| + | } |
| + | strcpy(buffer, string); |
| + | } |
| + | |
| + | if (!(rv = __parsespent(result_buf, buffer))) { |
| + | *result = result_buf; |
| + | } |
| + | |
| + | DONE: |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | |
| + | #ifdef GETXXKEY_R_FUNC |
| + | #error GETXXKEY_R_FUNC is already defined! |
| + | #endif |
| + | |
| + | #ifdef L_getpwnam_r |
| + | #define GETXXKEY_R_FUNC getpwnam_r |
| + | #define GETXXKEY_R_PARSER __parsepwent |
| + | #define GETXXKEY_R_ENTTYPE struct passwd |
| + | #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->pw_name, key)) |
| + | #define DO_GETXXKEY_R_KEYTYPE const char *__restrict |
| + | #define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD |
| + | #endif |
| + | |
| + | #ifdef L_getgrnam_r |
| + | #define GETXXKEY_R_FUNC getgrnam_r |
| + | #define GETXXKEY_R_PARSER __parsegrent |
| + | #define GETXXKEY_R_ENTTYPE struct group |
| + | #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->gr_name, key)) |
| + | #define DO_GETXXKEY_R_KEYTYPE const char *__restrict |
| + | #define DO_GETXXKEY_R_PATHNAME _PATH_GROUP |
| + | #endif |
| + | |
| + | #ifdef L_getspnam_r |
| + | #define GETXXKEY_R_FUNC getspnam_r |
| + | #define GETXXKEY_R_PARSER __parsespent |
| + | #define GETXXKEY_R_ENTTYPE struct spwd |
| + | #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->sp_namp, key)) |
| + | #define DO_GETXXKEY_R_KEYTYPE const char *__restrict |
| + | #define DO_GETXXKEY_R_PATHNAME _PATH_SHADOW |
| + | #endif |
| + | |
| + | #ifdef L_getpwuid_r |
| + | #define GETXXKEY_R_FUNC getpwuid_r |
| + | #define GETXXKEY_R_PARSER __parsepwent |
| + | #define GETXXKEY_R_ENTTYPE struct passwd |
| + | #define GETXXKEY_R_TEST(ENT) ((ENT)->pw_uid == key) |
| + | #define DO_GETXXKEY_R_KEYTYPE uid_t |
| + | #define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD |
| + | #endif |
| + | |
| + | #ifdef L_getgrgid_r |
| + | #define GETXXKEY_R_FUNC getgrgid_r |
| + | #define GETXXKEY_R_PARSER __parsegrent |
| + | #define GETXXKEY_R_ENTTYPE struct group |
| + | #define GETXXKEY_R_TEST(ENT) ((ENT)->gr_gid == key) |
| + | #define DO_GETXXKEY_R_KEYTYPE gid_t |
| + | #define DO_GETXXKEY_R_PATHNAME _PATH_GROUP |
| + | #endif |
| + | |
| + | /**********************************************************************/ |
| + | #ifdef GETXXKEY_R_FUNC |
| + | |
| + | int GETXXKEY_R_FUNC(DO_GETXXKEY_R_KEYTYPE key, |
| + | GETXXKEY_R_ENTTYPE *__restrict resultbuf, |
| + | char *__restrict buffer, size_t buflen, |
| + | GETXXKEY_R_ENTTYPE **__restrict result) |
| + | { |
| + | FILE *stream; |
| + | int rv; |
| + | |
| + | *result = NULL; |
| + | |
| + | if (!(stream = fopen(DO_GETXXKEY_R_PATHNAME, "r"))) { |
| + | rv = errno; |
| + | } else { |
| + | do { |
| + | if (!(rv = __pgsreader(GETXXKEY_R_PARSER, resultbuf, |
| + | buffer, buflen, stream)) |
| + | ) { |
| + | if (GETXXKEY_R_TEST(resultbuf)) { /* Found key? */ |
| + | *result = resultbuf; |
| + | break; |
| + | } |
| + | } else { |
| + | if (rv == ENOENT) { /* end-of-file encountered. */ |
| + | rv = 0; |
| + | } |
| + | break; |
| + | } |
| + | } while (1); |
| + | fclose(stream); |
| + | } |
| + | |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getpwuid |
| + | |
| + | struct passwd *getpwuid(uid_t uid) |
| + | { |
| + | static char buffer[PWD_BUFFER_SIZE]; |
| + | static struct passwd resultbuf; |
| + | struct passwd *result; |
| + | |
| + | getpwuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getgrgid |
| + | |
| + | struct group *getgrgid(gid_t gid) |
| + | { |
| + | static char buffer[GRP_BUFFER_SIZE]; |
| + | static struct group resultbuf; |
| + | struct group *result; |
| + | |
| + | getgrgid_r(gid, &resultbuf, buffer, sizeof(buffer), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getspuid_r |
| + | |
| + | /* This function is non-standard and is currently not built. It seems |
| + | * to have been created as a reentrant version of the non-standard |
| + | * functions getspuid. Why getspuid was added, I do not know. */ |
| + | |
| + | int getspuid_r(uid_t uid, struct spwd *__restrict resultbuf, |
| + | char *__restrict buffer, size_t buflen, |
| + | struct spwd **__restrict result) |
| + | { |
| + | int rv; |
| + | struct passwd *pp; |
| + | struct passwd password; |
| + | char pwd_buff[PWD_BUFFER_SIZE]; |
| + | |
| + | *result = NULL; |
| + | if (!(rv = getpwuid_r(uid, &password, pwd_buff, sizeof(pwd_buff), &pp))) { |
| + | rv = getspnam_r(password.pw_name, resultbuf, buffer, buflen, result); |
| + | } |
| + | |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getspuid |
| + | |
| + | /* This function is non-standard and is currently not built. |
| + | * Why it was added, I do not know. */ |
| + | |
| + | struct spwd *getspuid(uid_t uid) |
| + | { |
| + | static char buffer[PWD_BUFFER_SIZE]; |
| + | static struct spwd resultbuf; |
| + | struct spwd *result; |
| + | |
| + | getspuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getpwnam |
| + | |
| + | struct passwd *getpwnam(const char *name) |
| + | { |
| + | static char buffer[PWD_BUFFER_SIZE]; |
| + | static struct passwd resultbuf; |
| + | struct passwd *result; |
| + | |
| + | getpwnam_r(name, &resultbuf, buffer, sizeof(buffer), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getgrnam |
| + | |
| + | struct group *getgrnam(const char *name) |
| + | { |
| + | static char buffer[GRP_BUFFER_SIZE]; |
| + | static struct group resultbuf; |
| + | struct group *result; |
| + | |
| + | getgrnam_r(name, &resultbuf, buffer, sizeof(buffer), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getspnam |
| + | |
| + | struct spwd *getspnam(const char *name) |
| + | { |
| + | static char buffer[PWD_BUFFER_SIZE]; |
| + | static struct spwd resultbuf; |
| + | struct spwd *result; |
| + | |
| + | getspnam_r(name, &resultbuf, buffer, sizeof(buffer), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getpw |
| + | |
| + | int getpw(uid_t uid, char *buf) |
| + | { |
| + | struct passwd resultbuf; |
| + | struct passwd *result; |
| + | char buffer[PWD_BUFFER_SIZE]; |
| + | |
| + | if (!buf) { |
| + | errno=EINVAL; |
| + | } else if (!getpwuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result)) { |
| + | if (sprintf(buf, "%s:%s:%lu:%lu:%s:%s:%s\n", |
| + | resultbuf.pw_name, resultbuf.pw_passwd, |
| + | (unsigned long)(resultbuf.pw_uid), |
| + | (unsigned long)(resultbuf.pw_gid), |
| + | resultbuf.pw_gecos, resultbuf.pw_dir, |
| + | resultbuf.pw_shell) >= 0 |
| + | ) { |
| + | return 0; |
| + | } |
| + | } |
| + | |
| + | return -1; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getpwent_r |
| + | |
| + | static FILE *pwf /*= NULL*/; |
| + | void setpwent(void) |
| + | { |
| + | if (pwf) { |
| + | rewind(pwf); |
| + | } |
| + | } |
| + | |
| + | void endpwent(void) |
| + | { |
| + | if (pwf) { |
| + | fclose(pwf); |
| + | pwf = NULL; |
| + | } |
| + | } |
| + | |
| + | |
| + | int getpwent_r(struct passwd *__restrict resultbuf, |
| + | char *__restrict buffer, size_t buflen, |
| + | struct passwd **__restrict result) |
| + | { |
| + | int rv; |
| + | |
| + | *result = NULL; /* In case of error... */ |
| + | |
| + | if (!pwf) { |
| + | if (!(pwf = fopen(_PATH_PASSWD, "r"))) { |
| + | rv = errno; |
| + | goto ERR; |
| + | } |
| + | } |
| + | |
| + | if (!(rv = __pgsreader(__parsepwent, resultbuf, |
| + | buffer, buflen, pwf))) { |
| + | *result = resultbuf; |
| + | } |
| + | |
| + | ERR: |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getgrent_r |
| + | |
| + | static FILE *grf /*= NULL*/; |
| + | void setgrent(void) |
| + | { |
| + | if (grf) { |
| + | rewind(grf); |
| + | } |
| + | } |
| + | |
| + | void endgrent(void) |
| + | { |
| + | if (grf) { |
| + | fclose(grf); |
| + | grf = NULL; |
| + | } |
| + | } |
| + | |
| + | int getgrent_r(struct group *__restrict resultbuf, |
| + | char *__restrict buffer, size_t buflen, |
| + | struct group **__restrict result) |
| + | { |
| + | int rv; |
| + | |
| + | *result = NULL; /* In case of error... */ |
| + | |
| + | if (!grf) { |
| + | if (!(grf = fopen(_PATH_GROUP, "r"))) { |
| + | rv = errno; |
| + | goto ERR; |
| + | } |
| + | } |
| + | |
| + | if (!(rv = __pgsreader(__parsegrent, resultbuf, |
| + | buffer, buflen, grf))) { |
| + | *result = resultbuf; |
| + | } |
| + | |
| + | ERR: |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getspent_r |
| + | |
| + | static FILE *spf /*= NULL*/; |
| + | void setspent(void) |
| + | { |
| + | if (spf) { |
| + | rewind(spf); |
| + | } |
| + | } |
| + | |
| + | void endspent(void) |
| + | { |
| + | if (spf) { |
| + | fclose(spf); |
| + | spf = NULL; |
| + | } |
| + | } |
| + | |
| + | int getspent_r(struct spwd *resultbuf, char *buffer, |
| + | size_t buflen, struct spwd **result) |
| + | { |
| + | int rv; |
| + | |
| + | *result = NULL; /* In case of error... */ |
| + | |
| + | if (!spf) { |
| + | if (!(spf = fopen(_PATH_SHADOW, "r"))) { |
| + | rv = errno; |
| + | goto ERR; |
| + | } |
| + | } |
| + | |
| + | if (!(rv = __pgsreader(__parsespent, resultbuf, |
| + | buffer, buflen, spf))) { |
| + | *result = resultbuf; |
| + | } |
| + | |
| + | ERR: |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getpwent |
| + | |
| + | struct passwd *getpwent(void) |
| + | { |
| + | static char line_buff[PWD_BUFFER_SIZE]; |
| + | static struct passwd pwd; |
| + | struct passwd *result; |
| + | |
| + | getpwent_r(&pwd, line_buff, sizeof(line_buff), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getgrent |
| + | |
| + | struct group *getgrent(void) |
| + | { |
| + | static char line_buff[GRP_BUFFER_SIZE]; |
| + | static struct group gr; |
| + | struct group *result; |
| + | |
| + | getgrent_r(&gr, line_buff, sizeof(line_buff), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_getspent |
| + | |
| + | struct spwd *getspent(void) |
| + | { |
| + | static char line_buff[PWD_BUFFER_SIZE]; |
| + | static struct spwd spwd; |
| + | struct spwd *result; |
| + | |
| + | getspent_r(&spwd, line_buff, sizeof(line_buff), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_sgetspent |
| + | |
| + | struct spwd *sgetspent(const char *string) |
| + | { |
| + | static char line_buff[PWD_BUFFER_SIZE]; |
| + | static struct spwd spwd; |
| + | struct spwd *result; |
| + | |
| + | sgetspent_r(string, &spwd, line_buff, sizeof(line_buff), &result); |
| + | return result; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_initgroups |
| + | |
| + | int initgroups(const char *user, gid_t gid) |
| + | { |
| + | FILE *grf; |
| + | gid_t *group_list; |
| + | int num_groups, rv; |
| + | char **m; |
| + | struct group group; |
| + | char buff[PWD_BUFFER_SIZE]; |
| + | |
| + | rv = -1; |
| + | |
| + | /* We alloc space for 8 gids at a time. */ |
| + | if (((group_list = (gid_t *) malloc(8*sizeof(gid_t *))) != NULL) |
| + | && ((grf = fopen(_PATH_GROUP, "r")) != NULL) |
| + | ) { |
| + | |
| + | *group_list = gid; |
| + | num_groups = 1; |
| + | |
| + | while (!__pgsreader(__parsegrent, &group, buff, sizeof(buff), grf)) { |
| + | assert(group.gr_mem); /* Must have at least a NULL terminator. */ |
| + | if (group.gr_gid != gid) { |
| + | for (m=group.gr_mem ; *m ; m++) { |
| + | if (!strcmp(*m, user)) { |
| + | if (!(num_groups & 7)) { |
| + | gid_t *tmp = (gid_t *) |
| + | realloc(group_list, |
| + | (num_groups+8) * sizeof(gid_t *)); |
| + | if (!tmp) { |
| + | rv = -1; |
| + | goto DO_CLOSE; |
| + | } |
| + | group_list = tmp; |
| + | } |
| + | group_list[num_groups++] = group.gr_gid; |
| + | break; |
| + | } |
| + | } |
| + | } |
| + | } |
| + | |
| + | rv = setgroups(num_groups, group_list); |
| + | DO_CLOSE: |
| + | fclose(grf); |
| + | } |
| + | |
| + | /* group_list will be NULL if initial malloc failed, which may trigger |
| + | * warnings from various malloc debuggers. */ |
| + | free(group_list); |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_putpwent |
| + | |
| + | int putpwent(const struct passwd *__restrict p, FILE *__restrict f) |
| + | { |
| + | int rv = -1; |
| + | |
| + | if (!p || !f) { |
| + | errno=EINVAL; |
| + | } else { |
| + | /* No extra thread locking is needed above what fprintf does. */ |
| + | if (fprintf(f, "%s:%s:%lu:%lu:%s:%s:%s\n", |
| + | p->pw_name, p->pw_passwd, |
| + | (unsigned long)(p->pw_uid), |
| + | (unsigned long)(p->pw_gid), |
| + | p->pw_gecos, p->pw_dir, p->pw_shell) >= 0 |
| + | ) { |
| + | rv = 0; |
| + | } |
| + | } |
| + | |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_putgrent |
| + | |
| + | int putgrent(const struct group *__restrict p, FILE *__restrict f) |
| + | { |
| + | static const char format[] = ",%s"; |
| + | char **m; |
| + | const char *fmt; |
| + | int rv = -1; |
| + | |
| + | if (!p || !f) { /* Sigh... glibc checks. */ |
| + | errno=EINVAL; |
| + | } else { |
| + | if (fprintf(f, "%s:%s:%lu:", |
| + | p->gr_name, p->gr_passwd, |
| + | (unsigned long)(p->gr_gid)) >= 0 |
| + | ) { |
| + | |
| + | fmt = format + 1; |
| + | |
| + | assert(p->gr_mem); |
| + | m = p->gr_mem; |
| + | |
| + | do { |
| + | if (!*m) { |
| + | if (fputc_unlocked('\n', f) >= 0) { |
| + | rv = 0; |
| + | } |
| + | break; |
| + | } |
| + | if (fprintf(f, fmt, *m) < 0) { |
| + | break; |
| + | } |
| + | ++m; |
| + | fmt = format; |
| + | } while (1); |
| + | |
| + | } |
| + | |
| + | } |
| + | |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L_putspent |
| + | |
| + | static const unsigned char sp_off[] = { |
| + | offsetof(struct spwd, sp_lstchg), /* 2 - not a char ptr */ |
| + | offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ |
| + | offsetof(struct spwd, sp_max), /* 4 - not a char ptr */ |
| + | offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ |
| + | offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ |
| + | offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ |
| + | }; |
| + | |
| + | int putspent(const struct spwd *p, FILE *stream) |
| + | { |
| + | static const char ld_format[] = "%ld:"; |
| + | const char *f; |
| + | long int x; |
| + | int i; |
| + | int rv = -1; |
| + | |
| + | /* Unlike putpwent and putgrent, glibc does not check the args. */ |
| + | if (fprintf(stream, "%s:%s:", p->sp_namp, |
| + | (p->sp_pwdp ? p->sp_pwdp : "")) < 0 |
| + | ) { |
| + | goto DO_UNLOCK; |
| + | } |
| + | |
| + | for (i=0 ; i < sizeof(sp_off) ; i++) { |
| + | f = ld_format; |
| + | if ((x = *(const long int *)(((const char *) p) + sp_off[i])) == -1) { |
| + | f += 3; |
| + | } |
| + | if (fprintf(stream, f, x) < 0) { |
| + | goto DO_UNLOCK; |
| + | } |
| + | } |
| + | |
| + | if ((p->sp_flag != ~0UL) && (fprintf(stream, "%lu", p->sp_flag) < 0)) { |
| + | goto DO_UNLOCK; |
| + | } |
| + | |
| + | if (fputc_unlocked('\n', stream) > 0) { |
| + | rv = 0; |
| + | } |
| + | |
| + | DO_UNLOCK: |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | /* Internal uClibc functions. */ |
| + | /**********************************************************************/ |
| + | #ifdef L___parsepwent |
| + | |
| + | static const unsigned char pw_off[] = { |
| + | offsetof(struct passwd, pw_name), /* 0 */ |
| + | offsetof(struct passwd, pw_passwd), /* 1 */ |
| + | offsetof(struct passwd, pw_uid), /* 2 - not a char ptr */ |
| + | offsetof(struct passwd, pw_gid), /* 3 - not a char ptr */ |
| + | offsetof(struct passwd, pw_gecos), /* 4 */ |
| + | offsetof(struct passwd, pw_dir), /* 5 */ |
| + | offsetof(struct passwd, pw_shell) /* 6 */ |
| + | }; |
| + | |
| + | int __parsepwent(void *data, char *line) |
| + | { |
| + | char *endptr; |
| + | char *p; |
| + | int i; |
| + | |
| + | i = 0; |
| + | do { |
| + | p = ((char *) ((struct passwd *) data)) + pw_off[i]; |
| + | |
| + | if ((i & 6) ^ 2) { /* i!=2 and i!=3 */ |
| + | *((char **) p) = line; |
| + | if (i==6) { |
| + | return 0; |
| + | } |
| + | /* NOTE: glibc difference - glibc allows omission of |
| + | * ':' seperators after the gid field if all remaining |
| + | * entries are empty. We require all separators. */ |
| + | if (!(line = strchr(line, ':'))) { |
| + | break; |
| + | } |
| + | } else { |
| + | unsigned long t = strtoul(line, &endptr, 10); |
| + | /* Make sure we had at least one digit, and that the |
| + | * failing char is the next field seperator ':'. See |
| + | * glibc difference note above. */ |
| + | /* TODO: Also check for leading whitespace? */ |
| + | if ((endptr == line) || (*endptr != ':')) { |
| + | break; |
| + | } |
| + | line = endptr; |
| + | if (i & 1) { /* i == 3 -- gid */ |
| + | *((gid_t *) p) = t; |
| + | } else { /* i == 2 -- uid */ |
| + | *((uid_t *) p) = t; |
| + | } |
| + | } |
| + | |
| + | *line++ = 0; |
| + | ++i; |
| + | } while (1); |
| + | |
| + | return -1; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L___parsegrent |
| + | |
| + | static const unsigned char gr_off[] = { |
| + | offsetof(struct group, gr_name), /* 0 */ |
| + | offsetof(struct group, gr_passwd), /* 1 */ |
| + | offsetof(struct group, gr_gid) /* 2 - not a char ptr */ |
| + | }; |
| + | |
| + | int __parsegrent(void *data, char *line) |
| + | { |
| + | char *endptr; |
| + | char *p; |
| + | int i; |
| + | char **members; |
| + | char *end_of_buf; |
| + | |
| + | end_of_buf = ((struct group *) data)->gr_name; /* Evil hack! */ |
| + | i = 0; |
| + | do { |
| + | p = ((char *) ((struct group *) data)) + gr_off[i]; |
| + | |
| + | if (i < 2) { |
| + | *((char **) p) = line; |
| + | if (!(line = strchr(line, ':'))) { |
| + | break; |
| + | } |
| + | *line++ = 0; |
| + | ++i; |
| + | } else { |
| + | *((gid_t *) p) = strtoul(line, &endptr, 10); |
| + | |
| + | /* NOTE: glibc difference - glibc allows omission of the |
| + | * trailing colon when there is no member list. We treat |
| + | * this as an error. */ |
| + | |
| + | /* Make sure we had at least one digit, and that the |
| + | * failing char is the next field seperator ':'. See |
| + | * glibc difference note above. */ |
| + | if ((endptr == line) || (*endptr != ':')) { |
| + | break; |
| + | } |
| + | |
| + | i = 1; /* Count terminating NULL ptr. */ |
| + | p = endptr; |
| + | |
| + | if (p[1]) { /* We have a member list to process. */ |
| + | /* Overwrite the last ':' with a ',' before counting. |
| + | * This allows us to test for initial ',' and adds |
| + | * one ',' so that the ',' count equals the member |
| + | * count. */ |
| + | *p = ','; |
| + | do { |
| + | /* NOTE: glibc difference - glibc allows and trims leading |
| + | * (but not trailing) space. We treat this as an error. */ |
| + | /* NOTE: glibc difference - glibc allows consecutive and |
| + | * trailing commas, and ignores "empty string" users. We |
| + | * treat this as an error. */ |
| + | if (*p == ',') { |
| + | ++i; |
| + | *p = 0; /* nul-terminate each member string. */ |
| + | if (!*++p || (*p == ',') || isspace(*p)) { |
| + | goto ERR; |
| + | } |
| + | } |
| + | } while (*++p); |
| + | } |
| + | |
| + | /* Now align (p+1), rounding up. */ |
| + | /* Assumes sizeof(char **) is a power of 2. */ |
| + | members = (char **)( (((intptr_t) p) + sizeof(char **)) |
| + | & ~((intptr_t)(sizeof(char **) - 1)) ); |
| + | |
| + | if (((char *)(members + i)) > end_of_buf) { /* No space. */ |
| + | break; |
| + | } |
| + | |
| + | ((struct group *) data)->gr_mem = members; |
| + | |
| + | if (--i) { |
| + | p = endptr; /* Pointing to char prior to first member. */ |
| + | do { |
| + | *members++ = ++p; |
| + | if (!--i) break; |
| + | while (*++p) {} |
| + | } while (1); |
| + | } |
| + | *members = NULL; |
| + | |
| + | return 0; |
| + | } |
| + | } while (1); |
| + | |
| + | ERR: |
| + | return -1; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L___parsespent |
| + | |
| + | static const unsigned char sp_off[] = { |
| + | offsetof(struct spwd, sp_namp), /* 0 */ |
| + | offsetof(struct spwd, sp_pwdp), /* 1 */ |
| + | offsetof(struct spwd, sp_lstchg), /* 2 - not a char ptr */ |
| + | offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ |
| + | offsetof(struct spwd, sp_max), /* 4 - not a char ptr */ |
| + | offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ |
| + | offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ |
| + | offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ |
| + | offsetof(struct spwd, sp_flag) /* 8 - not a char ptr */ |
| + | }; |
| + | |
| + | int __parsespent(void *data, char * line) |
| + | { |
| + | char *endptr; |
| + | char *p; |
| + | int i; |
| + | |
| + | i = 0; |
| + | do { |
| + | p = ((char *) ((struct spwd *) data)) + sp_off[i]; |
| + | if (i < 2) { |
| + | *((char **) p) = line; |
| + | if (!(line = strchr(line, ':'))) { |
| + | break; |
| + | } |
| + | } else { |
| + | #if 0 |
| + | if (i==5) { /* Support for old format. */ |
| + | while (isspace(*line)) ++line; /* glibc eats space here. */ |
| + | if (!*line) { |
| + | ((struct spwd *) data)->sp_warn = -1; |
| + | ((struct spwd *) data)->sp_inact = -1; |
| + | ((struct spwd *) data)->sp_expire = -1; |
| + | ((struct spwd *) data)->sp_flag = ~0UL; |
| + | return 0; |
| + | } |
| + | } |
| + | #endif |
| + | |
| + | *((long *) p) = (long) strtoul(line, &endptr, 10); |
| + | |
| + | if (endptr == line) { |
| + | *((long *) p) = ((i != 8) ? -1L : ((long)(~0UL))); |
| + | } |
| + | |
| + | line = endptr; |
| + | |
| + | if (i == 8) { |
| + | if (!*endptr) { |
| + | return 0; |
| + | } |
| + | break; |
| + | } |
| + | |
| + | if (*endptr != ':') { |
| + | break; |
| + | } |
| + | |
| + | } |
| + | |
| + | *line++ = 0; |
| + | ++i; |
| + | } while (1); |
| + | |
| + | return EINVAL; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| + | #ifdef L___pgsreader |
| + | |
| + | /* Reads until if EOF, or until if finds a line which fits in the buffer |
| + | * and for which the parser function succeeds. |
| + | * |
| + | * Returns 0 on success and ENOENT for end-of-file (glibc concession). |
| + | */ |
| + | |
| + | int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data, |
| + | char *__restrict line_buff, size_t buflen, FILE *f) |
| + | { |
| + | int line_len; |
| + | int skip; |
| + | int rv = ERANGE; |
| + | |
| + | if (buflen < PWD_BUFFER_SIZE) { |
| + | errno=rv; |
| + | } else { |
| + | skip = 0; |
| + | do { |
| + | if (!fgets_unlocked(line_buff, buflen, f)) { |
| + | if (feof_unlocked(f)) { |
| + | rv = ENOENT; |
| + | } |
| + | break; |
| + | } |
| + | |
| + | line_len = strlen(line_buff) - 1; /* strlen() must be > 0. */ |
| + | if (line_buff[line_len] == '\n') { |
| + | line_buff[line_len] = 0; |
| + | } else if (line_len + 2 == buflen) { /* line too long */ |
| + | ++skip; |
| + | continue; |
| + | } |
| + | |
| + | if (skip) { |
| + | --skip; |
| + | continue; |
| + | } |
| + | |
| + | /* NOTE: glibc difference - glibc strips leading whitespace from |
| + | * records. We do not allow leading whitespace. */ |
| + | |
| + | /* Skip empty lines, comment lines, and lines with leading |
| + | * whitespace. */ |
| + | if (*line_buff && (*line_buff != '#') && !isspace(*line_buff)) { |
| + | if (__parserfunc == __parsegrent) { /* Do evil group hack. */ |
| + | /* The group entry parsing function needs to know where |
| + | * the end of the buffer is so that it can construct the |
| + | * group member ptr table. */ |
| + | ((struct group *) data)->gr_name = line_buff + buflen; |
| + | } |
| + | |
| + | if (!__parserfunc(data, line_buff)) { |
| + | rv = 0; |
| + | break; |
| + | } |
| + | } |
| + | } while (1); |
| + | |
| + | } |
| + | |
| + | return rv; |
| + | } |
| + | |
| + | #endif |
| + | /**********************************************************************/ |
| @@ -1,58 +0,0 @@ | |
| - | /* |
| - | * pwent.c - This file is part of the libc-8086/pwd package for ELKS, |
| - | * Copyright (C) 1995, 1996 Nat Friedman <[email protected]>. |
| - | * |
| - | * This library is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU Library General Public |
| - | * License as published by the Free Software Foundation; either |
| - | * version 2 of the License, or (at your option) any later version. |
| - | * |
| - | * This library is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| - | * Library General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public |
| - | * License along with this library; if not, write to the Free |
| - | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | * |
| - | */ |
| - | |
| - | #include <unistd.h> |
| - | #include <stdlib.h> |
| - | #include <errno.h> |
| - | #include <fcntl.h> |
| - | |
| - | #include "busybox.h" |
| - | #include "pwd_.h" |
| - | |
| - | /* |
| - | * setpwent(), endpwent(), and getpwent() are included in the same object |
| - | * file, since one cannot be used without the other two, so it makes sense to |
| - | * link them all in together. |
| - | */ |
| - | |
| - | /* file descriptor for the password file currently open */ |
| - | static int pw_fd = -1; |
| - | |
| - | void setpwent(void) |
| - | { |
| - | if (pw_fd != -1) |
| - | close(pw_fd); |
| - | |
| - | pw_fd = open(bb_path_passwd_file, O_RDONLY); |
| - | } |
| - | |
| - | void endpwent(void) |
| - | { |
| - | if (pw_fd != -1) |
| - | close(pw_fd); |
| - | pw_fd = -1; |
| - | } |
| - | |
| - | struct passwd *getpwent(void) |
| - | { |
| - | if (pw_fd != -1) |
| - | return (__getpwent(pw_fd)); |
| - | return NULL; |
| - | } |
| @@ -1,40 +0,0 @@ | |
| - | /* vi: set sw=4 ts=4: */ |
| - | /* |
| - | * Taken from the set of syscalls for uClibc |
| - | * |
| - | * Copyright (C) 1999-2004 by Erik Andersen <[email protected]> |
| - | * |
| - | * This program is free software; you can redistribute it and/or modify it |
| - | * under the terms of the GNU Library General Public License as published by |
| - | * the Free Software Foundation; either version 2 of the License, or (at your |
| - | * option) any later version. |
| - | * |
| - | * This program is distributed in the hope that it will be useful, but WITHOUT |
| - | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| - | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License |
| - | * for more details. |
| - | * |
| - | * You should have received a copy of the GNU Library General Public License |
| - | * along with this program; if not, write to the Free Software Foundation, |
| - | * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| - | * |
| - | */ |
| - | |
| - | #include "busybox.h" |
| - | |
| - | #include <errno.h> |
| - | #include <unistd.h> |
| - | #include <features.h> |
| - | #include <sys/types.h> |
| - | /* Kernel headers before 2.1.mumble need this on the Alpha to get |
| - | _syscall* defined. */ |
| - | #define __LIBRARY__ |
| - | #include <sys/syscall.h> |
| - | #include "grp_.h" |
| - | |
| - | int setgroups(size_t size, const gid_t * list) |
| - | { |
| - | return(syscall(__NR_setgroups, size, list)); |
| - | } |
| - | |
| - | |
| @@ -1,300 +0,0 @@ | |
| - | /* vi: set sw=4 ts=4: */ |
| - | /* |
| - | * Copyright 1989 - 1994, Julianne Frances Haugh |
| - | * <[email protected]>, <[email protected]> |
| - | * All rights reserved. |
| - | * |
| - | * Redistribution and use in source and binary forms, with or without |
| - | * modification, are permitted provided that the following conditions |
| - | * are met: |
| - | * 1. Redistributions of source code must retain the above copyright |
| - | * notice, this list of conditions and the following disclaimer. |
| - | * 2. Redistributions in binary form must reproduce the above copyright |
| - | * notice, this list of conditions and the following disclaimer in the |
| - | * documentation and/or other materials provided with the distribution. |
| - | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors |
| - | * may be used to endorse or promote products derived from this software |
| - | * without specific prior written permission. |
| - | * |
| - | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND |
| - | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| - | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| - | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE |
| - | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| - | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| - | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| - | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| - | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| - | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| - | * SUCH DAMAGE. |
| - | */ |
| - | |
| - | /* TODO: fgetspent_r.c getspent_r.c getspnam_r.c sgetspent_r.c |
| - | * lckpwdf ulckpwdf |
| - | */ |
| - | |
| - | #include <stdio.h> |
| - | #include <stdlib.h> |
| - | #include <string.h> |
| - | #include <unistd.h> |
| - | |
| - | #include "busybox.h" |
| - | #include "shadow_.h" |
| - | |
| - | static FILE *shadow; |
| - | static char spwbuf[BUFSIZ]; |
| - | static struct spwd spwd; |
| - | |
| - | #define FIELDS 9 |
| - | #define OFIELDS 5 |
| - | |
| - | /* setspent - initialize access to shadow text and DBM files */ |
| - | void setspent(void) |
| - | { |
| - | if (shadow) { |
| - | rewind(shadow); |
| - | } else { |
| - | shadow = bb_xfopen(bb_path_shadow_file, "r"); |
| - | } |
| - | } |
| - | |
| - | /* endspent - terminate access to shadow text and DBM files */ |
| - | void endspent(void) |
| - | { |
| - | if (shadow) |
| - | (void) fclose(shadow); |
| - | shadow = (FILE *) 0; |
| - | } |
| - | |
| - | /* getspent - get a (struct spwd *) from the current shadow file */ |
| - | struct spwd *getspent(void) |
| - | { |
| - | if (!shadow) |
| - | setspent(); |
| - | return (fgetspent(shadow)); |
| - | } |
| - | |
| - | /* getspnam - get a shadow entry by name */ |
| - | struct spwd *getspnam(const char *name) |
| - | { |
| - | struct spwd *sp; |
| - | |
| - | if (!name || !strlen(name)) |
| - | return NULL; |
| - | |
| - | setspent(); |
| - | while ((sp = getspent()) != NULL) { |
| - | if (strcmp(name, sp->sp_namp) == 0) |
| - | break; |
| - | } |
| - | endspent(); |
| - | return (sp); |
| - | } |
| - | |
| - | |
| - | /* sgetspent - convert string in shadow file format to (struct spwd *) */ |
| - | /* returns NULL on error */ |
| - | struct spwd *sgetspent(const char *string) |
| - | { |
| - | char *fields[FIELDS]; |
| - | char *cp; |
| - | char *cpp; |
| - | int i; |
| - | |
| - | /* |
| - | * Copy string to local buffer. It has to be tokenized and we |
| - | * have to do that to our private copy. |
| - | */ |
| - | |
| - | if (strlen(string) >= sizeof spwbuf) |
| - | /* return 0; */ |
| - | return NULL; |
| - | strcpy(spwbuf, string); |
| - | |
| - | if ((cp = strrchr(spwbuf, '\n'))) |
| - | *cp = '\0'; |
| - | |
| - | /* |
| - | * Tokenize the string into colon separated fields. Allow up to |
| - | * FIELDS different fields. |
| - | */ |
| - | |
| - | for (cp = spwbuf, i = 0; *cp && i < FIELDS; i++) { |
| - | fields[i] = cp; |
| - | while (*cp && *cp != ':') |
| - | cp++; |
| - | |
| - | if (*cp) |
| - | *cp++ = '\0'; |
| - | } |
| - | |
| - | /* |
| - | * It is acceptable for the last SVR4 field to be blank. This |
| - | * results in the loop being terminated early. In which case, |
| - | * we just make the last field be blank and be done with it. |
| - | */ |
| - | |
| - | if (i == (FIELDS - 1)) |
| - | fields[i++] = cp; |
| - | |
| - | if ((cp && *cp) || (i != FIELDS && i != OFIELDS)) |
| - | /* return 0; */ |
| - | return NULL; |
| - | |
| - | /* |
| - | * Start populating the structure. The fields are all in |
| - | * static storage, as is the structure we pass back. If we |
| - | * ever see a name with '+' as the first character, we try |
| - | * to turn on NIS processing. |
| - | */ |
| - | |
| - | spwd.sp_namp = fields[0]; |
| - | spwd.sp_pwdp = fields[1]; |
| - | |
| - | /* |
| - | * Get the last changed date. For all of the integer fields, |
| - | * we check for proper format. It is an error to have an |
| - | * incorrectly formatted number, unless we are using NIS. |
| - | */ |
| - | |
| - | if ((spwd.sp_lstchg = strtol(fields[2], &cpp, 10)) == 0 && *cpp) { |
| - | /* return 0; */ |
| - | return NULL; |
| - | } else if (fields[2][0] == '\0') |
| - | spwd.sp_lstchg = -1; |
| - | |
| - | /* |
| - | * Get the minimum period between password changes. |
| - | */ |
| - | |
| - | if ((spwd.sp_min = strtol(fields[3], &cpp, 10)) == 0 && *cpp) { |
| - | /* return 0; */ |
| - | return NULL; |
| - | } else if (fields[3][0] == '\0') |
| - | spwd.sp_min = -1; |
| - | |
| - | /* |
| - | * Get the maximum number of days a password is valid. |
| - | */ |
| - | |
| - | if ((spwd.sp_max = strtol(fields[4], &cpp, 10)) == 0 && *cpp) { |
| - | /* return 0; */ |
| - | return NULL; |
| - | } else if (fields[4][0] == '\0') |
| - | spwd.sp_max = -1; |
| - | |
| - | /* |
| - | * If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow |
| - | * formatted file), initialize the other field members to -1. |
| - | */ |
| - | |
| - | if (i == OFIELDS) { |
| - | spwd.sp_warn = spwd.sp_inact = spwd.sp_expire = spwd.sp_flag = -1; |
| - | |
| - | return &spwd; |
| - | } |
| - | |
| - | /* |
| - | * The rest of the fields are mandatory for SVR4, but optional |
| - | * for anything else. However, if one is present the others |
| - | * must be as well. |
| - | */ |
| - | |
| - | /* |
| - | * Get the number of days of password expiry warning. |
| - | */ |
| - | |
| - | if ((spwd.sp_warn = strtol(fields[5], &cpp, 10)) == 0 && *cpp) { |
| - | /* return 0; */ |
| - | return NULL; |
| - | } else if (fields[5][0] == '\0') |
| - | spwd.sp_warn = -1; |
| - | |
| - | /* |
| - | * Get the number of days of inactivity before an account is |
| - | * disabled. |
| - | */ |
| - | |
| - | if ((spwd.sp_inact = strtol(fields[6], &cpp, 10)) == 0 && *cpp) { |
| - | /* return 0; */ |
| - | return NULL; |
| - | } else if (fields[6][0] == '\0') |
| - | spwd.sp_inact = -1; |
| - | |
| - | /* |
| - | * Get the number of days after the epoch before the account is |
| - | * set to expire. |
| - | */ |
| - | |
| - | if ((spwd.sp_expire = strtol(fields[7], &cpp, 10)) == 0 && *cpp) { |
| - | /* return 0; */ |
| - | return NULL; |
| - | } else if (fields[7][0] == '\0') |
| - | spwd.sp_expire = -1; |
| - | |
| - | /* |
| - | * This field is reserved for future use. But it isn't supposed |
| - | * to have anything other than a valid integer in it. |
| - | */ |
| - | |
| - | if ((spwd.sp_flag = strtol(fields[8], &cpp, 10)) == 0 && *cpp) { |
| - | /* return 0; */ |
| - | return NULL; |
| - | } else if (fields[8][0] == '\0') |
| - | spwd.sp_flag = -1; |
| - | |
| - | return (&spwd); |
| - | } |
| - | |
| - | /* fgetspent - get an entry from an /etc/shadow formatted stream */ |
| - | struct spwd *fgetspent(FILE *fp) |
| - | { |
| - | char buf[BUFSIZ]; |
| - | char *cp; |
| - | |
| - | if (!fp) |
| - | /* return (0); */ |
| - | return NULL; |
| - | |
| - | if (fgets(buf, sizeof buf, fp) != (char *) 0) { |
| - | if ((cp = strchr(buf, '\n'))) |
| - | *cp = '\0'; |
| - | return (sgetspent(buf)); |
| - | } |
| - | /* return 0; */ |
| - | return NULL; |
| - | } |
| - | |
| - | /* |
| - | * putspent - put a (struct spwd *) into the (FILE *) you provide. |
| - | * |
| - | * this was described in shadow_.h but not implemented, so here |
| - | * I go. -beppu |
| - | * |
| - | */ |
| - | int putspent(const struct spwd *sp, FILE *fp) |
| - | { |
| - | int ret; |
| - | |
| - | /* seek to end */ |
| - | ret = fseek(fp, 0, SEEK_END); |
| - | if (ret == -1) { |
| - | /* return -1; */ |
| - | return 1; |
| - | } |
| - | |
| - | /* powered by fprintf */ |
| - | fprintf(fp, "%s:%s:%ld:%ld:%ld:%ld:%ld:%ld:%s\n", sp->sp_namp, /* login name */ |
| - | sp->sp_pwdp, /* encrypted password */ |
| - | sp->sp_lstchg, /* date of last change */ |
| - | sp->sp_min, /* minimum number of days between changes */ |
| - | sp->sp_max, /* maximum number of days between changes */ |
| - | sp->sp_warn, /* number of days of warning before password expires */ |
| - | sp->sp_inact, /* number of days after password expires until |
| - | the account becomes unusable */ |
| - | sp->sp_expire, /* days since 1/1/70 until account expires */ |
| - | ""); |
| - | return 0; |
| - | } |
| - | |
| - | |