/*---------------------------------------------------------------------- Check to see if user is allowed to read or write this folder. Args: s -- the name to check Result: Returns 1 if OK Returns 0 and posts an error message if access is denied ----*/ int context_allowed(char *s) { struct variable *vars = ps_global ? ps_global->vars : NULL; int retval = 1; MAILSTREAM stream; /* fake stream for error message in mm_notify */ if(ps_global && ps_global->restricted && (strindex("./~", s[0]) || srchstr(s, "/../"))){ stream.mailbox = s; mm_notify(&stream, "Restricted mode doesn't allow operation", WARN); retval = 0; } else if(vars && VAR_OPER_DIR && s[0] != '{' && !(s[0] == '*' && s[1] == '{') && strucmp(s,ps_global->inbox_name) != 0 && strcmp(s, ps_global->VAR_INBOX_PATH) != 0){ char *p, *free_this = NULL; p = s; if(strindex(s, '~')){ p = strindex(s, '~'); free_this = (char *)fs_get(strlen(p) + 200); strncpy(free_this, p, strlen(p)+200); fnexpand(free_this, strlen(p)+200); p = free_this; } else if(p[0] != '/'){ /* add home dir to relative paths */ free_this = p = (char *)fs_get(strlen(s) + strlen(ps_global->home_dir) + 2); build_path(p, ps_global->home_dir, s, strlen(s)+strlen(ps_global->home_dir)+2); } if(!in_dir(VAR_OPER_DIR, p)){ char err[200]; /* TRANSLATORS: User is restricted to operating within a certain directory */ snprintf(err, sizeof(err), _("Not allowed outside of %.150s"), VAR_OPER_DIR); stream.mailbox = p; mm_notify(&stream, err, WARN); retval = 0; } else if(srchstr(p, "/../")){ /* check for .. in path */ stream.mailbox = p; mm_notify(&stream, "\"..\" not allowed in name", WARN); retval = 0; } if(free_this) fs_give((void **)&free_this); } return retval; }
/** * Does the config path uniquely apply to a file in the current directory? * @param it the item * @param p the directory path * @param fname the full config file path * @return */ int item_path_unique( item *it, char *p, char *fname ) { path *temp = it->paths; int plen = strlen(p); while ( temp != NULL ) { char *pt = path_get(temp); if ( in_dir(pt,p,plen) && fnames_equal(fname,pt) ) return 1; else temp = path_next(temp); } return 0; }
/* * Return the name of a file in the same directory as filename. * Same as temp_nam except it figures out a name in the same directory. * It also returns the name of the directory in ret_dir if ret_dir is * not NULL. That has to be freed by caller. If return is not NULL the * empty file has been created. */ char * tempfile_in_same_dir(char *filename, char *prefix, char **ret_dir) { #ifndef MAXPATH #define MAXPATH 1000 /* Longest file path we can deal with */ #endif char dir[MAXPATH+1]; char *dirp = NULL; char *ret_file = NULL; if(filename){ char *lc; if((lc = last_cmpnt(filename)) != NULL){ int to_copy; to_copy = (lc - filename > 1) ? (lc - filename - 1) : 1; strncpy(dir, filename, MIN(to_copy, sizeof(dir)-1)); dir[MIN(to_copy, sizeof(dir)-1)] = '\0'; } else{ dir[0] = '.'; dir[1] = '\0'; } dirp = dir; } /* temp_nam creates ret_file */ ret_file = temp_nam(dirp, prefix); /* * If temp_nam can't write in dirp it puts the file in a temp directory * anyway. We don't want that to happen to us. */ if(dirp && ret_file && !in_dir(dirp, ret_file)){ our_unlink(ret_file); fs_give((void **)&ret_file); /* sets it to NULL */ } if(ret_file && ret_dir && dirp) *ret_dir = cpystr(dirp); return(ret_file); }
/********************************************************************** * Function name: in_dir * Purpose: to search through directory entries * Function Inputs: directory name and flags * * Function Output: reports all appropriate errors * Version: 1.0 * Author: William Collins **********************************************************************/ void in_dir(char *dName, int bFlag, int hFlag, int sFlag, int rFlag) { struct dirent *dp; DIR *dirp; char path[100]; if (check_file(dName, bFlag, hFlag, sFlag) == D) { if ((dirp = opendir(dName)) == NULL) fprintf(stderr, "%s: could not open directory\n", dName); while ((dp = readdir(dirp)) != NULL) { strcpy(path, dName); strcat(path, "/"); strcat(path, dp->d_name); if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0 && check_file(path, bFlag, hFlag, sFlag) == D && rFlag == 1) { in_dir(path, bFlag, hFlag, sFlag, rFlag); } } } else fprintf(stderr, "%s: not a directory\n", dName); }
int main(int argc,char *argv[]) { register int m,n; register char *p; struct stat statx; int mode; uid_t effuid; gid_t effgid; NOT_USED(argc); arglist = argv; if((command = argv[1]) == 0) error_exit(badexec); ruserid = getuid(); euserid = geteuid(); rgroupid = getgid(); egroupid = getegid(); p = argv[0]; #ifndef _lib_setreuid maketemp(tmpname); if(strcmp(p,tmpname)==0) { /* At this point, the presumption is that we are the * version of THISPROG copied into /tmp, with the owner, * group, and setuid/gid bits correctly set. This copy of * the program is executable by anyone, so we must be careful * not to allow just any invocation of it to succeed, since * it is setuid/gid. Validate the proper execution by * examining the FDVERIFY file descriptor -- if it is owned * by root and is mode SPECIAL, then this is proof that it was * passed by a program with superuser privileges -- hence we * can presume legitimacy. Otherwise, bail out, as we suspect * an impostor. */ if(fstat(FDVERIFY,&statb) < 0 || statb.st_uid != 0 || (statb.st_mode & ~S_IFMT) != SPECIAL || close(FDVERIFY)<0) error_exit(badexec); /* This enables the grandchild to clean up /tmp file */ close(FDSYNC); /* Make sure that this is a valid invocation of the clone. * Perhaps unnecessary, given FDVERIFY, but what the heck... */ if(stat(tmpname,&statb) < 0 || statb.st_nlink != 1 || !S_ISREG(statb.st_mode)) error_exit(badexec); if(ruserid != euserid && ((statb.st_mode & S_ISUID) == 0 || statb.st_uid != euserid)) error_exit(badexec); goto exec; } /* Make sure that this is the real setuid program, not the clone. * It is possible by clever hacking to get past this point in the * clone, but it doesn't do the hacker any good that I can see. */ if(euserid) error_exit(badexec); #endif /* _lib_setreuid */ /* Open the script for reading first and then validate it. This * prevents someone from pulling a switcheroo while we are validating. */ n = open(p,0); if(n == FDIN) { n = dup(n); close(FDIN); } if(n < 0) error_exit(badopen); /* validate execution rights to this script */ if(fstat(FDIN,&statb) < 0 || (statb.st_mode & ~S_IFMT) != SPECIAL) euserid = ruserid; else euserid = statb.st_uid; /* do it the easy way if you can */ if(euserid == ruserid && egroupid == rgroupid) { if(access(p,X_OK) < 0) error_exit(badexec); } else { /* have to check access on each component */ while(*p++) { if(*p == '/' || *p == 0) { m = *p; *p = 0; if(eaccess(argv[0],X_OK) < 0) error_exit(badexec); *p = m; } } p = argv[0]; } if(fstat(n, &statb) < 0 || !S_ISREG(statb.st_mode)) error_exit(badopen); if(stat(p, &statx) < 0 || statb.st_ino != statx.st_ino || statb.st_dev != statx.st_dev) error_exit(badexec); if(stat(THISPROG, &statx) < 0 || (statb.st_ino == statx.st_ino && statb.st_dev == statx.st_dev)) error_exit(badexec); close(FDIN); if(fcntl(n,F_DUPFD,FDIN) != FDIN) error_exit(badexec); close(n); /* compute the desired new effective user and group id */ effuid = euserid; effgid = egroupid; mode = 0; if(statb.st_mode & S_ISUID) effuid = statb.st_uid; if(statb.st_mode & S_ISGID) effgid = statb.st_gid; /* see if group needs setting */ if(effgid != egroupid) if(effgid != rgroupid || setgid(rgroupid) < 0) mode = S_ISGID; /* now see if the uid needs setting */ if(mode) { if(effuid != ruserid) mode |= S_ISUID; } else if(effuid) { if(effuid != ruserid || setuid(ruserid) < 0) mode = S_ISUID; } if(mode) setids(mode, effuid, effgid); #ifndef _lib_setreuid exec: #endif /* _lib_setreuid */ /* only use SHELL if file is in trusted directory and ends in sh */ shell = getenv("SHELL"); if(shell == 0 || !endsh(shell) || ( !in_dir("/bin",shell) && !in_dir("/usr/bin",shell) && !in_dir("/usr/lbin",shell) && !in_dir("/usr/local/bin",shell))) shell = DEFSHELL; argv[0] = command; argv[1] = (char*)devfd; execv(shell,argv); error_exit(badexec); }
void network_generator::random_in_out_let(vector < pair <int, int> > &inlet, vector < pair <int, int> > &outlet){ vector <int> in_dir(inlet.size()), out_dir(inlet.size()); vector < vector <int> > valid(4, vector <int>(101)); for( int i=0;i<in_dir.size();i++ ){ in_dir[i] = rand()%4 + 1; out_dir[i] = rand()%4 + 1; } while(in_dir[1] == in_dir[0]){ in_dir[1] = in_dir[1]%4 + 1; } while(in_dir[2] == in_dir[0] || in_dir[2] == in_dir[1]){ in_dir[2] = in_dir[2]%4 + 1; } while(in_dir[3] == in_dir[0] || in_dir[3] == in_dir[1] || in_dir[3] == in_dir[2]){ in_dir[3] = in_dir[3]%4 + 1; } while(out_dir[1] == out_dir[0]){ out_dir[1] = out_dir[1]%4 + 1; } while(out_dir[2] == out_dir[0] || out_dir[2] == out_dir[1]){ out_dir[2] = out_dir[2]%4 + 1; } while(out_dir[3] == out_dir[0] || out_dir[3] == out_dir[1] || out_dir[3] == out_dir[2]){ out_dir[3] = out_dir[3]%4 + 1; } for( int i=0;i<in_dir.size();i++ ){ if(in_dir[i] == 1){ inlet[i].first = 100; inlet[i].second = rand()%80 + 10; while(valid[0][inlet[i].second] == 1 || inlet[i].second%2 == 0){ inlet[i].second = rand()%80 + 10; } valid[0][inlet[i].second] = 1; } else if(in_dir[i] == 2){ inlet[i].second = 0; inlet[i].first = rand()%80 + 10; while(valid[1][inlet[i].first] == 1 || inlet[i].first%2 == 0){ inlet[i].first = rand()%80 + 10; } valid[1][inlet[i].first] = 1; } else if(in_dir[i] == 3){ inlet[i].first = 0; inlet[i].second = rand()%80 + 10; while(valid[2][inlet[i].second] == 1 || inlet[i].second%2 == 0){ inlet[i].second = rand()%80 + 10; } valid[2][inlet[i].second] = 1; } else if(in_dir[i] == 4){ inlet[i].second = 100; inlet[i].first = rand()%80 + 10; while(valid[3][inlet[i].first] == 1 || inlet[i].first%2 == 0){ inlet[i].first = rand()%80 + 10; } valid[3][inlet[i].first] = 1; } if(out_dir[i] == 1){ outlet[i].first = 100; outlet[i].second = rand()%80 + 10; while(valid[0][outlet[i].second] == 1 || outlet[i].second%2 == 0){ outlet[i].second = rand()%80 + 10; } } else if(out_dir[i] == 2){ outlet[i].second = 0; outlet[i].first = rand()%80 + 10; while(valid[1][outlet[i].first] == 1 || outlet[i].first%2 == 0){ outlet[i].first = rand()%80 + 10; } } else if(out_dir[i] == 3){ outlet[i].first = 0; outlet[i].second = rand()%80 + 10; while(valid[2][outlet[i].second] == 1 || outlet[i].second%2 == 0){ outlet[i].second = rand()%80 + 10; } } else if(out_dir[i] == 4){ outlet[i].second = 100; outlet[i].first = rand()%80 + 10; while(valid[3][outlet[i].first] == 1 || outlet[i].first%2 == 0){ outlet[i].first = rand()%80 + 10; } } } }