예제 #1
0
int create_socket_connect_verify(uint16_t server_port, uint16_t max_clients, char* module_name, int setupdone, int *connection_id)
{
    int connectSocket;

    mysyslog(LOG_INFO, "Waiting connections on %d..\n", server_port);

    if((connectSocket = create_socket_and_listen(server_port, setupdone)) < 0)
    {
         mysyslog(LOG_ERR, "Cannot create socket to listen.\n");
         return ERROR;
    }

    if(verify_max_clients(max_clients, connectSocket, module_name) != OK)
    {
         mysyslog(LOG_ERR, "verify_max_clients returned not OK.\n");
         return ERROR;
    }

    if((*connection_id = get_new_port(connectSocket, used_ports)) == NO_FREE_CONN)
    {
         mysyslog(LOG_ERR, "get_new_port returned NO_FREE_CONN\n");
         return ERROR;
    }

    return connectSocket;
}
예제 #2
0
파일: pam_cgm.c 프로젝트: hallyn/pam-cgm
int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
		const char **argv)
{
	const char *PAM_user = NULL;
	int ret;

	if (!cgm_dbus_connect()) {
		mysyslog(LOG_ERR, "Failed to connect to cgmanager\n");
		return PAM_SESSION_ERR;
	}
	if (argc > 1 && strcmp(argv[0], "-c") == 0)
		ctrl_list = validate_and_dup(argv[1]);
	if (!ctrl_list) 
		get_active_controllers();
	cgm_escape();

	ret = pam_get_user(pamh, &PAM_user, NULL);
	if (ret != PAM_SUCCESS) {
		cgm_dbus_disconnect();
		mysyslog(LOG_ERR, "PAM-CGM: couldn't get user\n");
		return PAM_SESSION_ERR;
	}

	ret = handle_login(PAM_user);
	cgm_dbus_disconnect();
	return ret;
}
예제 #3
0
int release_dead_connection_entry(int child_pid, struct used_port *ports)
{
 	int i;

    if(child_pid <= 0)
    {
         mysyslog(LOG_INFO, "child_pid cannot be less or equal zero in module %s. Please investigate this issue.\n", ext_module_name);
         return -1;
    }

    if(ports == NULL)
    {
         mysyslog(LOG_INFO, "Used_port struct null in module %s. Please investigate this issue.\n", ext_module_name);
         return -1;
    }

    for(i=0; i<ext_max_clients; i++)
	{
		if(ports[i].childpid == child_pid)
		{
			ports[i].childpid = 0;
			ports[i].ports = 0;
			total_clients--;
			mysyslog(LOG_INFO, "Released %s connection number %d\n", ext_module_name, i);
			return 0;
		}
	}
	return -1;
}
예제 #4
0
/** \brief create_socket_and_listen(int server_port, struct sockaddr_in * clientAddress, int *mysocket )
           function is used to create and wait for connections of stations wishing to communicate
           with this controller.
 *
 * \param server_port int used to indicate to wich port it should listen for connections.
 * \param clientAddress struct sockaddr_in* structure needed to create the listen socket.
 * \param mysocket int* variable to return the listening socket because it's used in other functions.
 * \return int returns a connectSocket when a stations connects to it.
 *
 */
int create_socket_and_listen(int server_port, int setupdone )
{
    int connectSocket, err;
    static int mysocket;
    static struct sockaddr_in serverAddress;
    static socklen_t clientAddressLength;
    struct sockaddr_in clientAddress;
    int yes;

    if(setupdone == 0)  /* do it only the first time. */
    {
        mysocket = socket(AF_INET, SOCK_STREAM, 0);
        if (mysocket < 0)
            return -1;

        serverAddress.sin_family = AF_INET;
        serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
        serverAddress.sin_port = htons(server_port);

        yes=1;

        if (setsockopt(mysocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
        {
            perror("setsockopt");
            return -1;
        }

        if ((err = bind(mysocket,(struct sockaddr *) &serverAddress,sizeof(serverAddress))) < 0)
        {
            mysyslog(LOG_ERR, "cannot bind socket %s\n", strerror(-err));
            return -1;
        }

        if ( listen(mysocket, 10) != 0 )
        {
            perror("Can't configure listening port");
            return -1;
        }

        mysyslog(LOG_INFO, "Socket created!\nWaiting for a TCP connection\n");

        clientAddressLength = sizeof(clientAddress);
    }


    connectSocket = accept(mysocket, (struct sockaddr *) &clientAddress, &clientAddressLength);  /* accept connection as usual */
    mysyslog("Connection: %s:%d\n",inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port));

	if (connectSocket < 0)
	{
	    mysyslog(LOG_ERR, "cannot accept connection \n");
	    return -1;
	}

	mysyslog(LOG_INFO, "Connection accepted\n");

    return connectSocket;

}
예제 #5
0
파일: logging.c 프로젝트: radosroka/sudo
/*
 * Log a message to syslog, pre-pending the username and splitting the
 * message into parts if it is longer than syslog_maxlen.
 */
static void
do_syslog(int pri, char *msg)
{
    size_t len, maxlen;
    char *p, *tmp, save;
    const char *fmt;
    int oldlocale;
    debug_decl(do_syslog, SUDOERS_DEBUG_LOGGING)

    /* A priority of -1 corresponds to "none". */
    if (pri == -1)
	debug_return;

    sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);

    /*
     * Log the full line, breaking into multiple syslog(3) calls if necessary
     */
    fmt = _("%8s : %s");
    maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(user_name));
    for (p = msg; *p != '\0'; ) {
	len = strlen(p);
	if (len > maxlen) {
	    /*
	     * Break up the line into what will fit on one syslog(3) line
	     * Try to avoid breaking words into several lines if possible.
	     */
	    tmp = memrchr(p, ' ', maxlen);
	    if (tmp == NULL)
		tmp = p + maxlen;

	    /* NULL terminate line, but save the char to restore later */
	    save = *tmp;
	    *tmp = '\0';

	    mysyslog(pri, fmt, user_name, p);

	    *tmp = save;			/* restore saved character */

	    /* Advance p and eliminate leading whitespace */
	    for (p = tmp; *p == ' '; p++)
		continue;
	} else {
	    mysyslog(pri, fmt, user_name, p);
	    p += len;
	}
	fmt = _("%8s : (command continued) %s");
	maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(user_name));
    }

    sudoers_setlocale(oldlocale, NULL);

    debug_return;
}
예제 #6
0
/** \brief child_terminated() function is connected via a signal to the termination of a child process.
 *        The function releases the connection in the master connection's table kept by the parent.
 * \param None
 * \return None
 *
 */
void child_terminated(void)
{
	pid_t child_pid;
	int status;

	child_pid = wait(&status);
	mysyslog(LOG_INFO, "Child exited with PID=%d\n", child_pid);
	if(release_dead_connection_entry(child_pid, used_ports) != 0)
        mysyslog(LOG_INFO, "Tried to release connection in module %s with child_pid %d but was not found on the table\n", ext_module_name, child_pid);

	return;
}
예제 #7
0
파일: logging.c 프로젝트: CVi/sudo
/*
 * Log a message to syslog, pre-pending the username and splitting the
 * message into parts if it is longer than MAXSYSLOGLEN.
 */
