sockaddr_in - ¿Cómo crear Unix Domain Socket con permisos específicos en C?
socket tcp udp c++ (3)
Bifurcar, usar umask y pasar el fd es la única forma portátil que se me ocurre. Tener un directorio para el socket es mejor en cualquier caso, por ejemplo, nadie puede eliminar el socket si el directorio no tiene los permisos adecuados, y la creación de direcciones se puede hacer atómicamente.
El mayor problema es que depender de los permisos no es portátil: muchas pilas de sockets derivadas de BSD simplemente ignoran los permisos de los directorios adjuntos y / o el propio socket.
En sistemas GNU / Linux, puede hacerlo llamando a fchmod en el socket fd después de socket () y antes de bind ()
Tengo un código simple, como:
sockaddr_un address;
address.sun_family = AF_UNIX;
strcpy(address.sun_path, path);
unlink(path);
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
bind(fd, (sockaddr*)(&address), sizeof(address));
listen(fd, 100);
Quiero crear atómicamente el archivo de socket de dominio de Unix con permisos específicos, por ejemplo: 0777
. El manual no dice nada sobre permisos de archivos socket con respecto a umask
o lo que sea. Incluso, si umask
sí afecta el archivo socket, entonces no es una forma atómica: en un programa de subprocesos múltiples.
Espero que haya una manera de lograr mi objetivo sin utilizar la sincronización de las llamadas a umask()
.
Otra solución es crear un directorio con los permisos deseados y luego crear el socket dentro de él (código de ejemplo sin tener en cuenta la comprobación de errores y los desbordamientos del búfer):
// Create a directory with the proper permissions
mkdir(path, 0700);
// Append the name of the socket
strcat(path, "/socket_name");
// Create the socket normally
sockaddr_un address;
address.sun_family = AF_UNIX;
strcpy(address.sun_path, path);
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
bind(fd, (sockaddr*)(&address), sizeof(address));
listen(fd, 100);
Tuve la mejor suerte usando chmod () (NO fchmod) usando el nombre de archivo para el socket del dominio Unix después de llamar a socket (), bind (), pero antes de llamar a listen ().
int return_value;
const char *sock_path;
struct sockaddr_un local;
sock_path = "/tmp/mysocket";
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1)
{
perror("socket");
exit(-1);
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, sock_path);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
bind(sockfd, (struct sockaddr *)&local, len);
chmod(sock_path, 0777);
retval = listen(sockfd, BACKLOG);
if (retval == -1)
{
perror("listen");
exit(-1);
}
. . . . .