bool SharedMemoryListener::isTrustEvent(Notification *notification) {
    bool trustEvent = false;

    switch (notification->event) {
        case kSecDefaultChangedEvent:
        case kSecKeychainListChangedEvent:
        case kSecTrustSettingsChangedEvent:
            trustEvent = true;
            break;
        case kSecAddEvent:
        case kSecDeleteEvent:
        case kSecUpdateEvent:
            {
                NameValueDictionary dictionary (notification->data);
                const NameValuePair *item = dictionary.FindByName(ITEM_KEY);
                if (item && (CSSM_DB_RECORDTYPE)getRecordType(item->Value()) == CSSM_DL_DB_RECORD_X509_CERTIFICATE) {
                    trustEvent = true;
                }
            }
            break;
        default:
            break;
    }

    if (trustEvent) {
        uint32_t result = notify_post(kSecServerCertificateTrustNotification);
        if (result != NOTIFY_STATUS_OK) {
            secdebug("MDSPRIVACY","Certificate trust event notification failed: %d", result);
        }
    }

    secdebug("MDSPRIVACY","[%03d] Event is %s trust event", mUID, trustEvent?"a":"not a");
    return trustEvent;
}
void SharedMemoryListener::action ()
{
	secinfo("notify", "Posted notification to clients.");
    secdebug("MDSPRIVACY","[%03d] Posted notification to clients", mUID);
	notify_post (mSegmentName.c_str ());
	mActive = false;
}
示例#3
0
/*
 * GuizmOVPN_Error(int errorno) :
 *      Send notification when an error occurs
 */
void GuizmOVPN_Error(int errorno)
{
	switch(errorno)
	{
		case EHOSTUNREACH:
			notify_post("com.guizmo.openvpn/NoRouteToHost");
			break;
			
		case EADDRNOTAVAIL:
			notify_post("com.guizmo.openvpn/CantAssignRequestedAddress");
			break;
            
		case HOST_NOT_FOUND:
			notify_post("com.guizmo.openvpn/HostNotFound");
			break;
	}
}
    void post_notification()
    {
#if FISH_NOTIFYD_AVAILABLE
        uint32_t status = notify_post(name.c_str());
        if (status != NOTIFY_STATUS_OK)
        {
            fprintf(stderr, "Warning: notify_post() failed with status %u. Universal variable notifications may not be sent.", status);
        }
#endif
    }
STATIC void
prefs_notify_change(void)
{
    uint32_t	status;

    status = notify_post(kEAPSIMAKAPrefsChangedNotification);
    if (status != NOTIFY_STATUS_OK) {
	EAPLOG_FL(LOG_NOTICE, "notify_post returned %d", status);
    }
    return;
}
示例#6
0
/*
 * Get the cached auditing state.
 */
int
auditd_get_state(void)
{

	if (auditing_state == AUD_STATE_INIT) {
		init_audit_state();
		notify_post(__BSM_INTERNAL_NOTIFY_KEY);
	}

	return (auditing_state);
}
static void
post_network_changed(void)
{
	if (network_changed) {
		uint32_t	status;

		status = notify_post(_SC_NOTIFY_NETWORK_CHANGE);
		if (status != NOTIFY_STATUS_OK) {
			SCLog(TRUE, LOG_ERR, CFSTR("notify_post() failed: error=%ld"), status);
		}

		network_changed = FALSE;
	}

	return;
}
示例#8
0
文件: daemon.c 项目: sristi194/uubt
static void daemon_sigint_handler(int param){
    
#ifdef USE_BLUETOOL
    // notify daemons
    notify_post("ch.ringwald.btstack.stopped");
#endif
    
    log_info(" <= SIGINT received, shutting down..\n");    

    hci_power_control( HCI_POWER_OFF);
    hci_close();
    
    log_info("Good bye, see you.\n");    
    
    exit(0);
}
示例#9
0
/*
 * Update the cached auditing state.  Let other tasks that may be caching it
 * as well to update their state via notify(3).
 */
void
auditd_set_state(int state)
{
	int old_auditing_state = auditing_state;

	if (state == AUD_STATE_INIT)
		init_audit_state();
	else
		auditing_state = state;

	if (auditing_state != old_auditing_state) {
		notify_post(__BSM_INTERNAL_NOTIFY_KEY);

		if (auditing_state == AUD_STATE_ENABLED)
			auditd_log_notice("Auditing enabled");	
		if (auditing_state == AUD_STATE_DISABLED)
			auditd_log_notice("Auditing disabled");
	}
}
示例#10
0
//
// Execute an atomic change to existing records in the authority table.
//
CFDictionaryRef PolicyEngine::manipulateRules(const std::string &stanza,
	CFTypeRef inTarget, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context)
{
	SQLite::Transaction xact(*this, SQLite3::Transaction::deferred, "rule_change");
	SQLite::Statement action(*this);
	authorizeUpdate(flags, context);
	selectRules(action, stanza, "authority", inTarget, type, flags, context);
	action.execute();
	unsigned int changes = this->changes();	// latch change count
	// We MUST purge objects with priority <= MAX(priority of any changed rules);
	// but for now we just get lazy and purge them ALL.
	if (changes) {
		this->purgeObjects(1.0E100);
		xact.commit();
		notify_post(kNotifySecAssessmentUpdate);
		return cfmake<CFDictionaryRef>("{%O=%d}", kSecAssessmentUpdateKeyCount, changes);
	}
	// no change; return an error
	MacOSError::throwMe(errSecCSNoMatches);
}
示例#11
0
static int PostNotifications(size_t noteCount, const char **noteNames)
    // Implements the "post" command.  Post the noteCount notifications whose 
    // names are in the noteNames array.
{
    int         retVal;
    uint32_t    noteErr;
    size_t      noteIndex;
    
    noteErr = NOTIFY_STATUS_OK;
    for (noteIndex = 0; noteIndex < noteCount; noteIndex++) {
        noteErr = notify_post(noteNames[noteIndex]);
        if (noteErr != NOTIFY_STATUS_OK) {
            break;
        }
    }
    if (noteErr == NOTIFY_STATUS_OK) {
        retVal = EXIT_SUCCESS;
    } else {
        PrintNotifyError("post failed", noteNames[noteIndex], noteErr);
        retVal = EXIT_FAILURE;
    }
    return retVal;
}
示例#12
0
文件: daemon.c 项目: sristi194/uubt
int main (int argc,  char * const * argv){
    
    static int tcp_flag = 0;
    
    while (1) {
        static struct option long_options[] = {
            { "tcp", no_argument, &tcp_flag, 1 },
            { "help", no_argument, 0, 0 },
            { 0,0,0,0 } // This is a filler for -1
        };
        
        int c;
        int option_index = -1;
        
        c = getopt_long(argc, argv, "h", long_options, &option_index);
        
        if (c == -1) break; // no more option
        
        // treat long parameter first
        if (option_index == -1) {
            switch (c) {
                case '?':
                case 'h':
                    usage(argv[0]);
                    return 0;
                    break;
            }
        } else {
            switch (option_index) {
                case 1:
                    usage(argv[0]);
                    return 0;
                    break;
            }
        }
    }
    
    // make stdout unbuffered
    setbuf(stdout, NULL);
    log_error("BTdaemon started\n");

    // handle CTRL-c
    signal(SIGINT, daemon_sigint_handler);
    // handle SIGTERM - suggested for launchd
    signal(SIGTERM, daemon_sigint_handler);
    // handle SIGPIPE
    struct sigaction act;
    act.sa_handler = SIG_IGN;
    sigemptyset (&act.sa_mask);
    act.sa_flags = 0;
    sigaction (SIGPIPE, &act, NULL);
    
    bt_control_t * control = NULL;
    
#ifdef HAVE_TRANSPORT_H4
    config.device_name   = UART_DEVICE;
    config.baudrate_init = UART_SPEED;
    config.baudrate_main = 0;
    config.flowcontrol = 1;
#if defined(USE_BLUETOOL) && defined(USE_POWERMANAGEMENT)
    if (bt_control_iphone_power_management_supported()){
        // use default (max) UART baudrate over netraph interface
        config.baudrate_init = 0;
        transport = hci_transport_h4_iphone_instance();
    } else {
        transport = hci_transport_h4_instance();
    }
#else
    transport = hci_transport_h4_instance();
#endif
#endif

#ifdef HAVE_TRANSPORT_USB
    transport = hci_transport_usb_instance();
#endif

#ifdef USE_BLUETOOL
    control = &bt_control_iphone;
#endif
    
#if defined(USE_BLUETOOL) && defined(USE_POWERMANAGEMENT)
    if (bt_control_iphone_power_management_supported()){
        hci_transport_h4_iphone_set_enforce_wake_device("/dev/btwake");
    }
#endif

#ifdef USE_SPRINGBOARD
    bluetooth_status_handler = platform_iphone_status_handler;
    platform_iphone_register_window_manager_restart(update_ui_status);
    platform_iphone_register_preferences_changed(preferences_changed_callback);
#endif
    
#ifdef REMOTE_DEVICE_DB
    remote_device_db = &REMOTE_DEVICE_DB;
#endif

    run_loop_init(RUN_LOOP_POSIX);
    
    // init power management notifications
    if (control && control->register_for_power_notifications){
        control->register_for_power_notifications(power_notification_callback);
    }

    // logging
    loggingEnabled = 0;
    int newLoggingEnabled = 1;
#ifdef USE_BLUETOOL
    // iPhone has toggle in Preferences.app
    newLoggingEnabled = platform_iphone_logging_enabled();
#endif
    daemon_set_logging_enabled(newLoggingEnabled);
    
    // init HCI
    hci_init(transport, &config, control, remote_device_db);

#ifdef USE_BLUETOOL
    // iPhone doesn't use SSP yet as there's no UI for it yet and auto accept is not an option
    hci_ssp_set_enable(0);
#endif
    // init L2CAP
    l2cap_init();
    l2cap_register_packet_handler(daemon_packet_handler);
    timeout.process = daemon_no_connections_timeout;

#ifdef HAVE_RFCOMM
    log_info("config.h: HAVE_RFCOMM\n");
    rfcomm_init();
    rfcomm_register_packet_handler(daemon_packet_handler);
#endif
    
#ifdef HAVE_SDP
    sdp_init();
    sdp_register_packet_handler(daemon_packet_handler);
#endif
    
#ifdef USE_LAUNCHD
    socket_connection_create_launchd();
#else
    // create server
    if (tcp_flag) {
        socket_connection_create_tcp(BTSTACK_PORT);
    } else {
        socket_connection_create_unix(BTSTACK_UNIX);
    }
#endif
    socket_connection_register_packet_callback(daemon_client_handler);
        
#ifdef USE_BLUETOOL 
    // notify daemons
    notify_post("ch.ringwald.btstack.started");

    // spawn thread to have BTstack run loop on new thread, while main thread is used to keep CFRunLoop
    pthread_t run_loop;
    pthread_create(&run_loop, NULL, &run_loop_thread, NULL);

    // needed to receive notifications
    CFRunLoopRun();
#endif
    
    // go!
    run_loop_execute();
    return 0;
}
示例#13
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int			i;		/* Looping var */
  char			*opt;		/* Option character */
  int			fg;		/* Run in the foreground */
  int			fds;		/* Number of ready descriptors */
  cupsd_client_t	*con;		/* Current client */
  cupsd_job_t		*job;		/* Current job */
  cupsd_listener_t	*lis;		/* Current listener */
  time_t		current_time,	/* Current time */
			activity,	/* Client activity timer */
			senddoc_time,	/* Send-Document time */
			expire_time,	/* Subscription expire time */
			report_time,	/* Malloc/client/job report time */
			event_time;	/* Last event notification time */
  long			timeout;	/* Timeout for cupsdDoSelect() */
  struct rlimit		limit;		/* Runtime limit */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction	action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
