Exemple #1
0
/*
 * vfs_init.c
 *
 * Allocate and fill in operations vectors.
 *
 * An undocumented feature of this approach to defining operations is that
 * there can be multiple entries in vfs_opv_descs for the same operations
 * vector. This allows third parties to extend the set of operations
 * supported by another layer in a binary compatibile way. For example,
 * assume that NFS needed to be modified to support Ficus. NFS has an entry
 * (probably nfs_vnopdeop_decls) declaring all the operations NFS supports by
 * default. Ficus could add another entry (ficus_nfs_vnodeop_decl_entensions)
 * listing those new operations Ficus adds to NFS, all without modifying the
 * NFS code. (Of couse, the OTW NFS protocol still needs to be munged, but
 * that is a(whole)nother story.) This is a feature.
 */
void
vfs_opv_init(void)
{
	int i, j, k;
	int (***opv_desc_vector_p)(void *);
	int (**opv_desc_vector)(void *);
	struct vnodeopv_entry_desc *opve_descp;

	/*
	 * Allocate the dynamic vectors and fill them in.
	 */
	for (i=0; vfs_opv_descs[i]; i++) {
		opv_desc_vector_p = vfs_opv_descs[i]->opv_desc_vector_p;
		/*
		 * Allocate and init the vector, if it needs it.
		 * Also handle backwards compatibility.
		 */
		if (*opv_desc_vector_p == NULL) {
			MALLOC(*opv_desc_vector_p, PFIvp*,
			       vfs_opv_numops*sizeof(PFIvp), M_TEMP, M_WAITOK);
			bzero (*opv_desc_vector_p, vfs_opv_numops*sizeof(PFIvp));
			DODEBUG(printf("vector at %x allocated\n",
			    opv_desc_vector_p));
		}
		opv_desc_vector = *opv_desc_vector_p;
		for (j=0; vfs_opv_descs[i]->opv_desc_ops[j].opve_op; j++) {
			opve_descp = &(vfs_opv_descs[i]->opv_desc_ops[j]);

			/*
			 * Sanity check:  is this operation listed
			 * in the list of operations?  We check this
			 * by seeing if its offest is zero.  Since
			 * the default routine should always be listed
			 * first, it should be the only one with a zero
			 * offset.  Any other operation with a zero
			 * offset is probably not listed in
			 * vfs_op_descs, and so is probably an error.
			 *
			 * A panic here means the layer programmer
			 * has committed the all-too common bug
			 * of adding a new operation to the layer's
			 * list of vnode operations but
			 * not adding the operation to the system-wide
			 * list of supported operations.
			 */
			if (opve_descp->opve_op->vdesc_offset == 0 &&
				    opve_descp->opve_op->vdesc_offset !=
				    	VOFFSET(vnop_default)) {
				printf("operation %s not listed in %s.\n",
				    opve_descp->opve_op->vdesc_name,
				    "vfs_op_descs");
				panic ("vfs_opv_init: bad operation");
			}
			/*
			 * Fill in this entry.
			 */
			opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
					opve_descp->opve_impl;
		}
	}
Exemple #2
0
int
writeHP(int action,
        u_char * var_val,
        u_char var_val_type,
        int var_val_len, u_char * statP, oid * name, int name_len)
{
    DODEBUG("Gotto:  writeHP\n");
    return SNMP_ERR_NOERROR;
}
OPENVPN_EXPORT void
openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle)
{
  ldap_context_t *context = (ldap_context_t *) handle;
  action_t *action = action_new( );

  if (DOINFO (context->verb))
    LOGINFO( "%s() called", __FUNCTION__ );
  if( action){
    action->type = LDAP_AUTH_ACTION_QUIT;
    action_push( context->action_list, action );
    if( DODEBUG( context->verb ) )
      LOGDEBUG ("Waiting for thread to return");
    pthread_join( action_thread, NULL );
    if( DODEBUG( context->verb ) )
      LOGDEBUG ("Thread returned queries left in queue: %d", list_length( context->action_list ));
    pthread_attr_destroy( &action_thread_attr );
    pthread_mutex_destroy( &action_mutex );
    pthread_cond_destroy( &action_cond );
  }
  ldap_context_free( context );
  //pthread_exit(NULL);
}
/*
**
** Given a filled in UPRINT structure, this function 
** will return an argument for ppr's -T switch.
*/
static const char *uprint_get_content_type_ppr(void *p)
	{
	struct UPRINT *upr = (struct UPRINT *)p;

	DODEBUG(("uprint_get_content_type_ppr(p=%p)", p));

	if(upr->content_type_lpr != '\0')
		{
		switch(upr->content_type_lpr)
			{
			case 'c':					/* cifplot(1) output */
				return "cif";
			case 'd':					/* TeX DVI */
				return "dvi";
			case 'f':					/* formatted */
				return (const char *)NULL;
			case 'g':					/* plot(1) data */
				return "plot";
			case 'l':					/* leave control codes */
				return (const char *)NULL;
			case 'n':					/* ditroff output */
				return "troff";
			case 'p':					/* pass thru pr(1) */
				return "pr";
			case 't':					/* old troff output */
				return "cat4";
			case 'v':					/* sun raster format */
				return "sunras";
			case 'o':					/* PostScript */
				return "postscript";
			}
		}

	else if(upr->content_type_lp != (char*)NULL)
		{
		if(strcmp(upr->content_type_lp, "simple") == 0)
			return (const char *)NULL;

		if(strcmp(upr->content_type_lp, "postscript") == 0)
			return "postscript";
		}

	return (const char *)NULL;
	} /* end of uprint_get_content_type_ppr() */
