Skip to content

Commit

Permalink
Merge pull request h2o#5 from h2o/kazuho/change-file-ownership-on-setuid
Browse files Browse the repository at this point in the history
when dropping privileges, change ownership of socket file
  • Loading branch information
kazuho committed Sep 24, 2015
2 parents 8d08a2d + 59ff545 commit 84eaa69
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
27 changes: 21 additions & 6 deletions neverbleed.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,8 @@ static struct {
size_t size;
RSA **keys;
} keys;
unsigned char auth_token[NEVERBLEED_AUTH_TOKEN_SIZE];
} daemon_vars;
neverbleed_t *nb;
} daemon_vars = {{PTHREAD_MUTEX_INITIALIZER}};

static RSA *daemon_get_rsa(size_t key_index)
{
Expand Down Expand Up @@ -614,14 +614,15 @@ static int load_key_stub(struct expbuf_t *buf)
return 0;
}

int neverbleed_setuidgid(neverbleed_t *nb, const char *user)
int neverbleed_setuidgid(neverbleed_t *nb, const char *user, int change_socket_ownership)
{
struct st_neverbleed_thread_data_t *thdata = get_thread_data(nb);
struct expbuf_t buf = {};
size_t ret;

expbuf_push_str(&buf, "setuidgid");
expbuf_push_str(&buf, user);
expbuf_push_num(&buf, change_socket_ownership);
if (expbuf_write(&buf, thdata->fd) != 0)
dief(errno != 0 ? "write error" : "connection closed by daemon");
expbuf_dispose(&buf);
Expand All @@ -640,11 +641,12 @@ int neverbleed_setuidgid(neverbleed_t *nb, const char *user)
static int setuidgid_stub(struct expbuf_t *buf)
{
const char *user;
size_t change_socket_ownership;
struct passwd pwbuf, *pw;
char pwstrbuf[65536]; /* should be large enough */
int ret = -1;

if ((user = expbuf_shift_str(buf)) == NULL) {
if ((user = expbuf_shift_str(buf)) == NULL || expbuf_shift_num(buf, &change_socket_ownership) != 0) {
errno = 0;
warnf("%s: failed to parse request", __FUNCTION__);
return -1;
Expand All @@ -659,6 +661,19 @@ static int setuidgid_stub(struct expbuf_t *buf)
warnf("%s: failed to obtain information of user:%s", __FUNCTION__, user);
goto Respond;
}

if (change_socket_ownership) {
char *fn = strdup(daemon_vars.nb->sun_.sun_path);
if (fn == NULL)
dief("no memory");
if (chown(fn, pw->pw_uid, pw->pw_gid) != 0)
dief("chown failed");
/* change the dir ownership as well */
*strrchr(fn, '/') = '\0';
if (chown(fn, pw->pw_uid, pw->pw_gid) != 0)
dief("chown failed");
}

/* setuidgid */
if (setgid(pw->pw_gid) != 0) {
warnf("%s: setgid(%d) failed", __FUNCTION__, (int)pw->pw_gid);
Expand Down Expand Up @@ -707,7 +722,7 @@ static void *daemon_conn_thread(void *_sock_fd)
warnf("failed to receive authencication token from client");
goto Exit;
}
if (memcmp(auth_token, daemon_vars.auth_token, NEVERBLEED_AUTH_TOKEN_SIZE) != 0) {
if (memcmp(auth_token, daemon_vars.nb->auth_token, NEVERBLEED_AUTH_TOKEN_SIZE) != 0) {
warnf("client authentication failed");
goto Exit;
}
Expand Down Expand Up @@ -853,7 +868,7 @@ int neverbleed_init(neverbleed_t *nb, char *errbuf)
#ifdef __linux__
prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
#endif
memcpy(daemon_vars.auth_token, nb->auth_token, NEVERBLEED_AUTH_TOKEN_SIZE);
daemon_vars.nb = nb;
daemon_main(listen_fd, pipe_fds[0], tempdir);
break;
default:
Expand Down
4 changes: 2 additions & 2 deletions neverbleed.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ int neverbleed_init(neverbleed_t *nb, char *errbuf);
*/
int neverbleed_load_private_key_file(neverbleed_t *nb, SSL_CTX *ctx, const char *fn, char *errbuf);
/**
* setuidgid
* setuidgid (also changes the file permissions so that `user` can connect to the daemon, if change_socket_ownership is non-zero)
*/
int neverbleed_setuidgid(neverbleed_t *nb, const char *user);
int neverbleed_setuidgid(neverbleed_t *nb, const char *user, int change_socket_ownership);

#ifdef __cplusplus
}
Expand Down

0 comments on commit 84eaa69

Please sign in to comment.