static void
do_syslog(int pri, char *msg)
{
    size_t len, maxlen;
    char *p, *tmp, save;
    const char *fmt;

#ifdef HAVE_SETLOCALE
    const char *old_locale = estrdup(setlocale(LC_ALL, NULL));
    if (!setlocale(LC_ALL, def_sudoers_locale))
	setlocale(LC_ALL, "C");
#endif /* HAVE_SETLOCALE */

    /*
     * Log the full line, breaking into multiple syslog(3) calls if necessary
     */
    fmt = _(FMT_FIRST);
    maxlen = MAXSYSLOGLEN - (strlen(fmt) - 5 + strlen(user_name));
    for (p = msg; *p != '\0'; ) {
	len = strlen(p);
	if (len > maxlen) {
	    /*
	     * Break up the line into what will fit on one syslog(3) line
	     * Try to avoid breaking words into several lines if possible.
	     */
	    tmp = memrchr(p, ' ', maxlen);
	    if (tmp == NULL)
		tmp = p + maxlen;

	    /* NULL terminate line, but save the char to restore later */
	    save = *tmp;
	    *tmp = '\0';

	    mysyslog(pri, fmt, user_name, p);

	    *tmp = save;			/* restore saved character */

	    /* Advance p and eliminate leading whitespace */
	    for (p = tmp; *p == ' '; p++)
		;
	} else {
	    mysyslog(pri, fmt, user_name, p);
	    p += len;
	}
	fmt = _(FMT_CONTD);
	maxlen = MAXSYSLOGLEN - (strlen(fmt) - 5 + strlen(user_name));
    }

#ifdef HAVE_SETLOCALE
    setlocale(LC_ALL, old_locale);
    efree((void *)old_locale);
#endif /* HAVE_SETLOCALE */
}
예제 #8
0
int closeconnection(int connectSocket, SSL* ssl, SSL_CTX* ctx, char *module_name)
{
    if (module_name == NULL)
    {
        mysyslog(LOG_ERR, "Argunments to closeconnection are null\n");
    }
    else
        mysyslog(LOG_INFO, "Quiting %s ethernet command parser\n", module_name);

    shutdown(connectSocket,SHUT_RDWR);
    close(connectSocket);
    SSL_free(ssl);         /* release SSL state */
    SSL_CTX_free(ctx);     /* release SSL context */
    return 0;

}
예제 #9
0
static void
bye (int signum)
{
#ifdef TCSETS
  (void) ioctl (0, TCSETS, &termorig);
#endif

  if (seteuid(orig_euid) != 0)
    {
      perror ("Reacquiring uid 0 failed");
      bye (EXIT_FAILURE);
    }
  set_perms_and_close_file(&timing);
  set_perms_and_close_file(&script);
#ifdef RECORDINPUT
  set_perms_and_close_file(&input);
#endif
  if (setuid(getuid()) != 0)
    {
      perror ("Dropping setuid 0 failed");
      bye (EXIT_FAILURE);
    }

  if (sudosh_option.priority != -1)
    mysyslog (sudosh_option.priority,
	      "stopping session for %s as %s, tty %s, shell %s", user.from,
	      user.to, ttyname (0), user.shell.ptr);
  exit (signum);
}
예제 #10
0
int get_priority(const u_char *new_priority) {
	int pri = PRIORITY;

	if (!strncasecmp(new_priority, "log_", 4))
		new_priority += 4;

	if (!strcasecmp(new_priority, "alert"))
		pri = LOG_ALERT;
	else if (!strcasecmp(new_priority, "crit"))
		pri = LOG_CRIT;
	else if (!strcasecmp(new_priority, "debug"))
		pri = LOG_DEBUG;
	else if (!strcasecmp(new_priority, "emerg"))
		pri = LOG_EMERG;
	else if (!strcasecmp(new_priority, "err"))
		pri = LOG_ERR;
	else if (!strcasecmp(new_priority, "error"))
		pri = LOG_ERR;
	else if (!strcasecmp(new_priority, "info"))
		pri = LOG_INFO;
	else if (!strcasecmp(new_priority, "notice"))
		pri = LOG_NOTICE;
	else if (!strcasecmp(new_priority, "panic"))
		pri = LOG_EMERG;
	else if (!strcasecmp(new_priority, "warn"))
		pri = LOG_WARNING;
	else if (!strcasecmp(new_priority, "warning"))
		pri = LOG_WARNING;
	else
		mysyslog("Invalid priority: \"%s\" - falling back to default.",
				new_priority);

	return (pri);
}
예제 #11
0
int statcom_main(uint16_t server_port, uint16_t max_clients, char* module_name, int (*call_command_handler_function) (SSL *, int))
{
	int 	    setupdone=0, connection_id, connectSocket;
	pid_t 	    pid;

    /*SSL specific.*/
    SSL *ssl;
	SSL_CTX *ctx;

	total_clients = 0;
	ctx = initialize_SSL(server_port, max_clients, module_name);

	while(1) /*while loop to serve many connections. When one connection arrives, a new process is forked to handle it.*/
	{         /*and the parent process comes here again to continue listening.*/
        if((connectSocket = create_socket_connect_verify(server_port, max_clients, module_name, setupdone, &connection_id)) == ERROR)
            goto error;

        switch(pid = fork()) /* here a new child process is created and the parent continues.*/
        {
            case -1:/*something went wrong..*/
                mysyslog(LOG_ERR, "Error in forking a new %s connection.\nAborting.....\n", module_name);
                break;

            case  0:/*child process*/
                signal(SIGCHLD,SIG_IGN); /* to keep track of when a child is terminated.*/
                signal(SIGCLD,SIG_IGN); /* to keep track of when a child is terminated.*/

                if((ssl = do_ssl_handshake(ctx, connectSocket)) != NULL) /* if OK call function to handle engstation comms.*/
                    call_command_handler_function(ssl, connection_id); /* this function don't return until the station ends the connection.*/

                closeconnection(connectSocket, ssl, ctx, module_name); /* we're done handling this connection, the client will exit now.*/
                exit(0);	/*when finished handling comms, we kill the child.*/
                break;

            default: /*parent process go on. The parent goes back to the begining of the while loop to continue listening.*/
                      /*the child handles the new connection.*/
                setupdone = 1;
                mysyslog(LOG_INFO, "Parent saving PID=%d of child in slot=%d\n", pid,connection_id );
                used_ports[connection_id].childpid = pid; /*save the PID of the child in the used_port table.*/
                break;
        }
error: ; /*an empty statmenent is needed by the compiler.*/
    }

	return 0; 	/*we should never reach here !*/
}
예제 #12
0
int get_facility(const u_char *new_facility) {
	int fac = FACILITY;

	if (!strncasecmp(new_facility, "log_", 4))
		new_facility += 4;

	if (!strcasecmp(new_facility, "auth"))
		fac = LOG_AUTH;
#ifdef LOG_AUTHPRIV
	else if (!strcasecmp(new_facility, "authpriv"))
		fac = LOG_AUTHPRIV;
#endif
	else if (!strcasecmp(new_facility, "cron"))
		fac = LOG_CRON;
	else if (!strcasecmp(new_facility, "daemon"))
		fac = LOG_DAEMON;
#ifdef LOG_FTP
	else if (!strcasecmp(new_facility, "ftp"))
		fac = LOG_FTP;
#endif
	else if (!strcasecmp(new_facility, "kern"))
		fac = LOG_KERN;
	else if (!strcasecmp(new_facility, "lpr"))
		fac = LOG_LPR;
	else if (!strcasecmp(new_facility, "mail"))
		fac = LOG_MAIL;
	else if (!strcasecmp(new_facility, "news"))
		fac = LOG_NEWS;
	else if (!strcasecmp(new_facility, "security"))
		fac = LOG_AUTH;
	else if (!strcasecmp(new_facility, "syslog"))
		fac = LOG_SYSLOG;
	else if (!strcasecmp(new_facility, "user"))
		fac = LOG_USER;
	else if (!strcasecmp(new_facility, "uucp"))
		fac = LOG_UUCP;
	else if (!strcasecmp(new_facility, "local0"))
		fac = LOG_LOCAL0;
	else if (!strcasecmp(new_facility, "local1"))
		fac = LOG_LOCAL1;
	else if (!strcasecmp(new_facility, "local2"))
		fac = LOG_LOCAL2;
	else if (!strcasecmp(new_facility, "local3"))
		fac = LOG_LOCAL3;
	else if (!strcasecmp(new_facility, "local4"))
		fac = LOG_LOCAL4;
	else if (!strcasecmp(new_facility, "local5"))
		fac = LOG_LOCAL5;
	else if (!strcasecmp(new_facility, "local6"))
		fac = LOG_LOCAL6;
	else if (!strcasecmp(new_facility, "local7"))
		fac = LOG_LOCAL7;
	else
		mysyslog("Invalid facility: \"%s\" - falling back to default.",
				new_facility);

	return (fac);
}
예제 #13
0
SSL_CTX* initialize_SSL(uint16_t server_port, uint16_t max_clients, char* module_name)
{
 	SSL_CTX *ctx;

 	mysyslog(LOG_INFO, "%s initing..\n", module_name);
	ext_server_port = server_port;
	ext_max_clients = max_clients;
	strcpy(ext_module_name, module_name);
	memset(used_ports,0,max_clients*sizeof(struct used_port));

	if((ctx = InitServerCTX()) == NULL)         /* initialize SSL */
    {
         mysyslog(LOG_ERR,"Error while creating ctx\n");
         abort();
    }

    return ctx;
}
예제 #14
0
void ShowCerts(SSL* ssl)
{   X509 *cert;
    char *line;

    cert = SSL_get_peer_certificate(ssl);
    if ( cert != NULL )
    {
        printf("Client certificates:\n");
        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
        mysyslog(LOG_INFO, "Subject: %s\n",line);
        free(line);
        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
        mysyslog(LOG_INFO, "Issuer: %s\n",line);
        free(line);
        X509_free(cert);
    }
    else
        printf("No certificates.\n");
}
예제 #15
0
파일: pam_cgm.c 프로젝트: hallyn/pam-cgm
static char *validate_and_dup(const char *arg)
{
	nih_local char *d = NIH_MUST( nih_strdup(NULL, arg) );
	nih_local char **valid_list = cgm_list_controllers();
	char *tok;

	if (!valid_list) {
		mysyslog(LOG_ERR, "Failed to get controller list\n");
		return NULL;
	}

	for (tok = strtok(d, ","); tok; tok = strtok(NULL, ",")) {
		if (!is_in_list(tok, valid_list)) {
			mysyslog(LOG_ERR, "Invalid controller: %s\n", tok);
			return NULL;
		}
	}
	return NIH_MUST( nih_strdup(NULL, arg) );
}
예제 #16
0
void makerealtime(char *task_name)
{
	int err=0;
	mlockall(MCL_CURRENT|MCL_FUTURE); /* Used by Xenomai to avoid paging used RAM.*/

	err = rt_task_shadow(&rt_task, task_name, ENGST_PRIORITY, ENGST_CREATE_MODE);
	mysyslog(LOG_INFO, "In makerealtime after shadow err = %d\n", err);

    /*5 secs ? if fdsched is not running, this blocks forever, why ?*/
	err = rt_task_bind(&sched_task,"SCHED_PROXY",5000000000ULL);
	if (err < 0 )
	{
		mysyslog(LOG_ERR, "Bind error %d in %s: %s\n",-err,ext_module_name,strerror(-err));
		exit(1);
	}
	else
		mysyslog(LOG_INFO, "Binding engstation to sched task succesfully.\n");

	return;
}
예제 #17
0
int verify_max_clients(int max_clients, int connectSocket, char* module_name)
{
    if(total_clients >= max_clients)
    {

        mysyslog(LOG_WARNING, "The number of %s connected exceeds the limit.\n", module_name);
        /*send "no more connections" message
        msg = NO_FREE_CONN;
        send_ushortdata(connectSocket, &msg ); TODO: perhaps this could be sent only with plain sockets, because no SSL yet.*/
        shutdown(connectSocket,2);
        close(connectSocket);
        return NOTOK;
    }
    else
        return OK;
}
예제 #18
0
파일: pam_cgm.c 프로젝트: hallyn/pam-cgm
static void get_active_controllers(void)
{
	int i;
	nih_local char **list = cgm_list_controllers();

	if (!list) {
		mysyslog(LOG_NOTICE, "unable to detect controllers");
		ctrl_list = NIH_MUST( nih_strdup(NULL, "all") );
		return;
	}
	for (i = 0; list[i]; i++) {
		if (strcmp(list[i], "name=systemd") == 0)
			continue;
		NIH_MUST( nih_strcat_sprintf(&ctrl_list, NULL, "%s%s",
			ctrl_list ? "," : "", list[i]) );
	}
}
예제 #19
0
/*There is an array that holds a map of the ports used to connect to other clients via ethernet.
This function searches in the array looking for a free socket and return an index that added to
the base give us the port number.*/
uint16_t get_new_port(int connectSocket, struct used_port *ports)
{
	uint16_t port=0;
	while(ports[port].ports != 0)
	{
		if(port < ext_max_clients)
			port++;
		else
		{
			mysyslog(LOG_ERR, "No more free ports for %s.\n", ext_module_name);
			shutdown(connectSocket,SHUT_RDWR);
			close(connectSocket);
			return NO_FREE_CONN;
		}
	}
	ports[port].ports = 1; /* mark it as used.*/
	total_clients++; /*one more client being served.*/

    return port;
}
예제 #20
0
파일: logger.c 프로젝트: knot/util-linux
/*
 * logger -- read and log utility
 *
 *	Reads from an input and arranges to write the result on the system
 *	log.
 */