void *
action_thread_main_loop (void *c)
{
  ldap_context_t *context = c;
  action_t *action = NULL;
  int rc;

  int loop = 1;
  while( loop ){
    action = action_pop(context->action_list);
    /* handle action */
    if (action){
      switch (action->type){
        case LDAP_AUTH_ACTION_AUTH:
          if( DOINFO(context->verb ) ){
            LOGINFO ( "Authentication requested for user %s",
                      ((auth_context_t *)action->context)->username);
          }
          rc = la_ldap_handle_authentication( context, action );
          /* we need to write the result to  auth_control_file */
          if( DODEBUG(context->verb ) ){
            LOGDEBUG( "User %s: Writing %c to auth_control_file %s",
                          ((auth_context_t *)action->context)->username,
                          rc == OPENVPN_PLUGIN_FUNC_SUCCESS ? '1' : '0',
                          ((auth_context_t *)action->context)->auth_control_file);
          }
          write_to_auth_control_file ( ((auth_context_t *)action->context)->auth_control_file,
                                        rc == OPENVPN_PLUGIN_FUNC_SUCCESS ? '1' : '0');
          break;
        case LDAP_AUTH_ACTION_QUIT:
          if( DOINFO(context->verb ) ){
            LOGINFO( "Authentication thread received ACTION_QUIT\n");
          }
          loop = 0;
          break;
        default:
          LOGWARNING( "%s:%d %s() Unknown action %d", __FILE__, __LINE__, __FUNCTION__, action->type);
      }
      action_free( action );
    }
  }
  pthread_exit (NULL);
}
Exemple #6
0
/*
** Handle an lpq style queue request.  The file names
** list is filled with a list of job numbers and
** user names.  This function is used by uprint-lpq
** to process local requests and from the new lprsrv in order
** to process requests from across the network.
**
** The term "agent" is from RFC-1179 and should probably
** be "remote_user".  Notice that it is not used.
*/
int uprint_lpq(uid_t uid, gid_t gid, const char agent[], const char queue[], int format, const char *arglist[], gu_boolean remote_too)
	{
	DODEBUG(("uprint_lpq(agent = \"%s\", queue = \"%s\", format = %d, arglist = ?)", agent, queue ? queue : "", format));

	if(queue == (char*)NULL)
		{
		uprint_error_callback("uprint_lpq(): queue is NULL");
		uprint_errno = UPE_NODEST;
		return -1;
		}

	/*
	** PPR spooler:
	** Use ppop.
	*/
	if(printdest_claim_ppr(queue))
		{
		const char *args[ARGS_SIZE + 1];
		int i, x;

		i = 0;
		args[i++] = "ppop";

		if(uprint_arrest_interest_interval)
			{
			args[i++] = "--arrest-interest-interval";
			args[i++] = uprint_arrest_interest_interval;
			}

		if(format == 0)
			args[i++] = "lpq";
		else
			args[i++] = "nhlist";

		args[i++] = queue;

		if(arglist != (const char **)NULL)
			{
			for(x = 0; arglist[x] != (const char *)NULL && x < ARGS_SIZE; x++, i++)
				{
				args[i] = arglist[x];
				}
			}

		args[i] = (const char *)NULL;

		return uprint_run(uid, gid, PPOP_PATH, args);
		}

	/*
	** System V lp:
	** Use the lpstat program.
	*/
	else if(printdest_claim_sysv(queue))
		{
		const char *args[ARGS_SIZE];
		int i, x;
		#ifdef LP_LPSTAT_BROKEN
		char temp[32+3];
		#endif

		i = 0;
		args[i++] = "lpstat";

		/* Certain very old versions of lpstat can't parse
		   options arranged according to POSIX rules, with
		   a space between option and argument.  The 32
		   character limit is chosen arbitrarily. */
		#ifdef LP_LPSTAT_BROKEN
		snprintf(temp, sizeof(temp), "-o%s", queue);
		args[i++] = temp;
		#else
		args[i++] = "-o";
		args[i++] = queue;
		#endif

		/* If there are file names (as opposed to no file names
		   which indicates stdin) then add them now. */
		if(arglist != (const char **)NULL)
			{
			for(x = 0; arglist[x] && x < ARGS_SIZE; x++, i++)
				{
				args[i] = arglist[x];
				}
			}

		/* Terminate the argument list. */
		args[i] = (const char *)NULL;

		return uprint_run(uid, gid, uprint_path_lpstat(), args);
		}

	/*
	** BSD lpr:
	** Use the lpq program.
	*/
	if(printdest_claim_bsd(queue))
		{
		const char *args[ARGS_SIZE];
		int i, x;

		args[0] = "lpq";
		args[1] = "-P";
		args[2] = queue;
		i = 3;
		if(format != 0)
			args[i++] = "-l";

		if(arglist != (const char **)NULL)
			{
			for(x = 0; arglist[x] != (const char *)NULL && x < ARGS_SIZE; x++, i++)
				{
				args[i] = arglist[x];
				}
			}

		args[i] = (const char *)NULL;

		return uprint_run(uid, gid, uprint_path_lpq(), args);
		}

	/*
	** Thru lpr/lpd protocol over the network:
	*/
	{
	struct REMOTEDEST info;
	if(remote_too && printdest_claim_remote(queue, &info))
		return uprint_lpq_rfc1179(queue, format, arglist, &info);
	}

	/*
	** We will only reach here if none of
	** the spoolers claimed the queue.
	*/
	uprint_errno = UPE_UNDEST;
	return -1;
	} /* end of uprint_lpq() */