#ifdef __sgi
  cups_file_t		*fp;		/* Fake lpsched lock file */
  struct stat		statbuf;	/* Needed for checking lpsched FIFO */
#endif /* __sgi */
  int			run_as_child = 0;
					/* Needed for background fork/exec */
#ifdef __APPLE__
  int			use_sysman = !getuid();
					/* Use system management functions? */
#else
  time_t		netif_time = 0;	/* Time since last network update */
#endif /* __APPLE__ */
#if HAVE_LAUNCHD
  int			launchd_idle_exit;
					/* Idle exit on select timeout? */
#endif	/* HAVE_LAUNCHD */


#ifdef HAVE_GETEUID
 /*
  * Check for setuid invocation, which we do not support!
  */

  if (getuid() != geteuid())
  {
    fputs("cupsd: Cannot run as a setuid program\n", stderr);
    return (1);
  }
#endif /* HAVE_GETEUID */

 /*
  * Check for command-line arguments...
  */

  fg = 0;

#ifdef HAVE_LAUNCHD
  if (getenv("CUPSD_LAUNCHD"))
  {
    Launchd = 1;
    fg      = 1;
  }
#endif /* HAVE_LAUNCHD */

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-')
      for (opt = argv[i] + 1; *opt != '\0'; opt ++)
        switch (*opt)
	{
	  case 'C' : /* Run as child with config file */
              run_as_child = 1;
	      fg           = -1;

	  case 'c' : /* Configuration file */
	      i ++;
	      if (i >= argc)
	      {
	        _cupsLangPuts(stderr, _("cupsd: Expected config filename "
		                        "after \"-c\" option."));
	        usage(1);
	      }

              if (argv[i][0] == '/')
	      {
	       /*
	        * Absolute directory...
		*/

		cupsdSetString(&ConfigurationFile, argv[i]);
              }
	      else
	      {
	       /*
	        * Relative directory...
		*/

                char *current;		/* Current directory */


	       /*
	        * Allocate a buffer for the current working directory to
		* reduce run-time stack usage; this approximates the
		* behavior of some implementations of getcwd() when they
		* are passed a NULL pointer.
	        */

                if ((current = malloc(1024)) == NULL)
		{
		  _cupsLangPuts(stderr,
		                _("cupsd: Unable to get current directory."));
                  return (1);
		}

		if (!getcwd(current, 1024))
		{
		  _cupsLangPuts(stderr,
		                _("cupsd: Unable to get current directory."));
                  free(current);
		  return (1);
		}

		cupsdSetStringf(&ConfigurationFile, "%s/%s", current, argv[i]);
		free(current);
              }
	      break;

          case 'f' : /* Run in foreground... */
	      fg = 1;
	      break;

          case 'F' : /* Run in foreground, but disconnect from terminal... */
	      fg = -1;
	      break;

          case 'h' : /* Show usage/help */
	      usage(0);
	      break;

          case 'l' : /* Started by launchd... */
#ifdef HAVE_LAUNCHD
	      Launchd = 1;
	      fg      = 1;
#else
	      _cupsLangPuts(stderr, _("cupsd: launchd(8) support not compiled "
	                              "in, running in normal mode."));
              fg = 0;
#endif /* HAVE_LAUNCHD */
	      break;

          case 'p' : /* Stop immediately for profiling */
              fputs("cupsd: -p (startup profiling) is for internal testing "
                    "use only!\n", stderr);
	      stop_scheduler = 1;
	      fg             = 1;
	      break;

          case 'P' : /* Disable security profiles */
              fputs("cupsd: -P (disable security profiles) is for internal "
                    "testing use only!\n", stderr);
	      UseProfiles = 0;
	      break;

#ifdef __APPLE__
          case 'S' : /* Disable system management functions */
              fputs("cupsd: -S (disable system management) for internal "
                    "testing use only!\n", stderr);
	      use_sysman = 0;
	      break;
#endif /* __APPLE__ */

          case 't' : /* Test the cupsd.conf file... */
	      TestConfigFile = 1;
	      fg             = 1;
	      break;

	  default : /* Unknown option */
              _cupsLangPrintf(stderr, _("cupsd: Unknown option \"%c\" - "
	                                "aborting."), *opt);
	      usage(1);
	      break;
	}
    else
    {
      _cupsLangPrintf(stderr, _("cupsd: Unknown argument \"%s\" - aborting."),
                      argv[i]);
      usage(1);
    }

  if (!ConfigurationFile)
    cupsdSetString(&ConfigurationFile, CUPS_SERVERROOT "/cupsd.conf");

 /*
  * If the user hasn't specified "-f", run in the background...
  */

  if (!fg)
  {
   /*
    * Setup signal handlers for the parent...
    */

#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
    sigset(SIGUSR1, parent_handler);
    sigset(SIGCHLD, parent_handler);

    sigset(SIGHUP, SIG_IGN);
#elif defined(HAVE_SIGACTION)
    memset(&action, 0, sizeof(action));
    sigemptyset(&action.sa_mask);
    sigaddset(&action.sa_mask, SIGUSR1);
    action.sa_handler = parent_handler;
    sigaction(SIGUSR1, &action, NULL);
    sigaction(SIGCHLD, &action, NULL);

    sigemptyset(&action.sa_mask);
    action.sa_handler = SIG_IGN;
    sigaction(SIGHUP, &action, NULL);
#else
    signal(SIGUSR1, parent_handler);
    signal(SIGCLD, parent_handler);

    signal(SIGHUP, SIG_IGN);
#endif /* HAVE_SIGSET */

    if (fork() > 0)
    {
     /*
      * OK, wait for the child to startup and send us SIGUSR1 or to crash
      * and the OS send us SIGCHLD...  We also need to ignore SIGHUP which
      * might be sent by the init script to restart the scheduler...
      */

      for (; parent_signal == 0;)
        sleep(1);

      if (parent_signal == SIGUSR1)
        return (0);

      if (wait(&i) < 0)
      {
        perror("cupsd");
	return (1);
      }
      else if (WIFEXITED(i))
      {
        fprintf(stderr, "cupsd: Child exited with status %d\n",
	        WEXITSTATUS(i));
	return (2);
      }
      else
      {
        fprintf(stderr, "cupsd: Child exited on signal %d\n", WTERMSIG(i));
	return (3);
      }
    }

#ifdef __OpenBSD__
   /*
    * Call _thread_sys_closefrom() so the child process doesn't reset the
    * parent's file descriptors to be blocking.  This is a workaround for a
    * limitation of userland libpthread on OpenBSD.
    */

    _thread_sys_closefrom(0);
#endif /* __OpenBSD__ */

   /*
    * Since CoreFoundation and DBUS both create fork-unsafe data on execution of
    * a program, and since this kind of really unfriendly behavior seems to be
    * more common these days in system libraries, we need to re-execute the
    * background cupsd with the "-C" option to avoid problems.  Unfortunately,
    * we also have to assume that argv[0] contains the name of the cupsd
    * executable - there is no portable way to get the real pathname...
    */

    execlp(argv[0], argv[0], "-C", ConfigurationFile, (char *)0);
    exit(errno);
  }

  if (fg < 1)
  {
   /*
    * Make sure we aren't tying up any filesystems...
    */

    chdir("/");

#ifndef DEBUG
   /*
    * Disable core dumps...
    */

    getrlimit(RLIMIT_CORE, &limit);
    limit.rlim_cur = 0;
    setrlimit(RLIMIT_CORE, &limit);

   /*
    * Disconnect from the controlling terminal...
    */

    setsid();

   /*
    * Close all open files...
    */

    getrlimit(RLIMIT_NOFILE, &limit);

    for (i = 0; i < limit.rlim_cur && i < 1024; i ++)
      close(i);

   /*
    * Redirect stdin/out/err to /dev/null...
    */

    if ((i = open("/dev/null", O_RDONLY)) != 0)
    {
      dup2(i, 0);
      close(i);
    }

    if ((i = open("/dev/null", O_WRONLY)) != 1)
    {
      dup2(i, 1);
      close(i);
    }

    if ((i = open("/dev/null", O_WRONLY)) != 2)
    {
      dup2(i, 2);
      close(i);
    }
#endif /* DEBUG */
  }

 /*
  * Set the timezone info...
  */

  tzset();

#ifdef LC_TIME
  setlocale(LC_TIME, "");
#endif /* LC_TIME */

 /*
  * Set the maximum number of files...
  */

  getrlimit(RLIMIT_NOFILE, &limit);

#if !defined(HAVE_POLL) && !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE)
  if (limit.rlim_max > FD_SETSIZE)
    MaxFDs = FD_SETSIZE;
  else
#endif /* !HAVE_POLL && !HAVE_EPOLL && !HAVE_KQUEUE */
#ifdef RLIM_INFINITY
  if (limit.rlim_max == RLIM_INFINITY)
    MaxFDs = 16384;
  else
#endif /* RLIM_INFINITY */
    MaxFDs = limit.rlim_max;

  limit.rlim_cur = MaxFDs;

  setrlimit(RLIMIT_NOFILE, &limit);

  cupsdStartSelect();

 /*
  * Read configuration...
  */

  if (!cupsdReadConfiguration())
  {
    if (TestConfigFile)
      printf("%s contains errors\n", ConfigurationFile);
    else
      syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
	     ConfigurationFile);
    return (1);
  }
  else if (TestConfigFile)
  {
    printf("%s is OK\n", ConfigurationFile);
    return (0);
  }

 /*
  * Clean out old temp files and printer cache data.
  */

  if (!strncmp(TempDir, RequestRoot, strlen(RequestRoot)))
    cupsdCleanFiles(TempDir, NULL);

  cupsdCleanFiles(CacheDir, "*.ipp");

#if HAVE_LAUNCHD
  if (Launchd)
  {
   /*
    * If we were started by launchd get the listen sockets file descriptors...
    */

    launchd_checkin();
    launchd_checkout();
  }
#endif /* HAVE_LAUNCHD */

 /*
  * Startup the server...
  */

  httpInitialize();

  cupsdStartServer();

 /*
  * Catch hangup and child signals and ignore broken pipes...
  */

#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
  sigset(SIGCHLD, sigchld_handler);
  sigset(SIGHUP, sighup_handler);
  sigset(SIGPIPE, SIG_IGN);
  sigset(SIGTERM, sigterm_handler);
#elif defined(HAVE_SIGACTION)
  memset(&action, 0, sizeof(action));

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGTERM);
  sigaddset(&action.sa_mask, SIGCHLD);
  action.sa_handler = sigchld_handler;
  sigaction(SIGCHLD, &action, NULL);

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGHUP);
  action.sa_handler = sighup_handler;
  sigaction(SIGHUP, &action, NULL);

  sigemptyset(&action.sa_mask);
  action.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &action, NULL);

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGTERM);
  sigaddset(&action.sa_mask, SIGCHLD);
  action.sa_handler = sigterm_handler;
  sigaction(SIGTERM, &action, NULL);
#else
  signal(SIGCLD, sigchld_handler);	/* No, SIGCLD isn't a typo... */
  signal(SIGHUP, sighup_handler);
  signal(SIGPIPE, SIG_IGN);
  signal(SIGTERM, sigterm_handler);
#endif /* HAVE_SIGSET */

#ifdef __sgi
 /*
  * Try to create a fake lpsched lock file if one is not already there.
  * Some Adobe applications need it under IRIX in order to enable
  * printing...
  */

  if ((fp = cupsFileOpen("/var/spool/lp/SCHEDLOCK", "w")) == NULL)
  {
    syslog(LOG_LPR, "Unable to create fake lpsched lock file "
                    "\"/var/spool/lp/SCHEDLOCK\"\' - %s!",
           strerror(errno));
  }
  else
  {
    fchmod(cupsFileNumber(fp), 0644);
    fchown(cupsFileNumber(fp), User, Group);

    cupsFileClose(fp);
  }