int
main(int argc, char **argv) {
	int ch, logflags, pri;
	char *tag, buf[1024];
	char *usock = NULL;
	char *udpserver = NULL;
	char *udpport = NULL;
	int LogSock = -1;

	static const struct option longopts[] = {
		{ "id",		no_argument,	    0, 'i' },
		{ "stderr",	no_argument,	    0, 's' },
		{ "file",	required_argument,  0, 'f' },
		{ "priority",	required_argument,  0, 'p' },
		{ "tag",	required_argument,  0, 't' },
		{ "socket",	required_argument,  0, 'u' },
		{ "udp",	no_argument,	    0, 'd' },
		{ "server",	required_argument,  0, 'n' },
		{ "port",	required_argument,  0, 'P' },
		{ "version",	no_argument,	    0, 'V' },
		{ "help",	no_argument,	    0, 'h' },
		{ NULL,		0, 0, 0 }
	};

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

	tag = NULL;
	pri = LOG_NOTICE;
	logflags = 0;
	while ((ch = getopt_long(argc, argv, "f:ip:st:u:dn:P:Vh",
					    longopts, NULL)) != -1) {
		switch((char)ch) {
		case 'f':		/* file to log */
			if (freopen(optarg, "r", stdin) == NULL)
				err(EXIT_FAILURE, _("file %s"),
				    optarg);
			break;
		case 'i':		/* log process id also */
			logflags |= LOG_PID;
			break;
		case 'p':		/* priority */
			pri = pencode(optarg);
			break;
		case 's':		/* log to standard error */
			logflags |= LOG_PERROR;
			break;
		case 't':		/* tag */
			tag = optarg;
			break;
		case 'u':		/* unix socket */
			usock = optarg;
			break;
		case 'd':
			optd = 1;	/* use datagrams */
			break;
		case 'n':		/* udp socket */
			optd = 1;	/* use datagrams because udp */
			udpserver = optarg;
			break;
		case 'P':		/* change udp port */
			udpport = optarg;
			break;
		case 'V':
			printf(_("%s from %s\n"), program_invocation_short_name,
						  PACKAGE_STRING);
			exit(EXIT_SUCCESS);
		case 'h':
			usage(stdout);
		case '?':
		default:
			usage(stderr);
		}
	}
	argc -= optind;
	argv += optind;

	/* setup for logging */
	if (!usock && !udpserver)
		openlog(tag ? tag : getlogin(), logflags, 0);
	else if (udpserver)
		LogSock = udpopenlog(udpserver,udpport);
	else
		LogSock = myopenlog(usock);

	/* log input line if appropriate */
	if (argc > 0) {
		register char *p, *endp;
		size_t len;

		for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) {
			len = strlen(*argv);
			if (p + len > endp && p > buf) {
			    if (!usock && !udpserver)
				syslog(pri, "%s", buf);
			    else
				mysyslog(LogSock, logflags, pri, tag, buf);
				p = buf;
			}
			if (len > sizeof(buf) - 1) {
			    if (!usock && !udpserver)
				syslog(pri, "%s", *argv++);
			    else
				mysyslog(LogSock, logflags, pri, tag, *argv++);
			} else {
				if (p != buf)
					*p++ = ' ';
				memmove(p, *argv++, len);
				*(p += len) = '\0';
			}
		}
		if (p != buf) {
		    if (!usock && !udpserver)
			syslog(pri, "%s", buf);
		    else
			mysyslog(LogSock, logflags, pri, tag, buf);
		}
	} else {
		while (fgets(buf, sizeof(buf), stdin) != NULL) {
		    /* glibc is buggy and adds an additional newline,
		       so we have to remove it here until glibc is fixed */
		    int len = strlen(buf);

		    if (len > 0 && buf[len - 1] == '\n')
			    buf[len - 1] = '\0';

		    if (!usock && !udpserver)
			syslog(pri, "%s", buf);
		    else
			mysyslog(LogSock, logflags, pri, tag, buf);
		}
	}
	if (!usock && !udpserver)
		closelog();
	else
		close(LogSock);

	return EXIT_SUCCESS;
}
예제 #21
0
int
main (int argc, char *argv[], char *environ[])
{
  int n = 1;
  int valid = -1;
  char iobuf[BUFSIZ];
  char sysconfdir[BUFSIZ];
  char c_str[BUFSIZ];
  char c_command[BUFSIZ];
  char *p = NULL;
  char *rand = rand2str (16);
  time_t now = time ((time_t *) NULL);
  struct stat s;
  struct sigaction saterm;
  struct sigaction sawinch;
  struct sigaction sachild;
  struct timeval tv;
  double oldtime, newtime;
  struct stat ttybuf;
  int c;
  char argtest[BUFSIZ];

  user.vshell = NULL;
  user.shell.ptr = NULL;
  user.home.ptr = NULL;
  user.term.ptr = NULL;

  progname = argv[0];

  if ((p = (char *) strrchr (progname, '/')) != NULL)
    progname = p + 1;

  if (*progname == '-')
    loginshell = 1;

  /* Who are you? */
  user.pw = getpwuid ((uid_t) getuid ());

  if (user.pw == NULL)
    {
      fprintf (stderr, "I do not know who you are.  Stopping.\n");
      perror ("getpwuid");
      exit (EXIT_FAILURE);
    }

  strncpy (user.to, user.pw->pw_name, BUFSIZ - 1);

  user.term.ptr = getenv ("TERM");

  if (user.term.ptr == NULL)
    user.term.ptr = "dumb";

  if (strlen (user.term.ptr) < 1)
    user.term.ptr = "dumb";

  snprintf (sysconfdir, BUFSIZ - 1, "%s/sudosh.conf", SYSCONFDIR);
  parse (&sudosh_option, sysconfdir);

  while ((c = getopt (argc, argv, "c:hivV")) != EOF)
    {
      switch (c)
	{
	case 'c':
//              fprintf(stderr,"optarg is [%s]\n",optarg);
	  strncpy (user.from, user.pw->pw_name, BUFSIZ - 1);
	  strncpy (c_str, optarg, BUFSIZ - 1);
	  strncpy (c_command, optarg, BUFSIZ - 1);
	  p = strchr (c_str, ' ');
	  if (p)
	    {
	      p[0] = 0;
//              fprintf(stderr,"args=%s\n",c_args);
	    }

	  if (c_str[0] != 0)
	    {
// Test for methods of escape
	      if (strchr (c_command, ';') != NULL ||
		  strchr (c_command, '&') != NULL ||
		  strchr (c_command, '|') != NULL ||
		  strchr (c_command, '<') != NULL ||
		  strchr (c_command, '>') != NULL ||
		  strchr (c_command, '`') != NULL)
		{
		  fprintf (stderr,
			   "\"%s\" isn't allowed to be executed with process or redirect controls.\n",
			   c_command);
		  exit (EXIT_FAILURE);
		}


//              fprintf(stderr,"Testing c\n");
	      // Make sure that c_str is in argallow

	      sprintf (argtest, "$%.100s$", c_str);
//              fprintf(stderr,"Testing for %s\n",argtest);

	      if (strstr (sudosh_option.argallow, argtest) != NULL || strchr(sudosh_option.argallow, '*')!=NULL)
		{
		  FILE *f;
		  snprintf (script.name, (size_t) BUFSIZ - 1,
			    "%s/%s%c%s%cinteractive%c%i%c%s",
			    sudosh_option.logdir, user.from,
			    sudosh_option.fdl, user.to, sudosh_option.fdl,
			    sudosh_option.fdl, (int) now, sudosh_option.fdl,
			    rand);

		  f = fopen (script.name, "w");

		  if (f == (FILE *) 0)
		    {
		      fprintf (stderr, "%.100s: %.100s (%i)\n", script.name,
			       strerror (errno), errno);
		      exit (EXIT_FAILURE);
		    }

		  fprintf (f, "%.256s\n", c_str);
		  fclose (f);

		  execl ("/bin/sh", "sh", "-c", c_command, (char *) 0);
		  exit (EXIT_SUCCESS);
		  break;
		}
	      else
		{
		  fprintf (stderr, "\"%s\" isn't allowed to be executed.\n",
			   c_str);
		  exit (EXIT_FAILURE);
		  break;
		}
	    }
	  break;
	case 'h':
	case '?':
	  fprintf (stdout,
		   "Usage: sudosh\n"
		   "sudo shell that supports input and output logging to syslog\n"
		   "\n"
		   "-h, --help	display this help and exit\n"
		   "-i, --init	initialize logdir (mkdir and chmod) (ignored for compatibility)\n"
		   "-v, --version	output version information and exit\n"
		   "\n" "Report bugs to <%s>\n", PACKAGE_BUGREPORT);
	  exit (EXIT_SUCCESS);
	  break;
	case 'i':
	  fprintf (stdout,
		   "Ignoring initialize option, this is done automatically\n");
	  exit (EXIT_SUCCESS);
	  break;
	case 'v':
	case 'V':
	  fprintf (stdout, "%s version %s\n", PACKAGE_NAME, VERSION);
	  exit (EXIT_SUCCESS);
	  break;
	default:
	  fputs ("Try `sudosh -h' for more information.\n", stderr);
	  exit (EXIT_FAILURE);
	  break;
	}
    }

  if (ttyname (0) != NULL)
    {
      if (stat (ttyname (0), &ttybuf) == 0)
	{
	  if ((getpwuid (ttybuf.st_uid)->pw_name) == NULL)
	    {
	      fprintf (stderr, "I have no idea who you are.\n");
	      exit (EXIT_FAILURE);
	    }
	  strncpy (user.from, getpwuid (ttybuf.st_uid)->pw_name, BUFSIZ - 1);
	}
      else
	{
	  fprintf (stderr, "Couldn't stat %s\n", ttyname (0));
	  exit (EXIT_FAILURE);
	}
    }
  else
    {
      fprintf (stderr, "%s: couldn't get your controlling terminal.\n",
	       progname);
      exit (EXIT_FAILURE);
    }
  user.pw = getpwuid ((uid_t) getuid ());

  snprintf (user.home.str, BUFSIZ - 1, "HOME=%s", user.pw->pw_dir);
  strncpy (user.to_home.str, user.pw->pw_dir, BUFSIZ - 1);
  snprintf (user.term.str, BUFSIZ - 1, "TERM=%s", user.term.ptr);


#ifdef HAVE_GETUSERSHELL
  if ((user.shell.ptr = getenv ("SHELL")) == NULL)
    user.shell.ptr = user.pw->pw_shell;

  /* check against /etc/shells to make sure it's a real shell */
  setusershell ();
  while ((user.vshell = (char *) getusershell ()) != (char *) 0)
    {
      if (strcmp (user.shell.ptr, user.vshell) == 0)
	valid = 1;
    }
  endusershell ();

  if (valid != 1)
    {
      if (user.shell.ptr == NULL)
	{
	  fprintf (stderr, "Could not determine a valid shell.\n");
	  if (sudosh_option.priority != -1)
	    mysyslog (sudosh_option.priority,
		      "Could not determine a valid shell");
	  exit (EXIT_FAILURE);
	}
      else
	{
	  fprintf (stderr, "%s is not in /etc/shells\n", user.shell.ptr);
	  mysyslog (sudosh_option.priority,
		    "%s,%s: %s is not in /etc/shells", user.from,
		    ttyname (0), user.shell.ptr);
	  exit (EXIT_FAILURE);
	}
    }

  if (stat ((const char *) user.shell.ptr, &s) == -1)
    {
      fprintf (stderr, "Shell %s doesn't exist.\n", user.shell.ptr);
      if (sudosh_option.priority != -1)
	mysyslog (sudosh_option.priority, "%s,%s: shell %s doesn't exist.",
		  user.from, ttyname (0), user.shell.ptr);
      exit (EXIT_FAILURE);
    }
#else
  user.shell.ptr = user.pw->pw_shell;
#endif /* HAVE_GETUSERSHELL */

  if (loginshell)
    user.shell.ptr = sudosh_option.defshell;

  snprintf (script.name, (size_t) BUFSIZ - 1, "%s/%s%c%s%cscript%c%i%c%s",
	    sudosh_option.logdir, user.from, sudosh_option.fdl, user.to,
	    sudosh_option.fdl, sudosh_option.fdl, (int) now,
	    sudosh_option.fdl, rand);
  snprintf (timing.name, (size_t) BUFSIZ - 1, "%s/%s%c%s%ctime%c%i%c%s",
	    sudosh_option.logdir, user.from, sudosh_option.fdl, user.to,
	    sudosh_option.fdl, sudosh_option.fdl, (int) now,
	    sudosh_option.fdl, rand);
#ifdef RECORDINPUT
  snprintf (input.name, (size_t) BUFSIZ - 1, "%s/%s%c%s%cinput%c%i%c%s",
	    sudosh_option.logdir, user.from, sudosh_option.fdl, user.to,
	    sudosh_option.fdl, sudosh_option.fdl, (int) now,
	    sudosh_option.fdl, rand);
#endif
  snprintf (start_msg, BUFSIZ - 1,
	    "starting session for %s as %s, tty %s, shell %s", user.from,
	    user.to, ttyname (0), user.shell.ptr);

  set_perms_and_open_file(&script);
  set_perms_and_open_file(&timing);
#ifdef RECORDINPUT
  set_perms_and_open_file(&input);
#endif

  if (sudosh_option.priority != -1)
    mysyslog (sudosh_option.priority, start_msg);
  rawmode (0);

  if (findms (&pspair) < 0)
    {
      perror ("open pty failed");
      bye (EXIT_FAILURE);
    }

  switch (fork ())
    {
    case 0:
      close (pspair.mfd);
      prepchild (&pspair);
    case -1:
      perror ("fork failed");
      bye (EXIT_FAILURE);
    default:
      close (pspair.sfd);
    }

  orig_euid = geteuid();

  if (seteuid (getuid ()) != 0)
    {
      perror ("setuid failed");
      bye (EXIT_FAILURE);
    }

  memset (&sawinch, 0, sizeof sawinch);
  sawinch.sa_handler = newwinsize;
  sawinch.sa_flags = SA_RESTART;
  sigaction (SIGWINCH, &sawinch, (struct sigaction *) 0);

  memset (&saterm, 0, sizeof saterm);
  saterm.sa_handler = bye;
  sigaction (SIGTERM, &sawinch, (struct sigaction *) 0);

  memset (&sachild, 0, sizeof sachild);
  sachild.sa_handler = bye;
  sigaction (SIGCHLD, &sachild, (struct sigaction *) 0);

  oldtime = time (NULL);

  while (n > 0)
    {
      fd_set readfds;

      FD_ZERO (&readfds);
      FD_SET (pspair.mfd, &readfds);
      FD_SET (0, &readfds);

      gettimeofday ((struct timeval *) &tv, NULL);
      if (select (pspair.mfd + 1, &readfds, (fd_set *) 0,
		  (fd_set *) 0, (struct timeval *) 0) < 0)
	{

	  if (errno == EINTR)
	    continue;

	  perror ("select");
	  bye (EXIT_FAILURE);
	}

      if (FD_ISSET (pspair.mfd, &readfds))
	{
	  if ((n = read (pspair.mfd, iobuf, sizeof (iobuf))) > 0)
	    {
	      DO_WRITE (1, iobuf, n);
	      script.bytes += DO_WRITE (script.fd, iobuf, n);
	    }
	  newtime = tv.tv_sec + (double) tv.tv_usec / 1000000;
	  snprintf (timing.str, BUFSIZ - 1, "%f %i\n", newtime - oldtime, n);
	  timing.bytes += DO_WRITE (timing.fd, &timing.str, strlen (timing.str));
	  oldtime = newtime;

	}

      if (FD_ISSET (0, &readfds))
	{
	  if ((n = read (0, iobuf, BUFSIZ)) > 0)
	    {
	      DO_WRITE (pspair.mfd, iobuf, n);
#ifdef RECORDINPUT
	      switch (*iobuf)
		{
		case '\r':
		  snprintf (input.str, BUFSIZ - 1, "\n");
		  break;
		case 0x003:
		  snprintf (input.str, BUFSIZ - 1, "(CTRL-C)");
		  break;
		case 0x004:
		  snprintf (input.str, BUFSIZ - 1, "(CTRL-D)\n");
		  break;
		case 0x1a:
		  snprintf (input.str, BUFSIZ - 1, "(CTRL-Z)\n");
		  break;
		case 0x1b:
		  snprintf (input.str, BUFSIZ - 1, "(ESC)");
		  break;
		default:
		  DO_WRITE (input.fd, iobuf, 1);
		  written = 1;
		  break;
		}

	      if (written == 0)
		{
		  DO_WRITE (input.fd, &input.str, strlen (input.str));
		}
#endif
	    }
	}
    }

  bye (EXIT_SUCCESS);
  return (0);
}
예제 #22
0
/*
 * logger -- read and log utility
 *
 *	Reads from an input and arranges to write the result on the system
 *	log.
 */
