wl_resource_set_implementation(resource, &tdm_implementation, data, destroy_client);
}
+static int
+_tdm_getgrnam_r(const char *name)
+{
+ struct group *grp = NULL;
+ struct group *grp_res = NULL;
+ char* buf = NULL;
+ size_t buf_len;
+ int ret;
+ int id;
+
+ buf_len = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (buf_len == -1)
+ buf_len = 2048;
+
+ buf = calloc(1, buf_len * sizeof(char));
+ if (!buf) {
+ TDM_ERR("creating buffer failed");
+ goto failed;
+ }
+
+ grp = calloc(1, sizeof(struct group));
+ if (!grp) {
+ TDM_ERR("creating group failed");
+ goto failed;
+ }
+
+ ret = getgrnam_r(name, grp, buf, buf_len, &grp_res);
+ if (ret < 0) {
+ TDM_ERR("getgrnam_r failed errno:%d(%m)", ret);
+ goto failed;
+ }
+
+ if (grp_res == NULL) {
+ TDM_ERR("finding name:%s group failed", name);
+ goto failed;
+ }
+
+ id = grp->gr_gid;
+ free(buf);
+ free(grp);
+
+ return id;
+
+failed:
+ if (buf)
+ free(buf);
+ if (grp)
+ free(grp);
+
+ return -1;
+}
+
+static int
+_tdm_socket_init(tdm_private_loop *private_loop)
+{
+ const char *dir = NULL;
+ char socket_path[128];
+ int ret = -1;
+ uid_t uid;
+ gid_t gid;
+
+ if (wl_display_add_socket(private_loop->wl_display, "tdm-socket")) {
+ TDM_ERR("createing a tdm-socket failed");
+ return 0;
+ }
+
+ dir = getenv("XDG_RUNTIME_DIR");
+ if (!dir) {
+ TDM_ERR("getting XDG_RUNTIME_DIR failed");
+ return 0;
+ }
+
+ snprintf(socket_path, sizeof(socket_path), "%s/%s", dir, "tdm-socket");
+
+ ret = chmod(socket_path, 509);
+ if (ret < 0) {
+ TDM_ERR("changing modes of socket file failed:%s (%m)", socket_path);
+ return 0;
+ }
+
+ ret = _tdm_getgrnam_r("root");
+ if (ret < 0) {
+ TDM_ERR("getting uid failed");
+ return 0;
+ }
+ uid = ret;
+
+ ret = _tdm_getgrnam_r("display");
+ if (ret < 0) {
+ TDM_ERR("getting gid failed");
+ return 0;
+ }
+ gid = ret;
+
+ ret = chown(socket_path, uid, gid);
+ if (ret < 0) {
+ TDM_ERR("changing owner of socket file failed:%s (%m)", socket_path);
+ return 0;
+ }
+
+ return 1;
+}
+
INTERN tdm_error
tdm_server_init(tdm_private_loop *private_loop)
{
if (private_loop->private_server)
return TDM_ERROR_NONE;
- if (wl_display_add_socket(private_loop->wl_display, "tdm-socket")) {
- TDM_ERR("createing a tdm-socket failed");
+ if (!_tdm_socket_init(private_loop)) {
+ TDM_ERR("initializing tdm-socket failed");
return TDM_ERROR_OPERATION_FAILED;
}