#endif /* __sgi */

 /*
  * Initialize authentication certificates...
  */

  cupsdInitCerts();

 /*
  * If we are running in the background, signal the parent process that
  * we are up and running...
  */

  if (!fg || run_as_child)
  {
   /*
    * Send a signal to the parent process, but only if the parent is
    * not PID 1 (init).  This avoids accidentally shutting down the
    * system on OpenBSD if you CTRL-C the server before it is up...
    */

    i = getppid();	/* Save parent PID to avoid race condition */

    if (i != 1)
      kill(i, SIGUSR1);
  }

#ifdef __APPLE__
 /*
  * Start power management framework...
  */

  if (use_sysman)
    cupsdStartSystemMonitor();
#endif /* __APPLE__ */

 /*
  * Send server-started event...
  */

#ifdef HAVE_LAUNCHD
  if (Launchd)
    cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
                  "Scheduler started via launchd.");
  else
#endif /* HAVE_LAUNCHD */
  if (fg)
    cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
                  "Scheduler started in foreground.");
  else
    cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
                  "Scheduler started in background.");

 /*
  * Start any pending print jobs...
  */

  cupsdCheckJobs();

 /*
  * Loop forever...
  */

  current_time  = time(NULL);
  event_time    = current_time;
  expire_time   = current_time;
  fds           = 1;
  report_time   = 0;
  senddoc_time  = current_time;

  while (!stop_scheduler)
  {
   /*
    * Check if there are dead children to handle...
    */

    if (dead_children)
      process_children();

   /*
    * Check if we need to load the server configuration file...
    */

    if (NeedReload)
    {
     /*
      * Close any idle clients...
      */

      if (cupsArrayCount(Clients) > 0)
      {
	for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
	     con;
	     con = (cupsd_client_t *)cupsArrayNext(Clients))
	  if (con->http.state == HTTP_WAITING)
	    cupsdCloseClient(con);
	  else
	    con->http.keep_alive = HTTP_KEEPALIVE_OFF;

        cupsdPauseListening();
      }

     /*
      * Restart if all clients are closed and all jobs finished, or
      * if the reload timeout has elapsed...
      */

      if ((cupsArrayCount(Clients) == 0 &&
           (cupsArrayCount(PrintingJobs) == 0 || NeedReload != RELOAD_ALL)) ||
          (time(NULL) - ReloadTime) >= ReloadTimeout)
      {
       /*
	* Shutdown the server...
	*/

        DoingShutdown = 1;

	cupsdStopServer();

       /*
	* Read configuration...
	*/

        if (!cupsdReadConfiguration())
        {
          syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
		 ConfigurationFile);
          break;
	}

#if HAVE_LAUNCHD
	if (Launchd)
	{
	 /*
	  * If we were started by launchd, get the listen socket file
	  * descriptors...
	  */

	  launchd_checkin();
	  launchd_checkout();
	}
#endif /* HAVE_LAUNCHD */

       /*
        * Startup the server...
        */

        DoingShutdown = 0;

        cupsdStartServer();

       /*
        * Send a server-restarted event...
	*/

        cupsdAddEvent(CUPSD_EVENT_SERVER_RESTARTED, NULL, NULL,
                      "Scheduler restarted.");
      }
    }

   /*
    * Check for available input or ready output.  If cupsdDoSelect()
    * returns 0 or -1, something bad happened and we should exit
    * immediately.
    *
    * Note that we at least have one listening socket open at all
    * times.
    */

    if ((timeout = select_timeout(fds)) > 1 && LastEvent)
      timeout = 1;

#if HAVE_LAUNCHD
   /*
    * If no other work is scheduled and we're being controlled by
    * launchd then timeout after 'LaunchdTimeout' seconds of
    * inactivity...
    */

    if (timeout == 86400 && Launchd && LaunchdTimeout &&
        !cupsArrayCount(ActiveJobs) &&
	(!Browsing || !BrowseLocalProtocols || !cupsArrayCount(Printers)))
    {
      timeout		= LaunchdTimeout;
      launchd_idle_exit = 1;
    }
    else
      launchd_idle_exit = 0;
#endif	/* HAVE_LAUNCHD */

    if ((fds = cupsdDoSelect(timeout)) < 0)
    {
     /*
      * Got an error from select!
      */

#ifdef HAVE_DNSSD
      cupsd_printer_t	*p;		/* Current printer */
#endif /* HAVE_DNSSD */


      if (errno == EINTR)		/* Just interrupted by a signal */
        continue;

     /*
      * Log all sorts of debug info to help track down the problem.
      */

      cupsdLogMessage(CUPSD_LOG_EMERG, "cupsdDoSelect() failed - %s!",
                      strerror(errno));

      for (i = 0, con = (cupsd_client_t *)cupsArrayFirst(Clients);
	   con;
	   i ++, con = (cupsd_client_t *)cupsArrayNext(Clients))
        cupsdLogMessage(CUPSD_LOG_EMERG,
	                "Clients[%d] = %d, file = %d, state = %d",
	                i, con->http.fd, con->file, con->http.state);

      for (i = 0, lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
           lis;
	   i ++, lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
        cupsdLogMessage(CUPSD_LOG_EMERG, "Listeners[%d] = %d", i, lis->fd);

      cupsdLogMessage(CUPSD_LOG_EMERG, "CGIPipes[0] = %d", CGIPipes[0]);

#ifdef __APPLE__
      cupsdLogMessage(CUPSD_LOG_EMERG, "SysEventPipes[0] = %d",
                      SysEventPipes[0]);
#endif /* __APPLE__ */

      for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
	   job;
	   job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
        cupsdLogMessage(CUPSD_LOG_EMERG, "Jobs[%d] = %d < [%d %d] > [%d %d]",
	        	job->id,
			job->status_buffer ? job->status_buffer->fd : -1,
			job->print_pipes[0], job->print_pipes[1],
			job->back_pipes[0], job->back_pipes[1]);

#ifdef HAVE_DNSSD
      for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
	   p;
	   p = (cupsd_printer_t *)cupsArrayNext(Printers))
        cupsdLogMessage(CUPSD_LOG_EMERG, "printer[%s] reg_name=\"%s\"", p->name,
	                p->reg_name ? p->reg_name : "(null)");
#endif /* HAVE_DNSSD */

      break;
    }

    current_time = time(NULL);

   /*
    * Write dirty config/state files...
    */

    if (DirtyCleanTime && current_time >= DirtyCleanTime)
      cupsdCleanDirty();

#ifdef __APPLE__
   /*
    * If we are going to sleep and still have pending jobs, stop them after
    * a period of time...
    */

    if (SleepJobs > 0 && current_time >= SleepJobs &&
        cupsArrayCount(PrintingJobs) > 0)
    {
      SleepJobs = 0;
      cupsdStopAllJobs(CUPSD_JOB_DEFAULT, 5);
    }
#endif /* __APPLE__ */

#ifndef __APPLE__
   /*
    * Update the network interfaces once a minute...
    */

    if ((current_time - netif_time) >= 60)
    {
      netif_time  = current_time;
      NetIFUpdate = 1;
    }
#endif /* !__APPLE__ */

#if HAVE_LAUNCHD
   /*
    * If no other work was scheduled and we're being controlled by launchd
    * then timeout after 'LaunchdTimeout' seconds of inactivity...
    */

    if (!fds && launchd_idle_exit)
    {
      cupsdLogMessage(CUPSD_LOG_INFO,
                      "Printer sharing is off and there are no jobs pending, "
		      "will restart on demand.");
      stop_scheduler = 1;
      break;
    }
#endif /* HAVE_LAUNCHD */

   /*
    * Resume listening for new connections as needed...
    */

    if (ListeningPaused && ListeningPaused <= current_time &&
        cupsArrayCount(Clients) < MaxClients)
      cupsdResumeListening();

   /*
    * Expire subscriptions and unload completed jobs as needed...
    */

    if (current_time > expire_time)
    {
      if (cupsArrayCount(Subscriptions) > 0)
        cupsdExpireSubscriptions(NULL, NULL);

      cupsdUnloadCompletedJobs();

      expire_time = current_time;
    }

#ifndef HAVE_AUTHORIZATION_H
   /*
    * Update the root certificate once every 5 minutes if we have client
    * connections...
    */

    if ((current_time - RootCertTime) >= RootCertDuration && RootCertDuration &&
        !RunUser && cupsArrayCount(Clients))
    {
     /*
      * Update the root certificate...
      */

      cupsdDeleteCert(0);
      cupsdAddCert(0, "root", NULL);
    }
#endif /* !HAVE_AUTHORIZATION_H */

   /*
    * Check for new data on the client sockets...
    */

    for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
	 con;
	 con = (cupsd_client_t *)cupsArrayNext(Clients))
    {
     /*
      * Process pending data in the input buffer...
      */

      if (con->http.used)
      {
        cupsdReadClient(con);
	continue;
      }

     /*
      * Check the activity and close old clients...
      */

      activity = current_time - Timeout;
      if (con->http.activity < activity && !con->pipe_pid)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "Closing client %d after %d seconds of inactivity...",
	                con->http.fd, Timeout);

        cupsdCloseClient(con);
        continue;
      }
    }

   /*
    * Update any pending multi-file documents...
    */

    if ((current_time - senddoc_time) >= 10)
    {
      cupsdCheckJobs();
      senddoc_time = current_time;
    }

   /*
    * Clean job history...
    */

    if (JobHistoryUpdate && current_time >= JobHistoryUpdate)
      cupsdCleanJobs();

   /*
    * Log statistics at most once a minute when in debug mode...
    */

    if ((current_time - report_time) >= 60 && LogLevel >= CUPSD_LOG_DEBUG)
    {
      size_t		string_count,	/* String count */
			alloc_bytes,	/* Allocated string bytes */
			total_bytes;	/* Total string bytes */
#ifdef HAVE_MALLINFO
      struct mallinfo	mem;		/* Malloc information */


      mem = mallinfo();
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-arena=%lu", mem.arena);
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-used=%lu",
                      mem.usmblks + mem.uordblks);
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-free=%lu",
		      mem.fsmblks + mem.fordblks);
#endif /* HAVE_MALLINFO */

      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: clients=%d",
                      cupsArrayCount(Clients));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: jobs=%d",
                      cupsArrayCount(Jobs));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: jobs-active=%d",
                      cupsArrayCount(ActiveJobs));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: printers=%d",
                      cupsArrayCount(Printers));

      string_count = _cupsStrStatistics(&alloc_bytes, &total_bytes);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-string-count=" CUPS_LLFMT,
		      CUPS_LLCAST string_count);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-alloc-bytes=" CUPS_LLFMT,
		      CUPS_LLCAST alloc_bytes);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-total-bytes=" CUPS_LLFMT,
		      CUPS_LLCAST total_bytes);

      report_time = current_time;
    }

   /*
    * Handle OS-specific event notification for any events that have
    * accumulated.  Don't send these more than once a second...
    */

    if (LastEvent && (current_time - event_time) >= 1)
    {
#ifdef HAVE_NOTIFY_POST
      if (LastEvent & (CUPSD_EVENT_PRINTER_ADDED |
                       CUPSD_EVENT_PRINTER_DELETED |
                       CUPSD_EVENT_PRINTER_MODIFIED))
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.printerListChange\")");
	notify_post("com.apple.printerListChange");
      }

      if (LastEvent & CUPSD_EVENT_PRINTER_STATE_CHANGED)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.printerHistoryChange\")");
	notify_post("com.apple.printerHistoryChange");
      }

      if (LastEvent & (CUPSD_EVENT_JOB_STATE_CHANGED |
                       CUPSD_EVENT_JOB_CONFIG_CHANGED |
                       CUPSD_EVENT_JOB_PROGRESS))
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.jobChange\")");
	notify_post("com.apple.jobChange");
      }