int main(int argc, char **argv)
{
	int ch, logflags, pri, prio_prefix;
	char *tag, buf[1024];
	char *usock = NULL;
	char *server = NULL;
	char *port = NULL;
	int LogSock = -1, socket_type = ALL_TYPES;
#ifdef HAVE_LIBSYSTEMD
	FILE *jfd = NULL;
#endif
	static const struct option longopts[] = {
		{ "id",		no_argument,	    0, 'i' },
		{ "stderr",	no_argument,	    0, 's' },
		{ "file",	required_argument,  0, 'f' },
		{ "priority",	required_argument,  0, 'p' },
		{ "tag",	required_argument,  0, 't' },
		{ "socket",	required_argument,  0, 'u' },
		{ "udp",	no_argument,	    0, 'd' },
		{ "tcp",	no_argument,	    0, 'T' },
		{ "server",	required_argument,  0, 'n' },
		{ "port",	required_argument,  0, 'P' },
		{ "version",	no_argument,	    0, 'V' },
		{ "help",	no_argument,	    0, 'h' },
		{ "prio-prefix", no_argument, 0, OPT_PRIO_PREFIX },
#ifdef HAVE_LIBSYSTEMD
		{ "journald",   optional_argument,  0, OPT_JOURNALD },
#endif
		{ NULL,		0, 0, 0 }
	};

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

	tag = NULL;
	pri = LOG_NOTICE;
	logflags = 0;
	prio_prefix = 0;
	while ((ch = getopt_long(argc, argv, "f:ip:st:u:dTn:P:Vh",
					    longopts, NULL)) != -1) {
		switch (ch) {
		case 'f':		/* file to log */
			if (freopen(optarg, "r", stdin) == NULL)
				err(EXIT_FAILURE, _("file %s"),
				    optarg);
			break;
		case 'i':		/* log process id also */
			logflags |= LOG_PID;
			break;
		case 'p':		/* priority */
			pri = pencode(optarg);
			break;
		case 's':		/* log to standard error */
			logflags |= LOG_PERROR;
			break;
		case 't':		/* tag */
			tag = optarg;
			break;
		case 'u':		/* unix socket */
			usock = optarg;
			break;
		case 'd':
			socket_type = TYPE_UDP;
			break;
		case 'T':
			socket_type = TYPE_TCP;
			break;
		case 'n':
			server = optarg;
			break;
		case 'P':
			port = optarg;
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			exit(EXIT_SUCCESS);
		case 'h':
			usage(stdout);
		case OPT_PRIO_PREFIX:
			prio_prefix = 1;
			break;
#ifdef HAVE_LIBSYSTEMD
		case OPT_JOURNALD:
			if (optarg) {
				jfd = fopen(optarg, "r");
				if (!jfd)
					err(EXIT_FAILURE, _("cannot open %s"),
					    optarg);
			} else
				jfd = stdin;
			break;
#endif
		case '?':
		default:
			usage(stderr);
		}
	}
	argc -= optind;
	argv += optind;

	/* setup for logging */
#ifdef HAVE_LIBSYSTEMD
	if (jfd) {
		int ret = journald_entry(jfd);
		if (stdin != jfd)
			fclose(jfd);
		return ret ? EXIT_FAILURE : EXIT_SUCCESS;
	}
#endif
	if (server)
		LogSock = inet_socket(server, port, socket_type);
	else if (usock)
		LogSock = unix_socket(usock, socket_type);
	else
		openlog(tag ? tag : getlogin(), logflags, 0);

	/* log input line if appropriate */
	if (argc > 0) {
		register char *p, *endp;
		size_t len;

		for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) {
			len = strlen(*argv);
			if (p + len > endp && p > buf) {
			    if (!usock && !server)
				syslog(pri, "%s", buf);
			    else
				mysyslog(LogSock, logflags, pri, tag, buf);
				p = buf;
			}
			if (len > sizeof(buf) - 1) {
			    if (!usock && !server)
				syslog(pri, "%s", *argv++);
			    else
				mysyslog(LogSock, logflags, pri, tag, *argv++);
			} else {
				if (p != buf)
					*p++ = ' ';
				memmove(p, *argv++, len);
				*(p += len) = '\0';
			}
		}
		if (p != buf) {
		    if (!usock && !server)
			syslog(pri, "%s", buf);
		    else
			mysyslog(LogSock, logflags, pri, tag, buf);
		}
	} else {
		char *msg;
		int default_priority = pri;
		while (fgets(buf, sizeof(buf), stdin) != NULL) {
		    /* glibc is buggy and adds an additional newline,
		       so we have to remove it here until glibc is fixed */
		    int len = strlen(buf);

		    if (len > 0 && buf[len - 1] == '\n')
			    buf[len - 1] = '\0';

			msg = buf;
			pri = default_priority;
			if (prio_prefix && msg[0] == '<')
				msg = get_prio_prefix(msg, &pri);

		    if (!usock && !server)
			syslog(pri, "%s", msg);
		    else
			mysyslog(LogSock, logflags, pri, tag, msg);
		}
	}
	if (!usock && !server)
		closelog();
	else
		close(LogSock);

	return EXIT_SUCCESS;
}
예제 #23
0
void get_options(int argc, char *const argv[]) {
	extern u_char *logfile, *lockfile, *user, *group, *ifstring;
	int opt;

	while ((opt = getopt_long(argc, argv, opts, longopts, NULL)) != EOF) {
		switch (opt) {
			case 10:
				enable(optarg, LOG_TCP);
				break;
			case 11:
				enable(optarg, LOG_UDP);
				break;
			case 12:
				enable(optarg, LOG_ICMP);
				break;
			case 13:
				facility = get_facility(optarg);
				break;
			case 14:
				priority = get_priority(optarg);
				break;
			case 15:
				if (lockfile != NULL)
					free(lockfile);
				lockfile = xstrdup(optarg);
				break;
			case 'w':
				enable(optarg, LOG_IP);
				break;
			case 'd':
				flags |= IGNORE_NS;
				break;
			case 'u':
				if (user != NULL)
					free(user);
				user = xstrdup(optarg);
				break;
			case 'g':
				if (group != NULL)
					free(group);
				group = xstrdup(optarg);
				break;
			case 'k':
				kill_iplog(15, lockfile);
				break;
			case 'l':
				if (opt_enabled(LOG_STDOUT)) {
					mysyslog("Warning: Overriding --stdout");
					flags &= ~LOG_STDOUT;
				} else if (logfile != NULL)
					free(logfile);
				logfile = xstrdup(optarg);
				break;
			case 'L':
				if (logfile != NULL) {
					mysyslog("Warning: Overriding --logfile");
					xfree(logfile);
				}
				flags |= LOG_STDOUT;
				break;
			case 'm':
				enable(optarg, SCANS_ONLY);
				break;
			case 'o':
				flags |= NO_FORK;
				break;
			case 'c':
				enable(optarg, DNS_CACHE);
				break;
			case 'y':
				enable(optarg, LOG_FRAG);
				break;
			case 'a':
				flags |= (PROMISC | LOG_DEST);
				if (pcap_network != NULL)
					free(pcap_network);
				pcap_network = xstrdup(optarg);
				break;
			case 'D':
				enable(optarg, LOG_DEST);
				break;
			case 'e':
#ifdef __linux__
				enable(optarg, GET_IDENT);
#else
				mysyslog("Ident lookups are only supported on Linux.");
#endif
				break;
			case 'T':
				enable(optarg, TCP_RES);
				break;
			case 'U':
				enable(optarg, UDP_RES);
				break;
			case 'V':
				enable(optarg, VERBOSE);
				break;
			case 'I':
				enable(optarg, ICMP_RES);
				break;
			case 'S':
				enable(optarg, SMURF);
				break;
			case 'b':
				enable(optarg, BOGUS);
				break;
			case 'P':
				enable(optarg, PING_FLOOD);
				break;
			case 'p':
				enable(optarg, PORTSCAN);
				break;
			case 'x':
				enable(optarg, XMAS_SCAN);
				break;
			case 'f':
				enable(optarg, FIN_SCAN);
				break;
			case 'q':
				enable(optarg, SYN_SCAN);
				break;
			case 'F':
				enable(optarg, UDP_SCAN);
				break;
			case 'N':
				flags |= NO_RESOLV;
				break;
			case 'n':
				enable(optarg, NULL_SCAN);
				break;
			case 's':
				enable(optarg, SYN_FLOOD);
				break;
			case 't':
				enable(optarg, TRACEROUTE);
				break;
			case 'i':
				if (ifstring != NULL)
					free(ifstring);
				ifstring = xstrdup(optarg);
				break;
			case 'R':
				kill_iplog(1, lockfile);
				break;
			case 'z':
				enable(optarg, FOOL_NMAP);
				break;
			case 'v':
				mysyslog("iplog version %s\nby %s\n%s",
					VERSION, AUTHORS, WEBPAGE);
				exit(0);
			case 'h':
			default:
				print_help();
				break;
		}
	}
}
예제 #24
0
int main (int argc, char const * argv [])

