示例#1
0
// whitelist for /home/user directory
void fs_whitelist(void) {
    char *homedir = cfg.homedir;
    assert(homedir);
    ProfileEntry *entry = cfg.profile;
    if (!entry)
        return;

    char *new_name = NULL;
    int home_dir = 0;	// /home/user directory flag
    int tmp_dir = 0;	// /tmp directory flag
    int media_dir = 0;	// /media directory flag
    int mnt_dir = 0;	// /mnt directory flag
    int var_dir = 0;		// /var directory flag
    int dev_dir = 0;		// /dev directory flag
    int opt_dir = 0;		// /opt directory flag
    int srv_dir = 0;                // /srv directory flag
    // verify whitelist files, extract symbolic links, etc.
    while (entry) {
        // handle only whitelist commands
        if (strncmp(entry->data, "whitelist ", 10)) {
            entry = entry->next;
            continue;
        }

        // resolve ${DOWNLOADS}
        if (strcmp(entry->data + 10, "${DOWNLOADS}") == 0) {
            char *tmp = resolve_downloads();
            if (tmp)
                entry->data = tmp;
            else {
                *entry->data = '\0';
                fprintf(stderr, "***\n");
                fprintf(stderr, "*** Warning: cannot whitelist Downloads directory\n");
                fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n");
                fprintf(stderr, "*** \tPlease create a proper Downloads directory for your application.\n");
                fprintf(stderr, "***\n");
                continue;
            }
        }

        // replace ~/ or ${HOME} into /home/username
//		if (new_name)
//			free(new_name);
        new_name = expand_home(entry->data + 10, cfg.homedir);
        assert(new_name);
        if (arg_debug)
            fprintf(stderr, "Debug %d: new_name #%s#\n", __LINE__, new_name);

        // valid path referenced to filesystem root
        if (*new_name != '/') {
            if (arg_debug)
                fprintf(stderr, "Debug %d: \n", __LINE__);
            goto errexit;
        }


        // extract the absolute path of the file
        // realpath function will fail with ENOENT if the file is not found
        char *fname = realpath(new_name, NULL);
        if (!fname) {
            // file not found, blank the entry in the list and continue
            if (arg_debug || arg_debug_whitelists) {
                printf("Removed whitelist path: %s\n", entry->data);
                printf("\texpanded: %s\n", new_name);
                printf("\treal path: (null)\n");
                printf("\t");
                fflush(0);
                perror("realpath");
            }
            *entry->data = '\0';

            // if 1 the file was not found; mount an empty directory
            if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) {
                if(!arg_private)
                    home_dir = 1;
            }
            else if (strncmp(new_name, "/tmp/", 5) == 0)
                tmp_dir = 1;
            else if (strncmp(new_name, "/media/", 7) == 0)
                media_dir = 1;
            else if (strncmp(new_name, "/mnt/", 5) == 0)
                mnt_dir = 1;
            else if (strncmp(new_name, "/var/", 5) == 0)
                var_dir = 1;
            else if (strncmp(new_name, "/dev/", 5) == 0)
                dev_dir = 1;
            else if (strncmp(new_name, "/opt/", 5) == 0)
                opt_dir = 1;
            else if (strncmp(new_name, "/srv/", 5) == 0)
                opt_dir = 1;

            continue;
        }

        // check for supported directories
        if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) {
            // whitelisting home directory is disabled if --private option is present
            if (arg_private) {
                if (arg_debug || arg_debug_whitelists)
                    printf("Removed whitelist path %s, --private option is present\n", entry->data);

                *entry->data = '\0';
                continue;
            }

            entry->home_dir = 1;
            home_dir = 1;
            if (arg_debug || arg_debug_whitelists)
                fprintf(stderr, "Debug %d: fname #%s#, cfg.homedir #%s#\n",
                        __LINE__, fname, cfg.homedir);

            // both path and absolute path are under /home
            if (strncmp(fname, cfg.homedir, strlen(cfg.homedir)) != 0) {
                // check if the file is owned by the user
                struct stat s;
                if (stat(fname, &s) == 0 && s.st_uid != getuid())
                    goto errexit;
            }
        }
        else if (strncmp(new_name, "/tmp/", 5) == 0) {
            entry->tmp_dir = 1;
            tmp_dir = 1;
            // both path and absolute path are under /tmp
            if (strncmp(fname, "/tmp/", 5) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/media/", 7) == 0) {
            entry->media_dir = 1;
            media_dir = 1;
            // both path and absolute path are under /media
            if (strncmp(fname, "/media/", 7) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/mnt/", 5) == 0) {
            entry->mnt_dir = 1;
            mnt_dir = 1;
            // both path and absolute path are under /mnt
            if (strncmp(fname, "/mnt/", 5) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/var/", 5) == 0) {
            entry->var_dir = 1;
            var_dir = 1;
            // both path and absolute path are under /var
            // exceptions: /var/run and /var/lock
            if (strcmp(new_name, "/var/run")== 0)
                ;
            else if (strcmp(new_name, "/var/lock")== 0)
                ;
            else if (strncmp(fname, "/var/", 5) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/dev/", 5) == 0) {
            entry->dev_dir = 1;
            dev_dir = 1;
            // both path and absolute path are under /dev
            if (strncmp(fname, "/dev/", 5) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/opt/", 5) == 0) {
            entry->opt_dir = 1;
            opt_dir = 1;
            // both path and absolute path are under /dev
            if (strncmp(fname, "/opt/", 5) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/srv/", 5) == 0) {
            entry->srv_dir = 1;
            srv_dir = 1;
            // both path and absolute path are under /srv
            if (strncmp(fname, "/srv/", 5) != 0) {
                goto errexit;
            }
        }
        else {
            goto errexit;
        }

        // mark symbolic links
        if (is_link(new_name))
            entry->link = new_name;
        else {
            free(new_name);
            new_name = NULL;
        }

        // change file name in entry->data
        if (strcmp(fname, entry->data + 10) != 0) {
            char *newdata;
            if (asprintf(&newdata, "whitelist %s", fname) == -1)
                errExit("asprintf");
            entry->data = newdata;
            if (arg_debug || arg_debug_whitelists)
                printf("Replaced whitelist path: %s\n", entry->data);
        }
        free(fname);
        entry = entry->next;
    }

    // /home/user
    if (home_dir) {
        // keep a copy of real home dir in RUN_WHITELIST_HOME_USER_DIR
        mkdir_attr(RUN_WHITELIST_HOME_USER_DIR, 0755, getuid(), getgid());
        if (mount(cfg.homedir, RUN_WHITELIST_HOME_USER_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
            errExit("mount bind");

        // mount a tmpfs and initialize /home/user
        fs_private();
    }

    // /tmp mountpoint
    if (tmp_dir) {
        // keep a copy of real /tmp directory in
        mkdir_attr(RUN_WHITELIST_TMP_DIR, 1777, 0, 0);
        if (mount("/tmp", RUN_WHITELIST_TMP_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
            errExit("mount bind");

        // mount tmpfs on /tmp
        if (arg_debug || arg_debug_whitelists)
            printf("Mounting tmpfs on /tmp directory\n");
        if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=1777,gid=0") < 0)
            errExit("mounting tmpfs on /tmp");
        fs_logger("tmpfs /tmp");
    }

    // /media mountpoint
    if (media_dir) {
        // some distros don't have a /media directory
        struct stat s;
        if (stat("/media", &s) == 0) {
            // keep a copy of real /media directory in RUN_WHITELIST_MEDIA_DIR
            mkdir_attr(RUN_WHITELIST_MEDIA_DIR, 0755, 0, 0);
            if (mount("/media", RUN_WHITELIST_MEDIA_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
                errExit("mount bind");

            // mount tmpfs on /media
            if (arg_debug || arg_debug_whitelists)
                printf("Mounting tmpfs on /media directory\n");
            if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
                errExit("mounting tmpfs on /media");
            fs_logger("tmpfs /media");
        }
        else
            media_dir = 0;
    }

    // /mnt mountpoint
    if (mnt_dir) {
        // check if /mnt directory exists
        struct stat s;
        if (stat("/mnt", &s) == 0) {
            // keep a copy of real /mnt directory in RUN_WHITELIST_MNT_DIR
            mkdir_attr(RUN_WHITELIST_MNT_DIR, 0755, 0, 0);
            if (mount("/mnt", RUN_WHITELIST_MNT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
                errExit("mount bind");

            // mount tmpfs on /mnt
            if (arg_debug || arg_debug_whitelists)
                printf("Mounting tmpfs on /mnt directory\n");
            if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
                errExit("mounting tmpfs on /mnt");
            fs_logger("tmpfs /mnt");
        }
        else
            mnt_dir = 0;
    }


    // /var mountpoint
    if (var_dir) {
        // keep a copy of real /var directory in RUN_WHITELIST_VAR_DIR
        mkdir_attr(RUN_WHITELIST_VAR_DIR, 0755, 0, 0);
        if (mount("/var", RUN_WHITELIST_VAR_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
            errExit("mount bind");

        // mount tmpfs on /var
        if (arg_debug || arg_debug_whitelists)
            printf("Mounting tmpfs on /var directory\n");
        if (mount("tmpfs", "/var", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mounting tmpfs on /var");
        fs_logger("tmpfs /var");
    }

    // /dev mountpoint
    if (dev_dir) {
        // keep a copy of real /dev directory in RUN_WHITELIST_DEV_DIR
        mkdir_attr(RUN_WHITELIST_DEV_DIR, 0755, 0, 0);
        if (mount("/dev", RUN_WHITELIST_DEV_DIR, NULL, MS_BIND|MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount bind");

        // mount tmpfs on /dev
        if (arg_debug || arg_debug_whitelists)
            printf("Mounting tmpfs on /dev directory\n");
        if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mounting tmpfs on /dev");
        fs_logger("tmpfs /dev");
    }

    // /opt mountpoint
    if (opt_dir) {
        // keep a copy of real /opt directory in RUN_WHITELIST_OPT_DIR
        mkdir_attr(RUN_WHITELIST_OPT_DIR, 0755, 0, 0);
        if (mount("/opt", RUN_WHITELIST_OPT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
            errExit("mount bind");

        // mount tmpfs on /opt
        if (arg_debug || arg_debug_whitelists)
            printf("Mounting tmpfs on /opt directory\n");
        if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mounting tmpfs on /opt");
        fs_logger("tmpfs /opt");
    }

    // /srv mountpoint
    if (srv_dir) {
        // check if /srv directory exists
        struct stat s;
        if (stat("/srv", &s) == 0) {
            // keep a copy of real /srv directory in RUN_WHITELIST_SRV_DIR
            mkdir_attr(RUN_WHITELIST_SRV_DIR, 0755, 0, 0);
            if (mount("/srv", RUN_WHITELIST_SRV_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
                errExit("mount bind");

            // mount tmpfs on /srv
            if (arg_debug || arg_debug_whitelists)
                printf("Mounting tmpfs on /srv directory\n");
            if (mount("tmpfs", "/srv", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
                errExit("mounting tmpfs on /srv");
            fs_logger("tmpfs /srv");
        }
        else
            srv_dir = 0;
    }



    // go through profile rules again, and interpret whitelist commands
    entry = cfg.profile;
    while (entry) {
        // handle only whitelist commands
        if (strncmp(entry->data, "whitelist ", 10)) {
            entry = entry->next;
            continue;
        }

//printf("here %d#%s#\n", __LINE__, entry->data);
        // whitelist the real file
        if (strcmp(entry->data, "whitelist /run") == 0 &&
                (strcmp(entry->link, "/var/run") == 0 || strcmp(entry->link, "/var/lock") == 0)) {
            int rv = symlink(entry->data + 10, entry->link);
            if (rv)
                fprintf(stderr, "Warning cannot create symbolic link %s\n", entry->link);
            else if (arg_debug || arg_debug_whitelists)
                printf("Created symbolic link %s -> %s\n", entry->link, entry->data + 10);
        }
        else {
            whitelist_path(entry);

            // create the link if any
            if (entry->link) {
                // if the link is already there, do not bother
                struct stat s;
                if (stat(entry->link, &s) != 0) {
                    // create the path if necessary
                    mkpath(entry->link, s.st_mode);

                    int rv = symlink(entry->data + 10, entry->link);
                    if (rv)
                        fprintf(stderr, "Warning cannot create symbolic link %s\n", entry->link);
                    else if (arg_debug || arg_debug_whitelists)
                        printf("Created symbolic link %s -> %s\n", entry->link, entry->data + 10);
                }
            }
        }

        entry = entry->next;
    }

    // mask the real home directory, currently mounted on RUN_WHITELIST_HOME_DIR
    if (home_dir) {
        if (mount("tmpfs", RUN_WHITELIST_HOME_USER_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_HOME_USER_DIR);
    }

    // mask the real /tmp directory, currently mounted on RUN_WHITELIST_TMP_DIR
    if (tmp_dir) {
        if (mount("tmpfs", RUN_WHITELIST_TMP_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_TMP_DIR);
    }

    // mask the real /var directory, currently mounted on RUN_WHITELIST_VAR_DIR
    if (var_dir) {
        if (mount("tmpfs", RUN_WHITELIST_VAR_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_VAR_DIR);
    }

    // mask the real /opt directory, currently mounted on RUN_WHITELIST_OPT_DIR
    if (opt_dir) {
        if (mount("tmpfs", RUN_WHITELIST_OPT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_OPT_DIR);
    }

    // mask the real /dev directory, currently mounted on RUN_WHITELIST_DEV_DIR
    if (dev_dir) {
        if (mount("tmpfs", RUN_WHITELIST_DEV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_DEV_DIR);
    }

    // mask the real /media directory, currently mounted on RUN_WHITELIST_MEDIA_DIR
    if (media_dir) {
        if (mount("tmpfs", RUN_WHITELIST_MEDIA_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_MEDIA_DIR);
    }

    // mask the real /mnt directory, currently mounted on RUN_WHITELIST_MNT_DIR
    if (mnt_dir) {
        if (mount("tmpfs", RUN_WHITELIST_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_MNT_DIR);
    }

    // mask the real /srv directory, currently mounted on RUN_WHITELIST_SRV_DIR
    if (srv_dir) {
        if (mount("tmpfs", RUN_WHITELIST_SRV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_SRV_DIR);
    }

    if (new_name)
        free(new_name);

    return;

errexit:
    fprintf(stderr, "Error: invalid whitelist path %s\n", new_name);
    exit(1);
}
示例#2
0
extern int task_cgroup_cpuset_create(slurmd_job_t *job)
{
	int rc;
	int fstatus = SLURM_ERROR;

	xcgroup_t cpuset_cg;

	uint32_t jobid = job->jobid;
	uint32_t stepid = job->stepid;
	uid_t uid = job->uid;
	uid_t gid = job->gid;
	char* user_alloc_cores = NULL;
	char* job_alloc_cores = NULL;
	char* step_alloc_cores = NULL;

	char* cpus = NULL;
	size_t cpus_size;

	/* build user cgroup relative path if not set (should not be) */
	if (*user_cgroup_path == '\0') {
		if (snprintf(user_cgroup_path,PATH_MAX,
			      "/uid_%u",uid) >= PATH_MAX) {
			error("task/cgroup: unable to build uid %u cpuset "
			      "cg relative path : %m",uid);
			return SLURM_ERROR;
		}
	}

	/* build job cgroup relative path if no set (should not be) */
	if (*job_cgroup_path == '\0') {
		if (snprintf(job_cgroup_path,PATH_MAX,"%s/job_%u",
			      user_cgroup_path,jobid) >= PATH_MAX) {
			error("task/cgroup: unable to build job %u cpuset "
			      "cg relative path : %m",jobid);
			return SLURM_ERROR;
		}
	}

	/* build job step cgroup relative path (should not be) */
	if (*jobstep_cgroup_path == '\0') {
		if (stepid == NO_VAL) {
			if (snprintf(jobstep_cgroup_path, PATH_MAX,
				     "%s/step_batch", job_cgroup_path)
			    >= PATH_MAX) {
				error("task/cgroup: unable to build job step"
				      " %u.batch cpuset cg relative path: %m",
				      jobid);
				return SLURM_ERROR;
			}
		} else {
			if (snprintf(jobstep_cgroup_path, PATH_MAX, "%s/step_%u",
				     job_cgroup_path, stepid) >= PATH_MAX) {
				error("task/cgroup: unable to build job step"
				      " %u.%u cpuset cg relative path: %m",
				      jobid, stepid);
				return SLURM_ERROR;
			}
		}
	}

	/*
	 * create cpuset root cg and lock it
	 *
	 * we will keep the lock until the end to avoid the effect of a release
	 * agent that would remove an existing cgroup hierarchy while we are
	 * setting it up. As soon as the step cgroup is created, we can release
	 * the lock.
	 * Indeed, consecutive slurm steps could result in cg being removed
	 * between the next EEXIST instanciation and the first addition of
	 * a task. The release_agent will have to lock the root cpuset cgroup
	 * to avoid this scenario.
	 */
	if (xcgroup_create(&cpuset_ns,&cpuset_cg,"",0,0) != XCGROUP_SUCCESS) {
		error("task/cgroup: unable to create root cpuset xcgroup");
		return SLURM_ERROR;
	}
	if (xcgroup_lock(&cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&cpuset_cg);
		error("task/cgroup: unable to lock root cpuset cg");
		return SLURM_ERROR;
	}

	/*
	 * build job and job steps allocated cores lists
	 */
	debug("task/cgroup: job abstract cores are '%s'",
	      job->job_alloc_cores);
	debug("task/cgroup: step abstract cores are '%s'",
	      job->step_alloc_cores);
	if (xcpuinfo_abs_to_mac(job->job_alloc_cores,
				 &job_alloc_cores) != XCPUINFO_SUCCESS) {
		error("task/cgroup: unable to build job physical cores");
		goto error;
	}
	if (xcpuinfo_abs_to_mac(job->step_alloc_cores,
				 &step_alloc_cores) != XCPUINFO_SUCCESS) {
		error("task/cgroup: unable to build step physical cores");
		goto error;
	}
	debug("task/cgroup: job physical cores are '%s'",
	      job->job_alloc_cores);
	debug("task/cgroup: step physical cores are '%s'",
	      job->step_alloc_cores);

	/*
	 * create user cgroup in the cpuset ns (it could already exist)
	 */
	if (xcgroup_create(&cpuset_ns,&user_cpuset_cg,
			    user_cgroup_path,
			    getuid(),getgid()) != XCGROUP_SUCCESS) {
		goto error;
	}
	if (xcgroup_instanciate(&user_cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		goto error;
	}

	/*
	 * check that user's cpuset cgroup is consistant and add the job cores
	 */
	rc = xcgroup_get_param(&user_cpuset_cg,"cpuset.cpus",&cpus,&cpus_size);
	if (rc != XCGROUP_SUCCESS || cpus_size == 1) {
		/* initialize the cpusets as it was inexistant */
		if (_xcgroup_cpuset_init(&user_cpuset_cg) !=
		     XCGROUP_SUCCESS) {
			xcgroup_delete(&user_cpuset_cg);
			xcgroup_destroy(&user_cpuset_cg);
			goto error;
		}
	}
	user_alloc_cores = xstrdup(job_alloc_cores);
	if (cpus != NULL && cpus_size > 1) {
		cpus[cpus_size-1]='\0';
		xstrcat(user_alloc_cores,",");
		xstrcat(user_alloc_cores,cpus);
	}
	xcgroup_set_param(&user_cpuset_cg,"cpuset.cpus",user_alloc_cores);
	xfree(cpus);

	/*
	 * create job cgroup in the cpuset ns (it could already exist)
	 */
	if (xcgroup_create(&cpuset_ns,&job_cpuset_cg,
			    job_cgroup_path,
			    getuid(),getgid()) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		goto error;
	}
	if (xcgroup_instanciate(&job_cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		xcgroup_destroy(&job_cpuset_cg);
		goto error;
	}
	if (_xcgroup_cpuset_init(&job_cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		xcgroup_destroy(&job_cpuset_cg);
		goto error;
	}
	xcgroup_set_param(&job_cpuset_cg,"cpuset.cpus",job_alloc_cores);

	/*
	 * create step cgroup in the cpuset ns (it should not exists)
	 * use job's user uid/gid to enable tasks cgroups creation by
	 * the user inside the step cgroup owned by root
	 */
	if (xcgroup_create(&cpuset_ns,&step_cpuset_cg,
			    jobstep_cgroup_path,
			    uid,gid) != XCGROUP_SUCCESS) {
		/* do not delete user/job cgroup as */
		/* they can exist for other steps */
		xcgroup_destroy(&user_cpuset_cg);
		xcgroup_destroy(&job_cpuset_cg);
		goto error;
	}
	if (xcgroup_instanciate(&step_cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		xcgroup_destroy(&job_cpuset_cg);
		xcgroup_destroy(&step_cpuset_cg);
		goto error;
	}
	if (_xcgroup_cpuset_init(&step_cpuset_cg) != XCGROUP_SUCCESS) {
		xcgroup_destroy(&user_cpuset_cg);
		xcgroup_destroy(&job_cpuset_cg);
		xcgroup_delete(&step_cpuset_cg);
		xcgroup_destroy(&step_cpuset_cg);
		goto error;
	}
	xcgroup_set_param(&step_cpuset_cg,"cpuset.cpus",step_alloc_cores);

	/* attach the slurmstepd to the step cpuset cgroup */
	pid_t pid = getpid();
	rc = xcgroup_add_pids(&step_cpuset_cg,&pid,1);
	if (rc != XCGROUP_SUCCESS) {
		error("task/cgroup: unable to add slurmstepd to cpuset cg '%s'",
		      step_cpuset_cg.path);
		fstatus = SLURM_ERROR;
	} else
		fstatus = SLURM_SUCCESS;

error:
	xcgroup_unlock(&cpuset_cg);
	xcgroup_destroy(&cpuset_cg);

	xfree(user_alloc_cores);
	xfree(job_alloc_cores);
	xfree(step_alloc_cores);

	return fstatus;
}
示例#3
0
void uwsgi_detach_daemons() {
	struct uwsgi_daemon *ud = uwsgi.daemons;
	while (ud) {
#ifdef UWSGI_SSL
		// stop any legion daemon, doesn't matter if dumb or smart
		if (ud->pid > 0 && (ud->legion || !ud->pidfile)) {
#else
		// stop only dumb daemons
		if (ud->pid > 0 && !ud->pidfile) {
#endif
			uwsgi_log("[uwsgi-daemons] stopping daemon (pid: %d): %s\n", (int) ud->pid, ud->command);
			// try to stop daemon gracefully, kill it if it won't die
			// if mercy is not set then wait up to 3 seconds
			time_t timeout = uwsgi_now() + (uwsgi.reload_mercy ? uwsgi.reload_mercy : 3);
			int waitpid_status;
			while (!kill(ud->pid, 0)) {
				kill(-(ud->pid), ud->stop_signal);
				sleep(1);
				waitpid(ud->pid, &waitpid_status, WNOHANG);
				if (uwsgi_now() >= timeout) {
					uwsgi_log("[uwsgi-daemons] daemon did not die in time, killing (pid: %d): %s\n", (int) ud->pid, ud->command);
					kill(-(ud->pid), SIGKILL);
					break;
				}
			}
			// unregister daemon to prevent it from being respawned
			ud->registered = 0;
		}
		ud = ud->next;
	}
}

static int daemon_spawn(void *);

void uwsgi_spawn_daemon(struct uwsgi_daemon *ud) {

	// skip unregistered daemons
	if (!ud->registered) return;

	ud->throttle = 0;

	if (uwsgi.current_time - ud->last_spawn <= 3) {
		ud->throttle = ud->respawns - (uwsgi.current_time - ud->last_spawn);
		// if ud->respawns == 0 then we can end up with throttle < 0
		if (ud->throttle <= 0) ud->throttle = 1;
	}

	pid_t pid = uwsgi_fork("uWSGI external daemon");
	if (pid < 0) {
		uwsgi_error("fork()");
		return;
	}

	if (pid > 0) {
		ud->has_daemonized = 0;
		ud->pid = pid;
		ud->status = 1;
		ud->pidfile_checks = 0;
		if (ud->respawns == 0) {
			ud->born = uwsgi_now();
		}

		ud->respawns++;
		ud->last_spawn = uwsgi_now();

	}
	else {
		// close uwsgi sockets
		uwsgi_close_all_sockets();
		uwsgi_close_all_fds();

#if defined(__linux__) && !defined(OBSOLETE_LINUX_KERNEL) && defined(CLONE_NEWPID)
		if (ud->ns_pid) {
			// we need to create a new session
			if (setsid() < 0) {
				uwsgi_error("setsid()");
				exit(1);
			}
			// avoid the need to set stop_signal in attach-daemon2
			signal(SIGTERM, end_me);

			char stack[PTHREAD_STACK_MIN];
                	pid_t pid = clone((int (*)(void *))daemon_spawn, stack + PTHREAD_STACK_MIN, SIGCHLD | CLONE_NEWPID, (void *) ud);
                        if (pid > 0) {

#ifdef PR_SET_PDEATHSIG
				if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
                                	uwsgi_error("uwsgi_spawn_daemon()/prctl()");
                        	}
#endif
                                // block all signals except SIGTERM
                                sigset_t smask;
                                sigfillset(&smask);
				sigdelset(&smask, SIGTERM);
                                sigprocmask(SIG_BLOCK, &smask, NULL);
                                int status;
                                if (waitpid(pid, &status, 0) < 0) {
                                        uwsgi_error("uwsgi_spawn_daemon()/waitpid()");
                                }
                                _exit(0);
                        }
			uwsgi_error("uwsgi_spawn_daemon()/clone()");
                        exit(1);
		}
#endif
		daemon_spawn((void *) ud);

	}
}


static int daemon_spawn(void *arg) {

	struct uwsgi_daemon *ud = (struct uwsgi_daemon *) arg;

		if (ud->gid) {
			if (setgid(ud->gid)) {
				uwsgi_error("uwsgi_spawn_daemon()/setgid()");
				exit(1);
			}
		}

		if (ud->uid) {
			if (setuid(ud->uid)) {
				uwsgi_error("uwsgi_spawn_daemon()/setuid()");
				exit(1);
			}
		}

		if (ud->daemonize) {
			/* refork... */
			pid_t pid = fork();
			if (pid < 0) {
				uwsgi_error("fork()");
				exit(1);
			}
			if (pid != 0) {
				_exit(0);
			}
			uwsgi_write_pidfile(ud->pidfile);
		}

		if (!uwsgi.daemons_honour_stdin && !ud->honour_stdin) {
			// /dev/null will became stdin
			uwsgi_remap_fd(0, "/dev/null");
		}

		if (setsid() < 0) {
			uwsgi_error("setsid()");
			exit(1);
		}

		if (!ud->pidfile) {
#ifdef PR_SET_PDEATHSIG
			if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
				uwsgi_error("prctl()");
			}
#endif
		}


		if (ud->throttle) {
			uwsgi_log("[uwsgi-daemons] throttling \"%s\" for %d seconds\n", ud->command, ud->throttle);
			sleep((unsigned int) ud->throttle);
		}

		uwsgi_log("[uwsgi-daemons] %sspawning \"%s\" (uid: %d gid: %d)\n", ud->respawns > 0 ? "re" : "", ud->command, (int) getuid(), (int) getgid());
		uwsgi_exec_command_with_args(ud->command);
		uwsgi_log("[uwsgi-daemons] unable to spawn \"%s\"\n", ud->command);

		// never here;
		exit(1);
}


void uwsgi_opt_add_daemon(char *opt, char *value, void *none) {

	struct uwsgi_daemon *uwsgi_ud = uwsgi.daemons, *old_ud;
	char *pidfile = NULL;
	int daemonize = 0;
	int freq = 10;
	char *space = NULL;
	int stop_signal = SIGTERM;
	int reload_signal = 0;

	char *command = uwsgi_str(value);

#ifdef UWSGI_SSL
	char *legion = NULL;
	if (!uwsgi_starts_with(opt, strlen(command), "legion-", 7)) {
		space = strchr(command, ' ');
		if (!space) {
			uwsgi_log("invalid legion daemon syntax: %s\n", command);
			exit(1);
		}
		*space = 0;
		legion = command;
		command = space+1;
	}
#endif

	if (!strcmp(opt, "smart-attach-daemon") || !strcmp(opt, "smart-attach-daemon2") || !strcmp(opt, "legion-smart-attach-daemon") || !strcmp(opt, "legion-smart-attach-daemon2")) {
		space = strchr(command, ' ');
		if (!space) {
			uwsgi_log("invalid smart-attach-daemon syntax: %s\n", command);
			exit(1);
		}
		*space = 0;
		pidfile = command;
		// check for freq
		char *comma = strchr(pidfile, ',');
		if (comma) {
			*comma = 0;
			freq = atoi(comma + 1);
		}
		command = space + 1;
		if (!strcmp(opt, "smart-attach-daemon2") || !strcmp(opt, "legion-smart-attach-daemon2")) {
			daemonize = 1;
		}
	}

	if (!uwsgi_ud) {
		uwsgi.daemons = uwsgi_calloc(sizeof(struct uwsgi_daemon));
		uwsgi_ud = uwsgi.daemons;
	}
	else {
		while (uwsgi_ud) {
			old_ud = uwsgi_ud;
			uwsgi_ud = uwsgi_ud->next;
		}

		uwsgi_ud = uwsgi_calloc(sizeof(struct uwsgi_daemon));
		old_ud->next = uwsgi_ud;
	}

	uwsgi_ud->command = command;
	uwsgi_ud->pid = 0;
	uwsgi_ud->status = 0;
	uwsgi_ud->freq = freq;
	uwsgi_ud->registered = 0;
	uwsgi_ud->next = NULL;
	uwsgi_ud->respawns = 0;
	uwsgi_ud->last_spawn = 0;
	uwsgi_ud->daemonize = daemonize;
	uwsgi_ud->pidfile = pidfile;
	uwsgi_ud->control = 0;
	uwsgi_ud->stop_signal = stop_signal;
	uwsgi_ud->reload_signal = reload_signal;
	if (!strcmp(opt, "attach-control-daemon")) {
		uwsgi_ud->control = 1;
	}
#ifdef UWSGI_SSL
	uwsgi_ud->legion = legion;
#endif

	uwsgi.daemons_cnt++;

}

void uwsgi_opt_add_daemon2(char *opt, char *value, void *none) {

        struct uwsgi_daemon *uwsgi_ud = uwsgi.daemons, *old_ud;

	char *d_command = NULL;
	char *d_freq = NULL;
	char *d_pidfile = NULL;
	char *d_control = NULL;
	char *d_legion = NULL;
	char *d_daemonize = NULL;
	char *d_touch = NULL;
	char *d_stopsignal = NULL;
	char *d_reloadsignal = NULL;
	char *d_stdin = NULL;
	char *d_uid = NULL;
	char *d_gid = NULL;
	char *d_ns_pid = NULL;

	char *arg = uwsgi_str(value);

	if (uwsgi_kvlist_parse(arg, strlen(arg), ',', '=',
		"command", &d_command,	
		"cmd", &d_command,	
		"exec", &d_command,	
		"freq", &d_freq,	
		"pidfile", &d_pidfile,	
		"control", &d_control,	
		"daemonize", &d_daemonize,	
		"daemon", &d_daemonize,	
		"touch", &d_touch,	
		"stopsignal", &d_stopsignal,	
		"stop_signal", &d_stopsignal,	
		"reloadsignal", &d_reloadsignal,	
		"reload_signal", &d_reloadsignal,	
		"stdin", &d_stdin,	
		"uid", &d_uid,	
		"gid", &d_gid,	
		"ns_pid", &d_ns_pid,	
	NULL)) {
		uwsgi_log("invalid --%s keyval syntax\n", opt);
		exit(1);
	}

	if (!d_command) {
		uwsgi_log("--%s: you need to specify a 'command' key\n", opt);
		exit(1);
	}

#ifndef UWSGI_SSL
	if (d_legion) {
		uwsgi_log("legion subsystem is not supported on this uWSGI version, rebuild with ssl support\n");
		exit(1);
	}
#endif



        if (!uwsgi_ud) {
                uwsgi.daemons = uwsgi_calloc(sizeof(struct uwsgi_daemon));
                uwsgi_ud = uwsgi.daemons;
        }
        else {
                while (uwsgi_ud) {
                        old_ud = uwsgi_ud;
                        uwsgi_ud = uwsgi_ud->next;
                }

                uwsgi_ud = uwsgi_calloc(sizeof(struct uwsgi_daemon));
                old_ud->next = uwsgi_ud;
        }
        uwsgi_ud->command = d_command;
        uwsgi_ud->freq = d_freq ? atoi(d_freq) : 10;
        uwsgi_ud->daemonize = d_daemonize ? 1 : 0;
        uwsgi_ud->pidfile = d_pidfile;
        uwsgi_ud->stop_signal = d_stopsignal ? atoi(d_stopsignal) : SIGTERM;
        uwsgi_ud->reload_signal = d_reloadsignal ? atoi(d_reloadsignal) : 0;
        uwsgi_ud->control = d_control ? 1 : 0;
	uwsgi_ud->uid = d_uid ? atoi(d_uid) : 0;
	uwsgi_ud->gid = d_gid ? atoi(d_gid) : 0;
	uwsgi_ud->honour_stdin = d_stdin ? 1 : 0;
#ifdef UWSGI_SSL
        uwsgi_ud->legion = d_legion;
#endif
        uwsgi_ud->ns_pid = d_ns_pid ? 1 : 0;

	if (d_touch) {
		size_t i,rlen = 0;
		char **argv = uwsgi_split_quoted(d_touch, strlen(d_touch), ";", &rlen);
		for(i=0;i<rlen;i++) {	
			uwsgi_string_new_list(&uwsgi_ud->touch, argv[i]);
		}
		if (argv) free(argv);
	}

        uwsgi.daemons_cnt++;

	free(arg);

}
示例#4
0
int
main(int argc, char **argv)
{
  int i;
  sigset_t set;
#if ENABLE_MPEGTS
  uint32_t adapter_mask = 0;
#endif
  int  log_level   = LOG_INFO;
  int  log_options = TVHLOG_OPT_MILLIS | TVHLOG_OPT_STDERR | TVHLOG_OPT_SYSLOG;
  const char *log_debug = NULL, *log_trace = NULL;
  char buf[512];

  main_tid = pthread_self();

  /* Setup global mutexes */
  pthread_mutex_init(&ffmpeg_lock, NULL);
  pthread_mutex_init(&fork_lock, NULL);
  pthread_mutex_init(&global_lock, NULL);
  pthread_mutex_init(&atomic_lock, NULL);
  pthread_cond_init(&gtimer_cond, NULL);

  /* Defaults */
  tvheadend_webui_port      = 9981;
  tvheadend_webroot         = NULL;
  tvheadend_htsp_port       = 9982;
  tvheadend_htsp_port_extra = 0;

  /* Command line options */
  int         opt_help         = 0,
              opt_version      = 0,
              opt_fork         = 0,
              opt_firstrun     = 0,
              opt_stderr       = 0,
              opt_syslog       = 0,
              opt_uidebug      = 0,
              opt_abort        = 0,
              opt_noacl        = 0,
              opt_fileline     = 0,
              opt_threadid     = 0,
              opt_ipv6         = 0,
              opt_tsfile_tuner = 0,
              opt_dump         = 0,
              opt_xspf         = 0;
  const char *opt_config       = NULL,
             *opt_user         = NULL,
             *opt_group        = NULL,
             *opt_logpath      = NULL,
             *opt_log_debug    = NULL,
             *opt_log_trace    = NULL,
             *opt_pidpath      = "/var/run/tvheadend.pid",
#if ENABLE_LINUXDVB
             *opt_dvb_adapters = NULL,
#endif
             *opt_bindaddr     = NULL,
             *opt_subscribe    = NULL,
             *opt_user_agent   = NULL;
  str_list_t  opt_satip_xml    = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) };
  str_list_t  opt_tsfile       = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) };
  cmdline_opt_t cmdline_opts[] = {
    {   0, NULL,        "Generic Options",         OPT_BOOL, NULL         },
    { 'h', "help",      "Show this page",          OPT_BOOL, &opt_help    },
    { 'v', "version",   "Show version infomation", OPT_BOOL, &opt_version },

    {   0, NULL,        "Service Configuration",   OPT_BOOL, NULL         },
    { 'c', "config",    "Alternate config path",   OPT_STR,  &opt_config  },
    { 'f', "fork",      "Fork and run as daemon",  OPT_BOOL, &opt_fork    },
    { 'u', "user",      "Run as user",             OPT_STR,  &opt_user    },
    { 'g', "group",     "Run as group",            OPT_STR,  &opt_group   },
    { 'p', "pid",       "Alternate pid path",      OPT_STR,  &opt_pidpath },
    { 'C', "firstrun",  "If no user account exists then create one with\n"
	                      "no username and no password. Use with care as\n"
	                      "it will allow world-wide administrative access\n"
	                      "to your Tvheadend installation until you edit\n"
	                      "the access-control from within the Tvheadend UI",
      OPT_BOOL, &opt_firstrun },
#if ENABLE_LINUXDVB
    { 'a', "adapters",  "Only use specified DVB adapters (comma separated)",
      OPT_STR, &opt_dvb_adapters },
#endif
#if ENABLE_SATIP_CLIENT
    {   0, "satip_xml", "URL with the SAT>IP server XML location",
      OPT_STR_LIST, &opt_satip_xml },
#endif
    {   0, NULL,         "Server Connectivity",    OPT_BOOL, NULL         },
    { '6', "ipv6",       "Listen on IPv6",         OPT_BOOL, &opt_ipv6    },
    { 'b', "bindaddr",   "Specify bind address",   OPT_STR,  &opt_bindaddr},
    {   0, "http_port",  "Specify alternative http port",
      OPT_INT, &tvheadend_webui_port },
    {   0, "http_root",  "Specify alternative http webroot",
      OPT_STR, &tvheadend_webroot },
    {   0, "htsp_port",  "Specify alternative htsp port",
      OPT_INT, &tvheadend_htsp_port },
    {   0, "htsp_port2", "Specify extra htsp port",
      OPT_INT, &tvheadend_htsp_port_extra },
    {   0, "useragent",  "Specify User-Agent header for the http client",
      OPT_STR, &opt_user_agent },
    {   0, "xspf",       "Use xspf playlist instead M3U",
      OPT_BOOL, &opt_xspf },

    {   0, NULL,        "Debug Options",           OPT_BOOL, NULL         },
    { 'd', "stderr",    "Enable debug on stderr",  OPT_BOOL, &opt_stderr  },
    { 's', "syslog",    "Enable debug to syslog",  OPT_BOOL, &opt_syslog  },
    { 'l', "logfile",   "Enable debug to file",    OPT_STR,  &opt_logpath },
    {   0, "debug",     "Enable debug subsystems", OPT_STR,  &opt_log_debug },
#if ENABLE_TRACE
    {   0, "trace",     "Enable trace subsystems", OPT_STR,  &opt_log_trace },
#endif
    {   0, "fileline",  "Add file and line numbers to debug", OPT_BOOL, &opt_fileline },
    {   0, "threadid",  "Add the thread ID to debug", OPT_BOOL, &opt_threadid },
    {   0, "uidebug",   "Enable webUI debug (non-minified JS)", OPT_BOOL, &opt_uidebug },
    { 'A', "abort",     "Immediately abort",       OPT_BOOL, &opt_abort   },
    { 'D', "dump",      "Enable coredumps for daemon", OPT_BOOL, &opt_dump },
    {   0, "noacl",     "Disable all access control checks",
      OPT_BOOL, &opt_noacl },
    { 'j', "join",      "Subscribe to a service permanently",
      OPT_STR, &opt_subscribe },


    { 0, NULL, "TODO: testing", OPT_BOOL, NULL },
    { 0, "tsfile_tuners", "Number of tsfile tuners", OPT_INT, &opt_tsfile_tuner },
    { 0, "tsfile", "tsfile input (mux file)", OPT_STR_LIST, &opt_tsfile },

  };

  /* Get current directory */
  tvheadend_cwd = dirname(dirname(tvh_strdupa(argv[0])));

  /* Set locale */
  setlocale(LC_ALL, "");
  setlocale(LC_NUMERIC, "C");

  /* make sure the timezone is set */
  tzset();

  /* Process command line */
  for (i = 1; i < argc; i++) {

    /* Find option */
    cmdline_opt_t *opt
      = cmdline_opt_find(cmdline_opts, ARRAY_SIZE(cmdline_opts), argv[i]);
    if (!opt)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 "invalid option specified [%s]", argv[i]);

    /* Process */
    if (opt->type == OPT_BOOL)
      *((int*)opt->param) = 1;
    else if (++i == argc)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 "option %s requires a value", opt->lopt);
    else if (opt->type == OPT_INT)
      *((int*)opt->param) = atoi(argv[i]);
    else if (opt->type == OPT_STR_LIST) {
      str_list_t *strl = opt->param;
      if (strl->num < strl->max)
        strl->str[strl->num++] = argv[i];
    }
    else
      *((char**)opt->param) = argv[i];

    /* Stop processing */
    if (opt_help)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), NULL);
    if (opt_version)
      show_version(argv[0]);
  }

  /* Additional cmdline processing */
#if ENABLE_LINUXDVB
  if (!opt_dvb_adapters) {
    adapter_mask = ~0;
  } else {
    char *p, *e;
    char *r = NULL;
    char *dvb_adapters = strdup(opt_dvb_adapters);
    adapter_mask = 0x0;
    p = strtok_r(dvb_adapters, ",", &r);
    while (p) {
      int a = strtol(p, &e, 10);
      if (*e != 0 || a < 0 || a > 31) {
        tvhlog(LOG_ERR, "START", "Invalid adapter number '%s'", p);
        free(dvb_adapters);
        return 1;
      }
      adapter_mask |= (1 << a);
      p = strtok_r(NULL, ",", &r);
    }
    free(dvb_adapters);
    if (!adapter_mask) {
      tvhlog(LOG_ERR, "START", "No adapters specified!");
      return 1;
    }
  }
#endif
  if (tvheadend_webroot) {
    char *tmp;
    if (*tvheadend_webroot == '/')
      tmp = strdup(tvheadend_webroot);
    else {
      tmp = malloc(strlen(tvheadend_webroot)+2);
      *tmp = '/';
      strcpy(tmp+1, tvheadend_webroot);
    }
    if (tmp[strlen(tmp)-1] == '/')
      tmp[strlen(tmp)-1] = '\0';
    tvheadend_webroot = tmp;
  }
  tvheadend_webui_debug = opt_uidebug;

  /* Setup logging */
  if (isatty(2))
    log_options |= TVHLOG_OPT_DECORATE;
  if (opt_stderr || opt_syslog || opt_logpath) {
    if (!opt_log_trace && !opt_log_debug)
      log_debug      = "all";
    log_level      = LOG_DEBUG;
    if (opt_stderr)
      log_options   |= TVHLOG_OPT_DBG_STDERR;
    if (opt_syslog)
      log_options   |= TVHLOG_OPT_DBG_SYSLOG;
    if (opt_logpath)
      log_options   |= TVHLOG_OPT_DBG_FILE;
  }
  if (opt_fileline)
    log_options |= TVHLOG_OPT_FILELINE;
  if (opt_threadid)
    log_options |= TVHLOG_OPT_THREAD;
  if (opt_log_trace) {
    log_level  = LOG_TRACE;
    log_trace  = opt_log_trace;
  }
  if (opt_log_debug)
    log_debug  = opt_log_debug;
    
  tvhlog_init(log_level, log_options, opt_logpath);
  tvhlog_set_debug(log_debug);
  tvhlog_set_trace(log_trace);
 
  signal(SIGPIPE, handle_sigpipe); // will be redundant later

  /* Daemonise */
  if(opt_fork) {
    const char *homedir;
    gid_t gid;
    uid_t uid;
    struct group  *grp = getgrnam(opt_group ?: "video");
    struct passwd *pw  = opt_user ? getpwnam(opt_user) : NULL;
    FILE   *pidfile    = fopen(opt_pidpath, "w+");

    if(grp != NULL) {
      gid = grp->gr_gid;
    } else {
      gid = 1;
    }

    if (pw != NULL) {
      if (getuid() != pw->pw_uid) {
        gid_t glist[10];
        int gnum;
        gnum = get_user_groups(pw, glist, 10);
        if (setgroups(gnum, glist)) {
          tvhlog(LOG_ALERT, "START",
                 "setgroups() failed, do you have permission?");
          return 1;
        }
      }
      uid     = pw->pw_uid;
      homedir = pw->pw_dir;
      setenv("HOME", homedir, 1);
    } else {
      uid = 1;
    }
    if ((getgid() != gid) && setgid(gid)) {
      tvhlog(LOG_ALERT, "START",
             "setgid() failed, do you have permission?");
      return 1;
    }
    if ((getuid() != uid) && setuid(uid)) {
      tvhlog(LOG_ALERT, "START",
             "setuid() failed, do you have permission?");
      return 1;
    }

    if(daemon(0, 0)) {
      exit(2);
    }
    if(pidfile != NULL) {
      fprintf(pidfile, "%d\n", getpid());
      fclose(pidfile);
    }

    /* Make dumpable */
    if (opt_dump) {
#ifdef PLATFORM_LINUX
      if (chdir("/tmp"))
        tvhwarn("START", "failed to change cwd to /tmp");
      prctl(PR_SET_DUMPABLE, 1);
#else
      tvhwarn("START", "Coredumps not implemented on your platform");
#endif
    }

    umask(0);
  }

  tvheadend_running = 1;

  /* Start log thread (must be done post fork) */
  tvhlog_start();

  /* Alter logging */
  if (opt_fork)
    tvhlog_options &= ~TVHLOG_OPT_STDERR;
  if (!isatty(2))
    tvhlog_options &= ~TVHLOG_OPT_DECORATE;
  
  /* Initialise clock */
  pthread_mutex_lock(&global_lock);
  time(&dispatch_clock);

  /* Signal handling */
  sigfillset(&set);
  sigprocmask(SIG_BLOCK, &set, NULL);
  trap_init(argv[0]);

  /* SSL library init */
  OPENSSL_config(NULL);
  SSL_load_error_strings();
  SSL_library_init();
  
  /* Initialise configuration */
  uuid_init();
  idnode_init();
  config_init(opt_config);

  /**
   * Initialize subsystems
   */

  intlconv_init();
  
  api_init();

  fsmonitor_init();

#if ENABLE_LIBAV
  libav_init();
  transcoding_init();
#endif

  imagecache_init();

  http_client_init(opt_user_agent);
  esfilter_init();

  service_init();

#if ENABLE_MPEGTS
  mpegts_init(adapter_mask, &opt_satip_xml, &opt_tsfile, opt_tsfile_tuner);
#endif

  channel_init();

  subscription_init();

  access_init(opt_firstrun, opt_noacl);

#if ENABLE_TIMESHIFT
  timeshift_init();
#endif

  tcp_server_init(opt_ipv6);
  http_server_init(opt_bindaddr);
  webui_init(opt_xspf);
#if ENABLE_UPNP
  upnp_server_init(opt_bindaddr);
#endif

  service_mapper_init();

  descrambler_init();

  epggrab_init();
  epg_init();

  dvr_init();

  htsp_init(opt_bindaddr);


  if(opt_subscribe != NULL)
    subscription_dummy_join(opt_subscribe, 1);

  avahi_init();
  bonjour_init();

  epg_updated(); // cleanup now all prev ref's should have been created

  pthread_mutex_unlock(&global_lock);

  /**
   * Wait for SIGTERM / SIGINT, but only in this thread
   */

  sigemptyset(&set);
  sigaddset(&set, SIGTERM);
  sigaddset(&set, SIGINT);

  signal(SIGTERM, doexit);
  signal(SIGINT, doexit);

  pthread_sigmask(SIG_UNBLOCK, &set, NULL);

  tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, "
         "running as PID:%d UID:%d GID:%d, CWD:%s CNF:%s",
         tvheadend_version,
         getpid(), getuid(), getgid(), getcwd(buf, sizeof(buf)),
         hts_settings_get_root());

  if(opt_abort)
    abort();

  mainloop();

#if ENABLE_UPNP
  tvhftrace("main", upnp_server_done);
#endif
  tvhftrace("main", htsp_done);
  tvhftrace("main", http_server_done);
  tvhftrace("main", webui_done);
  tvhftrace("main", fsmonitor_done);
#if ENABLE_MPEGTS
  tvhftrace("main", mpegts_done);
#endif
  tvhftrace("main", http_client_done);

  // Note: the locking is obviously a bit redundant, but without
  //       we need to disable the gtimer_arm call in epg_save()
  pthread_mutex_lock(&global_lock);
  tvhftrace("main", epg_save);

#if ENABLE_TIMESHIFT
  tvhftrace("main", timeshift_term);
#endif
  pthread_mutex_unlock(&global_lock);

  tvhftrace("main", epggrab_done);
  tvhftrace("main", tcp_server_done);
  tvhftrace("main", descrambler_done);
  tvhftrace("main", service_mapper_done);
  tvhftrace("main", service_done);
  tvhftrace("main", channel_done);
  tvhftrace("main", dvr_done);
  tvhftrace("main", subscription_done);
  tvhftrace("main", access_done);
  tvhftrace("main", epg_done);
  tvhftrace("main", avahi_done);
  tvhftrace("main", bonjour_done);
  tvhftrace("main", imagecache_done);
  tvhftrace("main", idnode_done);
  tvhftrace("main", lang_code_done);
  tvhftrace("main", api_done);
  tvhftrace("main", config_done);
  tvhftrace("main", hts_settings_done);
  tvhftrace("main", dvb_done);
  tvhftrace("main", lang_str_done);
  tvhftrace("main", esfilter_done);
  tvhftrace("main", intlconv_done);
  tvhftrace("main", urlparse_done);

  tvhlog(LOG_NOTICE, "STOP", "Exiting HTS Tvheadend");
  tvhlog_end();

  if(opt_fork)
    unlink(opt_pidpath);
    
  free(opt_tsfile.str);
  free(opt_satip_xml.str);

  /* OpenSSL - welcome to the "cleanup" hell */
  ENGINE_cleanup();
  RAND_cleanup();
  CRYPTO_cleanup_all_ex_data();
  EVP_cleanup();
  CONF_modules_free();
  COMP_zlib_cleanup();
  ERR_remove_state(0);
  ERR_free_strings();
  {
    sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
  }
  /* end of OpenSSL cleanup code */

  return 0;
}

/**
 *
 */
void
tvh_str_set(char **strp, const char *src)
{
  free(*strp);
  *strp = src ? strdup(src) : NULL;
}


/**
 *
 */
int
tvh_str_update(char **strp, const char *src)
{
  if(src == NULL)
    return 0;
  free(*strp);
  *strp = strdup(src);
  return 1;
}


/**
 *
 */
void
scopedunlock(pthread_mutex_t **mtxp)
{
  pthread_mutex_unlock(*mtxp);
}
示例#5
0
int
main(int argc, char *argv[])
{
    struct protox *tp = NULL;  /* for printing cblocks & stats */
    int ch;
    int fib = -1;
    char *endptr;

    af = AF_UNSPEC;

    while ((ch = getopt(argc, argv, "46AaBbdF:f:ghI:iLlM:mN:np:Qq:rSTsuWw:xz"))
            != -1)
        switch(ch) {
        case '4':
#ifdef INET
            af = AF_INET;
#else
            errx(1, "IPv4 support is not compiled in");
#endif
            break;
        case '6':
#ifdef INET6
            af = AF_INET6;
#else
            errx(1, "IPv6 support is not compiled in");
#endif
            break;
        case 'A':
            Aflag = 1;
            break;
        case 'a':
            aflag = 1;
            break;
        case 'B':
            Bflag = 1;
            break;
        case 'b':
            bflag = 1;
            break;
        case 'd':
            dflag = 1;
            break;
        case 'F':
            fib = strtol(optarg, &endptr, 0);
            if (*endptr != '\0' ||
                    (fib == 0 && (errno == EINVAL || errno == ERANGE)))
                errx(1, "%s: invalid fib", optarg);
            break;
        case 'f':
            if (strcmp(optarg, "ipx") == 0)
                af = AF_IPX;
            else if (strcmp(optarg, "inet") == 0)
                af = AF_INET;
#ifdef INET6
            else if (strcmp(optarg, "inet6") == 0)
                af = AF_INET6;
#endif
#ifdef IPSEC
            else if (strcmp(optarg, "pfkey") == 0)
                af = PF_KEY;
#endif
            else if (strcmp(optarg, "unix") == 0)
                af = AF_UNIX;
            else if (strcmp(optarg, "atalk") == 0)
                af = AF_APPLETALK;
#ifdef NETGRAPH
            else if (strcmp(optarg, "ng") == 0
                     || strcmp(optarg, "netgraph") == 0)
                af = AF_NETGRAPH;
#endif
            else if (strcmp(optarg, "link") == 0)
                af = AF_LINK;
            else {
                errx(1, "%s: unknown address family", optarg);
            }
            break;
        case 'g':
            gflag = 1;
            break;
        case 'h':
            hflag = 1;
            break;
        case 'I': {
            char *cp;

            iflag = 1;
            for (cp = interface = optarg; isalpha(*cp); cp++)
                continue;
            unit = atoi(cp);
            break;
        }
        case 'i':
            iflag = 1;
            break;
        case 'L':
            Lflag = 1;
            break;
        case 'M':
            memf = optarg;
            break;
        case 'm':
            mflag = 1;
            break;
        case 'N':
            nlistf = optarg;
            break;
        case 'n':
            numeric_addr = numeric_port = 1;
            break;
        case 'p':
            if ((tp = name2protox(optarg)) == NULL) {
                errx(1,
                     "%s: unknown or uninstrumented protocol",
                     optarg);
            }
            pflag = 1;
            break;
        case 'Q':
            Qflag = 1;
            break;
        case 'q':
            noutputs = atoi(optarg);
            if (noutputs != 0)
                noutputs++;
            break;
        case 'r':
            rflag = 1;
            break;
        case 's':
            ++sflag;
            break;
        case 'S':
            numeric_addr = 1;
            break;
        case 'u':
            af = AF_UNIX;
            break;
        case 'W':
        case 'l':
            Wflag = 1;
            break;
        case 'w':
            interval = atoi(optarg);
            iflag = 1;
            break;
        case 'T':
            Tflag = 1;
            break;
        case 'x':
            xflag = 1;
            break;
        case 'z':
            zflag = 1;
            break;
        case '?':
        default:
            usage();
        }
    argv += optind;
    argc -= optind;

#define	BACKWARD_COMPATIBILITY
#ifdef	BACKWARD_COMPATIBILITY
    if (*argv) {
        if (isdigit(**argv)) {
            interval = atoi(*argv);
            if (interval <= 0)
                usage();
            ++argv;
            iflag = 1;
        }
        if (*argv) {
            nlistf = *argv;
            if (*++argv)
                memf = *argv;
        }
    }
#endif

    /*
     * Discard setgid privileges if not the running kernel so that bad
     * guys can't print interesting stuff from kernel memory.
     */
    live = (nlistf == NULL && memf == NULL);
    if (!live)
        setgid(getgid());

    if (xflag && Tflag)
        errx(1, "-x and -T are incompatible, pick one.");

    if (Bflag) {
        if (!live)
            usage();
        bpf_stats(interface);
        exit(0);
    }
    if (mflag) {
        if (!live) {
            if (kread(0, NULL, 0) == 0)
                mbpr(kvmd, nl[N_SFSTAT].n_value);
        } else
            mbpr(NULL, 0);
        exit(0);
    }
    if (Qflag) {
        if (!live) {
            if (kread(0, NULL, 0) == 0)
                netisr_stats(kvmd);
        } else
            netisr_stats(NULL);
        exit(0);
    }
#if 0
    /*
     * Keep file descriptors open to avoid overhead
     * of open/close on each call to get* routines.
     */
    sethostent(1);
    setnetent(1);
#else
    /*
     * This does not make sense any more with DNS being default over
     * the files.  Doing a setXXXXent(1) causes a tcp connection to be
     * used for the queries, which is slower.
     */
#endif
    if (iflag && !sflag) {
        intpr(interval, NULL, af);
        exit(0);
    }
    if (rflag) {
        if (sflag) {
            rt_stats();
            flowtable_stats();
        } else
            routepr(fib, af);
        exit(0);
    }

    if (gflag) {
        if (sflag) {
            if (af == AF_INET || af == AF_UNSPEC)
                mrt_stats();
#ifdef INET6
            if (af == AF_INET6 || af == AF_UNSPEC)
                mrt6_stats();
#endif
        } else {
            if (af == AF_INET || af == AF_UNSPEC)
                mroutepr();
#ifdef INET6
            if (af == AF_INET6 || af == AF_UNSPEC)
                mroute6pr();
#endif
        }
        exit(0);
    }

    /* Load all necessary kvm symbols */
    kresolve_list(nl);

    if (tp) {
        printproto(tp, tp->pr_name);
        exit(0);
    }
    if (af == AF_INET || af == AF_UNSPEC)
        for (tp = protox; tp->pr_name; tp++)
            printproto(tp, tp->pr_name);
#ifdef INET6
    if (af == AF_INET6 || af == AF_UNSPEC)
        for (tp = ip6protox; tp->pr_name; tp++)
            printproto(tp, tp->pr_name);
#endif /*INET6*/
#ifdef IPSEC
    if (af == PF_KEY || af == AF_UNSPEC)
        for (tp = pfkeyprotox; tp->pr_name; tp++)
            printproto(tp, tp->pr_name);
#endif /*IPSEC*/
#ifdef IPX
    if (af == AF_IPX || af == AF_UNSPEC) {
        for (tp = ipxprotox; tp->pr_name; tp++)
            printproto(tp, tp->pr_name);
    }
#endif /* IPX */
    if (af == AF_APPLETALK || af == AF_UNSPEC)
        for (tp = atalkprotox; tp->pr_name; tp++)
            printproto(tp, tp->pr_name);
#ifdef NETGRAPH
    if (af == AF_NETGRAPH || af == AF_UNSPEC)
        for (tp = netgraphprotox; tp->pr_name; tp++)
            printproto(tp, tp->pr_name);
#endif /* NETGRAPH */
    if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
        unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value,
               nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value,
               nl[N_UNP_SPHEAD].n_value);
    exit(0);
}
示例#6
0
文件: w.c 项目: vkhromov/freebsd
int
main(int argc, char *argv[])
{
	struct kinfo_proc *kp;
	struct kinfo_proc *dkp;
	struct stat *stp;
	time_t touched;
	int ch, i, nentries, nusers, wcmd, longidle, longattime, dropgid;
	const char *memf, *nlistf, *p;
	char *x_suffix;
	char buf[MAXHOSTNAMELEN], errbuf[_POSIX2_LINE_MAX];
	char fn[MAXHOSTNAMELEN];
	char *dot;

	(void)setlocale(LC_ALL, "");
	use_ampm = (*nl_langinfo(T_FMT_AMPM) != '\0');
	use_comma = (*nl_langinfo(RADIXCHAR) != ',');

	/* Are we w(1) or uptime(1)? */
	if (this_is_uptime(argv[0]) == 0) {
		wcmd = 0;
		p = "";
	} else {
		wcmd = 1;
		p = "dhiflM:N:nsuw";
	}

	dropgid = 0;
	memf = _PATH_DEVNULL;
	nlistf = NULL;
	while ((ch = getopt(argc, argv, p)) != -1)
		switch (ch) {
		case 'd':
			dflag = 1;
			break;
		case 'h':
			header = 0;
			break;
		case 'i':
			sortidle = 1;
			break;
		case 'M':
			header = 0;
			memf = optarg;
			dropgid = 1;
			break;
		case 'N':
			nlistf = optarg;
			dropgid = 1;
			break;
		case 'n':
			nflag = 1;
			break;
		case 'f': case 'l': case 's': case 'u': case 'w':
			warnx("[-flsuw] no longer supported");
			/* FALLTHROUGH */
		case '?':
		default:
			usage(wcmd);
		}
	argc -= optind;
	argv += optind;

	if (!(_res.options & RES_INIT))
		res_init();
	_res.retrans = 2;	/* resolver timeout to 2 seconds per try */
	_res.retry = 1;		/* only try once.. */

	/*
	 * Discard setgid privileges if not the running kernel so that bad
	 * guys can't print interesting stuff from kernel memory.
	 */
	if (dropgid)
		setgid(getgid());

	if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == NULL)
		errx(1, "%s", errbuf);

	(void)time(&now);

	if (*argv)
		sel_users = argv;

	setutxent();
	for (nusers = 0; (utmp = getutxent()) != NULL;) {
		if (utmp->ut_type != USER_PROCESS)
			continue;
		if (!(stp = ttystat(utmp->ut_line)))
			continue;	/* corrupted record */
		++nusers;
		if (wcmd == 0)
			continue;
		if (sel_users) {
			int usermatch;
			char **user;

			usermatch = 0;
			for (user = sel_users; !usermatch && *user; user++)
				if (!strcmp(utmp->ut_user, *user))
					usermatch = 1;
			if (!usermatch)
				continue;
		}
		if ((ep = calloc(1, sizeof(struct entry))) == NULL)
			errx(1, "calloc");
		*nextp = ep;
		nextp = &ep->next;
		memmove(&ep->utmp, utmp, sizeof *utmp);
		ep->tdev = stp->st_rdev;
		/*
		 * If this is the console device, attempt to ascertain
		 * the true console device dev_t.
		 */
		if (ep->tdev == 0) {
			size_t size;

			size = sizeof(dev_t);
			(void)sysctlbyname("machdep.consdev", &ep->tdev, &size, NULL, 0);
		}
		touched = stp->st_atime;
		if (touched < ep->utmp.ut_tv.tv_sec) {
			/* tty untouched since before login */
			touched = ep->utmp.ut_tv.tv_sec;
		}
		if ((ep->idle = now - touched) < 0)
			ep->idle = 0;
	}
	endutxent();

	if (header || wcmd == 0) {
		pr_header(&now, nusers);
		if (wcmd == 0) {
			(void)kvm_close(kd);
			exit(0);
		}

#define HEADER_USER		"USER"
#define HEADER_TTY		"TTY"
#define HEADER_FROM		"FROM"
#define HEADER_LOGIN_IDLE	"LOGIN@  IDLE "
#define HEADER_WHAT		"WHAT\n"
#define WUSED  (W_DISPUSERSIZE + W_DISPLINESIZE + W_DISPHOSTSIZE + \
		sizeof(HEADER_LOGIN_IDLE) + 3)	/* header width incl. spaces */ 
		(void)printf("%-*.*s %-*.*s %-*.*s  %s", 
				W_DISPUSERSIZE, W_DISPUSERSIZE, HEADER_USER,
				W_DISPLINESIZE, W_DISPLINESIZE, HEADER_TTY,
				W_DISPHOSTSIZE, W_DISPHOSTSIZE, HEADER_FROM,
				HEADER_LOGIN_IDLE HEADER_WHAT);
	}

	if ((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == NULL)
		err(1, "%s", kvm_geterr(kd));
	for (i = 0; i < nentries; i++, kp++) {
		if (kp->ki_stat == SIDL || kp->ki_stat == SZOMB ||
		    kp->ki_tdev == NODEV)
			continue;
		for (ep = ehead; ep != NULL; ep = ep->next) {
			if (ep->tdev == kp->ki_tdev) {
				/*
				 * proc is associated with this terminal
				 */
				if (ep->kp == NULL && kp->ki_pgid == kp->ki_tpgid) {
					/*
					 * Proc is 'most interesting'
					 */
					if (proc_compare(ep->kp, kp))
						ep->kp = kp;
				}
				/*
				 * Proc debug option info; add to debug
				 * list using kinfo_proc ki_spare[0]
				 * as next pointer; ptr to ptr avoids the
				 * ptr = long assumption.
				 */
				dkp = ep->dkp;
				ep->dkp = kp;
				debugproc(kp) = dkp;
			}
		}
	}
	if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 &&
	     ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 &&
	     ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) || ws.ws_col == 0)
	       ttywidth = 79;
        else
	       ttywidth = ws.ws_col - 1;
	argwidth = ttywidth - WUSED;
	if (argwidth < 4)
		argwidth = 8;
	for (ep = ehead; ep != NULL; ep = ep->next) {
		if (ep->kp == NULL) {
			ep->args = strdup("-");
			continue;
		}
		ep->args = fmt_argv(kvm_getargv(kd, ep->kp, argwidth),
		    ep->kp->ki_comm, MAXCOMLEN);
		if (ep->args == NULL)
			err(1, NULL);
	}
	/* sort by idle time */
	if (sortidle && ehead != NULL) {
		struct entry *from, *save;

		from = ehead;
		ehead = NULL;
		while (from != NULL) {
			for (nextp = &ehead;
			    (*nextp) && from->idle >= (*nextp)->idle;
			    nextp = &(*nextp)->next)
				continue;
			save = from;
			from = from->next;
			save->next = *nextp;
			*nextp = save;
		}
	}

	for (ep = ehead; ep != NULL; ep = ep->next) {
		struct addrinfo hints, *res;
		struct sockaddr_storage ss;
		struct sockaddr *sa = (struct sockaddr *)&ss;
		struct sockaddr_in *lsin = (struct sockaddr_in *)&ss;
		struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *)&ss;
		time_t t;
		int isaddr;

		p = *ep->utmp.ut_host ? ep->utmp.ut_host : "-";
		if ((x_suffix = strrchr(p, ':')) != NULL) {
			if ((dot = strchr(x_suffix, '.')) != NULL &&
			    strchr(dot+1, '.') == NULL)
				*x_suffix++ = '\0';
			else
				x_suffix = NULL;
		}

		isaddr = 0;
		memset(&ss, '\0', sizeof(ss));
		if (inet_pton(AF_INET6, p, &lsin6->sin6_addr) == 1) {
			lsin6->sin6_len = sizeof(*lsin6);
			lsin6->sin6_family = AF_INET6;
			isaddr = 1;
		} else if (inet_pton(AF_INET, p, &lsin->sin_addr) == 1) {
			lsin->sin_len = sizeof(*lsin);
			lsin->sin_family = AF_INET;
			isaddr = 1;
		}
		if (!nflag) {
			/* Attempt to change an IP address into a name */
			if (isaddr && realhostname_sa(fn, sizeof(fn), sa,
			    sa->sa_len) == HOSTNAME_FOUND)
				p = fn;
		} else if (!isaddr) {
			/*
			 * If a host has only one A/AAAA RR, change a
			 * name into an IP address
			 */
			memset(&hints, 0, sizeof(hints));
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_UNSPEC;
			hints.ai_socktype = SOCK_STREAM;
			if (getaddrinfo(p, NULL, &hints, &res) == 0) {
				if (res->ai_next == NULL &&
				    getnameinfo(res->ai_addr, res->ai_addrlen,
					fn, sizeof(fn), NULL, 0,
					NI_NUMERICHOST) == 0)
					p = fn;
				freeaddrinfo(res);
			}
		}

		if (x_suffix) {
			(void)snprintf(buf, sizeof(buf), "%s:%s", p, x_suffix);
			p = buf;
		}
		if (dflag) {
			for (dkp = ep->dkp; dkp != NULL; dkp = debugproc(dkp)) {
				const char *ptr;

				ptr = fmt_argv(kvm_getargv(kd, dkp, argwidth),
				    dkp->ki_comm, MAXCOMLEN);
				if (ptr == NULL)
					ptr = "-";
				(void)printf("\t\t%-9d %s\n",
				    dkp->ki_pid, ptr);
			}
		}
		(void)printf("%-*.*s %-*.*s %-*.*s ",
		    W_DISPUSERSIZE, W_DISPUSERSIZE, ep->utmp.ut_user,
		    W_DISPLINESIZE, W_DISPLINESIZE,
		    *ep->utmp.ut_line ?
		    (strncmp(ep->utmp.ut_line, "tty", 3) &&
		    strncmp(ep->utmp.ut_line, "cua", 3) ?
		    ep->utmp.ut_line : ep->utmp.ut_line + 3) : "-",
		    W_DISPHOSTSIZE, W_DISPHOSTSIZE, *p ? p : "-");
		t = ep->utmp.ut_tv.tv_sec;
		longattime = pr_attime(&t, &now);
		longidle = pr_idle(ep->idle);
		(void)printf("%.*s\n", argwidth - longidle - longattime,
		    ep->args);
	}
	(void)kvm_close(kd);
	exit(0);
}
示例#7
0
/* Change the ownership and access permission of the slave pseudo
   terminal associated with the master pseudo terminal specified
   by FD.  */
int
grantpt (int fd)
{
  int retval = -1;
#ifdef PATH_MAX
  char _buf[PATH_MAX];
#else
  char _buf[512];
#endif
  char *buf = _buf;
  struct stat st;
  uid_t uid;
  gid_t gid;
  pid_t pid;

  if (pts_name (fd, &buf, sizeof (_buf)))
    return -1;

  if (stat(buf, &st) < 0)
    goto cleanup;

  /* Make sure that we own the device.  */
  uid = getuid ();
  if (st.st_uid != uid)
    {
      if (chown (buf, uid, st.st_gid) < 0)
	goto helper;
    }

  gid = getgid ();

  /* Make sure the group of the device is that special group.  */
  if (st.st_gid != gid)
    {
      if (chown (buf, uid, gid) < 0)
	goto helper;
    }

  /* Make sure the permission mode is set to readable and writable by
     the owner, and writable by the group.  */
  if ((st.st_mode & ACCESSPERMS) != (S_IRUSR|S_IWUSR|S_IWGRP))
    {
      if (chmod (buf, S_IRUSR|S_IWUSR|S_IWGRP) < 0)
	goto helper;
    }

  retval = 0;
  goto cleanup;

  /* We have to use the helper program.  */
 helper:

  pid = vfork ();
  if (pid == -1)
    goto cleanup;
  else if (pid == 0)
    {
      /* Disable core dumps.  */
      struct rlimit rl = { 0, 0 };
      setrlimit (RLIMIT_CORE, &rl);

      /* We pase the master pseudo terminal as file descriptor PTY_FILENO.  */
      if (fd != PTY_FILENO)
	if (dup2 (fd, PTY_FILENO) < 0)
	  _exit (FAIL_EBADF);

      execle (_PATH_PT_CHOWN, _PATH_PT_CHOWN, NULL, NULL);
      _exit (FAIL_EXEC);
    }
  else
    {
      int w;

      if (waitpid (pid, &w, 0) == -1)
	goto cleanup;
      if (!WIFEXITED (w))
	errno = ENOEXEC;
      else
	switch (WEXITSTATUS(w))
	  {
	  case 0:
	    retval = 0;
	    break;
	  case FAIL_EBADF:
	    errno = EBADF;
	    break;
	  case FAIL_EINVAL:
	    errno = EINVAL;
	    break;
	  case FAIL_EACCES:
	    errno = EACCES;
	    break;
	  case FAIL_EXEC:
	    errno = ENOEXEC;
	    break;

	  default:
	    assert(! "getpt: internal error: invalid exit code from pt_chown");
	  }
    }

 cleanup:
  if (buf != _buf)
    free (buf);

  return retval;
}
示例#8
0
void
edit_file(char *buf)
    /* copy file to a temp file, edit that file, and install it
       if necessary */
{
    char *cureditor = NULL;
    char editorcmd[PATH_LEN];
    pid_t pid;
    int status;
    struct stat st;
    time_t mtime = 0;
    char *tmp_str;
    FILE *f, *fi;
    int file = 0;
    int c;
    char correction = 0;
    short return_val = EXIT_OK;

    explain("fcrontab : editing %s's fcrontab", user);	

    if ((cureditor=getenv("VISUAL")) == NULL || strcmp(cureditor, "\0") == 0 )
	if((cureditor=getenv("EDITOR"))==NULL || strcmp(cureditor, "\0") == 0 )
	    cureditor = editor;
	
    file = temp_file(&tmp_str);
    if ( (fi = fdopen(file, "w")) == NULL ) {
	error_e("could not fdopen");
	goto exiterr;
    }
#ifndef USE_SETE_ID
    if (fchown(file, asuid, asgid) != 0) {
	error_e("Could not fchown %s to asuid and asgid", tmp_str);
	goto exiterr;
    }
#endif
    /* copy user's fcrontab (if any) to a temp file */
    if ( (f = fopen(buf, "r")) == NULL ) {
	if ( errno != ENOENT ) {
	    error_e("could not open file %s", buf);
	    goto exiterr;
	}
	else
	    fprintf(stderr, "no fcrontab for %s - using an empty one\n",
		    user);
    }
    else { 
	/* copy original file to temp file */
	while ( (c=getc(f)) != EOF )
	    putc(c, fi);
	fclose(f);
    }

    fclose(fi);
    close(file);

    do {

	if ( stat(tmp_str, &st) == 0 )
	    mtime = st.st_mtime;
	else {
	    error_e("could not stat \"%s\"", buf);
	    goto exiterr;
	}

	switch ( pid = fork() ) {
	case 0:
	    /* child */
	    if ( uid != ROOTUID ) {
		if (setgid(asgid) < 0) {
		    error_e("setgid(asgid)");
		    goto exiterr;
		}
		if (setuid(asuid) < 0) {
		    error_e("setuid(asuid)");
		    goto exiterr;
		}
	    }
	    else {
		/* Some programs, like perl, require gid=egid : */
		if ( setgid(getgid()) < 0 ) {
		    error_e("setgid(getgid())");
		    goto exiterr;
		}
	    }
	    snprintf(editorcmd, sizeof(editorcmd), "%s %s", cureditor, tmp_str);
	    execlp(shell, shell, "-c", editorcmd, tmp_str, NULL);
	    error_e("Error while running \"%s\"", cureditor);
	    goto exiterr;

	case -1:
	    error_e("fork");
	    goto exiterr;

	default:
	    /* parent */
	    break ;
	}
	    
	/* only reached by parent */
	waitpid(pid, &status, 0);
	if ( ! WIFEXITED(status) ) {
	    fprintf(stderr, "Editor exited abnormally:"
		    " fcrontab is unchanged.\n");
	    goto exiterr;
	}

#ifndef USE_SETE_ID
	/* we have chown the tmp file to user's name : user may have
	 * linked the tmp file to a file owned by root. In that case, as
	 * fcrontab is setuid root, user may read some informations he is not
	 * allowed to read :
	 * we *must* check that the tmp file is not a link. */

	/* open the tmp file, chown it to root and chmod it to avoid race
	 * conditions */
	/* make sure that the tmp file is not a link */
	{
	    int fd = 0;
	    if ( (fd = open(tmp_str, O_RDONLY)) <= 0 ||
		 fstat(fd, &st) != 0 || ! S_ISREG(st.st_mode) ||
		 S_ISLNK(st.st_mode) || st.st_uid != asuid || st.st_nlink > 1){
		fprintf(stderr, "%s is not a valid regular file.\n", tmp_str);
		close(fd);
		goto exiterr;
	    }
	    if ( fchown(fd, ROOTUID, ROOTGID) != 0 || fchmod(fd, S_IRUSR|S_IWUSR) != 0 ){
		fprintf(stderr, "Can't chown or chmod %s.\n", tmp_str);
		close(fd);
		goto exiterr;
	    }
	    close(fd);
	}
#endif
	
	/* check if file has been modified */
	if ( stat(tmp_str, &st) != 0 ) {
	    error_e("could not stat %s", tmp_str);
	    goto exiterr;
	}    

	else if ( st.st_mtime > mtime || correction == 1) {

	    correction = 0;

	    switch ( read_file(tmp_str) ) {
	    case ERR:
		goto exiterr;
	    case 2:
		fprintf(stderr, "\nFile contains some errors. "
			"Ignore [i] or Correct [c] ? ");
		/* the 2nd getchar() is for the newline char (\n) */
		while ( (c = getchar())	&& c != 'i' && c != 'c' ) {
		    fprintf(stderr, "Please press c to correct, "
			    "or i to ignore: ");
		    while (c != '\n')
			c = getchar();
		}
		if ( c == 'c' ) {
		    /* free memory used to store the list */
		    delete_file(user);
		    correction = 1;
		}
		break;
	    default:
		break;
	    }

	}
	else {
	    fprintf(stderr, "Fcrontab is unchanged :"
		    " no need to install it.\n"); 
	    goto end;
	}

    } while ( correction == 1);

    if ( write_file(tmp_str) != OK )
	return_val = EXIT_ERR;
    
    /* free memory used to store the list */
    delete_file(user);
    
    /* tell daemon to update the conf */
    need_sig = 1;
    
  end:
    if ( remove(tmp_str) != 0 )
	error_e("could not remove %s", tmp_str);
    free(tmp_str);
    xexit (return_val);

  exiterr:
    if ( remove(tmp_str) != 0 )
	error_e("could not remove %s", tmp_str);
    free(tmp_str);
    xexit (EXIT_ERR);

}
int main(int argc, char *argv[]) {
  int argPos;
  int result;
  char *targetSuidPath="/bin/su";
  char *helperSuidPath="/bin/mount";

  for(argPos=1; argPos<argc; argPos++) {
    char *argName=argv[argPos];
    if(!strcmp(argName, "--")) {
      argPos++;
      break;
    }
    if(strncmp(argName, "--", 2)) {
      break;
    }

    fprintf(stderr, "%s: unknown argument %s\n", argv[0], argName);
    exit(1);
  }

  mkdir("/tmp/x", 0700);
  mkdir("/tmp/x/bin", 0700);
  mkdir("/tmp/x/over", 0700);

// Create child; child commences execution in childFunc()
// CLONE_NEWNS: new mount namespace
// CLONE_NEWPID
// CLONE_NEWUTS
  pid_t pid=clone(childFunc, child_stack+STACK_SIZE,
      CLONE_NEWUSER|CLONE_NEWNS|SIGCHLD, argv+argPos);
  if(pid==-1) {
    fprintf(stderr, "Clone failed: %d (%s)\n", errno, strerror(errno));
    return(1);
  }

  char idMapFileName[128];
  char idMapData[128];

  sprintf(idMapFileName, "/proc/%d/setgroups", pid);
  int setGroupsFd=open(idMapFileName, O_WRONLY);
  if(setGroupsFd<0) {
    fprintf(stderr, "Failed to open setgroups\n");
    return(1);
  }
  result=write(setGroupsFd, "deny", 4);
  if(result<0) {
    fprintf(stderr, "Failed to disable setgroups\n");
    return(1);
  }
  close(setGroupsFd);

  sprintf(idMapFileName, "/proc/%d/uid_map", pid);
  fprintf(stderr, "Setting uid map in %s\n", idMapFileName);
  int uidMapFd=open(idMapFileName, O_WRONLY);
  if(uidMapFd<0) {
    fprintf(stderr, "Failed to open uid map\n");
    return(1);
  }
  sprintf(idMapData, "0 %d 1\n", getuid());
  result=write(uidMapFd, idMapData, strlen(idMapData));
  if(result<0) {
    fprintf(stderr, "UID map write failed: %d (%s)\n", errno, strerror(errno));
    return(1);
  }
  close(uidMapFd);

  sprintf(idMapFileName, "/proc/%d/gid_map", pid);
  fprintf(stderr, "Setting gid map in %s\n", idMapFileName);
  int gidMapFd=open(idMapFileName, O_WRONLY);
  if(gidMapFd<0) {
    fprintf(stderr, "Failed to open gid map\n");
    return(1);
  }
  sprintf(idMapData, "0 %d 1\n", getgid());
  result=write(gidMapFd, idMapData, strlen(idMapData));
  if(result<0) {
    fprintf(stderr, "GID map write failed: %d (%s)\n", errno, strerror(errno));
    return(1);
  }
  close(gidMapFd);

// Wait until /tmp/x/over/su exists
  struct stat statBuf;
  while(1) {
    usleep(100);
    result=stat("/tmp/x/over/su", &statBuf);
    if(!result) break;
  }

// Overwrite the file
  sprintf(idMapFileName, "/proc/%d/cwd/su", pid);

// No slashes allowed, everything else is OK.
  char suidExecMinimalElf[] = {
      0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
      0x80, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x02, 0x00, 0x28, 0x00,
      0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08, 0xa2, 0x00, 0x00, 0x00,
      0xa2, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
      0x01, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa4, 0x90, 0x04, 0x08,
      0xa4, 0x90, 0x04, 0x08, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
      0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x89, 0xc8,
      0x89, 0xd0, 0x89, 0xd8, 0x04, 0xd2, 0xcd, 0x80, 

      0x31, 0xc0, 0x04, 0xd0, 0xcd, 0x80,

      0x31, 0xc0, 0x89, 0xd0,
      0xb0, 0x0b, 0x89, 0xe1, 0x83, 0xc1, 0x08, 0x8b, 0x19, 0xcd, 0x80
  };
  char *helperArgs[]={"/bin/mount", NULL};

  int destFd=open(idMapFileName, O_RDWR|O_CREAT|O_TRUNC, 07777);
  if(destFd<0) {
    fprintf(stderr, "Failed to open %s, error %s\n", idMapFileName, strerror(errno));
    return(1);
  }

  char *suidWriteNext=suidExecMinimalElf;
  char *suidWriteEnd=suidExecMinimalElf+sizeof(suidExecMinimalElf);
  while(suidWriteNext!=suidWriteEnd) {
    char *suidWriteTestPos=suidWriteNext;
    while((!*suidWriteTestPos)&&(suidWriteTestPos!=suidWriteEnd))
      suidWriteTestPos++;
// We cannot write any 0-bytes. So let seek fill up the file wihh
// null-bytes for us.
    lseek(destFd, suidWriteTestPos-suidExecMinimalElf, SEEK_SET);
    suidWriteNext=suidWriteTestPos;
    while((*suidWriteTestPos)&&(suidWriteTestPos!=suidWriteEnd))
      suidWriteTestPos++;

    pid_t helperPid=fork();
    if(!helperPid) {
      struct rlimit limits;

// We can't truncate, that would remove the setgid property of
// the file. So make sure the SUID binary does not write too much.
      limits.rlim_cur=suidWriteTestPos-suidExecMinimalElf;
      limits.rlim_max=limits.rlim_cur;
      setrlimit(RLIMIT_FSIZE, &limits);

// Do not rely on some SUID binary to print out the unmodified
// program name, some OSes might have hardening against that.
// Let the ld-loader will do that for us.
      limits.rlim_cur=1<<22;
      limits.rlim_max=limits.rlim_cur;
      result=setrlimit(RLIMIT_AS, &limits);

      dup2(destFd, 1);
      dup2(destFd, 2);
      helperArgs[0]=suidWriteNext;
      execve(helperSuidPath, helperArgs, NULL);
      fprintf(stderr, "Exec failed\n");
      return(1);
    }
    waitpid(helperPid, NULL, 0);
    suidWriteNext=suidWriteTestPos;
  }
  close(destFd);
  execve(idMapFileName, argv+argPos-1, NULL);
  fprintf(stderr, "Failed to execute %s: %d (%s)\n", idMapFileName,
      errno, strerror(errno));
  return(1);
}
示例#10
0
文件: pcpd.c 项目: zixia/nospam
static int callback_login(struct userid_callback *a, void *vp)
{
	struct userid_info *uinfo=(struct userid_info *)vp;
	struct stat stat_buf;
	time_t t;
	char curdir[1024];
	char *token=NULL;

	if (stat(a->homedir, &stat_buf) < 0)
		return (-1);

	if (stat_buf.st_mode & S_ISVTX)
	{
		errno=EAGAIN;
		return (1);
	}

	time(&t);
	if (!uinfo->isproxy)
	{
		token=authtoken_create(uinfo->userid, t);
		if (!token)
		{
			syslog(LOG_NOTICE, "pcpd: authtoken_create() failed.");
			maildir_cache_cancel();
			return (1);
		}
	}

	maildir_cache_start();

	libmail_changeuidgid(a->uid, getgid());

	if (chdir(a->homedir) < 0)
	{
		free(token);
		syslog(LOG_NOTICE, "pcpd: chdir(%s) failed.", a->homedir);
		maildir_cache_cancel();
		exit(1);
	}

	if (chdir(a->maildir && *a->maildir ? a->maildir:"Maildir") < 0)
	{
		free(token);
		syslog(LOG_NOTICE, "pcpd: chdir(Maildir) failed.");
		maildir_cache_cancel();
		exit(1);
	}

	mkdir("calendar", 0700);
	if (chdir("calendar") < 0)
	{
		free(token);
		syslog(LOG_NOTICE, "pcpd: chdir(Maildir) failed.");
		maildir_cache_cancel();
		exit(1);
	}

	curdir[sizeof(curdir)-1]=0;
	if (getcwd(curdir, sizeof(curdir)-1) == 0)
	{
		syslog(LOG_NOTICE, "pcpd: getcwd() failed.");
		maildir_cache_cancel();
		exit(1);
	}

	maildir_cache_save(uinfo->userid, t, curdir, a->uid, getgid());

	alarm(0);
	if (!uinfo->isproxy)
	{
		printf("102 %s logged in.\n", token);
		free(token);
	}
	return (0);
}
示例#11
0
文件: Pipe.cpp 项目: narenas/nx-libs
FILE *Popen(char * const parameters[], const char *type)
{
  FILE *iop;

  struct pid *cur;
  int pdes[2], pid;

  if (parameters == NULL || type == NULL)
  {
    return NULL;
  }

  if ((*type != 'r' && *type != 'w') || type[1])
  {
    return NULL;
  }

  if ((cur = (struct pid *) malloc(sizeof(struct pid))) == NULL)
  {
    return NULL;
  }

  if (pipe(pdes) < 0)
  {
    free(cur);

    return NULL;
  }

  //
  // Block all signals until command is exited.
  // We need to gather information about the
  // child in Pclose().
  //

  DisableSignals();

  switch (pid = Fork())
  {
    case -1:
    {
      //
      // Error.
      //

      #ifdef PANIC
      *logofs << "Popen: PANIC! Function fork failed. "
              << "Error is " << EGET() << " '" << ESTR()
              << "'.\n" << logofs_flush;
      #endif

      cerr << "Error" << ": Function fork failed. "
           << "Error is " << EGET() << " '" << ESTR()
           << "'.\n";

      close(pdes[0]);
      close(pdes[1]);

      free(cur);

      return NULL;
    }
    case 0:
    {
      //
      // Child.
      //

      setgid(getgid());
      setuid(getuid());

      if (*type == 'r')
      {
        if (pdes[1] != 1)
        {
          //
          // Set up stdout.
          //

          dup2(pdes[1], 1);
          close(pdes[1]);
        }

        close(pdes[0]);
      }
      else
      {
        if (pdes[0] != 0)
        {
          //
          // Set up stdin.
          //

          dup2(pdes[0], 0);
          close(pdes[0]);
        }

        close(pdes[1]);
      }

      execvp(parameters[0], parameters + 1);

      exit(127);
    }
  }

  //
  // Parent. Save data about the child.
  //

  RegisterChild(pid);

  if (*type == 'r')
  {
    iop = fdopen(pdes[0], type);

    close(pdes[1]);
  }
  else
  {
    iop = fdopen(pdes[1], type);

    close(pdes[0]);
  }

  cur -> fp = iop;
  cur -> self = pid;
  cur -> next = pidlist;

  pidlist = cur;

  #ifdef TEST
  *logofs << "Popen: Executing ";

  for (int i = 0; i < 256 && parameters[i] != NULL; i++)
  {
    *logofs << "[" << parameters[i] << "]";
  }

  *logofs << " with descriptor " << fileno(iop)
          << ".\n" << logofs_flush;
  #endif

  return iop;
}
示例#12
0
/*
==============
VID_LoadRefresh
==============
*/
qboolean VID_LoadRefresh( char *name )
{
	refimport_t	ri;
	GetRefAPI_t	GetRefAPI;
	char	fn[MAX_OSPATH];
	struct stat st;
	extern uid_t saved_euid;
	FILE *fp;
	
	if ( reflib_active )
	{
		if (KBD_Close_fp)
			KBD_Close_fp();
		if (RW_IN_Shutdown_fp)
			RW_IN_Shutdown_fp();
		KBD_Close_fp = NULL;
		RW_IN_Shutdown_fp = NULL;
		re.Shutdown();
		VID_FreeReflib ();
	}

	Com_Printf( "------- Loading %s -------\n", name );

	//regain root
	seteuid(saved_euid);

	if ((fp = fopen(so_file, "r")) == NULL) {
		Com_Printf( "LoadLibrary(\"%s\") failed: can't open %s (required for location of ref libraries)\n", name, so_file);
		return false;
	}
	fgets(fn, sizeof(fn), fp);
	fclose(fp);
	while (*fn && isspace(fn[strlen(fn) - 1]))
		fn[strlen(fn) - 1] = 0;

	strcat(fn, "/");
	strcat(fn, name);

	// permission checking
	if (strstr(fn, "softx") == NULL) { // softx doesn't require root
		if (stat(fn, &st) == -1) {
			Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name, strerror(errno));
			return false;
		}
#if 0
		if (st.st_uid != 0) {
			Com_Printf( "LoadLibrary(\"%s\") failed: ref is not owned by root\n", name);
			return false;
		}
		if ((st.st_mode & 0777) & ~0700) {
			Com_Printf( "LoadLibrary(\"%s\") failed: invalid permissions, must be 700 for security considerations\n", name);
			return false;
		}
#endif
	} else {
		// softx requires we give up root now
		setreuid(getuid(), getuid());
		setegid(getgid());
	}

	if ( ( reflib_library = dlopen( fn, RTLD_LAZY | RTLD_GLOBAL ) ) == 0 )
	{
		Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name , dlerror());
		return false;
	}

  Com_Printf( "LoadLibrary(\"%s\")\n", fn );

	ri.Cmd_AddCommand = Cmd_AddCommand;
	ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
	ri.Cmd_Argc = Cmd_Argc;
	ri.Cmd_Argv = Cmd_Argv;
	ri.Cmd_ExecuteText = Cbuf_ExecuteText;
	ri.Con_Printf = VID_Printf;
	ri.Sys_Error = VID_Error;
	ri.FS_LoadFile = FS_LoadFile;
	ri.FS_FreeFile = FS_FreeFile;
	ri.FS_Gamedir = FS_Gamedir;
	ri.Cvar_Get = Cvar_Get;
	ri.Cvar_Set = Cvar_Set;
	ri.Cvar_SetValue = Cvar_SetValue;
	ri.Vid_GetModeInfo = VID_GetModeInfo;
	ri.Vid_MenuInit = VID_MenuInit;
	ri.Vid_NewWindow = VID_NewWindow;

	if ( ( GetRefAPI = (void *) dlsym( reflib_library, "GetRefAPI" ) ) == 0 )
		Com_Error( ERR_FATAL, "dlsym failed on %s", name );

	re = GetRefAPI( ri );

	if (re.api_version != API_VERSION)
	{
		VID_FreeReflib ();
		Com_Error (ERR_FATAL, "%s has incompatible api_version", name);
	}

	/* Init IN (Mouse) */
	in_state.IN_CenterView_fp = IN_CenterView;
	in_state.Key_Event_fp = Do_Key_Event;
	in_state.viewangles = cl.viewangles;
	in_state.in_strafe_state = &in_strafe.state;

	if ((RW_IN_Init_fp = dlsym(reflib_library, "RW_IN_Init")) == NULL ||
		(RW_IN_Shutdown_fp = dlsym(reflib_library, "RW_IN_Shutdown")) == NULL ||
		(RW_IN_Activate_fp = dlsym(reflib_library, "RW_IN_Activate")) == NULL ||
		(RW_IN_Commands_fp = dlsym(reflib_library, "RW_IN_Commands")) == NULL ||
		(RW_IN_Move_fp = dlsym(reflib_library, "RW_IN_Move")) == NULL ||
		(RW_IN_Frame_fp = dlsym(reflib_library, "RW_IN_Frame")) == NULL)
		Sys_Error("No RW_IN functions in REF.\n");

	Real_IN_Init();

	if ( re.Init( 0, 0 ) == -1 )
	{
		re.Shutdown();
		VID_FreeReflib ();
		return false;
	}

	/* Init KBD */
#if 1
	if ((KBD_Init_fp = dlsym(reflib_library, "KBD_Init")) == NULL ||
		(KBD_Update_fp = dlsym(reflib_library, "KBD_Update")) == NULL ||
		(KBD_Close_fp = dlsym(reflib_library, "KBD_Close")) == NULL)
		Sys_Error("No KBD functions in REF.\n");
#else
	{
		void KBD_Init(void);
		void KBD_Update(void);
		void KBD_Close(void);

		KBD_Init_fp = KBD_Init;
		KBD_Update_fp = KBD_Update;
		KBD_Close_fp = KBD_Close;
	}
#endif
	KBD_Init_fp(Do_Key_Event);

	// give up root now
	setreuid(getuid(), getuid());
	setegid(getgid());

	Com_Printf( "------------------------------------\n");
	reflib_active = true;
	return true;
}
示例#13
0
文件: sbnc.cpp 项目: demize/shroudbnc
/**
 * main
 *
 * Entry point for shroudBNC.
 */
int main(int argc, char **argv) {
#ifdef _WIN32
	char TclLibrary[512];
#endif
	CConfig *Config;
	bool Daemonize, Usage;
	char *ConfigDir = NULL, *LogDir = NULL, *DataDir = NULL, *PidPath = NULL;

	g_ArgC = argc;
	g_ArgV = argv;

	sbncGetExePath(); // first call sets exe path in static var

	Daemonize = true;
	Usage = false;

	for (int i = 1; i < argc; i++) {
		if (strcmp(argv[i], "--config") == 0) {
			if (i + 1 >= argc) {
				fprintf(stderr, "Missing parameter for --config: You need to specify the config directory.");

				return EXIT_FAILURE;
			}

			ConfigDir = argv[i + 1];

			i++;

			continue;
		}

		if (strcmp(argv[i], "--log") == 0) {
			if (i + 1 >= argc) {
				fprintf(stderr, "Missing parameter for --log: You need to specify the log directory.");

				return EXIT_FAILURE;
			}

			LogDir = argv[i + 1];

			i++;

			continue;
		}

		if (strcmp(argv[i], "--data") == 0) {
			if (i + 1 >= argc) {
				fprintf(stderr, "Missing parameter for --log: You need to specify the log directory.");

				return EXIT_FAILURE;
			}

			DataDir = argv[i + 1];

			i++;

			continue;
		}

		if (strcmp(argv[i], "--pid") == 0) {
			if (i + 1 >= argc) {
				fprintf(stderr, "Missing parameter for --pid: You need to specify the PID path.");

				return EXIT_FAILURE;
			}

			PidPath = argv[i + 1];

			i++;

			continue;
		}

		if (strcmp(argv[i], "--lpc") == 0) {
			fprintf(stderr, "Warning: Ignoring --lpc (which is now the default behaviour.)\n");

			continue;
		}

		if (strcmp(argv[i], "--foreground") == 0) {
			Daemonize = false;

			continue;
		}

		if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "/?") == 0) {
			Usage = true;

			continue;
		}

		fprintf(stderr, "Unknown command-line option: '%s'\n", argv[i]);

		return EXIT_FAILURE;
	}

	bool WasNull = false;

	if (ConfigDir == NULL) {
		WasNull = true;
		ConfigDir = sbncFindConfigDir();
	}

	if (mkdir(ConfigDir) < 0 && errno != EEXIST) {
		fprintf(stderr, "Config directory (%s) could not be created: %s\n", ConfigDir, strerror(errno));
		free(ConfigDir);

		return EXIT_FAILURE;
	}

	sbncSetConfigPath(ConfigDir);

	if (LogDir)
		sbncSetLogPath(LogDir);
	else if (DataDir)
		sbncSetLogPath(DataDir);
	else
		sbncSetLogPath(ConfigDir);

	if (DataDir)
		sbncSetDataPath(DataDir);
	else
		sbncSetDataPath(ConfigDir);

	if (PidPath)
		sbncSetPidPath(PidPath);
	else
		sbncSetPidPath(sbncBuildPath("sbnc.pid", sbncGetDataPath()));

	if (WasNull)
		free(ConfigDir);

	if (chdir(sbncGetDataPath()) < 0) {
		fprintf(stderr, "Could not chdir() into data directory (%s): %s\n", sbncGetDataPath(), strerror(errno));
		free(ConfigDir);
 
		return EXIT_FAILURE;
	}

	fprintf(stderr, "shroudBNC (version: " BNCVERSION ") - an object-oriented IRC bouncer\n");
	fprintf(stderr, "Configuration directory: %s\n", sbncGetConfigPath());
	fprintf(stderr, "Log directory: %s\n", sbncGetLogPath());
	fprintf(stderr, "Data directory: %s\n", sbncGetDataPath());
	fprintf(stderr, "PID path: %s\n", sbncGetPidPath());

	if (Usage) {
		fprintf(stderr, "\n");
		fprintf(stderr, "Syntax: %s [OPTION]", argv[0]);
		fprintf(stderr, "\n");
		fprintf(stderr, "Options:\n");
		fprintf(stderr, "\t--help\t\t\tdisplay this help and exit\n");
		fprintf(stderr, "\t--foreground\t\trun in the foreground\n");
		fprintf(stderr, "\t--config <config dir>\tspecifies the location of the configuration directory.\n");
		fprintf(stderr, "\t--data <data dir>\tspecifies the location of the data directory (defaults to the config directory).\n");
		fprintf(stderr, "\t--log <log dir>\tspecifies the location of the log directory (defaults to the data directory if given, else the config directory).\n");
		fprintf(stderr, "\t--pid <pid path>\tspecifies the location of the PID file (defaults to <data dir>/sbnc.pid).\n");

		return 3;
	}

#ifdef _WIN32
	if (!GetEnvironmentVariable("TCL_LIBRARY", TclLibrary, sizeof(TclLibrary)) || strlen(TclLibrary) == 0) {
		SetEnvironmentVariable("TCL_LIBRARY", "./tcl8.4");
	}
#endif

	srand((unsigned int)time(NULL));

#ifndef _WIN32
	if (getuid() == 0 || geteuid() == 0 || getgid() == 0 || getegid() == 0) {
		printf("You cannot run shroudBNC as 'root' or using an account which has 'wheel' "
			"privileges. Use an ordinary user account and remove the suid bit if it is set.\n");
		return EXIT_FAILURE;
	}

	rlimit core_limit = { INT_MAX, INT_MAX };
	setrlimit(RLIMIT_CORE, &core_limit);
#endif

#if !defined(_WIN32 ) || defined(__MINGW32__)
	lt_dlinit();
#endif

	time(&g_CurrentTime);

	Config = new CConfig(sbncBuildPath("sbnc.conf", NULL), NULL);

	if (Config == NULL) {
		printf("Fatal: could not create config object.");

#if !defined(_WIN32 ) || defined(__MINGW32__)
		lt_dlexit();
#endif

		return EXIT_FAILURE;
	}

	// constructor sets g_Bouncer
	new CCore(Config, argc, argv);

#if !defined(_WIN32)
	signal(SIGPIPE, SIG_IGN);
#endif

	g_Bouncer->StartMainLoop(Daemonize);

	delete g_Bouncer;
	delete Config;

#if !defined(_WIN32 ) || defined(__MINGW32__)
	lt_dlexit();
#endif

	exit(EXIT_SUCCESS);
}
示例#14
0
int ds_daemon(http_conf * conf, int t)
{  
    int uid = getuid();
    int gid = getgid();
    int status = 0;


    if(conf->user && strlen(conf->user)) {
        struct passwd * pw  = getpwnam(conf->user);
        if(!pw) {
            printf(" user[%s] no found\n", conf->user);
            exit(0);
        }
        uid = pw->pw_uid;
        gid = pw->pw_gid;
        printf("\n user:%s\n", conf->user);
    }


    if(t == 0 ) {
        ds_init_daemon(conf);
    }
   

   if( t == 0 || t == 1) {
       ds_init_children(conf);

       //ds_pid = getpid();

        if(setsid() == -1) {  //setsid创建一个新会话
            printf("setsid() failed!" DS_LINEEND);
            exit(0);
        }
        
        umask(0);
        setuid(uid);
        setgid(gid);
        ds_init(conf);
   }

   /*if( t == 2) {
       conf->work_mode = FORK_PROCESS_WORK_HTTP_MODE;
   }*/
   if(t == 2) {
       //使用两个pipe 完成accept 和cgi进程的通信,pipe 0read, 1write
       int pipHttp[2], pipCgi[2];
       pipe(pipHttp);
       pipe(pipCgi);
       int forkCgiPid = fork();
       if(forkCgiPid == 0) {
            conf->child_pip.in = pipCgi[0];
            conf->child_pip.out = pipHttp[1];
            close(pipHttp[0]);
            close(pipCgi[1]);
            conf->work_mode = FORK_PROCESS_WORK_CGI_MODE;
        } else {
            conf->child_pip.in = pipHttp[0];
            conf->child_pip.out = pipCgi[1];
            close(pipHttp[1]);
            close(pipCgi[0]);
            conf->work_mode = FORK_PROCESS_WORK_HTTP_MODE;
        }
   }
 

    


    return OK;
}
示例#15
0
// whitelist for /home/user directory
void fs_whitelist(void) {
	char *homedir = cfg.homedir;
	assert(homedir);
	ProfileEntry *entry = cfg.profile;
	if (!entry)
		return;
	
	// realpath function will fail with ENOENT if the file is not found
	// we need to expand the path before installing a new, empty home directory
	while (entry) {
		// handle only whitelist commands
		if (strncmp(entry->data, "whitelist ", 10)) {
			entry = entry->next;
			continue;
		}

		char *new_name = expand_home(entry->data + 10, cfg.homedir);
		assert(new_name);
		char *fname = realpath(new_name, NULL);
		free(new_name);
		if (fname) {
			// change file name in entry->data
			if (strcmp(fname, entry->data + 10) != 0) {
				char *newdata;
				if (asprintf(&newdata, "whitelist %s", fname) == -1)
					errExit("asprintf");
				entry->data = newdata;
				if (arg_debug)
					printf("Replaced whitelist path: %s\n", entry->data);
			}
						
			free(fname);
		}
		else {
			// file not found, blank the entry in the list
			if (arg_debug)
				printf("Removed whitelist path: %s\n", entry->data);
			*entry->data = '\0';
		}
		entry = entry->next;
	}
		
	// create /tmp/firejail/mnt/whome directory
	fs_build_mnt_dir();
	int rv = mkdir(WHITELIST_HOME_DIR, S_IRWXU | S_IRWXG | S_IRWXO);
	if (rv == -1)
		errExit("mkdir");
	if (chown(WHITELIST_HOME_DIR, getuid(), getgid()) < 0)
		errExit("chown");
	if (chmod(WHITELIST_HOME_DIR, 0755) < 0)
		errExit("chmod");

	// keep a copy of real home dir in /tmp/firejail/mnt/whome
	if (mount(cfg.homedir, WHITELIST_HOME_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
		errExit("mount bind");

	// start building the new home directory by mounting a tmpfs fielsystem
	 fs_private();

	// go through profile rules again, and interpret whitelist commands
	entry = cfg.profile;
	while (entry) {
		// handle only whitelist commands
		if (strncmp(entry->data, "whitelist ", 10)) {
			entry = entry->next;
			continue;
		}

		whitelist_path(entry->data + 10);

		entry = entry->next;
	}

	// mask the real home directory, currently mounted on /tmp/firejail/mnt/whome
	if (mount("tmpfs", WHITELIST_HOME_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
		errExit("mount tmpfs");
}
示例#16
0
文件: rdup-up.c 项目: miekg/rdup
int main(int argc, char **argv)
{
	struct sigaction sa;
	char pwd[BUFSIZE + 1];
	int c;
	guint i;
	char *path;

#ifdef ENABLE_NLS
	if (!setlocale(LC_MESSAGES, ""))
		msg(_("Locale could not be set"));

	bindtextdomain(PACKAGE_NAME, LOCALEROOTDIR);
	(void)textdomain(PACKAGE_NAME);
#endif				/* ENABLE_NLS */

	/* setup our signal handling */
	sa.sa_flags = 0;
	sigfillset(&sa.sa_mask);

	sa.sa_handler = got_sig;
	sigaction(SIGPIPE, &sa, NULL);
	sigaction(SIGINT, &sa, NULL);

	if (((getuid() != geteuid()) || (getgid() != getegid()))) {
		msg(_("Will not run suid/sgid for safety reasons"));
		exit(EXIT_FAILURE);
	}

	if (!getcwd(pwd, BUFSIZE)) {
		msg(_("Could not get current working directory"));
		exit(EXIT_FAILURE);
	}

	for (c = 0; c < argc; c++) {
		if (strlen(argv[c]) > BUFSIZE) {
			msg(_("Argument length overrun"));
			exit(EXIT_FAILURE);
		}
	}

	while ((c = getopt(argc, argv, "thnVvus:r:Tq")) != -1) {
		switch (c) {
		case 'v':
			opt_verbose = 1;
			break;
		case 'h':
			usage_up(stdout);
			exit(EXIT_SUCCESS);
		case 'n':
			opt_dry = TRUE;
			break;
		case 'T':
			opt_table = TRUE;
			opt_dry = TRUE;
			opt_verbose = 0;
			break;
		case 'u':
			opt_chown = FALSE;
			break;
		case 's':
			opt_strip = abs(atoi(optarg));
			break;
		case 'r':
			/* expand relative paths */
			if (!g_path_is_absolute(optarg))
				opt_path_strip =
				    abspath(g_strdup_printf
					    ("%s/%s", pwd, optarg));
			else
				opt_path_strip = abspath(optarg);

			if (!opt_path_strip) {
				msg(_("Failed to expand path `%s\'"), optarg);
				exit(EXIT_FAILURE);
			}

			if (opt_path_strip[strlen(opt_path_strip) - 1] != '/')
				opt_path_strip =
				    g_strdup_printf("%s/", opt_path_strip);

			/* count the number of labels */
			for (i = 0; i < strlen(opt_path_strip); i++) {
				if (opt_path_strip[i] == '/')
					opt_path_strip_len++;
			}
			opt_path_strip_len--;	/* we added the closing slash, so need -1 here */
			break;
		case 'q':
			opt_quiet = TRUE;
			break;
		case 't':
			opt_top = TRUE;
			break;
		case 'V':
#ifdef DEBUG
			fprintf(stdout, "%s %s (with --enable-debug)\n",
				PROGNAME, VERSION);
#else
			fprintf(stdout, "%s %s\n", PROGNAME, VERSION);
#endif				/* DEBUG */
			exit(EXIT_SUCCESS);
		default:
			msg(_("Unknown option seen `%c\'"), optopt);
			exit(EXIT_FAILURE);
		}
	}
	argc -= optind;
	argv += optind;

	if (opt_table) {
		path = NULL;
	} else {
		if (argc != 1) {
			msg(_("Destination directory is required"));
			exit(EXIT_FAILURE);
		}
		if (!g_path_is_absolute(argv[0])) {
			gchar *full_path =
			    g_strdup_printf("%s/%s", pwd, argv[0]);
			path = abspath(full_path);
			g_free(full_path);
		} else
			path = abspath(argv[0]);
	}

	if (!opt_dry) {
		if (opt_top) {
			/* this is not 100%, but better than nothing */
			if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
				msg(_("Failed to create directory `%s\'"),
				    path);
				exit(EXIT_FAILURE);
			}
			if (mkpath(path, 00777) == -1) {
				msg(_("Failed to create directory `%s\': %s"),
				    path, strerror(errno));
				exit(EXIT_FAILURE);
			}
		} else {
			if (!g_file_test(path, G_FILE_TEST_IS_DIR)) {
				msg(_("No such directory: `%s\'"), path);
				exit(EXIT_FAILURE);
			}
		}
	}

	if (update(path) == FALSE)
		exit(EXIT_FAILURE);

	g_free(path);

	exit(EXIT_SUCCESS);
}
示例#17
0
int main(int argc, char **argv) {
  char *gidmap = NULL, *inside = NULL, *outside = NULL, *uidmap = NULL;
  char *bind = NULL;
  int hostnet = 0, master, option, stdio = 0;
  pid_t child, parent;

  while ((option = getopt(argc, argv, "+:b:cg:i:no:u:")) > 0)
    switch (option) {
      case 'b':
        bind = optarg;
        break;
      case 'c':
        stdio++;
        break;
      case 'g':
        gidmap = optarg;
        break;
      case 'i':
        inside = optarg;
        break;
      case 'n':
        hostnet++;
        break;
      case 'o':
        outside = optarg;
        break;
      case 'u':
        uidmap = optarg;
        break;
      default:
        usage(argv[0]);
    }

  if (argc <= optind)
    usage(argv[0]);

  parent = getpid();
  switch (child = fork()) {
    case -1:
      error(1, errno, "fork");
    case 0:
      raise(SIGSTOP);
//      if (geteuid() != 0)
//        denysetgroups(parent);
      writemap(parent, GID, gidmap);
      writemap(parent, UID, uidmap);

      if (outside) {
        if (setgid(getgid()) < 0 || setuid(getuid()) < 0)
          error(1, 0, "Failed to drop privileges");
        execlp(SHELL, SHELL, "-c", outside, NULL);
        error(1, errno, "exec %s", outside);
      }

      exit(EXIT_SUCCESS);
  }

  if (setgid(getgid()) < 0 || setuid(getuid()) < 0)
    error(1, 0, "Failed to drop privileges");

  if (unshare(CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWUTS) < 0)
    error(1, 0, "Failed to unshare namespaces");

  if (!hostnet && unshare(CLONE_NEWNET) < 0)
      error(1, 0, "Failed to unshare network namespace");

  waitforstop(child);
  kill(child, SIGCONT);
  waitforexit(child);

  setgid(0);
  setgroups(0, NULL);
  setuid(0);

  master = stdio ? -1 : getconsole();
  createroot(argv[optind], master, inside, bind);

  unshare(CLONE_NEWPID);
  switch (child = fork()) {
    case -1:
      error(1, errno, "fork");
    case 0:
      mountproc();
      if (!hostnet)
        mountsys();
      enterroot();

      if (master >= 0) {
        close(master);
        setconsole("/dev/console");
      }

      clearenv();
      putenv("container=contain");

      if (argv[optind + 1])
        execv(argv[optind + 1], argv + optind + 1);
      else
        execl(SHELL, SHELL, NULL);
      error(1, errno, "exec");
  }

  return supervise(child, master);
}
示例#18
0
static void
xlocaledir(
    char *buf,
    int buf_len)
{
    char *p = buf;
    int len = 0;

#ifndef NO_XLOCALEDIR
    char *dir;
    int priv = 1;

    dir = getenv("XLOCALEDIR");

    if (dir) {
#ifndef WIN32
	/*
	 * Only use the user-supplied path if the process isn't priviledged.
	 */
	if (getuid() == geteuid() && getgid() == getegid()) {
#if defined(HASSETUGID)
	    priv = issetugid();
#elif defined(HASGETRESUID)
	    {
		uid_t ruid, euid, suid;
		gid_t rgid, egid, sgid;
		if ((getresuid(&ruid, &euid, &suid) == 0) &&
		    (getresgid(&rgid, &egid, &sgid) == 0))
		    priv = (euid != suid) || (egid != sgid);
	    }
#else
	    /*
	     * If there are saved ID's the process might still be priviledged
	     * even though the above test succeeded.  If issetugid() and
	     * getresgid() aren't available, test this by trying to set
	     * euid to 0.
	     *
	     * Note: this only protects setuid-root clients.  It doesn't
	     * protect other setuid or any setgid clients.  If this tradeoff
	     * isn't acceptable, set DisableXLocaleDirEnv to YES in host.def.
	     */
	    unsigned int oldeuid;
	    oldeuid = geteuid();
	    if (seteuid(0) != 0) {
		priv = 0;
	    } else {
		seteuid(oldeuid);
		priv = 1;
	    }
#endif
	}
#else
	priv = 0;
#endif
	if (!priv) {
	    len = strlen(dir);
	    strncpy(p, dir, buf_len);
	    if (len < buf_len) {
	        p[len++] = LC_PATHDELIM;
	        p += len;
	    }
	}
    }
#endif /* NO_XLOCALEDIR */

    if (len < buf_len)
#ifndef __UNIXOS2__
      strncpy(p, XLOCALEDIR, buf_len - len);
#else
      strncpy(p,__XOS2RedirRoot(XLOCALEDIR), buf_len - len);
#endif
    buf[buf_len-1] = '\0';
}
示例#19
0
int
main(int argc, char **argv)
{
	struct quotause *qup, *protoprivs, *curprivs;
	long id, protoid;
	long long lim;
	int i, quotatype, range, tmpfd;
	uid_t startuid, enduid;
	u_int32_t *limp;
	char *protoname, *cp, *oldoptarg, ch;
	int eflag = 0, tflag = 0, pflag = 0;
	char *fspath = NULL;
	char buf[MAXLOGNAME];

	if (argc < 2)
		usage();
	if (getuid())
		errx(1, "permission denied");
	quotatype = USRQUOTA;
	protoprivs = NULL;
	curprivs = NULL;
	protoname = NULL;
	while ((ch = getopt(argc, argv, "ugtf:p:e:")) != -1) {
		switch(ch) {
		case 'f':
			fspath = optarg;
			break;
		case 'p':
			protoname = optarg;
			pflag++;
			break;
		case 'g':
			quotatype = GRPQUOTA;
			break;
		case 'u':
			quotatype = USRQUOTA;
			break;
		case 't':
			tflag++;
			break;
		case 'e':
			if ((qup = malloc(sizeof(*qup))) == NULL)
				errx(2, "out of memory");
			bzero(qup, sizeof(*qup));
			i = 0;
			oldoptarg = optarg;
			for (cp = optarg; (cp = strsep(&optarg, ":")) != NULL;
			    i++) {
				if (cp != oldoptarg)
					*(cp - 1) = ':';
				limp = NULL;
				switch (i) {
				case 0:
					strlcpy(qup->fsname, cp,
					    sizeof(qup->fsname));
					break;
				case 1:
					limp = &qup->dqblk.dqb_bsoftlimit;
					break;
				case 2:
					limp = &qup->dqblk.dqb_bhardlimit;
					break;
				case 3:
					limp = &qup->dqblk.dqb_isoftlimit;
					break;
				case 4:
					limp = &qup->dqblk.dqb_ihardlimit;
					break;
				default:
					warnx("incorrect quota specification: "
					    "%s", oldoptarg);
					usage();
					break; /* XXX: report an error */
				}
				if (limp != NULL) {
					lim = strtoll(cp, NULL, 10);
					if (lim < 0 || lim > UINT_MAX)
						errx(1, "invalid limit value: "
						    "%lld", lim);
					*limp = (u_int32_t)lim;
				}
			}
			qup->dqblk.dqb_bsoftlimit =
			    btodb((off_t)qup->dqblk.dqb_bsoftlimit * 1024);
			qup->dqblk.dqb_bhardlimit =
			    btodb((off_t)qup->dqblk.dqb_bhardlimit * 1024);
			if (protoprivs == NULL) {
				protoprivs = curprivs = qup;
			} else {
				curprivs->next = qup;
				curprivs = qup;
			}
			eflag++;
			pflag++;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	if (pflag) {
		if (protoprivs == NULL) {
			if ((protoid = getentry(protoname, quotatype)) == -1)
				exit(1);
			protoprivs = getprivs(protoid, quotatype, fspath);
			for (qup = protoprivs; qup; qup = qup->next) {
				qup->dqblk.dqb_btime = 0;
				qup->dqblk.dqb_itime = 0;
			}
		}
		for (; argc-- > 0; argv++) {
			if (strspn(*argv, "0123456789-") == strlen(*argv) &&
			    (cp = strchr(*argv, '-')) != NULL) {
				*cp++ = '\0';
				startuid = atoi(*argv);
				enduid = atoi(cp);
				if (enduid < startuid)
					errx(1,
	"ending uid (%d) must be >= starting uid (%d) when using uid ranges",
						enduid, startuid);
				range = 1;
			} else {
				startuid = enduid = 0;
				range = 0;
			}
			for ( ; startuid <= enduid; startuid++) {
				if (range)
					snprintf(buf, sizeof(buf), "%d",
					    startuid);
				else
					snprintf(buf, sizeof(buf), "%s",
						*argv);
				if ((id = getentry(buf, quotatype)) < 0)
					continue;
				if (eflag) {
					for (qup = protoprivs; qup;
					    qup = qup->next) {
						curprivs = getprivs(id,
						    quotatype, qup->fsname);
						if (curprivs == NULL)
							continue;
						strcpy(qup->qfname,
						    curprivs->qfname);
						strcpy(qup->fsname,
						    curprivs->fsname);
					}
				}
				putprivs(id, quotatype, protoprivs);						
			}
		}
		exit(0);
	}
	tmpfd = mkstemp(tmpfil);
	fchown(tmpfd, getuid(), getgid());
	if (tflag) {
		protoprivs = getprivs(0, quotatype, fspath);
		if (writetimes(protoprivs, tmpfd, quotatype) == 0)
			exit(1);
		if (editit(tmpfil) && readtimes(protoprivs, tmpfil))
			putprivs(0, quotatype, protoprivs);
		freeprivs(protoprivs);
		close(tmpfd);
		unlink(tmpfil);
		exit(0);
	}
	for ( ; argc > 0; argc--, argv++) {
		if ((id = getentry(*argv, quotatype)) == -1)
			continue;
		curprivs = getprivs(id, quotatype, fspath);
		if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0)
			continue;
		if (editit(tmpfil) && readprivs(curprivs, tmpfil))
			putprivs(id, quotatype, curprivs);
		freeprivs(curprivs);
	}
	close(tmpfd);
	unlink(tmpfil);
	exit(0);
}
示例#20
0
int
main(int argc, char *argv[])
{
	int	 opt, proto = -1, route = 0;
	kvm_t	*kvmd = NULL;
	char	*memf = NULL;

	while ((opt = getopt(argc, argv, "hnM:p:r")) != -1) {
		switch (opt) {
		case 'n':
			numeric_bdaddr = 1;
			break;

		case 'M':
			memf = optarg;
			break;

		case 'p':
			if (strcasecmp(optarg, "hci_raw") == 0)
				proto = N_HCI_RAW;
			else if (strcasecmp(optarg, "l2cap_raw") == 0)
				proto = N_L2CAP_RAW;
			else if (strcasecmp(optarg, "l2cap") == 0)
				proto = N_L2CAP;
			else if (strcasecmp(optarg, "rfcomm") == 0)
				proto = N_RFCOMM;
			else if (strcasecmp(optarg, "rfcomm_s") == 0)
				proto = N_RFCOMM_S; 
			else
				usage();
				/* NOT REACHED */
			break;

		case 'r':
			route = 1;
			break;

		case 'h':
		default:
			usage();
			/* NOT REACHED */
		}
	}

	if ((proto == N_HCI_RAW || proto == N_RFCOMM || proto == N_RFCOMM_S) && route)
		usage();
		/* NOT REACHED */

	/*
	 * Discard setgid privileges if not the running kernel so that
	 * bad guys can't print interesting stuff from kernel memory.
	 */
	if (memf != NULL)
		if (setgid(getgid()) != 0)
			err(1, "setgid");

	kvmd = kopen(memf);
	if (kvmd == NULL)
		return (1);

	switch (proto) {
	case N_HCI_RAW:
		hcirawpr(kvmd, nl[N_HCI_RAW].n_value);
		break;

	case N_L2CAP_RAW:
		if (route)
			l2caprtpr(kvmd, nl[N_L2CAP_RAW_RT].n_value);
		else
			l2caprawpr(kvmd, nl[N_L2CAP_RAW].n_value);
		break;

	case N_L2CAP:
		if (route) 
			l2caprtpr(kvmd, nl[N_L2CAP_RT].n_value);
		else
			l2cappr(kvmd, nl[N_L2CAP].n_value);
		break;

	case N_RFCOMM:
		rfcommpr(kvmd, nl[N_RFCOMM].n_value);
		break;

	case N_RFCOMM_S:
		rfcommpr_s(kvmd, nl[N_RFCOMM_S].n_value);
		break;

	default:
		if (route) {
			l2caprtpr(kvmd, nl[N_L2CAP_RAW_RT].n_value);
			l2caprtpr(kvmd, nl[N_L2CAP_RT].n_value);
		} else {
			hcirawpr(kvmd, nl[N_HCI_RAW].n_value);
			l2caprawpr(kvmd, nl[N_L2CAP_RAW].n_value);
			l2cappr(kvmd, nl[N_L2CAP].n_value);
			rfcommpr_s(kvmd, nl[N_RFCOMM_S].n_value);
			rfcommpr(kvmd, nl[N_RFCOMM].n_value);
		}
		break;
	}

	return (kvm_close(kvmd));
} /* main */
示例#21
0
int     main(int argc, char **argv)
{
    static char *full_name = 0;		/* sendmail -F */
    struct stat st;
    char   *slash;
    char   *sender = 0;			/* sendmail -f */
    int     c;
    int     fd;
    int     mode;
    ARGV   *ext_argv;
    int     debug_me = 0;
    int     err;
    int     n;
    int     flags = SM_FLAG_DEFAULT;
    char   *site_to_flush = 0;
    char   *id_to_flush = 0;
    char   *encoding = 0;
    char   *qtime = 0;
    const char *errstr;
    uid_t   uid;
    const char *rewrite_context = MAIL_ATTR_RWR_LOCAL;
    int     dsn_notify = 0;
    const char *dsn_envid = 0;
    int     saved_optind;

    /*
     * Fingerprint executables and core dumps.
     */
    MAIL_VERSION_STAMP_ALLOCATE;

    /*
     * Be consistent with file permissions.
     */
    umask(022);

    /*
     * To minimize confusion, make sure that the standard file descriptors
     * are open before opening anything else. XXX Work around for 44BSD where
     * fstat can return EBADF on an open file descriptor.
     */
    for (fd = 0; fd < 3; fd++)
	if (fstat(fd, &st) == -1
	    && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
	    msg_fatal_status(EX_OSERR, "open /dev/null: %m");

    /*
     * The CDE desktop calendar manager leaks a parent file descriptor into
     * the child process. For the sake of sendmail compatibility we have to
     * close the file descriptor otherwise mail notification will hang.
     */
    for ( /* void */ ; fd < 100; fd++)
	(void) close(fd);

    /*
     * Process environment options as early as we can. We might be called
     * from a set-uid (set-gid) program, so be careful with importing
     * environment variables.
     */
    if (safe_getenv(CONF_ENV_VERB))
	msg_verbose = 1;
    if (safe_getenv(CONF_ENV_DEBUG))
	debug_me = 1;

    /*
     * Initialize. Set up logging, read the global configuration file and
     * extract configuration information. Set up signal handlers so that we
     * can clean up incomplete output.
     */
    if ((slash = strrchr(argv[0], '/')) != 0 && slash[1])
	argv[0] = slash + 1;
    msg_vstream_init(argv[0], VSTREAM_ERR);
    msg_cleanup(tempfail);
    msg_syslog_init(mail_task("sendmail"), LOG_PID, LOG_FACILITY);
    set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0]));

    /*
     * Some sites mistakenly install Postfix sendmail as set-uid root. Drop
     * set-uid privileges only when root, otherwise some systems will not
     * reset the saved set-userid, which would be a security vulnerability.
     */
    if (geteuid() == 0 && getuid() != 0) {
	msg_warn("the Postfix sendmail command has set-uid root file permissions");
	msg_warn("or the command is run from a set-uid root process");
	msg_warn("the Postfix sendmail command must be installed without set-uid root file permissions");
	set_ugid(getuid(), getgid());
    }

    /*
     * Further initialization. Load main.cf first, so that command-line
     * options can override main.cf settings. Pre-scan the argument list so
     * that we load the right main.cf file.
     */
#define GETOPT_LIST "A:B:C:F:GIL:N:O:R:UV:X:b:ce:f:h:imno:p:r:q:tvx"

    saved_optind = optind;
    while (argv[OPTIND] != 0) {
	if (strcmp(argv[OPTIND], "-q") == 0) {	/* not getopt compatible */
	    optind++;
	    continue;
	}
	if ((c = GETOPT(argc, argv, GETOPT_LIST)) <= 0)
	    break;
	if (c == 'C') {
	    VSTRING *buf = vstring_alloc(1);

	    if (setenv(CONF_ENV_PATH,
		   strcmp(sane_basename(buf, optarg), MAIN_CONF_FILE) == 0 ?
		       sane_dirname(buf, optarg) : optarg, 1) < 0)
		msg_fatal_status(EX_UNAVAILABLE, "out of memory");
	    vstring_free(buf);
	}
    }
    optind = saved_optind;
    mail_conf_read();
    if (strcmp(var_syslog_name, DEF_SYSLOG_NAME) != 0)
	msg_syslog_init(mail_task("sendmail"), LOG_PID, LOG_FACILITY);
    get_mail_conf_str_table(str_table);

    if (chdir(var_queue_dir))
	msg_fatal_status(EX_UNAVAILABLE, "chdir %s: %m", var_queue_dir);

    signal(SIGPIPE, SIG_IGN);

    /*
     * Optionally start the debugger on ourself. This must be done after
     * reading the global configuration file, because that file specifies
     * what debugger command to execute.
     */
    if (debug_me)
	debug_process();

    /*
     * The default mode of operation is determined by the process name. It
     * can, however, be changed via command-line options (for example,
     * "newaliases -bp" will show the mail queue).
     */
    if (strcmp(argv[0], "mailq") == 0) {
	mode = SM_MODE_MAILQ;
    } else if (strcmp(argv[0], "newaliases") == 0) {
	mode = SM_MODE_NEWALIAS;
    } else if (strcmp(argv[0], "smtpd") == 0) {
	mode = SM_MODE_DAEMON;
    } else {
	mode = SM_MODE_ENQUEUE;
    }

    /*
     * Parse JCL. Sendmail has been around for a long time, and has acquired
     * a large number of options in the course of time. Some options such as
     * -q are not parsable with GETOPT() and get special treatment.
     */
#define OPTIND  (optind > 0 ? optind : 1)

    while (argv[OPTIND] != 0) {
	if (strcmp(argv[OPTIND], "-q") == 0) {
	    if (mode == SM_MODE_DAEMON)
		msg_warn("ignoring -q option in daemon mode");
	    else
		mode = SM_MODE_FLUSHQ;
	    optind++;
	    continue;
	}
	if (strcmp(argv[OPTIND], "-V") == 0) {
	    msg_warn("option -V is deprecated with Postfix 2.3; "
		     "specify -XV instead");
	    argv[OPTIND] = "-XV";
	}
	if (strncmp(argv[OPTIND], "-V", 2) == 0 && strlen(argv[OPTIND]) == 4) {
	    msg_warn("option %s is deprecated with Postfix 2.3; "
		     "specify -X%s instead",
		     argv[OPTIND], argv[OPTIND] + 1);
	    argv[OPTIND] = concatenate("-X", argv[OPTIND] + 1, (char *) 0);
	}
	if (strcmp(argv[OPTIND], "-XV") == 0) {
	    verp_delims = var_verp_delims;
	    optind++;
	    continue;
	}
	if ((c = GETOPT(argc, argv, GETOPT_LIST)) <= 0)
	    break;
	switch (c) {
	default:
	    if (msg_verbose)
		msg_info("-%c option ignored", c);
	    break;
	case 'n':
	    msg_fatal_status(EX_USAGE, "-%c option not supported", c);
	case 'B':
	    if (strcmp(optarg, "8BITMIME") == 0)/* RFC 1652 */
		encoding = MAIL_ATTR_ENC_8BIT;
	    else if (strcmp(optarg, "7BIT") == 0)	/* RFC 1652 */
		encoding = MAIL_ATTR_ENC_7BIT;
	    else
		msg_fatal_status(EX_USAGE, "-B option needs 8BITMIME or 7BIT");
	    break;
	case 'F':				/* full name */
	    full_name = optarg;
	    break;
	case 'G':				/* gateway submission */
	    rewrite_context = MAIL_ATTR_RWR_REMOTE;
	    break;
	case 'I':				/* newaliases */
	    mode = SM_MODE_NEWALIAS;
	    break;
	case 'N':
	    if ((dsn_notify = dsn_notify_mask(optarg)) == 0)
		msg_warn("bad -N option value -- ignored");
	    break;
	case 'V':				/* DSN, was: VERP */
	    if (strlen(optarg) > 100)
		msg_warn("too long -V option value -- ignored");
	    else if (!allprint(optarg))
		msg_warn("bad syntax in -V option value -- ignored");
	    else
		dsn_envid = optarg;
	    break;
	case 'X':
	    switch (*optarg) {
	    default:
		msg_fatal_status(EX_USAGE, "unsupported: -%c%c", c, *optarg);
	    case 'V':				/* VERP */
		if (verp_delims_verify(optarg + 1) != 0)
		    msg_fatal_status(EX_USAGE, "-V requires two characters from %s",
				     var_verp_filter);
		verp_delims = optarg + 1;
		break;
	    }
	    break;
	case 'b':
	    switch (*optarg) {
	    default:
		msg_fatal_status(EX_USAGE, "unsupported: -%c%c", c, *optarg);
	    case 'd':				/* daemon mode */
		if (mode == SM_MODE_FLUSHQ)
		    msg_warn("ignoring -q option in daemon mode");
		mode = SM_MODE_DAEMON;
		break;
	    case 'h':				/* print host status */
	    case 'H':				/* flush host status */
		mode = SM_MODE_IGNORE;
		break;
	    case 'i':				/* newaliases */
		mode = SM_MODE_NEWALIAS;
		break;
	    case 'm':				/* deliver mail */
		mode = SM_MODE_ENQUEUE;
		break;
	    case 'p':				/* mailq */
		mode = SM_MODE_MAILQ;
		break;
	    case 's':				/* stand-alone mode */
		mode = SM_MODE_USER;
		break;
	    case 'v':				/* expand recipients */
		flags |= DEL_REQ_FLAG_USR_VRFY;
		break;
	    }
	    break;
	case 'f':
	    sender = optarg;
	    break;
	case 'i':
	    flags &= ~SM_FLAG_AEOF;
	    break;
	case 'o':
	    switch (*optarg) {
	    default:
		if (msg_verbose)
		    msg_info("-%c%c option ignored", c, *optarg);
		break;
	    case 'A':
		if (optarg[1] == 0)
		    msg_fatal_status(EX_USAGE, "-oA requires pathname");
		myfree(var_alias_db_map);
		var_alias_db_map = mystrdup(optarg + 1);
		set_mail_conf_str(VAR_ALIAS_DB_MAP, var_alias_db_map);
		break;
	    case '7':
	    case '8':
		break;
	    case 'i':
		flags &= ~SM_FLAG_AEOF;
		break;
	    case 'm':
		break;
	    }
	    break;
	case 'r':				/* obsoleted by -f */
	    sender = optarg;
	    break;
	case 'q':
	    if (ISDIGIT(optarg[0])) {
		qtime = optarg;
	    } else if (optarg[0] == 'R') {
		site_to_flush = optarg + 1;
		if (*site_to_flush == 0)
		    msg_fatal_status(EX_USAGE, "specify: -qRsitename");
	    } else if (optarg[0] == 'I') {
		id_to_flush = optarg + 1;
		if (*id_to_flush == 0)
		    msg_fatal_status(EX_USAGE, "specify: -qIqueueid");
	    } else {
		msg_fatal_status(EX_USAGE, "-q%c is not implemented",
				 optarg[0]);
	    }
	    break;
	case 't':
	    flags |= SM_FLAG_XRCPT;
	    break;
	case 'v':
	    msg_verbose++;
	    break;
	case '?':
	    msg_fatal_status(EX_USAGE, "usage: %s [options]", argv[0]);
	}
    }

    /*
     * Look for conflicting options and arguments.
     */
    if ((flags & SM_FLAG_XRCPT) && mode != SM_MODE_ENQUEUE)
	msg_fatal_status(EX_USAGE, "-t can be used only in delivery mode");

    if (site_to_flush && mode != SM_MODE_ENQUEUE)
	msg_fatal_status(EX_USAGE, "-qR can be used only in delivery mode");

    if (id_to_flush && mode != SM_MODE_ENQUEUE)
	msg_fatal_status(EX_USAGE, "-qI can be used only in delivery mode");

    if (flags & DEL_REQ_FLAG_USR_VRFY) {
	if (flags & SM_FLAG_XRCPT)
	    msg_fatal_status(EX_USAGE, "-t option cannot be used with -bv");
	if (dsn_notify)
	    msg_fatal_status(EX_USAGE, "-N option cannot be used with -bv");
	if (msg_verbose == 1)
	    msg_fatal_status(EX_USAGE, "-v option cannot be used with -bv");
    }

    /*
     * The -v option plays double duty. One requests verbose delivery, more
     * than one requests verbose logging.
     */
    if (msg_verbose == 1 && mode == SM_MODE_ENQUEUE) {
	msg_verbose = 0;
	flags |= DEL_REQ_FLAG_RECORD;
    }

    /*
     * Start processing. Everything is delegated to external commands.
     */
    if (qtime && mode != SM_MODE_DAEMON)
	exit(0);
    switch (mode) {
    default:
	msg_panic("unknown operation mode: %d", mode);
	/* NOTREACHED */
    case SM_MODE_ENQUEUE:
	if (site_to_flush) {
	    if (argv[OPTIND])
		msg_fatal_status(EX_USAGE, "flush site requires no recipient");
	    ext_argv = argv_alloc(2);
	    argv_add(ext_argv, "postqueue", "-s", site_to_flush, (char *) 0);
	    for (n = 0; n < msg_verbose; n++)
		argv_add(ext_argv, "-v", (char *) 0);
	    argv_terminate(ext_argv);
	    mail_run_replace(var_command_dir, ext_argv->argv);
	    /* NOTREACHED */
	} else if (id_to_flush) {
	    if (argv[OPTIND])
		msg_fatal_status(EX_USAGE, "flush queue_id requires no recipient");
	    ext_argv = argv_alloc(2);
	    argv_add(ext_argv, "postqueue", "-i", id_to_flush, (char *) 0);
	    for (n = 0; n < msg_verbose; n++)
		argv_add(ext_argv, "-v", (char *) 0);
	    argv_terminate(ext_argv);
	    mail_run_replace(var_command_dir, ext_argv->argv);
	    /* NOTREACHED */
	} else {
	    enqueue(flags, encoding, dsn_envid, dsn_notify,
		    rewrite_context, sender, full_name, argv + OPTIND);
	    exit(0);
	    /* NOTREACHED */
	}
	break;
    case SM_MODE_MAILQ:
	if (argv[OPTIND])
	    msg_fatal_status(EX_USAGE,
			     "display queue mode requires no recipient");
	ext_argv = argv_alloc(2);
	argv_add(ext_argv, "postqueue", "-p", (char *) 0);
	for (n = 0; n < msg_verbose; n++)
	    argv_add(ext_argv, "-v", (char *) 0);
	argv_terminate(ext_argv);
	mail_run_replace(var_command_dir, ext_argv->argv);
	/* NOTREACHED */
    case SM_MODE_FLUSHQ:
	if (argv[OPTIND])
	    msg_fatal_status(EX_USAGE,
			     "flush queue mode requires no recipient");
	ext_argv = argv_alloc(2);
	argv_add(ext_argv, "postqueue", "-f", (char *) 0);
	for (n = 0; n < msg_verbose; n++)
	    argv_add(ext_argv, "-v", (char *) 0);
	argv_terminate(ext_argv);
	mail_run_replace(var_command_dir, ext_argv->argv);
	/* NOTREACHED */
    case SM_MODE_DAEMON:
	if (argv[OPTIND])
	    msg_fatal_status(EX_USAGE, "daemon mode requires no recipient");
	ext_argv = argv_alloc(2);
	argv_add(ext_argv, "postfix", (char *) 0);
	for (n = 0; n < msg_verbose; n++)
	    argv_add(ext_argv, "-v", (char *) 0);
	argv_add(ext_argv, "start", (char *) 0);
	argv_terminate(ext_argv);
	err = (mail_run_background(var_command_dir, ext_argv->argv) < 0);
	argv_free(ext_argv);
	exit(err);
	break;
    case SM_MODE_NEWALIAS:
	if (argv[OPTIND])
	    msg_fatal_status(EX_USAGE,
			 "alias initialization mode requires no recipient");
	if (*var_alias_db_map == 0)
	    return (0);
	ext_argv = argv_alloc(2);
	argv_add(ext_argv, "postalias", (char *) 0);
	for (n = 0; n < msg_verbose; n++)
	    argv_add(ext_argv, "-v", (char *) 0);
	argv_split_append(ext_argv, var_alias_db_map, ", \t\r\n");
	argv_terminate(ext_argv);
	mail_run_replace(var_command_dir, ext_argv->argv);
	/* NOTREACHED */
    case SM_MODE_USER:
	if (argv[OPTIND])
	    msg_fatal_status(EX_USAGE,
			     "stand-alone mode requires no recipient");
	/* The actual enforcement happens in the postdrop command. */
	if ((errstr = check_user_acl_byuid(var_submit_acl, uid = getuid())) != 0)
	    msg_fatal_status(EX_NOPERM,
			     "User %s(%ld) is not allowed to submit mail",
			     errstr, (long) uid);
	ext_argv = argv_alloc(2);
	argv_add(ext_argv, "smtpd", "-S", (char *) 0);
	for (n = 0; n < msg_verbose; n++)
	    argv_add(ext_argv, "-v", (char *) 0);
	argv_terminate(ext_argv);
	mail_run_replace(var_daemon_dir, ext_argv->argv);
	/* NOTREACHED */
    case SM_MODE_IGNORE:
	exit(0);
	/* NOTREACHED */
    }
}
示例#22
0
INTERNAL int SYS_GetGID(void)
{
	return getgid();
}
示例#23
0
文件: odcgi.c 项目: simkiv/opendomo
/** Main execution routine
 @param argc Number of args (0)
 @param argv Args (always empty)
 */
int
main (int argc, char *argv[])
{


  /* ---------------------------------------------------------------------
   *  Alert! setuid program with root privileges
   * ---------------------------------------------------------------------*/

  /* syslog */
  openlog ("odcgi", LOG_PID, LOG_USER);

  script_env_t env;


  /* Agent address */
  //! @todo: what if eth0 don't exists?
  snprintf (env.agent_address, MAX_ENV_SIZE, "%s", getip ("eth0"));

  //! @todo: lots of static variables. Maybe some can be reused to save memory
  char http_gui[8];
  //char http_style[10];
  char http_logout[8];
  char http_user[256];
  char http_pass[256];
  char http_session[1024];
  char http_noheader[8];
  char http_newuser[256];
  char http_newpass1[256];
  char http_newpass2[256];
  char http_deluser[256];
  char http_moduser[256];
  char http_modpass1[256];
  char http_modpass2[256];
  char http_modoldpass[256];
  char http_getfile[256];
  char http_resource[50];
  char http_play_mjpg[100];
  char http_temp[100];

  /* Configuration vars */
  FILE *fh;
  read_config_file (fh, OD_APP_I18N_CONF, lang, "en");
  //read_config_file(fh,OD_APP_STYLE_CONF,style,"default");
  //read_config_file(fh,OD_APP_SKIN_CONF,skin,"silver");

  /* Get HTTP variables */
  cgi_t *cgi = cgi_alloc ();

  cgi_get_param_by_name (cgi, "GUI", http_gui, sizeof (http_gui));
  cgi_get_param_by_name (cgi, "LOGOUT", http_logout, sizeof (http_logout));
  cgi_get_param_by_name (cgi, "USER", http_user, sizeof (http_user));
  cgi_get_param_by_name (cgi, "PASS", http_pass, sizeof (http_pass));
  cgi_get_param_by_name (cgi, "HTSESSID", http_session,
			 sizeof (http_session));
  cgi_get_param_by_name (cgi, "NOHEADER", http_noheader,
			 sizeof (http_noheader));
  cgi_get_param_by_name (cgi, "NEWUSER", http_newuser, sizeof (http_newuser));
  cgi_get_param_by_name (cgi, "NEWPASS1", http_newpass1,
			 sizeof (http_newpass1));
  cgi_get_param_by_name (cgi, "NEWPASS2", http_newpass2,
			 sizeof (http_newpass2));
  cgi_get_param_by_name (cgi, "DELUSER", http_deluser, sizeof (http_deluser));
  cgi_get_param_by_name (cgi, "MODUSER", http_moduser, sizeof (http_moduser));
  cgi_get_param_by_name (cgi, "MODPASS1", http_modpass1,
			 sizeof (http_modpass1));
  cgi_get_param_by_name (cgi, "MODPASS2", http_modpass2,
			 sizeof (http_modpass2));
  cgi_get_param_by_name (cgi, "MODOLDPASS", http_modoldpass,
			 sizeof (http_modoldpass));
  cgi_get_param_by_name (cgi, "FILE", http_getfile, sizeof (http_getfile));
  cgi_get_param_by_name (cgi, "resource", http_resource,
			 sizeof (http_resource));
  cgi_get_param_by_name (cgi, "play_mjpg", http_play_mjpg,
			 sizeof (http_play_mjpg));



//      if (cgi_get_param_by_name(cgi,"style", http_style, sizeof(http_style))==1)
//      {
//              //cgi_get_cookie("HTSTYLE", http_style, sizeof(http_style));
//              strncpy(style, http_style, sizeof(http_style));
//              cgi_http_header_set_cookie("HTSTYLE", style);
//      }

  // Si se ha solicitado una hoja de estilo, la entregamos
  if (cgi_get_param_by_name (cgi, "css", http_temp, sizeof (http_temp)) == 1)
    {
      syslog (LOG_NOTICE, "printing style: %s\n", http_temp);
      odcgi_print_file (http_temp);
      cgi_free (cgi);
      return 0;
    }
/*	// Si se ha solicitado el javascript específico, lo entregamos
	if (cgi_get_param_by_name(cgi, "js", http_temp, sizeof(http_temp))==1) 
	{
		syslog(LOG_NOTICE, "printing script: %s\n", http_temp);
		odcgi_print_file(http_temp);
		return 0;
	} */


  if (strlen (http_session) == 0)
    {
      cgi_get_cookie ("HTSESSID", http_session, sizeof (http_session));
      syslog (LOG_NOTICE, "session from cookie: %s\n", http_session);
    }

  /* get gui type */
  if (strcmp (http_gui, "XML") == 0)
    gui = xml;
  if (strcmp (http_gui, "none") == 0)
    gui = none;


  /* login process */
  if (odcgi_login (&env, http_user, http_pass,
		   http_session, sizeof (http_session)) == -1)
    {
      syslog (LOG_NOTICE, "login failed: %s-%s\n", http_user, http_pass);
      cgi_free (cgi);
      return -1;
    }

//      syslog(LOG_NOTICE, "env.user: %s\n", env.user);
//      syslog(LOG_NOTICE, "http_user: %s\n", http_user);


  /* check logout */
  if (odcgi_logout (&env, http_logout))
    {
      cgi_free (cgi);
      return -1;
    }


  /* ---------------------------------------------------------------------
   *  Login OK: odcgi is setuid root
   * --------------------------------------------------------------------- */
  //syslog(LOG_NOTICE, "[odcgi] userid: %d\n", getuid());

  /* root has not access */
  if (odcgi_check_root (http_user))
    {
      cgi_free (cgi);
      return -1;
    }


  /* ---------------------------------------------------------------------
   *  Login OK:
   *  + admin has root privileges
   *  + normal user has Linux privileges
   * --------------------------------------------------------------------- */
  syslog (LOG_NOTICE, "[odcgi] user: %s, uid: %d, guid: %d\n",
	  env.user, getuid (), getgid ());

	/* NO USER MANAGEMENT FUNCTIONS IN
  // adds a new user 
  if (odcgi_add_user (http_newuser, http_newpass1, http_newpass2) == -1)
    {
      cgi_free (cgi);
      return -1;
    }

  // delete user 
  if (odcgi_del_user (http_deluser) == -1)
    {
      cgi_free (cgi);
      return -1;
    }

  // modify user password 
  if (odcgi_mod_user (http_moduser, http_modoldpass,
		      http_modpass1, http_modpass2) == -1)
    {
      cgi_free (cgi);
      return -1;
    }

	*/

  /* set session */
  /* Privilege separation: drop root privileges */
//   syslog(LOG_NOTICE, "set session %s\n", http_session);
//   syslog(LOG_NOTICE, "[odcgi] session_set_ids user: %s\n", env.user);
  session_set_ids (env.user);
  syslog (LOG_NOTICE, "[odcgi] dropped privileges user: %s, uid: %d, guid: %d\n",
	  env.user, getuid (), getgid ());
  

  /* File reference with user permissions applied */
  if (strlen (http_getfile) > 5)
    {
      char buffer[1024] = "/media/";
      strcat (buffer, http_getfile);
      if (http_send_file (buffer))
	{
	  cgi_free (cgi);
	  return 0;
	}
      else
	{
	  //! @todo Mostrar error
	}
    }


  /* play mjpg file */
  if (strlen (http_play_mjpg) > 3)
	{
		syslog (LOG_NOTICE, "play: %s\n", http_play_mjpg);
		mjpg_play (http_play_mjpg);
		cgi_free (cgi);
		return 0;
	}

	switch (gui)
	{
		case xml:
			cgi_http_header_begin ("text/xml");
		break;
		case html:
			cgi_http_header_begin ("text/html");
		break;
		default:
			cgi_http_header_begin ("text/plain");
	}


  /* Resource reference */
  //TODO Verificar permisos de usuario
  if (strlen (http_resource) > 3)
	{
		syslog (LOG_NOTICE, "Serving resource %s\n", http_resource);
		if (mjpg_streaming_rsc (http_resource))
		{
			cgi_free (cgi);
			return 0;
		}
		else
		{
			//printf("<div id='connfail'><p class='error'>%s</p></div>\n",
			//              T(ODCGI_ERROR__CONNECTION_FAILURE));
			cgi_free (cgi);
			return 0;
		}
	}



	syslog (LOG_NOTICE, "1.session: %s\n", http_session);
	cgi_http_header_set_cookie ("HTSESSID", http_session);
	//   cgi_get_cookie("HTSTYLE", style, sizeof(style));
	//   cgi_http_header_set_cookie("HTSTYLE", style);
	cgi_http_header_end ();




	/* ---------------------------------------------------------------------
	*  User privileges
	* ---------------------------------------------------------------------*/

	size_t len = cgi->decoded_url->size;
	char path_info[256 + len];
	path_info[0] = 0;
	sstrncpy (path_info, cgi_get_path_info (cgi), sizeof (path_info));
	syslog (LOG_NOTICE, "path_info %s - %d\n", path_info, strlen (path_info));



	// If any POST/GET vars matches with submit_X.sh, X.sh is the target
	// then replace 'path_info'.
	char options[256 + len];
	int index = 0;
	char varname[256];
	char varvalue[256 + len];
	int has_option = 0;
	char scriptname[256] = "";
	char path[256 + len];
	path[0] = 0;

	while (cgi_get_param_by_index (cgi, index, varname, sizeof (varname),
				 varvalue, sizeof (varvalue)))
	{
		// Replace "+" for " "
		for (int i=0;i<sizeof(varvalue);i++) {
			if (varvalue[i]=='+') varvalue[i]=' ';
		}

		syslog (LOG_DEBUG, "CGIParam %d %s=%s\n", index, varname, varvalue);
		
		if (strcmp (varname, "GUI") == 0)
		{
		// Ignore               

		}
		else if (strcmp (varname, "odcgioptionsel") == 0)
		{
			sstrncat (options, varvalue, sizeof (options));
			sstrncat (options, " ", sizeof (options));
			has_option = 1;
		}

		else if (strncmp (varname, "submit_", 7) == 0)
		{
			syslog (LOG_NOTICE, "Submit redirection found at %s\n", varname);
			sstrncpy (scriptname, varname + 7, sizeof (scriptname));
			//sstrncpy(path_info, scriptname, sizeof(path_info));
			snprintf (path, sizeof (path), "/usr/local/opendomo/%s",
			    scriptname);
			syslog (LOG_DEBUG, "debugging %s - %s [%s]\n", scriptname, path,
			  options);
			break;
		}
		index++;
	}


  /* Check PATH variable */
  if (strlen (path_info) == 0)
    strcpy (path_info, "/");

  /* filters */
  if (!match
      (path_info,
       "^/[a-záéíóúàèäëïöüñçA-ZÁÉÍÓÚÀÈÄËÏÖÜÑÇ0-9_/]*\\.{0,1}[a-záéíóúàèäëïöüñçA-ZÁÉÍÓÚÀÈÄËÏÖÜÑÇ0-9_/+ =?:]*$"))
    {
      odcgi_print_header ("error", env.user);
      syslog (LOG_ERR, "%s\n", ODCGI_ERROR__INVALID_PATH);
      odcgi_msg_error (ODCGI_ERROR__INVALID_PATH,
      	"Invalid character found in the command.");
      printf ("\n<!-- PATH_INFO: %s-->\n", path_info);
      odcgi_print_footer ("", 0, cgi);
      cgi_free (cgi);
      return -1;
    }

  int err = 0;

  char *param_regex = "[$;'\\\"]";
  if (strstr (cgi_get_query_string (cgi), ".."))
    err = 1;
  else if (strstr (cgi_get_decoded_url (cgi), ".."))
    err = 2;
  else if (strlen (cgi_get_query_string (cgi)) > 0 &&
	   match (cgi_get_query_string (cgi), param_regex))
    err = 3;
  else if (strlen (cgi_get_decoded_url (cgi)) > 0 &&
	   match (cgi_get_decoded_url (cgi), param_regex))
    err = 4;

  if (err!=0)
    {
      odcgi_print_header ("error", env.user);
      syslog (LOG_ERR, "%s\n", ODCGI_ERROR__INVALID_PATH);
      odcgi_msg_error (ODCGI_ERROR__INVALID_PATH,
		 "Invalid character found in the parameters.");
      printf ("\n<!-- PATH ERROR: %d (not allowed) \n\t%s \n\t %s -->\n", 
      	err,
      	cgi_get_query_string (cgi),
      	cgi_get_decoded_url (cgi));
      odcgi_print_footer ("", 0, cgi);
      cgi_free (cgi);
      return -1;
    }

  // If PATH is not modified, use the default path in CONF_DIR.
  if (path[0] == 0)
    {
      snprintf (path, sizeof (path), "%s/%s", OD_CFG_ROOT_DIR, path_info);
    }

  /* root directory */
  if (chdir (OD_CFG_ROOT_DIR) != 0)
    {
      odcgi_print_header ("error", env.user);
      syslog (LOG_ERR, "%s\n", ODCGI_ERROR__ROOT_PATH_ACCESS);
      odcgi_msg_error (ODCGI_ERROR__ROOT_PATH_ACCESS,
		 "Cannot access the configuration directory. "
		 "Missing privileges or misconfiguration");
      odcgi_print_footer ("", 0, cgi);
      cgi_free (cgi);
      return -1;
    }


  char name[256 + len];
  char value[256 + len];
  char prename[256 + len];
  char *shname;
  string_t *cmd = string_alloc ("");

  file_t fs;
  strcpy (scriptname, basename (path));

  /* HTML-head begin */
  odcgi_print_header (scriptname, env.user);

  printf ("<!-- path: %s, path_info: %s-->\n", path, path_info);

  /* Check NOHEADER */
  if ((gui == html) && (atoi (http_noheader) != 1))
    {
      string_assign_str (cmd, "/usr/bin/categories.sh ");
      string_append (cmd, path_info);

      script_exec (cmd->str, "header", &env);
      if (strlen (path_info) < 2)
	{
	  printf
	    ("  <div class='applicationTitle'><h1>OpenDomo</h1></div>\n");
	}
      else
	{
	  printf ("  <div class='root'><a href='" OD_URI "/'> </a></div>\n");
	}
    }



  sstrncpy (prename, path, sizeof (prename));
  shname = strtok (prename, " ");
  file_set_filename (&fs, shname);
  strcpy (scriptname, basename (path));

  /* if dir: list contents */
  if (file_is_dir (&fs))
    {
      string_assign_str (cmd,  "/usr/bin/list.sh ");
      string_append (cmd, path_info);
      string_append (cmd, " contents");

      script_exec (cmd->str, "main", &env);
    }
  else
    {
      /* if file: execute */
      // The path might be a redirection (no actual link in ..opendomo/root/)
      if (!file_is_file (&fs))
	{
	  snprintf (path, sizeof (path), "/usr/local/opendomo/%s",
		    basename (scriptname));
	  printf ("\n<!-- debug paths: %s / %s [%s] -->\n", path, path_info,
		  scriptname);
	  file_set_filename (&fs, path);
	  if (!file_is_file (&fs))	// If it's still not a valid path, abort
	    {
	      odcgi_msg_error (ODCGI_ERROR__SCRIPT_NOT_FOUND,
			 "The script was not found. "
			 "Maybe the function you are requiring "
			 "is not installed in this system");
	      printf ("<!-- BASENAME: %s -->\n", basename (scriptname));
	      odcgi_print_footer ("", 0, cgi);
	      cgi_free (cgi);
	      return 1;
	    }
	}
      //printf("<!-- debug path: %s -->\n", path);
      //char *p = strrchr(path, '/');
      if (has_option /*&& p */ )
	{
	  string_assign_str (cmd, path);
	  string_append (cmd, " ");
	  string_append (cmd, options);
	}
      else
	{
	  string_assign_str (cmd, path);
	  string_append (cmd, " ");
	}
      printf ("\n<!-- decoded_url: %s \n\tquery_string: %s-->\n", 
      	cgi->decoded_url->str, cgi->query_string->str);
      int i = 0;
      while (cgi_get_param_by_index (cgi, i++,
				     name, sizeof (name), value,
				     sizeof (value)))
	{
		if (strcmp (name, ODCGI_SESSION_NAME) == 0)
		{
			// Ignoring session name var ...
		}
		else if (strncmp (name, "GUI", 3) == 0)
		{
			// Ignoring GUI param
		}
		else if (strncmp (name, "submit_", 7) == 0)
		{
			// Ignoring possible submit redirection ...
		}
		else
		{
			//for (i = 0; i < sizeof(value); i++){
			//	if (value[i]=='+') value[i]=' ';
			//}
			// Avoid overwritting a defined environment var
			if (getenv (name) == NULL)
				setenv (name, value, 1);
			string_append (cmd, " \"");
			string_append (cmd, value);
			string_append (cmd, "\" ");
		}
	}
	string_replace (cmd, "+", " ");
	string_replace (cmd, "'", "&apos;");

     printf ("<!-- cmd (file): %s -->\n", cmd->str);
      //fflush(stdout); // Force flush, otherwise an error will preceed stdout
      // Check the returned value of script_exec()


      int ret = script_exec (cmd->str, "main", &env);
      if (ret != 0)
	{
	  /* else: empty div */
	  printf ("<div id='main'><p class='error'>%s</p></div>",
		  ODCGI_ERROR__SCRIPT_NOT_FOUND);
	}
    }
  /* Print scripts */
  //odcgi_print_script(path); DEPRECATED

  /* HTML end */
  if (atoi (http_noheader) != 1)
    {
      odcgi_print_footer ("", BUTTON_LOGOUT + BUTTON_DEBUG, cgi);
    }

  string_free (cmd);
  cgi_free (cgi);
  closelog ();
  return 0;
}
示例#24
0
文件: noitd.c 项目: easel/reconnoiter
int main(int argc, char **argv) {
  int fd, lockfd;
  char conf_str[1024];
  char lockfile[PATH_MAX];
  char user[32], group[32];
  char *trace_dir = NULL;

  parse_clargs(argc, argv);

  /* First initialize logging, so we can log errors */
  noit_log_init();
  noit_log_stream_add_stream(noit_debug, noit_stderr);
  noit_log_stream_add_stream(noit_error, noit_stderr);

  /* Next load the configs */
  noit_conf_init(APPNAME);
  if(noit_conf_load(config_file) == -1) {
    fprintf(stderr, "Cannot load config: '%s'\n", config_file);
    exit(-1);
  }

  /* Reinitialize the logging system now that we have a config */
  snprintf(user, sizeof(user), "%d", getuid());
  snprintf(group, sizeof(group), "%d", getgid());
  if(noit_security_usergroup(droptouser, droptogroup, noit_true)) {
    noitL(noit_stderr, "Failed to drop privileges, exiting.\n");
    exit(-1);
  }
  noit_conf_log_init(APPNAME);
  cli_log_switches();
  if(noit_security_usergroup(user, group, noit_true)) {
    noitL(noit_stderr, "Failed to regain privileges, exiting.\n");
    exit(-1);
  }
  if(debug)
    noit_debug->enabled = 1;

  if(!glider) noit_conf_get_string(NULL, "/" APPNAME "/watchdog/@glider", &glider);
  noit_watchdog_glider(glider);
  noit_conf_get_string(NULL, "/" APPNAME "/watchdog/@tracedir", &trace_dir);
  if(trace_dir) noit_watchdog_glider_trace_dir(trace_dir);

  /* Lastly, run through all other system inits */
  if(!noit_conf_get_stringbuf(NULL, "/" APPNAME "/eventer/@implementation",
                              conf_str, sizeof(conf_str))) {
    noitL(noit_stderr, "Cannot find '%s' in configuration\n",
          "/" APPNAME "/eventer/@implementation");
    exit(-1);
  }
  if(eventer_choose(conf_str) == -1) {
    noitL(noit_stderr, "Cannot choose eventer %s\n", conf_str);
    exit(-1);
  }
  if(configure_eventer() != 0) {
    noitL(noit_stderr, "Cannot configure eventer\n");
    exit(-1);
  }

  noit_watchdog_prefork_init();

  if(chdir("/") != 0) {
    noitL(noit_stderr, "Failed chdir(\"/\"): %s\n", strerror(errno));
    exit(-1);
  }

  /* Acquire the lock so that we can throw an error if it doesn't work.
   * If we've started -D, we'll have the lock.
   * If not we will daemon and must reacquire the lock.
   */
  lockfd = -1;
  lockfile[0] = '\0';
  if(noit_conf_get_stringbuf(NULL, "/" APPNAME "/@lockfile",
                             lockfile, sizeof(lockfile))) {
    if((lockfd = noit_lockfile_acquire(lockfile)) < 0) {
      noitL(noit_stderr, "Failed to acquire lock: %s\n", lockfile);
      exit(-1);
    }
  }

  if(foreground) return child_main();

  /* This isn't inherited across forks... */
  if(lockfd >= 0) noit_lockfile_release(lockfd);

  fd = open("/dev/null", O_RDWR);
  dup2(fd, STDIN_FILENO);
  dup2(fd, STDOUT_FILENO);
  dup2(fd, STDERR_FILENO);
  if(fork()) exit(0);
  setsid();
  if(fork()) exit(0);

  /* Reacquire the lock */
  if(*lockfile) {
    if(noit_lockfile_acquire(lockfile) < 0) {
      noitL(noit_stderr, "Failed to acquire lock: %s\n", lockfile);
      exit(-1);
    }
  }

  signal(SIGHUP, SIG_IGN);
  return noit_watchdog_start_child("noitd", child_main, 0);
}
示例#25
0
/*! \brief Save the schematic file
 *  \par Function Description
 *  This function saves the current schematic file in the toplevel object.
 *
 *  \param [in,out] toplevel  The TOPLEVEL object containing the schematic.
 *  \param [in]      filename  The file name to save the schematic to.
 *  \return 1 on success, 0 on failure.
 */
int f_save(TOPLEVEL *toplevel, const char *filename)
{
  gchar *backup_filename;
  gchar *real_filename;
  gchar *only_filename;
  gchar *dirname;
  mode_t saved_umask, mask;
  struct stat st;

  /* Get the real filename and file permissions */
  real_filename = follow_symlinks (filename, NULL);

  if (real_filename == NULL) {
    s_log_message (_("Can't get the real filename of %s."), filename);
    return 0;
  }
  
  /* Get the directory in which the real filename lives */
  dirname = g_path_get_dirname (real_filename);
  only_filename = g_path_get_basename(real_filename);  

  /* Do a backup if it's not an undo file backup and it was never saved. */
  if (toplevel->page_current->saved_since_first_loaded == 0) {
    if ( (g_file_test (real_filename, G_FILE_TEST_EXISTS)) && 
	 (!g_file_test(real_filename, G_FILE_TEST_IS_DIR)) )
    {
      backup_filename = g_strdup_printf("%s%c%s~", dirname, 
					G_DIR_SEPARATOR, only_filename);

      /* Make the backup file read-write before saving a new one */
      if ( g_file_test (backup_filename, G_FILE_TEST_EXISTS) && 
	   (! g_file_test (backup_filename, G_FILE_TEST_IS_DIR))) {
	if (chmod(backup_filename, S_IREAD|S_IWRITE) != 0) {
	  s_log_message (_("Could NOT set previous backup file [%s] read-write\n"),
			 backup_filename);
	}
      }
	
      if (rename(real_filename, backup_filename) != 0) {
	s_log_message (_("Can't save backup file: %s."), backup_filename);
      }
      else {
	/* Make the backup file readonly so a 'rm *' command will ask 
	   the user before deleting it */
	saved_umask = umask(0);
	mask = (S_IWRITE|S_IWGRP|S_IEXEC|S_IXGRP|S_IXOTH);
	mask = (~mask)&0777;
	mask &= ((~saved_umask) & 0777);
	if (chmod(backup_filename, mask) != 0) {
	  s_log_message (_("Could NOT set backup file [%s] readonly\n"),
                         backup_filename);
	}
	umask(saved_umask);
      }

      g_free(backup_filename);
    }
  }
    /* If there is not an existing file with that name, compute the
     * permissions and uid/gid that we will use for the newly-created file.
     */
       
  if (stat (real_filename, &st) != 0)
  {
    struct stat dir_st;
    int result;
    
    /* Use default permissions */
    saved_umask = umask(0);
    st.st_mode = 0666 & ~saved_umask;
    umask(saved_umask);
#ifdef HAVE_CHOWN
    st.st_uid = getuid ();
    
    result = stat (dirname, &dir_st);
    
    if (result == 0 && (dir_st.st_mode & S_ISGID))
	  st.st_gid = dir_st.st_gid;
    else
    st.st_gid = getgid ();
#endif /* HAVE_CHOWN */
  }
  g_free (dirname);
  g_free (only_filename);
  
  if (o_save(toplevel, real_filename)) {

    toplevel->page_current->saved_since_first_loaded = 1;

    /* Reset the last saved timer */
    g_get_current_time (&toplevel->page_current->last_load_or_save_time);
    toplevel->page_current->ops_since_last_backup = 0;
    toplevel->page_current->do_autosave_backup = 0;

    /* Restore permissions. */
    chmod (real_filename, st.st_mode);
#ifdef HAVE_CHOWN
    if (chown (real_filename, st.st_uid, st.st_gid)) {
      /* Error occured with chown */
#warning FIXME: What do we do?
    }
#endif

    g_free (real_filename);
    return 1;
  }
  else {
    g_free (real_filename);
    return 0;
  }
}
示例#26
0
文件: fileapi.cpp 项目: 4nkh/rhodes
RHO_GLOBAL void JNICALL Java_com_rhomobile_rhodes_file_RhoFileApi_nativeInit
  (JNIEnv *env, jclass)
{
    clsFileApi = getJNIClass(RHODES_JAVA_CLASS_RHOFILEAPI);
    if (!clsFileApi) return;
    midCopy = getJNIClassStaticMethod(env, clsFileApi, "copy", "(Ljava/lang/String;)Z");
    if (!midCopy) return;
    midOpen = getJNIClassStaticMethod(env, clsFileApi, "openInPackage", "(Ljava/lang/String;)Ljava/io/InputStream;");
    if (!midOpen) return;
    midClose = getJNIClassStaticMethod(env, clsFileApi, "close", "(Ljava/io/InputStream;)V");
    if (!midClose) return;
    midRead = getJNIClassStaticMethod(env, clsFileApi, "read", "(Ljava/io/InputStream;[B)I");
    if (!midRead) return;
    midSeek = getJNIClassStaticMethod(env, clsFileApi, "seek", "(Ljava/io/InputStream;I)V");
    if (!midSeek) return;
    midGetChildren = getJNIClassStaticMethod(env, clsFileApi, "getChildren", "(Ljava/lang/String;)[Ljava/lang/String;");
    if (!midGetChildren) return;
    midReloadStatTable = getJNIClassStaticMethod(env, clsFileApi, "reloadStatTable", "()V");
    if (!midReloadStatTable) return;

    const char *libc = "/system/lib/libc.so";
    void *pc = dlopen(libc, RTLD_LAZY);
    __sflags = (func_sflags_t)dlsym(pc, "__sflags");
    __sfp = (func_sfp_t)dlsym(pc, "__sfp");
    real_access = (func_access_t)dlsym(pc, "access");
    real_close = (func_close_t)dlsym(pc, "close");
    real_dup = (func_dup_t)dlsym(pc, "dup");
    real_dup2 = (func_dup2_t)dlsym(pc, "dup2");
    real_chown = (func_chown_t)dlsym(pc, "chown");
    real_fchown = (func_fchown_t)dlsym(pc, "fchown");
    real_lchown = (func_lchown_t)dlsym(pc, "lchown");
    real_link = (func_link_t)dlsym(pc, "link");
    real_symlink = (func_symlink_t)dlsym(pc, "symlink");
    real_readlink = (func_readlink_t)dlsym(pc, "readlink");
    real_mkdir = (func_mkdir_t)dlsym(pc, "mkdir");
    real_fchdir = (func_fchdir_t)dlsym(pc, "fchdir");
    real_fcntl = (func_fcntl_t)dlsym(pc, "fcntl");
    real_fsync = (func_fsync_t)dlsym(pc, "fsync");
    real_fdatasync = (func_fdatasync_t)dlsym(pc, "fdatasync");

    if (real_fdatasync == NULL) {
        //Android 2.1 have no fdatasync call. Use fsync instead
        RHO_LOG("No fdatasync implementation, using fsync instead");
        real_fdatasync = real_fsync;
    }

    real_flock = (func_flock_t)dlsym(pc, "flock");
    real_fstat = (func_fstat_t)dlsym(pc, "fstat");
    real_ftruncate = (func_ftruncate_t)dlsym(pc, "ftruncate");
    real_lseek = (func_lseek_t)dlsym(pc, "lseek");
    real_lseek64 = (func_lseek64_t)dlsym(pc, "lseek64");
    real_lstat = (func_lstat_t)dlsym(pc, "lstat");
    real_open = (func_open_t)dlsym(pc, "open");
    real_read = (func_read_t)dlsym(pc, "read");
    real_select = (func_select_t)dlsym(pc, "select");
    real_stat = (func_stat_t)dlsym(pc, "stat");
    real_unlink = (func_unlink_t)dlsym(pc, "unlink");
    real_write = (func_write_t)dlsym(pc, "write");
    real_getdents = (func_getdents_t)dlsym(pc, "getdents");
    real_rmdir = (func_rmdir_t)dlsym(pc, "rmdir");
    real_opendir = (func_opendir_t)dlsym(pc, "opendir");
    real_fdopendir = (func_fdopendir_t)dlsym(pc, "fdopendir");
    real_readdir = (func_readdir_t)dlsym(pc, "readdir");
    real_readdir_r = (func_readdir_r_t)dlsym(pc, "readdir_r");
    real_closedir = (func_closedir_t)dlsym(pc, "closedir");
    real_rewinddir = (func_rewinddir_t)dlsym(pc, "rewinddir");
    real_dirfd = (func_dirfd_t)dlsym(pc, "dirfd");
    real_scandir = (func_scandir_t)dlsym(pc, "scandir");
    dlclose(pc);

    // This is just to get typical stat of file
    std::string librhodes = rho_root_path() + "../lib/librhodes.so";
    RHO_LOG("Native library: %s", librhodes.c_str());

    real_stat(librhodes.c_str(), &librhodes_st);
    librhodes_st.st_mode = S_IFREG|S_IRWXU;
    librhodes_st.st_nlink = 1;
    librhodes_st.st_uid = getuid();
    librhodes_st.st_gid = getgid();

    RHO_LOG("Library stat (mode: %d, uid: %d, gid: %d)", librhodes_st.st_mode, librhodes_st.st_uid, librhodes_st.st_gid);
}
示例#27
0
/*
=================
Sys_GetGameAPI

Loads the game dll
=================
*/
void *Sys_GetGameAPI (void *parms)
{
	void	*(*GetGameAPI) (void *);
	
	FILE	*fp;
	char	name[MAX_OSPATH];
	char	*path;
	char	*str_p;
#if defined __i386__
	const char *gamename = "gamei386.so";
#elif defined __x86_64__
	const char *gamename = "gamex86_64.so";
#elif defined __alpha__
	const char *gamename = "gameaxp.so";
#elif defined __powerpc__
	const char *gamename = "gameppc.so";
#elif defined __sparc__
	const char *gamename = "gamesparc.so";
#elif defined __gcw__
	const char *gamename = "gamegcw.so";
#else
	const char *gamename = "gamegcw.so";
#endif

	setreuid(getuid(), getuid());
	setegid(getgid());

	if (game_library)
		Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame");

	Com_Printf("------- Loading %s -------\n", gamename);

	// now run through the search paths
	path = NULL;
	while (1)
	{
		path = FS_NextPath (path);
		if (!path)
		{
			snprintf(name, MAX_OSPATH, "%s/%s", getenv("PWD"), gamename);

			printf("%s\n" ,name);
			fp = fopen(name, "rb");
			if (fp == NULL)
				return NULL;		// couldn't find one anywhere
			fclose(fp);	
		}
		else
		{
			snprintf (name, MAX_OSPATH, "%s/%s", path, gamename);

			/* skip it if it just doesn't exist */
			fp = fopen(name, "rb");
			if (fp == NULL)
				continue;
			fclose(fp);
		}
		
		game_library = dlopen (name, RTLD_NOW);
		if (game_library)
		{
			Com_MDPrintf ("LoadLibrary (%s)\n",name);
			break;
		} 
		else 
		{
			Com_Printf ("LoadLibrary (%s):", name);
			
			path = dlerror();
			str_p = strchr(path, ':'); // skip the path (already shown)
			if (str_p == NULL)
				str_p = path;
			else
				str_p++;
				
			Com_Printf ("%s\n", str_p);
			
			return NULL; 
		}
	}

	GetGameAPI = (void *)dlsym (game_library, "GetGameAPI");

	if (!GetGameAPI)
	{
		Sys_UnloadGame ();		
		return NULL;
	}

	return GetGameAPI (parms);
}
示例#28
0
void selfCheck() {
    // 'access' function tests based on uid, 'eaccess' ignores ACLs, have to set uid/gid.
    setgid(xware_gid);
    setuid(xware_uid); // uid after gid, otherwise fail on setting gid.

    if (verbose_mode) {
        printf("# [DEBUG] uid=%d, euid=%d, xware_uid=%d\n", getuid(), geteuid(), xware_uid);
    }
    // check uid
    if (getuid() != xware_uid) {
        fprintf(stderr, "Not running as xware user.\n");
        exit(EXIT_FAILURE);
    }

    // check euid
    if (geteuid() != xware_uid) {
        fprintf(stderr, "Not running as xware user.\n");
        exit(EXIT_FAILURE);
    }


    if (verbose_mode) {
        printf("# [DEBUG] gid=%d, egid=%d, xware_gid=%d\n", getgid(), getegid(), xware_gid);
    }
    // check gid
    if (getgid() != xware_gid) {
        fprintf(stderr, "Not running as xware group.\n");
        exit(EXIT_FAILURE);
    }
    // check egid
    if (getegid() != xware_gid) {
        fprintf(stderr, "Not running as xware group.\n");
        exit(EXIT_FAILURE);
    }

    // check supplementary groups
    nGrpList2 = getgroups(NGROUPS_MAX, grpList2);
    if (nGrpList2 == -1) {
        perror("getgroups");
        exit(EXIT_FAILURE);
    }
    if (verbose_mode) {
        printf("# [DEBUG] xware is a member of: ");
        int i = 0;
        for (i = 0; i < nGrpList1; i++) {
            printf("%d\t", grpList1[i]);
        }
        printf("\n");

        printf("# [DEBUG] post-setgroups, calling process groups: ");
        for (i = 0; i < nGrpList2; i++) {
            printf("%d\t", grpList2[i]);
        }
        printf("\n");
    }
    if ( (nGrpList1 != nGrpList2) ||
         (memcmp(grpList1, grpList2, nGrpList2 * sizeof(gid_t)) != 0)) {
        fprintf(stderr, "Failed to clear supplementary groups.\n");
        exit(EXIT_FAILURE);
    }
}
示例#29
0
文件: getuid.c 项目: lufb/code
int main(void)
{
	printf("uid = %d, gid = %d\n", getuid(), getgid());
	
	return 0;
}
示例#30
0
static void regain_privilege(void) 
{
    setegid(getgid());
    seteuid(getuid());
}