#endif /* HAVE_NOTIFY_POST */

     /*
      * Reset the accumulated events...
      */

      LastEvent  = CUPSD_EVENT_NONE;
      event_time = current_time;
    }
  }

 /*
  * Log a message based on what happened...
  */

  if (stop_scheduler)
  {
    cupsdLogMessage(CUPSD_LOG_INFO, "Scheduler shutting down normally.");
    cupsdAddEvent(CUPSD_EVENT_SERVER_STOPPED, NULL, NULL,
                  "Scheduler shutting down normally.");
  }
  else
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Scheduler shutting down due to program error.");
    cupsdAddEvent(CUPSD_EVENT_SERVER_STOPPED, NULL, NULL,
                  "Scheduler shutting down due to program error.");
  }

 /*
  * Close all network clients...
  */

  DoingShutdown = 1;

  cupsdStopServer();

#ifdef HAVE_LAUNCHD
 /*
  * Update the launchd KeepAlive file as needed...
  */

  if (Launchd)
    launchd_checkout();
#endif /* HAVE_LAUNCHD */

 /*
  * Stop all jobs...
  */

  cupsdFreeAllJobs();

#ifdef __APPLE__
 /*
  * Stop monitoring system event monitoring...
  */

  if (use_sysman)
    cupsdStopSystemMonitor();
#endif /* __APPLE__ */

#ifdef HAVE_GSSAPI
 /*
  * Free the scheduler's Kerberos context...
  */

#  ifdef __APPLE__
 /*
  * If the weak-linked GSSAPI/Kerberos library is not present, don't try
  * to use it...
  */

  if (krb5_init_context != NULL)
#  endif /* __APPLE__ */
  if (KerberosContext)
    krb5_free_context(KerberosContext);
#endif /* HAVE_GSSAPI */

#ifdef __sgi
 /*
  * Remove the fake IRIX lpsched lock file, but only if the existing
  * file is not a FIFO which indicates that the real IRIX lpsched is
  * running...
  */

  if (!stat("/var/spool/lp/FIFO", &statbuf))
    if (!S_ISFIFO(statbuf.st_mode))
      unlink("/var/spool/lp/SCHEDLOCK");
