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