Beispiel #1
0
/*----------------------------------------------------------------------
    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;
}
Beispiel #2
0
/**
 * 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;
}
Beispiel #3
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);
}
Beispiel #4
0
/**********************************************************************
 * 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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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;
			}
		}
	}
}