/* * 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); }
/* 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); }
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"); }
/* * 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); }
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)); } }
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); }
/* * 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); }
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); }
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); }
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); }
/* * 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); }
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); }
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); }
/* * 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); }
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); }
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; } }
/* * 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); }
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); }
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); }
/* * 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); }
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*/ }
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(¤t_admin) != 0)) { (void) fprintf(stderr, gettext("%s doesn't appear to be running.\n"), argv[0]); exit(1); } (void) client_showstats(¤t_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(¤t_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(¤t_admin); } if (doset) { current_admin.debug_level = debug_level; if (client_setadmin(¤t_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(¤t_admin, current_admin.logfile); /* * validate the range of debug level number * and set the number to current_admin.debug_level */ if (cachemgr_set_dl(¤t_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(¤t_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); }
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*/ }
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); }
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); }
/* * 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); }
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); }