659 lines
21 KiB
Diff
659 lines
21 KiB
Diff
From 1d768559f42375eb3bbb3ad0de52a6b49535e40c Mon Sep 17 00:00:00 2001
|
|
From: chegJH <hejunjie10@huawei.com>
|
|
Date: Thu, 7 Apr 2022 17:33:06 +0800
|
|
Subject: [PATCH 05/16] Adapt to bionic libc, parser for passwd and group
|
|
object
|
|
|
|
Signed-off-by: chegJH <hejunjie10@huawei.com>
|
|
---
|
|
.../modules/image/image_rootfs_handler.c | 25 ++
|
|
src/utils/cutils/utils_pwgr.c | 317 ++++++++++++++++++
|
|
src/utils/cutils/utils_pwgr.h | 33 ++
|
|
test/cutils/CMakeLists.txt | 1 +
|
|
test/cutils/utils_pwgr/CMakeLists.txt | 29 ++
|
|
test/cutils/utils_pwgr/group_sample | 8 +
|
|
test/cutils/utils_pwgr/passwd_sample | 11 +
|
|
test/cutils/utils_pwgr/utils_pwgr_ut.cc | 101 ++++++
|
|
8 files changed, 525 insertions(+)
|
|
create mode 100644 src/utils/cutils/utils_pwgr.c
|
|
create mode 100644 src/utils/cutils/utils_pwgr.h
|
|
create mode 100644 test/cutils/utils_pwgr/CMakeLists.txt
|
|
create mode 100644 test/cutils/utils_pwgr/group_sample
|
|
create mode 100644 test/cutils/utils_pwgr/passwd_sample
|
|
create mode 100644 test/cutils/utils_pwgr/utils_pwgr_ut.cc
|
|
|
|
diff --git a/src/daemon/modules/image/image_rootfs_handler.c b/src/daemon/modules/image/image_rootfs_handler.c
|
|
index f7bc9bc9..960d52c7 100644
|
|
--- a/src/daemon/modules/image/image_rootfs_handler.c
|
|
+++ b/src/daemon/modules/image/image_rootfs_handler.c
|
|
@@ -33,6 +33,7 @@
|
|
#include "path.h"
|
|
#include "utils_convert.h"
|
|
#include "utils_file.h"
|
|
+#include "utils_pwgr.h"
|
|
|
|
#define MINUID 0
|
|
#define MAXUID (((1LL << 31) - 1))
|
|
@@ -88,7 +89,11 @@ static int proc_by_fpasswd(FILE *f_passwd, const char *user, defs_process_user *
|
|
struct passwd *pwbufp = NULL;
|
|
|
|
if (f_passwd != NULL) {
|
|
+#ifdef __ANDROID__
|
|
+ errval = util_getpwent_r(f_passwd, &pw, buf, sizeof(buf), &pwbufp);
|
|
+#else
|
|
errval = fgetpwent_r(f_passwd, &pw, buf, sizeof(buf), &pwbufp);
|
|
+#endif
|
|
|
|
while (errval == 0 && pwbufp != NULL) {
|
|
userfound = b_user_found(user, pwbufp);
|
|
@@ -102,7 +107,11 @@ static int proc_by_fpasswd(FILE *f_passwd, const char *user, defs_process_user *
|
|
*matched_username = util_strdup_s(pwbufp->pw_name);
|
|
break;
|
|
}
|
|
+#ifdef __ANDROID__
|
|
+ errval = util_getpwent_r(f_passwd, &pw, buf, sizeof(buf), &pwbufp);
|
|
+#else
|
|
errval = fgetpwent_r(f_passwd, &pw, buf, sizeof(buf), &pwbufp);
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
@@ -212,14 +221,22 @@ static int do_proc_by_froup(FILE *f_group, const char *group, defs_process_user
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef __ANDROID__
|
|
+ errval = util_getgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
|
|
+#else
|
|
errval = fgetgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
|
|
+#endif
|
|
while (errval == 0 && gbufp != NULL) {
|
|
// Treat numeric group as valid GID
|
|
if (group == NULL) {
|
|
if (search_group_list(gbufp, matched_username, puser) != 0) {
|
|
return -1;
|
|
}
|
|
+#ifdef __ANDROID__
|
|
+ errval = util_getgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
|
|
+#else
|
|
errval = fgetgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
|
|
+#endif
|
|
continue;
|
|
}
|
|
|
|
@@ -229,7 +246,11 @@ static int do_proc_by_froup(FILE *f_group, const char *group, defs_process_user
|
|
puser->gid = gbufp->gr_gid;
|
|
*groupcnt = 1;
|
|
}
|
|
+#ifdef __ANDROID__
|
|
+ errval = util_getgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
|
|
+#else
|
|
errval = fgetgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp);
|
|
+#endif
|
|
}
|
|
|
|
return 0;
|
|
@@ -363,7 +384,11 @@ static int get_additional_groups(char **additional_groups, size_t additional_gro
|
|
struct group *gbufp = NULL;
|
|
struct group *groups = NULL;
|
|
|
|
+#ifdef __ANDROID__
|
|
+ while (f_group != NULL && util_getgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp) == 0) {
|
|
+#else
|
|
while (f_group != NULL && fgetgrent_r(f_group, &grp, buf, sizeof(buf), &gbufp) == 0) {
|
|
+#endif
|
|
for (i = 0; i < additional_groups_len; i++) {
|
|
if (!group_matched(additional_groups[i], gbufp)) {
|
|
continue;
|
|
diff --git a/src/utils/cutils/utils_pwgr.c b/src/utils/cutils/utils_pwgr.c
|
|
new file mode 100644
|
|
index 00000000..f4588268
|
|
--- /dev/null
|
|
+++ b/src/utils/cutils/utils_pwgr.c
|
|
@@ -0,0 +1,317 @@
|
|
+/******************************************************************************
|
|
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
|
|
+ * iSulad licensed under the Mulan PSL v2.
|
|
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
+ * You may obtain a copy of Mulan PSL v2 at:
|
|
+ * http://license.coscl.org.cn/MulanPSL2
|
|
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
|
+ * PURPOSE.
|
|
+ * See the Mulan PSL v2 for more details.
|
|
+ * Author: hejunjie
|
|
+ * Create: 2022-04-08
|
|
+ * Description: Provide line parser for android
|
|
+ *******************************************************************************/
|
|
+
|
|
+#define _GNU_SOURCE
|
|
+#include "utils_pwgr.h"
|
|
+
|
|
+#include <unistd.h>
|
|
+#include <errno.h>
|
|
+#include <stdlib.h>
|
|
+#include <stdio_ext.h>
|
|
+
|
|
+#include "isula_libutils/log.h"
|
|
+#include "utils_string.h"
|
|
+#include "utils_convert.h"
|
|
+#include "utils_file.h"
|
|
+#include "utils.h"
|
|
+
|
|
+static int hold_int(const char delim, bool required, char **src, unsigned int *dst)
|
|
+{
|
|
+ long long res = 0;
|
|
+ char *walker = *src;
|
|
+ char *err_str = NULL;
|
|
+
|
|
+ if (**src == '\0') {
|
|
+ ERROR("Empty subject on given entrie is not allowed.");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ while (*walker != delim) {
|
|
+ if (*walker == '\0') {
|
|
+ break;
|
|
+ }
|
|
+ ++walker;
|
|
+ }
|
|
+
|
|
+ if (*walker == **src) {
|
|
+ if (required) { // deafult 0 while required full content but integer part is missing
|
|
+ *dst = 0;
|
|
+ *src = walker + 1;
|
|
+ return 0;
|
|
+ }
|
|
+ ERROR("Integer part is missing.");
|
|
+ ++(*src);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ res = strtoll(*src, &err_str, 0);
|
|
+ if (errno == ERANGE) {
|
|
+ ERROR("Parse int from string failed.");
|
|
+ return -1;
|
|
+ }
|
|
+ if (res < 0) {
|
|
+ ERROR("Gid uid shall not be negative.");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (sizeof(void *) > 4 && res > UINT_MAX) { // make sure 64-bit platform behave same as 32-bit
|
|
+ res = UINT_MAX;
|
|
+ }
|
|
+ res = res & UINT_MAX;
|
|
+ *dst = (uint32_t)res;
|
|
+ *src = err_str + 1; // update src to next valid context in line.
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int hold_string(const char delim, char **src, char **dst)
|
|
+{
|
|
+ if (**src == delim) { // if src point to deliminator, content parsing is skiped.
|
|
+ *dst = "";
|
|
+ *src = *src + 1;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (**src == '\0') {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ for (*dst = *src; **src != delim; ++(*src)) {
|
|
+ if (**src == '\0') {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (**src == delim) {
|
|
+ **src = '\0';
|
|
+ ++(*src);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int parse_line_pw(const char delim, char *line, struct passwd *result)
|
|
+{
|
|
+ int ret = 0;
|
|
+ bool required = false;
|
|
+
|
|
+ ret = hold_string(delim, &line, &result->pw_name);
|
|
+ if (ret != 0) {
|
|
+ ERROR("Parse name error.");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ required = (result->pw_name[0] == '+' || result->pw_name[0] == '-') ? true : false;
|
|
+
|
|
+ ret = hold_string(delim, &line, &result->pw_passwd);
|
|
+ if (ret != 0) {
|
|
+ ERROR("Parse passwd error.");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ret = hold_int(delim, required, &line, &result->pw_uid);
|
|
+ if (ret != 0) {
|
|
+ // a legitimate line must have uid
|
|
+ ERROR("Parse uid error.");
|
|
+ return ret;
|
|
+ }
|
|
+ ret = hold_int(delim, required, &line, &result->pw_gid);
|
|
+ if (ret != 0) {
|
|
+ // it's ok to not provide gid
|
|
+ ERROR("Parse gid error.");
|
|
+ }
|
|
+
|
|
+ ret = hold_string(delim, &line, &result->pw_gecos);
|
|
+ if (ret != 0) {
|
|
+ ERROR("Parse gecos error.");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ret = hold_string(delim, &line, &result->pw_dir);
|
|
+ if (ret != 0) {
|
|
+ ERROR("Parse dir error.");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ret = hold_string(delim, &line, &result->pw_shell);
|
|
+ if (ret != 0) {
|
|
+ ERROR("Parse shell error.");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static char **hold_string_list(char **line, char *buf_start, char *buf_end, const char terminator)
|
|
+{
|
|
+ char **result = NULL;
|
|
+ char **walker = NULL;
|
|
+
|
|
+ if (**line == '\0') {
|
|
+ return 0;
|
|
+ }
|
|
+ // For ultimate space usage, the blank area from buffer which was allocated from stack is used
|
|
+ buf_start += __alignof__(char *) - 1;
|
|
+ // align the starting position of the buffer to use it as a 2d array
|
|
+ buf_start -= (buf_start - (char *)0) % __alignof__(char *);
|
|
+ // record the starting position for latter return
|
|
+ result = (char **)buf_start;
|
|
+ // set stop edge for the buffer
|
|
+ walker = result;
|
|
+
|
|
+ for (; walker < (char **)buf_end; ++walker) {
|
|
+ (void)util_trim_space(*line);
|
|
+ if (hold_string(',', line, walker) != 0) {
|
|
+ ERROR("Parse string list error.");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if ((char *)(walker + 2) > buf_end) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (**line == '\0') {
|
|
+ return result;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return result;
|
|
+}
|
|
+
|
|
+static int parse_line_gr(const char delim, char *line, size_t buflen, struct group *result)
|
|
+{
|
|
+ int ret = 0;
|
|
+ bool rf = false;
|
|
+ char *freebuff = line + 1 + strlen(line);
|
|
+ char *buffend = line + buflen;
|
|
+
|
|
+ ret = hold_string(delim, &line, &result->gr_name);
|
|
+ if (ret != 0) {
|
|
+ ERROR("Parse name error.");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ret = hold_string(delim, &line, &result->gr_passwd);
|
|
+ if (ret != 0) {
|
|
+ ERROR("Parse gecos error.");
|
|
+ return ret;
|
|
+ }
|
|
+ if (result->gr_name[0] == '+' || result->gr_name[0] == '-') {
|
|
+ rf = true;
|
|
+ }
|
|
+
|
|
+ ret = hold_int(delim, rf, &line, &result->gr_gid);
|
|
+ if (ret != 0) {
|
|
+ ERROR("Parse gid error.");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ result->gr_mem = hold_string_list(&line, freebuff, buffend, ',');
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int util_getpwent_r(FILE *stream, struct passwd *resbuf, char *buffer, size_t buflen, struct passwd **result)
|
|
+{
|
|
+ const char delim = ':';
|
|
+
|
|
+ if (stream == NULL || resbuf == NULL || buffer == NULL) {
|
|
+ ERROR("Password obj, params is NULL.");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (buflen <= 1) {
|
|
+ ERROR("Inadiquate buffer length was given.");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (*result != NULL) {
|
|
+ ERROR("Result shall point to null to start.");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ __fsetlocking(stream, FSETLOCKING_BYCALLER);
|
|
+ buffer[buflen - 1] = '\0';
|
|
+
|
|
+ if (feof(stream)) {
|
|
+ *result = NULL;
|
|
+ return ENOENT;
|
|
+ }
|
|
+
|
|
+ while (fgets(buffer, buflen, stream) != NULL) {
|
|
+ (void)util_trim_space(buffer);
|
|
+ if (buffer[0] == '\0' || buffer[0] == '#' || strlen(buffer) < 1) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (parse_line_pw(delim, buffer, resbuf) == 0) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (buffer[buflen - 1] != '\0') {
|
|
+ *result = NULL;
|
|
+ return ERANGE;
|
|
+ }
|
|
+ }
|
|
+ *result = resbuf;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int util_getgrent_r(FILE *stream, struct group *resbuf, char *buffer, size_t buflen, struct group **result)
|
|
+{
|
|
+ const char delim = ':';
|
|
+
|
|
+ if (stream == NULL || resbuf == NULL || buffer == NULL) {
|
|
+ ERROR("Group obj, params is NULL.");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (buflen <= 1) {
|
|
+ ERROR("Inadiquate buffer length was given.");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (*result != NULL) {
|
|
+ ERROR("Result shall point to null to start.");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ __fsetlocking(stream, FSETLOCKING_BYCALLER);
|
|
+ buffer[buflen - 1] = '\0';
|
|
+
|
|
+ if (feof(stream)) {
|
|
+ *result = NULL;
|
|
+ return ENOENT;
|
|
+ }
|
|
+
|
|
+ while (fgets(buffer, buflen, stream) != NULL) {
|
|
+ (void)util_trim_space(buffer);
|
|
+ if (buffer[0] == '\0' || buffer[0] == '#' || strlen(buffer) < 1) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (parse_line_gr(delim, buffer, buflen, resbuf) == 0) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (buffer[buflen - 1] != '\0') {
|
|
+ *result = NULL;
|
|
+ return ERANGE;
|
|
+ }
|
|
+ }
|
|
+ *result = resbuf;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/src/utils/cutils/utils_pwgr.h b/src/utils/cutils/utils_pwgr.h
|
|
new file mode 100644
|
|
index 00000000..45e38059
|
|
--- /dev/null
|
|
+++ b/src/utils/cutils/utils_pwgr.h
|
|
@@ -0,0 +1,33 @@
|
|
+/******************************************************************************
|
|
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
|
|
+ * iSulad licensed under the Mulan PSL v2.
|
|
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
+ * You may obtain a copy of Mulan PSL v2 at:
|
|
+ * http://license.coscl.org.cn/MulanPSL2
|
|
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
|
+ * PURPOSE.
|
|
+ * See the Mulan PSL v2 for more details.
|
|
+ * Author: hejunjie
|
|
+ * Create: 2022-04-08
|
|
+ * Description: Provide line parser for android
|
|
+ *******************************************************************************/
|
|
+#ifndef UTILS_CUTILS_UTILS_PWGR_H
|
|
+#define UTILS_CUTILS_UTILS_PWGR_H
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <pwd.h>
|
|
+#include <grp.h>
|
|
+
|
|
+#ifdef __cplusplus
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+int util_getpwent_r(FILE *stream, struct passwd *resbuf, char *buffer, size_t buflen, struct passwd **result);
|
|
+
|
|
+int util_getgrent_r(FILE *stream, struct group *resbuf, char *buffer, size_t buflen, struct group **result);
|
|
+
|
|
+#ifdef __cplusplus
|
|
+}
|
|
+#endif
|
|
+#endif // UTILS_CUTILS_UTILS_PWGR_H
|
|
diff --git a/test/cutils/CMakeLists.txt b/test/cutils/CMakeLists.txt
|
|
index 826255cd..b549f844 100644
|
|
--- a/test/cutils/CMakeLists.txt
|
|
+++ b/test/cutils/CMakeLists.txt
|
|
@@ -4,3 +4,4 @@ add_subdirectory(utils_string)
|
|
add_subdirectory(utils_convert)
|
|
add_subdirectory(utils_array)
|
|
add_subdirectory(utils_base64)
|
|
+add_subdirectory(utils_pwgr)
|
|
diff --git a/test/cutils/utils_pwgr/CMakeLists.txt b/test/cutils/utils_pwgr/CMakeLists.txt
|
|
new file mode 100644
|
|
index 00000000..548718da
|
|
--- /dev/null
|
|
+++ b/test/cutils/utils_pwgr/CMakeLists.txt
|
|
@@ -0,0 +1,29 @@
|
|
+project(iSulad_UT)
|
|
+
|
|
+SET(EXE utils_pwgr_ut)
|
|
+
|
|
+add_executable(${EXE}
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_string.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_array.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_file.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_convert.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_verify.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_regex.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_pwgr.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/sha256/sha256.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map/map.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map/rb_tree.c
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/path.c
|
|
+ utils_pwgr_ut.cc)
|
|
+
|
|
+target_include_directories(${EXE} PUBLIC
|
|
+ ${GTEST_INCLUDE_DIR}
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../include
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/common
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/sha256
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils
|
|
+ )
|
|
+target_link_libraries(${EXE} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${ISULA_LIBUTILS_LIBRARY} -lcrypto -lyajl -lz)
|
|
+add_test(NAME ${EXE} COMMAND ${EXE} --gtest_output=xml:${EXE}-Results.xml)
|
|
diff --git a/test/cutils/utils_pwgr/group_sample b/test/cutils/utils_pwgr/group_sample
|
|
new file mode 100644
|
|
index 00000000..c73883cc
|
|
--- /dev/null
|
|
+++ b/test/cutils/utils_pwgr/group_sample
|
|
@@ -0,0 +1,8 @@
|
|
+root:x:0:
|
|
+#bin:x:1:
|
|
+
|
|
+-adm:x:4:
|
|
++adm:x:4:
|
|
+adm:x:4:a,list,of,users
|
|
+adm:x:4:are,split,by,comma
|
|
+adm:x:4:root,john, boob,jason
|
|
\ No newline at end of file
|
|
diff --git a/test/cutils/utils_pwgr/passwd_sample b/test/cutils/utils_pwgr/passwd_sample
|
|
new file mode 100644
|
|
index 00000000..d4f3250d
|
|
--- /dev/null
|
|
+++ b/test/cutils/utils_pwgr/passwd_sample
|
|
@@ -0,0 +1,11 @@
|
|
+root:x:0:0:root:/root:/bin/bash
|
|
+bin:x:1:1:bin:/bin:/sbin/nologin
|
|
+bin:x:-1:1:bin:/bin:/sbin/nologin
|
|
+uidonly:x:1::bin:/bin:/sbin/nologin
|
|
+::::1:1:bin:/bin:/sbin/nologin
|
|
+
|
|
+#npt:*:66:77::/etc/ntp:/sbin/nologin
|
|
+npt:*:66:77::/etc/ntp:/sbin/nologin
|
|
+npt:*:66:77::/etc/ntp:/sbin/nologin:some:extra:context:added
|
|
++npt:*::::/etc/ntp:/sbin/nologin
|
|
+-npt:*::::/etc/ntp:/sbin/nologin
|
|
\ No newline at end of file
|
|
diff --git a/test/cutils/utils_pwgr/utils_pwgr_ut.cc b/test/cutils/utils_pwgr/utils_pwgr_ut.cc
|
|
new file mode 100644
|
|
index 00000000..1a121f88
|
|
--- /dev/null
|
|
+++ b/test/cutils/utils_pwgr/utils_pwgr_ut.cc
|
|
@@ -0,0 +1,101 @@
|
|
+/******************************************************************************
|
|
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
|
|
+ * iSulad licensed under the Mulan PSL v2.
|
|
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
+ * You may obtain a copy of Mulan PSL v2 at:
|
|
+ * http://license.coscl.org.cn/MulanPSL2
|
|
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
|
+ * PURPOSE.
|
|
+ * See the Mulan PSL v2 for more details.
|
|
+ * Author: hejunjie
|
|
+ * Create: 2022-04-08
|
|
+ * Description: utils_pwgr unit test
|
|
+ *******************************************************************************/
|
|
+
|
|
+#include <gtest/gtest.h>
|
|
+#include "utils_pwgr.h"
|
|
+
|
|
+TEST(utils_pwgr, test_getpwent_r)
|
|
+{
|
|
+ std::string path = "../../../../test/cutils/utils_pwgr/passwd_sample";
|
|
+ FILE *f_pw = fopen(path.c_str(), "r");
|
|
+ ASSERT_NE(f_pw, nullptr);
|
|
+
|
|
+ struct passwd pw;
|
|
+ struct passwd *ppw = nullptr;
|
|
+ char buf[BUFSIZ];
|
|
+
|
|
+ std::vector<std::tuple<std::string, std::string, int, int, std::string, std::string, std::string>> testcase = {
|
|
+ std::make_tuple("root", "x", 0, 0, "root", "/root", "/bin/bash"),
|
|
+ std::make_tuple("bin", "x", 1, 1, "bin", "/bin", "/sbin/nologin"),
|
|
+ std::make_tuple("uidonly", "x", 1, 0, "bin", "/bin", "/sbin/nologin"),
|
|
+ std::make_tuple("npt", "*", 66, 77, "", "/etc/ntp", "/sbin/nologin"),
|
|
+ std::make_tuple("npt", "*", 66, 77, "", "/etc/ntp", "/sbin/nologin"),
|
|
+ std::make_tuple("+npt", "*", 0, 0, "", "/etc/ntp", "/sbin/nologin"),
|
|
+ std::make_tuple("-npt", "*", 0, 0, "", "/etc/ntp", "/sbin/nologin")
|
|
+ };
|
|
+
|
|
+ for (const auto &elem : testcase) {
|
|
+ ASSERT_EQ(util_getpwent_r(f_pw, &pw, buf, sizeof(buf), &ppw), 0);
|
|
+ ASSERT_STREQ(pw.pw_name, std::get<0>(elem).c_str());
|
|
+ ASSERT_STREQ(pw.pw_passwd, std::get<1>(elem).c_str());
|
|
+ ASSERT_EQ(pw.pw_uid, std::get<2>(elem));
|
|
+ ASSERT_EQ(pw.pw_gid, std::get<3>(elem));
|
|
+ ASSERT_STREQ(pw.pw_gecos, std::get<4>(elem).c_str());
|
|
+ ASSERT_STREQ(pw.pw_dir, std::get<5>(elem).c_str());
|
|
+ ASSERT_STREQ(pw.pw_shell, std::get<6>(elem).c_str());
|
|
+ EXPECT_TRUE(ppw == &pw);
|
|
+ ppw = nullptr;
|
|
+ pw = {0};
|
|
+ }
|
|
+
|
|
+ fclose(f_pw);
|
|
+}
|
|
+
|
|
+TEST(utils_pwgr, test_getgrent_r)
|
|
+{
|
|
+ std::string path = "../../../../test/cutils/utils_pwgr/group_sample";
|
|
+ FILE *f_gr = fopen(path.c_str(), "r");
|
|
+ ASSERT_NE(f_gr, nullptr);
|
|
+
|
|
+ struct group gr{0};
|
|
+ struct group *pgr = nullptr;
|
|
+ char buf[BUFSIZ];
|
|
+ size_t i = 0;
|
|
+ size_t j = 0;
|
|
+ std::vector<std::vector<std::string>> string_list{
|
|
+ {}, {}, {},
|
|
+ {"a", "list", "of", "users"},
|
|
+ {"are", "split", "by", "comma"},
|
|
+ {"root", "john", "boob", "jason"}
|
|
+ };
|
|
+
|
|
+ std::vector<std::tuple<std::string, std::string, int>> testcase = {
|
|
+ std::make_tuple("root", "x", 0),
|
|
+ std::make_tuple("-adm", "x", 4),
|
|
+ std::make_tuple("+adm", "x", 4),
|
|
+ std::make_tuple("adm", "x", 4),
|
|
+ std::make_tuple("adm", "x", 4),
|
|
+ std::make_tuple("adm", "x", 4),
|
|
+ };
|
|
+
|
|
+ for (; i < string_list.size(); ++i) {
|
|
+ ASSERT_EQ(util_getgrent_r(f_gr, &gr, buf, sizeof(buf), &pgr), 0);
|
|
+ ASSERT_STREQ(gr.gr_name, std::get<0>(testcase[i]).c_str());
|
|
+ ASSERT_STREQ(gr.gr_passwd, std::get<1>(testcase[i]).c_str());
|
|
+ ASSERT_EQ(gr.gr_gid, std::get<2>(testcase[i]));
|
|
+ if (string_list[i].size()) {
|
|
+ for (j = 0; j < string_list[i].size(); ++j) {
|
|
+ EXPECT_TRUE(strcmp(gr.gr_mem[j], string_list[i][j].c_str()) == 0);
|
|
+ }
|
|
+ } else {
|
|
+ EXPECT_TRUE(gr.gr_mem == nullptr);
|
|
+ }
|
|
+ EXPECT_TRUE(pgr == &gr);
|
|
+ gr = {0};
|
|
+ pgr = nullptr;
|
|
+ }
|
|
+
|
|
+ fclose(f_gr);
|
|
+}
|
|
\ No newline at end of file
|
|
--
|
|
2.20.1
|
|
|