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 }