#endif /* __sgi */

  cupsdStopSelect();

  return (!stop_scheduler);
}
示例#14
0
static void
booter(kickeeRef target)
{
	char			**argv		= NULL;
	char			*cmd		= NULL;
	CFStringRef		execCommand	= CFDictionaryGetValue(target->dict, CFSTR("execCommand"));
	int			i;
	CFArrayRef		keys		= NULL;
	CFStringRef		name		= CFDictionaryGetValue(target->dict, CFSTR("name"));
	int			nKeys		= 0;
	Boolean			ok		= FALSE;
	CFStringRef		postName	= CFDictionaryGetValue(target->dict, CFSTR("postName"));

	SCLog(_verbose, LOG_DEBUG, CFSTR("Kicker callback, target=%@"), name);

	if (!isA_CFString(postName) && !isA_CFString(execCommand)) {
		goto error;	/* if no notifications to post nor commands to execute */
	}

	if (isA_CFString(postName)) {
		uint32_t	status;

		/*
		 * post a notification
		 */
		cmd = _SC_cfstring_to_cstring(postName, NULL, 0, kCFStringEncodingASCII);
		if (!cmd) {
			SCLog(TRUE, LOG_DEBUG, CFSTR("  could not convert post name to C string"));
			goto error;
		}

		SCLog(TRUE, LOG_NOTICE, CFSTR("posting notification %s"), cmd);
		status = notify_post(cmd);
		if (status != NOTIFY_STATUS_OK) {
			SCLog(TRUE, LOG_DEBUG, CFSTR("  notify_post() failed: error=%ld"), status);
			goto error;
		}

		CFAllocatorDeallocate(NULL, cmd);	/* clean up */
		cmd = NULL;
	}

	/*
	 * get the arguments for the kickee
	 */
	keys = target->changedKeys;
	target->changedKeys = NULL;

	if (isA_CFString(execCommand)) {
		CFRange			bpr;
		CFNumberRef		execGID		= CFDictionaryGetValue(target->dict, CFSTR("execGID"));
		CFNumberRef		execUID		= CFDictionaryGetValue(target->dict, CFSTR("execUID"));
		CFBooleanRef		passKeys	= CFDictionaryGetValue(target->dict, CFSTR("changedKeysAsArguments"));
		gid_t			reqGID		= 0;
		uid_t			reqUID		= 0;
		CFMutableStringRef	str;

		/*
		 * build the kickee command
		 */
		str = CFStringCreateMutableCopy(NULL, 0, execCommand);
		bpr = CFStringFind(str, CFSTR("$BUNDLE"), 0);
		if (bpr.location != kCFNotFound) {
			CFStringRef	bundlePath;

			bundlePath = CFURLCopyFileSystemPath(myBundleURL, kCFURLPOSIXPathStyle);
			CFStringReplace(str, bpr, bundlePath);
			CFRelease(bundlePath);
		}

		cmd = _SC_cfstring_to_cstring(str, NULL, 0, kCFStringEncodingASCII);
		CFRelease(str);
		if (!cmd) {
			SCLog(TRUE, LOG_DEBUG, CFSTR("  could not convert command to C string"));
			goto error;
		}

		/*
		 * get the UID/GID for the kickee
		 */
		if (isA_CFNumber(execUID)) {
			CFNumberGetValue(execUID, kCFNumberIntType, &reqUID);
		}

		if (isA_CFNumber(execGID)) {
			CFNumberGetValue(execGID, kCFNumberIntType, &reqGID);
		}

		nKeys = CFArrayGetCount(keys);
		argv  = CFAllocatorAllocate(NULL, (nKeys + 2) * sizeof(char *), 0);
		for (i = 0; i < (nKeys + 2); i++) {
			argv[i] = NULL;
		}

		/* create command name argument */
		if ((argv[0] = rindex(cmd, '/')) != NULL) {
			argv[0]++;
		} else {
			argv[0] = cmd;
		}

		/* create changed key arguments */
		if (isA_CFBoolean(passKeys) && CFBooleanGetValue(passKeys)) {
			for (i = 0; i < nKeys; i++) {
				CFStringRef	key = CFArrayGetValueAtIndex(keys, i);

				argv[i+1] = _SC_cfstring_to_cstring(key, NULL, 0, kCFStringEncodingASCII);
				if (!argv[i+1]) {
					SCLog(TRUE, LOG_DEBUG, CFSTR("  could not convert argument to C string"));
					goto error;
				}
			}
		}

		SCLog(TRUE,     LOG_NOTICE, CFSTR("executing %s"), cmd);
		SCLog(_verbose, LOG_DEBUG,  CFSTR("  current uid = %d, requested = %d"), geteuid(), reqUID);

		/* this kicker is now "running" */
		target->active = TRUE;

		(void)_SCDPluginExecCommand(booterExit,
			      target,
			      reqUID,
			      reqGID,
			      cmd,
			      argv);

//		CFAllocatorDeallocate(NULL, cmd);	/* clean up */
//		cmd = NULL;
	} else {
		target->active = FALSE;
	}

	target->needsKick = FALSE;	/* allow additional requests to be queued */
	ok = TRUE;

    error :

	if (keys)	CFRelease(keys);
	if (cmd)	CFAllocatorDeallocate(NULL, cmd);
	if (argv) {
		for (i = 0; i < nKeys; i++) {
			if (argv[i+1]) {
				CFAllocatorDeallocate(NULL, argv[i+1]);
			}
		}
		CFAllocatorDeallocate(NULL, argv);
	}

	if (!ok) {
		/*
		 * If the target action can't be performed this time then
		 * there's not much point in trying again. As such, I close
		 * the session and the kickee target released.
		 */
		cleanupKicker(target);
	}

	return;
}
示例#15
0
static int
_bsd_send(aslmsg msg, struct config_rule *r, char **out, char **fwd, time_t now)
{
	char *sf, *outmsg;
	const char *vlevel, *vfacility;
	size_t outlen;
	int pf, fc, status, is_dup, do_write;
	uint32_t msg_hash, n;

	if (out == NULL) return -1;
	if (fwd == NULL) return -1;
	if (r == NULL) return -1;

	_syslog_dst_open(r);

	if (r->type == DST_TYPE_NOTE)
	{
		notify_post(r->dst+1);
		return 0;
	}

	msg_hash = 0;
	outmsg = NULL;

	/* Build output string if it hasn't been built by a previous rule-match */
	if (*out == NULL)
	{
		*out = asl_format_message((asl_msg_t *)msg, ASL_MSG_FMT_BSD, ASL_TIME_FMT_LCL, ASL_ENCODE_SAFE, &n);
		if (*out == NULL) return -1;
	}

	/* check if message is a duplicate of the last message, and inside the dup time window */
	is_dup = 0;
	if ((global.bsd_max_dup_time > 0) && (*out != NULL) && (r->last_msg != NULL))
	{
		msg_hash = asl_core_string_hash(*out + 16, strlen(*out + 16));
		if ((r->last_hash == msg_hash) && (!strcmp(r->last_msg, *out + 16)))
		{
			if ((now - r->last_time) < global.bsd_max_dup_time) is_dup = 1;
		}
	}

	if ((*fwd == NULL) && (r->type == DST_TYPE_SOCK))
	{
		pf = 7;
		vlevel = asl_get(msg, ASL_KEY_LEVEL);
		if (vlevel != NULL) pf = atoi(vlevel);

		fc = asl_syslog_faciliy_name_to_num(asl_get(msg, ASL_KEY_FACILITY));
		if (fc > 0) pf |= fc;

		sf = NULL;
		asprintf(&sf, "<%d>%s", pf, *out);
		if (sf == NULL) return -1;

		*fwd = sf;
	}

	if (r->type == DST_TYPE_SOCK) outlen = strlen(*fwd);
	else outlen = strlen(*out);

	if ((r->type == DST_TYPE_FILE) || (r->type == DST_TYPE_CONS))
	{
		/*
		 * If current message is NOT a duplicate and r->last_count > 0
		 * we need to write a "last message was repeated N times" log entry
		 */
		if ((r->type == DST_TYPE_FILE) && (is_dup == 0) && (r->last_count > 0)) _bsd_send_repeat_msg(r);

		do_write = 1;

		/*
		 * Special case for kernel messages.
		 * Don't write kernel messages to /dev/console.
		 * The kernel printf routine already sends them to /dev/console
		 * so writing them here would cause duplicates.
		 */
		vfacility = asl_get(msg, ASL_KEY_FACILITY);
		if ((vfacility != NULL) && (!strcmp(vfacility, FACILITY_KERNEL)) && (r->type == DST_TYPE_CONS)) do_write = 0;
		if ((do_write == 1) && (r->type == DST_TYPE_FILE) && (is_dup == 1))
		{
			do_write = 0;

			if (r->dup_timer == NULL)
			{
				/* create a timer to flush dups on this file */
				r->dup_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, bsd_out_queue);
				dispatch_source_set_event_handler(r->dup_timer, ^{ _bsd_send_repeat_msg(r); });
			}
示例#16
0
void
cupsdStopServer(void)
{
  if (!started)
    return;

 /*
  * Close all network clients and stop all jobs...
  */

  cupsdCloseAllClients();
  cupsdStopListening();
  cupsdStopPolling();
  cupsdStopBrowsing();
  cupsdStopAllNotifiers();
  cupsdSaveRemoteCache();
  cupsdDeleteAllCerts();

  if (Clients)
  {
    cupsArrayDelete(Clients);
    Clients = NULL;
  }

 /*
  * Close the pipe for CGI processes...
  */

  if (CGIPipes[0] >= 0)
  {
    cupsdRemoveSelect(CGIPipes[0]);

    cupsdStatBufDelete(CGIStatusBuffer);
    close(CGIPipes[1]);

    CGIPipes[0] = -1;
    CGIPipes[1] = -1;
  }

 /*
  * Close all log files...
  */

  if (AccessFile != NULL)
  {
    cupsFileClose(AccessFile);

    AccessFile = NULL;
  }

  if (ErrorFile != NULL)
  {
    cupsFileClose(ErrorFile);

    ErrorFile = NULL;
  }

  if (PageFile != NULL)
  {
    cupsFileClose(PageFile);

    PageFile = NULL;
  }

#ifdef HAVE_NOTIFY_POST
 /*
  * Send one last notification as the server shuts down.
  */

  cupsdLogMessage(CUPSD_LOG_DEBUG,
                  "notify_post(\"com.apple.printerListChange\") last");
  notify_post("com.apple.printerListChange");
#endif /* HAVE_NOTIFY_POST */

  started = 0;
}
示例#17
0
//
// Add a rule to the policy database
//
CFDictionaryRef PolicyEngine::add(CFTypeRef inTarget, AuthorityType type, SecAssessmentFlags flags, CFDictionaryRef context)
{
	// default type to execution
	if (type == kAuthorityInvalid)
		type = kAuthorityExecute;

	authorizeUpdate(flags, context);
	CFDictionary ctx(context, errSecCSInvalidAttributeValues);
	CFCopyRef<CFTypeRef> target = inTarget;
	CFRef<CFDataRef> bookmark = NULL;
	std::string filter_unsigned;

	switch (type) {
	case kAuthorityExecute:
		normalizeTarget(target, ctx, &filter_unsigned);
		// bookmarks are untrusted and just a hint to callers
		bookmark = ctx.get<CFDataRef>(kSecAssessmentRuleKeyBookmark);
		break;
	case kAuthorityInstall:
		if (inTarget && CFGetTypeID(inTarget) == CFURLGetTypeID()) {
			// no good way to turn an installer file into a requirement. Pretend to succeeed so caller proceeds
			return cfmake<CFDictionaryRef>("{%O=%O}", kSecAssessmentAssessmentAuthorityOverride, CFSTR("virtual install"));
		}
		break;
	case kAuthorityOpenDoc:
		// handle document-open differently: use quarantine flags for whitelisting
		if (!target || CFGetTypeID(target) != CFURLGetTypeID())	// can only "add" file paths
			MacOSError::throwMe(errSecCSInvalidObjectRef);
		try {
			std::string spath = cfString(target.as<CFURLRef>());
			FileQuarantine qtn(spath.c_str());
			qtn.setFlag(QTN_FLAG_ASSESSMENT_OK);
			qtn.applyTo(spath.c_str());
		} catch (const CommonError &error) {
			// could not set quarantine flag - report qualified success
			return cfmake<CFDictionaryRef>("{%O=%O,'assessment:error'=%d}",
				kSecAssessmentAssessmentAuthorityOverride, CFSTR("error setting quarantine"), error.osStatus());
		} catch (...) {
			return cfmake<CFDictionaryRef>("{%O=%O}", kSecAssessmentAssessmentAuthorityOverride, CFSTR("unable to set quarantine"));
		}
		return NULL;
	}
	
	// if we now have anything else, we're busted
	if (!target || CFGetTypeID(target) != SecRequirementGetTypeID())
		MacOSError::throwMe(errSecCSInvalidObjectRef);

	double priority = 0;
	string label;
	bool allow = true;
	double expires = never;
	string remarks;
	
	if (CFNumberRef pri = ctx.get<CFNumberRef>(kSecAssessmentUpdateKeyPriority))
		CFNumberGetValue(pri, kCFNumberDoubleType, &priority);
	if (CFStringRef lab = ctx.get<CFStringRef>(kSecAssessmentUpdateKeyLabel))
		label = cfString(lab);
	if (CFDateRef time = ctx.get<CFDateRef>(kSecAssessmentUpdateKeyExpires))
		// we're using Julian dates here; convert from CFDate
		expires = dateToJulian(time);
	if (CFBooleanRef allowing = ctx.get<CFBooleanRef>(kSecAssessmentUpdateKeyAllow))
		allow = allowing == kCFBooleanTrue;
	if (CFStringRef rem = ctx.get<CFStringRef>(kSecAssessmentUpdateKeyRemarks))
		remarks = cfString(rem);

	CFRef<CFStringRef> requirementText;
	MacOSError::check(SecRequirementCopyString(target.as<SecRequirementRef>(), kSecCSDefaultFlags, &requirementText.aref()));
	SQLite::Transaction xact(*this, SQLite3::Transaction::deferred, "add_rule");
	SQLite::Statement insert(*this,
		"INSERT INTO authority (type, allow, requirement, priority, label, expires, filter_unsigned, remarks)"
		"	VALUES (:type, :allow, :requirement, :priority, :label, :expires, :filter_unsigned, :remarks);");
	insert.bind(":type").integer(type);
	insert.bind(":allow").integer(allow);
	insert.bind(":requirement") = requirementText.get();
	insert.bind(":priority") = priority;
	if (!label.empty())
		insert.bind(":label") = label;
	insert.bind(":expires") = expires;
	insert.bind(":filter_unsigned") = filter_unsigned.empty() ? NULL : filter_unsigned.c_str();
	if (!remarks.empty())
		insert.bind(":remarks") = remarks;
	insert.execute();
	SQLite::int64 newRow = this->lastInsert();
	if (bookmark) {
		SQLite::Statement bi(*this, "INSERT INTO bookmarkhints (bookmark, authority) VALUES (:bookmark, :authority)");
		bi.bind(":bookmark") = CFDataRef(bookmark);
		bi.bind(":authority").integer(newRow);
		bi.execute();
	}
	this->purgeObjects(priority);
	xact.commit();
	notify_post(kNotifySecAssessmentUpdate);
	return cfmake<CFDictionaryRef>("{%O=%d}", kSecAssessmentUpdateKeyRow, newRow);
}
示例#18
0
/*
 * GuizmOVPN_initialization_sequence_completed() :
 *      Handle actions when tunnel is initialized
 */
void GuizmOVPN_initialization_sequence_completed()
{
	notify_post("com.guizmo.openvpn/StatusIconAdd");
}
示例#19
0
文件: main.c 项目: uroboro/IRCyslog
uint32_t post(const char *notification) {
	uint32_t r = notify_post(notification);
	print_message(0, "%sPosted \"%s\".\n", (r)?"not ":"", notification);
	return r;
}
void SharedMemoryListener::action ()
{
	secdebug("notify", "Posted notification to clients.");
	notify_post (mSegmentName.c_str ());
	mActive = false;
}
示例#21
0
static void shareTheSystemLoad(bool shouldNotify)
{
    static uint64_t         lastSystemLoad  = 0;
    uint64_t                theseSystemLoad = 0;
    int                     userLevel       = kIOSystemLoadAdvisoryLevelGreat;
    int                     batteryLevel    = kIOSystemLoadAdvisoryLevelGreat;
    int                     powerLevel      = kIOSystemLoadAdvisoryLevelGreat;
    int                     combinedLevel   = kIOSystemLoadAdvisoryLevelGreat;

/******************************************
 * Power Level Computation code begins here
 * Edit this block of code to change what
 * defines a "good time" to do work, based on system load.
 */
/******************************************/

    if (onACPower) {
        batteryLevel = kIOSystemLoadAdvisoryLevelGreat;
    } else if (!batteryBelowThreshold) {
        batteryLevel = kIOSystemLoadAdvisoryLevelOK;
    } else {
        batteryLevel = kIOSystemLoadAdvisoryLevelBad;
    }
    
    if (plimitBelowThreshold) {
        powerLevel = kIOSystemLoadAdvisoryLevelOK;
    }
    if (coresConstrained || forcedIdle || thermalWarningLevel) {
        powerLevel = kIOSystemLoadAdvisoryLevelBad;
    }

    // TODO: Use seconds since last UI activity as an indicator of
    // userLevel. Basing this data on display dimming is a crutch,
    // and may be invalid on systems with display dimming disabled.
    if (loggedInUser) {
        if (userIsIdle)
        {
            if (_DWBT_enabled()) {
               // System allows DWBT & user has opted in

               if (isA_BTMtnceWake( ) )
                  userLevel = kIOSystemLoadAdvisoryLevelGreat;
               else
                  userLevel = kIOSystemLoadAdvisoryLevelOK;
            }
            else
               userLevel = kIOSystemLoadAdvisoryLevelGreat;

        } else {
            userLevel = kIOSystemLoadAdvisoryLevelOK;
        }
        // TODO: If user is performing a full screen activity, or
        // is actively producing UI events, time is BAD.
    }

    // The combined level is the lowest/worst level of the contributing factors
    combinedLevel = minOfThree(userLevel, batteryLevel, powerLevel);

/******************************************/
/* Power Level Computation code ends here */
/******************************************/

    theseSystemLoad = combinedLevel
                | (userLevel << 8)
                | (batteryLevel << 16)
                | (powerLevel << 24);

    if (theseSystemLoad != lastSystemLoad) 
    {
        CFMutableDictionaryRef publishDetails = NULL;
        CFNumberRef publishNum = NULL;
    
        lastSystemLoad = theseSystemLoad;

        /* Publish the combinedLevel under our notify key 'kIOSystemLoadAdvisoryNotifyName'
         */
        notify_set_state(gNotifyToken, (uint64_t)combinedLevel);        

        /* Publish the SystemLoad key read by API
         * IOGetSystemLoadAdvisory();
         */
        publishNum = CFNumberCreate(0, kCFNumberSInt64Type, &theseSystemLoad);
        if (publishNum)
        {
            PMStoreSetValue(systemLoadKey, publishNum);
            CFRelease(publishNum);
            publishNum = NULL;
        }
    
        /* Publish the Detailed key read by API
         * CFDictionaryRef IOPMCheckSystemLoadDetailed();
         */
        publishDetails = CFDictionaryCreateMutable(0, 0,
                                &kCFTypeDictionaryKeyCallBacks,
                                &kCFTypeDictionaryValueCallBacks);
        if (!publishDetails) return;
        publishNum = CFNumberCreate(0, kCFNumberIntType, &userLevel);
        if (publishNum) {
            CFDictionarySetValue(publishDetails, 
                                    kIOSystemLoadAdvisoryUserLevelKey,
                                    publishNum);
            CFRelease(publishNum);
            publishNum = 0;
        }
        publishNum = CFNumberCreate(0, kCFNumberIntType, &batteryLevel);
        if (publishNum) {
            CFDictionarySetValue(publishDetails, 
                                    kIOSystemLoadAdvisoryBatteryLevelKey,
                                    publishNum);
            CFRelease(publishNum);
            publishNum = 0;
        }
        publishNum = CFNumberCreate(0, kCFNumberIntType, &powerLevel);
        if (publishNum) {
            CFDictionarySetValue(publishDetails, 
                                    kIOSystemLoadAdvisoryThermalLevelKey,
                                    publishNum);
            CFRelease(publishNum);
            publishNum = 0;
        }
        publishNum = CFNumberCreate(0, kCFNumberIntType, &combinedLevel);
        if (publishNum) {
            CFDictionarySetValue(publishDetails, 
                                    kIOSystemLoadAdvisoryCombinedLevelKey,
                                    publishNum);
            CFRelease(publishNum);
            publishNum = 0;
        }

        // Publish SystemLoadDetailed
        PMStoreSetValue(systemLoadDetailedKey, publishDetails);
        CFRelease(publishDetails);

        // post notification
        if (shouldNotify) {
            notify_post(kIOSystemLoadAdvisoryNotifyName);
        }
    }
}
示例#22
0
/*
 * GuizmOVPN_close_tun() :
 *      Handle actions when tunnel is closed
 */
void GuizmOVPN_close_tun()
{
    tapemu_clear();
    
	notify_post("com.guizmo.openvpn/StatusIconRemove");
}
示例#23
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[]			/* I - Command-line arguments */
#ifdef PRINT_AUXV
     ,
     char* envp[]
#endif
     )
{
  int			i;		/* Looping var */
  char			*opt;		/* Option character */
  int			fg;		/* Run in the foreground */
  int			fds;		/* Number of ready descriptors */
  cupsd_client_t	*con;		/* Current client */
  cupsd_job_t		*job;		/* Current job */
  cupsd_listener_t	*lis;		/* Current listener */
  time_t		current_time,	/* Current time */
			activity,	/* Client activity timer */
			browse_time,	/* Next browse send time */
			senddoc_time,	/* Send-Document time */
			expire_time,	/* Subscription expire time */
			report_time,	/* Malloc/client/job report time */
			event_time;	/* Last time an event notification was done */
  long			timeout;	/* Timeout for cupsdDoSelect() */
  struct rlimit		limit;		/* Runtime limit */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction	action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
#ifdef __sgi
  cups_file_t		*fp;		/* Fake lpsched lock file */
  struct stat		statbuf;	/* Needed for checking lpsched FIFO */
#endif /* __sgi */
#ifdef __APPLE__
  int			run_as_child = 0;
					/* Needed for Mac OS X fork/exec */
#else
  time_t		netif_time = 0;	/* Time since last network update */
#endif /* __APPLE__ */
#if HAVE_LAUNCHD
  int			launchd_idle_exit;
					/* Idle exit on select timeout? */
#endif	/* HAVE_LAUNCHD */
    

#ifdef PRINT_AUXV
  Elf32_auxv_t *auxv;
  while(*envp++ != NULL);

  for (auxv = (Elf32_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++)
    {
      if (auxv->a_type == AT_SYSINFO)
	{
	  printf("AT_RANDOM is 0x%x\n", auxv->a_un.a_val);
	}
      
    }
#endif
 
#if UNDERSTAND_CUPS
  printf("[main.c::main()] cups has just started in main()\n");
#endif
  
  int count = 0;
  int loops_desired = -1; // loop forever unless this is set

#ifdef HAVE_GETEUID
  /*
  * Check for setuid invocation, which we do not support!
  */
  if (getuid() != geteuid())
  {
    fputs("cupsd: Cannot run as a setuid program!\n", stderr);
    return (1);
  }
#if UNDERSTAND_CUPS
  printf("[main.c::main()] uid = %d, euid = %d\n", getuid(), geteuid());
#endif
#endif /* HAVE_GETEUID */
  
 /*
  * Check for command-line arguments...
  */
#if UNDERSTAND_CUPS
  printf("[main.c::main()] parsing command line arguments \n");
#endif
  
  fg = 0;

#ifdef HAVE_LAUNCHD
  if (getenv("CUPSD_LAUNCHD"))
  {
    Launchd = 1;
    fg      = 1;
  }
#endif /* HAVE_LAUNCHD */

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-')
      for (opt = argv[i] + 1; *opt != '\0'; opt ++)
        switch (*opt)
	{
#ifdef __APPLE__
	  case 'C' : /* Run as child with config file */
              run_as_child = 1;
	      fg           = -1;
#endif /* __APPLE__ */

	  case 'c' : /* Configuration file */
	      i ++;
	      if (i >= argc)
	      {
	        _cupsLangPuts(stderr, _("cupsd: Expected config filename "
		                        "after \"-c\" option!\n"));
	        usage(1);
	      }

              if (argv[i][0] == '/')
	      {
	       /*
	        * Absolute directory...
		*/

		cupsdSetString(&ConfigurationFile, argv[i]);
              }
	      else
	      {
	       /*
	        * Relative directory...
		*/

                char *current;		/* Current directory */


	       /*
	        * Allocate a buffer for the current working directory to
		* reduce run-time stack usage; this approximates the
		* behavior of some implementations of getcwd() when they
		* are passed a NULL pointer.
	        */

                if ((current = malloc(1024)) == NULL)
		{
		  _cupsLangPuts(stderr,
		                _("cupsd: Unable to get current directory!\n"));
                  return (1);
		}

		if (!getcwd(current, 1024))
		{
		  _cupsLangPuts(stderr,
		                _("cupsd: Unable to get current directory!\n"));
                  free(current);
		  return (1);
		}

		cupsdSetStringf(&ConfigurationFile, "%s/%s", current, argv[i]);
		free(current);
              }
	      break;

          case 'f' : /* Run in foreground... */
	    fg = 1;
	    break;
	    
          case 'F' : /* Run in foreground, but disconnect from terminal... */
	    fg = -1;
	    break;
	    
          case 'h' : /* Show usage/help */
	    usage(0);
	    break;
	    
          case 'l' : /* Started by launchd... */
#ifdef HAVE_LAUNCHD
	    Launchd = 1;
	    fg      = 1;
#else
	    _cupsLangPuts(stderr, _("cupsd: launchd(8) support not compiled "
				    "in, running in normal mode.\n"));
	    fg = 0;
#endif /* HAVE_LAUNCHD */
	      break;
	      
	case 'p' : /* Stop immediately for profiling */
	  puts("Warning: -p option is for internal testing use only!");
	  stop_scheduler = 1;
	  fg             = 1;
	  break;
	  
	/// XXX RAZA
	case 'x' : /* Number of Iterations to Perform */
	  i ++;
	  loops_desired = atoi(argv[i]);
	  break;
	  
	default : /* Unknown option */
	  _cupsLangPrintf(stderr, _("cupsd: Unknown option \"%c\" - "
				    "aborting!\n"), *opt);
	  usage(1);
	  break;
	}
    else
      {
	_cupsLangPrintf(stderr, _("cupsd: Unknown argument \"%s\" - aborting!\n"),
			argv[i]);
	usage(1);
      }

#if UNDERSTAND_CUPS
  printf("[main.c::main()] done parsing command line arguments \n");
  printf("[main.c::main()] num_loops = %d, foreground = %d\n", loops_desired, fg);
#endif

  if (!ConfigurationFile)
    cupsdSetString(&ConfigurationFile, CUPS_SERVERROOT "/cupsd.conf");

  printf("[main.c::main()] configuration file = %s\n", ConfigurationFile);
  
  /*
   * If the user hasn't specified "-f", run in the background...
  */

  if (!fg)
  {
   /*
    * Setup signal handlers for the parent...
    */

#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
    sigset(SIGUSR1, parent_handler);
    sigset(SIGCHLD, parent_handler);

    sigset(SIGHUP, SIG_IGN);
#elif defined(HAVE_SIGACTION)
    memset(&action, 0, sizeof(action));
    sigemptyset(&action.sa_mask);
    sigaddset(&action.sa_mask, SIGUSR1);
    action.sa_handler = parent_handler;
    sigaction(SIGUSR1, &action, NULL);
    sigaction(SIGCHLD, &action, NULL);

    sigemptyset(&action.sa_mask);
    action.sa_handler = SIG_IGN;
    sigaction(SIGHUP, &action, NULL);
#else
    signal(SIGUSR1, parent_handler);
    signal(SIGCLD, parent_handler);

    signal(SIGHUP, SIG_IGN);
#endif /* HAVE_SIGSET */

    if (fork() > 0)
    {
     /*
      * OK, wait for the child to startup and send us SIGUSR1 or to crash
      * and the OS send us SIGCHLD...  We also need to ignore SIGHUP which
      * might be sent by the init script to restart the scheduler...
      */

      for (; parent_signal == 0;)
        sleep(1);

      if (parent_signal == SIGUSR1)
        return (0);

      if (wait(&i) < 0)
      {
        perror("cupsd");
	return (1);
      }
      else if (WIFEXITED(i))
      {
        fprintf(stderr, "cupsd: Child exited with status %d!\n",
	        WEXITSTATUS(i));
	return (2);
      }
      else
      {
        fprintf(stderr, "cupsd: Child exited on signal %d!\n", WTERMSIG(i));
	return (3);
      }
    }

#ifdef __APPLE__
   /*
    * Since CoreFoundation has an overly-agressive check for whether a
    * process has forked but not exec'd (whether CF has been called or
    * not...), we now have to exec ourselves with the "-f" option to
    * eliminate their bogus warning messages.
    */

    execlp(argv[0], argv[0], "-C", ConfigurationFile, (char *)0);
    exit(errno);
#endif /* __APPLE__ */
  }

  if (fg < 1)
  {
   /*
    * Make sure we aren't tying up any filesystems...
    */

    chdir("/");

#ifndef DEBUG
   /*
    * Disable core dumps...
    */

    getrlimit(RLIMIT_CORE, &limit);
    limit.rlim_cur = 0;
    setrlimit(RLIMIT_CORE, &limit);

   /*
    * Disconnect from the controlling terminal...
    */

    setsid();

   /*
    * Close all open files...
    */

    getrlimit(RLIMIT_NOFILE, &limit);

    for (i = 0; i < limit.rlim_cur && i < 1024; i ++)
      close(i);
#endif /* DEBUG */
  }

 /*
  * Set the timezone info...
  */
#if UNDERSTAND_CUPS
  printf("[main.c::main()] setting timezone info, tzset()\n");
#endif

  tzset();

#ifdef LC_TIME
  setlocale(LC_TIME, "");
#if UNDERSTAND_CUPS
  printf("[main.c::main()] setting locale info, setlocale()\n");
#endif
#endif /* LC_TIME */

 /*
  * Set the maximum number of files...
  */
  getrlimit(RLIMIT_NOFILE, &limit);

#if !defined(HAVE_POLL) && !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE)
  if (limit.rlim_max > FD_SETSIZE)
    MaxFDs = FD_SETSIZE;
  else
#endif /* !HAVE_POLL && !HAVE_EPOLL && !HAVE_KQUEUE */
#ifdef RLIM_INFINITY
  if (limit.rlim_max == RLIM_INFINITY)
    MaxFDs = 16384;
  else
#endif /* RLIM_INFINITY */
    MaxFDs = limit.rlim_max;

  limit.rlim_cur = MaxFDs;

  setrlimit(RLIMIT_NOFILE, &limit);

#if UNDERSTAND_CUPS
  printf("[main.c::main()] set the maximum nuber of files = %d\n", MaxFDs);
#endif

  cupsdStartSelect();

#if UNDERSTAND_CUPS
  printf("[main.c::main()] done with cupsdStartSelect() i.e. polling engine\n");
#endif

 /*
  * Read configuration...
  */

  if (!cupsdReadConfiguration())
  {
    syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
           ConfigurationFile);
    return (1);
  }

  printf("[main.c::main()] done with cupsdReadConfiguration\n");
  
  if (!strncmp(TempDir, RequestRoot, strlen(RequestRoot)))
  {
   /*
    * Clean out the temporary directory...
    */

    cups_dir_t		*dir;		/* Temporary directory */
    cups_dentry_t	*dent;		/* Directory entry */
    char		tempfile[1024];	/* Temporary filename */

    printf("[main.c::main()] cleaning temp dir = %s\n", TempDir);

    if ((dir = cupsDirOpen(TempDir)) != NULL)
    {
      cupsdLogMessage(CUPSD_LOG_INFO,
                      "Cleaning out old temporary files in \"%s\"...", TempDir);

      while ((dent = cupsDirRead(dir)) != NULL)
      {
        snprintf(tempfile, sizeof(tempfile), "%s/%s", TempDir, dent->filename);
	printf("[main.c::main()] deleting temp file = %s\n", tempfile);

	if (cupsdRemoveFile(tempfile)) {
	  cupsdLogMessage(CUPSD_LOG_ERROR,
	                  "Unable to remove temporary file \"%s\" - %s",
	                  tempfile, strerror(errno));
	  printf("[main.c::main()] failed in deleting temp file = %s\n", tempfile);
	} 
	else {
	  cupsdLogMessage(CUPSD_LOG_DEBUG, "Removed temporary file \"%s\"...",
			              tempfile);
	  printf("[main.c::main()] deleted temp file = %s\n", tempfile);
	}
      }

      cupsDirClose(dir);
    }
    else {
      cupsdLogMessage(CUPSD_LOG_ERROR,
                      "Unable to open temporary directory \"%s\" - %s",
		                  TempDir, strerror(errno));
      printf("[main.c::main()] couldn't open temp dir = %s\n", TempDir);
    }

    printf("[main.c::main()] DONE cleaning temp dir = %s\n", TempDir);
  }

#if HAVE_LAUNCHD
  if (Launchd)
  {
   /*
    * If we were started by launchd get the listen sockets file descriptors...
    */
    printf("[main.c::main()] launchd check in \n");
    launchd_checkin();
  }
#endif /* HAVE_LAUNCHD */

#if defined(__APPLE__) && defined(HAVE_DLFCN_H)
 /*
  * Load Print Service quota enforcement library (X Server only)
  */

  PSQLibRef = dlopen(PSQLibPath, RTLD_LAZY);

  if (PSQLibRef)
    PSQUpdateQuotaProc = dlsym(PSQLibRef, PSQLibFuncName);
#endif /* __APPLE__ && HAVE_DLFCN_H */

#ifdef HAVE_GSSAPI
#  ifdef __APPLE__
 /*
  * If the weak-linked GSSAPI/Kerberos library is not present, don't try
  * to use it...
  */

  if (krb5_init_context != NULL)
#  endif /* __APPLE__ */

 /*
  * Setup a Kerberos context for the scheduler to use...
  */
  if (krb5_init_context(&KerberosContext))
  {
    KerberosContext = NULL;

    printf("[main.c::main()] unable to use krb5_init_context() \n");

    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize Kerberos context");
  }
  else
    {
      printf("[main.c::main()] used krb5_init_context() \n");
    }
#endif /* HAVE_GSSAPI */

 /*
  * Startup the server...
  */

  cupsdStartServer();

 /*
  * Catch hangup and child signals and ignore broken pipes...
  */

#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
  sigset(SIGCHLD, sigchld_handler);
  sigset(SIGHUP, sighup_handler);
  sigset(SIGPIPE, SIG_IGN);
  sigset(SIGTERM, sigterm_handler);
  printf("[main.c::main()] used system V signals over POSIX\n");
#elif defined(HAVE_SIGACTION)
  printf("[main.c::main()] used HAVE_SIGACTION\n");

  memset(&action, 0, sizeof(action));
  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGTERM);
  sigaddset(&action.sa_mask, SIGCHLD);
  action.sa_handler = sigchld_handler;
  sigaction(SIGCHLD, &action, NULL);

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGHUP);
  action.sa_handler = sighup_handler;
  sigaction(SIGHUP, &action, NULL);

  sigemptyset(&action.sa_mask);
  action.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &action, NULL);

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGTERM);
  sigaddset(&action.sa_mask, SIGCHLD);
  action.sa_handler = sigterm_handler;
  sigaction(SIGTERM, &action, NULL);
