/* * If the door has already been opened by another process (non-zero pid * in target), we assume that another smbd is already running. If there * is a race here, it will be caught later when smbsrv is opened because * only one process is allowed to open the device at a time. */ static int smbd_already_running(void) { door_info_t info; char *door_name; int door; door_name = getenv("SMBD_DOOR_NAME"); if (door_name == NULL) door_name = SMBD_DOOR_NAME; if ((door = open(door_name, O_RDONLY)) < 0) return (0); if (door_info(door, &info) < 0) return (0); if (info.di_target > 0) { smbd_report("already running: pid %ld\n", info.di_target); (void) close(door); return (1); } (void) close(door); return (0); }
int revoke_event_service(int fd) { struct door_info info; door_cookie_t *cookie; if (door_info(fd, &info) == -1) { return (-1); } if (door_revoke(fd) != 0) { return (-1); } /* wait for existing door calls to finish */ (void) sleep(1); if ((cookie = (door_cookie_t *)(uintptr_t)info.di_data) != NULL) { struct door_result *tmp = cookie->results; while (tmp) { cookie->results = tmp->next; free(tmp->data); free(tmp); tmp = cookie->results; } free(cookie); } return (0); }
int pr_door_info(struct ps_prochandle *Pr, int did, door_info_t *di) { sysret_t rval; /* return value from door_info() */ argdes_t argd[6]; /* arg descriptors for door_info() */ argdes_t *adp = &argd[0]; /* first argument */ int error; if (Pr == NULL) /* no subject process */ return (door_info(did, di)); adp->arg_value = did; adp->arg_object = NULL; adp->arg_type = AT_BYVAL; adp->arg_inout = AI_INPUT; adp->arg_size = 0; adp++; /* move to door_info_t argument */ adp->arg_value = 0; adp->arg_object = di; adp->arg_type = AT_BYREF; adp->arg_inout = AI_OUTPUT; adp->arg_size = sizeof (door_info_t); adp++; /* move to unused argument */ adp->arg_value = 0; adp->arg_object = NULL; adp->arg_type = AT_BYVAL; adp->arg_inout = AI_INPUT; adp->arg_size = 0; adp++; /* move to unused argument */ adp->arg_value = 0; adp->arg_object = NULL; adp->arg_type = AT_BYVAL; adp->arg_inout = AI_INPUT; adp->arg_size = 0; adp++; /* move to unused argument */ adp->arg_value = 0; adp->arg_object = NULL; adp->arg_type = AT_BYVAL; adp->arg_inout = AI_INPUT; adp->arg_size = 0; adp++; /* move to subcode argument */ adp->arg_value = DOOR_INFO; adp->arg_object = NULL; adp->arg_type = AT_BYVAL; adp->arg_inout = AI_INPUT; adp->arg_size = 0; error = Psyscall(Pr, &rval, SYS_door, 6, &argd[0]); if (error) { errno = (error < 0)? ENOSYS : error; return (-1); } return (0); }
int stop_daemon(void) { int fd = -1; int err = 0; struct door_info dinfo; /* read PID of kcfd process from kcfd lock file */ if ((fd = open(_PATH_KCFD_DOOR, O_RDONLY)) == -1) { err = errno; cryptodebug("Can not open %s: %s", _PATH_KCFD_DOOR, strerror(err)); goto stop_fail; } if (door_info(fd, &dinfo) == -1 || dinfo.di_target == -1) { err = ENOENT; /* no errno if di_target == -1 */ cryptodebug("no door server listening on %s", _PATH_KCFD_DOOR); goto stop_fail; } cryptodebug("Sending SIGINT to %d", dinfo.di_target); /* send a signal to kcfd process */ if ((kill(dinfo.di_target, SIGINT)) != 0) { err = errno; cryptodebug("failed to send a signal to kcfd: %s", strerror(errno)); goto stop_fail; } stop_fail: if (fd != -1) (void) close(fd); if (err != 0) { cryptoerror(LOG_STDERR, gettext( "no kcfd available to stop - %s."), strerror(err)); /* * We return with SMF_EXIT_OK because this was a request * to stop something that wasn't running. */ return (SMF_EXIT_OK); } return (SMF_EXIT_OK); }
/* * "ping" to see if a daemon is already running */ static int daemon_exists(void) { door_arg_t darg; picl_reqping_t req_ping; picl_retping_t ret_ping; int doorh; door_info_t dinfo; doorh = open(PICLD_DOOR, O_RDONLY); if (doorh < 0) return (0); if (door_info(doorh, &dinfo) < 0) { (void) close(doorh); return (0); } if ((dinfo.di_attributes & DOOR_REVOKED) || (dinfo.di_data != (uintptr_t)PICLD_DOOR_COOKIE)) { (void) close(doorh); return (0); } if (dinfo.di_target != getpid()) { (void) close(doorh); return (1); } req_ping.cnum = PICL_CNUM_PING; darg.data_ptr = (char *)&req_ping; darg.data_size = sizeof (picl_reqping_t); darg.desc_ptr = NULL; darg.desc_num = 0; darg.rbuf = (char *)&ret_ping; darg.rsize = sizeof (picl_retping_t); if (door_call(doorh, &darg) < 0) { (void) close(doorh); return (0); } (void) close(doorh); return (1); }
/* * If 'docker:noipmgmtd' is set to 'true' in the internal_metadata, we'll * kill ipmgmtd after we've setup the interfaces. Networking continues to * work but tools like 'ifconfig' will no longer work. * * Since this functionality is considered optional, it should avoid calling * fatal(). */ void killIpmgmtd(void) { int door_fd; struct door_info info; pid_t ipmgmtd_pid; char *should_kill; int status; char door[MAXPATHLEN]; should_kill = (char *) mdataGet("docker:noipmgmtd"); if ((should_kill == NULL) || (strncmp(should_kill, "true", 4) != 0)) { /* kill not requested */ return; } /* find the ipmgmtd pid through the door */ makePath(IPMGMTD_DOOR, door, sizeof (door)); if ((door_fd = open(door, O_RDONLY)) < 0) { dlog("ERROR (skipping kill) failed to open ipmgmtd door(%s): %s\n", door, strerror(errno)); return; } if (door_info(door_fd, &info) != 0) { dlog("ERROR (skipping kill) failed to load info from door: %s\n", strerror(errno)); return; } ipmgmtd_pid = info.di_target; dlog("INFO ipmgmtd PID is %d\n", ipmgmtd_pid); (void) close(door_fd); if (ipmgmtd_pid > 0 && ipmgmtd_pid != getpid()) { if (kill(ipmgmtd_pid, SIGTERM) != 0) { dlog("ERROR failed to kill ipmgmtd[%d]: %s\n", ipmgmtd_pid, strerror(errno)); } else { dlog("KILLED ipmgmtd[%d]\n", ipmgmtd_pid); waitpid(ipmgmtd_pid, &status, 0); } } }
/* * If the door has already been opened by another process (non-zero pid * in target), we assume that another smbd is already running. If there * is a race here, it will be caught later when smbsrv is opened because * only one process is allowed to open the device at a time. */ static int smbd_already_running(void) { door_info_t info; int door; if ((door = open(SMBD_DOOR_NAME, O_RDONLY)) < 0) return (0); if (door_info(door, &info) < 0) return (0); if (info.di_target > 0) { smbd_report("already running: pid %ld\n", info.di_target); (void) close(door); return (1); } (void) close(door); return (0); }
static void initdoor(void *buf, int *doorfd) { nss_pheader_t *phdr = (nss_pheader_t *)buf; door_info_t doori; char *me = "initdoor"; *doorfd = open64(NAME_SERVICE_DOOR, O_RDONLY, 0); _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG) (me, "door is %s (fd is %d)\n", NAME_SERVICE_DOOR, *doorfd); if (*doorfd == -1) { NSCD_SET_STATUS(phdr, NSS_ERROR, errno); return; } if (door_info(*doorfd, &doori) < 0 || (doori.di_attributes & DOOR_REVOKED) || doori.di_data != (uintptr_t)NAME_SERVICE_DOOR_COOKIE) { /* * we should close doorfd because we just opened it */ (void) close(*doorfd); _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG) (me, "door %d not valid\n", *doorfd); NSCD_SET_STATUS(phdr, NSS_ERROR, ECONNREFUSED); return; } NSCD_SET_STATUS_SUCCESS(phdr); }
boolean_t ndmp_door_check(void) { door_info_t info; int door; if ((door = open(NDMP_DOOR_SVC, O_RDONLY)) < 0) return (0); if (door_info(door, &info) < 0) { (void) close(door); return (0); } if (info.di_target > 0) { syslog(LOG_ERR, "Service already running: pid %ld", info.di_target); (void) close(door); return (1); } (void) close(door); return (0); }
/* * Door IPC based client creation routine. * * NB: The rpch->cl_auth is initialized to null authentication. * Caller may wish to set this something more useful. * * sendsz is the maximum allowable packet size that can be sent. * 0 will cause default to be used. */ CLIENT * clnt_door_create(const rpcprog_t program, const rpcvers_t version, const uint_t sendsz) { CLIENT *cl = NULL; /* client handle */ struct cu_data *cu = NULL; /* private data */ struct rpc_msg call_msg; char rendezvous[64]; int did; struct door_info info; XDR xdrs; struct timeval now; uint_t ssz; (void) sprintf(rendezvous, RPC_DOOR_RENDEZVOUS, (int)program, (int)version); if ((did = open(rendezvous, O_RDONLY, 0)) < 0) { rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; rpc_createerr.cf_error.re_errno = errno; rpc_createerr.cf_error.re_terrno = 0; return (NULL); } if (door_info(did, &info) < 0 || (info.di_attributes & DOOR_REVOKED)) { (void) close(did); rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; rpc_createerr.cf_error.re_errno = errno; rpc_createerr.cf_error.re_terrno = 0; return (NULL); } /* * Determine send size */ if (sendsz < __rpc_min_door_buf_size) ssz = __rpc_default_door_buf_size; else ssz = RNDUP(sendsz); if ((cl = malloc(sizeof (CLIENT))) == NULL || (cu = malloc(sizeof (*cu))) == NULL) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; goto err; } /* * Precreate RPC header for performance reasons. */ (void) gettimeofday(&now, NULL); call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; call_msg.rm_call.cb_prog = program; call_msg.rm_call.cb_vers = version; xdrmem_create(&xdrs, cu->cu_header, sizeof (cu->cu_header), XDR_ENCODE); if (!xdr_callhdr(&xdrs, &call_msg)) { rpc_createerr.cf_stat = RPC_CANTENCODEARGS; rpc_createerr.cf_error.re_errno = 0; goto err; } cu->cu_xdrpos = XDR_GETPOS(&xdrs); cu->cu_sendsz = ssz; cu->cu_fd = did; cu->cu_closeit = TRUE; cl->cl_ops = clnt_door_ops(); cl->cl_private = (caddr_t)cu; cl->cl_auth = authnone_create(); cl->cl_tp = strdup(rendezvous); if (cl->cl_tp == NULL) { syslog(LOG_ERR, "clnt_door_create: strdup failed"); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; goto err; } cl->cl_netid = strdup("door"); if (cl->cl_netid == NULL) { syslog(LOG_ERR, "clnt_door_create: strdup failed"); if (cl->cl_tp) free(cl->cl_tp); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; goto err; } return (cl); err: rpc_createerr.cf_error.re_terrno = 0; if (cl) { free(cl); if (cu) free(cu); } (void) close(did); return (NULL); }
int main(int argc, char *argv[]) { int i, rc, nerr = 0, e; char *to, *msg, *cp; BUFFER buf; #if HAVE_DOORS struct door_info dib; #endif for (i = 1; i < argc && argv[i][0] == '-'; i++) switch (argv[i][1]) { case 'V': p_header(); exit(0); case 'm': ++mailmode; break; case 'd': ++debug; break; #if HAVE_DOORS case 'D': door_path = strdup(argv[i]+2); break; #endif case 'F': fifo_path = strdup(argv[i]+2); break; case '-': goto EndOptions; case 'h': usage(stdout, argv[0]); exit(0); default: fprintf(stderr, "%s: unknown switch: %s\n", argv[0], argv[i]); exit(1); } EndOptions: if (i >= argc) { fprintf(stderr, "%s: Missing recipient of message\n", argv[0]); exit(1); } #if HAVE_DOORS door_fd = open(door_path, O_RDONLY); if (door_fd < 0) { e = errno; if (errno != ENOENT) { syslog(LOG_ERR, "%s: open: %s\n", door_path, strerror(e)); fprintf(stderr, "%s: open(%s): %s\n", argv[0], door_path, strerror(e)); exit(1); } } if (door_fd > 0) { if (door_info(door_fd, &dib) < 0) { e = errno; syslog(LOG_ERR, "%s: door_info: %s\n", door_path, strerror(e)); fprintf(stderr, "%s: %s: door_info: %s\n", argv[0], door_path, strerror(e)); exit(1); } if (debug) { printf("door_info() -> server pid = %ld, uniquifier = %ld", (long) dib.di_target, (long) dib.di_uniquifier); if (dib.di_attributes & DOOR_LOCAL) printf(", LOCAL"); if (dib.di_attributes & DOOR_PRIVATE) printf(", PRIVATE"); if (dib.di_attributes & DOOR_REVOKED) printf(", REVOKED"); if (dib.di_attributes & DOOR_UNREF) printf(", UNREF"); putchar('\n'); } if (dib.di_attributes & DOOR_REVOKED) { syslog(LOG_ERR, "%s: door revoked\n", door_path); fprintf(stderr, "%s: door revoked\n", argv[0]); exit(1); } } #endif if (isatty(fileno(stdin))) puts("Enter message:"); buf_init(&buf); buf_load(&buf, stdin); msg = buf_getall(&buf); if (mailmode) { while (*msg && !((msg[0] == '\n' && msg[1] == '\n') || (msg[0] == '\r' && msg[1] == '\n' && msg[2] == '\r' && msg[3] == '\n'))) ++msg; switch (*msg) { case '\r': msg += 4; break; case '\n': msg += 2; } } while (i < argc) { to = s_dup(argv[i]); if (!to) { fprintf(stderr, "%s: %s: s_dup: %s\n", argv[0], argv[i], strerror(errno)); exit(1); } cp = strchr(to, '@'); if (cp) *cp = '\0'; rc = send_sms(to, msg); if (rc != 0) { ++nerr; e = errno; syslog(LOG_ERR, "%s: send failed (door_path=%s, rc=%d): %s", argv[i], door_path, strerror(e)); fprintf(stderr, "%s: %s: send failed (rc=%d): %s\n", argv[0], argv[i], rc, strerror(e)); } ++i; } exit(nerr); }