On Fri, Feb 07, 2003 at 12:23:30PM +1100, Martin Pool wrote: > The bug apparently came in Andrew Bartlett's merge in 1.45; the > provenance of it I don't know. (TNG?) This patch ought to be applied > to 2.2, HEAD, 3.0, and APPL_HEAD. > > Tim, how's this patch?
How about this - I've collapsed the two error exits into one. Tim. Index: lib/util_sock.c =================================================================== RCS file: /data/cvs/samba/source/lib/util_sock.c,v retrieving revision 1.75 diff -u -r1.75 util_sock.c --- lib/util_sock.c 9 Jan 2003 06:58:07 -0000 1.75 +++ lib/util_sock.c 7 Feb 2003 04:51:10 -0000 @@ -885,13 +885,18 @@ } -/******************************************************************* - Create protected unix domain socket. - - some unixen cannot set permissions on a ux-dom-sock, so we - have to make sure that the directory contains the protection - permissions, instead. - ******************************************************************/ +/** + * Create protected unix domain socket. + * + * Some unixen cannot set permissions on a ux-dom-sock, so we have to + * make sure that the directory contains the protection permissions, + * instead. + * + * It must be possible to access the socket from unprivileged + * programs, even if the daemon is started with a restrictive umask. + * Therefore is is temporarily removed while creating the directory + * and socket. + **/ int create_pipe_sock(const char *socket_dir, const char *socket_name, mode_t dir_perms) @@ -899,60 +904,50 @@ #ifdef HAVE_UNIXSOCKET struct sockaddr_un sunaddr; struct stat st; - int sock; + int sock = -1; mode_t old_umask; pstring path; + old_umask = umask(0); + /* Create the socket directory or reuse the existing one */ if (lstat(socket_dir, &st) == -1) { - if (errno == ENOENT) { - - /* Create directory */ - if (mkdir(socket_dir, dir_perms) == -1) { DEBUG(0, ("error creating socket directory " "%s: %s\n", socket_dir, strerror(errno))); - return -1; + goto error; } - } else { - DEBUG(0, ("lstat failed on socket directory %s: %s\n", socket_dir, strerror(errno))); - return -1; + goto error; } - } else { - /* Check ownership and permission on existing directory */ - if (!S_ISDIR(st.st_mode)) { DEBUG(0, ("socket directory %s isn't a directory\n", socket_dir)); - return -1; + goto error; } if ((st.st_uid != sec_initial_uid()) || ((st.st_mode & 0777) != dir_perms)) { DEBUG(0, ("invalid permissions on socket directory " "%s\n", socket_dir)); - return -1; + goto error; } } /* Create the socket file */ - old_umask = umask(0); - sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock == -1) { perror("socket"); - umask(old_umask); - return -1; + goto error; } snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name); @@ -966,25 +961,26 @@ DEBUG(0, ("bind failed on pipe socket %s: %s\n", path, strerror(errno))); - close(sock); - umask(old_umask); - return -1; + goto error; } if (listen(sock, 5) == -1) { DEBUG(0, ("listen failed on pipe socket %s: %s\n", path, strerror(errno))); - close(sock); - umask(old_umask); - return -1; + goto error; } umask(old_umask); - - /* Success! */ - - return sock; + return sock; /* success */ + +error: + if (sock != -1) + close(sock); + + umask(old_umask); + return -1; + #else DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n")); return -1;