{
	static char const * optv [] =
	{
		"write a message to the system logging facility",
		"[message]",
		"b:def:i:p:ns:t",
		"b s\tidentity is the basename of s ",
		"e\techo messages on stderr",
		"f s\tmessage filename",
		"i s\tidentity string",
		"p s\tpriority in facility.severity format",
		"n\tinclude PID number",
		"d\tuse datagrams",
		"s s\tsocket filename",
		"t\tsend test messages",
		(char const *) (0)
	};
	char message [TEXTLINE_MAX];
	char * bp = message;
	char const * socketname = (char *) (0);
	char const * identity = (char *) (0);
	int priority = SYSLOG_USER | SYSLOG_INFO;
	code_t sockettype = SOCK_STREAM;
	flag_t options = (flag_t) (0);
	file_t fd = (file_t) (-1);
	int c;
	while (~ (c = getoptv (argc, argv, optv)))
	{
		switch (c)
		{
		case 'b':
			for (identity = optarg; * optarg != (char) (0); optarg++)
			{
				if (* optarg == PATH_C_EXTENDER)
				{
					identity = optarg +  1;
				}
			}
			break;
		case 'd':
			sockettype = SOCK_DGRAM;
			break;
		case 'e':
			_setbits (options, SYSLOG_PERROR);
			break;
		case 'f':
			if (freopen (optarg, "rb", stdin) == (FILE *) (0))
			{
				error (1, errno, "%s", optarg);
			}
			break;
		case 'i':
			identity = optarg;
			break;
		case 'n':
			_setbits (options, SYSLOG_PROCESS);
			break;
		case 'p':
			priority = syslog_encode (optarg);
			break;
		case 's':
			socketname = optarg;
			break;
		case 't':
			mysyslogtest (priority);
			exit (0);
		default: 
			break;
		}
	}
	argc -= optind;
	argv += optind;
	fclose (stdout);
	if (socketname)
	{
		fd = myopenlog (socketname, sockettype);
	}
	else 
	{
		openlog (identity, options, priority);
	}
	if (! argc)
	{
		while ((c = getc (stdin)) != EOF)
		{
			if (nobreak (c))
			{
				if ((unsigned) (bp - message) < STRLEN (message))
				{
					* bp++ = c;
				}
			}
			else 
			{
				* bp = (char) (0);
				if (socketname)
				{
					mysyslog (fd, options, priority, identity, message);
				}
				else 
				{
					syslog (priority, "%s", message);
				}
				bp = message;
			}
		}
	}
	else 
	{
		for (bp = message; (argc) && (* argv); * bp++ = ' ')
		{
			char const * string;
			for (string = * argv; * string; string++)
			{
				if ((unsigned) (bp - message) < STRLEN (message))
				{
					* bp++ = * string;
				}
			}
			argc--;
			argv++;
		}
		if (bp > message)
		{
			bp--;
		}
		* bp = (char) (0);
		if (socketname)
		{
			mysyslog (fd, options, priority, identity, message);
		}
		else 
		{
			syslog (priority, "%s", message);
		}
	}
	if (socketname)
	{
		close (fd);
	}
	else 
	{
		closelog ();
	}
	exit (0);
}
예제 #25
0
static void print_help(void) {
	mysyslog(
"Usage: " PACKAGE " [options] (\"*\" Denotes enabled by default)\n"
"--user      or -u <user|UID>     Run as specified the user or UID.\n"
"--group     or -g <group|GID>    Run with specified the group or GID.\n"
"--logfile   or -l <file>         Log to <file>.\n"
"--pid-file  <file>               Use <file> as the pid file.\n"
"--ignore    or -d                Ignore DNS traffic from nameservers listed in\n"
"                                 /etc/resolv.conf.\n"
"--interface or -i <if0,...,ifN>  Listen on the specified interface(s).\n"
"--promisc   or -a <network>      Log traffic to all hosts on <network>.\n"
"--kill      or -k                Kill iplog, if it is running.\n"
"--restart   or -R                Restart iplog, if it is running.\n"
"--no-fork   or -o                Run in the foreground.\n"
"--stdout    or -L                Log to stdout.\n"
"--help      or -h                This help screen.\n"
"--version   or -v                Print version information and exit.\n"
"\n"
"--facility <facility>            Use the specified syslog facility.\n"
"--priority <priority>            Use the specified syslog priority.\n"
"\n"
"--tcp[=true|false|toggle]                      %cLog TCP traffic.\n"
"--udp[=true|false|toggle]                      %cLog UDP traffic.\n"
"--icmp[=true|false|toggle]                     %cLog ICMP traffic.\n"
"\n"
"--log-ip[=true|false|toggle]            or -w  %cLog IP along with hostname.\n"
"--log-dest[=true|false|toggle]          or -D  %cLog the destination of traffic.\n"
"--dns-cache[=true|false|toggle]         or -c  %cUse the built-in DNS cache.\n"
"--get-ident[=true|false|toggle]         or -e  %cGet ident info on connections\n"
"                                                to listening ports.\n"
"\n"
"--tcp-resolve[=true|false|toggle]       or -T  %cResolve IPs of TCP traffic.\n"
"--udp-resolve[=true|false|toggle]       or -U  %cResolve IPs of UDP traffic.\n"
"--icmp-resolve[=true|false|toggle]      or -I  %cResolve IPs of ICMP traffic.\n"
"--disable-resolver                      or -N  %cDo not resolve any IPs.\n"
"\n"
"--verbose[=true|false|toggle]           or -V  %cBe verbose.\n"
"--fool-nmap[=true|false|toggle]         or -z  %cFool nmap's OS detection.\n"
"--scans-only[=true|false|toggle]        or -m  %cOnly log scans.\n"
"--detect-syn-flood[=true|false|toggle]  or -s  %cStop resolving IPs if a\n"
"                                                SYN flood is detected.\n"
"\n"
"--log-frag[=true|false|toggle]          or -y  %cLog fragment attacks.\n"
"--log-traceroute[=true|false|toggle]    or -t  %cLog traceroutes.\n"
"--log-ping-flood[=true|false|toggle]    or -P  %cLog ICMP ping floods.\n"
"--log-smurf[=true|false|toggle]         or -S  %cLog smurf attacks.\n"
"--log-bogus[=true|false|toggle]         or -b  %cLog bogus TCP flags.\n"
"--log-portscan[=true|false|toggle]      or -p  %cLog port scans.\n"
"--log-udp-scan[=true|false|toggle]      or -F  %cLog UDP scans/floods.\n"
"--log-fin-scan[=true|false|toggle]      or -f  %cLog FIN scans.\n"
"--log-syn-scan[=true|false|toggle]      or -q  %cLog SYN scans.\n"
"--log-xmas-scan[=true|false|toggle]     or -x  %cLog Xmas scans.\n"
"--log-null-scan[=true|false|toggle]     or -n  %cLog null scans.",
IS_DEFAULT(LOG_TCP),	IS_DEFAULT(LOG_UDP),	IS_DEFAULT(LOG_ICMP),
IS_DEFAULT(LOG_IP),		IS_DEFAULT(LOG_DEST),	IS_DEFAULT(DNS_CACHE),
IS_DEFAULT(GET_IDENT),	IS_DEFAULT(TCP_RES),	IS_DEFAULT(UDP_RES),
IS_DEFAULT(ICMP_RES),	IS_DEFAULT(NO_RESOLV),	IS_DEFAULT(VERBOSE),
IS_DEFAULT(FOOL_NMAP),	IS_DEFAULT(SCANS_ONLY),	IS_DEFAULT(SYN_FLOOD),
IS_DEFAULT(LOG_FRAG),	IS_DEFAULT(TRACEROUTE),	IS_DEFAULT(PING_FLOOD),
IS_DEFAULT(SMURF),		IS_DEFAULT(BOGUS),		IS_DEFAULT(PORTSCAN),
IS_DEFAULT(UDP_SCAN),	IS_DEFAULT(FIN_SCAN),	IS_DEFAULT(SYN_SCAN),
IS_DEFAULT(XMAS_SCAN),	IS_DEFAULT(NULL_SCAN));
	exit(0);
}
예제 #26
0
파일: logging.c 프로젝트: CVi/sudo
/*
 * Send a message to MAILTO user
 */
