Пример #1
0
static int
unlink_dir(const char *src)
{
	struct stat sb;

	if (lstat(src, &sb)) {
		perror(src);
		return (1);
	}
	if (S_ISDIR(sb.st_mode)) {
		DIR *dirp;
		struct dirent *dp;

		/* allow read and write access always */
		chmod(src, (sb.st_mode | S_IRUSR | S_IWUSR) & 07777);

		dirp = opendir(src);
		if (dirp == NULL) {
			perror(src);
			return (1);
		}
		while ((dp = readdir(dirp)) != NULL) {
			char *f;

			if (strcmp(dp->d_name, ".") == 0
			    || strcmp(dp->d_name, "..") == 0 || dp->d_ino == 0)
				continue;

			GFARM_MALLOC_ARRAY(f, 
				strlen(src) + 1 + strlen(dp->d_name) + 1);
			if (f == NULL) {
				print_errmsg(dp->d_name, NULL,
					"not enough memory");
				return (1);
			}
			strcpy(f, src);
			strcat(f, "/");
			strcat(f, dp->d_name);

			(void)unlink_dir(f);

			free(f);
		}
		closedir(dirp);
		if (rmdir(src)) {
			perror(src);
			return (1);
		}
	}
	else if (unlink(src)) {
		/* if 'src' is not a directory, try to unlink. */
		perror(src);
		return (1);
	}
	return (0);
}
Пример #2
0
static void
delete_invalid_file_or_directory(char *pathname)
{
	if (delete_invalid_file) {
		if (unlink_dir(pathname) == 0)
			print_msg(pathname, NULL, "deleted");
		else
			print_errmsg(pathname, NULL, "cannot delete");
	}
}
Пример #3
0
static void
delete_invalid_file_or_directory(char *pathname)
{
	if (delete_invalid_file) {
		if (unlink_dir(pathname) == 0)
			printf("%s on %s: deleted\n",
			       pathname, gfarm_host_get_self_name());
		else
			print_errmsg(pathname, "cannot delete");
	}
}
Пример #4
0
static int
unlink_dir(const char *src)
{
	struct stat sb;

	if (lstat(src, &sb)) {
		perror(src);
		return (1);
	}
	if (S_ISDIR(sb.st_mode)) {
		DIR *dirp;
		struct dirent *dp;

		dirp = opendir(src);
		if (dirp == NULL) {
			perror(src);
			return (1);
		}
		while ((dp = readdir(dirp)) != NULL) {
			char *f;

			if (strcmp(dp->d_name, ".") == 0
			    || strcmp(dp->d_name, "..") == 0 || dp->d_ino == 0)
				continue;

			f = malloc(strlen(src) + 1 + strlen(dp->d_name) + 1);
			if (f == NULL) {
				print_errmsg(dp->d_name, "not enough memory");
				return (1);
			}
			strcpy(f, src);
			strcat(f, "/");
			strcat(f, dp->d_name);

			(void)unlink_dir(f);

			free(f);
		}
		closedir(dirp);
		if (rmdir(src)) {
			perror(src);
			return (1);
		}
	}
	else if (unlink(src)) {
		/* if 'src' is not a directory, try to unlink. */
		perror(src);
		return (1);
	}
	return (0);
}
Пример #5
0
static void unlink_dir(const char *path)
{
    DIR *dp;
    char buf[PATH_MAX];

    if ((dp = opendir(path)) != NULL) {
        struct dirent entbuf, *entp;
        while (readdir_r(dp, &entbuf, &entp) == 0 && entp != NULL) {
            if (strcmp(entp->d_name, ".") == 0 || strcmp(entp->d_name, "..") == 0)
                continue;
            snprintf(buf, sizeof(buf), "%s/%s", path, entp->d_name);
            unlink_dir(buf);
        }
        closedir(dp);
    }
    unlink(path);
}
Пример #6
0
__attribute__((noreturn)) static void *daemon_close_notify_thread(void *_close_notify_fd)
{
    int close_notify_fd = (int)((char *)_close_notify_fd - (char *)NULL);
    char b;
    ssize_t r;

Redo:
    r = read(close_notify_fd, &b, 1);
    if (r == -1 && errno == EINTR)
        goto Redo;
    if (r > 0)
        goto Redo;
    /* close or error */

    /* unlink the temporary directory and socket file */
    unlink_dir(dirname(daemon_vars.nb->sun_.sun_path));

    _exit(0);
}
Пример #7
0
int neverbleed_init(neverbleed_t *nb, char *errbuf)
{
    int pipe_fds[2] = {-1, -1}, listen_fd = -1;
    char *tempdir = NULL;

    const RSA_METHOD *default_method = RSA_PKCS1_SSLeay();
    rsa_method.rsa_pub_enc = default_method->rsa_pub_enc;
    rsa_method.rsa_pub_dec = default_method->rsa_pub_dec;
    rsa_method.rsa_verify = default_method->rsa_verify;

    /* setup the daemon */
    if (pipe(pipe_fds) != 0) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "pipe(2) failed:%s", strerror(errno));
        goto Fail;
    }
    fcntl(pipe_fds[1], F_SETFD, O_CLOEXEC);
    if ((tempdir = strdup("/tmp/openssl-privsep.XXXXXX")) == NULL) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "no memory");
        goto Fail;
    }
    if (mkdtemp(tempdir) == NULL) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to create temporary directory under /tmp:%s", strerror(errno));
        goto Fail;
    }
    memset(&nb->sun_, 0, sizeof(nb->sun_));
    nb->sun_.sun_family = AF_UNIX;
    snprintf(nb->sun_.sun_path, sizeof(nb->sun_.sun_path), "%s/_", tempdir);
    RAND_bytes(nb->auth_token, sizeof(nb->auth_token));
    if ((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "socket(2) failed:%s", strerror(errno));
        goto Fail;
    }
    if (bind(listen_fd, (void *)&nb->sun_, sizeof(nb->sun_)) != 0) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to bind to %s:%s", nb->sun_.sun_path, strerror(errno));
        goto Fail;
    }
    if (listen(listen_fd, SOMAXCONN) != 0) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "listen(2) failed:%s", strerror(errno));
        goto Fail;
    }
    switch (fork()) {
    case -1:
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "fork(2) failed:%s", strerror(errno));
        goto Fail;
    case 0:
        close(pipe_fds[1]);
