diff --git a/libs/libc/Kconfig b/libs/libc/Kconfig index 78c64ad419..402a23e459 100644 --- a/libs/libc/Kconfig +++ b/libs/libc/Kconfig @@ -14,6 +14,8 @@ source libs/libc/string/Kconfig source libs/libc/pthread/Kconfig source libs/libc/dlfcn/Kconfig source libs/libc/modlib/Kconfig +source libs/libc/grp/Kconfig +source libs/libc/pwd/Kconfig source libs/libc/wchar/Kconfig source libs/libc/locale/Kconfig source libs/libc/lzf/Kconfig diff --git a/libs/libc/grp/Kconfig b/libs/libc/grp/Kconfig new file mode 100644 index 0000000000..f375b9e081 --- /dev/null +++ b/libs/libc/grp/Kconfig @@ -0,0 +1,43 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LIBC_GROUP_FILE + bool "Have group file" + default n + depends on FS_READABLE + ---help--- + Have a group file. The format of the group file is: + + group:x:gid:users + + Where: + group: The group name + x: Group password + gid: Group ID + users: A comma separated list of members of the group + +if LIBC_GROUP_FILE + +config LIBC_GROUP_FILEPATH + string "Path to group file" + default "/etc/group" + ---help--- + Provides the location of the group file. The default is /etc/group + +config LIBC_GROUP_NUSERS + int "Maximum group members" + default 8 + ---help--- + The maximum length number of user names that can be reported for a + group. + +config LIBC_GROUP_LINESIZE + int "Maximum line size" + default 80 + ---help--- + The maximum length of one line in the group file. This determines + the size of the I/O buffer used to access the group file. + +endif # LIBC_GROUP_FILE diff --git a/libs/libc/grp/Make.defs b/libs/libc/grp/Make.defs index ae17e58161..d99ef83573 100644 --- a/libs/libc/grp/Make.defs +++ b/libs/libc/grp/Make.defs @@ -36,7 +36,13 @@ # Add the grp C files to the build CSRCS += lib_getgrgid.c lib_getgrgidr.c lib_getgrnam.c lib_getgrnamr.c -CSRCS += lib_grp.c lib_initgroups.c +CSRCS += lib_initgroups.c + +ifeq ($(CONFIG_LIBC_GROUP_FILE),y) +CSRCS += lib_find_grpfile.c lib_grp_globals.c +else +CSRCS += lib_getgrbuf.c lib_getgrbufr.c +endif # Add the grp directory to the build diff --git a/libs/libc/grp/lib_find_grpfile.c b/libs/libc/grp/lib_find_grpfile.c new file mode 100644 index 0000000000..f3ab6d7b41 --- /dev/null +++ b/libs/libc/grp/lib_find_grpfile.c @@ -0,0 +1,342 @@ +/**************************************************************************** + * libs/libc/grp/lib_find_grpfile.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 NuttX 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 THE COPYRIGHT HOLDERS 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 THE + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "grp/lib_grp.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef CODE int (grp_foreach_match_t)(FAR const struct group *entry, + FAR void *arg); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: grp_match_name + * + * Description: + * Called for each record in the group file. Returns "1" if the record + * matches the group name (passed as arg) + * + * Input Parameters: + * entry - The parsed group file record + * arg - A pointer to the group name to match + * + * Returned Value: + * < 0 : An error has occurred. + * = 0 : No entry name does not match. + * = 1 : The entry name matches + * + ****************************************************************************/ + +static int grp_match_name(FAR const struct group *entry, FAR void *arg) +{ + FAR const char *gname = (FAR const char *)arg; + return strcmp(entry->gr_name, gname) == 0 ? 1 : 0; +} + +/**************************************************************************** + * Name: grp_match_gid + * + * Description: + * Called for each record in the group file. Returns "1" if the record + * matches the group ID (passed as arg) + * + * Input Parameters: + * entry - The parsed group file record + * arg - The group ID to match + * + * Returned Value: + * < 0 : An error has occurred. + * = 0 : No entry name does not match. + * = 1 : The entry name matches + * + ****************************************************************************/ + +static int grp_match_gid(FAR const struct group *entry, FAR void *arg) +{ + int match_gid = (int)((uintptr_t)arg); + return match_gid == entry->gr_gid ? 1 : 0; +} + +/**************************************************************************** + * Name: grp_foreach + * + * Description: + * Visit each record in group file. + * + * Input Parameters: + * match - The match function to call on each record + * arg - Argument passed to the match function + * entry - Location to return the parsed group file entry + * buffer - I/O buffer used to access the group file + * buflen - The size of the I/O buffer in bytes + * + * Returned Value: + * < 0 : An error has occurred. + * = 0 : No entry with this name was found. + * = 1 : The entry with this name was found. + * + ****************************************************************************/ + +static int grp_foreach(grp_foreach_match_t match, FAR void *arg, + FAR struct group *entry, FAR char *buffer, + size_t buflen) +{ + FAR FILE *stream; + FAR char *ptr; + FAR char *line; + FAR char *save; + size_t linelen; + unsigned int nmembers; + int ret; + + stream = fopen(CONFIG_LIBC_GROUP_FILEPATH, "r"); + if (stream == NULL) + { + int errcode = errno; + DEBUGASSERT(errno > 0); + return -errcode; + } + + /* Read the password file line by line until the record with the matching + * username is found, or until the end of the file is reached. + * + * The format of the password file is: + * + * user:x:uid:gid:home + * + * Where: + * user: User name + * x: Encrypted password + * uid: User ID + * gid: Group ID + * home: Login directory + */ + + DEBUGASSERT(buflen > MEMBER_SIZE); /* Buffer must also be aligned */ + line = buffer + MEMBER_SIZE; + linelen = buflen - MEMBER_SIZE; + + while (fgets(line, linelen, stream) != NULL) + { + ptr = line; + entry->gr_name = ptr; + + /* Skip to the end of the name and properly terminate it. The name + * must be terminated with the field delimiter ':'. + */ + + for (; *ptr != '\n' && *ptr != '\0' && *ptr != ':'; ptr++) + { + } + + if (*ptr == '\n' || *ptr == '\0') + { + /* Bad line format? */ + + continue; + } + + *ptr++ = '\0'; + entry->gr_passwd = ptr; + + /* Skip to the end of the password and properly terminate it. The + * password must be terminated with the field delimiter ':'. + */ + + for (; *ptr != '\n' && *ptr != '\0' && *ptr != ':'; ptr++) + { + } + + if (*ptr == '\n' || *ptr == '\0') + { + /* Bad line format? */ + + continue; + } + + *ptr++ = '\0'; + save = ptr; + + /* Skip to the end of the group ID and properly terminate it. The + * group ID must be terminated with the field delimiter ':'. + */ + + for (; *ptr != '\n' && *ptr != '\0' && *ptr != ':'; ptr++) + { + } + + if (*ptr == '\n' || *ptr == '\0') + { + /* Bad line format? */ + + continue; + } + + *ptr++ = '\0'; + entry->gr_gid = (gid_t)atoi(save); + + /* This is followed by a variable number of user names. The ':' + * delimited will be followed by '\n' or '\0' if there are no users + * in the group + */ + + nmembers = 0; + entry->gr_mem = (FAR char **)buffer; + + if (*ptr != '\n' && *ptr != '\0') + { + for (; ; ) + { + /* Add the next user name */ + + entry->gr_mem[nmembers] = ptr; + nmembers++; + if (nmembers >= CONFIG_LIBC_GROUP_NUSERS) + { + break; + } + + /* Skip to the end of the user name and properly terminate it. + * The user name must be terminated with either (1) ',' + * meaning that another user name is present, or (2) '\n' or + * '\0' meaning that we have reached the end of the line and + * there are no further user names. + */ + + for (; *ptr != '\n' && *ptr != '\0' && *ptr != ','; ptr++) + { + } + + if (*ptr == '\n' || *ptr == '\0') + { + *ptr = '\0'; + break; + } + + *ptr++ = '\0'; + } + } + + /* The list terminates with a NULL pointer */ + + entry->gr_mem[nmembers] = NULL; + + /* Check for a match */ + + ret = match(entry, arg); + if (ret != 0) + { + /* We either have the match or an error occurred. */ + + fclose(stream); + return ret; + } + } + + fclose(stream); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: grp_findby_name + * + * Description: + * Find group file entry using the group name. + * + * Input Parameters: + * gname - The group name + * entry - Location to return the parsed group file entry + * buffer - I/O buffer used to access the group file + * buflen - The size of the I/O buffer in bytes + * + * Returned Value: + * < 0 : An error has occurred. + * = 0 : No entry with this name was found. + * = 1 : The entry with this name was found. + * + ****************************************************************************/ + +int grp_findby_name(FAR const char *gname, FAR struct group *entry, + FAR char *buffer, size_t buflen) +{ + return grp_foreach(grp_match_name, (FAR void *)gname, entry, buffer, buflen); +} + +/**************************************************************************** + * Name: grp_findby_gid + * + * Description: + * Find group file entry using the group ID. + * + * Input Parameters: + * gid - The group ID + * entry - Location to return the parsed group file entry + * buffer - I/O buffer used to access the group file + * buflen - The size of the I/O buffer in bytes + * + * Returned Value: + * < 0 : An error has occurred. + * = 0 : No entry with this name was found. + * = 1 : The entry with this name was found. + * + ****************************************************************************/ + +int grp_findby_gid(gid_t gid, FAR struct group *entry, FAR char *buffer, + size_t buflen) +{ + return grp_foreach(grp_match_gid, (FAR void *)((uintptr_t)gid), entry, + buffer, buflen); +} diff --git a/libs/libc/grp/lib_getgrbuf.c b/libs/libc/grp/lib_getgrbuf.c new file mode 100644 index 0000000000..82a7337a07 --- /dev/null +++ b/libs/libc/grp/lib_getgrbuf.c @@ -0,0 +1,126 @@ +/**************************************************************************** + * libs/libc/grp/lib_getgrbuf.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Michael Jung + * + * 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 NuttX 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 THE COPYRIGHT HOLDERS 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 THE + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "grp/lib_grp.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static FAR char *g_buf; +static FAR struct group *g_grp; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: getgrbuf + * + * Description: + * libc/grp internal helper function for getgrgid and getgrnam to allocate + * and setup a group structure once a matching entry has been found. + * + * Input Parameters: + * gid - Value to set the group structure's gr_gid field to. + * name - Value to set the group structure's gr_name field to. + * passwd - Value to set the group structure's passwd field to. + * + * Returned Value: + * A pointer to a statically allocated group structure, or NULL if an + * error occurs, in which case errno is set appropriately. + * + ****************************************************************************/ + +FAR struct group *getgrbuf(gid_t gid, FAR const char *name, + FAR const char *passwd) +{ + FAR struct group *result; + FAR char *newbuf; + size_t buflen; + int err; + + buflen = sizeof(FAR char **) + strlen(name) + 1 + strlen(passwd) + 1; + + newbuf = (FAR char *)realloc(g_buf, buflen); + + if (!newbuf) + { + err = ENOMEM; + goto error; + } + + g_buf = newbuf; + + if (!g_grp) + { + g_grp = (FAR struct group *)malloc(sizeof(struct group)); + } + + if (!g_grp) + { + err = ENOMEM; + goto error; + } + + err = getgrbuf_r(gid, name, passwd, g_grp, g_buf, buflen, &result); + + if (err) + { + goto error; + } + + return result; + +error: + free(g_grp); + free(g_buf); + g_grp = NULL; + g_buf = NULL; + set_errno(err); + + return NULL; +} diff --git a/libs/libc/grp/lib_grp.c b/libs/libc/grp/lib_getgrbufr.c similarity index 70% rename from libs/libc/grp/lib_grp.c rename to libs/libc/grp/lib_getgrbufr.c index c6b48d8606..de864819b5 100644 --- a/libs/libc/grp/lib_grp.c +++ b/libs/libc/grp/lib_getgrbufr.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libs/libc/grp/lib_grp.c + * libs/libc/grp/lib_getgrbufr.c * * Copyright (C) 2019 Gregory Nutt. All rights reserved. * Author: Michael Jung @@ -46,85 +46,10 @@ #include "grp/lib_grp.h" -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static FAR char *g_buf; -static FAR struct group *g_grp; - /**************************************************************************** * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: getgrbuf - * - * Description: - * libc/grp internal helper function for getgrgid and getgrnam to allocate - * and setup a group structure once a matching entry has been found. - * - * Input Parameters: - * gid - Value to set the group structure's gr_gid field to. - * name - Value to set the group structure's gr_name field to. - * passwd - Value to set the group structure's passwd field to. - * - * Returned Value: - * A pointer to a statically allocated group structure, or NULL if an - * error occurs, in which case errno is set appropriately. - * - ****************************************************************************/ - -FAR struct group *getgrbuf(gid_t gid, FAR const char *name, - FAR const char *passwd) -{ - FAR struct group *result; - FAR char *newbuf; - size_t buflen; - int err; - - buflen = sizeof(FAR char **) + strlen(name) + 1 + strlen(passwd) + 1; - - newbuf = (FAR char *)realloc(g_buf, buflen); - - if (!newbuf) - { - err = ENOMEM; - goto error; - } - - g_buf = newbuf; - - if (!g_grp) - { - g_grp = (FAR struct group *)malloc(sizeof(struct group)); - } - - if (!g_grp) - { - err = ENOMEM; - goto error; - } - - err = getgrbuf_r(gid, name, passwd, g_grp, g_buf, buflen, &result); - - if (err) - { - goto error; - } - - return result; - -error: - free(g_grp); - free(g_buf); - g_grp = NULL; - g_buf = NULL; - set_errno(err); - - return NULL; -} - /**************************************************************************** * Name: getgrbuf_r * diff --git a/libs/libc/grp/lib_getgrgid.c b/libs/libc/grp/lib_getgrgid.c index 25767ef841..8c294f5297 100644 --- a/libs/libc/grp/lib_getgrgid.c +++ b/libs/libc/grp/lib_getgrgid.c @@ -68,10 +68,22 @@ FAR struct group *getgrgid(gid_t gid) { +#ifdef CONFIG_LIBC_GROUP_FILE + int ret; + + ret = grp_findby_gid(gid, &g_group, g_group_buffer, GRPBUF_RESERVE_SIZE); + if (ret != 1) + { + return NULL; + } + + return &g_group; +#else if (gid != ROOT_GID) { return NULL; } return getgrbuf(ROOT_GID, ROOT_NAME, ROOT_PASSWD); +#endif } diff --git a/libs/libc/grp/lib_getgrgidr.c b/libs/libc/grp/lib_getgrgidr.c index 953dee2a65..d3d4a053cc 100644 --- a/libs/libc/grp/lib_getgrgidr.c +++ b/libs/libc/grp/lib_getgrgidr.c @@ -72,6 +72,19 @@ int getgrgid_r(gid_t gid, FAR struct group *grp, FAR char *buf, size_t buflen, FAR struct group **result) { +#ifdef CONFIG_LIBC_GROUP_FILE + int ret; + + ret = grp_findby_gid(gid, grp, buf, buflen); + if (ret != 1) + { + *result = NULL; + return ret < 0 ? -ret : 0; + } + + *result = grp; + return 0; +#else if (gid != ROOT_GID) { /* The only known group is 'root', which has a gid of 0. Thus, report @@ -84,4 +97,5 @@ int getgrgid_r(gid_t gid, FAR struct group *grp, FAR char *buf, size_t buflen, return getgrbuf_r(ROOT_GID, ROOT_NAME, ROOT_PASSWD, grp, buf, buflen, result); +#endif } diff --git a/libs/libc/grp/lib_getgrnam.c b/libs/libc/grp/lib_getgrnam.c index 4c2f0da61e..a79ada35d8 100644 --- a/libs/libc/grp/lib_getgrnam.c +++ b/libs/libc/grp/lib_getgrnam.c @@ -69,10 +69,22 @@ FAR struct group *getgrnam(FAR const char *name) { +#ifdef CONFIG_LIBC_GROUP_FILE + int ret; + + ret = grp_findby_name(name, &g_group, g_group_buffer, GRPBUF_RESERVE_SIZE); + if (ret != 1) + { + return NULL; + } + + return &g_group; +#else if (strcmp(name, "root")) { return NULL; } return getgrbuf(ROOT_GID, ROOT_NAME, ROOT_PASSWD); +#endif } diff --git a/libs/libc/grp/lib_getgrnamr.c b/libs/libc/grp/lib_getgrnamr.c index 7b84c1f153..350685fceb 100644 --- a/libs/libc/grp/lib_getgrnamr.c +++ b/libs/libc/grp/lib_getgrnamr.c @@ -73,6 +73,19 @@ int getgrnam_r(FAR const char *name, FAR struct group *grp, FAR char *buf, size_t buflen, FAR struct group **result) { +#ifdef CONFIG_LIBC_GROUP_FILE + int ret; + + ret = grp_findby_name(name, grp, buf, buflen); + if (ret != 1) + { + *result = NULL; + return ret < 0 ? -ret : 0; + } + + *result = grp; + return 0; +#else if (strcmp(name, ROOT_NAME)) { /* The only known group is 'root', which has a gid of 0. Thus, report @@ -85,4 +98,5 @@ int getgrnam_r(FAR const char *name, FAR struct group *grp, FAR char *buf, return getgrbuf_r(ROOT_GID, ROOT_NAME, ROOT_PASSWD, grp, buf, buflen, result); +#endif } diff --git a/libs/libc/grp/lib_grp.h b/libs/libc/grp/lib_grp.h index 1980f67b2b..7cea1d50e7 100644 --- a/libs/libc/grp/lib_grp.h +++ b/libs/libc/grp/lib_grp.h @@ -52,6 +52,16 @@ #define ROOT_NAME "root" #define ROOT_PASSWD "x" +/* Reserver space for a NULL terminated list for group member names */ + +#define MEMBER_SIZE ((CONFIG_LIBC_GROUP_NUSERS + 1) * sizeof(FAR char *)) + +/* Reserve space for the maximum line in the group file PLUS space for an + * array of Member names. + */ + +#define GRPBUF_RESERVE_SIZE (CONFIG_LIBC_GROUP_LINESIZE + MEMBER_SIZE) + /**************************************************************************** * Public Data ****************************************************************************/ @@ -64,6 +74,13 @@ extern "C" #define EXTERN extern #endif +#ifdef CONFIG_LIBC_GROUP_FILE +/* Data for non-reentrant group functions */ + +EXTERN struct group g_group; +EXTERN char g_group_buffer[GRPBUF_RESERVE_SIZE]; +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -74,6 +91,13 @@ int getgrbuf_r(gid_t gid, FAR const char *name, FAR const char *passwd, FAR struct group *grp, FAR char *buf, size_t buflen, FAR struct group **result); +#ifdef CONFIG_LIBC_GROUP_FILE +int grp_findby_name(FAR const char *gname, FAR struct group *entry, + FAR char *buffer, size_t buflen); +int grp_findby_gid(gid_t gid, FAR struct group *entry, FAR char *buffer, + size_t buflen); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/libs/libc/grp/lib_grp_globals.c b/libs/libc/grp/lib_grp_globals.c new file mode 100644 index 0000000000..dcaedc2160 --- /dev/null +++ b/libs/libc/grp/lib_grp_globals.c @@ -0,0 +1,55 @@ +/**************************************************************************** + * libs/libc/grp/lib_grp_globals.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 NuttX 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 THE COPYRIGHT HOLDERS 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 THE + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "grp/lib_grp.h" + +#ifdef CONFIG_LIBC_GROUP_FILE + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Data for non-reentrant group functions */ + +struct group g_group; +char g_group_buffer[GRPBUF_RESERVE_SIZE]; + +#endif /* CONFIG_LIBC_GROUP_FILE */ diff --git a/libs/libc/pwd/Kconfig b/libs/libc/pwd/Kconfig new file mode 100644 index 0000000000..c34d19bc32 --- /dev/null +++ b/libs/libc/pwd/Kconfig @@ -0,0 +1,37 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LIBC_PASSWD_FILE + bool "Have passwd file" + default n + depends on FS_READABLE + ---help--- + Have a passwd file. The format of the password file is: + + user:x:uid:gid:home + + Where: + user: User name + x: Encrypted password + uid: User ID + gid: Group ID + home: Login directory + +if LIBC_PASSWD_FILE + +config LIBC_PASSWD_FILEPATH + string "Path to passwd file" + default "/etc/passwd" + ---help--- + Provides the location of the passwd file. The default is /etc/passwd + +config LIBC_PASSWD_LINESIZE + int "Maximum line size" + default 80 + ---help--- + The maximum length of one line in the passwd file. This determines + the size of the I/O buffer used to access the passwd file. + +endif # LIBC_PASSWD_FILE diff --git a/libs/libc/pwd/Make.defs b/libs/libc/pwd/Make.defs index 0cc22c688b..2024f10740 100644 --- a/libs/libc/pwd/Make.defs +++ b/libs/libc/pwd/Make.defs @@ -36,7 +36,12 @@ # Add the pwd C files to the build CSRCS += lib_getpwnam.c lib_getpwnamr.c lib_getpwuid.c lib_getpwuidr.c -CSRCS += lib_pwd.c + +ifeq ($(CONFIG_LIBC_PASSWD_FILE),y) +CSRCS += lib_find_pwdfile.c lib_pwd_globals.c +else +CSRCS += lib_getpwbuf.c lib_getpwbufr.c +endif # Add the pwd directory to the build diff --git a/libs/libc/pwd/lib_find_pwdfile.c b/libs/libc/pwd/lib_find_pwdfile.c new file mode 100644 index 0000000000..57b9a4980d --- /dev/null +++ b/libs/libc/pwd/lib_find_pwdfile.c @@ -0,0 +1,319 @@ +/**************************************************************************** + * libs/libc/pwd/lib_find_pwdfile.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 NuttX 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 THE COPYRIGHT HOLDERS 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 THE + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "pwd/lib_pwd.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef CODE int (pwd_foreach_match_t)(FAR const struct passwd *entry, + FAR void *arg); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pwd_match_name + * + * Description: + * Called for each record in the passwd file. Returns "1" if the record + * matches the user name (passed as arg) + * + * Input Parameters: + * entry - The parsed passwd file record + * arg - A pointer to the user name to match + * + * Returned Value: + * < 0 : An error has occurred. + * = 0 : No entry name does not match. + * = 1 : The entry name matches + * + ****************************************************************************/ + +static int pwd_match_name(FAR const struct passwd *entry, FAR void *arg) +{ + FAR const char *uname = (FAR const char *)arg; + return strcmp(entry->pw_name, uname) == 0 ? 1 : 0; +} + +/**************************************************************************** + * Name: pwd_match_uid + * + * Description: + * Called for each record in the passwd file. Returns "1" if the record + * matches the user ID (passed as arg) + * + * Input Parameters: + * entry - The parsed passwd file record + * arg - The user ID to match + * + * Returned Value: + * < 0 : An error has occurred. + * = 0 : No entry name does not match. + * = 1 : The entry name matches + * + ****************************************************************************/ + +static int pwd_match_uid(FAR const struct passwd *entry, FAR void *arg) +{ + int match_uid = (int)((uintptr_t)arg); + return match_uid == entry->pw_uid ? 1 : 0; +} + +/**************************************************************************** + * Name: pwd_foreach + * + * Description: + * Visit each record in passwd file. + * + * Input Parameters: + * match - The match function to call on each record + * arg - Argument passed to the match function + * entry - Location to return the parsed passwd file entry + * buffer - I/O buffer used to access the passwd file + * buflen - The size of the I/O buffer in bytes + * + * Returned Value: + * < 0 : An error has occurred. + * = 0 : No entry with this name was found. + * = 1 : The entry with this name was found. + * + ****************************************************************************/ + +static int pwd_foreach(pwd_foreach_match_t match, FAR void *arg, + FAR struct passwd *entry, FAR char *buffer, + size_t buflen) +{ + FAR FILE *stream; + FAR char *ptr; + FAR char *save; + int ret; + + stream = fopen(CONFIG_LIBC_PASSWD_FILEPATH, "r"); + if (stream == NULL) + { + int errcode = errno; + DEBUGASSERT(errno > 0); + return -errcode; + } + + /* Read the password file line by line until the record with the matching + * username is found, or until the end of the file is reached. + * + * The format of the password file is: + * + * user:x:uid:uid:home + * + * Where: + * user: User name + * x: Encrypted password + * uid: User ID + * uid: Group ID + * home: Login directory + */ + + while (fgets(buffer, buflen, stream) != NULL) + { + ptr = buffer; + entry->pw_name = ptr; + + /* Skip to the end of the name and properly terminate it. The name + * must be terminated with the field delimiter ':'. + */ + + for (; *ptr != '\n' && *ptr != '\0' && *ptr != ':'; ptr++) + { + } + + if (*ptr == '\n' || *ptr == '\0') + { + /* Bad line format? */ + + continue; + } + + *ptr++ = '\0'; + + /* Skip to the end of the password and properly terminate it. The + * password must be terminated with the field delimiter ':'. + */ + + for (; *ptr != '\n' && *ptr != '\0' && *ptr != ':'; ptr++) + { + } + + if (*ptr == '\n' || *ptr == '\0') + { + /* Bad line format? */ + + continue; + } + + *ptr++ = '\0'; + save = ptr; + + /* Skip to the end of the user ID and properly terminate it. The + * user ID must be terminated with the field delimiter ':'. + */ + + for (; *ptr != '\n' && *ptr != '\0' && *ptr != ':'; ptr++) + { + } + + if (*ptr == '\n' || *ptr == '\0') + { + /* Bad line format? */ + + continue; + } + + *ptr++ = '\0'; + entry->pw_uid = (uid_t)atoi(save); + save = ptr; + + /* Skip to the end of the group ID and properly terminate it. The + * group ID must be terminated with the field delimiter ':'. + */ + + for (; *ptr != '\n' && *ptr != '\0' && *ptr != ':'; ptr++) + { + } + + if (*ptr == '\n' || *ptr == '\0') + { + /* Bad line format? */ + + continue; + } + + *ptr++ = '\0'; + entry->pw_gid = (gid_t)atoi(save); + entry->pw_dir = ptr; + + /* Skip to the end of the home directory and properly terminate it. + * The home directory must be the last thing on the line. + */ + + for (; *ptr != '\n' && *ptr != '\0' /* && *ptr != ':' */ ; ptr++) + { + } + + *ptr++ = '\0'; + entry->pw_shell = ROOT_SHELL; + + /* Check for a match */ + + ret = match(entry, arg); + if (ret != 0) + { + /* We either have the match or an error occurred. */ + + fclose(stream); + return ret; + } + } + + fclose(stream); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pwd_findby_name + * + * Description: + * Find passwd file entry using the user name. + * + * Input Parameters: + * uname - The user name + * entry - Location to return the parsed passwd file entry + * buffer - I/O buffer used to access the passwd file + * buflen - The size of the I/O buffer in bytes + * + * Returned Value: + * < 0 : An error has occurred. + * = 0 : No entry with this name was found. + * = 1 : The entry with this name was found. + * + ****************************************************************************/ + +int pwd_findby_name(FAR const char *uname, FAR struct passwd *entry, + FAR char *buffer, size_t buflen) +{ + return pwd_foreach(pwd_match_name, (FAR void *)uname, entry, buffer, buflen); +} + +/**************************************************************************** + * Name: pwd_findby_uid + * + * Description: + * Find passwd file entry using the user ID. + * + * Input Parameters: + * uid - The user ID + * entry - Location to return the parsed passwd file entry + * buffer - I/O buffer used to access the passwd file + * buflen - The size of the I/O buffer in bytes + * + * Returned Value: + * < 0 : An error has occurred. + * = 0 : No entry with this name was found. + * = 1 : The entry with this name was found. + * + ****************************************************************************/ + +int pwd_findby_uid(uid_t uid, FAR struct passwd *entry, FAR char *buffer, + size_t buflen) +{ + return pwd_foreach(pwd_match_uid, (FAR void *)((uintptr_t)uid), entry, + buffer, buflen); +} diff --git a/libs/libc/pwd/lib_pwd.c b/libs/libc/pwd/lib_getpwbuf.c similarity index 68% rename from libs/libc/pwd/lib_pwd.c rename to libs/libc/pwd/lib_getpwbuf.c index 05da8ab93c..ce67cdd696 100644 --- a/libs/libc/pwd/lib_pwd.c +++ b/libs/libc/pwd/lib_getpwbuf.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libs/libc/pwd/lib_pwd.c + * libs/libc/pwd/lib_getpwbuf.c * * Copyright (C) 2019 Gregory Nutt. All rights reserved. * Author: Michael Jung @@ -126,59 +126,3 @@ error: return NULL; } - -/**************************************************************************** - * Name: getpwbuf_r - * - * Description: - * libc/grp internal helper function for getpwuid_r and getpwnam_r to setup - * the caller supplied 'pwd' and 'buf' buffers once a matching entry has - * been found. - * - * Input Parameters: - * uid - Value to set the passwd structure's pw_uid field to. - * gid - Value to set the passwd structure's pw_gid field to. - * name - Value to set the passwd structure's pw_name field to. - * dir - Value to set the passwd structure's pw_dir field to. - * shell - Value to set the passwd structure's pw_shell field to. - * pwd - Pointer to the space to store the retrieved passwd structure in. - * buf - String fields pointed to by the passwd struct are stored here. - * buflen - The length of buf in bytes. - * result - Pointer to the resulting passwd struct, or NULL in case of fail. - * - * Returned Value: - * On success getpwgid_r returns 0 and sets *result to pwd. In case of - * failure an error number is returned. - * - ****************************************************************************/ - -int getpwbuf_r(uid_t uid, gid_t gid, FAR const char *name, - FAR const char *dir, FAR const char *shell, - FAR struct passwd *pwd, FAR char *buf, size_t buflen, - FAR struct passwd **result) -{ - size_t reqdlen; - - reqdlen = strlen(name) + 1 + strlen(dir) + 1 + strlen(shell) + 1; - - if (buflen < reqdlen) - { - /* Insufficient buffer space supplied. */ - - *result = NULL; - return ERANGE; - } - - pwd->pw_name = buf; - pwd->pw_dir = &buf[strlen(name) + 1]; - pwd->pw_shell = &buf[strlen(name) + 1 + strlen(dir) + 1]; - - pwd->pw_uid = uid; - pwd->pw_gid = gid; - strcpy(pwd->pw_name, name); - strcpy(pwd->pw_dir, dir); - strcpy(pwd->pw_shell, shell); - - *result = pwd; - return 0; -} diff --git a/libs/libc/pwd/lib_getpwbufr.c b/libs/libc/pwd/lib_getpwbufr.c new file mode 100644 index 0000000000..cbe8cb67bf --- /dev/null +++ b/libs/libc/pwd/lib_getpwbufr.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * libs/libc/pwd/lib_getpwbufr.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Michael Jung + * + * 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 NuttX 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 THE COPYRIGHT HOLDERS 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 THE + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "pwd/lib_pwd.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: getpwbuf_r + * + * Description: + * libc/grp internal helper function for getpwuid_r and getpwnam_r to setup + * the caller supplied 'pwd' and 'buf' buffers once a matching entry has + * been found. + * + * Input Parameters: + * uid - Value to set the passwd structure's pw_uid field to. + * gid - Value to set the passwd structure's pw_gid field to. + * name - Value to set the passwd structure's pw_name field to. + * dir - Value to set the passwd structure's pw_dir field to. + * shell - Value to set the passwd structure's pw_shell field to. + * pwd - Pointer to the space to store the retrieved passwd structure in. + * buf - String fields pointed to by the passwd struct are stored here. + * buflen - The length of buf in bytes. + * result - Pointer to the resulting passwd struct, or NULL in case of fail. + * + * Returned Value: + * On success getpwgid_r returns 0 and sets *result to pwd. In case of + * failure an error number is returned. + * + ****************************************************************************/ + +int getpwbuf_r(uid_t uid, gid_t gid, FAR const char *name, + FAR const char *dir, FAR const char *shell, + FAR struct passwd *pwd, FAR char *buf, size_t buflen, + FAR struct passwd **result) +{ + size_t reqdlen; + + reqdlen = strlen(name) + 1 + strlen(dir) + 1 + strlen(shell) + 1; + + if (buflen < reqdlen) + { + /* Insufficient buffer space supplied. */ + + *result = NULL; + return ERANGE; + } + + pwd->pw_name = buf; + pwd->pw_dir = &buf[strlen(name) + 1]; + pwd->pw_shell = &buf[strlen(name) + 1 + strlen(dir) + 1]; + + pwd->pw_uid = uid; + pwd->pw_gid = gid; + strcpy(pwd->pw_name, name); + strcpy(pwd->pw_dir, dir); + strcpy(pwd->pw_shell, shell); + + *result = pwd; + return 0; +} diff --git a/libs/libc/pwd/lib_getpwnam.c b/libs/libc/pwd/lib_getpwnam.c index 21de0510a1..6d2456eaff 100644 --- a/libs/libc/pwd/lib_getpwnam.c +++ b/libs/libc/pwd/lib_getpwnam.c @@ -69,10 +69,23 @@ FAR struct passwd *getpwnam(FAR const char *name) { +#ifdef CONFIG_LIBC_PASSWD_FILE + int ret; + + ret = pwd_findby_name(name, &g_passwd, g_passwd_buffer, + CONFIG_LIBC_PASSWD_LINESIZE); + if (ret != 1) + { + return NULL; + } + + return &g_passwd; +#else if (strcmp(name, ROOT_NAME)) { return NULL; } return getpwbuf(ROOT_UID, ROOT_GID, ROOT_NAME, ROOT_DIR, ROOT_SHELL); +#endif } diff --git a/libs/libc/pwd/lib_getpwnamr.c b/libs/libc/pwd/lib_getpwnamr.c index 74b4324507..1fb8a349fd 100644 --- a/libs/libc/pwd/lib_getpwnamr.c +++ b/libs/libc/pwd/lib_getpwnamr.c @@ -73,6 +73,19 @@ int getpwnam_r(FAR const char *name, FAR struct passwd *pwd, FAR char *buf, size_t buflen, FAR struct passwd **result) { +#ifdef CONFIG_LIBC_PASSWD_FILE + int ret; + + ret = pwd_findby_name(name, pwd, buf, buflen); + if (ret != 1) + { + *result = NULL; + return ret < 0 ? -ret : 0; + } + + *result = pwd; + return 0; +#else if (strcmp(name, ROOT_NAME)) { /* The only known user is 'root', which has a uid of 0. Thus, report @@ -85,4 +98,5 @@ int getpwnam_r(FAR const char *name, FAR struct passwd *pwd, FAR char *buf, return getpwbuf_r(ROOT_UID, ROOT_GID, ROOT_NAME, ROOT_DIR, ROOT_SHELL, pwd, buf, buflen, result); +#endif } diff --git a/libs/libc/pwd/lib_getpwuid.c b/libs/libc/pwd/lib_getpwuid.c index 79aa396675..a4f33effae 100644 --- a/libs/libc/pwd/lib_getpwuid.c +++ b/libs/libc/pwd/lib_getpwuid.c @@ -68,10 +68,23 @@ FAR struct passwd *getpwuid(uid_t uid) { +#ifdef CONFIG_LIBC_PASSWD_FILE + int ret; + + ret = pwd_findby_uid(uid, &g_passwd, g_passwd_buffer, + CONFIG_LIBC_PASSWD_LINESIZE); + if (ret != 1) + { + return NULL; + } + + return &g_passwd; +#else if (uid != ROOT_UID) { return NULL; } return getpwbuf(ROOT_UID, ROOT_GID, ROOT_NAME, ROOT_DIR, ROOT_SHELL); +#endif } diff --git a/libs/libc/pwd/lib_getpwuidr.c b/libs/libc/pwd/lib_getpwuidr.c index 81abcaced0..7ea6105c44 100644 --- a/libs/libc/pwd/lib_getpwuidr.c +++ b/libs/libc/pwd/lib_getpwuidr.c @@ -72,6 +72,19 @@ int getpwuid_r(uid_t uid, FAR struct passwd *pwd, FAR char *buf, size_t buflen, FAR struct passwd **result) { +#ifdef CONFIG_LIBC_PASSWD_FILE + int ret; + + ret = pwd_findby_uid(uid, pwd, buf, buflen); + if (ret != 1) + { + *result = NULL; + return ret < 0 ? -ret : 0; + } + + *result = pwd; + return 0; +#else if (uid != ROOT_UID) { /* The only known user is 'root', which has a uid of 0. Thus, report @@ -84,4 +97,5 @@ int getpwuid_r(uid_t uid, FAR struct passwd *pwd, FAR char *buf, return getpwbuf_r(ROOT_UID, ROOT_GID, ROOT_NAME, ROOT_DIR, ROOT_SHELL, pwd, buf, buflen, result); +#endif } diff --git a/libs/libc/pwd/lib_pwd.h b/libs/libc/pwd/lib_pwd.h index 5c1915f251..843eeac2ff 100644 --- a/libs/libc/pwd/lib_pwd.h +++ b/libs/libc/pwd/lib_pwd.h @@ -66,6 +66,13 @@ extern "C" #define EXTERN extern #endif +#ifdef CONFIG_LIBC_PASSWD_FILE +/* Data for non-reentrant group functions */ + +EXTERN struct passwd g_passwd; +EXTERN char g_passwd_buffer[CONFIG_LIBC_PASSWD_LINESIZE]; +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -77,6 +84,13 @@ int getpwbuf_r(uid_t uid, gid_t gid, FAR const char *name, FAR struct passwd *pwd, FAR char *buf, size_t buflen, FAR struct passwd **result); +#ifdef CONFIG_LIBC_PASSWD_FILE +int pwd_findby_name(FAR const char *uname, FAR struct passwd *entry, + FAR char *buffer, size_t buflen); +int pwd_findby_uid(uid_t uid, FAR struct passwd *entry, FAR char *buffer, + size_t buflen); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/libs/libc/pwd/lib_pwd_globals.c b/libs/libc/pwd/lib_pwd_globals.c new file mode 100644 index 0000000000..542421f49a --- /dev/null +++ b/libs/libc/pwd/lib_pwd_globals.c @@ -0,0 +1,55 @@ +/**************************************************************************** + * libs/libc/pwd/lib_pwd_globals.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 NuttX 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 THE COPYRIGHT HOLDERS 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 THE + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "pwd/lib_pwd.h" + +#ifdef CONFIG_LIBC_PASSWD_FILE + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Data for non-reentrant group functions */ + +struct passwd g_passwd; +char g_passwd_buffer[CONFIG_LIBC_PASSWD_LINESIZE]; + +#endif /* CONFIG_LIBC_GROUP_FILE */