/******************************************************************* report a fault ********************************************************************/ static void fault_report(int sig) { static int counter; if (counter) abort(); counter++; LOG(log_severe, logtype_default, "==============================================================="); LOG(log_severe, logtype_default, "INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),VERSION); LOG(log_severe, logtype_default, "==============================================================="); netatalk_panic("internal error"); if (cont_fn) { cont_fn(NULL); #ifdef SIGSEGV CatchSignal(SIGSEGV,SIGNAL_CAST SIG_DFL); #endif #ifdef SIGBUS CatchSignal(SIGBUS,SIGNAL_CAST SIG_DFL); #endif return; /* this should cause a core dump */ } abort(); }
/******************************************************************* report a fault ********************************************************************/ static void fault_report(int sig) { static int counter; if (counter) _exit(1); counter++; DEBUGSEP(0); DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)sys_getpid(),SAMBA_VERSION_STRING)); DEBUG(0,("\nPlease read the Trouble-Shooting section of the Samba3-HOWTO\n")); DEBUG(0,("\nFrom: http://www.samba.org/samba/docs/Samba3-HOWTO.pdf\n")); DEBUGSEP(0); smb_panic("internal error"); if (cont_fn) { cont_fn(NULL); #ifdef SIGSEGV CatchSignal(SIGSEGV,SIGNAL_CAST SIG_DFL); #endif #ifdef SIGBUS CatchSignal(SIGBUS,SIGNAL_CAST SIG_DFL); #endif #ifdef SIGABRT CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL); #endif return; /* this should cause a core dump */ } exit(1); }
/******************************************************************* report a fault ********************************************************************/ static void fault_report(int sig) { static int counter; if (counter) _exit(1); counter++; DEBUG(0,("===============================================================\n")); DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)sys_getpid(),VERSION)); DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n")); DEBUG(0,("===============================================================\n")); smb_panic("internal error"); if (cont_fn) { cont_fn(NULL); #ifdef SIGSEGV CatchSignal(SIGSEGV,SIGNAL_CAST SIG_DFL); #endif #ifdef SIGBUS CatchSignal(SIGBUS,SIGNAL_CAST SIG_DFL); #endif return; /* this should cause a core dump */ } exit(1); }
BOOL do_file_lock (int fd, int waitsecs, int type) { SMB_STRUCT_FLOCK lock; int ret; gotalarm = 0; CatchSignal (SIGALRM, SIGNAL_CAST gotalarm_sig); lock.l_type = type; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 1; lock.l_pid = 0; alarm (waitsecs); ret = fcntl (fd, SMB_F_SETLKW, &lock); alarm (0); CatchSignal (SIGALRM, SIGNAL_CAST SIG_DFL); if (gotalarm) { DEBUG (0, ("do_file_lock: failed to %s file.\n", type == F_UNLCK ? "unlock" : "lock")); return False; } return (ret == 0); }
/*************************************************************************** create a child process to handle DNS lookups ****************************************************************************/ void start_async_dns(void) { int fd1[2], fd2[2]; CatchChild(); if (pipe(fd1) || pipe(fd2)) { DEBUG(0,("can't create asyncdns pipes\n")); return; } child_pid = sys_fork(); if (child_pid) { fd_in = fd1[0]; fd_out = fd2[1]; close(fd1[1]); close(fd2[0]); DEBUG(0,("started asyncdns process %d\n", (int)child_pid)); return; } fd_in = fd2[0]; fd_out = fd1[1]; CatchSignal(SIGUSR2, SIG_IGN); CatchSignal(SIGUSR1, SIG_IGN); CatchSignal(SIGHUP, SIG_IGN); CatchSignal(SIGTERM, SIGNAL_CAST sig_term ); asyncdns_process(); }
static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout, int rw_type) { /* Allow tdb_chainlock to be interrupted by an alarm. */ int ret; gotalarm = 0; if (timeout) { CatchSignal(SIGALRM, gotalarm_sig); tdb_setalarm_sigptr(tdb, &gotalarm); alarm(timeout); } if (rw_type == F_RDLCK) ret = tdb_chainlock_read(tdb, key); else ret = tdb_chainlock(tdb, key); if (timeout) { alarm(0); tdb_setalarm_sigptr(tdb, NULL); CatchSignal(SIGALRM, SIG_IGN); if (gotalarm && (ret != 0)) { DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n", timeout, key.dptr, tdb_name(tdb))); /* TODO: If we time out waiting for a lock, it might * be nice to use F_GETLK to get the pid of the * process currently holding the lock and print that * as part of the debugging message. -- mbp */ return -1; } } return ret == 0 ? 0 : -1; }
static bool do_file_lock(int fd, int waitsecs, int type) { SMB_STRUCT_FLOCK lock; int ret; void (*oldsig_handler)(int); gotalarm = 0; oldsig_handler = CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); lock.l_type = type; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 1; lock.l_pid = 0; alarm(waitsecs); /* Note we must *NOT* use sys_fcntl here ! JRA */ ret = fcntl(fd, SMB_F_SETLKW, &lock); alarm(0); CatchSignal(SIGALRM, SIGNAL_CAST oldsig_handler); if (gotalarm && ret == -1) { DEBUG(0, ("do_file_lock: failed to %s file.\n", type == F_UNLCK ? "unlock" : "lock")); return False; } return (ret == 0); }
/* setup signal masks */ static void setup_signals(void) { /* we are never interested in SIGPIPE */ BlockSignals(true,SIGPIPE); #if defined(SIGFPE) /* we are never interested in SIGFPE */ BlockSignals(true,SIGFPE); #endif /* We are no longer interested in USR1 */ BlockSignals(true, SIGUSR1); #if defined(SIGUSR2) /* We are no longer interested in USR2 */ BlockSignals(true,SIGUSR2); #endif /* POSIX demands that signals are inherited. If the invoking process has * these signals masked, we will have problems, as we won't receive them. */ BlockSignals(false, SIGHUP); BlockSignals(false, SIGTERM); CatchSignal(SIGHUP, sig_hup); CatchSignal(SIGTERM, sig_term); }
/* setup signal masks */ static void setup_signals(void) { /* we are never interested in SIGPIPE */ BlockSignals(true, SIGPIPE); #if defined(SIGFPE) /* we are never interested in SIGFPE */ BlockSignals(true, SIGFPE); #endif /* We are no longer interested in USR1 */ BlockSignals(true, SIGUSR1); /* We are no longer interested in SIGINT except for monitor */ BlockSignals(true, SIGINT); #if defined(SIGUSR2) /* We are no longer interested in USR2 */ BlockSignals(true, SIGUSR2); #endif /* POSIX demands that signals are inherited. If the invoking process has * these signals masked, we will have problems, as we won't receive them. */ BlockSignals(false, SIGHUP); BlockSignals(false, SIGTERM); #ifndef HAVE_PRCTL /* If prctl is not defined on the system, try to handle * some common termination signals gracefully */ CatchSignal(SIGSEGV, sig_segv_abrt); CatchSignal(SIGABRT, sig_segv_abrt); #endif }
static http_t *cups_connect(TALLOC_CTX *frame) { http_t *http = NULL; char *server = NULL, *p = NULL; int port; int timeout = lp_cups_connection_timeout(); size_t size; if (lp_cups_server(talloc_tos()) != NULL && strlen(lp_cups_server(talloc_tos())) > 0) { if (!push_utf8_talloc(frame, &server, lp_cups_server(talloc_tos()), &size)) { return NULL; } } else { server = talloc_strdup(frame,cupsServer()); } if (!server) { return NULL; } p = strchr(server, ':'); if (p) { port = atoi(p+1); *p = '\0'; } else { port = ippPort(); } DEBUG(10, ("connecting to cups server %s:%d\n", server, port)); gotalarm = 0; if (timeout) { CatchSignal(SIGALRM, gotalarm_sig); alarm(timeout); } #ifdef HAVE_HTTPCONNECTENCRYPT http = httpConnectEncrypt(server, port, lp_cups_encrypt()); #else http = httpConnect(server, port); #endif CatchSignal(SIGALRM, SIG_IGN); alarm(0); if (http == NULL) { DEBUG(0,("Unable to connect to CUPS server %s:%d - %s\n", server, port, strerror(errno))); } return http; }
/******************************************************************* setup our fault handlers ********************************************************************/ void fault_setup(void (*fn)(void *)) { cont_fn = fn; #ifdef SIGSEGV CatchSignal(SIGSEGV,SIGNAL_CAST sig_fault); #endif #ifdef SIGBUS CatchSignal(SIGBUS,SIGNAL_CAST sig_fault); #endif }
void ZSList::WorldShutDown(uint32 time, uint32 interval) { if( time > 0 ) { SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down in %i seconds, everyone log out before this time.",time); time *= 1000; interval *= 1000; if(interval < 5000) { interval = 5000; } shutdowntimer->SetTimer(time); reminder->SetTimer(interval-1000); reminder->SetAtTrigger(interval); shutdowntimer->Start(); reminder->Start(); } else { SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down, everyone log out now."); ServerPacket* pack = new ServerPacket; pack->opcode = ServerOP_ShutdownAll; pack->size=0; SendPacket(pack); safe_delete(pack); Process(); CatchSignal(2); } }
void dump_core(void) { /* Note that even if core dumping has been disabled, we still set up * the core path. This is to handle the case where core dumping is * turned on in smb.conf and the relevant daemon is not restarted. */ if (!lp_enable_core_files()) { DEBUG(0, ("Exiting on internal error (core file administratively disabled\n")); exit(1); } if (*corepath != '\0') { /* The chdir might fail if we dump core before we finish * processing the config file. */ if (chdir(corepath) != 0) { DEBUG(0, ("unable to change to %s", corepath)); DEBUGADD(0, ("refusing to dump core\n")); exit(1); } DEBUG(0,("dumping core in %s\n", corepath)); } umask(~(0700)); dbgflush(); /* Ensure we don't have a signal handler for abort. */ #ifdef SIGABRT CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL); #endif abort(); }
/** Something really nasty happened - panic ! **/ _PUBLIC_ _NORETURN_ void smb_panic(const char *why) { int result; if (panic_action && *panic_action) { char pidstr[20]; char cmdstring[200]; safe_strcpy(cmdstring, panic_action, sizeof(cmdstring)); snprintf(pidstr, sizeof(pidstr), "%u", getpid()); all_string_sub(cmdstring, "%PID%", pidstr, sizeof(cmdstring)); if (progname) { all_string_sub(cmdstring, "%PROG%", progname, sizeof(cmdstring)); } DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmdstring)); result = system(cmdstring); if (result == -1) DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n", strerror(errno))); else DEBUG(0, ("smb_panic(): action returned status %d\n", WEXITSTATUS(result))); } DEBUG(0,("PANIC: %s\n", why)); call_backtrace(); #ifdef SIGABRT CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL); #endif abort(); }
void AddEQEMuError(eEQEMuError iError, bool iExitNow) { if (!iError) return; if (!EQEMuErrorList) { EQEMuErrorList = new LinkedList<char*>; MEQEMuErrorList = new Mutex; } LockMutex lock(MEQEMuErrorList); LinkedListIterator<char*> iterator(*EQEMuErrorList); iterator.Reset(); while (iterator.MoreElements()) { if (iterator.GetData()[0] == 1) { //Umm... this gets a big WTF... // if (*((uint32*) iterator.GetData()[1]) == iError) //not sure whats going on, using a character as a pointer.... if (*((eEQEMuError*) &(iterator.GetData()[1])) == iError) return; } iterator.Advance(); } char* tmp = new char[6]; tmp[0] = 1; tmp[5] = 0; *((uint32*) &tmp[1]) = iError; EQEMuErrorList->Append(tmp); if (iExitNow) CatchSignal(2); }
/** setup our fault handlers **/ _PUBLIC_ void fault_setup(const char *pname) { if (progname == NULL) { progname = pname; } #ifdef SIGSEGV CatchSignal(SIGSEGV,SIGNAL_CAST sig_fault); #endif #ifdef SIGBUS CatchSignal(SIGBUS,SIGNAL_CAST sig_fault); #endif #ifdef SIGABRT CatchSignal(SIGABRT,SIGNAL_CAST sig_fault); #endif #ifdef SIGFPE CatchSignal(SIGFPE,SIGNAL_CAST sig_fault); #endif }
void dump_core(void) { static bool called; if (called) { DEBUG(0, ("dump_core() called recursive\n")); exit(1); } called = true; /* Note that even if core dumping has been disabled, we still set up * the core path. This is to handle the case where core dumping is * turned on in smb.conf and the relevant daemon is not restarted. */ if (!lp_enable_core_files()) { DEBUG(0, ("Exiting on internal error (core file administratively disabled)\n")); exit(1); } #if DUMP_CORE /* If we're running as non root we might not be able to dump the core * file to the corepath. There must not be an unbecome_root() before * we call abort(). */ if (geteuid() != 0) { become_root(); } if (*corepath != '\0') { /* The chdir might fail if we dump core before we finish * processing the config file. */ if (chdir(corepath) != 0) { DEBUG(0, ("unable to change to %s\n", corepath)); DEBUGADD(0, ("refusing to dump core\n")); exit(1); } DEBUG(0,("dumping core in %s\n", corepath)); } umask(~(0700)); dbgflush(); /* Ensure we don't have a signal handler for abort. */ #ifdef SIGABRT CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL); #endif abort(); #else /* DUMP_CORE */ exit(1); #endif /* DUMP_CORE */ }
/* ************************************************************************** ** * catch a sigusr2 - decrease the debug log level. * ************************************************************************** ** */ void sig_usr2( int sig ) { DEBUGLEVEL--; if( DEBUGLEVEL < 0 ) DEBUGLEVEL = 0; DEBUG( 0, ( "Got SIGUSR2; set debug level to %d.\n", DEBUGLEVEL ) ); #if !defined(HAVE_SIGACTION) CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 ); #endif } /* sig_usr2 */
// --------------------------------------------------------------------------- // void OnSignalProc(int s) // // handle signal, if signal SIGTERM is received. // the main process should be shutdown. // --------------------------------------------------------------------------- // void OnSignalProc(int s) { const char *funcName = "OnSignalProc"; LOG(LL_ERROR, "%s::Catch signal :%d", funcName, s); if (s == SIGUSR1) { LOG(LL_ERROR, "%s::signal :%d", funcName, s); } else { LOG(LL_ERROR, "%s::Catch signal :%d, exit!!!", funcName, s); gIsStoped = true; exit(0); } CatchSignal(); }
static void sig_cld_leave_status(int signum) { /* * Turns out it's *really* important not to * restore the signal handler here if we have real POSIX * signal handling. If we do, then we get the signal re-delivered * immediately - hey presto - instant loop ! JRA. */ #if !defined(HAVE_SIGACTION) CatchSignal(SIGCLD, sig_cld_leave_status); #endif }
static void winbind_msg_validate_cache(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data) { uint8 ret; pid_t child_pid; NTSTATUS status; DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache " "message.\n")); /* * call the validation code from a child: * so we don't block the main winbindd and the validation * code can safely use fork/waitpid... */ child_pid = sys_fork(); if (child_pid == -1) { DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n", strerror(errno))); return; } if (child_pid != 0) { /* parent */ DEBUG(5, ("winbind_msg_validate_cache: child created with " "pid %d.\n", (int)child_pid)); return; } /* child */ status = winbindd_reinit_after_fork(NULL, NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n", nt_errstr(status))); _exit(0); } /* install default SIGCHLD handler: validation code uses fork/waitpid */ CatchSignal(SIGCHLD, SIG_DFL); ret = (uint8)winbindd_validate_cache_nobackup(); DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret)); messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret, (size_t)1); _exit(0); }
void AddEQEMuError(char* iError, bool iExitNow) { if (!iError) return; if (!EQEMuErrorList) { EQEMuErrorList = new LinkedList<char*>; MEQEMuErrorList = new Mutex; } LockMutex lock(MEQEMuErrorList); char* tmp = strcpy(new char[strlen(iError) + 1], iError); EQEMuErrorList->Append(tmp); if (iExitNow) CatchSignal(2); }
/* ************************************************************************** ** * catch a sigusr1 - increase the debug log level. * ************************************************************************** ** */ void sig_usr1( int sig ) { DEBUGLEVEL++; if( DEBUGLEVEL > 10 ) DEBUGLEVEL = 10; DEBUG( 0, ( "Got SIGUSR1; set debug level to %d.\n", DEBUGLEVEL ) ); #if !defined(HAVE_SIGACTION) CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 ); #endif } /* sig_usr1 */
static void sig_cld(int signum) { while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0) ; /* * Turns out it's *really* important not to * restore the signal handler here if we have real POSIX * signal handling. If we do, then we get the signal re-delivered * immediately - hey presto - instant loop ! JRA. */ #if !defined(HAVE_SIGACTION) CatchSignal(SIGCLD, sig_cld); #endif }
BOOL message_init(void) { if (tdb) return True; tdb = tdb_open_log(lock_path("messages.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDWR|O_CREAT,0600); if (!tdb) { DEBUG(0,("ERROR: Failed to initialise messages database\n")); return False; } CatchSignal(SIGUSR1, SIGNAL_CAST sig_usr1); message_register(MSG_PING, ping_message); message_register(MSG_REQ_DEBUGLEVEL, debuglevel_message); return True; }
void ZSList::Process() { if(shutdowntimer && shutdowntimer->Check()){ _log(WORLD__ZONELIST, "Shutdown timer has expired. Telling all zones to shut down and exiting. (fake sigint)"); ServerPacket* pack2 = new ServerPacket; pack2->opcode = ServerOP_ShutdownAll; pack2->size=0; SendPacket(pack2); safe_delete(pack2); Process(); CatchSignal(2); } if(reminder && reminder->Check()){ SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down, everyone log out now. World will shut down in %i seconds...",shutdowntimer->GetRemainingTime()/1000); } LinkedListIterator<ZoneServer*> iterator(list); iterator.Reset(); while(iterator.MoreElements()) { if (!iterator.GetData()->Process()) { ZoneServer* zs = iterator.GetData(); struct in_addr in; in.s_addr = zs->GetIP(); _log(WORLD__ZONELIST,"Removing zoneserver #%d at %s:%d",zs->GetID(),zs->GetCAddress(),zs->GetCPort()); zs->LSShutDownUpdate(zs->GetZoneID()); if (holdzones){ _log(WORLD__ZONELIST,"Hold Zones mode is ON - rebooting lost zone"); if(!zs->IsStaticZone()) RebootZone(inet_ntoa(in),zs->GetCPort(),zs->GetCAddress(),zs->GetID()); else RebootZone(inet_ntoa(in),zs->GetCPort(),zs->GetCAddress(),zs->GetID(),database.GetZoneID(zs->GetZoneName())); } iterator.RemoveCurrent(); numzones--; } else { iterator.Advance(); } } }
BOOL message_init(void) { if (tdb) return True; tdb = tdb_open_log(lock_path("messages.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDWR|O_CREAT,0600); if (!tdb) { DEBUG(0,("ERROR: Failed to initialise messages database\n")); return False; } CatchSignal(SIGUSR1, SIGNAL_CAST sig_usr1); message_register(MSG_PING, ping_message); /* Register some debugging related messages */ register_msg_pool_usage(); register_dmalloc_msgs(); return True; }
int main(int argc, const char ** argv) { int i; const char ** dd_args; struct tevent_context *ev; poptContext pctx; struct poptOption poptions[] = { /* POPT_AUTOHELP */ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, cifsddHelpOptions, 0, "Help options:", NULL }, POPT_COMMON_SAMBA POPT_COMMON_CONNECTION POPT_COMMON_CREDENTIALS POPT_COMMON_VERSION { NULL } }; /* Block sizes. */ set_arg_val("bs", (uint64_t)4096); set_arg_val("ibs", (uint64_t)4096); set_arg_val("obs", (uint64_t)4096); /* Block counts. */ set_arg_val("count", (uint64_t)-1); set_arg_val("seek", (uint64_t)0); set_arg_val("seek", (uint64_t)0); /* Files. */ set_arg_val("if", NULL); set_arg_val("of", NULL); /* Options. */ set_arg_val("direct", false); set_arg_val("sync", false); set_arg_val("oplock", false); pctx = poptGetContext(PROGNAME, argc, argv, poptions, 0); while ((i = poptGetNextOpt(pctx)) != -1) { ; } for (dd_args = poptGetArgs(pctx); dd_args && *dd_args; ++dd_args) { if (!set_arg_argv(*dd_args)) { fprintf(stderr, "%s: invalid option: %s\n", PROGNAME, *dd_args); exit(SYNTAX_EXIT_CODE); } /* "bs" has the side-effect of setting "ibs" and "obs". */ if (strncmp(*dd_args, "bs=", 3) == 0) { uint64_t bs = check_arg_numeric("bs"); set_arg_val("ibs", bs); set_arg_val("obs", bs); } } ev = s4_event_context_init(talloc_autofree_context()); gensec_init(cmdline_lp_ctx); dump_args(); if (check_arg_numeric("ibs") == 0 || check_arg_numeric("ibs") == 0) { fprintf(stderr, "%s: block sizes must be greater that zero\n", PROGNAME); exit(SYNTAX_EXIT_CODE); } if (check_arg_pathname("if") == NULL) { fprintf(stderr, "%s: missing input filename\n", PROGNAME); exit(SYNTAX_EXIT_CODE); } if (check_arg_pathname("of") == NULL) { fprintf(stderr, "%s: missing output filename\n", PROGNAME); exit(SYNTAX_EXIT_CODE); } CatchSignal(SIGINT, dd_handle_signal); CatchSignal(SIGUSR1, dd_handle_signal); return(copy_files(ev, cmdline_lp_ctx)); }
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { unsigned int ctrl; int retval, *ret_data = NULL; struct samu *sampass = NULL; const char *name; void (*oldsig_handler)(int) = NULL; bool found; /* Points to memory managed by the PAM library. Do not free. */ char *p = NULL; /* Samba initialization. */ load_case_tables(); lp_set_in_client(True); ctrl = set_ctrl(pamh, flags, argc, argv); /* Get a few bytes so we can pass our return value to pam_sm_setcred(). */ ret_data = SMB_MALLOC_P(int); /* we need to do this before we call AUTH_RETURN */ /* Getting into places that might use LDAP -- protect the app from a SIGPIPE it's not expecting */ oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN); /* get the username */ retval = pam_get_user( pamh, &name, "Username: "******"auth: could not identify user"); } AUTH_RETURN; } if (on( SMB_DEBUG, ctrl )) { _log_err(pamh, LOG_DEBUG, "username [%s] obtained", name ); } if (geteuid() != 0) { _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root."); retval = PAM_AUTHINFO_UNAVAIL; AUTH_RETURN; } if (!initialize_password_db(True, NULL)) { _log_err(pamh, LOG_ALERT, "Cannot access samba password database" ); retval = PAM_AUTHINFO_UNAVAIL; AUTH_RETURN; } sampass = samu_new( NULL ); if (!sampass) { _log_err(pamh, LOG_ALERT, "Cannot talloc a samu struct" ); retval = nt_status_to_pam(NT_STATUS_NO_MEMORY); AUTH_RETURN; } found = pdb_getsampwnam( sampass, name ); if (on( SMB_MIGRATE, ctrl )) { retval = _smb_add_user(pamh, ctrl, name, sampass, found); TALLOC_FREE(sampass); AUTH_RETURN; } if (!found) { _log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", name); retval = PAM_USER_UNKNOWN; TALLOC_FREE(sampass); sampass = NULL; AUTH_RETURN; } /* if this user does not have a password... */ if (_smb_blankpasswd( ctrl, sampass )) { TALLOC_FREE(sampass); retval = PAM_SUCCESS; AUTH_RETURN; } /* get this user's authentication token */ retval = _smb_read_password(pamh, ctrl, NULL, "Password: "******"auth: no password provided for [%s]", name); TALLOC_FREE(sampass); AUTH_RETURN; } /* verify the password of this user */ retval = _smb_verify_password( pamh, sampass, p, ctrl ); TALLOC_FREE(sampass); p = NULL; AUTH_RETURN; }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ int copies; /* Number of copies */ int port; /* Port number */ char uri[1024], /* URI */ *sep, /* Pointer to separator */ *password; /* Password */ const char *username, /* Username */ *server, /* Server name */ *printer; /* Printer name */ const char *workgroup; /* Workgroup */ FILE *fp; /* File to print */ int status=0; /* Status of LPD job */ struct cli_state *cli; /* SMB interface */ char null_str[1]; int tries = 0; const char *dev_uri; null_str[0] = '\0'; /* we expect the URI in argv[0]. Detect the case where it is in argv[1] and cope */ if (argc > 2 && strncmp(argv[0],"smb://", 6) && !strncmp(argv[1],"smb://", 6)) { argv++; argc--; } if (argc == 1) { /* * NEW! In CUPS 1.1 the backends are run with no arguments to list the * available devices. These can be devices served by this backend * or any other backends (i.e. you can have an SNMP backend that * is only used to enumerate the available network printers... :) */ list_devices(); return (0); } if (argc < 6 || argc > 7) { fprintf(stderr, "Usage: %s [DEVICE_URI] job-id user title copies options [file]\n", argv[0]); fputs(" The DEVICE_URI environment variable can also contain the\n", stderr); fputs(" destination printer:\n", stderr); fputs("\n", stderr); fputs(" smb://[username:password@][workgroup/]server[:port]/printer\n", stderr); return (1); } /* * If we have 7 arguments, print the file named on the command-line. * Otherwise, print data from stdin... */ if (argc == 6) { /* * Print from Copy stdin to a temporary file... */ fp = stdin; copies = 1; } else if ((fp = fopen(argv[6], "rb")) == NULL) { perror("ERROR: Unable to open print file"); return (1); } else copies = atoi(argv[4]); /* * Find the URI... */ dev_uri = getenv("DEVICE_URI"); if (dev_uri) strncpy(uri, dev_uri, sizeof(uri) - 1); else if (strncmp(argv[0], "smb://", 6) == 0) strncpy(uri, argv[0], sizeof(uri) - 1); else { fputs("ERROR: No device URI found in DEVICE_URI environment variable or argv[0] !\n", stderr); return (1); } uri[sizeof(uri) - 1] = '\0'; /* * Extract the destination from the URI... */ if ((sep = strrchr_m(uri, '@')) != NULL) { username = uri + 6; *sep++ = '\0'; server = sep; /* * Extract password as needed... */ if ((password = strchr_m(username, ':')) != NULL) *password++ = '\0'; else password = null_str; } else { username = null_str; password = null_str; server = uri + 6; } if ((sep = strchr_m(server, '/')) == NULL) { fputs("ERROR: Bad URI - need printer name!\n", stderr); return (1); } *sep++ = '\0'; printer = sep; if ((sep = strchr_m(printer, '/')) != NULL) { /* * Convert to smb://[username:password@]workgroup/server/printer... */ *sep++ = '\0'; workgroup = server; server = printer; printer = sep; } else workgroup = NULL; if ((sep = strrchr_m(server, ':')) != NULL) { *sep++ = '\0'; port=atoi(sep); } else port=0; /* * Setup the SAMBA server state... */ setup_logging("smbspool", True); in_client = True; /* Make sure that we tell lp_load we are */ load_case_tables(); if (!lp_load(dyn_CONFIGFILE, True, False, False, True)) { fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); return (1); } if (workgroup == NULL) workgroup = lp_workgroup(); load_interfaces(); do { if ((cli = smb_connect(workgroup, server, port, printer, username, password, argv[2])) == NULL) { if (getenv("CLASS") == NULL) { fprintf(stderr, "ERROR: Unable to connect to CIFS host, will retry in 60 seconds...\n"); sleep (60); /* should just waiting and retrying fix authentication ??? */ tries++; } else { fprintf(stderr, "ERROR: Unable to connect to CIFS host, trying next printer...\n"); return (1); } } } while ((cli == NULL) && (tries < MAX_RETRY_CONNECT)); if (cli == NULL) { fprintf(stderr, "ERROR: Unable to connect to CIFS host after (tried %d times)\n", tries); return (1); } /* * Now that we are connected to the server, ignore SIGTERM so that we * can finish out any page data the driver sends (e.g. to eject the * current page... Only ignore SIGTERM if we are printing data from * stdin (otherwise you can't cancel raw jobs...) */ if (argc < 7) CatchSignal(SIGTERM, SIG_IGN); /* * Queue the job... */ for (i = 0; i < copies; i ++) if ((status = smb_print(cli, argv[3] /* title */, fp)) != 0) break; cli_shutdown(cli); /* * Return the queue status... */ return (status); }