#else
  printf("[main.c::main()]last signal options\n");
  signal(SIGCLD, sigchld_handler);	/* No, SIGCLD isn't a typo... */
  signal(SIGHUP, sighup_handler);
  signal(SIGPIPE, SIG_IGN);
  signal(SIGTERM, sigterm_handler);
  
#endif /* HAVE_SIGSET */

#ifdef __sgi
 /*
  * Try to create a fake lpsched lock file if one is not already there.
  * Some Adobe applications need it under IRIX in order to enable
  * printing...
  */
  printf("[main.c::main()] creating fake lpsched lock file \n");
  if ((fp = cupsFileOpen("/var/spool/lp/SCHEDLOCK", "w")) == NULL)
  {
    syslog(LOG_LPR, "Unable to create fake lpsched lock file "
                    "\"/var/spool/lp/SCHEDLOCK\"\' - %s!",
           strerror(errno));
  }
  else
  {
    fchmod(cupsFileNumber(fp), 0644);
    fchown(cupsFileNumber(fp), User, Group);

    cupsFileClose(fp);
  }
#endif /* __sgi */

 /*
  * Initialize authentication certificates...
  */

  cupsdInitCerts();

 /*
  * If we are running in the background, signal the parent process that
  * we are up and running...
  */

#ifdef __APPLE__
  if (!fg || run_as_child)
