summaryrefslogtreecommitdiffstats
path: root/sysconfig/network-scripts/ifup-post
Commit message (Expand)AuthorAgeFilesLines
* remove support for the old firewall typeBill Nottingham2005-04-151-13/+0
* remove wackycommentBill Nottingham2004-08-201-2/+0
* fix for bug 125712: added change_resolv_conf function to network-functions; m...Jason Vas Dias2004-07-301-2/+2
* revertBill Nottingham2004-07-301-1/+1
* fix for bug 125712: added change_resolv_conf function to network-functions; m...Jason Vas Dias2004-07-301-1/+1
* support randomly named network devices, part 1Bill Nottingham2003-06-241-8/+0
* fix DNS punching in the case of other rules for the DNS server (#97686, <mart...Bill Nottingham2003-06-191-1/+1
* - make usernetctl use the nickname instead of the device nameBill Nottingham2003-05-281-2/+1
* revert. chain name change was reverted.Bill Nottingham2003-03-131-3/+3
* handle changed chain nameBill Nottingham2003-02-241-3/+3
* redhat-config-network writes $NAME.route, not $DEVICE.route. HandleBill Nottingham2003-02-201-1/+1
* don't write multiple search lines (#79107, <redhat-com-box@dndtales.org>)Bill Nottingham2003-01-141-3/+3
* switch to -I (#71201)Bill Nottingham2002-08-151-1/+1
* look at the right file (#68368)Bill Nottingham2002-08-131-1/+1
* fix iptables invocation (#71201)Bill Nottingham2002-08-121-1/+1
* use -n with iptables -L (#70807)Bill Nottingham2002-08-121-1/+4
* use iptables & our lokkit chainBill Nottingham2002-07-171-4/+4
* - speed up FIREWALL_MODS=no caseFlorian La Roche2002-07-051-7/+2
* fix invocation of need_hostname (#58946)Bill Nottingham2002-02-071-6/+7
* added \ on the end of the multiline ifHarald Hoyer2001-11-191-4/+4
* better nickname handlingHarald Hoyer2001-11-191-1/+1
* don't run logger if /usr isn't mountedBill Nottingham2001-10-161-1/+1
* need_hostname now returns true or false, doesn't set NEEDHOSTNAME. Some refo...Preston Brown2001-09-251-2/+5
* only allow dest port 1025-65535 for DNS replies (#40833, #44038)Bill Nottingham2001-08-091-1/+1
* log that we're punching something through the firewallBill Nottingham2001-02-271-0/+1
* ifup-post could be called from places other than ifup, so recheck $FWACTIVE hereBill Nottingham2001-02-121-0/+6
* modify the firewall to allow any (new) DNS servers through on ifupBill Nottingham2001-02-061-9/+21
* fix scoping isuse (#22547)Bill Nottingham2000-12-261-1/+4
* fix more ifconfig greps (patch from Conectiva)Bill Nottingham2000-12-121-1/+1
* check for RESOLV_MODS before testingBill Nottingham2000-04-121-1/+1
* fix overwrite problem of resolv.conf on ippp/ppp/slip connectionsThan Ngo2000-04-041-1/+4
* set umask before writing /etc/resolv.confBill Nottingham2000-03-201-0/+4
* allow for spaces in lines that are readBill Nottingham2000-02-241-1/+1
* Fix typo in ifup-post.Florian La Roche2000-02-211-1/+1
* *** empty log message ***r4-95Bill Nottingham2000-02-171-0/+1
* support for isdn stuffBill Nottingham2000-02-171-1/+18
* set hostname only on bootBill Nottingham2000-01-311-1/+1
* change grep slightlyBill Nottingham2000-01-211-1/+1
* don't munge resolv.conf if DNS1 is in there somewhere alreadyBill Nottingham2000-01-191-1/+1
* DNS{1,2} useful for more than just PPPMichael K. Johnson1999-11-021-1/+1
* add new nameserver entries as well as replacing nameserver entriesMichael K. Johnson1999-10-271-3/+5
* do not read /etc/resolv.conf forever...Michael K. Johnson1999-09-071-1/+1
* DEFROUTE defaults on; PEERDNS documented and defaults onMichael K. Johnson1999-09-061-1/+1
* take advantage of userpeerdnsMichael K. Johnson1999-08-041-0/+31
* add routes after aliasesBill Nottingham1999-06-141-2/+1
* run ifup-local as appropriateErik Troan1999-04-061-0/+4
* don't set hostname on ppp/slip (kills X)Bill Nottingham1999-03-181-1/+3
* Always "cd /etc/sysconfig/network-scripts" before sourcing network_functions.Jeff Johnson1998-07-071-2/+1
* linuxconf supportr3-56Michael K. Johnson1998-05-021-5/+1
* look for ipcalc in /bin, not /sbinr3-50Erik Troan1998-03-101-1/+1
ass="hl kwa">return ENOMEM; } child_ctx->sige = tevent_add_signal(ev, child_ctx, SIGCHLD, SA_SIGINFO, child_sig_handler, child_ctx); if(!child_ctx->sige) { /* Error setting up signal handler */ talloc_free(child_ctx); return ENOMEM; } child_ctx->pid = pid; child_ctx->cb = cb; child_ctx->pvt = pvt; DEBUG(8, ("Signal handler set up for pid [%d]\n", pid)); return EOK; } /* Async communication with the child process via a pipe */ struct write_pipe_state { int fd; uint8_t *buf; size_t len; size_t written; }; static void write_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *pvt); struct tevent_req *write_pipe_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, uint8_t *buf, size_t len, int fd) { struct tevent_req *req; struct write_pipe_state *state; struct tevent_fd *fde; req = tevent_req_create(mem_ctx, &state, struct write_pipe_state); if (req == NULL) return NULL; state->fd = fd; state->buf = buf; state->len = len; state->written = 0; fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, write_pipe_handler, req); if (fde == NULL) { DEBUG(1, ("tevent_add_fd failed.\n")); goto fail; } return req; fail: talloc_zfree(req); return NULL; } static void write_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct write_pipe_state *state = tevent_req_data(req, struct write_pipe_state); ssize_t size; if (flags & TEVENT_FD_READ) { DEBUG(1, ("write_pipe_done called with TEVENT_FD_READ," " this should not happen.\n")); tevent_req_error(req, EINVAL); return; } size = write(state->fd, state->buf + state->written, state->len - state->written); if (size == -1) { if (errno == EAGAIN || errno == EINTR) return; DEBUG(1, ("write failed [%d][%s].\n", errno, strerror(errno))); tevent_req_error(req, errno); return; } else if (size >= 0) { state->written += size; if (state->written > state->len) { DEBUG(1, ("write to much, this should never happen.\n")); tevent_req_error(req, EINVAL); return; } } else { DEBUG(1, ("unexpected return value of write [%d].\n", size)); tevent_req_error(req, EINVAL); return; } if (state->len == state->written) { DEBUG(6, ("All data has been sent!\n")); tevent_req_done(req); return; } } int write_pipe_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct read_pipe_state { int fd; uint8_t *buf; size_t len; }; static void read_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *pvt); struct tevent_req *read_pipe_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd) { struct tevent_req *req; struct read_pipe_state *state; struct tevent_fd *fde; req = tevent_req_create(mem_ctx, &state, struct read_pipe_state); if (req == NULL) return NULL; state->fd = fd; state->buf = NULL; state->len = 0; fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_pipe_handler, req); if (fde == NULL) { DEBUG(1, ("tevent_add_fd failed.\n")); goto fail; } return req; fail: talloc_zfree(req); return NULL; } static void read_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct read_pipe_state *state = tevent_req_data(req, struct read_pipe_state); ssize_t size; errno_t err; uint8_t buf[CHILD_MSG_CHUNK]; if (flags & TEVENT_FD_WRITE) { DEBUG(1, ("read_pipe_done called with TEVENT_FD_WRITE," " this should not happen.\n")); tevent_req_error(req, EINVAL); return; } size = read(state->fd, buf, CHILD_MSG_CHUNK); if (size == -1) { err = errno; if (err == EAGAIN || err == EINTR) { return; } DEBUG(1, ("read failed [%d][%s].\n", err, strerror(err))); tevent_req_error(req, err); return; } else if (size > 0) { state->buf = talloc_realloc(state, state->buf, uint8_t, state->len + size); if(!state->buf) { tevent_req_error(req, ENOMEM); return; } safealign_memcpy(&state->buf[state->len], buf, size, &state->len); return; } else if (size == 0) { DEBUG(6, ("EOF received, client finished\n")); tevent_req_done(req); return; } else { DEBUG(1, ("unexpected return value of read [%d].\n", size)); tevent_req_error(req, EINVAL); return; } } int read_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **buf, ssize_t *len) { struct read_pipe_state *state; state = tevent_req_data(req, struct read_pipe_state); TEVENT_REQ_RETURN_ON_ERROR(req); *buf = talloc_steal(mem_ctx, state->buf); *len = state->len; return EOK; } /* The pipes to communicate with the child must be nonblocking */ void fd_nonblocking(int fd) { int flags; int ret; flags = fcntl(fd, F_GETFL, 0); if (flags == -1) { ret = errno; DEBUG(1, ("F_GETFL failed [%d][%s].\n", ret, strerror(ret))); return; } if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { ret = errno; DEBUG(1, ("F_SETFL failed [%d][%s].\n", ret, strerror(ret))); } return; } static void child_invoke_callback(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt); void child_sig_handler(struct tevent_context *ev, struct tevent_signal *sige, int signum, int count, void *__siginfo, void *pvt) { int ret, err; struct sss_child_ctx *child_ctx; struct tevent_immediate *imm; if (count <= 0) { DEBUG(0, ("SIGCHLD handler called with invalid child count\n")); return; } child_ctx = talloc_get_type(pvt, struct sss_child_ctx); DEBUG(7, ("Waiting for child [%d].\n", child_ctx->pid)); errno = 0; ret = waitpid(child_ctx->pid, &child_ctx->child_status, WNOHANG); if (ret == -1) { err = errno; DEBUG(1, ("waitpid failed [%d][%s].\n", err, strerror(err))); } else if (ret == 0) { DEBUG(1, ("waitpid did not found a child with changed status.\n")); } else { if WIFEXITED(child_ctx->child_status) { if (WEXITSTATUS(child_ctx->child_status) != 0) { DEBUG(1, ("child [%d] failed with status [%d].\n", ret, WEXITSTATUS(child_ctx->child_status))); } else { DEBUG(4, ("child [%d] finished successfully.\n", ret)); } } else if WIFSIGNALED(child_ctx->child_status) { DEBUG(1, ("child [%d] was terminated by signal [%d].\n", ret, WTERMSIG(child_ctx->child_status))); } else { if WIFSTOPPED(child_ctx->child_status) { DEBUG(7, ("child [%d] was stopped by signal [%d].\n", ret, WSTOPSIG(child_ctx->child_status))); } if WIFCONTINUED(child_ctx->child_status) { DEBUG(7, ("child [%d] was resumed by delivery of SIGCONT.\n", ret)); } return; } /* Invoke the callback in a tevent_immediate handler * so that it is safe to free the tevent_signal * */ imm = tevent_create_immediate(ev); if (imm == NULL) { DEBUG(0, ("Out of memory invoking sig handler callback\n")); return; } tevent_schedule_immediate(imm, ev,child_invoke_callback, child_ctx); } return; } static void child_invoke_callback(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt) { struct sss_child_ctx *child_ctx = talloc_get_type(pvt, struct sss_child_ctx); if (child_ctx->cb) { child_ctx->cb(child_ctx->child_status, child_ctx->sige, child_ctx->pvt); } /* Stop monitoring for this child */ talloc_free(child_ctx); } static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx, int child_debug_fd, const char *binary, char ***_argv) { uint_t argc = 3; /* program name, debug_level and NULL */ char ** argv; errno_t ret = EINVAL; /* Save the current state in case an interrupt changes it */ bool child_debug_to_file = debug_to_file; bool child_debug_timestamps = debug_timestamps; if (child_debug_to_file) argc++; if (!child_debug_timestamps) argc++; /* program name, debug_level, * debug_to_file, debug_timestamps * and NULL */ argv = talloc_array(mem_ctx, char *, argc); if (argv == NULL) { DEBUG(1, ("talloc_array failed.\n")); return ENOMEM; } argv[--argc] = NULL; argv[--argc] = talloc_asprintf(argv, "--debug-level=%d", debug_level); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } if (child_debug_to_file) { argv[--argc] = talloc_asprintf(argv, "--debug-fd=%d", child_debug_fd); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } } if (!child_debug_timestamps) { argv[--argc] = talloc_strdup(argv, "--debug-timestamps=0"); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } } argv[--argc] = talloc_strdup(argv, binary); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } if (argc != 0) { ret = EINVAL; goto fail; } *_argv = argv; return EOK; fail: talloc_free(argv); return ret; } errno_t exec_child(TALLOC_CTX *mem_ctx, int *pipefd_to_child, int *pipefd_from_child, const char *binary, int debug_fd) { int ret; errno_t err; char **argv; close(pipefd_to_child[1]); ret = dup2(pipefd_to_child[0], STDIN_FILENO); if (ret == -1) { err = errno; DEBUG(1, ("dup2 failed [%d][%s].\n", err, strerror(err))); return err; } close(pipefd_from_child[0]); ret = dup2(pipefd_from_child[1], STDOUT_FILENO); if (ret == -1) { err = errno; DEBUG(1, ("dup2 failed [%d][%s].\n", err, strerror(err))); return err; } ret = prepare_child_argv(mem_ctx, debug_fd, binary, &argv); if (ret != EOK) { DEBUG(1, ("prepare_child_argv.\n")); return ret; } ret = execv(binary, argv); if (ret == -1) { err = errno; DEBUG(1, ("execv failed [%d][%s].\n", err, strerror(err))); return err; } return EOK; } void child_cleanup(int readfd, int writefd) { int ret; if (readfd != -1) { ret = close(readfd); if (ret != EOK) { ret = errno; DEBUG(1, ("close failed [%d][%s].\n", errno, strerror(errno))); } } if (writefd != -1) { ret = close(writefd); if (ret != EOK) { ret = errno; DEBUG(1, ("close failed [%d][%s].\n", errno, strerror(errno))); } } }