Add the directory for system session and user session to share. 93/103693/3 submit/tizen_3.0/20161212.042035
authorwchang kim <wchang.kim@samsung.com>
Fri, 9 Dec 2016 07:02:55 +0000 (16:02 +0900)
committerwchang kim <wchang.kim@samsung.com>
Mon, 12 Dec 2016 04:13:44 +0000 (13:13 +0900)
Making the directory of /run/user_ext/<uid>.
Mounting tmpfs to it with smackfstransmute System::Run.
Unmounting directories which systemd_user_helper made when service is
stopped.

Change-Id: Ia749ba8ec291018c29216c65a0d47ee7ab385dbc
Signed-off-by: Woochang Kim <wchang.kim@samsung.com>
packaging/system-plugin.spec
packaging/systemd-user-helper.manifest
src/systemd-user-helper/systemd-user-helper.c

index fe80dd9..ec8a348 100644 (file)
@@ -320,9 +320,12 @@ mv %{_sysconfdir}/fstab_lazymnt %{_sysconfdir}/fstab
 %posttrans -n systemd-user-helper
 cp -a /usr/lib/systemd/system/user\@.service /usr/lib/systemd/system/__user@.service
 /usr/bin/sed -i -e 's/Type=\(.*\)/Type=forking/' /usr/lib/systemd/system/user\@.service
-/usr/bin/sed -i -e 's/ExecStart=\(.*\)/ExecStart=\/usr\/bin\/systemd_user_helper %i/' /usr/lib/systemd/system/user\@.service
+/usr/bin/sed -i -e 's/ExecStart=\(.*\)/ExecStart=\/usr\/bin\/systemd_user_helper start %i/' /usr/lib/systemd/system/user\@.service
+/usr/bin/sed -i -e '/ExecStart=\(.*\)/ a ExecStop=\/usr\/bin\/systemd_user_helper stop %i' /usr/lib/systemd/system/user\@.service
 /usr/bin/sed -i -e '/PIDFile=\(.*\)/d' /usr/lib/systemd/system/user\@.service
+/usr/bin/sed -i -e '/XDG_RUNTIME_DIR/ a Environment=XDG_RUNTIME_EXT_DIR=/run/user_ext/%i' /usr/lib/systemd/system/user\@.service
 echo 'PIDFile=/run/user/%i/.systemd.pid' >> /usr/lib/systemd/system/user\@.service
+echo "d /run/user_ext 0755 root root -" >> /usr/lib/tmpfiles.d/systemd.conf
 
 %files profile_ivi
 %{_prefix}/lib/udev/rules.d/99-usb-ethernet.rules
index 2a0cec5..bcde152 100644 (file)
@@ -2,4 +2,7 @@
   <request>
     <domain name="_"/>
   </request>
+  <assign>
+    <filesystem path="/usr/bin/systemd_user_helper" label="System::Privileged" exec_label="System::Privileged" />
+  </assign>
 </manifest>
index 6ffe977..a8145fa 100644 (file)
 
 #include <tzplatform_config.h>
 
+#include <sys/types.h>
+#include <grp.h>
+#include <string.h>
+
 #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
 #define PIDFILE_PATH ".systemd.pid"
 
                } \
        } while (0);
 