static void
send_mail(const char *fmt, ...)
{
    FILE *mail;
    char *p;
    int fd, pfd[2], status;
    pid_t pid, rv;
    sigaction_t sa;
    va_list ap;
#ifndef NO_ROOT_MAILER
    static char *root_envp[] = {
	"HOME=/",
	"PATH=/usr/bin:/bin:/usr/sbin:/sbin",
	"LOGNAME=root",
	"USERNAME=root",
	"USER=root",
	NULL
    };
#endif /* NO_ROOT_MAILER */

    /* Just return if mailer is disabled. */
    if (!def_mailerpath || !def_mailto)
	return;

    /* Fork and return, child will daemonize. */
    switch (pid = fork()) {
	case -1:
	    /* Error. */
	    error(1, _("unable to fork"));
	    break;
	case 0:
	    /* Child. */
	    switch (pid = fork()) {
		case -1:
		    /* Error. */
		    mysyslog(LOG_ERR, _("unable to fork: %m"));
		    _exit(1);
		case 0:
		    /* Grandchild continues below. */
		    break;
		default:
		    /* Parent will wait for us. */
		    _exit(0);
	    }
	    break;
	default:
	    /* Parent. */
	    do {
		rv = waitpid(pid, &status, 0);
	    } while (rv == -1 && errno == EINTR);
	    return;
    }

    /* Daemonize - disassociate from session/tty. */
    if (setsid() == -1)
      warning("setsid");
    if (chdir("/") == -1)
      warning("chdir(/)");
    if ((fd = open(_PATH_DEVNULL, O_RDWR, 0644)) != -1) {
	(void) dup2(fd, STDIN_FILENO);
	(void) dup2(fd, STDOUT_FILENO);
	(void) dup2(fd, STDERR_FILENO);
    }

#ifdef HAVE_SETLOCALE
    if (!setlocale(LC_ALL, def_sudoers_locale)) {
	setlocale(LC_ALL, "C");
	efree(def_sudoers_locale);
	def_sudoers_locale = estrdup("C");
    }
#endif /* HAVE_SETLOCALE */

    /* Close password, group and other fds so we don't leak. */
    sudo_endpwent();
    sudo_endgrent();
    closefrom(STDERR_FILENO + 1);

    /* Ignore SIGPIPE in case mailer exits prematurely (or is missing). */
    zero_bytes(&sa, sizeof(sa));
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_INTERRUPT;
    sa.sa_handler = SIG_IGN;
    (void) sigaction(SIGPIPE, &sa, NULL);

    if (pipe(pfd) == -1) {
	mysyslog(LOG_ERR, _("unable to open pipe: %m"));
	_exit(1);
    }

    switch (pid = fork()) {
	case -1:
	    /* Error. */
	    mysyslog(LOG_ERR, _("unable to fork: %m"));
	    _exit(1);
	    break;
	case 0:
	    {
		char *argv[MAX_MAILFLAGS + 1];
		char *mpath, *mflags;
		int i;

		/* Child, set stdin to output side of the pipe */
		if (pfd[0] != STDIN_FILENO) {
		    if (dup2(pfd[0], STDIN_FILENO) == -1) {
			mysyslog(LOG_ERR, _("unable to dup stdin: %m"));
			_exit(127);
		    }
		    (void) close(pfd[0]);
		}
		(void) close(pfd[1]);

		/* Build up an argv based on the mailer path and flags */
		mflags = estrdup(def_mailerflags);
		mpath = estrdup(def_mailerpath);
		if ((argv[0] = strrchr(mpath, ' ')))
		    argv[0]++;
		else
		    argv[0] = mpath;

		i = 1;
		if ((p = strtok(mflags, " \t"))) {
		    do {
			argv[i] = p;
		    } while (++i < MAX_MAILFLAGS && (p = strtok(NULL, " \t")));
		}
		argv[i] = NULL;

		/*
		 * Depending on the config, either run the mailer as root
		 * (so user cannot kill it) or as the user (for the paranoid).
		 */
#ifndef NO_ROOT_MAILER
		set_perms(PERM_ROOT|PERM_NOEXIT);
		execve(mpath, argv, root_envp);
#else
		set_perms(PERM_FULL_USER|PERM_NOEXIT);
		execv(mpath, argv);
#endif /* NO_ROOT_MAILER */
		mysyslog(LOG_ERR, _("unable to execute %s: %m"), mpath);
		_exit(127);
	    }
	    break;
    }

    (void) close(pfd[0]);
    mail = fdopen(pfd[1], "w");

    /* Pipes are all setup, send message. */
    (void) fprintf(mail, "To: %s\nFrom: %s\nAuto-Submitted: %s\nSubject: ",
	def_mailto, def_mailfrom ? def_mailfrom : user_name, "auto-generated");
    for (p = def_mailsub; *p; p++) {
	/* Expand escapes in the subject */
	if (*p == '%' && *(p+1) != '%') {
	    switch (*(++p)) {
		case 'h':
		    (void) fputs(user_host, mail);
		    break;
		case 'u':
		    (void) fputs(user_name, mail);
		    break;
		default:
		    p--;
		    break;
	    }
	} else
	    (void) fputc(*p, mail);
    }

#ifdef HAVE_NL_LANGINFO
    if (strcmp(def_sudoers_locale, "C") != 0)
	(void) fprintf(mail, "\nContent-Type: text/plain; charset=\"%s\"\nContent-Transfer-Encoding: 8bit", nl_langinfo(CODESET));
#endif /* HAVE_NL_LANGINFO */

    (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host,
	get_timestr(time(NULL), def_log_year), user_name);
    va_start(ap, fmt);
    (void) vfprintf(mail, fmt, ap);
    va_end(ap);
    fputs("\n\n", mail);

    fclose(mail);
    do {
        rv = waitpid(pid, &status, 0);
    } while (rv == -1 && errno == EINTR);
    _exit(0);
}
예제 #27
0
/*
 * logger -- read and log utility
 * Reads from an input and arranges to write the result on the system log.
 */
