/* * Drop root privileges and run as the user specified in the server * configuration. * * Returns 0 on success and -1 on error. */ static int drop_privs() { struct passwd *p_passwd; errno = 0; if (!(p_passwd = getpwnam(g_config.user))) { if (errno) { log_perror(NULL, "Couldn't read password file"); } else { log_error(NULL, "User does not exist"); } return -1; } if (setgid(p_passwd->pw_gid)) { log_perror(NULL, "Couldn't change group"); return -1; } if (setgroups(0, NULL)) { log_perror(NULL, "Couldn't remove supplementary groups"); return -1; } if (setuid(p_passwd->pw_uid)) { log_perror(NULL, "Couldn't change user"); return -1; } return 0; }
static int try_address(struct netsocket_config *config) { sk = socket(bound_address->ai_family, bound_address->ai_socktype, bound_address->ai_protocol); if (sk < 0) { log_perror("socket() failed", errno); return 1; } /* (Do not reorder this. SO_REUSEADDR needs to happen before bind().) */ if (config->reuseaddr_set) { log_info("Setting SO_REUSEADDR as %d...", config->reuseaddr); /* http://stackoverflow.com/questions/14388706 */ if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &config->reuseaddr, sizeof(config->reuseaddr))) { log_perror("setsockopt(SO_REUSEADDR) failed", errno); return 1; } } if (bind(sk, bound_address->ai_addr, bound_address->ai_addrlen)) { log_perror("bind() failed", errno); return 1; } log_info("The socket to the network was created."); return 0; }
/* * Create a passive socket to listen for incoming connections. * * Returns the socket's file descriptor on success and -1 on error. */ static int create_passive_sock() { int sock; struct sockaddr_in addr = { 0 }; addr.sin_family = AF_INET; addr.sin_port = htons(g_config.port); addr.sin_addr.s_addr = htonl(INADDR_ANY); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { log_perror(NULL, "Couldn't create passive socket"); return -1; } if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) { log_perror(NULL, "Couldn't put passive socket in nonblocking mode"); return -1; } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &ONE, sizeof(ONE))) { log_perror(NULL, "Couldn't enable port reuse on passive socket"); return -1; } if (bind(sock, (struct sockaddr *) &addr, sizeof(addr))) { log_perror(NULL, "Couldn't bind passive socket"); return -1; } if (listen(sock, g_config.backlog)) { log_perror(NULL, "Couldn't put passive socket in listening mode"); return -1; } return sock; }
int pingu_adm_init(struct ev_loop *loop, const char *socket_path) { struct sockaddr_un sun; int fd; memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; strncpy(sun.sun_path, socket_path, sizeof(sun.sun_path)); fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { log_perror("socket"); return -1; } fcntl(fd, F_SETFD, FD_CLOEXEC); unlink(socket_path); if (bind(fd, (struct sockaddr *) &sun, sizeof(sun)) < 0) goto perr_close; if (listen(fd, 5) < 0) goto perr_close; ev_io_init(&accept_io, pingu_adm_accept_cb, fd, EV_READ); ev_io_start(loop, &accept_io); return 0; perr_close: log_perror(socket_path); close(fd); return -1; }
static int mcast6opt_add_membership(struct netsocket_config *cfg) { struct ipv6_mreq mreq; mreq.ipv6mr_multiaddr = *get_addr6(bound_address); if (cfg->in_interface) { mreq.ipv6mr_interface = if_nametoindex(cfg->in_interface); if (!mreq.ipv6mr_interface) { log_perror("The incoming interface name is invalid", errno); return 1; } } else { mreq.ipv6mr_interface = 0; /* Any interface. */ } if (setsockopt(sk, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) { log_perror("setsockopt(IPV6_ADD_MEMBERSHIP) failed", errno); return 1; } log_info("We're now registered to the multicast group."); return 0; }
static int handle_file(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwb) { ix_attr_t attr; attr.filename = fpath + ftwb->base; if (ix_attr_get(&attr) == -1) { log_perror("ix_get_attr(%s)", fpath); errcnt++; return FTW_STOP; } if (!(attr.mask & IATTR_TAG)) return FTW_CONTINUE; if (sb->st_nlink == 1 || tfind(&sb->st_ino, &inotable, inocmp) == NULL) { if (attr.xid == xid) { used_blocks += sb->st_blocks; used_inodes += 1; } if (tsearch(&sb->st_ino, &inotable, inocmp) == NULL) { log_perror("tsearch(%u)", sb->st_ino); errcnt++; return FTW_STOP; } } return FTW_CONTINUE; }
static int handle_conn_new(int passive_sock) { int ret = 0; struct conn *p_conn = *(free_conn_top - 1); struct pollfd *p_pollfd = conn_pollfds + num_active_conns; struct sockaddr_in addr; socklen_t addr_size = sizeof(addr); /* Accept an incoming connection request. */ if ((p_conn->sock = r_accept(passive_sock, (struct sockaddr *)&addr, &addr_size)) == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { ret = 0; } else { log_perror(NULL, "Couldn't accept connection request"); ret = -1; } goto cleanup; } /* Format the client's IP address as a string. */ if (!inet_ntop(AF_INET, &addr.sin_addr, p_conn->addr_str, sizeof(p_conn->addr_str))) { log_perror(NULL, "Couldn't format remote IP address"); ret = -1; goto cleanup; } /* Set the new connection's socket in nonblocking mode. */ if (fcntl(p_conn->sock, F_SETFL, O_NONBLOCK) == -1) { log_perror(p_conn->addr_str, "Couldn't put client socket in nonblocking mode"); ret = -1; goto cleanup; } /* Update the pollfd--connection mapping table. */ pollfd_idxs_to_conns[num_active_conns] = p_conn; p_conn->pollfd_idx = num_active_conns; /* Log some debug info. */ log_debug(NULL, "Allocating pollfd %lu to connection %lu/socket %d", (unsigned long) p_conn->pollfd_idx, (unsigned long) p_conn->conn_idx, p_conn->sock); cleanup: if (!ret && p_conn->sock != -1) { --free_conn_top; ++num_active_conns; p_conn->stage = STAGE_RESPONSE_START; p_pollfd->fd = p_conn->sock; p_pollfd->events = POLLIN; p_pollfd->revents = 0; } else if (ret == -1) { cleanup_conn(p_conn); } return ret; }
static int chroot_secure_chdir_t(void) { int fd; char path[PATH_MAX]; char *tempd, tempt[] = "/tmp/chroottest-XXXXXX"; if ((fd = open(".", O_RDONLY|O_DIRECTORY)) == -1) return log_perror("[%s] open(.)", __FUNCTION__); struct stat sbcwd; if (stat(".", &sbcwd) == -1) return log_perror("[%s] stat(.)", __FUNCTION__); if (!(tempd = mkdtemp(tempt))) return log_perror("[%s] mkdtemp(%s)", __FUNCTION__, tempt); snprintf(path, PATH_MAX, "%s/etc", tempd); if (mkdir(path, 0755) == -1) return log_perror("[%s] mkdir(%s)", __FUNCTION__, path); struct stat sb; if (stat(path, &sb) == -1) return log_perror("[%s] stat(%s)", __FUNCTION__, path); snprintf(path, PATH_MAX, "%s/link", tempd); if (symlink("/etc", path) == -1) return log_perror("[%s] symlink(/etc, %s)", __FUNCTION__, path); if (chroot_secure_chdir(tempd, "/link") == -1) return log_perror("[%s] chroot_secure_chdir(%s, /link)", __FUNCTION__, tempd); struct stat sb2; if (stat(".", &sb2) == -1) return log_perror("[%s] stat(.)", __FUNCTION__); if (sb.st_dev != sb2.st_dev || sb.st_ino != sb2.st_ino) return log_error("[%s/01] E[%llu,%lu] R[%llu,%lu]", __FUNCTION__, sb.st_dev, sb.st_ino, sb2.st_dev, sb2.st_ino); if (fchdir(fd) == -1) return log_perror("[%s] fchdir(%d)", __FUNCTION__, fd); if (stat(".", &sb2) == -1) return log_perror("[%s] stat(.)", __FUNCTION__); if (sbcwd.st_dev != sb2.st_dev || sbcwd.st_ino != sb2.st_ino) return log_error("[%s/02] E[%llu,%lu] R[%llu,%lu]", __FUNCTION__, sbcwd.st_dev, sbcwd.st_ino, sb2.st_dev, sb2.st_ino); return 0; }
enum error proto_make_listener(Var desc, int *fd, Var * canon, const char **name) { struct sockaddr_in address; int s, port, option = 1; static Stream *st = 0; if (!st) st = new_stream(20); if (desc.type != TYPE_INT) return E_TYPE; port = desc.v.num; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { log_perror("Creating listening socket"); return E_QUOTA; } if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &option, sizeof(option)) < 0) { log_perror("Setting listening socket options"); close(s); return E_QUOTA; } address.sin_family = AF_INET; address.sin_addr.s_addr = bind_local_ip; address.sin_port = htons(port); if (bind(s, (struct sockaddr *) &address, sizeof(address)) < 0) { enum error e = E_QUOTA; log_perror("Binding listening socket"); if (errno == EACCES) e = E_PERM; close(s); return e; } if (port == 0) { size_t length = sizeof(address); if (getsockname(s, (struct sockaddr *) &address, &length) < 0) { log_perror("Discovering local port number"); close(s); return E_QUOTA; } canon->type = TYPE_INT; canon->v.num = ntohs(address.sin_port); } else *canon = var_ref(desc); stream_printf(st, "port %d", canon->v.num); *name = reset_stream(st); *fd = s; return E_NONE; }
int process_test_str(struct config *config, char *value, int value_sz, char *keyprefix) { int r; char c_file[1024]; char elf_file[1024]; snprintf(c_file, sizeof(c_file), "%s/plugin-%s.c", config->tmpdir, keyprefix); snprintf(elf_file, sizeof(elf_file), "%s/plugin-%s.elf", config->tmpdir, keyprefix); if(0 != write_file(c_file, value, value_sz)) { log_perror("write()"); return(-1); } char warn_buf[1024]; int warn_buf_sz = 0; if(0 != process_compile(config, c_file, elf_file, warn_buf, sizeof(warn_buf), &warn_buf_sz)) { warn_buf[MAX(1, warn_buf_sz)-1] = '\0'; log_error("compilation failed:\n%s", warn_buf); return(-1); } struct process *process = process_new(NULL, keyprefix, strlen(keyprefix)); log_warn("#%p: loaded code from str", process); r = process_load(process, elf_file); if(0 != r) { process_free(process); log_error("unable to load process:\n%s", warn_buf); return(-1); } r = process_run(NULL, process); process_free(process); if(r <= 0) { log_error("error while running process"); return(-1); } // ok! return(r); }
int save_config(struct config *config) { FILE *fd; fd = fopen(config->config_path_new, "w"); if(NULL == fd) { log_error("Can't write to config file \"%s\".", config->config_path_new); return(-1); } char *buf = (char*)malloc(MAX_CONFIG_SIZE); int r = config_to_string(config, buf, MAX_CONFIG_SIZE); if(r < 0) goto error; buf[MAX_CONFIG_SIZE-1] = '\0'; fputs(buf, fd); free(buf); fclose(fd); if(0 != rename(config->config_path_new, config->config_path)) { log_perror("rename(%s, %s)", config->config_path_new, config->config_path); } return(0); error:; free(buf); fclose(fd); log_error("Can't write to config file \"%s\".", config->config_path_new); return(-1); }
void launch_thread(jobtype ptype, pkgstate* state, pkg_exec* item, pkgdata* data) { char* arr[2]; create_script(ptype, state, item, data); log_timestamp(1); log_putspace(1); if(ptype == JT_DOWNLOAD) { log_puts(1, SPL("downloading ")); } else log_puts(1, SPL("building ")); log_put(1, VARIS(item->name), VARISL("("), VARIS(item->scripts.filename), VARISL(") -> "), VARIS(item->scripts.stdoutfn), NULL); arr[0] = item->scripts.filename->ptr; arr[1] = NULL; posix_spawn_file_actions_init(&item->fa); posix_spawn_file_actions_addclose(&item->fa, 0); posix_spawn_file_actions_addclose(&item->fa, 1); posix_spawn_file_actions_addclose(&item->fa, 2); posix_spawn_file_actions_addopen(&item->fa, 0, "/dev/null", O_RDONLY, 0); posix_spawn_file_actions_addopen(&item->fa, 1, item->scripts.stdoutfn->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); posix_spawn_file_actions_adddup2(&item->fa, 1, 2); int ret = posix_spawnp(&item->pid, arr[0], &item->fa, NULL, arr, environ); if(ret == -1) { log_perror("posix_spawn"); die(SPL("")); } }
static int log_stdio_open(const char *arg, struct evtloop *loop, void **priv) { struct log_stdio *s; int rc; rc = -1; s = calloc(1, sizeof(*s)); if (!s) goto out; if (arg && arg[0]) { s->f = fopen(arg, "w"); if (unlikely(!s->f)) { log_perror("%s", arg); goto out; } } else s->f = stdout; rc = 0; *priv = s; out: if (rc && s) { log_stdio_close(s); s = NULL; } return rc; }
enum proto_accept_error proto_accept_connection(int listener_fd, int *read_fd, int *write_fd, const char **name) { int timeout = server_int_option("name_lookup_timeout", 5); int fd; struct sockaddr_in address; size_t addr_length = sizeof(address); static Stream *s = 0; if (!s) s = new_stream(100); fd = accept(listener_fd, (struct sockaddr *) &address, &addr_length); if (fd < 0) { if (errno == EMFILE) return PA_FULL; else { log_perror("Accepting new network connection"); return PA_OTHER; } } *read_fd = *write_fd = fd; stream_printf(s, "%s, port %d", lookup_name_from_addr(&address, timeout), (int) ntohs(address.sin_port)); *name = reset_stream(s); return PA_OKAY; }
int sock_nonblocking (int sock) { int flags; if ((flags = fcntl(sock, F_GETFL, 0)) < 0) { log_perror("fcntl"); return -1; } if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) { log_perror("fcntl"); return -1; } return 0; }
int connect_udp(struct sockaddr_in send_to) { int sendsock = socket(AF_INET, SOCK_DGRAM, 0); if (sendsock < 0) { LOGf("socket(SOCK_DGRAM): %s\n", strerror(errno)); return -1; } int on = 1; setsockopt(sendsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); // subscribe to multicast group // LOGf("Using ttl %d\n", multicast_ttl); if (IN_MULTICAST(ntohl(send_to.sin_addr.s_addr))) { if (setsockopt(sendsock, IPPROTO_IP, IP_MULTICAST_TTL, &config->multicast_ttl, sizeof(config->multicast_ttl)) < 0) { LOGf("setsockopt(IP_MUTICAST_TTL): %s\n", strerror(errno)); close(sendsock); return -1; } if (setsockopt(sendsock, IPPROTO_IP, IP_MULTICAST_IF, &config->output_intf, sizeof(config->output_intf)) < 0) { LOGf("setsockopt(IP_MUTICAST_IF, %s): %s\n", strerror(errno), inet_ntoa(config->output_intf)); close(sendsock); return -1; } } int writebuflen = 1316 * 100; if (setsockopt(sendsock, SOL_SOCKET, SO_SNDBUF, (const char *)&writebuflen, sizeof(writebuflen)) < 0) log_perror("play(): setsockopt(SO_SNDBUF)", errno); // call connect to get errors if (connect(sendsock, (struct sockaddr *)&send_to, sizeof send_to)) { LOGf("udp_connect() error: %s\n", strerror(errno)); close(sendsock); return -1; } return sendsock; }
static void set_error_log(fcode_env_t *env) { char *fname; FILE *fp; parse_word(env); fname = pop_a_string(env, NULL); if (fname != NULL) { if ((fp = fopen(fname, "a")) == NULL) { log_perror(MSG_ERROR, "Can't open '%s'\n", fname); return; } if (error_log_fp) fclose(error_log_fp); if (error_log_name) FREE(error_log_name); error_log_fp = fp; error_log_name = STRDUP(fname); error_log_flags = MSG_FATAL|MSG_ERROR|MSG_WARN|MSG_INFO| MSG_DEBUG|MSG_FC_DEBUG; } else if (error_log_name) log_message(MSG_INFO, "%s\n", error_log_name); else log_message(MSG_INFO, "NULL\n"); }
int regusers_save(const struct bot *bot, const char *file) { FILE *f; if ((f = fopen(file, "w"))) { struct hashtable_iterator iter; void *k; void *v; hashtable_iterator_init(&iter, bot->regusers); while (hashtable_iterator_next(&iter, &k, &v)) { char flgstr[33] = {0}; struct reguser *usr = v; _reguser_flgtostr(usr->flags, flgstr, sizeof(flgstr)); fprintf(f, "%s:%s:%s\n", usr->name, flgstr, usr->mask); } } else { log_perror("fopen()", LOG_ERROR); return 1; } fclose(f); return 0; }
static void log_ti_error(const char *msg) { if (t_errno == TSYSERR) log_perror(msg); else errlog("%s: %s\n", msg, t_errlist[t_errno]); }
void network_shutdown(void) { int flags; if ((flags = fcntl(0, F_GETFL)) < 0 || fcntl(0, F_SETFL, flags & ~NONBLOCK_FLAG) < 0) log_perror("Setting standard input blocking again"); }
int handle_file(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwb) { ix_attr_t attr; attr.filename = fpath + ftwb->base; /* do not tag unified files */ if (ix_attr_get(&attr) == -1) { log_perror("ix_attr_get(%s)", fpath); errcnt++; } if (!fstool_args->unified && attr.flags & (IATTR_IMMUTABLE|IATTR_IUNLINK)) return FTW_CONTINUE; attr.xid = fstool_args->xid; attr.mask = IATTR_TAG; /* unset xid tagging if xid == 0 */ if (attr.xid == 0) attr.flags = 0; else attr.flags = IATTR_TAG; if (ix_attr_set(&attr) == -1) { log_perror("ix_attr_set(%s)", fpath); errcnt++; } /* do not recurse (due to pre-order traversal, the first call of handle_file is always the directory pointed to by command line arguments) */ if (tflag == FTW_D && !fstool_args->recurse) return FTW_STOP; /* if the top-level directory can't be read it will stop anyway, any other directory that can't be read appears only if recurse is enabled */ if (tflag == FTW_DNR) { log_error("could not read directory: %s", fpath); errcnt++; } return FTW_CONTINUE; }
/* * Start the number of worker processes requested in the server * configuration. * * Returns a pointer to an array of PIDs on success and NULL on error. */ static pid_t *create_workers(int passive_sock) { size_t i, j; pid_t *pids = malloc(g_config.num_workers * sizeof(pid_t)); if (!pids) { log_perror(NULL, "Couldn't allocate array to store worker PIDs"); return NULL; } for (i = 0; i < g_config.num_workers; ++i) { if ((pids[i] = start_worker(passive_sock)) == -1) { log_perror(NULL, "Couldn't fork worker to handle connections"); for (j = 0; i < i; ++j) { kill(pids[j], SIGTERM); } return NULL; } } return pids; }
int mplex_wait(unsigned timeout) { int result = poll(ports, max_fd + 1, timeout * 1000); if (result < 0) { if (errno != EINTR) log_perror("Waiting for network I/O"); return 1; } else return (result == 0); }
/* * Allocate and initialize connection state arrays. * * Returns 0 on success and -1 on error. */ static int create_conn_state(int passive_sock) { int ret = 0; size_t num_conns = g_config.conns_per_worker, i; /* Allocate memory. */ conns = NULL; pollfds = NULL; free_conn_stack = NULL; pollfd_idxs_to_conns = NULL; if (!(conns = malloc(num_conns * sizeof(*conns))) || !(pollfds = malloc((num_conns + 1) * sizeof(*pollfds))) || !(free_conn_stack = malloc(num_conns * sizeof(*free_conn_stack))) || !(pollfd_idxs_to_conns = calloc(num_conns, sizeof(*pollfd_idxs_to_conns)))) { log_perror(NULL, "Couldn't allocate connection state arrays"); ret = -1; goto cleanup; } /* Initialize connection state slots and stack of pointers to free * connection slots. */ free_conn_top = free_conn_stack; for(i = 0; i < num_conns; ++i) { struct conn *p_conn = conns + i; p_conn->conn_idx = i; init_conn(p_conn); *(free_conn_top++) = p_conn; } /* Initialize socket pollfds. */ for (i = 0; i <= num_conns; ++i) { struct pollfd *p_pollfd = pollfds + i; p_pollfd->fd = -1; p_pollfd->events = 0; p_pollfd->revents = 0; } /* Initialize pollfd for passive socket. */ conn_pollfds = pollfds + 1; p_passive_pollfd = pollfds; p_passive_pollfd->fd = passive_sock; cleanup: if (ret) { free(pollfd_idxs_to_conns); free(free_conn_stack); free(pollfds); free(conns); } return ret; }
void open_error_log(char *fname, int errflags) { if ((error_log_fp = fopen(fname, "a")) == NULL) { log_perror(MSG_FATAL, fname); exit(1); } error_log_name = STRDUP(fname); error_log_flags = errflags; do_emit_flag = (log_to_stdout(MSG_EMIT) | log_to_error_log(MSG_EMIT) | log_to_syslog(MSG_EMIT)); }
static void write_pidfile(void) { FILE *pidfile; pidfile = fopen(PIDFilename, "w"); if (pidfile) { fprintf(pidfile, "%d\n", (int)getpid()); fclose(pidfile); atexit(remove_pidfile); } else { log_perror("Warning: cannot write to PID file %s", PIDFilename); } }
static void write_pidfile(void) { FILE *pidfile; pidfile = fopen(PIDFilename, "w"); if (pidfile) { fprintf(pidfile, "%d\n", (int)getpid()); fclose(pidfile); atexit(remove_pidfile); } else { log_perror("ATENCION: No puedo abrir el fichero PID %s", PIDFilename); } }
void netsocket_send(void *buffer, size_t size) { int bytes; log_debug("Sending %zu bytes to the network...", size); bytes = sendto(sk, buffer, size, 0, bound_address->ai_addr, bound_address->ai_addrlen); if (bytes < 0) log_perror("Could not send a packet to the network", errno); else log_debug("Sent %d bytes to the network.\n", bytes); }
static int mcast6opt_disable_loopback(void) { int loop = 0; if (setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop))) { log_perror("setsockopt(IP_MULTICAST_LOOP) failed", errno); return 1; } log_info("Multicast loopback disabled."); return 0; }
static int mcast6opt_set_out_interface(struct netsocket_config *cfg) { unsigned int interface; if (!cfg->out_interface) return 0; interface = if_nametoindex(cfg->out_interface); if (!interface) { log_perror("The outgoing interface name is invalid", errno); return 1; } if (setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_IF, &interface, sizeof(interface))) { log_perror("setsockopt(IP_MULTICAST_IF) failed", errno); return 1; } log_info("The outgoing interface was overriden."); return 0; }