Пример #1
0
/* ======================================================================
Function: clean_exit
Purpose : exit program 
Input 	: exit code
Output	: -
Comments: 
====================================================================== */
void clean_exit (int exit_code)
{
	int r;	
	
	// close serials
  if (g_fd_teleinfo)
  {
		// Restore Old parameters.
  	if (  (r = tcsetattr(g_fd_teleinfo, TCSAFLUSH, &g_oldtermios)) < 0 )
			log_syslog(stderr, "cannot restore old parameters %s: %s", opts.port, strerror(errno));

		// then close
  	tlf_close_serial(g_fd_teleinfo);
  }
	
	 	// close socket
 	if (g_tlf_sock)
 		close(g_tlf_sock);
	
	// Release OLED and Raspberry I/O control
  display.close();

	if ( exit_code == EXIT_SUCCESS)
	{			
			log_syslog(stdout, "Succeded to do my job\n");
	}
	else
	{
			log_syslog(stdout, "Closing teleinfo due to error\n");
	}
	
	exit(exit_code);
}
Пример #2
0
/* ======================================================================
Function: isr_handler
Purpose : Interrupt routine Code for signal
Input 	: -
Output	: -
Comments: 
====================================================================== */
void isr_handler (int signum)
{
	// Does we received CTRL-C ?
	if ( signum==SIGINT || signum==SIGTERM)
	{
		// Indicate we want to quit
		g_exit_pgm = true;
		
		log_syslog(NULL, "Received SIGINT/SIGTERM");
	}
	// Our receive buffer is full
	else if (signum == SIGIO)
	{
		log_syslog(NULL, "Received SIGIO");
	
	}
	
}
Пример #3
0
static void flush_logqueue (void)
{
	int empty;

	do {
		pthread_mutex_lock(&logq_lock);
		empty = log_dequeue(la->buff);
		pthread_mutex_unlock(&logq_lock);
		if (!empty)
			log_syslog(la->buff);
	} while (empty == 0);
}
Пример #4
0
static void
do_log( int priority, const char *format, va_list ap ) {
  assert( started() );

  if ( output & LOGGING_TYPE_FILE ) {
    log_file( priority, format, ap );
  }
  if ( output & LOGGING_TYPE_SYSLOG ) {
    log_syslog( priority, format, ap );
  }
  if ( output & LOGGING_TYPE_STDOUT ) {
    log_stdout( format, ap );
  }
}
Пример #5
0
/* ======================================================================
Function: tlf_init_serial
Purpose : initialize serial port for receiving teleinfo
Input 	: -
Output	: Serial Port Handle
Comments: -
====================================================================== */
int tlf_init_serial(void)
{
	int tty_fd, r ;
	struct termios  termios ;
	
  // Ouverture de la liaison serie (Nouvelle version de config.)
  if ( (tty_fd = open(opts.port, O_RDONLY | O_NOCTTY)) == -1 ) 
  	fatal( "tlf_init_serial %s: %s", opts.port, strerror(errno));
  else
		log_syslog( stdout, "'%s' opened.\n",opts.port);
 
	// Get current parameters.
  if (  (r = tcgetattr(tty_fd, &g_oldtermios)) < 0 )
		log_syslog(stderr, "cannot get current parameters %s: %s",  opts.port, strerror(errno));
		
	// clear struct
	bzero(&termios, sizeof(termios)); 

	// Even Parity with 7 bits data
	termios.c_cflag = (B1200 | PARENB | CS7 | CLOCAL | CREAD) ;
	//termios.c_iflag = IGNPAR ;
	termios.c_iflag =	(IGNPAR | INPCK | ISTRIP) ; ;
	termios.c_oflag = 0;	// Pas de mode de sortie particulier (mode raw).
	termios.c_lflag = 0;	// non canonique
	termios.c_cc[VTIME] = 0;     /* inter-character timer unused */
	termios.c_cc[VMIN]  = 1;     /* blocking read until 1 character arrives */

	tcflush(tty_fd, TCIFLUSH);

  if ( ( r = tcsetattr(tty_fd,TCSANOW,&termios) < 0 ) )
		log_syslog(stderr, "cannot get current parameters %s: %s",  opts.port, strerror(errno));

	// Sleep 500ms
	usleep(500000);

 	return tty_fd ;
}
Пример #6
0
/* ======================================================================
Function: tlf_get_frame
Purpose : check for teleinfo frame broadcasted on the network
Input 	: true if we need to wait for frame, false if async (take if any)
Output	: true if frame ok, else false
Comments: 
====================================================================== */
int tlf_get_frame(char block) 
{
	struct sockaddr_in tlf_from;
	int fromlen = sizeof(tlf_from);
	int n = 0;
	int timeout = 100; // (10 * 100ms)
	int ret  =false;
	char	rcv_buff[TELEINFO_BUFSIZE];

	// clear ou receive  buffer
	memset(rcv_buff,0, TELEINFO_BUFSIZE );

	// do until received or timed out
	while (n<=0 && timeout--)
	{
		// read data received on socket ?
		n = recvfrom(g_tlf_sock,rcv_buff,TELEINFO_BUFSIZE,0, (struct sockaddr *)&tlf_from,(socklen_t *)&fromlen);

		// Do we received frame on socket ?
		if (n > 0) 
		{
			//log_syslog( stderr, "recvfrom %d buffer='%s'\n",n, rcv_buff);
			// check the frame and do stuff
			ret = tlf_check_frame( rcv_buff );
		}
		else 
		{
			// want to wait frame ?
			if ( block)
			{
				// Letting time to the Operating system doing other jobs
				// Wait 100ms it won't bother us
				usleep(100000);
			}
			else
			{
				break;
			}
		}
	}
	
	// check for timed out
	if (block && timeout<=0)
			log_syslog( stderr, "tlf_get_frame() Time-Out Expired\n");
		
	return (ret);
}
Пример #7
0
static void log_flush(void)
{
	while (!la->empty) {
		la->ops[0].sem_op = -1;
		if (semop(la->semid, la->ops, 1) < 0) {
			syslog(LOG_ERR, "semop up failed");
			exit(1);
		}
		log_dequeue(la->buff);
		la->ops[0].sem_op = 1;
		if (semop(la->semid, la->ops, 1) < 0) {
			syslog(LOG_ERR, "semop down failed");
			exit(1);
		}
		log_syslog(la->buff);
	}
}
Пример #8
0
static void log_flush(void)
{
	int msglen;

	while (!la->empty) {
		la->ops[0].sem_op = -1;
		if (semop(la->semid, la->ops, 1) < 0) {
			syslog(LOG_ERR, "semop up failed %d", errno);
			exit(1);
		}
		msglen = log_dequeue(la->buff);
		la->ops[0].sem_op = 1;
		if (semop(la->semid, la->ops, 1) < 0) {
			syslog(LOG_ERR, "semop down failed");
			exit(1);
		}
		if (msglen)
			log_syslog(la->buff);
	}
}
Пример #9
0
int fswc_openlog(fswebcam_config_t *config)
{
	char *s;
	int r;
	
	/* Get the first part of the filename. */
	s = argdup(config->logfile, ":", 0, 0);
	if(!s)
	{
		ERROR("Out of memory.");
		return(-1);
	}
	
	if(!strcasecmp(s, "file"))
	{
		free(s);
		
		s = argdup(config->logfile, ":", 1, 0);
		if(!s)
		{
			ERROR("No log file was specified.");
			return(-1);
		}
	}
	else if(!strcasecmp(s, "syslog"))
	{
		free(s);
		log_syslog(1);
		return(0);
	}
	
	r = log_open(s);
	free(s);
	
	return(r);
}
static void
authenticate (const struct passwd* pw) {
    const struct passwd* lpw = NULL;
    const char* cp, *srvname = NULL;
    int retval;

    switch (su_mode) {
    case SU_MODE:
        srvname = simulate_login ? PAM_SRVNAME_SU_L : PAM_SRVNAME_SU;
        break;
    case RUNUSER_MODE:
        srvname = simulate_login ? PAM_SRVNAME_RUNUSER_L : PAM_SRVNAME_RUNUSER;
        break;
    default:
        abort();
        break;
    }

    retval = pam_start (srvname, pw->pw_name, &conv, &pamh);
    if (is_pam_failure(retval)) {
        goto done;
    }

    if (isatty (0) && (cp = ttyname (0)) != NULL) {
        const char* tty;

        if (strncmp (cp, "/dev/", 5) == 0) {
            tty = cp + 5;
        } else {
            tty = cp;
        }
        retval = pam_set_item (pamh, PAM_TTY, tty);
        if (is_pam_failure(retval)) {
            goto done;
        }
    }

    lpw = current_getpwuid ();
    if (lpw && lpw->pw_name) {
        retval = pam_set_item (pamh, PAM_RUSER, (const void*) lpw->pw_name);
        if (is_pam_failure(retval)) {
            goto done;
        }
    }

    if (su_mode == RUNUSER_MODE) {
        /*
         * This is the only difference between runuser(1) and su(1). The command
         * runuser(1) does not required authentication, because user is root.
         */
        if (restricted) {
            errx(EXIT_FAILURE, _("may not be used by non-root users"));
        }
        return;
    }

    retval = pam_authenticate (pamh, 0);
    if (is_pam_failure(retval)) {
        goto done;
    }

    retval = pam_acct_mgmt (pamh, 0);
    if (retval == PAM_NEW_AUTHTOK_REQD) {
        /* Password has expired.  Offer option to change it.  */
        retval = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
    }

done:

    log_syslog(pw, !is_pam_failure(retval));

    if (is_pam_failure(retval)) {
        const char* msg;

        log_btmp(pw);

        msg  = pam_strerror(pamh, retval);
        pam_end(pamh, retval);
        sleep (getlogindefs_num ("FAIL_DELAY", 1));
        errx (EXIT_FAILURE, "%s", msg ? msg : _("incorrect password"));
    }
}
Пример #11
0
/* ======================================================================
Function: main
Purpose : Main entry Point
Input 	: -
Output	: -
Comments: 
====================================================================== */
int main(int argc, char **argv)
{
	struct sockaddr_in server;
	struct sigaction exit_action;
	int length, flags;
  int n;
	unsigned char c;
	char	rcv_buff[TELEINFO_BUFSIZE];
	int		rcv_idx;
  char time_str[200];
  time_t t;
  struct tm *tmp;
	int frame_ok ;

	rcv_idx = 0;
	g_fd_teleinfo = 0; 
	g_exit_pgm = false;
	
	bzero(rcv_buff, TELEINFO_BUFSIZE);

	parse_args(argc, argv);

	// Set up the structure to specify the exit action.
	exit_action.sa_handler = isr_handler;
	sigemptyset (&exit_action.sa_mask);
	exit_action.sa_flags = 0;
	sigaction (SIGTERM, &exit_action, NULL);
	sigaction (SIGINT, &exit_action, NULL); 

	// Grab teleinfo frame from network
	if (opts.mode == MODE_NET )
	{
		// Init Sockets
		g_tlf_sock=socket(AF_INET, SOCK_DGRAM, 0);
		
		if (g_tlf_sock < 0) 
			fatal( "Error Opening Socket %d: %s\n",g_tlf_sock, strerror (errno));
		else
		{
			if (opts.verbose)
				log_syslog(stderr, "Opened Socket\n");
		}
		
		flags = fcntl(g_tlf_sock,F_GETFL,0);
		fcntl(g_tlf_sock, F_SETFL, flags | O_NONBLOCK);

		length = sizeof(server);
		bzero(&server,length);
		
		server.sin_family=AF_INET;
		server.sin_addr.s_addr=INADDR_ANY;
		server.sin_port=htons(opts.netport);
		
		if ( bind(g_tlf_sock,(struct sockaddr *)&server,length) < 0 ) 
			fatal("Error Binding Socket %d : %s\n", g_tlf_sock, strerror (errno));
		else
		{
			if (opts.verbose)
				log_syslog(stderr, "Binded on port %d\n",opts.netport);
		}

		if (opts.verbose)
			log_syslog(stdout, "Network Init succeded\n");
		
	}

	// Grab teleinfo frame from serial device
	if (opts.mode == MODE_SERIAL)
	{
		if ( (g_fd_teleinfo = tlf_init_serial()) >0 )
		{
			if (opts.verbose)
				log_syslog(stdout, "Serial device %s Init succeded\n", opts.port);
		}
	}
	
	 // SPI
	if (display.oled_is_spi_proto(opts.oled))
	{
		// SPI change parameters to fit to your LCD
		if ( !display.init(OLED_SPI_DC,OLED_SPI_RESET,OLED_SPI_CS, opts.oled) )
			exit(EXIT_FAILURE);
	}
	else
	{
		// I2C change parameters to fit to your LCD
		if ( !display.init(OLED_I2C_RESET,opts.oled) )
			exit(EXIT_FAILURE);
	}

	display.begin();
	display.clearDisplay();
	
	// show 
  display.display(); 

 	log_syslog(stdout, "Inits succeded, entering Main loop\n");
 	
  if (opts.daemon)
  {
	 	log_syslog(stdout, "Starting as a daemon\n");
  	daemonize();
  }
	

	// Do while not end
	while ( ! g_exit_pgm ) 
	{
		// by default no frame
		frame_ok = false;
	
		// Grab from network
		if (opts.mode == MODE_NET )
		{
			// Get frame from network
			frame_ok =  tlf_get_frame(true);
		}
		else
		{
			// loop from serial port until frame ok
			while ( ! frame_ok)
			{
				// Read from serial port
				n = read(g_fd_teleinfo, &c, 1);
			
				if (n == 0)
					fatal("nothing to read");
				else if (errno == EINTR  )
					break;
				else if ( n < 0 )
					fatal("read failed: %s", strerror(errno));

				//log_syslog(stdout, "%c", c);
				//printf("%c",c);

				// What we received ?
				switch (c)
				{
					// start of frame ???
					case  STX:
						// Clear buffer, begin to store in it
						rcv_idx = 0;
						bzero(rcv_buff, TELEINFO_BUFSIZE);
						rcv_buff[rcv_idx++]=c;
					break;
						
					// End of frame ?
					case  ETX:
						// We had STX ?
						if ( rcv_idx )
						{
							// Store in buffer and proceed
							rcv_buff[rcv_idx++]=c;
							
							// clear the end of buffer (paranoia inside)
							bzero(&rcv_buff[rcv_idx], TELEINFO_BUFSIZE-rcv_idx);
							
							// Is this frame valid ?
							if ( (length = tlf_check_frame(rcv_buff)) > 0 )
							{
								frame_ok = true;
							}
						}
						// May be begin of the program or other problem.
						else
						{
							rcv_idx = 0;
							bzero(rcv_buff, TELEINFO_BUFSIZE);
						}
					break;
					
					// other char ?
					default:
					{
						// If we are in a frame, store data recceived
						if (rcv_idx)
						{
							// If buffer is not full
							if ( rcv_idx < TELEINFO_BUFSIZE)
							{
								// Store data recceived
								rcv_buff[rcv_idx++]=c;
							}
							else
							{
								// clear buffer & restart
								rcv_idx=0;
								bzero(rcv_buff, TELEINFO_BUFSIZE);
							}
						}
					}
					break;
				}
			}
		} // while not frame ok from serial
		
		// here we received a frame, even serial or from network
		// If frame  ok
		if ( frame_ok )
		{
			//char oled_buff[1024];
			int percent=0;
			
			t = time(NULL);
			tmp = localtime(&t);
			if (tmp) 
			{
				if (strftime(time_str, sizeof(time_str), "%d %b %Y %T" , tmp) == 0) 
					strcpy( time_str, "No Time");
			}

			// good full frame received, do whatever you want here
			//fprintf(stdout, "==========================\nTeleinfo Frame of %d char\n%s\n==========================%s\n",
			//								strlen(rcv_buff), time_str, rcv_buff );

			//sprintf( oled_buff, "Creuses %09lu\nPleines %09lu\n%d W   %d \n%s\n",
			//					g_values.hchp, g_values.hchc, g_values.papp, (100*g_values.iinst)/g_values.isousc, time_str);
			//fprintf(stdout, oled_buff);
			
			display.clearDisplay();   // clears the screen and buffer	display.setTextSize(1);
			display.setTextColor(WHITE);
			display.setCursor(0,0);

			// Percent of total power 
			percent = (100.0 * g_values.iinst) / g_values.isousc ;

			
			if (display.height() == 32 )
			{
				if (g_values.ptec == PTEC_HP )
					display.setTextColor(BLACK, WHITE); // 'inverted' text
			
				display.print("Pleines ");
				display.printf("%09ld\n", g_values.hchp);
				display.setTextColor(WHITE); // normaltext
				
				if (g_values.ptec == PTEC_HC )
					display.setTextColor(BLACK, WHITE); // 'inverted' text
					
				display.print("Creuses ");
				display.printf("%09ld\n", g_values.hchc);
				display.setTextColor(WHITE); // normaltext

				// Calculate Bargraph display
				
				//display.setTextColor(BLACK, WHITE); // 'inverted' text
				//skip seconds
				time_str[17] = 0x00;
				display.printf("%d W %d%%  %3d A\n%s", g_values.papp, percent, g_values.iinst, time_str);
				display.drawVerticalBargraph(114,0,12,32,1, percent);
				display.display();
				display.setTextColor(BLACK, WHITE); // 'inverted' text
			}
			else
			{
				if (g_values.ptec == PTEC_HP )
					display.setTextColor(BLACK, WHITE); // 'inverted' text
			
				display.setTextSize(2); 

				display.printf("%09ld\n", g_values.hchp);
				display.setTextColor(WHITE); // normaltext
				
				if (g_values.ptec == PTEC_HC )
					display.setTextColor(BLACK, WHITE); // 'inverted' text
					
				display.printf("%09ld\n", g_values.hchc);
				display.setTextColor(WHITE); // normaltext

				
				//display.setTextColor(BLACK, WHITE); // 'inverted' text
				display.setTextSize(1); 
				display.printf("%d W %d%%  %3d A\n", g_values.papp, percent, g_values.iinst);
				display.printf("%s", time_str);

				// Calculate Bargraph display
				// Percent of total power 
				display.drawHorizontalBargraph(0, 49,128,14,1, percent);

				display.display();
				display.setTextColor(BLACK, WHITE); // 'inverted' text
			}

		}

		// We want to display results ?
		if (opts.verbose)
		{
			if ( (n = write(STDOUT_FILENO, &c, 1)) <= 0 )
				fatal("write to stdout failed: %s", strerror(errno));
		}
	}
	

  log_syslog(stderr, "Program terminated\n");
  
  clean_exit(EXIT_SUCCESS);
  
  // avoid compiler warning
  return (0);
}
Пример #12
0
/* ======================================================================
Function: tlf_check_frame
Purpose : check for teleinfo frame
Input 	: -
Output	: the length of valid buffer, 0 otherwhile
Comments: 
====================================================================== */
int tlf_check_frame( char * pframe) 
{
	char * pstart; 
	char * pend; 
	char * pnext; 
	char * ptok; 
	char * pvalue; 
	char * pcheck;
	char	buff[TELEINFO_BUFSIZE];
	int frame_err , len;

	len = strlen(pframe); 
	
	strncpy( buff, pframe, len+1);

	pstart = &buff[0];
	pend   = pstart + len;

	if (opts.verbose)
	{
		fprintf(stdout, "------------------- Received %d char %s Frame.%s\n-------------------", len, opts.mode_str, buff);
		fflush(stdout);
	}	
	
	// just one vefification, buffer should be at least 100 Char
	if ( pstart && pend && (pend > pstart+100 ) )
	{
		//fprintf(stdout, "Frame to analyse [%d]%s\n", pend-pstart, pstart);
		//fflush(stdout);	

		// by default no error
		frame_err = false;
		
		//log_syslog(stderr, "Found %d Bytes Frame\n", pend-pstart);

		// ignore STX
		pstart++;

		// Init our pointers
		ptok = pvalue = pnext = pcheck = NULL;
		

		// Loop in buffer	
		while ( pstart < pend )
		{
			// start of token
			if ( *pstart=='\n' )
			{		
				// Position on token				
				ptok = ++pstart;
			}						

			// start of token value
			if ( *pstart==' ' && ptok)
			{						
				// Isolate token name
				*pstart++ = '\0';

				// no value yet, setit ?
				if (!pvalue)
					pvalue = pstart;
				// we had value, so it's checksum
				else
					pcheck = pstart;
			}						

			// new line ? ok we got all we need ?
			if ( *pstart=='\r' )
			{						
				
				*pstart='\0';

				// Good format ?
				if ( ptok && pvalue && pcheck )
				{
					// Checksum OK
					if ( tlf_checksum_ok(ptok, pvalue, *pcheck))
					{
						//fprintf(stdout, "%s=%s\n",ptok, pvalue);
						
						// In case we need to do things
						tlf_treat_label(ptok, pvalue);
					}
					else
					{
						frame_err = true;
						//fprintf(stdout, "%s=%s BAD",ptok, pvalue);
						log_syslog(stderr, "tlf_checksum_ok('%s','%s','%c') error\n",ptok, pvalue, *pcheck);
						
					}
				}
				else
				{
					frame_err = true;
					log_syslog(stderr, "tlf_check_frame() no correct frame '%s'\n",ptok);
				}
				
				// reset data
				ptok = pvalue = pnext = pcheck = NULL;

			}						
			
			// next
			pstart++;
	
		}

		// no error in this frame ?
		if (!frame_err)
		{
			if (opts.verbose)
				fprintf(stdout, "Frame OK (%d)\n", len);

			//debug_dump_sensors(0);
			return (len);
		}
	}	
	else
	{
		log_syslog(stderr, "tlf_check_frame() No correct frame found\n");
	}

	return (0);

}
Пример #13
0
int main(int argc, char **argv)
{
	int c;
	int cnt;
	char *childArgv[10];
	char *buff;
	int childArgc = 0;
	int retcode;

	char *pwdbuf = NULL;
	struct passwd *pwd = NULL, _pwd;

	struct login_context cxt = {
		.tty_mode = TTY_MODE,		/* tty chmod() */
		.pid = getpid(),		/* PID */
		.conv = { misc_conv, NULL }	/* PAM conversation function */
	};

	timeout = getlogindefs_num("LOGIN_TIMEOUT", LOGIN_TIMEOUT);

	signal(SIGALRM, timedout);
	siginterrupt(SIGALRM, 1);	/* we have to interrupt syscalls like ioclt() */
	alarm((unsigned int)timeout);
	signal(SIGQUIT, SIG_IGN);
	signal(SIGINT, SIG_IGN);

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	setpriority(PRIO_PROCESS, 0, 0);
	initproctitle(argc, argv);

	/*
	 * -p is used by getty to tell login not to destroy the environment
	 * -f is used to skip a second login authentication
	 * -h is used by other servers to pass the name of the remote
	 *    host to login so that it may be placed in utmp and wtmp
	 */
	while ((c = getopt(argc, argv, "fHh:pV")) != -1)
		switch (c) {
		case 'f':
			cxt.noauth = 1;
			break;

		case 'H':
			cxt.nohost = 1;
			break;

		case 'h':
			if (getuid()) {
				fprintf(stderr,
					_("login: -h for super-user only.\n"));
				exit(EXIT_FAILURE);
			}
			init_remote_info(&cxt, optarg);
			break;

		case 'p':
			cxt.keep_env = 1;
			break;

		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case '?':
		default:
			fprintf(stderr, _("usage: login [ -p ] [ -h host ] [ -H ] [ -f username | username ]\n"));
			exit(EXIT_FAILURE);
		}
	argc -= optind;
	argv += optind;

	if (*argv) {
		char *p = *argv;
		cxt.username = xstrdup(p);

		/* wipe name - some people mistype their password here */
		/* (of course we are too late, but perhaps this helps a little ..) */
		while (*p)
			*p++ = ' ';
	}

	for (cnt = get_fd_tabsize() - 1; cnt > 2; cnt--)
		close(cnt);

	setpgrp();	 /* set pgid to pid this means that setsid() will fail */

	openlog("login", LOG_ODELAY, LOG_AUTHPRIV);

	init_tty(&cxt);
	init_loginpam(&cxt);

	/* login -f, then the user has already been authenticated */
	cxt.noauth = cxt.noauth && getuid() == 0 ? 1 : 0;

	if (!cxt.noauth)
		loginpam_auth(&cxt);

	/*
	 * Authentication may be skipped (for example, during krlogin, rlogin,
	 * etc...), but it doesn't mean that we can skip other account checks.
	 * The account could be disabled or password expired (althought
	 * kerberos ticket is valid).         -- [email protected] (22-Feb-2006)
	 */
	loginpam_acct(&cxt);

	if (!(cxt.pwd = get_passwd_entry(cxt.username, &pwdbuf, &_pwd))) {
		warnx(_("\nSession setup problem, abort."));
		syslog(LOG_ERR, _("Invalid user name \"%s\" in %s:%d. Abort."),
		       cxt.username, __FUNCTION__, __LINE__);
		pam_end(cxt.pamh, PAM_SYSTEM_ERR);
		sleepexit(EXIT_FAILURE);
	}

	pwd = cxt.pwd;
	cxt.username = pwd->pw_name;

	/*
	 * Initialize the supplementary group list. This should be done before
	 * pam_setcred because the PAM modules might add groups during
	 * pam_setcred.
	 *
         * For root we don't call initgroups, instead we call setgroups with
	 * group 0. This avoids the need to step through the whole group file,
	 * which can cause problems if NIS, NIS+, LDAP or something similar
	 * is used and the machine has network problems.
	 */
	retcode = pwd->pw_uid ? initgroups(cxt.username, pwd->pw_gid) :	/* user */
			        setgroups(0, NULL);			/* root */
	if (retcode < 0) {
		syslog(LOG_ERR, _("groups initialization failed: %m"));
		warnx(_("\nSession setup problem, abort."));
		pam_end(cxt.pamh, PAM_SYSTEM_ERR);
		sleepexit(EXIT_FAILURE);
	}

	/*
	 * Open PAM session (after successful authentication and account check)
	 */
	loginpam_session(&cxt);

	/* committed to login -- turn off timeout */
	alarm((unsigned int)0);

	endpwent();

	cxt.quiet = get_hushlogin_status(pwd);

	log_utmp(&cxt);
	log_audit(&cxt, 1);
	log_lastlog(&cxt);

	chown_tty(&cxt);

	if (setgid(pwd->pw_gid) < 0 && pwd->pw_gid) {
		syslog(LOG_ALERT, _("setgid() failed"));
		exit(EXIT_FAILURE);
	}

	if (pwd->pw_shell == NULL || *pwd->pw_shell == '\0')
		pwd->pw_shell = _PATH_BSHELL;

	init_environ(&cxt);		/* init $HOME, $TERM ... */

	setproctitle("login", cxt.username);

	log_syslog(&cxt);

	if (!cxt.quiet) {
		motd();

#ifdef LOGIN_STAT_MAIL
		/*
		 * This turns out to be a bad idea: when the mail spool
		 * is NFS mounted, and the NFS connection hangs, the
		 * login hangs, even root cannot login.
		 * Checking for mail should be done from the shell.
		 */
		{
			struct stat st;
			char *mail;

			mail = getenv("MAIL");
			if (mail && stat(mail, &st) == 0 && st.st_size != 0) {
				if (st.st_mtime > st.st_atime)
					printf(_("You have new mail.\n"));
				else
					printf(_("You have mail.\n"));
			}
		}
#endif
	}

	/*
	 * Detach the controlling terminal, fork() and create, new session
	 * and reinilizalize syslog stuff.
	 */
	fork_session(&cxt);

	/* discard permissions last so can't get killed and drop core */
	if (setuid(pwd->pw_uid) < 0 && pwd->pw_uid) {
		syslog(LOG_ALERT, _("setuid() failed"));
		exit(EXIT_FAILURE);
	}

	/* wait until here to change directory! */
	if (chdir(pwd->pw_dir) < 0) {
		warn(_("%s: change directory failed"), pwd->pw_dir);

		if (!getlogindefs_bool("DEFAULT_HOME", 1))
			exit(0);
		if (chdir("/"))
			exit(EXIT_FAILURE);
		pwd->pw_dir = "/";
		printf(_("Logging in with home = \"/\".\n"));
	}

	/* if the shell field has a space: treat it like a shell script */
	if (strchr(pwd->pw_shell, ' ')) {
		buff = xmalloc(strlen(pwd->pw_shell) + 6);

		strcpy(buff, "exec ");
		strcat(buff, pwd->pw_shell);
		childArgv[childArgc++] = "/bin/sh";
		childArgv[childArgc++] = "-sh";
		childArgv[childArgc++] = "-c";
		childArgv[childArgc++] = buff;
	} else {
		char tbuf[PATH_MAX + 2], *p;

		tbuf[0] = '-';
		xstrncpy(tbuf + 1, ((p = strrchr(pwd->pw_shell, '/')) ?
				    p + 1 : pwd->pw_shell), sizeof(tbuf) - 1);

		childArgv[childArgc++] = pwd->pw_shell;
		childArgv[childArgc++] = xstrdup(tbuf);
	}

	childArgv[childArgc++] = NULL;

	execvp(childArgv[0], childArgv + 1);

	if (!strcmp(childArgv[0], "/bin/sh"))
		warn(_("couldn't exec shell script"));
	else
		warn(_("no shell"));

	exit(EXIT_SUCCESS);
}
Пример #14
0
int main(int argc, char **argv) {
    int conf_err = 0;
    int option;
    int dflag = 0;
    conf_ruleset_s rset;

    // Set the default logger to syslog
    log_syslog(&logger);

    // Initialize the config and its rulesets
    conf_init(&conf);
    conf_rset_init(&rset);

    // Set the real path
    conf_set_realpath(&conf, argv[0]);

    conf_rset_add(&rset, conf_rule_create("root = %s", &conf.document_root));
    conf_rset_add(&rset, conf_rule_create("handler = %s", &conf.method));
    conf_rset_add(&rset, conf_rule_create("port = %hu", &conf.port));
    conf_rset_add(&rset, conf_rule_create("backlog = %d", &conf.backlog));
    conf_rset_add(&rset, conf_rule_create("mime = %s", &conf.mime));
    conf_rset_add(&rset, conf_rule_create("logfile = %s", &conf.logfile));

    if (conf_read(conf.real_path, ".lab3-config", rset) == -1)
        exit_fatal("The configuration file could not be read");

    while((option = getopt(argc, argv, "hp:dl:s:")) != -1) {
        switch(option) {
            case 'p': conf_set_port(&conf, optarg); break;
            case 'd': dflag = 1; break;
            case 'l':
                conf_set_logfile(&conf, optarg);

                if (strncmp(optarg, "stdout", 6) == 0)
                    log_stdout(&logger);
                else
                    log_file(&logger);
                break;
            case 's': conf_set_method(&conf, optarg); break;
            case 'h': default: usage(argv[0]); exit(EXIT_SUCCESS);
        }
    }

    // Register signal handler for SIGINT
    signal(SIGINT, sigint_handler);

    if ((conf_err = conf_validate(conf)) < 0)
        conf_print_err(conf_err);

    // Daemonize the process if the dflag is set
    if (dflag) {
        log_syslog(&logger);
        daemonize();
    } else {
        jail_proc(dflag);
    }

    server_create();

    return 0;
}
Пример #15
0
/* main -- dnsproxy main function
 */