OPENVPN_EXPORT openvpn_plugin_handle_t
openvpn_plugin_open_v2 (unsigned int *type_mask, const char *argv[], const char *envp[], struct openvpn_plugin_string_list **return_list)
{

  ldap_context_t *context;
  const char *daemon_string = NULL;
  const char *log_redirect = NULL;

  const char *configfile = NULL;
  int rc = 0;
  uint8_t     allow_core_files = 0;

  /* Are we in daemonized mode? If so, are we redirecting the logs? */
  daemon_string = get_env ("daemon", envp);
  use_syslog = 0;
  if( daemon_string && daemon_string[0] == '1'){
    log_redirect = get_env ("daemon_log_redirect", envp);
    if( !(log_redirect && log_redirect[0] == '1'))
      use_syslog = 1;
  }
  /*
   * Allocate our context
   */
  context = ldap_context_new( );
  if( !context ){
    LOGERROR( "Failed to initialize ldap_context, no memory available?" );
    goto error;
  }
  /*
   * Intercept the --auth-user-pass-verify callback.
   */
  *type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY);

   while ( ( rc = getopt ( string_array_len (argv), (char **)argv, ":H:D:c:t:WZC" ) ) != - 1 ){
    switch( rc ) {
      case 'H':
        context->config->ldap->uri = strdup(optarg);
        break;
      case 'Z':
        context->config->ldap->ssl = strdup("start_tls");
        break;
      case 'D':
        context->config->ldap->binddn = strdup(optarg);
        break;
      case 'W':
        context->config->ldap->bindpw = get_passwd("BindPW Password: "******"Password is %s: length: %d\n", config->bindpw, strlen(config->bindpw) );
        break;
      case 'c':
        configfile = optarg;
        break;
      case 't':
        context->config->ldap->timeout = atoi( optarg );
        break;
      case 'C':
        LOGDEBUG("Core file generation requested");
        allow_core_files = 1;
        break;
      case '?':
        LOGERROR("Unknown Option -%c !!", optopt );
        break;
      case ':':
        LOGERROR ("Missing argument for option -%c !!", optopt );
        break;
      default:
        LOGERROR ("?? getopt returned character code 0%o ??", rc);
        abort();
    }
  }

