tizen 2.3.1 release
[framework/web/mobile/wrt.git] / src / wrt-launchpad-daemon / src / access_control.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 #include <errno.h>
18 #include <grp.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <sys/capability.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #include <privilege-control.h>
26
27 #include "access_control.h"
28 #include "config.h"
29 #include "simple_util.h"
30
31 namespace {
32 const char* const APP_USER_NAME = "app";
33 const char* const APP_HOME_DIR = "/home/app";
34 const char* const APP_GROUP_PATH = "/usr/share/privilege-control/2.2.1/app_group_list";
35 const int APP_UID = 5000;
36 const int APP_GID = 5000;
37 } // anonymous namespace
38
39 #ifdef DAC_ACTIVATE
40
41 int AccessControl::setPriviledge(const char* pkg_name, const char* pkg_type, const char* app_path)
42 {
43     return perm_app_set_privilege(pkg_name, pkg_type, app_path);
44 }
45
46 #else
47
48 int AccessControl::setPriviledge(const char* pkg_name, const char* pkg_type, const char* app_path)
49 {
50     return 0;
51 }
52
53 #endif
54
55 int AccessControl::setWLDPrivilege(void)
56 {
57     WrtLogD("setAccessForWLD");
58
59     // get app group info
60     FILE* fp = NULL;
61     if(!(fp = fopen(APP_GROUP_PATH, "r"))) {
62         WrtLogE("fopen failed.");
63         return -1;
64     }
65
66     int cnt = 0;
67     gid_t* glist = NULL;
68     char buf[10] = {0, };
69     while(fgets(buf, 10, fp) != NULL) {
70         errno = 0;
71         gid_t temp = strtoul(buf, 0, 10);
72         if(errno != 0) {
73             WrtLogE("Cannot change string to integer: %s", buf);
74             goto error;
75         }
76
77         glist = (gid_t*)realloc(glist, sizeof(gid_t) * (cnt + 1));
78         if(!glist) {
79             WrtLogE("Cannot allocate memory");
80             goto error;
81         }
82         glist[cnt] = temp;
83         cnt++;
84     }
85     fclose(fp);
86     fp = NULL;
87
88     // setgroups()
89     if(setgroups(cnt, glist) != 0) {
90         WrtLogE("setgroups failed");
91         goto error;
92     }
93     if(glist != NULL) {
94         free(glist);
95         glist = NULL;
96     }
97
98     // setuid() & setgid()
99     if(setgid(APP_GID) != 0) {
100         WrtLogE("Failed to execute setgid().");
101         goto error;
102     }
103     if(setuid(APP_UID) != 0) {
104         WrtLogE("Failed to execute setuid().");
105         goto error;
106     }
107
108     // setenv()
109     if(setenv("USER", APP_USER_NAME, 1) != 0) {
110         WrtLogE("Failed to execute setenv() USER");
111         goto error;
112     }
113     if(setenv("HOME", APP_HOME_DIR, 1) != 0) {
114         WrtLogE("Failed to execute setenv() HOME");
115         goto error;
116     }
117
118     return 0;
119
120 error:
121     if(fp != NULL) {
122         fclose(fp);
123     }
124     if(glist != NULL) {
125         free(glist);
126     }
127
128     return -1;
129 }
130
131 int AccessControl::setWLDCapability(void)
132 {
133     cap_user_header_t header;
134     cap_user_data_t data;
135
136     header = static_cast<cap_user_header_t>(malloc(sizeof(*header)));
137     if (header == NULL) {
138         WrtLogE("memory allocation error");
139         return -1;
140     }
141
142     data = static_cast<cap_user_data_t>(calloc(sizeof(*data), _LINUX_CAPABILITY_U32S_3));
143     if (data == NULL) {
144         WrtLogE("memory allocation error");
145         free(header);
146         return -1;
147     }
148
149     header->pid = getpid();
150     header->version = _LINUX_CAPABILITY_VERSION_3;
151
152     // read already granted capabilities of this process
153     if (capget(header, data) < 0) {
154         WrtLogE("capget error");
155         free(header);
156         free(data);
157         return -1;
158     }
159
160     // set only inheritable bit for CAP_MAC_ADMIN to '1'
161     data[CAP_TO_INDEX(CAP_MAC_ADMIN)].inheritable |= CAP_TO_MASK(CAP_MAC_ADMIN);
162
163     // remove capabilities not needed any more
164     data[CAP_TO_INDEX(CAP_MAC_ADMIN)].permitted &= ~CAP_TO_MASK(CAP_MAC_ADMIN);
165     data[CAP_TO_INDEX(CAP_MAC_ADMIN)].effective &= ~CAP_TO_MASK(CAP_MAC_ADMIN);
166     data[CAP_TO_INDEX(CAP_SETPCAP)].permitted &= ~CAP_TO_MASK(CAP_SETPCAP);
167     data[CAP_TO_INDEX(CAP_SETPCAP)].effective &= ~CAP_TO_MASK(CAP_SETPCAP);
168
169     int ret = 0;
170     if (capset(header, data) < 0) {
171         WrtLogE("capset error");
172         ret = -1;
173     }
174
175     free(header);
176     free(data);
177
178     return ret;
179 }
180