+#define MOUNT_SIZE  "10000k"
+#define MAX_GRP_BUF_SIZE (1024 * 4)
+#define GRP_NAME_SYSTEM_SHARE    "system_share"
+
 static void *container_handle = NULL;
 
 static const char *systemd_arg[] = {
@@ -57,9 +65,117 @@ static const char *systemd_arg[] = {
        NULL
 };
 
+int mac_smack_use(void) {
+        static int cached_use = -1;
+
+        if (cached_use < 0)
+                cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
+
+        return cached_use;
+}
+
+static int mount_user_ext(char *username)
+{
+       char *mount_point = NULL;
+       char *mount_option = NULL;
+       uid_t mnt_uid;
+       gid_t mnt_gid;
+       struct group *p_grp = NULL, grp_buf;
+       char buf[MAX_GRP_BUF_SIZE];
+       int r;
+
+       mnt_uid = atoi(username);
+       if(mnt_uid <= 0)
+               return -1;
+
+       r = asprintf(&mount_point, "/run/user_ext/%s", username);
+       if (r < 0) {
+               fprintf(stderr, "Failed to set mount point for user_ext\n");
+               return r;
+       }
+
+       (void) mkdir(mount_point, 0750);
+
+       r = getgrnam_r(GRP_NAME_SYSTEM_SHARE, &grp_buf, buf, sizeof(buf), &p_grp);
+       if( r == 0 && p_grp != NULL)
+       {
+               mnt_gid = p_grp->gr_gid;
+       }
+       else
+       {
+               free(mount_point);
+               return -2;
+       }
+
+       if (mac_smack_use())
+               r = asprintf(&mount_option, "mode=0750,smackfstransmute=System::Run,uid=%d,gid=%d,size=%s", mnt_uid, mnt_gid, MOUNT_SIZE);
+       else
+               r = asprintf(&mount_option, "mode=0750,uid=%d,gid=%d,size=%s", mnt_uid, mnt_gid, MOUNT_SIZE);
+
+       if (r < 0) {
+               fprintf(stderr, "Failed to set mount option for user_ext\n");
+               free(mount_point);
+               return r;
+       }
+
+       r = mount("tmpfs", mount_point, "tmpfs", MS_NODEV|MS_NOSUID|MS_NOEXEC, mount_option);
+       free(mount_point);
+       free(mount_option);
+
+       if (r < 0) {
+               fprintf(stderr, "Failed to mount user_ext\n");
+               return r;
+       }
+       return 0;
+}
+
+static int umount_user_ext(char *username)
+{
+       int r;
+       char *mount_point = NULL;
+
+       r = asprintf(&mount_point, "/run/user_ext/%s", username);
+       if (r < 0) {
+               fprintf(stderr, "Failed to set mount point for user_ext\n");
+               return r;
+       }
+       r = umount2(mount_point, MNT_DETACH);
+       if (r < 0) {
+               fprintf(stderr, "Failed to umount user_ext\n");
+               free(mount_point);
+               return r;
+       }
+       r = rmdir(mount_point);
+       if (r < 0) {
+               fprintf(stderr, "Failed to rmdir user_ext\n");
+               free(mount_point);
+               return r;
+       }
+       free(mount_point);
+       return 0;
+}
+
+static int stop_process(char *username)
+{
+       int r;
+
+       (void)umount_user_ext(username);
+       r = umount2(tzplatform_getenv(TZ_USER_CONTENT), MNT_DETACH);
+       if (r < 0) {
+               fprintf(stderr, "Warning : Failed to umount user content\n");
+       }
+
+       r = umount2(tzplatform_getenv(TZ_USER_APP), MNT_DETACH);
+       if (r < 0) {
+               fprintf(stderr, "Warning : Failed to umount application content\n");
+       }
+       return 0;
+}
+
 static int normal_user_preprocess(char *username)
 {
        int r;
+
        r = unshare(CLONE_NEWNS);
        if (r < 0) {
                fprintf(stderr, "unshare failed\n");
@@ -198,6 +314,30 @@ static int make_pid_file(int pid, char* user_id)
        return r;
 }
 
+static int change_smack_for_user_session()
+{
+       FILE *fp;
+       int r = 0;
+
+       fp = fopen("/proc/self/attr/current", "w");
+
+       if(fp == NULL)
+       {
+               r = -errno;
+               return r;
+       }
+       r = fputs("User", fp);
+       if(r == EOF)
+       {
+               fclose(fp);
+               r = -errno;
+               return r;
+       }
+       fclose(fp);
+
+       return 0;
+}
+
 int run_child(int argc, const char *argv[], char* user_id)
 {
        pid_t pid;
@@ -230,14 +370,38 @@ int main(int argc, char *argv[])
 {
        int r = 0;
        int support_container = 0;
+       char *operation;
+       char *username;
 
-       if (argc < 2) {
+       if (argc < 3) {
                fprintf(stderr, "require user argument\n");
                return -1;
        }
+       operation = argv[1];
+       username = argv[2];
+
+       if (strcmp(operation,"stop") == 0) {
+               return stop_process(username);
+       } else if (strcmp(operation, "start") == 0) {
+       } else {
+               fprintf(stderr, "option is invalid(%s)\n", operation);
+               return -2;
+       }
+
+       r = mount_user_ext(username);
+       if (r < 0) {
+               fprintf(stderr, "mount user_ext failed\n");
+               return r;
+       }
+       r = change_smack_for_user_session();
+       if(r != 0)
+       {
+               fprintf(stderr, "failed to change smack\n");
+               return r;
+       }
 
        /* pre-processing */
-       r = normal_user_preprocess(argv[1]);
+       r = normal_user_preprocess(username);
        if (r < 0) {
                fprintf(stderr, "normal user preprocess failed\n");
                return r;
@@ -246,14 +410,14 @@ int main(int argc, char *argv[])
        /* If container supports below funcs, below line should be enabled. */
        support_container = (access(CONTAINER_LIB, F_OK) == 0) ? 1 : 0;
        if (support_container) {
-               r = container_preprocess(argv[1]);
+               r = container_preprocess(username);
                if (r < 0) {
                        fprintf(stderr, "container preprocess failed\n");
                        return r;
                }
        }
 
-       r = run_child(ARRAY_SIZE(systemd_arg), systemd_arg, argv[1]);
+       r = run_child(ARRAY_SIZE(systemd_arg), systemd_arg, username);
        if (r < 0) {
                fprintf(stderr, "systemd user execution failed\n");
                return r;
@@ -265,14 +429,14 @@ int main(int argc, char *argv[])
        wait_condition();
 
        /* post-processing */
-       r = normal_user_postprocess(argv[1]);
+       r = normal_user_postprocess(username);
        if (r < 0) {
                fprintf(stderr, "normal user postprocess failed\n");
                return r;
        }
 
        if (support_container) {
-               r = container_postprocess(argv[1]);
+               r = container_postprocess(username);
                if (r < 0) {
                        fprintf(stderr, "container postprocess failed\n");
                        return r;