#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
  if (allow_core_files){
    LOGDEBUG ("Setting core file");
    unlimit_core_size();
  }
#endif

  /**
   * Parse configuration file is -c filename is provided
   * If not provided, use a default config file OCONFIG
   * This file must exists even though it might be empty
   */
  if( configfile == NULL) {
    configfile = OCONFIG;
  }

  if( config_parse_file( configfile, context->config ) ){
    goto error;
  }
  /**
   * Set default config values
   */
  config_set_default( context->config );


  /* when ldap userconf is define, we need to hook onto those callbacks */
  if( config_is_pf_enabled( context->config )){
    *type_mask |= OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ENABLE_PF);
  }
#ifdef ENABLE_LDAPUSERCONF
  *type_mask |= OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2)
                | OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_DISCONNECT);
#else
  if( config_is_redirect_gw_enabled( context->config ) ){
    *type_mask |= OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2);
  }
#endif

  /*
   * Get verbosity level from environment
   */
  const char *verb_string = get_env ("verb", envp);
  if (verb_string)
    context->verb = atoi (verb_string);

  if( DODEBUG( context->verb ) )
      config_dump( context->config );


  /* set up mutex/cond */
  pthread_mutex_init (&action_mutex, NULL);
  pthread_cond_init (&action_cond, NULL);

  /* start our authentication thread */
  pthread_attr_setdetachstate(&action_thread_attr, PTHREAD_CREATE_JOINABLE);
  rc = pthread_create(&action_thread, &action_thread_attr, action_thread_main_loop, context);

  switch( rc ){
    case EAGAIN:
      LOGERROR( "pthread_create returned EAGAIN: lacking resources" );
      break;
    case EINVAL:
      LOGERROR( "pthread_create returned EINVAL: invalid attributes" );
      break;
    case EPERM:
      LOGERROR( "pthread_create returned EPERM: no permission to create thread" );
      break;
    case 0:
      break;
    default:
      LOGERROR( "pthread_create returned an unhandled value: %d", rc );
  }
  if( rc == 0)
    return (openvpn_plugin_handle_t) context;

  /* Failed to initialize, free resources */
  pthread_attr_destroy( &action_thread_attr );
  pthread_mutex_destroy( &action_mutex );
  pthread_cond_destroy( &action_cond );

