Exemplo n.º 1
0
/*
 * Create the slm to picl plugin door
 */
static int
setup_door(void)
{
	struct stat	stbuf;

	/*
	 * Create the door
	 */
	door_id = door_create(event_handler, PICLEVENT_DOOR_COOKIE,
	    DOOR_REFUSE_DESC | DOOR_NO_CANCEL);

	if (door_id < 0)
		return (-1);

	if (stat(PICLEVENT_DOOR, &stbuf) < 0) {
		int newfd;
		if ((newfd = creat(PICLEVENT_DOOR, 0444)) < 0) {
			(void) door_revoke(door_id);
			door_id = -1;
			return (-1);
		}
		(void) close(newfd);
	}

	if (fattach(door_id, PICLEVENT_DOOR) < 0) {
		if ((errno != EBUSY) || (fdetach(PICLEVENT_DOOR) < 0) ||
		    (fattach(door_id, PICLEVENT_DOOR) < 0)) {
			(void) door_revoke(door_id);
			door_id = -1;
			return (-1);
		}
	}

	return (0);
}
Exemplo n.º 2
0
/* ARGSUSED */
static void *
nfsauth_svc(void *arg)
{
	int	doorfd = -1;
	uint_t	darg;
#ifdef DEBUG
	int	dfd;
#endif

	if ((doorfd = door_create(nfsauth_func, NULL,
	    DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
		syslog(LOG_ERR, "Unable to create door: %m\n");
		exit(10);
	}

#ifdef DEBUG
	/*
	 * Create a file system path for the door
	 */
	if ((dfd = open(MOUNTD_DOOR, O_RDWR|O_CREAT|O_TRUNC,
	    S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) {
		syslog(LOG_ERR, "Unable to open %s: %m\n", MOUNTD_DOOR);
		(void) close(doorfd);
		exit(11);
	}

	/*
	 * Clean up any stale namespace associations
	 */
	(void) fdetach(MOUNTD_DOOR);

	/*
	 * Register in namespace to pass to the kernel to door_ki_open
	 */
	if (fattach(doorfd, MOUNTD_DOOR) == -1) {
		syslog(LOG_ERR, "Unable to fattach door: %m\n");
		(void) close(dfd);
		(void) close(doorfd);
		exit(12);
	}
	(void) close(dfd);
#endif

	/*
	 * Must pass the doorfd down to the kernel.
	 */
	darg = doorfd;
	(void) _nfssys(MOUNTD_ARGS, &darg);

	/*
	 * Wait for incoming calls
	 */
	/*CONSTCOND*/
	for (;;)
		(void) pause();

	/*NOTREACHED*/
	syslog(LOG_ERR, gettext("Door server exited"));
	return (NULL);
}
Exemplo n.º 3
0
static void server_proc (void *cookie, char *argp, size_t arg_size,
	door_desc_t *dp, uint_t n_desc)
{
	long arg;
	long res;

	if (argp == DOOR_UNREF_DATA) {
		printf ("Door unreferenced\n");
		if (fattach (door_fd, door_path) == -1)
			 err_msg ("fattach failed");
		if (door_return (NULL, 0, NULL, 0) == -1)
			err_msg ("door_return failed");
	}

	if (fdetach (door_path) == -1)
		err_msg("fdetach failed");

	arg = *((long *) argp);
	res = arg * arg;

	printf ("Server proc returning, res = %ld\n", res);

	if (door_return ((char *) &res, sizeof (long), NULL, 0) == -1)
		err_msg ("door_return failed");
}
Exemplo n.º 4
0
/*
 * door_server_fini()
 *
 *	Terminate and cleanup the door server.
 */
void
door_server_fini(void)
{
    if (door_fd != -1) {
        (void) door_revoke(door_fd);
        (void) fdetach(HOTPLUGD_DOOR);
    }

    (void) unlink(HOTPLUGD_DOOR);
}
Exemplo n.º 5
0
static void
ipmgmt_door_fini()
{
	if (ipmgmt_door_fd == -1)
		return;

	(void) fdetach(IPMGMT_DOOR);
	if (door_revoke(ipmgmt_door_fd) == -1) {
		ipmgmt_log(LOG_ERR, "failed to revoke access to door %s: %s",
		    IPMGMT_DOOR, strerror(errno));
	}
}
Exemplo n.º 6
0
void
ndmp_door_fini(void)
{
	(void) mutex_lock(&ndmp_doorsrv_mutex);

	if (ndmp_door_fildes != -1) {
		(void) fdetach(NDMP_DOOR_SVC);
		(void) door_revoke(ndmp_door_fildes);
		ndmp_door_fildes = -1;
	}

	(void) mutex_unlock(&ndmp_doorsrv_mutex);
}
Exemplo n.º 7
0
/*
 * door_server_init()
 *
 *	Create the door file, and initialize the door server.
 */
boolean_t
door_server_init(void)
{
    int	fd;

    /* Create the door file */
    if ((fd = open(HOTPLUGD_DOOR, O_CREAT|O_EXCL|O_RDONLY, 0644)) == -1) {
        if (errno == EEXIST) {
            log_err("Door service is already running.\n");
        } else {
            log_err("Cannot open door file '%s': %s\n",
                    HOTPLUGD_DOOR, strerror(errno));
        }
        return (B_FALSE);
    }
    (void) close(fd);

    /* Initialize the door service */
    if ((door_fd = door_create(door_server, NULL,
                               DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
        log_err("Cannot create door service: %s\n", strerror(errno));
        return (B_FALSE);
    }

    /* Cleanup stale door associations */
    (void) fdetach(HOTPLUGD_DOOR);

    /* Associate door service with door file */
    if (fattach(door_fd, HOTPLUGD_DOOR) != 0) {
        log_err("Cannot attach to door file '%s': %s\n", HOTPLUGD_DOOR,
                strerror(errno));
        (void) door_revoke(door_fd);
        (void) fdetach(HOTPLUGD_DOOR);
        door_fd = -1;
        return (B_FALSE);
    }

    return (B_TRUE);
}
Exemplo n.º 8
0
int
setup_main_door(const char *doorpath)
{
	mode_t oldmask;
	int fd;

	int door_flags = DOOR_UNREF | DOOR_REFUSE_DESC;
#ifdef DOOR_NO_CANCEL
	door_flags |= DOOR_NO_CANCEL;
#endif
	if ((main_door_fd = door_create(main_switcher, REPOSITORY_DOOR_COOKIE,
	    door_flags)) < 0) {
		perror("door_create");
		return (0);
	}

#ifdef DOOR_PARAM_DATA_MIN
	if (door_setparam(main_door_fd, DOOR_PARAM_DATA_MIN,
	    offsetofend(repository_door_request_t, rdr_request)) == -1 ||
	    door_setparam(main_door_fd, DOOR_PARAM_DATA_MAX,
	    sizeof (repository_door_request_t)) == -1) {
		perror("door_setparam");
		return (0);
	}
#endif /* DOOR_PARAM_DATA_MIN */

	/*
	 * Create the file if it doesn't exist.  Ignore errors, since
	 * fattach(3C) will catch any real problems.
	 */
	oldmask = umask(000);		/* disable umask temporarily */
	fd = open(doorpath, O_RDWR | O_CREAT | O_EXCL, 0644);
	(void) umask(oldmask);

	if (fd >= 0)
		(void) close(fd);

	if (fattach(main_door_fd, doorpath) < 0) {
		if ((errno != EBUSY) ||
		    (fdetach(doorpath) < 0) ||
		    (fattach(main_door_fd, doorpath) < 0)) {
			perror("fattach");
			(void) door_revoke(main_door_fd);
			main_door_fd = -1;
			return (0);
		}
	}

	return (1);
}
Exemplo n.º 9
0
static void
dlmgmt_door_fini()
{
	if (dlmgmt_door_fd == -1)
		return;

	if (door_revoke(dlmgmt_door_fd) == -1) {
		dlmgmt_log(LOG_WARNING, "door_revoke(%s) failed: %s",
		    DLMGMT_DOOR, strerror(errno));
	}

	(void) fdetach(DLMGMT_DOOR);
	(void) dlmgmt_set_doorfd(B_FALSE);
}
Exemplo n.º 10
0
int
create_event_service(char *door_name,
    void (*func)(void **data, size_t *datalen))
{
	int service_door, fd;
	door_cookie_t *cookie;

	/* create an fs file */
	fd = open(door_name, O_EXCL|O_CREAT, S_IREAD|S_IWRITE);
	if ((fd == -1) && (errno != EEXIST)) {
		return (-1);
	}
	(void) close(fd);

	/* allocate space for door cookie */
	if ((cookie = calloc(1, sizeof (*cookie))) == NULL) {
		return (-1);
	}

	cookie->door_func = func;
	if ((service_door = door_create(door_service, (void *)cookie,
	    DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
		dprint("door create failed: %s\n", strerror(errno));
		free(cookie);
		return (-1);
	}

retry:
	(void) fdetach(door_name);
	if (fattach(service_door, door_name) != 0) {
		if (errno == EBUSY) {
			/*
			 * EBUSY error may occur if anyone references the door
			 * file while we are fattach'ing. Since librcm, in the
			 * the process context of a DR initiator program, may
			 * reference the door file (via open/close/stat/
			 * door_call etc.) while we are still fattach'ing,
			 * retry on EBUSY.
			 */
			goto retry;
		}
		dprint("door attaching failed: %s\n", strerror(errno));
		free(cookie);
		(void) close(service_door);
		return (-1);
	}

	return (service_door);
}
Exemplo n.º 11
0
/*
 * vs_stats_fini
 *
 * Invoked on daemon unload
 */
void
vs_stats_fini(void)
{
	(void) pthread_mutex_lock(&vs_stats_mutex);

	/* door termination */
	if (vs_stats_door_fd != -1)
		(void) door_revoke(vs_stats_door_fd);
	vs_stats_door_fd = -1;

	(void) fdetach(VS_STATS_DOOR_NAME);
	(void) unlink(VS_STATS_DOOR_NAME);

	(void) pthread_mutex_unlock(&vs_stats_mutex);
}
Exemplo n.º 12
0
static int
start_reparsed_svcs()
{
	int doorfd;
	int dfd;

	if ((doorfd = door_create(reparsed_doorfunc, NULL,
	    DOOR_REFUSE_DESC|DOOR_NO_CANCEL)) == -1) {
		syslog(LOG_ERR, "Unable to create door");
		return (1);
	}

	/*
	 * Create a file system path for the door
	 */
	if ((dfd = open(REPARSED_DOOR, O_RDWR|O_CREAT|O_TRUNC,
	    S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) {
		syslog(LOG_ERR, "unable to open %s", REPARSED_DOOR);
		(void) close(doorfd);
		return (1);
	}

	/*
	 * Clean up any stale associations
	 */
	(void) fdetach(REPARSED_DOOR);

	/*
	 * Register in the kernel namespace for door_ki_open().
	 */
	if (fattach(doorfd, REPARSED_DOOR) == -1) {
		syslog(LOG_ERR, "Unable to fattach door %s", REPARSED_DOOR);
		(void) close(doorfd);
		(void) close(dfd);
		return (1);
	}
	(void) close(dfd);

	/*
	 * Wait for incoming calls
	 */
	/*CONSTCOND*/
	while (1)
		(void) pause();

	syslog(LOG_ERR, "Door server exited");
	return (10);
}
Exemplo n.º 13
0
int
ndmp_door_init(void)
{
	int fd;

	(void) mutex_lock(&ndmp_doorsrv_mutex);

	if (ndmp_door_fildes != -1) {
		syslog(LOG_ERR,
		    "ndmp_door_init: ndmpd service is already running.");
		(void) mutex_unlock(&ndmp_doorsrv_mutex);
		return (0);
	}

	if ((ndmp_door_fildes = door_create(ndmp_door_server,
	    NULL, DOOR_UNREF)) < 0) {
		syslog(LOG_ERR, "ndmp_door_init: Could not create door.");
		(void) mutex_unlock(&ndmp_doorsrv_mutex);
		return (-1);
	}

	(void) unlink(NDMP_DOOR_SVC);

	if ((fd = creat(NDMP_DOOR_SVC, 0444)) < 0) {
		syslog(LOG_ERR, "ndmp_door_init: Can't create %s: %m.",
		    NDMP_DOOR_SVC);
		(void) door_revoke(ndmp_door_fildes);
		ndmp_door_fildes = -1;
		(void) mutex_unlock(&ndmp_doorsrv_mutex);
		return (-1);
	}

	(void) close(fd);
	(void) fdetach(NDMP_DOOR_SVC);

	if (fattach(ndmp_door_fildes, NDMP_DOOR_SVC) < 0) {
		syslog(LOG_ERR, "ndmp_door_init: fattach failed %m");
		(void) door_revoke(ndmp_door_fildes);
		ndmp_door_fildes = -1;
		(void) mutex_unlock(&ndmp_doorsrv_mutex);
		return (-1);
	}

	syslog(LOG_DEBUG, "ndmp_door_init: Door server successfully started");
	(void) mutex_unlock(&ndmp_doorsrv_mutex);
	return (0);
}
Exemplo n.º 14
0
/*
 * Create the driver to wpad door
 */
int
wpa_supplicant_door_setup(void *cookie, char *doorname)
{
	struct stat stbuf;
	int error = 0;

	wpa_printf(MSG_DEBUG, "wpa_supplicant_door_setup(%s)", doorname);
	/*
	 * Create the door
	 */
	door_id = door_create(event_handler, cookie,
	    DOOR_UNREF | DOOR_REFUSE_DESC | DOOR_NO_CANCEL);

	if (door_id < 0) {
		error = -1;
		goto out;
	}

	if (stat(doorname, &stbuf) < 0) {
		int newfd;
		if ((newfd = creat(doorname, 0666)) < 0) {
			(void) door_revoke(door_id);
			door_id = -1;
			error = -1;

			goto out;
		}
		(void) close(newfd);
	}

	if (fattach(door_id, doorname) < 0) {
		if ((errno != EBUSY) || (fdetach(doorname) < 0) ||
		    (fattach(door_id, doorname) < 0)) {
			(void) door_revoke(door_id);
			door_id = -1;
			error = -1;

			goto out;
		}
	}

out:
	return (error);
}
Exemplo n.º 15
0
static int
dlmgmt_door_init()
{
	int fd;
	int err;

	/*
	 * Create the door file for dlmgmtd.
	 */
	if ((fd = open(DLMGMT_DOOR, O_CREAT|O_RDONLY, 0644)) == -1) {
		err = errno;
		dlmgmt_log(LOG_ERR, "open(%s) failed: %s",
		    DLMGMT_DOOR, strerror(err));
		return (err);
	}
	(void) close(fd);

	if ((dlmgmt_door_fd = door_create(dlmgmt_handler, NULL,
	    DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
		err = errno;
		dlmgmt_log(LOG_ERR, "door_create() failed: %s",
		    strerror(err));
		return (err);
	}
	if (fattach(dlmgmt_door_fd, DLMGMT_DOOR) != 0) {
		err = errno;
		dlmgmt_log(LOG_ERR, "fattach(%s) failed: %s",
		    DLMGMT_DOOR, strerror(err));
		goto fail;
	}
	if ((err = dlmgmt_set_doorfd(B_TRUE)) != 0) {
		dlmgmt_log(LOG_ERR, "cannot set kernel doorfd: %s",
		    strerror(err));
		(void) fdetach(DLMGMT_DOOR);
		goto fail;
	}

	return (0);
fail:
	(void) door_revoke(dlmgmt_door_fd);
	dlmgmt_door_fd = -1;
	return (err);
}
Exemplo n.º 16
0
static void
afstreams_init_door(int hook_type G_GNUC_UNUSED, gpointer user_data)
{
  AFStreamsSourceDriver *self = (AFStreamsSourceDriver *) user_data;
  struct stat st;
  gint fd;

  if (stat(self->door_filename->str, &st) == -1)
    {
      /* file does not exist, create it */
      fd = creat(self->door_filename->str, 0666);
      if (fd == -1)
        {
          msg_error("Error creating syslog door file",
                    evt_tag_str(EVT_TAG_FILENAME, self->door_filename->str),
                    evt_tag_errno(EVT_TAG_OSERROR, errno),
                    NULL);
          close(fd);
          return;
        }
    }
  fdetach(self->door_filename->str);
  self->door_fd = door_create(afstreams_sd_door_server_proc, NULL, 0);
  if (self->door_fd == -1)
    {
      msg_error("Error creating syslog door",
                evt_tag_str(EVT_TAG_FILENAME, self->door_filename->str),
                evt_tag_errno(EVT_TAG_OSERROR, errno),
                NULL);
      return;
    }
  g_fd_set_cloexec(self->door_fd, TRUE);
  if (fattach(self->door_fd, self->door_filename->str) == -1)
    {
      msg_error("Error attaching syslog door",
                evt_tag_str(EVT_TAG_FILENAME, self->door_filename->str),
                evt_tag_errno(EVT_TAG_OSERROR, errno),
                NULL);
      close(self->door_fd);
      self->door_fd = -1;
      return;
    }
}
Exemplo n.º 17
0
/*
 * Create the picld door
 */
static int
setup_door(void)
{
	struct stat	stbuf;

	(void) door_server_create(picld_server_create_fn);
	(void) pthread_mutex_lock(&door_mutex);
	/*
	 * Create the door
	 */
	door_id = door_create(picld_door_handler, PICLD_DOOR_COOKIE,
	    DOOR_REFUSE_DESC | DOOR_NO_CANCEL | DOOR_PRIVATE);

	if (door_id < 0) {
		(void) pthread_mutex_unlock(&door_mutex);
		return (-1);
	} else {
		(void) pthread_cond_signal(&door_cv);
		(void) pthread_mutex_unlock(&door_mutex);
	}

	if (stat(PICLD_DOOR, &stbuf) < 0) {
		int newfd;
		mode_t old_mask;
		/* ensure that the door file is world-readable */
		old_mask = umask(0);
		newfd = creat(PICLD_DOOR, 0444);
		/* restore the file mode creation mask */
		(void) umask(old_mask);
		if (newfd < 0)
			return (-1);
		(void) close(newfd);
	}

	if (fattach(door_id, PICLD_DOOR) < 0) {
		if ((errno != EBUSY) ||
		    (fdetach(PICLD_DOOR) < 0) ||
		    (fattach(door_id, PICLD_DOOR) < 0))
			return (-1);
	}
	return (0);
}
Exemplo n.º 18
0
void
wpa_supplicant_door_destroy(char *doorname)
{
	wpa_printf(MSG_DEBUG, "wpa_supplicant_door_destroy(%s)\n", doorname);

	if (door_id == -1)
		return;

	if (door_revoke(door_id) == -1) {
		wpa_printf(MSG_ERROR, "failed to door_revoke(%d) %s, exiting.",
		    door_id, strerror(errno));
	}

	if (fdetach(doorname) == -1) {
		wpa_printf(MSG_ERROR, "failed to fdetach %s: %s, exiting.",
		    doorname, strerror(errno));
	}

	(void) close(door_id);
}
Exemplo n.º 19
0
static int
ipmgmt_door_init()
{
	int fd;
	int err;

	/* create the door file for ipmgmtd */
	if ((fd = open(IPMGMT_DOOR, O_CREAT|O_RDONLY, IPADM_FILE_MODE)) == -1) {
		err = errno;
		ipmgmt_log(LOG_ERR, "could not open %s: %s",
		    IPMGMT_DOOR, strerror(err));
		return (err);
	}
	(void) close(fd);

	if ((ipmgmt_door_fd = door_create(ipmgmt_handler, NULL,
	    DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
		err = errno;
		ipmgmt_log(LOG_ERR, "failed to create door: %s", strerror(err));
		return (err);
	}
	/*
	 * fdetach first in case a previous daemon instance exited
	 * ungracefully.
	 */
	(void) fdetach(IPMGMT_DOOR);
	if (fattach(ipmgmt_door_fd, IPMGMT_DOOR) != 0) {
		err = errno;
		ipmgmt_log(LOG_ERR, "failed to attach door to %s: %s",
		    IPMGMT_DOOR, strerror(err));
		goto fail;
	}
	return (0);
fail:
	(void) door_revoke(ipmgmt_door_fd);
	ipmgmt_door_fd = -1;
	return (err);
}
Exemplo n.º 20
0
/*
 * vs_stats_init
 *
 * Invoked on daemon load and unload
 */
int
vs_stats_init(void)
{
	(void) pthread_mutex_lock(&vs_stats_mutex);

	(void) memset(&vscan_stats, 0, sizeof (vs_stats_t));

	/* door initialization */
	if ((vs_stats_door_fd = door_create(vs_stats_door_call,
	    &vs_stats_door_cookie, (DOOR_UNREF | DOOR_REFUSE_DESC))) < 0) {
		vs_stats_door_fd = -1;
	} else {
		(void) fdetach(VS_STATS_DOOR_NAME);
		if (fattach(vs_stats_door_fd, VS_STATS_DOOR_NAME) < 0) {
			(void) door_revoke(vs_stats_door_fd);
			vs_stats_door_fd = -1;
		}
	}

	(void) pthread_mutex_unlock(&vs_stats_mutex);

	return ((vs_stats_door_fd == -1) ? -1 : 0);
}
Exemplo n.º 21
0
static void
lxt_server_enter(int fifo1_wr, int fifo2_rd)
{
	struct stat	stat;
	char		door_path[MAXPATHLEN];
	int		i, dfd, junk = 0;

	/*
	 * Do some sanity checks.  Make sure we've got the fifos
	 * we need passed to us on the correct file descriptors.
	 */
	if ((fstat(fifo1_wr, &stat) != 0) ||
	    ((stat.st_mode & S_IFMT) != S_IFIFO) ||
	    (fstat(fifo2_rd, &stat) != 0) ||
	    ((stat.st_mode & S_IFMT) != S_IFIFO)) {
		lx_err("lx_thunk server aborting, can't contact parent");
		exit(-1);
	}

	/*
	 * Get the initial Linux call handle so we can invoke other
	 * Linux calls.
	 */
	lxh_init = lx_call_init();
	if (lxh_init == NULL) {
		lx_err("lx_thunk server aborting, failed Linux call init");
		exit(-1);
	}

	/* Now lookup other Linux symbols we'll need access to. */
	for (i = 0; lxt_handles[i].lxth_name != NULL; i++) {
		assert(lxt_handles[i].lxth_index == i);
		if ((lxt_handles[i].lxth_handle = lx_call_dlsym(lxh_init,
		    lxt_handles[i].lxth_name)) == NULL) {
			lx_err("lx_thunk server aborting, "
			    "failed Linux symbol lookup: %s",
			    lxt_handles[i].lxth_name);
			exit(-1);
		}
	}

	/* get the path to the door server */
	if (read(fifo2_rd, door_path, sizeof (door_path)) < 0) {
		lx_err("lxt_server_enter: failed to get door path");
		exit(-1);
	}
	(void) close(fifo2_rd);

	/* Create the door server. */
	if ((dfd = door_create(lxt_server, door_path,
	    DOOR_UNREF | DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) < 0) {
		lx_err("lxt_server_enter: door_create() failed");
		exit(-1);
	}

	/* Attach the door to a file system path. */
	(void) fdetach(door_path);
	if (fattach(dfd, door_path) < 0) {
		lx_err("lxt_server_enter: fattach() failed");
		exit(-1);
	}

	/* The door server is ready, signal this via a fifo write */
	(void) write(fifo1_wr, &junk, 1);
	(void) close(fifo1_wr);

	lx_debug("lxt_server_enter: doors server initialized");
	lxt_server_loop();
	/*NOTREACHED*/
}
Exemplo n.º 22
0
int
main(int argc, char ** argv)
{
	int			did;
	int			opt;
	int			errflg = 0;
	int			showstats = 0;
	int			doset = 0;
	int			dofg = 0;
	struct stat		buf;
	sigset_t		myset;
	struct sigaction	sighupaction;
	static void		client_killserver();
	int			debug_level = 0;

	/* setup for localization */
	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);

	openlog("ldap_cachemgr", LOG_PID, LOG_DAEMON);

	if (chdir(NSLDAPDIRECTORY) < 0) {
		(void) fprintf(stderr, gettext("chdir(\"%s\") failed: %s\n"),
		    NSLDAPDIRECTORY, strerror(errno));
		exit(1);
	}

	/*
	 * Correctly set file mode creation mask, so to make the new files
	 * created for door calls being readable by all.
	 */
	(void) umask(0);

	/*
	 *  Special case non-root user here -	he/she/they/it can just print
	 *					stats
	 */

	if (geteuid()) {
		if (argc != 2 || strcmp(argv[1], "-g")) {
			(void) fprintf(stderr,
			    gettext("Must be root to use any option "
			    "other than -g.\n\n"));
			usage(argv[0]);
		}

		if ((__ns_ldap_cache_ping() != SUCCESS) ||
		    (client_getadmin(&current_admin) != 0)) {
			(void) fprintf(stderr,
			    gettext("%s doesn't appear to be running.\n"),
			    argv[0]);
			exit(1);
		}
		(void) client_showstats(&current_admin);
		exit(0);
	}



	/*
	 *  Determine if there is already a daemon running
	 */

	will_become_server = (__ns_ldap_cache_ping() != SUCCESS);

	/*
	 *  load normal config file
	 */

	if (will_become_server) {
		static const ldap_stat_t defaults = {
			0,		/* stat */
			DEFAULTTTL};	/* ttl */

		current_admin.ldap_stat = defaults;
		(void) strcpy(current_admin.logfile, LOGFILE);
	} else {
		if (client_getadmin(&current_admin)) {
			(void) fprintf(stderr, gettext("Cannot contact %s "
			    "properly(?)\n"), argv[0]);
			exit(1);
		}
	}

#ifndef SLP
	while ((opt = getopt(argc, argv, "fKgl:r:d:")) != EOF) {
#else
	while ((opt = getopt(argc, argv, "fKgs:l:r:d:")) != EOF) {
#endif /* SLP */
		ldap_stat_t	*cache;

		switch (opt) {
		case 'K':
			client_killserver();
			exit(0);
			break;
		case 'g':
			showstats++;
			break;
		case 'f':
			dofg++;
			break;
		case 'r':
			doset++;
			cache = getcacheptr("ldap");
			if (!optarg) {
				errflg++;
				break;
			}
			cache->ldap_ttl = atoi(optarg);
			break;
		case 'l':
			doset++;
			(void) strlcpy(current_admin.logfile,
			    optarg, sizeof (current_admin.logfile));
			break;
		case 'd':
			doset++;
			debug_level = atoi(optarg);
			break;
#ifdef SLP
		case 's':	/* undocumented: use dynamic (SLP) config */
			use_slp = 1;
			break;
#endif /* SLP */
		default:
			errflg++;
			break;
		}
	}

	if (errflg)
		usage(argv[0]);

	/*
	 * will not show statistics if no daemon running
	 */
	if (will_become_server && showstats) {
		(void) fprintf(stderr,
		    gettext("%s doesn't appear to be running.\n"),
		    argv[0]);
		exit(1);
	}

	if (!will_become_server) {
		if (showstats) {
			(void) client_showstats(&current_admin);
		}
		if (doset) {
			current_admin.debug_level = debug_level;
			if (client_setadmin(&current_admin) < 0) {
				(void) fprintf(stderr,
				    gettext("Error during admin call\n"));
				exit(1);
			}
		}
		if (!showstats && !doset) {
			(void) fprintf(stderr,
			gettext("%s already running....use '%s "
			    "-K' to stop\n"), argv[0], argv[0]);
		}
		exit(0);
	}

	/*
	 *   daemon from here on
	 */

	if (debug_level) {
		/*
		 * we're debugging...
		 */
		if (strlen(current_admin.logfile) == 0)
			/*
			 * no specified log file
			 */
			(void) strcpy(current_admin.logfile, LOGFILE);
		else
			(void) cachemgr_set_lf(&current_admin,
			    current_admin.logfile);
		/*
		 * validate the range of debug level number
		 * and set the number to current_admin.debug_level
		 */
		if (cachemgr_set_dl(&current_admin, debug_level) < 0) {
				/*
				 * print error messages to the screen
				 * cachemgr_set_dl prints msgs to cachemgr.log
				 * only
				 */
				(void) fprintf(stderr,
				gettext("Incorrect Debug Level: %d\n"
				"It should be between %d and %d\n"),
				    debug_level, DBG_OFF, MAXDEBUG);
			exit(-1);
		}
	} else {
		if (strlen(current_admin.logfile) == 0)
			(void) strcpy(current_admin.logfile, "/dev/null");
			(void) cachemgr_set_lf(&current_admin,
			    current_admin.logfile);
	}

	if (dofg == 0)
		detachfromtty(argv[0]);

	/*
	 * perform some initialization
	 */

	initialize_lookup_clearance();

	if (getldap_init() != 0)
		exit(-1);

	/*
	 * Establish our own server thread pool
	 */

	(void) door_server_create(server_create);
	if (thr_keycreate(&server_key, server_destroy) != 0) {
		logit("thr_keycreate() call failed\n");
		syslog(LOG_ERR,
		    gettext("ldap_cachemgr: thr_keycreate() call failed"));
		perror("thr_keycreate");
		exit(-1);
	}

	/*
	 * Create a door
	 */

	if ((did = door_create(switcher, LDAP_CACHE_DOOR_COOKIE,
	    DOOR_UNREF | DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) < 0) {
		logit("door_create() call failed\n");
		syslog(LOG_ERR, gettext(
		    "ldap_cachemgr: door_create() call failed"));
		perror("door_create");
		exit(-1);
	}

	/*
	 * bind to file system
	 */

	if (stat(LDAP_CACHE_DOOR, &buf) < 0) {
		int	newfd;

		if ((newfd = creat(LDAP_CACHE_DOOR, 0444)) < 0) {
			logit("Cannot create %s:%s\n",
			    LDAP_CACHE_DOOR,
			    strerror(errno));
			exit(1);
		}
		(void) close(newfd);
	}

	if (fattach(did, LDAP_CACHE_DOOR) < 0) {
		if ((errno != EBUSY) ||
		    (fdetach(LDAP_CACHE_DOOR) <  0) ||
		    (fattach(did, LDAP_CACHE_DOOR) < 0)) {
			logit("fattach() call failed\n");
			syslog(LOG_ERR, gettext(
			    "ldap_cachemgr: fattach() call failed"));
			perror("fattach");
			exit(2);
		}
	}

	/* catch SIGHUP revalid signals */
	sighupaction.sa_handler = getldap_revalidate;
	sighupaction.sa_flags = 0;
	(void) sigemptyset(&sighupaction.sa_mask);
	(void) sigemptyset(&myset);
	(void) sigaddset(&myset, SIGHUP);

	if (sigaction(SIGHUP, &sighupaction, NULL) < 0) {
		logit("sigaction() call failed\n");
		syslog(LOG_ERR,
		    gettext("ldap_cachemgr: sigaction() call failed"));
		perror("sigaction");
		exit(1);
	}

	if (thr_sigsetmask(SIG_BLOCK, &myset, NULL) < 0) {
		logit("thr_sigsetmask() call failed\n");
		syslog(LOG_ERR,
		    gettext("ldap_cachemgr: thr_sigsetmask() call failed"));
		perror("thr_sigsetmask");
		exit(1);
	}

	/*
	 *  kick off revalidate threads only if ttl != 0
	 */

	if (thr_create(NULL, NULL, (void *(*)(void*))getldap_refresh,
	    0, 0, NULL) != 0) {
		logit("thr_create() call failed\n");
		syslog(LOG_ERR,
		    gettext("ldap_cachemgr: thr_create() call failed"));
		perror("thr_create");
		exit(1);
	}

	/*
	 *  kick off the thread which refreshes the server info
	 */

	if (thr_create(NULL, NULL, (void *(*)(void*))getldap_serverInfo_refresh,
	    0, 0, NULL) != 0) {
		logit("thr_create() call failed\n");
		syslog(LOG_ERR,
		    gettext("ldap_cachemgr: thr_create() call failed"));
		perror("thr_create");
		exit(1);
	}

#ifdef SLP
	if (use_slp) {
		/* kick off SLP discovery thread */
		if (thr_create(NULL, NULL, (void *(*)(void *))discover,
		    (void *)&refresh, 0, NULL) != 0) {
			logit("thr_create() call failed\n");
			syslog(LOG_ERR, gettext("ldap_cachemgr: thr_create() "
			    "call failed"));
			perror("thr_create");
			exit(1);
		}
	}
#endif /* SLP */

	if (thr_sigsetmask(SIG_UNBLOCK, &myset, NULL) < 0) {
		logit("thr_sigsetmask() call failed\n");
		syslog(LOG_ERR,
		    gettext("ldap_cachemgr: the_sigsetmask() call failed"));
		perror("thr_sigsetmask");
		exit(1);
	}

	/*CONSTCOND*/
	while (1) {
		(void) pause();
	}
	/* NOTREACHED */
	/*LINTED E_FUNC_HAS_NO_RETURN_STMT*/
}


/*
 * Before calling the alloca() function we have to be sure that we won't get
 * beyond the stack. Since we don't know the precise layout of the stack,
 * the address of an automatic of the function gives us a rough idea, plus/minus
 * a bit. We also need a bit more of stackspace after the call to be able
 * to call further functions. Even something as simple as making a system call
 * from within this function can take ~100 Bytes of stackspace.
 */
#define	SAFETY_BUFFER 32 * 1024 /* 32KB */

static
size_t
get_data_size(LineBuf *config_info, int *err_code)
{
	size_t		configSize = sizeof (ldap_return_t);
	dataunion	*buf = NULL; /* For the 'sizeof' purpose */

	if (config_info->str != NULL &&
	    config_info->len >= sizeof (buf->data.ldap_ret.ldap_u.config)) {
		configSize = sizeof (buf->space) +
		    config_info->len -
		    sizeof (buf->data.ldap_ret.ldap_u.config);

		if (!stack_inbounds((char *)&buf -
		    (configSize + SAFETY_BUFFER))) {
			/*
			 * We do not have enough space on the stack
			 * to accomodate the whole DUAProfile
			 */
			logit("The DUAProfile is too big. There is not enough "
			    "space to process it. Ignoring it.\n");
			syslog(LOG_ERR, gettext("ldap_cachemgr: The DUAProfile "
			    "is too big. There is not enough space "
			    "to process it. Ignoring it."));

			*err_code = SERVERERROR;

			free(config_info->str);
			config_info->str = NULL;
			config_info->len = 0;
			configSize = sizeof (ldap_return_t);
		}
	}

	return (configSize);
}
Exemplo n.º 23
0
static void
server_main(int argc, char **argv)
{
	int did;
	int c;
	struct statvfs vfsbuf;
	int imexit = 0;
	pid_t parent;
	char *root = NULL;
	char *sadmdir = NULL;
	hrtime_t delta;
	int dir = 0;
	int dfd;

	(void) set_prog_name("pkgserv");

	openlog("pkgserv", LOG_PID | LOG_ODELAY, LOG_DAEMON);

	while ((c = getopt(argc, argv, "d:eoN:pP:R:r:")) != EOF) {
		switch (c) {
		case 'e':
			imexit = 1;
			break;
		case 'd':
			sadmdir = optarg;
			if (*sadmdir != '/' || strlen(sadmdir) >= PATH_MAX ||
			    access(sadmdir, X_OK) != 0)
				exit(99);
			break;
		case 'N':
			(void) set_prog_name(optarg);
			break;
		case 'o':
			one_shot = B_TRUE;
			verbose = 0;
			break;
		case 'p':
			/*
			 * We are updating possibly many zones; so we're not
			 * dumping based on a short timeout and we will not
			 * exit.
			 */
			permanent = B_TRUE;
			dumptimeout = 3600;
			break;
		case 'P':
			client_pid = atoi(optarg);
			break;
		case 'R':
			root = optarg;
			if (*root != '/' || strlen(root) >= PATH_MAX ||
			    access(root, X_OK) != 0)
				exit(99);
			break;
		case 'r':
			read_only = B_TRUE;
			one_shot = B_TRUE;
			verbose = 0;
			door = optarg;
			break;
		default:
			exit(99);
		}
	}

	if (one_shot && permanent) {
		progerr(gettext("Incorrect Usage"));
		exit(99);
	}

	umem_nofail_callback(no_memory_abort);

	if (root != NULL && strcmp(root, "/") != 0) {
		if (snprintf(pkgdir, PATH_MAX, "%s%s", root,
		    sadmdir == NULL ? SADM_DIR : sadmdir) >= PATH_MAX) {
			exit(99);
		}
	} else {
		if (sadmdir == NULL)
			(void) strcpy(pkgdir, SADM_DIR);
		else
			(void) strcpy(pkgdir, sadmdir);
	}

	if (chdir(pkgdir) != 0) {
		progerr(gettext("can't chdir to %s"), pkgdir);
		exit(2);
	}

	closefrom(3);

	if (!read_only && establish_lock(LOCK) < 0) {
		progerr(gettext(
		    "couldn't lock in %s (server running?): %s"),
		    pkgdir, strerror(errno));
		exit(1);
	}

	did = door_create(pkg_door_srv, 0, DOOR_REFUSE_DESC);
	if (did == -1) {
		progerr("door_create: %s", strerror(errno));
		exit(2);
	}

	(void) fdetach(door);

	if ((dfd = creat(door, 0644)) < 0 || close(dfd) < 0) {
		progerr("door_create: %s", strerror(errno));
		exit(2);
	}

	(void) mutex_lock(&mtx);

	myuid = geteuid();

	(void) sigset(SIGHUP, signal_handler);
	(void) sigset(SIGTERM, signal_handler);
	(void) sigset(SIGINT, signal_handler);
	(void) sigset(SIGQUIT, signal_handler);

	(void) signal(SIGPIPE, SIG_IGN);

	(void) atexit(finish);

	if (fattach(did, door) != 0) {
		progerr(gettext("attach door: %s"), strerror(errno));
		exit(2);
	}
	(void) close(did);

	ecache = umem_cache_create("entry", sizeof (pkgentry_t),
	    sizeof (char *), NULL, NULL, NULL, NULL, NULL, 0);

	avl_create(list, avlcmp, sizeof (pkgentry_t),
	    offsetof(pkgentry_t, avl));

	IS_ST0['\0'] = 1;
	IS_ST0[' '] = 1;
	IS_ST0['\t'] = 1;

	IS_ST0Q['\0'] = 1;
	IS_ST0Q[' '] = 1;
	IS_ST0Q['\t'] = 1;
	IS_ST0Q['='] = 1;

	parse_contents();
	if (parse_log() > 0)
		pkgdump();

	if (imexit)
		exit(0);

	if (statvfs(".", &vfsbuf) != 0) {
		progerr(gettext("statvfs: %s"), strerror(errno));
		exit(2);
	}

	if (strcmp(vfsbuf.f_basetype, "zfs") == 0)
		flushbeforemark = 0;

	/* We've started, tell the parent */
	parent = getppid();
	if (parent != 1)
		(void) kill(parent, SIGUSR1);

	if (!one_shot) {
		int fd;
		(void) setsid();
		fd = open("/dev/null", O_RDWR, 0);
		if (fd >= 0) {
			(void) dup2(fd, STDIN_FILENO);
			(void) dup2(fd, STDOUT_FILENO);
			(void) dup2(fd, STDERR_FILENO);
			if (fd > 2)
				(void) close(fd);
		}
	}

	lastcall = lastchange = gethrtime();

	/*
	 * Start the main thread, here is where we unlock the mutex.
	 */
	for (;;) {
		if (want_to_quit) {
			pkgdump();
			exit(0);
		}
		/* Wait forever when root or when there's a running filter */
		if (write_locked ||
		    (!one_shot && permanent && dir == changes)) {
			(void) cond_wait(&cv, &mtx);
			continue;
		}
		delta = time_since_(lastchange);
		/* Wait until DUMPTIMEOUT after last change before we pkgdump */
		if (delta < dumptimeout * LLNANOSEC) {
			my_cond_reltimedwait(delta, dumptimeout);
			continue;
		}
		/* Client still around? Just wait then. */
		if (client_pid > 1 && kill(client_pid, 0) == 0) {
			lastchange = lastcall = gethrtime();
			continue;
		}
		/* Wait for another EXITTIMEOUT seconds before we exit */
		if ((one_shot || !permanent) && dir == changes) {
			delta = time_since_(lastcall);
			if (delta < EXITTIMEOUT * LLNANOSEC) {
				my_cond_reltimedwait(delta, EXITTIMEOUT);
				continue;
			}
			exit(0);
		}
		pkgdump();
		dir = changes;
	}

	/*NOTREACHED*/
}
Exemplo n.º 24
0
int
_nscd_setup_server(char *execname, char **argv)
{

	int		fd;
	int		errnum;
	int		bind_failed = 0;
	mode_t		old_mask;
	struct stat	buf;
	sigset_t	myset;
	struct sigaction action;
	char		*me = "_nscd_setup_server";

	main_execname = execname;
	main_argv = argv;

	/* Any nscd process is to ignore SIGPIPE */
	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
		errnum = errno;
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
		(me, "signal (SIGPIPE): %s\n", strerror(errnum));
		return (-1);
	}

	keep_open_dns_socket();

	/*
	 * the max number of server threads should be fixed now, so
	 * set flag to indicate that no in-flight change is allowed
	 */
	max_servers_set = 1;

	(void) thr_keycreate(&lookup_state_key, NULL);
	(void) sema_init(&common_sema, frontend_cfg_g.common_worker_threads,
	    USYNC_THREAD, 0);

	/* Establish server thread pool */
	(void) door_server_create(server_create);
	if (thr_keycreate(&server_key, server_destroy) != 0) {
		errnum = errno;
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
		(me, "thr_keycreate (server thread): %s\n",
		    strerror(errnum));
		return (-1);
	}

	/* Create a door */
	if ((fd = door_create(switcher, NAME_SERVICE_DOOR_COOKIE,
	    DOOR_UNREF | DOOR_NO_CANCEL)) < 0) {
		errnum = errno;
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
		(me, "door_create: %s\n", strerror(errnum));
		return (-1);
	}

	/* if not main nscd, no more setup to do */
	if (_whoami != NSCD_MAIN)
		return (fd);

	/* bind to file system */
	if (is_system_labeled() && (getzoneid() == GLOBAL_ZONEID)) {
		if (stat(TSOL_NAME_SERVICE_DOOR, &buf) < 0) {
			int	newfd;

			/* make sure the door will be readable by all */
			old_mask = umask(0);
			if ((newfd = creat(TSOL_NAME_SERVICE_DOOR, 0444)) < 0) {
				errnum = errno;
				_NSCD_LOG(NSCD_LOG_FRONT_END,
				    NSCD_LOG_LEVEL_ERROR)
				(me, "Cannot create %s: %s\n",
				    TSOL_NAME_SERVICE_DOOR,
				    strerror(errnum));
				bind_failed = 1;
			}
			/* rstore the old file mode creation mask */
			(void) umask(old_mask);
			(void) close(newfd);
		}
		if (symlink(TSOL_NAME_SERVICE_DOOR, NAME_SERVICE_DOOR) != 0) {
			if (errno != EEXIST) {
				errnum = errno;
				_NSCD_LOG(NSCD_LOG_FRONT_END,
				    NSCD_LOG_LEVEL_ERROR)
				(me, "Cannot symlink %s: %s\n",
				    NAME_SERVICE_DOOR, strerror(errnum));
				bind_failed = 1;
			}
		}
	} else if (stat(NAME_SERVICE_DOOR, &buf) < 0) {
		int	newfd;

		/* make sure the door will be readable by all */
		old_mask = umask(0);
		if ((newfd = creat(NAME_SERVICE_DOOR, 0444)) < 0) {
			errnum = errno;
			_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
			(me, "Cannot create %s: %s\n", NAME_SERVICE_DOOR,
			    strerror(errnum));
			bind_failed = 1;
		}
		/* rstore the old file mode creation mask */
		(void) umask(old_mask);
		(void) close(newfd);
	}

	if (bind_failed == 1) {
		(void) door_revoke(fd);
		return (-1);
	}

	if (fattach(fd, NAME_SERVICE_DOOR) < 0) {
		if ((errno != EBUSY) ||
		    (fdetach(NAME_SERVICE_DOOR) <  0) ||
		    (fattach(fd, NAME_SERVICE_DOOR) < 0)) {
			errnum = errno;
			_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
			(me, "fattach: %s\n", strerror(errnum));
			(void) door_revoke(fd);
			return (-1);
		}
	}

	/*
	 * kick off routing socket monitor thread
	 */
	if (thr_create(NULL, NULL,
	    (void *(*)(void *))rts_mon, 0, 0, NULL) != 0) {
		errnum = errno;
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
		(me, "thr_create (routing socket monitor): %s\n",
		    strerror(errnum));

		(void) door_revoke(fd);
		return (-1);
	}

	/*
	 * set up signal handler for SIGHUP
	 */
	action.sa_handler = dozip;
	action.sa_flags = 0;
	(void) sigemptyset(&action.sa_mask);
	(void) sigemptyset(&myset);
	(void) sigaddset(&myset, SIGHUP);

	if (sigaction(SIGHUP, &action, NULL) < 0) {
		errnum = errno;
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
		(me, "sigaction (SIGHUP): %s\n", strerror(errnum));

		(void) door_revoke(fd);
		return (-1);
	}

	return (fd);
}
Exemplo n.º 25
0
static void
/*ARGSUSED*/
lxt_server(void *cookie, char *argp, size_t request_size,
    door_desc_t *dp, uint_t n_desc)
{
	/*LINTED*/
	lxt_server_arg_t	*request = (lxt_server_arg_t *)argp;
	lxt_req_t		lxt_req;
	char			*door_path = cookie;

	/* Check if there's no callers left */
	if (argp == DOOR_UNREF_DATA) {
		(void) fdetach(door_path);
		(void) unlink(door_path);
		lx_debug("lxt_thunk_server: no clients, exiting");
		exit(0);
	}

	/* Sanity check the incomming request. */
	if (request_size < sizeof (*request)) {
		/* the lookup failed */
		lx_debug("lxt_thunk_server: invalid request size");
		(void) door_return(NULL, 0, NULL, 0);
		return;
	}

	if ((request->lxt_sa_op < LXT_SERVER_OP_MIN) ||
	    (request->lxt_sa_op > LXT_SERVER_OP_MAX)) {
		lx_debug("lxt_thunk_server: invalid request op");
		(void) door_return(NULL, 0, NULL, 0);
		return;
	}

	/* Handle ping requests immediatly, return here. */
	if (request->lxt_sa_op == LXT_SERVER_OP_PING) {
		lx_debug("lxt_thunk_server: handling ping request");
		request->lxt_sa_success = 1;
		(void) door_return((char *)request, request_size, NULL, 0);
		return;
	}

	lx_debug("lxt_thunk_server: hand off request to Linux thread, "
	    "request = 0x%p", request);

	/* Pack the request up so we can pass it to a Linux thread. */
	lxt_req.lxtr_request = request;
	lxt_req.lxtr_request_size = request_size;
	lxt_req.lxtr_result = NULL;
	lxt_req.lxtr_result_size = 0;
	lxt_req.lxtr_complete = 0;
	(void) cond_init(&lxt_req.lxtr_complete_cv, USYNC_THREAD, NULL);

	/* Pass the request onto a Linux thread. */
	(void) mutex_lock(&lxt_req_lock);
	while (lxt_req_ptr != NULL)
		(void) cond_wait(&lxt_req_cv, &lxt_req_lock);
	lxt_req_ptr = &lxt_req;
	(void) cond_broadcast(&lxt_req_cv);

	/* Wait for the request to be completed. */
	while (lxt_req.lxtr_complete == 0)
		(void) cond_wait(&lxt_req.lxtr_complete_cv, &lxt_req_lock);
	assert(lxt_req_ptr != &lxt_req);
	(void) mutex_unlock(&lxt_req_lock);

	lx_debug("lxt_thunk_server: hand off request completed, "
	    "request = 0x%p", request);

	/*
	 * If door_return() is successfull it never returns, so if we made
	 * it here there was some kind of error, but there's nothing we can
	 * really do about it.
	 */
	(void) door_return(
	    lxt_req.lxtr_result, lxt_req.lxtr_result_size, NULL, 0);
}
Exemplo n.º 26
0
/*
 * setup_mgmt_door -- Create a door portal for management application requests
 *
 * First check to see if another daemon is already running by attempting
 * to send an empty request to the door. If successful it means this
 * daemon should exit.
 */
int
setup_mgmt_door(msg_queue_t *sys_q)
{
	int fd, door_id;
	struct stat buf;
	door_arg_t darg;

	isnslog(LOG_DEBUG, "setup_mgmt_door", "entered");
	/* check if a door is already running. */
	if ((fd = open(ISNS_DOOR_NAME, 0)) >= 0) {
		darg.data_ptr = "<?xml version='1.0' encoding='UTF-8'?>"
				"<isnsRequest><get><isnsObject>"
				"<DiscoveryDomain name=\"default\">"
				"</DiscoveryDomain></isnsObject></get>"
				"</isnsRequest>";
		darg.data_size = xmlStrlen((xmlChar *)darg.data_ptr) + 1;
		darg.desc_ptr = NULL;
		darg.desc_num = 0;
		darg.rbuf = NULL;
		darg.rsize = 0;

		if (door_call(fd, &darg) == 0) {
			/* door already running. */
			(void) close(fd);
			isnslog(LOG_DEBUG, "setup_mgmt_door",
			    "management door is already runninng.");
			if (darg.rsize > darg.data_size) {
			    (void) munmap(darg.rbuf, darg.rsize);
			}
			door_created = B_FALSE;
			return (0);
		}
		(void) close(fd);
	}

	if ((door_id = door_create(door_server, (void *)sys_q, 0)) < 0) {
		isnslog(LOG_DEBUG, "setup_mgmt_door",
			"Failed to create managment door");
		exit(1);
	}

	if (stat(ISNS_DOOR_NAME, &buf) < 0) {
	    if ((fd = creat(ISNS_DOOR_NAME, 0666)) < 0) {
		isnslog(LOG_DEBUG, "setup_mgmt_door",
		    "open failed on %s errno = %d", ISNS_DOOR_NAME, errno);
		exit(1);
	    }
	    (void) close(fd);
	}

	/* make sure the file permission set to general access. */
	(void) chmod(ISNS_DOOR_NAME, 0666);
	(void) fdetach(ISNS_DOOR_NAME);

	if (fattach(door_id, ISNS_DOOR_NAME) < 0) {
		syslog(LOG_DEBUG, "setup_mgmt_door",
		    "fattach failed on %s errno=%d",
		    ISNS_DOOR_NAME, errno);
		return (-1);
	}

	door_created = B_TRUE;

	return (0);
}
Exemplo n.º 27
0
int
main(int argc, char **argv)
{
	static const int door_attrs =
	    DOOR_REFUSE_DESC | DOOR_NO_CANCEL;
	sigset_t oldmask, tmpmask;
	char *env, *door_path = NULL;
	int door_fd = -1, tmp_fd = -1;
	int err, i, sig;
	int rc = EXIT_FAIL;

	/* Debugging support. */
	if ((env = getenv("SMBFS_DEBUG")) != NULL) {
		smb_debug = atoi(env);
		if (smb_debug < 1)
			smb_debug = 1;
	}

	/*
	 * Find out if an IOD is already running.
	 * If so, we lost a harmless startup race.
	 * An IOD did start, so exit success.
	 */
	err = smb_iod_open_door(&door_fd);
	if (err == 0) {
		close(door_fd);
		door_fd = -1;
		DPRINT("main: already running\n");
		exit(EXIT_OK);
	}

	/*
	 * Create a file for the door.
	 */
	door_path = smb_iod_door_path();
	unlink(door_path);
	tmp_fd = open(door_path, O_RDWR|O_CREAT|O_EXCL, 0600);
	if (tmp_fd < 0) {
		perror(door_path);
		exit(EXIT_FAIL);
	}
	close(tmp_fd);
	tmp_fd = -1;


	/*
	 * Close FDs 0,1,2 so we don't have a TTY, and
	 * re-open them on /dev/null so they won't be
	 * used for device handles (etc.) later, and
	 * we don't have to worry about printf calls
	 * or whatever going to these FDs.
	 */
	for (i = 0; i < 3; i++) {
		/* Exception: If smb_debug, keep stderr */
		if (smb_debug && i == 2)
			break;
		close(i);
		tmp_fd = open("/dev/null", O_RDWR);
		if (tmp_fd < 0)
			perror("/dev/null");
		if (tmp_fd != i)
			DPRINT("Open /dev/null - wrong fd?\n");
	}

	/*
	 * Become session leader.
	 */
	setsid();

	/*
	 * Create door service threads with signals blocked.
	 */
	sigfillset(&tmpmask);
	sigprocmask(SIG_BLOCK, &tmpmask, &oldmask);

	/* Setup the door service. */
	door_fd = door_create(iod_dispatch, NULL, door_attrs);
	if (door_fd < 0) {
		fprintf(stderr, "%s: door_create failed\n", argv[0]);
		rc = EXIT_FAIL;
		goto errout;
	}
	fdetach(door_path);
	if (fattach(door_fd, door_path) < 0) {
		fprintf(stderr, "%s: fattach failed\n", argv[0]);
		rc = EXIT_FAIL;
		goto errout;
	}

	/*
	 * Post the initial alarm, and then just
	 * wait for signals.
	 */
	alarm(ALARM_TIME);
again:
	sig = sigwait(&tmpmask);
	DPRINT("main: sig=%d\n", sig);

	/*
	 * If a door call races with the alarm, ignore the alarm.
	 * It will be rescheduled when the threads go away.
	 */
	mutex_lock(&iod_mutex);
	if (sig == SIGALRM && iod_thr_count > 0) {
		mutex_unlock(&iod_mutex);
		goto again;
	}
	iod_terminating = 1;
	mutex_unlock(&iod_mutex);
	rc = EXIT_OK;

errout:
	fdetach(door_path);
	door_revoke(door_fd);
	door_fd = -1;
	unlink(door_path);

	return (rc);
}