1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <errno.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <grp.h>
19 #include <pwd.h>
20 #include <dirent.h>
21
22 #include "begetctl.h"
23 #include "init_utils.h"
24 #include "init_param.h"
25 #include "securec.h"
26 #include "shell_utils.h"
27 #include "parameter.h"
28
29 #define BEGETCTRL_INIT_CMD "ohos.servicectrl.cmd"
30
31 /**
32 * @brief 通用的命令通道,注册函数完成参数校验,调用HandleCmd进行处理
33 * init进程使用 initCmd 按命令字进行处理
34 */
HandleCmd(BShellHandle shell,const char * cmdName,int argc,char ** argv)35 static int HandleCmd(BShellHandle shell, const char *cmdName, int argc, char **argv)
36 {
37 BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
38 BSH_LOGI("initCmd %s argc %d", cmdName, argc);
39 // format args
40 if (argc == 0) {
41 return SystemSetParameter(BEGETCTRL_INIT_CMD, cmdName);
42 }
43 char value[PARAM_VALUE_LEN_MAX] = { 0 };
44 int ret = sprintf_s(value, sizeof(value) - 1, "%s ", cmdName);
45 BSH_CHECK(ret > 0, return BSH_INVALID_PARAM, "Failed to format cmdName");
46 for (int i = 0; i < argc; i++) {
47 ret = strcat_s(value, sizeof(value), argv[i]);
48 BSH_CHECK(ret == 0, return BSH_INVALID_PARAM, "Failed to format name");
49 ret = strcat_s(value, sizeof(value), " ");
50 BSH_CHECK(ret == 0, return BSH_INVALID_PARAM, "Failed to format name");
51 }
52 return SystemSetParameter(BEGETCTRL_INIT_CMD, value);
53 }
54
SetInitLogLevelFromParam(BShellHandle shell,int argc,char ** argv)55 static int SetInitLogLevelFromParam(BShellHandle shell, int argc, char **argv)
56 {
57 if (argc != 2) { // 2 is set log level parameter number
58 char *helpArgs[] = {"set", NULL};
59 BShellCmdHelp(shell, 1, helpArgs);
60 return 0;
61 }
62 errno = 0;
63 unsigned int level = strtoul(argv[1], 0, 10); // 10 is decimal
64 if (errno != 0) {
65 printf("Failed to transform %s to unsigned int. \n", argv[1]);
66 return -1;
67 }
68 if ((level >= INIT_DEBUG) && (level <= INIT_FATAL)) {
69 const char *logLevelStr[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" };
70 int ret = HandleCmd(shell, "setloglevel", argc - 1, &argv[1]);
71 if (ret != 0) {
72 printf("Failed to set log level %s. \n", logLevelStr[level]);
73 } else {
74 printf("Success to set log level %s. \n", logLevelStr[level]);
75 }
76 } else {
77 printf("%s is invalid. \n", argv[1]);
78 }
79 return 0;
80 }
81
GetInitLogLevelFromParam(BShellHandle shell,int argc,char ** argv)82 static int32_t GetInitLogLevelFromParam(BShellHandle shell, int argc, char **argv)
83 {
84 int level = GetIntParameter(INIT_DEBUG_LEVEL, (int)INIT_ERROR);
85 if ((level >= INIT_DEBUG) && (level <= INIT_FATAL)) {
86 const char *logLevelStr[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" };
87 printf("Init log level: %s \n", logLevelStr[level]);
88 }
89 return 0;
90 }
91
GetUidByName(BShellHandle shell,int argc,char ** argv)92 static int32_t GetUidByName(BShellHandle shell, int argc, char **argv)
93 {
94 if (argc != 2) { // 2 is dac get uid parameter number
95 char *helpArgs[] = {"dac", NULL};
96 BShellCmdHelp(shell, 1, helpArgs);
97 return 0;
98 }
99 struct passwd *data = getpwnam(argv[1]);
100 if (data == NULL) {
101 printf("getpwnam uid failed\n");
102 } else {
103 printf("getpwnam uid %s : %u\n", argv[1], data->pw_uid);
104 }
105
106 data = NULL;
107 while ((data = getpwent()) != NULL) {
108 if ((data->pw_name != NULL) && (strcmp(data->pw_name, argv[1]) == 0)) {
109 printf("getpwent uid %s : %u\n", argv[1], data->pw_uid);
110 break;
111 }
112 }
113 endpwent();
114 return 0;
115 }
116
ShowUserInGroup(struct group * data)117 static void ShowUserInGroup(struct group *data)
118 {
119 int index = 0;
120 printf("users in this group:");
121 while (data->gr_mem[index]) { // user in this group
122 printf(" %s", data->gr_mem[index]);
123 index++;
124 }
125 printf("\n");
126 return;
127 }
128
GetGidByName(BShellHandle shell,int argc,char ** argv)129 static int32_t GetGidByName(BShellHandle shell, int argc, char **argv)
130 {
131 if (argc != 2) { // 2 is dac get gid parameter number
132 char *helpArgs[] = {"dac", NULL};
133 BShellCmdHelp(shell, 1, helpArgs);
134 return 0;
135 }
136 struct group *data = getgrnam(argv[1]);
137 if (data == NULL) {
138 printf("getgrnam gid failed\n");
139 } else {
140 printf("getgrnam gid %s : %u\n", argv[1], data->gr_gid);
141 ShowUserInGroup(data);
142 }
143
144 data = NULL;
145 while ((data = getgrent()) != NULL) {
146 if ((data->gr_name != NULL) && (strcmp(data->gr_name, argv[1]) == 0)) {
147 printf("getgrent gid %s : %u\n", argv[1], data->gr_gid);
148 ShowUserInGroup(data);
149 break;
150 }
151 }
152 endgrent();
153 return 0;
154 }
155
MODULE_CONSTRUCTOR(void)156 MODULE_CONSTRUCTOR(void)
157 {
158 const CmdInfo infos[] = {
159 {"set", SetInitLogLevelFromParam,
160 "set init log level 0:debug, 1:info, 2:warning, 3:err, 4:fatal", "set log level", "set log level"},
161 {"get", GetInitLogLevelFromParam, "get init log level", "get log level", "get log level"},
162 {"dac", GetGidByName, "get dac gid by group name", "dac gid groupname", "dac gid"},
163 {"dac", GetUidByName, "get dac uid by user name", "dac uid username", "dac uid"},
164 };
165 for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
166 BShellEnvRegisterCmd(GetShellHandle(), &infos[i]);
167 }
168 }