error:
  if ( context ){
    ldap_context_free (context);
  }
  return NULL;
}
Exemple #8
0
/*
** Tie it all together.
*/
int int_main(int argc, char *argv[])
	{
	int portfd;							/* file handle of the printer port */
	struct termios settings;			/* printer port settings */
	struct OPTIONS options;				/* a bundle of other options */

	/* Initialize internation messages library. */
	#ifdef INTERNATIONAL
	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE_INTERFACES, LOCALEDIR);
	textdomain(PACKAGE_INTERFACES);
	#endif

	int_cmdline_set(argc, argv);

	DODEBUG(("============================================================"));
	DODEBUG(("\"%s\", \"%s\", \"%s\", %d, %s %d",
		int_cmdline.printer,
		int_cmdline.address,
		int_cmdline.options,
		int_cmdline.jobbreak,
		int_cmdline.feedback ? "TRUE" : "FALSE",
		int_cmdline.codes));

	/* There is no out-of-band path for probing printers over a serial line. */
	if(int_cmdline.probe)
		{
		fprintf(stderr, _("The interface program \"%s\" does not support probing.\n"), int_cmdline.int_basename);
	    int_exit(EXIT_PRNERR);
		}

	/* Check for unusable job break methods. */
	if(int_cmdline.jobbreak == JOBBREAK_SIGNAL || int_cmdline.jobbreak == JOBBREAK_SIGNAL_PJL)
		{
		alert(int_cmdline.printer, TRUE,
				_("The jobbreak methods \"signal\" and \"signal/pjl\" are not compatible with\n"
				"the PPR interface program \"%s\"."), int_cmdline.int_basename);
		int_exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS);
		}

	/* Check for unusable codes settings. */
	if(int_cmdline.codes == CODES_Binary)
		{
		alert(int_cmdline.printer, TRUE,
				_("The codes setting \"Binary\" is not compatible with the PPR interface\n"
				"program \"%s\"."), int_cmdline.int_basename);
		int_exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS);
		}

	gu_write_string(1, "%%[ PPR connecting ]%%\n");

	/* Open the printer port and esablish default settings: */
	portfd = open_port(int_cmdline.printer, int_cmdline.address, &settings);

	/* Parse printer_options and set struct OPTIONS and
	   printer port apropriately: */
	set_options(int_cmdline.printer, int_cmdline.options, portfd, &settings, &options);

	/*
	** Make sure the necessary modem control lines are on to
	** indicate that the printer is on line.
	**
	** I think I got the information to write this test from
	** the SunOS 5.x ioctl() man page.
	*/
	#ifdef TIOCMGET
	if(options.online != 0)
		{
		int x;
		int modem_status;
		struct timeval tv;

		/* We must retry this operation because the printer may not
		   have had time to respond to our raising of DTR and RTS. */
		for(x=0; x < 20; x++)
			{
			if(ioctl(portfd, TIOCMGET, &modem_status) < 0)
				printer_error("ioctl", portfd, errno);

			DODEBUG(("modem status: %s %s %s",
					modem_status & TIOCM_CD ? "CD" : "",
					modem_status & TIOCM_DSR ? "DSR" : "",
					modem_status & TIOCM_CTS ? "CTS" : ""
					));

			if( (modem_status & options.online) == options.online )
				break;

			/* Delay for 1 tenth of one second. */
			tv.tv_sec = 0;
			tv.tv_usec = 100000;
			select(0, NULL, NULL, NULL, &tv);
			}

		if(x == 20)
			{
			DODEBUG(("offline"));
			gu_write_string(1, "%%[ PrinterError: off line ]%%\n");
			int_exit(EXIT_ENGAGED);
			}
		}
	#endif

	gu_write_string(1, "%%[ PPR connected ]%%\n");

	int_copy_job(portfd, 
		options.idle_status_interval, 
		printer_error, 
		NULL, NULL, NULL,
		0,
		NULL
		);

	DODEBUG(("closing port"));
	close(portfd);

	DODEBUG(("sucessful completion"));
	return EXIT_PRINTED;		/* needn't call int_exit() */
	} /* end of main() */
