|
Blender
V2.59
|
00001 /* 00002 * $Id: blenderplayer-wrapper.c 36276 2011-04-21 15:53:30Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: none. 00024 * 00025 * Contributor(s): Enrico Fracasso 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 * wrapper used to run webplugin with lower privilage: it must be setuid root 00029 */ 00030 00031 00032 // Enabling O_NOFOLLOW 00033 #define _GNU_SOURCE 00034 00035 #include <stdio.h> 00036 #include <unistd.h> 00037 00038 #include <sys/types.h> 00039 #include <sys/stat.h> 00040 #include <fcntl.h> 00041 00042 #include <pwd.h> 00043 #include <stdlib.h> // exit 00044 #include <string.h> // memcpy 00045 00046 #include <signal.h> 00047 00048 // the blenderplayer id (used by sigterm_handler handler) 00049 pid_t blenderplayer_id = 0; 00050 00051 00052 00053 void print_id(){ 00054 00055 uid_t ruid, euid, suid; 00056 00057 getresuid(&ruid, &euid, &suid); 00058 printf("Real UID %d, Effective UID %d, Saved UID %d\n", ruid, euid, suid); 00059 00060 } 00061 00066 void sigterm_handler(int signum) { 00067 printf("Signal!!!\n"); 00068 if (blenderplayer_id != 0) { 00069 kill(blenderplayer_id, SIGKILL); 00070 printf("Signal sent!!!\n"); 00071 } 00072 00073 } 00074 00082 int main(int argc, char *argv[]) { 00083 00084 uid_t privid = geteuid(); 00085 uid_t caller_id = getuid(); 00086 00089 struct passwd *pw; 00090 pw = getpwnam("nobody"); // make it a param on a config file 00091 uid_t new_id = pw->pw_uid; 00092 00093 if (argc != 3) { 00094 fprintf(stderr, "I need two parameters on command line!\n"); 00095 exit(EXIT_FAILURE); 00096 } 00097 00098 /* If the caller is the owner of the file, chown to the privsep user */ 00099 const char* file_name = argv[1]; 00100 const char* window_id = argv[2]; 00101 fprintf(stderr, "File name: %s XID: %s\n", file_name, window_id); 00102 00103 struct stat stat_data; 00104 00105 int fd = open(file_name, O_NOFOLLOW); 00106 if (fd == -1 ) { 00107 perror("Cannot open file\n"); 00108 exit(EXIT_FAILURE); 00109 } 00110 00111 if (fstat(fd, &stat_data) != 0) { 00112 perror("Cannot read file\n"); 00113 exit(EXIT_FAILURE); 00114 } 00115 00116 if (stat_data.st_uid != caller_id) { 00117 printf("File not owned by the caller\n"); 00118 exit(EXIT_FAILURE); 00119 } 00120 00121 if (!S_ISREG(stat_data.st_mode)) { 00122 printf("File is not a regular file\n"); 00123 exit(EXIT_FAILURE); 00124 } 00125 00126 if (fchown(fd, new_id, -1) != 0 ){ 00127 perror("Cannot chown file\n"); 00128 exit(EXIT_FAILURE); 00129 } 00130 00131 if ( close(fd) != 0) { 00132 perror("Cannot close file\n"); 00133 exit(EXIT_FAILURE); 00134 } 00135 00136 00137 /* creating Xlib xauth file */ 00138 char template[] = "/tmp/blender-auth.XXXXXX"; 00139 /* We need a temp file name only; file will be created by xauth later */ 00140 char * auth_file_name = mktemp(template); 00141 00142 const char* display = getenv("DISPLAY"); 00143 if (display == NULL) { 00144 fprintf(stderr, "DISPLAY environment variable not found, aborting"); 00145 exit(EXIT_FAILURE); 00146 } 00147 00148 printf("Forking auth....\n"); 00149 pid_t id_auth = fork(); 00150 00151 if (id_auth == 0) { //child 00152 00153 /* I want to run xauth as caller user */ 00154 if (setuid(caller_id) != 0) { 00155 perror("Cannot drop privilages!\n"); 00156 exit(EXIT_FAILURE); 00157 } 00158 00159 00160 if (setuid(0) != -1) { 00161 perror("Privilages can be restored!\n"); 00162 exit(EXIT_FAILURE); 00163 } 00164 00165 print_id(); 00166 00167 int e = execlp ("xauth", "xauth", "-f", auth_file_name, "generate", display, ".", "trusted", (char*)NULL); 00168 perror("Error executing xauth!\n"); 00169 exit(EXIT_FAILURE); 00170 00171 } if (id_auth < 0 ) { //error 00172 perror("Cannot fork!\n"); 00173 exit(EXIT_FAILURE); 00174 00175 } else { // parent 00176 int status; 00177 fprintf(stderr, "Waiting for xauth....\n"); 00178 wait(&status); 00179 fprintf(stderr, "Done!\n"); 00180 } 00181 00182 /* xauth file must be readable by the privsep user */ 00183 if (chown(auth_file_name, new_id, -1) != 0 ){ 00184 perror("Cannot chown auth file\n"); 00185 exit(EXIT_FAILURE); 00186 } 00187 00188 signal(SIGTERM, sigterm_handler); 00189 print_id(); 00190 00191 blenderplayer_id = fork(); 00192 if (blenderplayer_id == 0 ) { //child 00193 00196 if (setuid(new_id) != 0) { 00197 perror("Cannot drop privilages!\n"); 00198 exit(EXIT_FAILURE); 00199 } 00200 00201 if (setuid(0) != -1) { 00202 perror("Privilages can be restored!\n"); 00203 exit(EXIT_FAILURE); 00204 } 00205 00206 print_id(); 00207 fprintf(stderr, "Privilages dropped successfully\n"); 00208 00209 setenv("XAUTHORITY", auth_file_name, 1); 00210 00211 const char* blenderplayer = "/usr/bin/blenderplayer"; 00212 execl(blenderplayer, "blenderplayer", "-i", window_id, file_name, (char*)NULL); 00213 } else { 00215 int status; 00216 fprintf(stderr, "Waiting for blenderplayer....\n"); 00217 wait(&status); 00218 fprintf(stderr, "blenderplayer done!\n"); 00219 00220 // We have to remove xauth file and I have to chown blender file back to the original user 00221 if (chown(file_name, caller_id, -1) != 0 ){ 00222 perror("Cannot chown file back to original user\n"); 00223 exit(EXIT_FAILURE); 00224 } 00225 00226 if (unlink(auth_file_name) != 0) { 00227 perror("Cannot remove xauth file!\n"); 00228 exit(EXIT_FAILURE); 00229 } 00230 00231 } 00232 00233 00234 } 00235