int
main(int argc, char *argv[])
{
    int ch;
    struct passwd *pw = NULL;
    struct sockaddr_in addr;
    struct event evq, eva;
    const char *config = "/etc/dnsproxy.conf";
    int daemonize = 0;

    /* Process commandline arguments */
    while ((ch = getopt(argc, argv, "c:dhV")) != -1) {
        switch (ch) {
        case 'c':
            config = optarg;
            break;
        case 'd':
            daemonize = 1;
            break;
        case 'V':
            fprintf(stderr, PACKAGE_STRING "\n");
            exit(0);
        /* FALLTHROUGH */
        case 'h':
        default:
            fprintf(stderr,
            "usage: dnsproxy [-c file] [-dhV]\n"        \
            "\t-c file  Read configuration from file\n" \
            "\t-d       Detach and run as a daemon\n"   \
            "\t-h       This help text\n"           \
            "\t-V       Show version information\n");
            exit(1);
        }
    }

    /* Parse configuration and check required parameters */
    if (!parse(config))
        fatal("unable to parse configuration");

    if (!authoritative || !recursive)
        fatal("No authoritative or recursive server defined");

    if (!listenat)
        listenat = strdup("0.0.0.0");

    /* Create and bind query socket */
    if ((sock_query = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        fatal("unable to create socket: %s", strerror(errno));

    memset(&addr, 0, sizeof(struct sockaddr_in));
    addr.sin_addr.s_addr = inet_addr(listenat);
    addr.sin_port = htons(port);
    addr.sin_family = AF_INET;

    if (bind(sock_query, (struct sockaddr *)&addr, sizeof(addr)) != 0)
        fatal("unable to bind socket: %s", strerror(errno));

    /* Create and bind answer socket */
    if ((sock_answer = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        fatal("unable to create socket: %s", strerror(errno));

    memset(&addr, 0, sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET;

    if (bind(sock_answer, (struct sockaddr *)&addr, sizeof(addr)) != 0)
        fatal("unable to bind socket: %s", strerror(errno));

    /* Fill sockaddr_in structs for both servers */
    memset(&authoritative_addr, 0, sizeof(struct sockaddr_in));
    authoritative_addr.sin_addr.s_addr = inet_addr(authoritative);
    authoritative_addr.sin_port = htons(authoritative_port);
    authoritative_addr.sin_family = AF_INET;

    memset(&recursive_addr, 0, sizeof(struct sockaddr_in));
    recursive_addr.sin_addr.s_addr = inet_addr(recursive);
    recursive_addr.sin_port = htons(recursive_port);
    recursive_addr.sin_family = AF_INET;

    /* Daemonize if requested and switch to syslog */
    if (daemonize) {
        if (daemon(0, 0) == -1)
            fatal("unable to daemonize");
        log_syslog("dnsproxy");
    }

    /* Find less privileged user */
    if (user) {
        pw = getpwnam(user);
        if (!pw)
            fatal("unable to find user %s", user);
    }

    /* Do a chroot if requested */
    if (chrootdir) {
        if (chdir(chrootdir) || chroot(chrootdir))
            fatal("unable to chroot to %s", chrootdir);
        chdir("/");
    }

    /* Drop privileges */
    if (user) {
        if (setgroups(1, &pw->pw_gid) < 0)
            fatal("setgroups: %s", strerror(errno));
#if defined(HAVE_SETRESGID)
        if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0)
            fatal("setresgid: %s", strerror(errno));
#elif defined(HAVE_SETREGID)
        if (setregid(pw->pw_gid, pw->pw_gid) < 0)
            fatal("setregid: %s", strerror(errno));
#else
        if (setegid(pw->pw_gid) < 0)
            fatal("setegid: %s", strerror(errno));
        if (setgid(pw->pw_gid) < 0)
            fatal("setgid: %s", strerror(errno));
#endif
#if defined(HAVE_SETRESUID)
        if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0)
            fatal("setresuid: %s", strerror(errno));
#elif defined(HAVE_SETREUID)
        if (setreuid(pw->pw_uid, pw->pw_uid) < 0)
            fatal("setreuid: %s", strerror(errno));
#else
        if (seteuid(pw->pw_uid) < 0)
            fatal("seteuid: %s", strerror(errno));
        if (setuid(pw->pw_uid) < 0)
            fatal("setuid: %s", strerror(errno));
#endif
    }

    /* Init event handling */
    event_init();

    event_set(&evq, sock_query, EV_READ, do_query, &evq);
    event_add(&evq, NULL);

    event_set(&eva, sock_answer, EV_READ, do_answer, &eva);
    event_add(&eva, NULL);

    /* Zero counters and start statistics timer */
    statistics_start();

    /* Take care of signals */
    if (signal(SIGINT, signal_handler) == SIG_ERR)
        fatal("unable to mask signal SIGINT: %s", strerror(errno));

    if (signal(SIGTERM, signal_handler) == SIG_ERR)
        fatal("unable to mask signal SIGTERM: %s", strerror(errno));

    if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
        fatal("unable to mask signal SIGHUP: %s", strerror(errno));

    event_sigcb = signal_event;

    /* Start libevent main loop */
    event_dispatch();

    return 0;

}