#else
  if (!fg)
#endif /* __APPLE__ */
  {
   /*
    * Send a signal to the parent process, but only if the parent is
    * not PID 1 (init).  This avoids accidentally shutting down the
    * system on OpenBSD if you CTRL-C the server before it is up...
    */

    i = getppid();	/* Save parent PID to avoid race condition */

    if (i != 1)
      kill(i, SIGUSR1);
  }

#ifdef __APPLE__
 /*
  * Start power management framework...
  */
  printf("[main.c::main()] starting system monitor (power management) \n");
  cupsdStartSystemMonitor();
#endif /* __APPLE__ */

 /*
  * Start any pending print jobs...
  */

  printf("[main.c::main()] starting any pending print jobs \n");
  cupsdCheckJobs();

 /*
  * Loop forever...
  */

  current_time  = time(NULL);
  browse_time   = current_time;
  event_time    = current_time;
  expire_time   = current_time;
  fds           = 1;
  report_time   = 0;
  senddoc_time  = current_time;

  
  while (!stop_scheduler)
   {
    
    // XXX RAZA
    printf("[main.c::main()] scheduler loop # %d\n", count);
    if (count++ == loops_desired)
      {
	printf("[main.c::main()] stopping scheduler loop\n");
   	stop_scheduler = 1;
	continue;
      } 
    
    printf("[main.c::main()]  Top of loop, dead_children=%d, NeedReload=%d\n",
	   dead_children, NeedReload);    
    
#ifdef DEBUG
    cupsdLogMessage(CUPSD_LOG_DEBUG2,
                    "main: Top of loop, dead_children=%d, NeedReload=%d",
                    dead_children, NeedReload);
#endif /* DEBUG */

    

   /*
    * Check if there are dead children to handle...
    */

    if (dead_children)
      process_children();

   /*
    * Check if we need to load the server configuration file...
    */

    if (NeedReload)
    {
     /*
      * Close any idle clients...
      */

      if (cupsArrayCount(Clients) > 0)
      {
	for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
	     con;
	     con = (cupsd_client_t *)cupsArrayNext(Clients))
	  if (con->http.state == HTTP_WAITING)
	    cupsdCloseClient(con);
	  else
	    con->http.keep_alive = HTTP_KEEPALIVE_OFF;

        cupsdPauseListening();
      }

     /*
      * Check for any active jobs...
      */

      for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
	   job;
	   job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
        if (job->state_value == IPP_JOB_PROCESSING)
	  break;

     /*
      * Restart if all clients are closed and all jobs finished, or
      * if the reload timeout has elapsed...
      */

      if ((cupsArrayCount(Clients) == 0 &&
           (!job || NeedReload != RELOAD_ALL)) ||
          (time(NULL) - ReloadTime) >= ReloadTimeout)
      {
       /*
	* Shutdown the server...
	*/

	cupsdStopServer();

       /*
	* Read configuration...
	*/

        if (!cupsdReadConfiguration())
        {
          syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
		 ConfigurationFile);
          break;
	}

#if HAVE_LAUNCHD
	if (Launchd)
	{
	 /*
	  * If we were started by launchd get the listen sockets file descriptors...
	  */

	  launchd_checkin();
	}
#endif /* HAVE_LAUNCHD */

       /*
        * Startup the server...
        */

        cupsdStartServer();
      }
    }

   /*
    * Check for available input or ready output.  If cupsdDoSelect()
    * returns 0 or -1, something bad happened and we should exit
    * immediately.
    *
    * Note that we at least have one listening socket open at all
    * times.
    */

    if ((timeout = select_timeout(fds)) > 1 && LastEvent)
      timeout = 1;

#if HAVE_LAUNCHD
   /*
    * If no other work is scheduled and we're being controlled by
    * launchd then timeout after 'LaunchdTimeout' seconds of
    * inactivity...
    */

    if (timeout == 86400 && Launchd && LaunchdTimeout && !NumPolled &&
        !cupsArrayCount(ActiveJobs) &&
	(!Browsing || 
	 (!BrowseRemoteProtocols && 
	  (!NumBrowsers || !BrowseLocalProtocols ||
	   cupsArrayCount(Printers) == 0))))
    {
      timeout		= LaunchdTimeout;
      launchd_idle_exit = 1;
    }
    else
      launchd_idle_exit = 0;
#endif	/* HAVE_LAUNCHD */

    if ((fds = cupsdDoSelect(timeout)) < 0)
    {
     /*
      * Got an error from select!
      */

#ifdef HAVE_DNSSD
      cupsd_printer_t	*p;		/* Current printer */
#endif /* HAVE_DNSSD */


      if (errno == EINTR)		/* Just interrupted by a signal */
        continue;

     /*
      * Log all sorts of debug info to help track down the problem.
      */

      cupsdLogMessage(CUPSD_LOG_EMERG, "cupsdDoSelect() failed - %s!",
                      strerror(errno));

      for (i = 0, con = (cupsd_client_t *)cupsArrayFirst(Clients);
	   con;
	   i ++, con = (cupsd_client_t *)cupsArrayNext(Clients))
        cupsdLogMessage(CUPSD_LOG_EMERG,
	                "Clients[%d] = %d, file = %d, state = %d",
	                i, con->http.fd, con->file, con->http.state);

      for (i = 0, lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
           lis;
	   i ++, lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
        cupsdLogMessage(CUPSD_LOG_EMERG, "Listeners[%d] = %d", i, lis->fd);

      cupsdLogMessage(CUPSD_LOG_EMERG, "BrowseSocket = %d", BrowseSocket);

      cupsdLogMessage(CUPSD_LOG_EMERG, "CGIPipes[0] = %d", CGIPipes[0]);

#ifdef __APPLE__
      cupsdLogMessage(CUPSD_LOG_EMERG, "SysEventPipes[0] = %d",
                      SysEventPipes[0]);
#endif /* __APPLE__ */

      for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
	   job;
	   job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
        cupsdLogMessage(CUPSD_LOG_EMERG, "Jobs[%d] = %d < [%d %d] > [%d %d]",
	        	job->id,
			job->status_buffer ? job->status_buffer->fd : -1,
			job->print_pipes[0], job->print_pipes[1],
			job->back_pipes[0], job->back_pipes[1]);

#ifdef HAVE_DNSSD
      for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
	   p;
	   p = (cupsd_printer_t *)cupsArrayNext(Printers))
        cupsdLogMessage(CUPSD_LOG_EMERG, "printer[%s] %d", p->name,
	                p->dnssd_ipp_fd);
#endif /* HAVE_DNSSD */

      break;
    }

    current_time = time(NULL);

#ifndef __APPLE__
   /*
    * Update the network interfaces once a minute...
    */

    if ((current_time - netif_time) >= 60)
    {
      netif_time  = current_time;
      NetIFUpdate = 1;
    }
#endif /* !__APPLE__ */

#if HAVE_LAUNCHD
   /*
    * If no other work was scheduled and we're being controlled by launchd
    * then timeout after 'LaunchdTimeout' seconds of inactivity...
    */

    if (!fds && launchd_idle_exit)
    {
      cupsdLogMessage(CUPSD_LOG_INFO,
                      "Printer sharing is off and there are no jobs pending, "
		      "will restart on demand.");
      stop_scheduler = 1;
      break;
    }
