int zuluCryptCanOpenPathForReading( const char * path,uid_t uid ) { return path_is_accessible( path,uid,ZULUCRYPTread ) ; }
int zuluCryptCanOpenPathForWriting( const char * path,uid_t uid ) { return path_is_accessible( path,uid,ZULUCRYPTwrite ) ; }
static void _check_auth_client_dir (const char *dir, int got_force) { #if defined(AUTH_METHOD_RECVFD_MKFIFO) || defined(AUTH_METHOD_RECVFD_MKNOD) int got_symlink; struct stat st; int n; char dirdir [PATH_MAX]; char ebuf [1024]; if ((dir == NULL) || (*dir == '\0')) { log_err (EMUNGE_SNAFU, LOG_ERR, "The auth client dir name is undefined"); } /* Check directory permissions and whatnot. */ got_symlink = (lstat (dir, &st) == 0) ? S_ISLNK (st.st_mode) : 0; if (stat (dir, &st) < 0) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to check auth client dir \"%s\"", dir); } if (!S_ISDIR (st.st_mode) || got_symlink) { if (!got_force || !got_symlink) log_err (EMUNGE_SNAFU, LOG_ERR, "The auth client dir is insecure: " "\"%s\" must be a directory", dir); else log_msg (LOG_WARNING, "The auth client dir is insecure: " "\"%s\" should not be a symlink", dir); } if ((st.st_uid != 0) && (st.st_uid != geteuid ())) { if (!got_force) log_err (EMUNGE_SNAFU, LOG_ERR, "The auth client dir is insecure: " "invalid ownership of \"%s\"", dir); else log_msg (LOG_WARNING, "The auth client dir is insecure: " "invalid ownership of \"%s\"", dir); } if ((st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH | S_ISVTX)) != (S_IWUSR | S_IWGRP | S_IWOTH | S_ISVTX)) { log_err (EMUNGE_SNAFU, LOG_ERR, "The auth client dir is insecure: " "\"%s\" must be writable by all with the sticky bit set", dir); } /* Ensure auth client parent dir is secure against modification by others. */ if (path_dirname (dir, dirdir, sizeof (dirdir)) < 0) { log_err (EMUNGE_SNAFU, LOG_ERR, "Failed to determine dirname of auth client dir \"%s\"", dir); } n = path_is_secure (dirdir, ebuf, sizeof (ebuf)); if (n < 0) { log_err (EMUNGE_SNAFU, LOG_ERR, "Failed to check auth client parent dir \"%s\": %s", dirdir, ebuf); } else if ((n == 0) && (!got_force)) { log_err (EMUNGE_SNAFU, LOG_ERR, "The auth client dir is insecure: %s", ebuf); } else if (n == 0) { log_msg (LOG_WARNING, "The auth client dir is insecure: %s", ebuf); } /* Ensure auth client dir is accessible by all. */ n = path_is_accessible (dir, ebuf, sizeof (ebuf)); if (n < 0) { log_err (EMUNGE_SNAFU, LOG_ERR, "Failed to check auth client dir \"%s\": %s", dir, ebuf); } else if ((n == 0) && (!got_force)) { log_err (EMUNGE_SNAFU, LOG_ERR, "The auth client dir is inaccessible: %s", ebuf); } else if (n == 0) { log_msg (LOG_WARNING, "The auth client dir is inaccessible: %s", ebuf); } #endif /* AUTH_METHOD_RECVFD_MKFIFO || AUTH_METHOD_RECVFD_MKNOD */ return; }
static void _check_auth_server_dir (const char *dir, int got_force) { #if defined(AUTH_METHOD_RECVFD_MKFIFO) || defined(AUTH_METHOD_RECVFD_MKNOD) int got_symlink; struct stat st; int n; char ebuf [1024]; if ((dir == NULL) || (*dir == '\0')) { log_err (EMUNGE_SNAFU, LOG_ERR, "The auth server dir name is undefined"); } /* Check directory permissions and whatnot. */ got_symlink = (lstat (dir, &st) == 0) ? S_ISLNK (st.st_mode) : 0; if (stat (dir, &st) < 0) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to stat auth server dir \"%s\"", dir); } if (!S_ISDIR (st.st_mode) || got_symlink) { if (!got_force || !got_symlink) log_err (EMUNGE_SNAFU, LOG_ERR, "The auth server dir is insecure: " "\"%s\" must be a directory", dir); else log_msg (LOG_WARNING, "The auth server dir is insecure: " "\"%s\" should not be a symlink", dir); } if (st.st_uid != geteuid ()) { log_err (EMUNGE_SNAFU, LOG_ERR, "The auth server dir is insecure: " "\"%s\" must be owned by UID %u", dir, (unsigned) geteuid ()); } if (!(st.st_mode & S_IWUSR)) { log_err (EMUNGE_SNAFU, LOG_ERR, "The auth server dir is insecure: " "\"%s\" must be writable by user", dir); } if (st.st_mode & (S_IRGRP | S_IROTH)) { if (!got_force) log_err (EMUNGE_SNAFU, LOG_ERR, "The auth server dir is insecure: " "\"%s\" should not be readable by group or world", dir); else log_msg (LOG_WARNING, "The auth server dir is insecure: " "\"%s\" should not be readable by group or world", dir); } /* Ensure auth server dir is secure against modification by others. */ n = path_is_secure (dir, ebuf, sizeof (ebuf)); if (n < 0) { log_err (EMUNGE_SNAFU, LOG_ERR, "Failed to check auth server dir \"%s\": %s", dir, ebuf); } else if ((n == 0) && (!got_force)) { log_err (EMUNGE_SNAFU, LOG_ERR, "The auth server dir is insecure: %s", ebuf); } else if (n == 0) { log_msg (LOG_WARNING, "The auth server dir is insecure: %s", ebuf); } /* Ensure auth server dir is accessible by all. */ n = path_is_accessible (dir, ebuf, sizeof (ebuf)); if (n < 0) { log_err (EMUNGE_SNAFU, LOG_ERR, "Failed to check auth server dir \"%s\": %s", dir, ebuf); } else if ((n == 0) && (!got_force)) { log_err (EMUNGE_SNAFU, LOG_ERR, "The auth server dir is inaccessible: %s", ebuf); } else if (n == 0) { log_msg (LOG_WARNING, "The auth server dir is inaccessible: %s", ebuf); } #endif /* AUTH_METHOD_RECVFD_MKFIFO || AUTH_METHOD_RECVFD_MKNOD */ return; }
static void sock_create (conf_t conf) { char sockdir [PATH_MAX]; char ebuf [1024]; int n; int sd; struct sockaddr_un addr; mode_t mask; int rv; assert (conf != NULL); if ((conf->socket_name == NULL) || (*conf->socket_name == '\0')) { log_err (EMUNGE_SNAFU, LOG_ERR, "MUNGE socket name is undefined"); } /* Ensure socket dir is secure against modification by others. */ if (path_dirname (conf->socket_name, sockdir, sizeof (sockdir)) < 0) { log_err (EMUNGE_SNAFU, LOG_ERR, "Failed to determine dirname of socket \"%s\"", conf->socket_name); } n = path_is_secure (sockdir, ebuf, sizeof (ebuf)); if (n < 0) { log_err (EMUNGE_SNAFU, LOG_ERR, "Failed to check socket dir \"%s\": %s", sockdir, ebuf); } else if ((n == 0) && (!conf->got_force)) { log_err (EMUNGE_SNAFU, LOG_ERR, "Socket is insecure: %s", ebuf); } else if (n == 0) { log_msg (LOG_WARNING, "Socket is insecure: %s", ebuf); } /* Ensure socket dir is accessible by all. */ n = path_is_accessible (sockdir, ebuf, sizeof (ebuf)); if (n < 0) { log_err (EMUNGE_SNAFU, LOG_ERR, "Failed to check socket dir \"%s\": %s", sockdir, ebuf); } else if ((n == 0) && (!conf->got_force)) { log_err (EMUNGE_SNAFU, LOG_ERR, "Socket is inaccessible: %s", ebuf); } else if (n == 0) { log_msg (LOG_WARNING, "Socket is inaccessible: %s", ebuf); } /* Create lockfile for exclusive access to the socket. */ sock_lock (conf); /* * Create socket for communicating with clients. */ if ((sd = socket (PF_UNIX, SOCK_STREAM, 0)) < 0) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to create socket"); } memset (&addr, 0, sizeof (addr)); addr.sun_family = AF_UNIX; n = strlcpy (addr.sun_path, conf->socket_name, sizeof (addr.sun_path)); if (n >= sizeof (addr.sun_path)) { log_err (EMUNGE_SNAFU, LOG_ERR, "Exceeded maximum length of socket pathname"); } /* Ensure socket is accessible by all. */ mask = umask (0); rv = bind (sd, (struct sockaddr *) &addr, sizeof (addr)); umask (mask); if (rv < 0) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to bind \"%s\"", conf->socket_name); } if (listen (sd, MUNGE_SOCKET_BACKLOG) < 0) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to listen on \"%s\"", conf->socket_name); } conf->ld = sd; return; }