#ifdef __linux__
        prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
#endif
        memcpy(daemon_auth_token, nb->auth_token, NEVERBLEED_AUTH_TOKEN_SIZE);
        daemon_main(listen_fd, pipe_fds[0], tempdir);
        break;
    default:
        break;
    }
    close(listen_fd);
    listen_fd = -1;
    close(pipe_fds[0]);
    pipe_fds[0] = -1;

    /* setup engine */
    if ((nb->engine = ENGINE_new()) == NULL ||
        !ENGINE_set_id(nb->engine, "neverbleed") ||
        !ENGINE_set_name(nb->engine, "privilege separation software engine") ||
        !ENGINE_set_RSA(nb->engine, &rsa_method)) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to initialize the OpenSSL engine");
        goto Fail;
    }
    ENGINE_add(nb->engine);

    /* setup thread key */
    pthread_key_create(&nb->thread_key, dispose_thread_data);

    free(tempdir);
    return 0;
Fail:
    if (pipe_fds[0] != -1)
        close(pipe_fds[0]);
    if (pipe_fds[1] != -1)
        close(pipe_fds[1]);
    if (tempdir != NULL) {
        unlink_dir(tempdir);
        free(tempdir);
    }
    if (listen_fd != -1)
        close(listen_fd);
    if (nb->engine != NULL) {
        ENGINE_free(nb->engine);
        nb->engine = NULL;
    }
    return -1;
}