#endif /* HAVE_LAUNCHD */

   /*
    * Resume listening for new connections as needed...
    */

    if (ListeningPaused && ListeningPaused <= current_time &&
        cupsArrayCount(Clients) < MaxClients)
      cupsdResumeListening();

   /*
    * Expire subscriptions and unload completed jobs as needed...
    */

    if (current_time > expire_time)
    {
      if (cupsArrayCount(Subscriptions) > 0)
        cupsdExpireSubscriptions(NULL, NULL);

      cupsdUnloadCompletedJobs();

      expire_time = current_time;
    }

   /*
    * Update the browse list as needed...
    */

    if (Browsing)
    {
#ifdef HAVE_LIBSLP
      if ((BrowseRemoteProtocols & BROWSE_SLP) &&
          BrowseSLPRefresh <= current_time)
        cupsdUpdateSLPBrowse();
#endif /* HAVE_LIBSLP */

#ifdef HAVE_LDAP
      if ((BrowseRemoteProtocols & BROWSE_LDAP) &&
          BrowseLDAPRefresh <= current_time)
        cupsdUpdateLDAPBrowse();
#endif /* HAVE_LDAP */
    }

    if (Browsing && current_time > browse_time)
    {
      cupsdSendBrowseList();
      browse_time = current_time;
    }

   /*
    * Update the root certificate once every 5 minutes if we have client
    * connections...
    */

    if ((current_time - RootCertTime) >= RootCertDuration && RootCertDuration &&
        !RunUser && cupsArrayCount(Clients))
    {
     /*
      * Update the root certificate...
      */

      cupsdDeleteCert(0);
      cupsdAddCert(0, "root", NULL);
    }

   /*
    * Check for new data on the client sockets...
    */

    for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
	 con;
	 con = (cupsd_client_t *)cupsArrayNext(Clients))
    {
     /*
      * Process pending data in the input buffer...
      */

      if (con->http.used)
      {
        cupsdReadClient(con);
	continue;
      }

     /*
      * Check the activity and close old clients...
      */

      activity = current_time - Timeout;
      if (con->http.activity < activity && !con->pipe_pid)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "Closing client %d after %d seconds of inactivity...",
	                con->http.fd, Timeout);

        cupsdCloseClient(con);
        continue;
      }
    }

   /*
    * Update any pending multi-file documents...
    */

    if ((current_time - senddoc_time) >= 10)
    {
      cupsdCheckJobs();
      senddoc_time = current_time;
    }

   /*
    * Log statistics at most once a minute when in debug mode...
    */

    if ((current_time - report_time) >= 60 && LogLevel >= CUPSD_LOG_DEBUG)
    {
      size_t		string_count,	/* String count */
			alloc_bytes,	/* Allocated string bytes */
			total_bytes;	/* Total string bytes */
#ifdef HAVE_MALLINFO
      struct mallinfo	mem;		/* Malloc information */


      mem = mallinfo();
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-arena=%lu", mem.arena);
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-used=%lu",
                      mem.usmblks + mem.uordblks);
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-free=%lu",
		      mem.fsmblks + mem.fordblks);
#endif /* HAVE_MALLINFO */

      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: clients=%d",
                      cupsArrayCount(Clients));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: jobs=%d",
                      cupsArrayCount(Jobs));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: jobs-active=%d",
                      cupsArrayCount(ActiveJobs));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: printers=%d",
                      cupsArrayCount(Printers));
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: printers-implicit=%d",
                      cupsArrayCount(ImplicitPrinters));

      string_count = _cupsStrStatistics(&alloc_bytes, &total_bytes);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-string-count=" CUPS_LLFMT,
		      CUPS_LLCAST string_count);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-alloc-bytes=" CUPS_LLFMT,
		      CUPS_LLCAST alloc_bytes);
      cupsdLogMessage(CUPSD_LOG_DEBUG,
                      "Report: stringpool-total-bytes=" CUPS_LLFMT,
		      CUPS_LLCAST total_bytes);

      report_time = current_time;
    }

   /*
    * Handle OS-specific event notification for any events that have
    * accumulated.  Don't send these more than once a second...
    */

    if (LastEvent && (current_time - event_time) >= 1)
    {
#ifdef HAVE_NOTIFY_POST
      if (LastEvent & (CUPSD_EVENT_PRINTER_ADDED |
                       CUPSD_EVENT_PRINTER_DELETED |
                       CUPSD_EVENT_PRINTER_MODIFIED))
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.printerListChange\")");
	notify_post("com.apple.printerListChange");
      }

      if (LastEvent & CUPSD_EVENT_PRINTER_STATE_CHANGED)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.printerHistoryChange\")");
	notify_post("com.apple.printerHistoryChange");
      }

      if (LastEvent & (CUPSD_EVENT_JOB_STATE_CHANGED |
                       CUPSD_EVENT_JOB_CONFIG_CHANGED |
                       CUPSD_EVENT_JOB_PROGRESS))
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
	                "notify_post(\"com.apple.jobChange\")");
	notify_post("com.apple.jobChange");
      }
#endif /* HAVE_NOTIFY_POST */

     /*
      * Reset the accumulated events...
      */

      LastEvent  = CUPSD_EVENT_NONE;
      event_time = current_time;
    }
   }

 /*
  * Log a message based on what happened...
  */

  if (stop_scheduler)
    cupsdLogMessage(CUPSD_LOG_INFO, "Scheduler shutting down normally.");
  else
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Scheduler shutting down due to program error.");

 /*
  * Close all network clients...
  */

  cupsdStopServer();

#ifdef HAVE_LAUNCHD
 /*
  * Update the launchd KeepAlive file as needed...
  */

  if (Launchd)
    launchd_checkout();
#endif /* HAVE_LAUNCHD */

 /*
  * Stop all jobs...
  */

  cupsdFreeAllJobs();

#ifdef __APPLE__
 /*
  * Stop monitoring system event monitoring...
  */

  cupsdStopSystemMonitor();
#endif /* __APPLE__ */

#ifdef HAVE_GSSAPI
 /*
  * Free the scheduler's Kerberos context...
  */

#  ifdef __APPLE__
 /*
  * If the weak-linked GSSAPI/Kerberos library is not present, don't try
  * to use it...
  */

  if (krb5_init_context != NULL)
#  endif /* __APPLE__ */
  if (KerberosContext)
    krb5_free_context(KerberosContext);
#endif /* HAVE_GSSAPI */

#ifdef __APPLE__
#ifdef HAVE_DLFCN_H
 /* 
  * Unload Print Service quota enforcement library (X Server only) 
  */

  PSQUpdateQuotaProc = NULL;
  if (PSQLibRef)
  {
    dlclose(PSQLibRef);
    PSQLibRef = NULL;
  }
#endif /* HAVE_DLFCN_H */
#endif	/* __APPLE__ */

#ifdef __sgi
 /*
  * Remove the fake IRIX lpsched lock file, but only if the existing
  * file is not a FIFO which indicates that the real IRIX lpsched is
  * running...
  */

  if (!stat("/var/spool/lp/FIFO", &statbuf))
    if (!S_ISFIFO(statbuf.st_mode))
      unlink("/var/spool/lp/SCHEDLOCK");
#endif /* __sgi */

  cupsdStopSelect();

  return (!stop_scheduler);
}
示例#24
0
/*
 * GuizmOVPN_get_user_pass(char *username,char *password,const int capacity, char * prefix) :
 *      Request username/password from the user
 */
void GuizmOVPN_get_user_pass(char *username,char *password,const int capacity, char * prefix)
{
	int token, status, check;
	
	status = notify_register_check("com.guizmo.openvpn/ReceivedUserPass", &token);
	notify_check(token, &check);
	if (status != NOTIFY_STATUS_OK)
	{
		msg (M_FATAL, "Unable to receive authentification");
	}
	
	// Check which user/pass request to handle
	if(!strcmp(prefix,"token-insertion-request"))
	{
		notify_post("com.guizmo.openvpn/RequestTokenInsertionPass");
		
	} else if(!strcmp(prefix,"Auth")) {
		notify_post("com.guizmo.openvpn/RequestAuthUserPass");
		
	} else if(!strcmp(prefix,"HTTP Proxy")) {
		notify_post("com.guizmo.openvpn/RequestProxyUserPass");
		
	} else if(!strcmp(prefix,"pkcs11-id-request")) {
		notify_post("com.guizmo.openvpn/RequestPKCS11UserPass");
		
	} else if(!strcmp(prefix,"Private Key")) {
		notify_post("com.guizmo.openvpn/RequestPrivateKeyPass");
		
	} else if(!strstr(prefix," token")) {
		notify_post("com.guizmo.openvpn/RequestTokenPIN");
		
	} else {
		msg (M_FATAL, "Unknown user/pass request : %s",prefix);
		return;
	}
	
    msg (M_INFO, "Waiting for username/password (%s)",prefix);
	// May need to do a cleaner wait
	int received=0;
	while(!received)
	{
		status = notify_check(token, &check);
		if ((status == NOTIFY_STATUS_OK) && (check != 0))
		{
			msg (M_INFO,"Username/password received");
			received=1;
		}
		sleep(1);
	}
	
	// Read the username/password from file
	const char *path="/tmp/guizmovpn_temp_auth";
	FILE *fp = fopen (path, "r");
	if (!fp)
	{
		msg (M_FATAL, "Error receiving authentification");
	}
	
	if (fgets (username, capacity, fp) == NULL || fgets (password, capacity, fp) == NULL)
	{
		msg (M_FATAL, "Error receiving authentification");
	}
	
	fclose (fp);
	unlink(path);
	
	chomp (username);
	chomp (password);
    
	return;
}
示例#25
0
/*
 * Function: EAPOLClientConfigurationSave
 * 
 * Purpose:
 *   Write the configuration to persistent storage.
 *
 * Returns:
 *   TRUE if successfully written, FALSE otherwise.
 */	
Boolean
EAPOLClientConfigurationSave(EAPOLClientConfigurationRef cfg)
{
    Boolean		changed = FALSE;
    CFDictionaryRef	existing_prefs_dict;
    CFDictionaryRef	prefs_dict;
    Boolean		ret = FALSE;

    /* save the 802.1X prefs */
    prefs_dict = export_profiles(cfg);
    if (prefs_dict == NULL) {
	EAPLOG(LOG_NOTICE,
	       "EAPOLClientConfigurationSave export_profiles() failed");
	goto done;
    }
    existing_prefs_dict = SCPreferencesGetValue(cfg->eap_prefs,
						kConfigurationKeyProfiles);
    if (cfg->def_auth_props_changed == FALSE
	&& my_CFEqual(existing_prefs_dict, prefs_dict)) {
	/* configuration is the same, no need to save */
    }
    else {
	if (cfg->def_auth_props_changed) {
	    ret = SCPreferencesSetValue(cfg->eap_prefs,
					kConfigurationKeyDefaultAuthenticationProperties,
					cfg->def_auth_props);
	    if (ret == FALSE) {
		EAPLOG(LOG_NOTICE,
		       "EAPOLClientConfigurationSave SCPreferencesSetValue"
		       " failed %s",
		       SCErrorString(SCError()));
		goto done;
	    }
	}
	ret = SCPreferencesSetValue(cfg->eap_prefs, kConfigurationKeyProfiles,
				    prefs_dict);
	if (ret == FALSE) {
	    EAPLOG(LOG_NOTICE,
		   "EAPOLClientConfigurationSave SCPreferencesSetValue"
		   " failed %s",
		   SCErrorString(SCError()));
	    goto done;
	}
	ret = SCPreferencesCommitChanges(cfg->eap_prefs);
	if (ret == FALSE) {
	    EAPLOG(LOG_NOTICE,
		   "EAPOLClientConfigurationSave SCPreferencesCommitChanges"
		   " failed %s", SCErrorString(SCError()));
	    return (FALSE);
	}
	cfg->def_auth_props_changed = FALSE;
	SCPreferencesApplyChanges(cfg->eap_prefs);
	changed = TRUE;
    }

    /* save the network prefs */
    {
	Boolean		this_changed = FALSE;

	ret = saveInterfaceEAPOLConfiguration(cfg, &this_changed);
	if (ret == FALSE) {
	    goto done;
	}
	if (this_changed) {
	    changed = TRUE;
	}
    }
    my_CFRelease(&cfg->sc_prefs); /* force a refresh */

 done:
    my_CFRelease(&prefs_dict);
    if (changed) {
	notify_post(kEAPOLClientConfigurationChangedNotifyKey);
    }
    return (ret);
}