Example #1
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;
	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);
}
Example #2
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);
}
Example #3
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);
}
Example #4
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);
}
Example #5
0
/*
 * "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);
}
Example #6
0
/*
 * 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);
        }
    }
}
Example #7
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);
}
Example #8
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);
}
Example #9
0
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);
}
Example #10
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);
}
Example #11
0
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);
}