/** * create_full_path: * @filename: a gchar * with the (relative or not) filename * @basedir: a gchar * with a basedir or NULL for current dir * * if filename is already absolute, it returns it * else it will use basedir if available, else the current dir * to add to the filename to form the full path * * for URL's it will simply return a strdup(), except for file:// URL's, * there the file:// bit is stripped and * IF YOU HAVE GNOME_VFS any %XX sequenves are converted * so if you DON'T have gnome_vfs, you should not feed file:// uri's!! * * it does use most_efficient_filename() to remote unwanted dir/../ entries * * Return value: a newly allocated gchar * with the full path **/ gchar *create_full_path(const gchar * filename, const gchar *basedir) { gchar *absolute_filename; gchar *tmpcdir; if (!filename) return NULL; DEBUG_MSG("create_full_path, filename=%s, basedir=%s\n", filename, basedir); #ifdef STRIP_FILE_URI if (strchr(filename, ':') != NULL) { /* it is an URI!! */ DEBUG_MSG("create_full_path, %s is an URI\n",filename); if (strncmp(filename, "file://", 7)==0) { #ifdef HAVE_GNOME_VFS return gnome_vfs_get_local_path_from_uri(filename); #else /* THIS IS A BUG, IF YOU DON'T HAVE GNOME_VFS BUT YOU DO HAVE GTK-2.4 A %21 OR SOMETHING LIKE THAT IS NOW NOT CONVERTED !!!!!!!!! */ #ifdef WIN32 return g_strdup(bf_strrepl(filename+7,"%20"," ")); #endif return g_strdup(filename+7); /* file:// URI's are never relative paths */ #endif } #ifdef WIN32 return g_strdup(bf_strrepl(filename,"%20"," ")); #endif return g_strdup(filename); /* cannot do this on remote paths */ } #endif /* HAVE_GNOME_VFS */ if (g_path_is_absolute(filename)) { absolute_filename = g_strdup(filename); } else { if (basedir) { tmpcdir = ending_slash(basedir); } else { gchar *curdir = g_get_current_dir(); tmpcdir = ending_slash(curdir); g_free(curdir); } absolute_filename = g_strconcat(tmpcdir, filename, NULL); g_free(tmpcdir); } absolute_filename = most_efficient_filename(absolute_filename); #ifdef WIN32 return g_strdup(bf_strrepl(absolute_filename,"%20"," ")); #endif return absolute_filename; }
gchar *create_full_path(gchar const * filename, gchar *basedir) { gchar *absolute_filename; gchar *tmpcdir; if (g_path_is_absolute(filename)) { absolute_filename = g_strdup(filename); } else { if (basedir) { tmpcdir = ending_slash(basedir); } else { gchar *curdir = g_get_current_dir(); tmpcdir = ending_slash(curdir); g_free(curdir); } absolute_filename = g_strconcat(tmpcdir, filename, NULL); g_free(tmpcdir); } absolute_filename = most_efficient_filename(absolute_filename); return absolute_filename; }
int basicjailissafe(const char *path) { char *tmp, *path_w_slash; int retval = 1; if (path && testsafepath(path, 0, 0) !=0) { return 0; } path_w_slash = ending_slash(path); tmp = malloc0(strlen(path_w_slash)+6); if (retval == 1 && (testsafepath(strcat(strcpy(tmp,path_w_slash), "dev/"), 0, 0) &~TESTPATH_NOREGPATH)!=0) retval = 0; if (retval == 1 && (testsafepath(strcat(strcpy(tmp,path_w_slash), "etc/"), 0, 0) &~TESTPATH_NOREGPATH)!=0) retval = 0; if (retval == 1 && (testsafepath(strcat(strcpy(tmp,path_w_slash), "lib/"), 0, 0) &~TESTPATH_NOREGPATH)!=0) retval = 0; if (retval == 1 && (testsafepath(strcat(strcpy(tmp,path_w_slash), "usr/"), 0, 0) &~TESTPATH_NOREGPATH)!=0) retval = 0; if (retval == 1 && (testsafepath(strcat(strcpy(tmp,path_w_slash), "bin/"), 0, 0) &~TESTPATH_NOREGPATH)!=0) retval = 0; if (retval == 1 && (testsafepath(strcat(strcpy(tmp,path_w_slash), "sbin/"), 0, 0)&~TESTPATH_NOREGPATH)!=0) retval = 0; free(tmp); free(path_w_slash); DEBUG_MSG("basicjailissafe, returning %d\n",retval); return retval; }
int main (int argc, char **argv) { char *pidfile=NULL, *jail=NULL, *exec=NULL; int uid=-1,gid=-1; unsigned int i; char **newargv; openlog(PROGRAMNAME, LOG_PID, LOG_DAEMON); { int c=0; char *tuser=NULL, *tgroup=NULL, *texec=NULL; while (c != -1) { int option_index = 0; static struct option long_options[] = { {"pidfile", required_argument, NULL, 'p'}, {"jail", required_argument, NULL, 'j'}, {"exec", required_argument, NULL, 'x'}, {"user", required_argument, NULL, 'u'}, {"group", required_argument, NULL, 'g'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, {NULL, 0, NULL, 0} }; c = getopt_long(argc, argv, "j:p:u:g:x:hv",long_options, &option_index); switch (c) { case 'j': jail = ending_slash(optarg); break; case 'p': pidfile = strdup(optarg); break; case 'u': tuser = strdup(optarg); break; case 'g': tgroup = strdup(optarg); break; case 'x': texec = strdup(optarg); break; case 'h': case 'V': print_usage(); exit(1); } } uid = parse_uid(tuser); gid = parse_gid(tgroup); exec = test_jail_and_exec(jail,texec); /* construct the new argv from all leftover options */ newargv = malloc0((2 + argc - optind)*sizeof(char *)); newargv[0] = exec; c = 1; while (optind < argc) { newargv[c] = strdup(argv[optind]); c++; optind++; } free(tuser); free(tgroup); free(texec); } if (pidfile) { FILE *pidfilefd = fopen(pidfile, "w"); int pid = getpid(); if (pidfilefd && fprintf(pidfilefd, "%d",pid)>=0) { fclose(pidfilefd); } else { syslog(LOG_NOTICE, "failed to write PID into %s", pidfile); } } /* open file descriptors can be used to break out of a chroot, so we close all of them, except for stdin,stdout and stderr */ #ifdef OPEN_MAX i = OPEN_MAX; #elif defined(NOFILE) i = NOFILE; #else i = getdtablesize(); #endif while (--i > 2) { while (close(i) != 0 && errno == EINTR); } if (chdir(jail)) { syslog(LOG_ERR, "abort, could not change directory chdir() to the jail %s: %s", jail,strerror(errno)); exit(33); } if (chroot(jail)) { syslog(LOG_ERR, "abort, could not change root chroot() to the jail %s: %s", jail,strerror(errno)); exit(35); } if (gid != -1 && setgid(gid)<0) { syslog(LOG_ERR, "abort, could not setgid %d: %s", gid,strerror(errno)); exit(37); } if (uid != -1 && setuid(uid)<0) { syslog(LOG_ERR, "abort, could not setuid %d: %s", uid,strerror(errno)); exit(39); } syslog(LOG_NOTICE,"executing %s in jail %s",exec,jail); execv(exec, newargv); syslog(LOG_ERR, "error: failed to execute %s in jail %s: %s",exec,jail,strerror(errno)); exit(31); }