|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* Amanda, The Advanced Maryland Automatic Network Disk Archiver
|
|
Packit Service |
392537 |
* Copyright (c) 2016-2016 Carbonite, Inc. All Rights Reserved.
|
|
Packit Service |
392537 |
* All Rights Reserved.
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
Packit Service |
392537 |
* documentation for any purpose is hereby granted without fee, provided that
|
|
Packit Service |
392537 |
* the above copyright notice appear in all copies and that both that
|
|
Packit Service |
392537 |
* copyright notice and this permission notice appear in supporting
|
|
Packit Service |
392537 |
* documentation, and that the name of U.M. not be used in advertising or
|
|
Packit Service |
392537 |
* publicity pertaining to distribution of the software without specific,
|
|
Packit Service |
392537 |
* written prior permission. U.M. makes no representations about the
|
|
Packit Service |
392537 |
* suitability of this software for any purpose. It is provided "as is"
|
|
Packit Service |
392537 |
* without express or implied warranty.
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
|
Packit Service |
392537 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
|
|
Packit Service |
392537 |
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
Packit Service |
392537 |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
Packit Service |
392537 |
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
Packit Service |
392537 |
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* Authors: the Amanda Development Team. Its members are listed in a
|
|
Packit Service |
392537 |
* file named AUTHORS, in the root directory of this distribution.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#include <config.h>
|
|
Packit Service |
392537 |
#include <sys/types.h>
|
|
Packit Service |
392537 |
#include <netinet/in.h>
|
|
Packit Service |
392537 |
#include "sockaddr-util.h"
|
|
Packit Service |
392537 |
#include <sys/socket.h>
|
|
Packit Service |
392537 |
#include <errno.h>
|
|
Packit Service |
392537 |
#include <stdio.h>
|
|
Packit Service |
392537 |
#include <string.h>
|
|
Packit Service |
392537 |
#include <unistd.h>
|
|
Packit Service |
392537 |
#include <stdlib.h>
|
|
Packit Service |
392537 |
#include "security-file.h"
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
main(
|
|
Packit Service |
392537 |
int argc,
|
|
Packit Service |
392537 |
char ** argv)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
int s;
|
|
Packit Service |
392537 |
int r;
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
struct msghdr msg;
|
|
Packit Service |
392537 |
struct msghdr msg_socket;
|
|
Packit Service |
392537 |
struct msghdr msg_ambind_data;
|
|
Packit Service |
392537 |
struct cmsghdr *cmsg;
|
|
Packit Service |
392537 |
char cmsg_socket[CMSG_SPACE(sizeof(s))];
|
|
Packit Service |
392537 |
char cmsgbuf[CMSG_SPACE(sizeof(s))];
|
|
Packit Service |
392537 |
ambind_t ambind;
|
|
Packit Service |
392537 |
struct iovec iov[2];
|
|
Packit Service |
392537 |
int sockfd;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (argc < 2) {
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
sockfd = atoi(argv[1]);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
do {
|
|
Packit Service |
392537 |
struct timeval timeout = { 5, 0 };
|
|
Packit Service |
392537 |
fd_set readSet;
|
|
Packit Service |
392537 |
FD_ZERO(&readSet);
|
|
Packit Service |
392537 |
FD_SET(sockfd, &readSet);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
rc = select(sockfd+1, &readSet, NULL, NULL, &timeout);
|
|
Packit Service |
392537 |
} while (rc < 0 && errno == EINTR);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (rc <= 0) {
|
|
Packit Service |
392537 |
fprintf(stderr, "ambind: select failed: %s\n", strerror(errno));
|
|
Packit Service |
392537 |
shutdown(sockfd, SHUT_RDWR);
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
// read the message socket msg
|
|
Packit Service |
392537 |
memset(&msg_socket, 0, sizeof(msg_socket));
|
|
Packit Service |
392537 |
msg_socket.msg_control = cmsg_socket;
|
|
Packit Service |
392537 |
msg_socket.msg_controllen = sizeof(cmsg_socket);
|
|
Packit Service |
392537 |
rc = recvmsg(sockfd, &msg_socket, 0);
|
|
Packit Service |
392537 |
if (rc == -1) {
|
|
Packit Service |
392537 |
fprintf(stderr, "ambind: first recvmsg failed: %s\n", strerror(errno));
|
|
Packit Service |
392537 |
exit(1);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
cmsg = CMSG_FIRSTHDR(&msg_socket);
|
|
Packit Service |
392537 |
if (cmsg == NULL || cmsg -> cmsg_type != SCM_RIGHTS) {
|
|
Packit Service |
392537 |
fprintf(stderr, "ambind: The first control structure contains no file descriptor.\n");
|
|
Packit Service |
392537 |
exit(2);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
memcpy(&s, CMSG_DATA(cmsg), sizeof(s));
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
do {
|
|
Packit Service |
392537 |
struct timeval timeout = { 5, 0 };
|
|
Packit Service |
392537 |
fd_set readSet;
|
|
Packit Service |
392537 |
FD_ZERO(&readSet);
|
|
Packit Service |
392537 |
FD_SET(sockfd, &readSet);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
rc = select(sockfd+1, &readSet, NULL, NULL, &timeout);
|
|
Packit Service |
392537 |
} while (rc < 0 && errno == EINTR);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (rc <= 0) {
|
|
Packit Service |
392537 |
fprintf(stderr, "ambind: select failed: %s\n", strerror(errno));
|
|
Packit Service |
392537 |
shutdown(sockfd, SHUT_RDWR);
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
// read the ambind msg
|
|
Packit Service |
392537 |
memset(&msg_ambind_data, 0, sizeof(msg_ambind_data));
|
|
Packit Service |
392537 |
iov[0].iov_base = &ambind;
|
|
Packit Service |
392537 |
iov[0].iov_len = sizeof(ambind_t);
|
|
Packit Service |
392537 |
iov[1].iov_base = NULL;
|
|
Packit Service |
392537 |
iov[1].iov_len = 0;
|
|
Packit Service |
392537 |
msg_ambind_data.msg_iov = iov;
|
|
Packit Service |
392537 |
msg_ambind_data.msg_iovlen = 1;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
rc = recvmsg(sockfd, &msg_ambind_data, 0);
|
|
Packit Service |
392537 |
if (rc == -1) {
|
|
Packit Service |
392537 |
fprintf(stderr, "ambind: second recvmsg failed: %s\n", strerror(errno));
|
|
Packit Service |
392537 |
shutdown(sockfd, SHUT_RDWR);
|
|
Packit Service |
392537 |
exit(2);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
if (rc != sizeof(ambind_t)) {
|
|
Packit Service |
392537 |
fprintf(stderr, "ambind: recvmsg failed: size == %d\n", rc);
|
|
Packit Service |
392537 |
shutdown(sockfd, SHUT_RDWR);
|
|
Packit Service |
392537 |
exit(2);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (!security_allow_bind(s, &ambind.addr)) {
|
|
Packit Service |
392537 |
shutdown(sockfd, SHUT_RDWR);
|
|
Packit Service |
392537 |
exit(2);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
r = bind(s, (struct sockaddr *)&ambind.addr, ambind.socklen);
|
|
Packit Service |
392537 |
if (r != 0) {
|
|
Packit Service |
392537 |
if (errno != EADDRINUSE) {
|
|
Packit Service |
392537 |
fprintf(stderr, "ambind: bind failed A: %s\n", strerror(errno));
|
|
Packit Service |
392537 |
shutdown(sockfd, SHUT_RDWR);
|
|
Packit Service |
392537 |
exit(2);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
fprintf(stderr, "WARNING: ambind: bind failed B: %s\n", strerror(errno));
|
|
Packit Service |
392537 |
if (shutdown(sockfd, SHUT_RDWR) < 0) {
|
|
Packit Service |
392537 |
fprintf(stderr, "ambind: shutdown failed B: %s\n", strerror(errno));
|
|
Packit Service |
392537 |
exit(1);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
exit(1);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
memset(&msg,0, sizeof(msg));
|
|
Packit Service |
392537 |
msg.msg_control = cmsgbuf;
|
|
Packit Service |
392537 |
msg.msg_controllen = sizeof(cmsgbuf);
|
|
Packit Service |
392537 |
cmsg = CMSG_FIRSTHDR(&msg;;
|
|
Packit Service |
392537 |
cmsg->cmsg_level = SOL_SOCKET;
|
|
Packit Service |
392537 |
cmsg->cmsg_type = SCM_RIGHTS;
|
|
Packit Service |
392537 |
cmsg->cmsg_len = CMSG_LEN(sizeof(s));
|
|
Packit Service |
392537 |
memcpy(CMSG_DATA(cmsg), &s, sizeof(s));
|
|
Packit Service |
392537 |
msg.msg_controllen = cmsg->cmsg_len;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
// send the socket
|
|
Packit Service |
392537 |
if ((sendmsg(sockfd, &msg, 0)) < 0) {
|
|
Packit Service |
392537 |
fprintf(stderr, "ambind: sendmsg failed: %s\n", strerror(errno));
|
|
Packit Service |
392537 |
exit(1);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
if (shutdown(sockfd, SHUT_RDWR) < 0) {
|
|
Packit Service |
392537 |
fprintf(stderr, "ambind: shutdown failed C: %s\n", strerror(errno));
|
|
Packit Service |
392537 |
exit(1);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
exit(0);
|
|
Packit Service |
392537 |
}
|