diff options
author | David McCullough <davidm@snapgear.com> | 2002-01-17 06:26:05 +0000 |
---|---|---|
committer | David McCullough <davidm@snapgear.com> | 2002-01-17 06:26:05 +0000 |
commit | 23457259675d4a21f6840a30e2b41014540eab2d (patch) | |
tree | 1e29e4b02bd95566e6aea0205d4e8b564c5ce853 | |
parent | 47e0a8060499c822772437a3ca1765297857c131 (diff) |
* Added /etc/shadow support (Config selectable)
* Moved some file paths from code into <paths.h>
-rw-r--r-- | extra/Configs/Config.arm | 3 | ||||
-rw-r--r-- | extra/Configs/Config.cross.arm.uclinux | 3 | ||||
-rw-r--r-- | extra/Configs/Config.i386 | 3 | ||||
-rw-r--r-- | extra/Configs/Config.m68k | 3 | ||||
-rw-r--r-- | extra/Configs/Config.m68k.coff | 3 | ||||
-rw-r--r-- | extra/Configs/Config.mips | 3 | ||||
-rw-r--r-- | extra/Configs/Config.mipsel | 3 | ||||
-rw-r--r-- | extra/Configs/Config.powerpc | 3 | ||||
-rw-r--r-- | extra/Configs/Config.sh | 3 | ||||
-rw-r--r-- | include/paths.h | 3 | ||||
-rw-r--r-- | libc/pwd_grp/Makefile | 6 | ||||
-rw-r--r-- | libc/pwd_grp/__getspent_r.c | 57 | ||||
-rw-r--r-- | libc/pwd_grp/__sgetspent_r.c | 161 | ||||
-rw-r--r-- | libc/pwd_grp/fgetspent.c | 45 | ||||
-rw-r--r-- | libc/pwd_grp/getgrgid.c | 3 | ||||
-rw-r--r-- | libc/pwd_grp/getgrnam.c | 3 | ||||
-rw-r--r-- | libc/pwd_grp/getpwnam.c | 4 | ||||
-rw-r--r-- | libc/pwd_grp/getpwuid.c | 4 | ||||
-rw-r--r-- | libc/pwd_grp/getspnam.c | 61 | ||||
-rw-r--r-- | libc/pwd_grp/getspuid.c | 50 | ||||
-rw-r--r-- | libc/pwd_grp/grent.c | 3 | ||||
-rw-r--r-- | libc/pwd_grp/initgroups.c | 3 | ||||
-rw-r--r-- | libc/pwd_grp/lckpwdf.c | 163 | ||||
-rw-r--r-- | libc/pwd_grp/putspent.c | 79 | ||||
-rw-r--r-- | libc/pwd_grp/pwent.c | 3 | ||||
-rw-r--r-- | libc/pwd_grp/sgetspent.c | 41 | ||||
-rw-r--r-- | libc/pwd_grp/spent.c | 71 |
27 files changed, 778 insertions, 9 deletions
diff --git a/extra/Configs/Config.arm b/extra/Configs/Config.arm index ba0023367..deb75ed34 100644 --- a/extra/Configs/Config.arm +++ b/extra/Configs/Config.arm @@ -77,6 +77,9 @@ DO_C99_MATH = false # Also omits strto(u)ll, and (u)lltostr from the library if `false'. HAS_LONG_LONG = false +# Set this to 'false if you don't need shadow password support. +HAS_SHADOW = false + # Set this to `false' if you don't have/need locale support; `true' otherwise. # Note: Currently only affects the ctype functions. You must also generate # a locale file for anything but the C locale. See directory extra/locale for diff --git a/extra/Configs/Config.cross.arm.uclinux b/extra/Configs/Config.cross.arm.uclinux index 2c3f8163f..5e905f636 100644 --- a/extra/Configs/Config.cross.arm.uclinux +++ b/extra/Configs/Config.cross.arm.uclinux @@ -73,6 +73,9 @@ DO_C99_MATH = false # Also omits strto(u)ll, and (u)lltostr from the library if `false'. HAS_LONG_LONG = true +# Set this to 'false if you don't need shadow password support. +HAS_SHADOW = false + # Set this to `false' if you don't have/need locale support; `true' otherwise. # Note: Currently only affects the ctype functions. You must also generate # a locale file for anything but the C locale. See directory extra/locale for diff --git a/extra/Configs/Config.i386 b/extra/Configs/Config.i386 index 7d77441d7..ef2ee4e22 100644 --- a/extra/Configs/Config.i386 +++ b/extra/Configs/Config.i386 @@ -73,6 +73,9 @@ DO_C99_MATH = false # Also omits strto(u)ll, and (u)lltostr from the library if `false'. HAS_LONG_LONG = true +# Set this to 'false if you don't need shadow password support. +HAS_SHADOW = false + # Set this to `false' if you don't have/need locale support; `true' otherwise. # Note: Currently only affects the ctype functions. You must also generate # a locale file for anything but the C locale. See directory extra/locale for diff --git a/extra/Configs/Config.m68k b/extra/Configs/Config.m68k index a2afa37e3..fd6a7da6e 100644 --- a/extra/Configs/Config.m68k +++ b/extra/Configs/Config.m68k @@ -73,6 +73,9 @@ DO_C99_MATH = false # Also omits strto(u)ll, and (u)lltostr from the library if `false'. HAS_LONG_LONG = true +# Set this to 'false if you don't need shadow password support. +HAS_SHADOW = false + # Set this to `false' if you don't have/need locale support; `true' otherwise. # Note: Currently only affects the ctype functions. You must also generate # a locale file for anything but the C locale. See directory extra/locale for diff --git a/extra/Configs/Config.m68k.coff b/extra/Configs/Config.m68k.coff index f18aef30e..00576be6b 100644 --- a/extra/Configs/Config.m68k.coff +++ b/extra/Configs/Config.m68k.coff @@ -73,6 +73,9 @@ DO_C99_MATH = false # Also omits strto(u)ll, and (u)lltostr from the library if `false'. HAS_LONG_LONG = true +# Set this to 'false if you don't need shadow password support. +HAS_SHADOW = false + # Set this to `false' if you don't have/need locale support; `true' otherwise. # Note: Currently only affects the ctype functions. You must also generate # a locale file for anything but the C locale. See directory extra/locale for diff --git a/extra/Configs/Config.mips b/extra/Configs/Config.mips index a7ff1f0c6..1416a3ed1 100644 --- a/extra/Configs/Config.mips +++ b/extra/Configs/Config.mips @@ -72,6 +72,9 @@ DO_C99_MATH = false # Also omits strto(u)ll, and (u)lltostr from the library if `false'. HAS_LONG_LONG = true +# Set this to 'false if you don't need shadow password support. +HAS_SHADOW = false + # Set this to `false' if you don't have/need locale support; `true' otherwise. # Note: Currently only affects the ctype functions. You must also generate # a locale file for anything but the C locale. See directory extra/locale for diff --git a/extra/Configs/Config.mipsel b/extra/Configs/Config.mipsel index a7ff1f0c6..1416a3ed1 100644 --- a/extra/Configs/Config.mipsel +++ b/extra/Configs/Config.mipsel @@ -72,6 +72,9 @@ DO_C99_MATH = false # Also omits strto(u)ll, and (u)lltostr from the library if `false'. HAS_LONG_LONG = true +# Set this to 'false if you don't need shadow password support. +HAS_SHADOW = false + # Set this to `false' if you don't have/need locale support; `true' otherwise. # Note: Currently only affects the ctype functions. You must also generate # a locale file for anything but the C locale. See directory extra/locale for diff --git a/extra/Configs/Config.powerpc b/extra/Configs/Config.powerpc index 16cc2d8b2..91b874f04 100644 --- a/extra/Configs/Config.powerpc +++ b/extra/Configs/Config.powerpc @@ -73,6 +73,9 @@ DO_C99_MATH = false # Also omits strto(u)ll, and (u)lltostr from the library if `false'. HAS_LONG_LONG = true +# Set this to 'false if you don't need shadow password support. +HAS_SHADOW = false + # Set this to `false' if you don't have/need locale support; `true' otherwise. # Note: Currently only affects the ctype functions. You must also generate # a locale file for anything but the C locale. See directory extra/locale for diff --git a/extra/Configs/Config.sh b/extra/Configs/Config.sh index e93b998f6..daf685491 100644 --- a/extra/Configs/Config.sh +++ b/extra/Configs/Config.sh @@ -97,6 +97,9 @@ DO_C99_MATH = false # Also omits strto(u)ll, and (u)lltostr from the library if `false'. HAS_LONG_LONG = false +# Set this to 'false if you don't need shadow password support. +HAS_SHADOW = false + # Set this to `false' if you don't have/need locale support; `true' otherwise. # Note: Currently only affects the ctype functions. You must also generate # a locale file for anything but the C locale. See directory extra/locale for diff --git a/include/paths.h b/include/paths.h index 2f7cc6dad..3cdd39cc2 100644 --- a/include/paths.h +++ b/include/paths.h @@ -63,6 +63,9 @@ #define _PATH_UTMP "/var/run/utmp" #define _PATH_VI "/usr/bin/vi" #define _PATH_WTMP "/var/log/wtmp" +#define _PATH_LOCALE "/usr/lib/locale" +#define _PATH_PASSWD "/etc/passwd" +#define _PATH_GROUP "/etc/group" /* Provide trailing slash, since mostly used for building pathnames. */ #define _PATH_DEV "/dev/" diff --git a/libc/pwd_grp/Makefile b/libc/pwd_grp/Makefile index f9b49c461..5efa1414e 100644 --- a/libc/pwd_grp/Makefile +++ b/libc/pwd_grp/Makefile @@ -27,6 +27,12 @@ include $(TOPDIR)Rules.mak CSRC= pwent.c getpwnam.c getpwuid.c putpwent.c getpw.c fgetpwent.c \ __getgrent.c grent.c getgrnam.c getgrgid.c fgetgrent.c \ initgroups.c __getpwent_r.c + +ifeq ($(HAS_SHADOW),true) +CSRC+= lckpwdf.c spent.c getspnam.c getspuid.c putspent.c sgetspent.c \ + fgetspent.c __getspent_r.c __sgetspent_r.c +endif + COBJS=$(patsubst %.c,%.o, $(CSRC)) OBJS=$(COBJS) diff --git a/libc/pwd_grp/__getspent_r.c b/libc/pwd_grp/__getspent_r.c new file mode 100644 index 000000000..d8e1fbdce --- /dev/null +++ b/libc/pwd_grp/__getspent_r.c @@ -0,0 +1,57 @@ +/* + * __getspent_r.c - Based on __getpwent_r.c + * + * 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 <shadow.h> + + +int __getspent_r(struct spwd * spwd, char * line_buff, size_t buflen, int spwd_fd) +{ + char *endptr; + int line_len; + + /* We use the restart label to handle malformatted lines */ + restart: + /* Read the shadow line into the static buffer using a minimal of + syscalls. */ + if ((line_len = read(spwd_fd, line_buff, buflen)) <= 0) + return -1; + endptr = strchr(line_buff, '\n'); + if (endptr != NULL) + lseek(spwd_fd, (long) (1 + endptr - (line_buff + line_len)), + SEEK_CUR); + else { /* The line is too long - skip it. :-\ */ + + do { + if ((line_len = read(spwd_fd, line_buff, buflen)) <= 0) + return -1; + } while (!(endptr = strchr(line_buff, '\n'))); + lseek(spwd_fd, (long) (endptr - line_buff) - line_len + 1, + SEEK_CUR); + goto restart; + } + + if (__sgetspent_r(line_buff, spwd, line_buff, buflen) < 0) + goto restart; + + return 0; +} diff --git a/libc/pwd_grp/__sgetspent_r.c b/libc/pwd_grp/__sgetspent_r.c new file mode 100644 index 000000000..f2cd73195 --- /dev/null +++ b/libc/pwd_grp/__sgetspent_r.c @@ -0,0 +1,161 @@ +/* + * __sgetspent_r.c - Based on __getpwent_r.c + * + * 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 <shadow.h> + + +int __sgetspent_r(const char * string, struct spwd * spwd, char * line_buff, size_t buflen) +{ + char *field_begin; + char *endptr; + char *lstchg_ptr=NULL; + char *min_ptr=NULL; + char *max_ptr=NULL; + char *warn_ptr=NULL; + char *inact_ptr=NULL; + char *expire_ptr=NULL; + char *flag_ptr=NULL; + int i; + + if (string != line_buff) { + if (strlen(string) >= buflen) + return -1; + strcpy(line_buff, string); + } + + if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' || + *line_buff == '\t') + return -1; + + field_begin = strchr(line_buff, '\n'); + if (field_begin != NULL) + *field_begin = '\0'; + + /* We've read the line; now parse it. */ + field_begin = line_buff; + for (i = 0; i < 9; i++) { + switch (i) { + case 0: + spwd->sp_namp = field_begin; + break; + case 1: + spwd->sp_pwdp = field_begin; + break; + case 2: + lstchg_ptr = field_begin; + break; + case 3: + min_ptr = field_begin; + break; + case 4: + max_ptr = field_begin; + break; + case 5: + warn_ptr = field_begin; + break; + case 6: + inact_ptr = field_begin; + break; + case 7: + expire_ptr = field_begin; + break; + case 8: + flag_ptr = field_begin; + break; + } + if (i < 8) { + field_begin = strchr(field_begin, ':'); + if (field_begin == NULL) { + if (i==4 || i==7) + break; + return -1; + } + *field_begin++ = '\0'; + } + } + + if (*lstchg_ptr == '\0') { + spwd->sp_lstchg = -1; + } else { + spwd->sp_lstchg = (gid_t) strtoul(lstchg_ptr, &endptr, 10); + if (*endptr != '\0') + return -1; + } + + if (*min_ptr == '\0') { + spwd->sp_min = -1; + } else { + spwd->sp_min = (gid_t) strtoul(min_ptr, &endptr, 10); + if (*endptr != '\0') + return -1; + } + + if (*max_ptr == '\0') { + spwd->sp_max = -1; + } else { + spwd->sp_max = (gid_t) strtoul(max_ptr, &endptr, 10); + if (*endptr != '\0') + return -1; + } + + if (warn_ptr == NULL) { + /* Support for old format */ + spwd->sp_warn = -1; + spwd->sp_inact = -1; + spwd->sp_expire = -1; + spwd->sp_flag = 0; + } + else { + if (*warn_ptr == '\0') { + spwd->sp_warn = -1; + } else { + spwd->sp_warn = (gid_t) strtoul(warn_ptr, &endptr, 10); + if (*endptr != '\0') + return -1; + } + + if (*inact_ptr == '\0') { + spwd->sp_inact = -1; + } else { + spwd->sp_inact = (gid_t) strtoul(inact_ptr, &endptr, 10); + if (*endptr != '\0') + return -1; + } + + if (*expire_ptr == '\0') { + spwd->sp_expire = -1; + } else { + spwd->sp_expire = (gid_t) strtoul(expire_ptr, &endptr, 10); + if (*endptr != '\0') + return -1; + } + + if (flag_ptr==NULL || *flag_ptr=='\0') { + spwd->sp_flag = ~0ul; + } else { + spwd->sp_flag = (gid_t) strtoul(flag_ptr, &endptr, 10); + if (*endptr != '\0') + return -1; + } + } + + return 0; +} diff --git a/libc/pwd_grp/fgetspent.c b/libc/pwd_grp/fgetspent.c new file mode 100644 index 000000000..cf949065f --- /dev/null +++ b/libc/pwd_grp/fgetspent.c @@ -0,0 +1,45 @@ +/* + * fgetspent.c - Based on fgetpwent.c + * + * 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 <errno.h> +#include <stdio.h> +#include <shadow.h> + +#define PWD_BUFFER_SIZE 256 + +int fgetspent_r (FILE *file, struct spwd *spwd, + char *buff, size_t buflen, struct spwd **crap) +{ + if (file == NULL) { + __set_errno(EINTR); + return -1; + } + return(__getspent_r(spwd, buff, buflen, fileno(file))); +} + +struct spwd *fgetspent(FILE * file) +{ + static char line_buff[PWD_BUFFER_SIZE]; + static struct spwd spwd; + + if (fgetspent_r(file, &spwd, line_buff, PWD_BUFFER_SIZE, NULL) != -1) { + return &spwd; + } + return NULL; +} diff --git a/libc/pwd_grp/getgrgid.c b/libc/pwd_grp/getgrgid.c index 70e7152ce..f41e305ef 100644 --- a/libc/pwd_grp/getgrgid.c +++ b/libc/pwd_grp/getgrgid.c @@ -22,6 +22,7 @@ #include <unistd.h> #include <fcntl.h> #include <grp.h> +#include <paths.h> #include "config.h" struct group *getgrgid(const gid_t gid) @@ -29,7 +30,7 @@ struct group *getgrgid(const gid_t gid) struct group *group; int grp_fd; - if ((grp_fd = open("/etc/group", O_RDONLY)) < 0) + if ((grp_fd = open(_PATH_GROUP, O_RDONLY)) < 0) return NULL; while ((group = __getgrent(grp_fd)) != NULL) diff --git a/libc/pwd_grp/getgrnam.c b/libc/pwd_grp/getgrnam.c index 705342489..77301797c 100644 --- a/libc/pwd_grp/getgrnam.c +++ b/libc/pwd_grp/getgrnam.c @@ -23,6 +23,7 @@ #include <errno.h> #include <fcntl.h> #include <grp.h> +#include <paths.h> #include "config.h" struct group *getgrnam(const char *name) @@ -35,7 +36,7 @@ struct group *getgrnam(const char *name) return NULL; } - if ((grp_fd = open("/etc/group", O_RDONLY)) < 0) + if ((grp_fd = open(_PATH_GROUP, O_RDONLY)) < 0) return NULL; while ((group = __getgrent(grp_fd)) != NULL) diff --git a/libc/pwd_grp/getpwnam.c b/libc/pwd_grp/getpwnam.c index f5ad9ca1d..36f6f0942 100644 --- a/libc/pwd_grp/getpwnam.c +++ b/libc/pwd_grp/getpwnam.c @@ -23,9 +23,9 @@ #include <errno.h> #include <fcntl.h> #include <pwd.h> +#include <paths.h> #include "config.h" - #define PWD_BUFFER_SIZE 256 /* file descriptor for the password file currently open */ @@ -43,7 +43,7 @@ int getpwnam_r (const char *name, struct passwd *password, return -1; } - if ((passwd_fd = open("/etc/passwd", O_RDONLY)) < 0) + if ((passwd_fd = open(_PATH_PASSWD, O_RDONLY)) < 0) return -1; while (__getpwent_r(password, buff, buflen, passwd_fd) != -1) diff --git a/libc/pwd_grp/getpwuid.c b/libc/pwd_grp/getpwuid.c index 101d668ae..4d6d60ee8 100644 --- a/libc/pwd_grp/getpwuid.c +++ b/libc/pwd_grp/getpwuid.c @@ -22,9 +22,9 @@ #include <unistd.h> #include <fcntl.h> #include <pwd.h> +#include <paths.h> #include "config.h" - #define PWD_BUFFER_SIZE 256 /* file descriptor for the password file currently open */ @@ -36,7 +36,7 @@ int getpwuid_r (uid_t uid, struct passwd *password, { int passwd_fd; - if ((passwd_fd = open("/etc/passwd", O_RDONLY)) < 0) + if ((passwd_fd = open(_PATH_PASSWD, O_RDONLY)) < 0) return -1; while (__getpwent_r(password, buff, buflen, passwd_fd) != -1) diff --git a/libc/pwd_grp/getspnam.c b/libc/pwd_grp/getspnam.c new file mode 100644 index 000000000..3865a0dc5 --- /dev/null +++ b/libc/pwd_grp/getspnam.c @@ -0,0 +1,61 @@ +/* + * getspnam.c - Based on getpwnam.c + * + * 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 <string.h> +#include <errno.h> +#include <fcntl.h> +#include <shadow.h> + +#define PWD_BUFFER_SIZE 256 + +int getspnam_r (const char *name, struct spwd *spwd, + char *buff, size_t buflen, struct spwd **crap) +{ + int spwd_fd; + + if (name == NULL) { + __set_errno(EINVAL); + return -1; + } + + if ((spwd_fd = open(_PATH_SHADOW, O_RDONLY)) < 0) + return -1; + + while (__getspent_r(spwd, buff, buflen, spwd_fd) != -1) + if (!strcmp(spwd->sp_namp, name)) { + close(spwd_fd); + return 0; + } + + close(spwd_fd); + return -1; +} + +struct spwd *getspnam(const char *name) +{ + static char line_buff[PWD_BUFFER_SIZE]; + static struct spwd spwd; + + if (getspnam_r(name, &spwd, line_buff, PWD_BUFFER_SIZE, NULL) != -1) { + return &spwd; + } + return NULL; +} + diff --git a/libc/pwd_grp/getspuid.c b/libc/pwd_grp/getspuid.c new file mode 100644 index 000000000..2f01cdca0 --- /dev/null +++ b/libc/pwd_grp/getspuid.c @@ -0,0 +1,50 @@ +/* + * getspuid.c - Based on getpwuid.c + * + * 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 <pwd.h> +#include <shadow.h> + +#define PWD_BUFFER_SIZE 256 + +int getspuid_r (uid_t uid, struct spwd *spwd, + char *buff, size_t buflen, struct spwd **crap) +{ + char pwd_buff[PWD_BUFFER_SIZE]; + struct passwd password; + + if (getpwuid_r(uid, &password, pwd_buff, PWD_BUFFER_SIZE, NULL) < 0) + return -1; + + return getspnam_r(password.pw_name, spwd, buff, buflen, crap); +} + +struct spwd *getspuid(uid_t uid) +{ + static char line_buff[PWD_BUFFER_SIZE]; + static struct spwd spwd; + + if (getspuid_r(uid, &spwd, line_buff, PWD_BUFFER_SIZE, NULL) != -1) { + return &spwd; + } + return NULL; +} + diff --git a/libc/pwd_grp/grent.c b/libc/pwd_grp/grent.c index 8e4af5143..973213f83 100644 --- a/libc/pwd_grp/grent.c +++ b/libc/pwd_grp/grent.c @@ -27,6 +27,7 @@ #include <unistd.h> #include <fcntl.h> #include <grp.h> +#include <paths.h> #include "config.h" static int grp_fd = -1; @@ -35,7 +36,7 @@ void setgrent(void) { if (grp_fd != -1) close(grp_fd); - grp_fd = open("/etc/group", O_RDONLY); + grp_fd = open(_PATH_GROUP, O_RDONLY); } void endgrent(void) diff --git a/libc/pwd_grp/initgroups.c b/libc/pwd_grp/initgroups.c index 04de22632..87a6b569d 100644 --- a/libc/pwd_grp/initgroups.c +++ b/libc/pwd_grp/initgroups.c @@ -22,6 +22,7 @@ #include <string.h> #include <fcntl.h> #include <grp.h> +#include <paths.h> #include "config.h" int initgroups(__const char *user, gid_t gid) @@ -38,7 +39,7 @@ int initgroups(__const char *user, gid_t gid) int grp_fd; - if ((grp_fd = open("/etc/group", O_RDONLY)) < 0) + if ((grp_fd = open(_PATH_GROUP, O_RDONLY)) < 0) return -1; num_groups = 0; diff --git a/libc/pwd_grp/lckpwdf.c b/libc/pwd_grp/lckpwdf.c new file mode 100644 index 000000000..2f55ff65a --- /dev/null +++ b/libc/pwd_grp/lckpwdf.c @@ -0,0 +1,163 @@ +/* Handle locking of password file. + Copyright (C) 1996, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + + The GNU C 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. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <fcntl.h> +#include <shadow.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> +#include <sys/file.h> +#include <paths.h> + +/* How long to wait for getting the lock before returning with an + error. */ +#define TIMEOUT 15 /* sec */ + +/* File descriptor for lock file. */ +static int lock_fd = -1; + +/* Prototypes for local functions. */ +static void noop_handler __P ((int __sig)); + + +int +lckpwdf () +{ + int flags; + sigset_t saved_set; /* Saved set of caught signals. */ + struct sigaction saved_act; /* Saved signal action. */ + sigset_t new_set; /* New set of caught signals. */ + struct sigaction new_act; /* New signal action. */ + struct flock fl; /* Information struct for locking. */ + int result; + + if (lock_fd != -1) + /* Still locked by own process. */ + return -1; + + lock_fd = open (_PATH_PASSWD, O_WRONLY); + if (lock_fd == -1) + /* Cannot create lock file. */ + return -1; + + /* Make sure file gets correctly closed when process finished. */ + flags = fcntl (lock_fd, F_GETFD, 0); + if (flags == -1) { + /* Cannot get file flags. */ + close(lock_fd); + lock_fd = -1; + return -1; + } + flags |= FD_CLOEXEC; /* Close on exit. */ + if (fcntl (lock_fd, F_SETFD, flags) < 0) { + /* Cannot set new flags. */ + close(lock_fd); + lock_fd = -1; + return -1; + } + + /* Now we have to get exclusive write access. Since multiple + process could try this we won't stop when it first fails. + Instead we set a timeout for the system call. Once the timer + expires it is likely that there are some problems which cannot be + resolved by waiting. + + It is important that we don't change the signal state. We must + restore the old signal behaviour. */ + memset (&new_act, '\0', sizeof (struct sigaction)); + new_act.sa_handler = noop_handler; + sigfillset (&new_act.sa_mask); + new_act.sa_flags = 0ul; + + /* Install new action handler for alarm and save old. */ + if (sigaction (SIGALRM, &new_act, &saved_act) < 0) { + /* Cannot install signal handler. */ + close(lock_fd); + lock_fd = -1; + return -1; + } + + /* Now make sure the alarm signal is not blocked. */ + sigemptyset (&new_set); + sigaddset (&new_set, SIGALRM); + if (sigprocmask (SIG_UNBLOCK, &new_set, &saved_set) < 0) { + sigaction (SIGALRM, &saved_act, NULL); + close(lock_fd); + lock_fd = -1; + return -1; + } + + /* Start timer. If we cannot get the lock in the specified time we + get a signal. */ + alarm (TIMEOUT); + + /* Try to get the lock. */ + memset (&fl, '\0', sizeof (struct flock)); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + result = fcntl (lock_fd, F_SETLKW, &fl); + + /* Clear alarm. */ + alarm (0); + + /* Restore old set of handled signals. We don't need to know + about the current one.*/ + sigprocmask (SIG_SETMASK, &saved_set, NULL); + + /* Restore old action handler for alarm. We don't need to know + about the current one. */ + sigaction (SIGALRM, &saved_act, NULL); + + if (result < 0) { + close(lock_fd); + lock_fd = -1; + return -1; + } + + return 0; +} + + +int +ulckpwdf () +{ + int result; + + if (lock_fd == -1) { + /* There is no lock set. */ + result = -1; + } + else { + result = close (lock_fd); + + /* Mark descriptor as unused. */ + lock_fd = -1; + } + + return result; +} + + +static void +noop_handler (sig) + int sig; +{ + /* We simply return which makes the `fcntl' call return with an error. */ +} diff --git a/libc/pwd_grp/putspent.c b/libc/pwd_grp/putspent.c new file mode 100644 index 000000000..a4626e1b4 --- /dev/null +++ b/libc/pwd_grp/putspent.c @@ -0,0 +1,79 @@ +/* Copyright (C) 1991, 1992, 1996, 1997, 1998 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdio.h> +#include <shadow.h> + +#define _S(x) x ? x : "" + + +/* Write an entry to the given stream. + This must know the format of the password file. */ +int +putspent (const struct spwd *p, FILE *stream) +{ + int errors = 0; + + if (fprintf (stream, "%s:%s:", p->sp_namp, _S (p->sp_pwdp)) < 0) + ++errors; + + if ((p->sp_lstchg != (long int) -1 + && fprintf (stream, "%ld:", p->sp_lstchg) < 0) + || (p->sp_lstchg == (long int) -1 + && putc (':', stream) == EOF)) + ++errors; + + if ((p->sp_min != (long int) -1 + && fprintf (stream, "%ld:", p->sp_min) < 0) + || (p->sp_min == (long int) -1 + && putc (':', stream) == EOF)) + ++errors; + + if ((p->sp_max != (long int) -1 + && fprintf (stream, "%ld:", p->sp_max) < 0) + || (p->sp_max == (long int) -1 + && putc (':', stream) == EOF)) + ++errors; + + if ((p->sp_warn != (long int) -1 + && fprintf (stream, "%ld:", p->sp_warn) < 0) + || (p->sp_warn == (long int) -1 + && putc (':', stream) == EOF)) + ++errors; + + if ((p->sp_inact != (long int) -1 + && fprintf (stream, "%ld:", p->sp_inact) < 0) + || (p->sp_inact == (long int) -1 + && putc (':', stream) == EOF)) + ++errors; + + if ((p->sp_expire != (long int) -1 + && fprintf (stream, "%ld:", p->sp_expire) < 0) + || (p->sp_expire == (long int) -1 + && putc (':', stream) == EOF)) + ++errors; + + if (p->sp_flag != ~0ul + && fprintf (stream, "%ld", p->sp_flag) < 0) + ++errors; + + if (putc ('\n', stream) == EOF) + ++errors; + + return errors ? -1 : 0; +} diff --git a/libc/pwd_grp/pwent.c b/libc/pwd_grp/pwent.c index e4a17e2b3..804bd8957 100644 --- a/libc/pwd_grp/pwent.c +++ b/libc/pwd_grp/pwent.c @@ -23,6 +23,7 @@ #include <errno.h> #include <pwd.h> #include <fcntl.h> +#include <paths.h> #include "config.h" /* @@ -43,7 +44,7 @@ void setpwent(void) if (pw_fd != -1) close(pw_fd); - pw_fd = open("/etc/passwd", O_RDONLY); + pw_fd = open(_PATH_PASSWD, O_RDONLY); } void endpwent(void) diff --git a/libc/pwd_grp/sgetspent.c b/libc/pwd_grp/sgetspent.c new file mode 100644 index 000000000..6f80c87d6 --- /dev/null +++ b/libc/pwd_grp/sgetspent.c @@ -0,0 +1,41 @@ +/* + * sgetspent.c + * + * 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 <errno.h> +#include <stdio.h> +#include <shadow.h> + +#define PWD_BUFFER_SIZE 256 + +int sgetspent_r (const char *string, struct spwd *spwd, + char *buff, size_t buflen, struct spwd **crap) +{ + return(__sgetspent_r(string, spwd, buff, buflen)); +} + +struct spwd *sgetspent(const char *string) +{ + static char line_buff[PWD_BUFFER_SIZE]; + static struct spwd spwd; + + if (sgetspent_r(string, &spwd, line_buff, PWD_BUFFER_SIZE, NULL) != -1) { + return &spwd; + } + return NULL; +} diff --git a/libc/pwd_grp/spent.c b/libc/pwd_grp/spent.c new file mode 100644 index 000000000..196a952bd --- /dev/null +++ b/libc/pwd_grp/spent.c @@ -0,0 +1,71 @@ +/* + * spent.c - Based on pwent.c + * + * 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 <shadow.h> +#include <fcntl.h> + +/* + * setspent(), endspent(), and getspent() 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. + */ + +#define PWD_BUFFER_SIZE 256 + +/* file descriptor for the password file currently open */ +static int spwd_fd = -1; + +void setspent(void) +{ + if (spwd_fd != -1) + close(spwd_fd); + + spwd_fd = open(_PATH_SHADOW, O_RDONLY); +} + +void endspent(void) +{ + if (spwd_fd != -1) + close(spwd_fd); + spwd_fd = -1; +} + +int getspent_r (struct spwd *spwd, char *buff, + size_t buflen, struct spwd **crap) +{ + if (spwd_fd != -1 && __getspent_r(spwd, buff, buflen, spwd_fd) != -1) { + return 0; + } + return -1; +} + +struct spwd *getspent(void) +{ + static char line_buff[PWD_BUFFER_SIZE]; + static struct spwd spwd; + + if (getspent_r(&spwd, line_buff, PWD_BUFFER_SIZE, NULL) != -1) { + return &spwd; + } + return NULL; +} + |