Exemple #9
0
/*
** Open the printer port.
*/
static int open_port(const char *printer_name, const char *printer_address, struct termios *settings)
	{
	struct stat statbuf;				/* buffer for stat on the port */
	int portfd;

	DODEBUG(("open_port(printer_name=\"%s\", printer_address=\"%s\", settings=%p", printer_name, printer_address, settings));

	/*
	** Make sure the address we were given is a tty.
	** If stat() fails, we will ignore the error
	** for now, we will let open() catch it.
	*/
	if(stat(printer_address, &statbuf) == 0)
		{
		if( ! (statbuf.st_mode & S_IFCHR) )
			{
			alert(int_cmdline.printer, TRUE, "The file \"%s\" is not a tty.");
			int_exit(EXIT_PRNERR_NORETRY_BAD_SETTINGS);
			}
		}

	/*
	** Open the port.  We use alarm() to give this operation a
	** timeout since printers which are off line have been known
	** to cause open() to block indefinitely.
	*/
	portfd = open(printer_address, O_RDWR | O_NONBLOCK | O_NOCTTY | O_EXCL);

	if(portfd == -1)	/* If error, */
		{
		switch(errno)
			{
			case EACCES:
				alert(int_cmdline.printer, TRUE, _("Access to port \"%s\" is denied."), printer_address);
				int_exit(EXIT_PRNERR_NORETRY_ACCESS_DENIED);
			case ENOENT:		/* file not found */
			case ENOTDIR:		/* path not found */
				alert(int_cmdline.printer, TRUE, "The port \"%s\" does not exist.", printer_address);
				int_exit(EXIT_PRNERR_NORETRY_NO_SUCH_ADDRESS);
			case ENXIO:
				alert(int_cmdline.printer, TRUE, "The device file \"%s\" exists, but the device doesn't.", printer_address);
				int_exit(EXIT_PRNERR_NORETRY_NO_SUCH_ADDRESS);
			case EIO:
				alert(int_cmdline.printer, TRUE, _("Hangup or other error while opening \"%s\"."), printer_address);
				int_exit(EXIT_PRNERR);
			case ENFILE:
				alert(int_cmdline.printer, TRUE, _("System open file table is full."));
				int_exit(EXIT_STARVED);
			#ifdef ENOSR
			case ENOSR:
				alert(int_cmdline.printer, TRUE, "System is out of STREAMS.");
				int_exit(EXIT_STARVED);
			#endif
			default:
				alert(int_cmdline.printer, TRUE, "Can't open \"%s\", %s.", printer_address, gu_strerror(errno));
				int_exit(EXIT_PRNERR_NORETRY);
			}
		}

	/*
	** Wait for output to drain and then get the current port settings.
	** Getting the current settings is said to be important because the
	** termios structure might have some implementations specific bits
	** that we should not mess with.
	**
	** (See POSIX Programmers Guide, Donald Lewine, page 161.)
	*/
	tcdrain(portfd);
	tcgetattr(portfd, settings);

	/*
	** Establish some default port settings.
	** I wonder if we are messing with some of those
	** implementation specific bits.
	*/
	settings->c_iflag = IXON | IXOFF;
	settings->c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
	settings->c_oflag = 0;
	settings->c_lflag = 0;
	settings->c_cc[VMIN] = 1;	/* Don't return with zero characters */
	settings->c_cc[VTIME] = 2;	/* Wait 0.2 second for next character */
	cfsetispeed(settings, B9600);
	cfsetospeed(settings, B9600);

	return portfd;
	} /* end of open_port() */