- struct sockaddr_un addr;
- char *lastslash;
-
- if(strlen(controlsocketname) >= sizeof addr.sun_path) {
- logger(LOG_ERR, "Control socket filename too long!");
- goto bail;
- }
-
- memset(&addr, 0, sizeof addr);
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, controlsocketname, sizeof addr.sun_path - 1);
-
- control_socket = socket(PF_UNIX, SOCK_STREAM, 0);
-
- if(control_socket < 0) {
- logger(LOG_ERR, "Creating UNIX socket failed: %s", strerror(errno));
- goto bail;
- }
-
- /*
- * Restrict connections to our control socket by ensuring the parent
- * directory can be traversed only by root. Note this is not totally
- * race-free unless all ancestors are writable only by trusted users,
- * which we don't verify.
- */
-
- struct stat statbuf;
- lastslash = strrchr(controlsocketname, '/');
- if(lastslash != NULL) {
- *lastslash = 0; /* temporarily change controlsocketname to be dir */
- if(mkdir(controlsocketname, 0700) < 0 && errno != EEXIST) {
- logger(LOG_ERR, "Unable to create control socket directory %s: %s", controlsocketname, strerror(errno));
- *lastslash = '/';
- goto bail;
- }
-
- result = stat(controlsocketname, &statbuf);
- *lastslash = '/';
- } else
- result = stat(".", &statbuf);
-
- if(result < 0) {
- logger(LOG_ERR, "Examining control socket directory failed: %s", strerror(errno));
- goto bail;
- }
-
- if(statbuf.st_uid != 0 || (statbuf.st_mode & S_IXOTH) != 0 || (statbuf.st_gid != 0 && (statbuf.st_mode & S_IXGRP)) != 0) {
- logger(LOG_ERR, "Control socket directory ownership/permissions insecure.");
- goto bail;
- }