/* * 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; } }
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); }
/* ** 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; }
/* ** 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() */
/* ** 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() */