static pid_t run_child(int argc, char *argv[]) { pid_t pid; if(ulogIsDebug()) { char command[1024]; size_t left = sizeof(command) - 1; int ii; command[0] = 0; for (ii = 0; ii < argc; ++ii) { size_t nbytes; if (ii > 0) { (void)strncat(command, " ", left); left -= (1 <= left) ? 1 : left; } (void)strncat(command, argv[ii], left); nbytes = strlen(argv[ii]); left -= (nbytes <= left) ? nbytes : left; } udebug("exec'ing: \"%s\"", command); } pid = ldmfork(); if(pid == -1) { log_log(LOG_ERR); return pid; } if(pid == 0) { /* child */ const unsigned ulogOptions = ulog_get_options(); const char* ulogIdent = getulogident(); const unsigned ulogFacility = getulogfacility(); const char* ulogPath = getulogpath(); (void)signal(SIGCHLD, SIG_DFL); (void)signal(SIGTERM, SIG_DFL); /* keep same descriptors as parent */ /* don't let child get real privilege */ endpriv(); (void) execvp(argv[0], &argv[0]); openulog(ulogIdent, ulogOptions, ulogFacility, ulogPath); serror("run_child: execvp: %s", argv[0]); _exit(127); } /* else, parent */ return pid; }
static pid_t run_child(int argc, char *argv[]) { pid_t pid; if(ulogIsDebug()) { char command[1024]; char *cp = command; int ii = 0; command[0] = 0; while (ii < argc) { strcpy(cp, argv[ii]); cp += strlen(argv[ii]); if(++ii == argc) break; *cp++ = ' '; *cp = 0; } udebug("exec'ing: \"%s\"", command); } pid = ldmfork(); if(pid == -1) { log_log(LOG_ERR); return pid; } if(pid == 0) { /* child */ (void)signal(SIGCHLD, SIG_DFL); (void)signal(SIGTERM, SIG_DFL); /* keep same descriptors as parent */ /* don't let child get real privilege */ endpriv(); (void) execvp(argv[0], &argv[0]); serror("run_child: execvp: %s", argv[0]); _exit(127); } /* else, parent */ return pid; }
/* * Handles an incoming RPC connection on a socket. This method will fork(2) * a copy of this program, if appropriate, for handling incoming RPC messages. * * sock The socket with the incoming RPC connection. */ static void handle_connection( int sock) { struct sockaddr_in raddr; socklen_t len; int xp_sock; pid_t pid; SVCXPRT *xprt; int status = 1; /* EXIT_FAILURE assumed unless one_svc_run() success */ peer_info* remote = get_remote(); again: len = sizeof(raddr); (void) memset(&raddr, 0, len); xp_sock = accept(sock, (struct sockaddr *) &raddr, &len); (void) exitIfDone(0); if (xp_sock < 0) { if (errno == EINTR) { errno = 0; goto again; } /* else */ serror("accept"); return; } /* * Don't bother continuing if no more clients are allowed. */ if (cps_count() >= maxClients) { setremote(&raddr, xp_sock); unotice("Denying connection from [%s] because too many clients", remote->astr); (void) close(xp_sock); return; } pid = ldmfork(); if (pid == -1) { log_add("Couldn't fork process to handle incoming connection"); log_log(LOG_ERR); /* TODO: try again?*/ (void) close(xp_sock); return; } if (pid > 0) { /* parent */ /* unotice("child %d", pid); */ (void) close(xp_sock); if (cps_add(pid)) serror("Couldn't add child PID to set"); return; } /* else child */ setremote(&raddr, xp_sock); /* Access control */ if (!lcf_isHostOk(remote)) { ensureRemoteName(&raddr); if (!lcf_isHostOk(remote)) { if (remote->printname == remote->astr) { unotice("Denying connection from [%s] because not " "allowed", remote->astr); } else { unotice("Denying connection from \"%s\" because not " "allowed", remote_name()); } /* * Try to tell the other guy. * TODO: Why doesn't this work? */ xprt = svcfd_create(xp_sock, remote->sendsz, remote->recvsz); if (xprt != NULL ) { xprt->xp_raddr = raddr; xprt->xp_addrlen = (int) len; svcerr_weakauth(xprt); svc_destroy(xprt); } goto unwind_sock; } } /* else */ endpriv(); portIsMapped = 0; /* don't call pmap_unset() from child */ (void) close(sock); /* Set the ulog identifier, optional. */ set_abbr_ident(remote_name(), NULL ); uinfo("Connection from %s", remote_name()); xprt = svcfd_create(xp_sock, remote->sendsz, remote->recvsz); if (xprt == NULL ) { uerror("Can't create fd service."); goto unwind_sock; } /* hook up the remote address to the xprt. */ /* xprt->xp_raddr = raddr; */ xprt->xp_raddr = raddr; xprt->xp_addrlen = (int) len; if (!svc_register(xprt, LDMPROG, 4, ldmprog_4, 0)) { uerror("unable to register LDM-4 service."); svc_destroy(xprt); goto unwind_sock; } if (!svc_register(xprt, LDMPROG, FIVE, ldmprog_5, 0)) { uerror("unable to register LDM-5 service."); svc_destroy(xprt); goto unwind_sock; } if (!svc_register(xprt, LDMPROG, SIX, ldmprog_6, 0)) { uerror("unable to register LDM-6 service."); svc_destroy(xprt); goto unwind_sock; } #if WANT_MULTICAST if (!svc_register(xprt, LDMPROG, SEVEN, ldmprog_7, 0)) { uerror("unable to register LDM-7 service."); svc_destroy(xprt); goto unwind_sock; } #endif /* * handle rpc requests */ { const unsigned TIMEOUT = 2*interval; status = one_svc_run(xp_sock, TIMEOUT); (void) exitIfDone(0); if (status == 0) { log_add("Done"); log_log(LOG_INFO); } else if (status == ETIMEDOUT) { log_add("Connection from client LDM silent for %u seconds", TIMEOUT); log_log(LOG_NOTICE); } else { /* connection to client lost */ log_add("Connection with client LDM closed"); log_log(LOG_INFO); status = 0; /* EXIT_SUCCESS */ } } /* svc_destroy(xprt); done by svc_getreqset() */ unwind_sock: (void) close(xp_sock); exit(status); }
/*ARGSUSED*/ static int exec_prodput( const product* prod, int argc, char** argv, const void* xprod, size_t xlen) { pid_t pid = 0; if (NULL == execMap) { execMap = cm_new(); if (NULL == execMap) { LOG_ADD0("Couldn't create child-process map for EXEC entries"); log_log(LOG_ERR); pid = -1; } } /* child-process map not allocated */ if (0 == pid) { int waitOnChild = 0; /* default is not to wait */ if (strcmp(argv[0], "-wait") == 0) { waitOnChild = 1; /* => wait for child */ argc--; argv++; } pid = ldmfork(); if (-1 == pid) { LOG_SERROR0("Couldn't fork EXEC process"); log_log(LOG_ERR); } else { if (0 == pid) { /* * Child process. * * Detach the child process from the parents process group?? * * (void) setpgid(0,0); */ const unsigned ulogOptions = ulog_get_options(); const char* ulogIdent = getulogident(); const unsigned ulogFacility = getulogfacility(); const char* ulogPath = getulogpath(); (void)signal(SIGTERM, SIG_DFL); (void)pq_close(pq); /* * It is assumed that the standard input, output, and error * streams are correctly established and should not be * modified. */ /* * Don't let the child process get any inappropriate privileges. */ endpriv(); (void) execvp(argv[0], argv); openulog(ulogIdent, ulogOptions, ulogFacility, ulogPath); LOG_SERROR1("Couldn't execute command \"%s\"", argv[0]); log_log(LOG_ERR); exit(EXIT_FAILURE); } /* child process */ else { /* * Parent process. */ (void)cm_add_argv(execMap, pid, argv); if (!waitOnChild) { udebug(" exec %s[%d]", argv[0], pid); } else { udebug(" exec -wait %s[%d]", argv[0], pid); (void)reap(pid, 0); } } } /* child-process forked */ } /* child-process map allocated */ return -1 == pid ? -1 : 1; }