int main (int argc, char **argv) {
    int ch, logflags, pri;
    char *tag, buf[MAX_LINE];
    char *usock = NULL;
    long timeout_ms = 100;
    long timeout_sec;
    long timeout_usec;
    int indent_mode = 0;
    char *udpserver = NULL;
    int LogSock = -1;
    long tmpport;

    static const struct option longopts[] = {
        { "id",       no_argument,        0, 'i' },
        { "stderr",   no_argument,        0, 's' },
        { "file",     required_argument,  0, 'f' },
        { "priority", required_argument,  0, 'p' },
        { "tag",      required_argument,  0, 't' },
        { "socket",   required_argument,  0, 'u' },
        { "udp",      no_argument,        0, 'd' },
        { "server",   required_argument,  0, 'n' },
        { "port",     required_argument,  0, 'P' },
        { "indent",   required_argument,  0, 'I' },
        { "version",  no_argument,        0, 'V' },
        { "help",     no_argument,        0, 'h' },
        { NULL,       0,                  0, 0   }
    };

    tag = NULL;
    pri = LOG_NOTICE;
    logflags = 0;

    while ((ch = getopt_long(argc, argv, "f:ip:st:u:dI:n:P:Vh", longopts, NULL)) != -1) {
        switch((char) ch) {
            case 'f': /* file to log */
                if (freopen(optarg, "r", stdin) == NULL)
                    err(EXIT_FAILURE, "file %s", optarg);
                break;

            case 'i': /* log process id also */
                logflags |= LOG_PID;
                break;

            case 'p': /* priority */
                pri = pencode(optarg);
                break;

            case 's': /* log to standard error */
                logflags |= LOG_PERROR;
                break;

            case 't': /* tag */
                tag = optarg;
                break;

            case 'u': /* unix socket */
                usock = optarg;
                break;

            case 'd':
                optd = 1; /* use datagrams */
                break;

            case 'n': /* udp socket */
                optd = 1; /* use datagrams because udp */
                udpserver = optarg;
                break;

            case 'P': /* change udp port */
                tmpport = strtol_or_err(optarg, "failed to parse port number");

                if (tmpport < 0 || 65535 < tmpport) {
                    errx(EXIT_FAILURE, "port `%ld' out of range", tmpport);
                }

                udpport = (int) tmpport;
                break;

            case 'V':
                printf("%s %s\n", PROGRAM_NAME, PROGRAM_VERSION);
                exit(EXIT_SUCCESS);

            case 'I':
                indent_mode = 1;
                timeout_ms = strtol_or_err(optarg, "failed to parse timeout number");

                if (timeout_ms < 1) {
                    errx(EXIT_FAILURE, "Invalid value for timeout %li", timeout_ms);
                }

                break;

            case 'h':
                usage(stdout);

            case '?':
            default:
                usage(stderr);
        }
    }

    argc -= optind;
    argv += optind;

    /* setup for logging */
    if (!usock && !udpserver) {
        openlog(tag ? tag : getlogin(), logflags, 0);
    } else if (udpserver) {
        LogSock = udpopenlog(udpserver, udpport);
    } else {
        LogSock = myopenlog(usock);
    }

    (void) fclose(stdout);

    /* log input line if appropriate */
    if (argc > 0) {
        char *p, *endp;
        size_t len;

        for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) {
            len = strlen(*argv);
            if (p + len > endp && p > buf) {
                if (!usock && !udpserver) {
                    syslog(pri, "%s", buf);
                } else {
                    mysyslog(LogSock, logflags, pri, tag, buf);
                }

                p = buf;
            }

            if (len > sizeof(buf) - 1) {
                if (!usock && !udpserver) {
                    syslog(pri, "%s", *argv++);
                } else {
                    mysyslog(LogSock, logflags, pri, tag, *argv++);
                }

            } else {
                if (p != buf) {
                    *p++ = ' ';
                }

                memmove(p, *argv++, len);
                *(p += len) = '\0';
            }
        }

        if (p != buf) {
            if (!usock && !udpserver) {
                syslog(pri, "%s", buf);
            } else {
                mysyslog(LogSock, logflags, pri, tag, buf);
            }
        }

    } else if (indent_mode) {
        int len;

        timeout_sec = timeout_ms / 1000;
        timeout_usec = (timeout_ms % 1000) * 1000;

        while ((len = readBlock(buf, MAX_LINE, timeout_sec, timeout_usec)) != EOF) {
            //fprintf(stderr, "Got buf %i\n", len);
            if (len > 0 && buf[len - 1] == '\n') {
                buf[len - 1] = '\0';
            }

            if (!usock && !udpserver) {
                syslog(pri, "%s", buf);
            } else {
                mysyslog(LogSock, logflags, pri, tag, buf);
            }
        }
    } else {
        while (fgets(buf, sizeof(buf), stdin) != NULL) {
            /* glibc is buggy and adds an additional newline, so we have to remove it here until glibc is fixed */
            int len = strlen(buf);

            if (len > 0 && buf[len - 1] == '\n') {
                buf[len - 1] = '\0';
            }

            if (!usock && !udpserver) {
                syslog(pri, "%s", buf);
            } else {
                mysyslog(LogSock, logflags, pri, tag, buf);
            }
        }
    }

    if (!usock && !udpserver) {
        closelog();
    } else {
        close(LogSock);
    }

    return EXIT_SUCCESS;
}
예제 #28
0
파일: pam_cgm.c 프로젝트: hallyn/pam-cgm
static int handle_login(const char *user)
{
	int idx = 0, ret;
	int existed = 1;
	size_t ulen = strlen("user/") + strlen(user);
	size_t len = ulen + 50; // Just make sure there's room for "user/$user or an <integer>"
	uid_t uid = 0;
	gid_t gid = 0;
	nih_local char *cg = NIH_MUST( nih_alloc(NULL, len) );

	if (!get_uid_gid(user, &uid, &gid)) {
		mysyslog(LOG_ERR, "failed to get uid and gid for %s\n", user);
		return PAM_SESSION_ERR;
	}

	memset(cg, 0, len);
	strcpy(cg, user);

	ret = snprintf(cg, len, "user/%s", user);
	if (ret < 0 || ret >= len)
		return PAM_SESSION_ERR;

	if (!cgm_create(cg, &existed)) {
		mysyslog(LOG_ERR, "failed to create cgroup %s\n", cg);
		return PAM_SESSION_ERR;
	}

	if (existed == 0) {
		if (!cgm_autoremove(cg)) {
			mysyslog(LOG_ERR, "Warning: failed to set autoremove on %s\n", cg);
		}
	}

	if (!cgm_enter(cg)) {
		mysyslog(LOG_ERR, "failed to enter cgroup %s\n", cg);
		return PAM_SESSION_ERR;
	}

	while (idx >= 0) {
		sprintf(cg, "%d", idx);
		if (!cgm_create(cg, &existed)) {
			mysyslog(LOG_ERR, "failed to create a user cgroup\n");
			return PAM_SESSION_ERR;
		}

		if (existed == 1) {
			idx++;
			continue;
		}

		if (!cgm_chown(cg, uid, gid)) {
			mysyslog(LOG_ERR, "Warning: failed to chown %s\n", cg);
		}

		if (!cgm_autoremove(cg)) {
			mysyslog(LOG_ERR, "Warning: failed to set autoremove on %s\n", cg);
		}

		if (!cgm_enter(cg)) {
			mysyslog(LOG_ERR, "failed to enter user cgroup %s\n", cg);
			return PAM_SESSION_ERR;
		}
		break;
	}

	return PAM_SUCCESS;
}