static char *makemsg(char *fname, char **mvec, int mvecsz, size_t *mbufsize, int print_banner) { register int ch, cnt; struct stat sbuf; FILE *fp; char *p, *lbuf, *tmpname, *mbuf; long line_max; line_max = sysconf(_SC_LINE_MAX); lbuf = xmalloc(line_max); if ((fp = xfmkstemp(&tmpname, NULL)) == NULL) err(EXIT_FAILURE, _("can't open temporary file")); unlink(tmpname); free(tmpname); if (print_banner == TRUE) { char *hostname = xgethostname(); char *whom, *where, *date; struct passwd *pw; time_t now; if (!(whom = getlogin()) || !*whom) whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???"; if (!whom) { whom = "someone"; warn(_("cannot get passwd uid")); } where = ttyname(STDOUT_FILENO); if (!where) { where = "somewhere"; warn(_("cannot get tty name")); } else if (strncmp(where, "/dev/", 5) == 0) where += 5; time(&now); date = xstrdup(ctime(&now)); date[strlen(date) - 1] = '\0'; /* * all this stuff is to blank out a square for the message; * we wrap message lines at column 79, not 80, because some * terminals wrap after 79, some do not, and we can't tell. * Which means that we may leave a non-blank character * in column 80, but that can't be helped. */ /* snprintf is not always available, but the sprintf's here will not overflow as long as %d takes at most 100 chars */ fprintf(fp, "\r%79s\r\n", " "); sprintf(lbuf, _("Broadcast message from %s@%s (%s) (%s):"), whom, hostname, where, date); fprintf(fp, "%-79.79s\007\007\r\n", lbuf); free(hostname); free(date); } fprintf(fp, "%79s\r\n", " "); if (mvec) { /* * Read message from argv[] */ int i; for (i = 0; i < mvecsz; i++) { fputs(mvec[i], fp); if (i < mvecsz - 1) fputc(' ', fp); } fputc('\r', fp); fputc('\n', fp); } else { /* * read message from <file> */ if (fname) { /* * When we are not root, but suid or sgid, refuse to read files * (e.g. device files) that the user may not have access to. * After all, our invoker can easily do "wall < file" * instead of "wall file". */ uid_t uid = getuid(); if (uid && (uid != geteuid() || getgid() != getegid())) errx(EXIT_FAILURE, _("will not read %s - use stdin."), fname); if (!freopen(fname, "r", stdin)) err(EXIT_FAILURE, _("cannot open %s"), fname); } /* * Read message from stdin. */ while (fgets(lbuf, line_max, stdin)) { for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) { if (cnt == 79 || ch == '\n') { for (; cnt < 79; ++cnt) putc(' ', fp); putc('\r', fp); putc('\n', fp); cnt = 0; } if (ch == '\t') cnt += (7 - (cnt % 8)); if (ch != '\n') fputc_careful(ch, fp, '^'); } } } fprintf(fp, "%79s\r\n", " "); free(lbuf); rewind(fp); if (fstat(fileno(fp), &sbuf)) err(EXIT_FAILURE, _("stat failed")); *mbufsize = (size_t) sbuf.st_size; mbuf = xmalloc(*mbufsize); if (fread(mbuf, 1, *mbufsize, fp) != *mbufsize) err(EXIT_FAILURE, _("fread failed")); if (close_stream(fp) != 0) errx(EXIT_FAILURE, _("write error")); return mbuf; }
/*ARGSUSED*/ int main(int argc, char *argv[]) { char hostname[HOST_NAME_MAX+1], s[BUFSIZ], s1[BUFSIZ], date[256]; char *p, *style, *nstyle, *ttynam; struct itimerval ntimer, otimer; int ch, sectimeout, usemine, cnt, tries = 10, backoff = 3; const char *errstr; struct passwd *pw; struct tm *timp; time_t curtime; login_cap_t *lc; sectimeout = TIMEOUT; style = NULL; usemine = 0; no_timeout = 0; if (pledge("stdio rpath wpath getpw tty proc exec", NULL) == -1) err(1, "pledge"); if (!(pw = getpwuid(getuid()))) errx(1, "unknown uid %u.", getuid()); lc = login_getclass(pw->pw_class); if (lc != NULL) { /* * We allow "login-tries" attempts to login but start * slowing down after "login-backoff" attempts. */ tries = (int)login_getcapnum(lc, "login-tries", 10, 10); backoff = (int)login_getcapnum(lc, "login-backoff", 3, 3); } while ((ch = getopt(argc, argv, "a:npt:")) != -1) { switch (ch) { case 'a': if (lc) { style = login_getstyle(lc, optarg, "auth-lock"); if (style == NULL) errx(1, "invalid authentication style: %s", optarg); } usemine = 1; break; case 't': sectimeout = (int)strtonum(optarg, 1, INT_MAX, &errstr); if (errstr) errx(1, "timeout %s: %s", errstr, optarg); break; case 'p': usemine = 1; break; case 'n': no_timeout = 1; break; default: (void)fprintf(stderr, "usage: %s [-np] [-a style] [-t timeout]\n", __progname); exit(1); } } timeout.tv_sec = sectimeout * 60; gethostname(hostname, sizeof(hostname)); if (usemine && lc == NULL) errx(1, "login class not found"); if (!(ttynam = ttyname(STDIN_FILENO))) errx(1, "not a terminal?"); curtime = time(NULL); nexttime = curtime + (sectimeout * 60); timp = localtime(&curtime); strftime(date, sizeof(date), "%c", timp); if (!usemine) { /* get key and check again */ if (!readpassphrase("Key: ", s, sizeof(s), RPP_ECHO_OFF) || *s == '\0') exit(0); /* * Don't need EOF test here, if we get EOF, then s1 != s * and the right things will happen. */ (void)readpassphrase("Again: ", s1, sizeof(s1), RPP_ECHO_OFF); if (strcmp(s1, s)) { warnx("\apasswords didn't match."); exit(1); } s[0] = '\0'; } /* set signal handlers */ (void)signal(SIGINT, hi); (void)signal(SIGQUIT, hi); (void)signal(SIGTSTP, hi); (void)signal(SIGALRM, bye); ntimer.it_interval = zerotime; ntimer.it_value = timeout; if (!no_timeout) setitimer(ITIMER_REAL, &ntimer, &otimer); /* header info */ if (no_timeout) { (void)fprintf(stderr, "%s: %s on %s. no timeout\ntime now is %s\n", __progname, ttynam, hostname, date); } else { (void)fprintf(stderr, "%s: %s on %s. timeout in %d minutes\ntime now is %s\n", __progname, ttynam, hostname, sectimeout, date); } for (cnt = 0;;) { if (!readpassphrase("Key: ", s, sizeof(s), RPP_ECHO_OFF) || *s == '\0') { hi(0); continue; } if (usemine) { /* * If user entered 's/key' or the style specified via * the '-a' argument, auth_userokay() will prompt * for a new password. Otherwise, use what we have. */ if ((strcmp(s, "s/key") == 0 && (nstyle = login_getstyle(lc, "skey", "auth-lock"))) || ((nstyle = style) && strcmp(s, nstyle) == 0)) p = NULL; else p = s; if (auth_userokay(pw->pw_name, nstyle, "auth-lock", p)) break; } else if (strcmp(s, s1) == 0) break; (void)putc('\a', stderr); cnt %= tries; if (++cnt > backoff) { sigset_t set, oset; sigfillset(&set); sigprocmask(SIG_BLOCK, &set, &oset); sleep((u_int)((cnt - backoff) * tries / 2)); sigprocmask(SIG_SETMASK, &oset, NULL); } } exit(0); }
pid_t forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws) { int slave = -1, fd, pipe_fd[2]; char *path, dummy; pid_t pid; if (pipe(pipe_fd) == -1) return (-1); if ((*master = open("/dev/ptc", O_RDWR|O_NOCTTY)) == -1) goto out; if ((path = ttyname(*master)) == NULL) goto out; if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1) goto out; switch (pid = fork()) { case -1: goto out; case 0: close(*master); close(pipe_fd[1]); while (read(pipe_fd[0], &dummy, 1) == -1) { if (errno != EINTR) break; } close(pipe_fd[0]); fd = open(_PATH_TTY, O_RDWR|O_NOCTTY); if (fd >= 0) { ioctl(fd, TIOCNOTTY, NULL); close(fd); } if (setsid() < 0) fatal("setsid"); fd = open(_PATH_TTY, O_RDWR|O_NOCTTY); if (fd >= 0) fatalx("open succeeded (failed to disconnect)"); fd = open(path, O_RDWR); if (fd < 0) fatal("open failed"); close(fd); fd = open("/dev/tty", O_WRONLY); if (fd < 0) fatal("open failed"); close(fd); if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1) fatal("tcsetattr failed"); if (ioctl(slave, TIOCSWINSZ, ws) == -1) fatal("ioctl failed"); dup2(slave, 0); dup2(slave, 1); dup2(slave, 2); if (slave > 2) close(slave); return (0); } close(slave); close(pipe_fd[0]); close(pipe_fd[1]); return (pid); out: if (*master != -1) close(*master); if (slave != -1) close(slave); close(pipe_fd[0]); close(pipe_fd[1]); return (-1); }
int main(int argc, char *argv[]) { int client_sock = -1; int client_name_len = sizeof (client_name); int request=0; struct nunetwork_headerstruct *header_buf; header_buf = (struct nunetwork_headerstruct*)malloc( sizeof(*header_buf) ); /******************** * Don't forget to make pointer to variable cast (*pointer) * When using sizeof(). Otherwise it may cost you a week of * debug time. *******************/ if (geteuid()) { printf("Netustad must be run as root.\n"); exit(1); } conffile = (char *)strdup(default_conf_file); /*setlocale (LC_ALL, "");*/ bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR); textdomain ( PACKAGE ); /*******************/ /* Check Arguments */ /*******************/ if (argc==2) { if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { printf( gettext("\nnetUstad: Network Ustadi (Network Master)\n")); printf( gettext("Copyright (C) 2004 by Ozkan KIRIK\n")); printf( gettext("Usage: netustad [options]\n")); printf( gettext("\n")); printf( "%s:\n", gettext("Options")); printf( gettext("\t-h\tShow this help screen\n")); printf( gettext("\t-v\tShow version\n")); printf (gettext("\t-c\tUse following parameter as configuration file")); printf("\n"); exit(0); } else if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) { printf(gettext("\nnetUstad: Network Ustadi (Network Master)\n")); printf(gettext("Copyright (C) 2004 by Ozkan KIRIK\n\n")); printf(gettext("Version: %s\n\n"), NUVERSION); exit(0); } } else if (argc == 3 && strcmp(argv[1], "-c") == 0) { conffile = strdup(argv[2]); } else if (argc!=1) { if (strcmp(argv[1], "-c") == 0) { printf (gettext("\nnetUstad: Invalid Number Of Arguments\n\n")); } else { printf(gettext("\nnetUstad: Invalid Argument\n\n")); } exit(1); } /**********************/ /* Start Main Program */ /**********************/ readconfig(conffile); if (setlocale (LC_ALL, (const char*) lc_all) == NULL) { log_msg(mainlogfile, gettext("setlocale failed\n"), 1); printf(gettext("setlocale failed\n")); } bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR); textdomain ( PACKAGE ); nameoftty = ttyname(0); daemonize(); #ifndef WITHOUT_SSL ssl = nunetwork_init_ssl( nunetwork_init_ctx( cert_file, key_file) ); #endif server_sock = startup(&port); /* Open Socket & Listen */ log_msg(mainlogfile, "<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>\n", 0); snprintf(log_msg_text, sizeof(log_msg_text)-1, "netUstad-%s\n", NUVERSION); log_msg(mainlogfile, log_msg_text, 0); snprintf(log_msg_text, sizeof (log_msg_text)-1, "%s", gettext("netUstad is started\n")); log_msg(mainlogfile, log_msg_text, 1); snprintf(log_msg_text, sizeof (log_msg_text)-1, gettext("\nListening port %d\n"), port); log_msg(mainlogfile, log_msg_text, 0); log_msg(mainlogfile, gettext("Ready for requests...\n\n"), 0); snprintf(log_msg_text, sizeof(log_msg_text)-1, "netUstad-%s\n", NUVERSION); log_msg(nameoftty, log_msg_text, 0); snprintf(log_msg_text, sizeof (log_msg_text)-1, gettext("\nnetUstad is started\nListening port %d\n"), port); log_msg(nameoftty, log_msg_text, 0); while (1) { client_sock = accept(server_sock, (struct sockaddr *) &client_name, (socklen_t *)&client_name_len); if (client_sock == -1) continue; #ifndef WITHOUT_SSL SSL_set_fd(ssl, client_sock); sslerror = SSL_accept(ssl); if ( sslerror <= 0 ) { sslerror= SSL_get_error(ssl, sslerror); ERR_error_string(sslerror, log_msg_text); log_msg(mainlogfile, log_msg_text, 1); log_msg(mainlogfile, "\n",0); SSL_shutdown(ssl); SSL_free(ssl); close(client_sock); ssl = nunetwork_init_ssl(ctx); continue; } request = nunetwork_getheaders(ssl, header_buf, nu_acceptedheaders); if (request > 0) accept_request(ssl, header_buf); else if (request==-2 || request==0) bad_request(ssl); nunetwork_close(ssl); #else request = nunetwork_getheaders(client_sock, header_buf, nu_acceptedheaders); if (request > 0) accept_request(client_sock, header_buf); else if (request==-2 || request==0 ) bad_request(ssl); nunetwork_close(client_sock); #endif } #ifndef WITHOUT_SSL SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ctx); #else close(server_sock); #endif return (0); }
const char * Shell::TTYName() const { return ttyname(fFd); }
void init_io(void) { long ttpgrp; static char outbuf[BUFSIZ], errbuf[BUFSIZ]; #ifdef RSH_BUG_WORKAROUND int i; #endif /* stdout, stderr fully buffered */ #ifdef _IOFBF setvbuf(stdout, outbuf, _IOFBF, BUFSIZ); setvbuf(stderr, errbuf, _IOFBF, BUFSIZ); #else setbuffer(stdout, outbuf, BUFSIZ); setbuffer(stderr, errbuf, BUFSIZ); #endif /* This works around a bug in some versions of in.rshd. * * Currently this is not defined by default. */ #ifdef RSH_BUG_WORKAROUND if (cmd) { for (i = 3; i < 10; i++) close(i); } #endif if (shout) { fclose(shout); shout = 0; } if (SHTTY != -1) { zclose(SHTTY); SHTTY = -1; } /* Make sure the tty is opened read/write. */ if (isatty(0)) { zsfree(ttystrname); if ((ttystrname = ztrdup(ttyname(0)))) SHTTY = movefd(open(ttystrname, O_RDWR)); } if (SHTTY == -1 && (SHTTY = movefd(open("/dev/tty", O_RDWR))) != -1) { zsfree(ttystrname); ttystrname = ztrdup("/dev/tty"); } if (SHTTY == -1) { zsfree(ttystrname); ttystrname = ztrdup(""); } /* We will only use zle if shell is interactive, * * SHTTY != -1, and shout != 0 */ if (interact && SHTTY != -1) { init_shout(); if(!shout) opts[USEZLE] = 0; } else opts[USEZLE] = 0; #ifdef JOB_CONTROL /* If interactive, make the shell the foreground process */ if (opts[MONITOR] && interact && (SHTTY != -1)) { attachtty(GETPGRP()); if ((mypgrp = GETPGRP()) > 0) { while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) { sleep(1); mypgrp = GETPGRP(); if (mypgrp == gettygrp()) break; #ifndef __EMX__ killpg(mypgrp, SIGTTIN); #endif mypgrp = GETPGRP(); } } else opts[MONITOR] = 0; } else opts[MONITOR] = 0; #else opts[MONITOR] = 0; #endif }
/** * vte_pty_child_setup: * @pty: a #VtePty * * FIXMEchpe */ void vte_pty_child_setup (VtePty *pty) { VtePtyPrivate *priv = pty->priv; VtePtyChildSetupData *data = &priv->child_setup_data; int fd = -1; const char *tty = NULL; char version[7]; if (priv->foreign) { fd = priv->pty_fd; } else { /* Save the name of the pty -- we'll need it later to acquire * it as our controlling terminal. */ switch (data->mode) { case TTY_OPEN_BY_NAME: tty = data->tty.name; break; case TTY_OPEN_BY_FD: fd = data->tty.fd; tty = ttyname(fd); break; } _vte_debug_print (VTE_DEBUG_PTY, "Setting up child pty: name = %s, fd = %d\n", tty ? tty : "(none)", fd); /* Try to reopen the pty to acquire it as our controlling terminal. */ /* FIXMEchpe: why not just use the passed fd in TTY_OPEN_BY_FD mode? */ if (tty != NULL) { int i = open(tty, O_RDWR); if (i != -1) { if (fd != -1){ close(fd); } fd = i; } } } if (fd == -1) _exit (127); /* Start a new session and become process-group leader. */ #if defined(HAVE_SETSID) && defined(HAVE_SETPGID) _vte_debug_print (VTE_DEBUG_PTY, "Starting new session\n"); setsid(); setpgid(0, 0); #endif #ifdef TIOCSCTTY /* TIOCSCTTY is defined? Let's try that, too. */ ioctl(fd, TIOCSCTTY, fd); #endif #ifdef HAVE_STROPTS_H if (isastream (fd) == 1) { if ((ioctl(fd, I_FIND, "ptem") == 0) && (ioctl(fd, I_PUSH, "ptem") == -1)) { _exit (127); } if ((ioctl(fd, I_FIND, "ldterm") == 0) && (ioctl(fd, I_PUSH, "ldterm") == -1)) { _exit (127); } if ((ioctl(fd, I_FIND, "ttcompat") == 0) && (ioctl(fd, I_PUSH, "ttcompat") == -1)) { perror ("ioctl (fd, I_PUSH, \"ttcompat\")"); _exit (127); } } #endif /* now setup child I/O through the tty */ if (fd != STDIN_FILENO) { if (dup2(fd, STDIN_FILENO) != STDIN_FILENO){ _exit (127); } } if (fd != STDOUT_FILENO) { if (dup2(fd, STDOUT_FILENO) != STDOUT_FILENO){ _exit (127); } } if (fd != STDERR_FILENO) { if (dup2(fd, STDERR_FILENO) != STDERR_FILENO){ _exit (127); } } /* Close the original slave descriptor, unless it's one of the stdio * descriptors. */ if (fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO) { close(fd); } /* Reset our signals -- our parent may have done any number of * weird things to them. */ _vte_pty_reset_signal_handlers(); /* Now set the TERM environment variable */ /* FIXME: Setting environment here seems to have no effect, the merged envp2 will override on exec. * By the way, we'd need to set the one from there, if any. */ g_setenv("TERM", VTE_DEFAULT_TERM, TRUE); g_snprintf (version, sizeof (version), "%u", VTE_VERSION_NUMERIC); g_setenv ("VTE_VERSION", version, TRUE); /* Finally call an extra child setup */ if (data->extra_child_setup) { data->extra_child_setup (data->extra_child_setup_data); } }
int main(int argc, char **argv) { static struct option long_options[] = { {"pidfile\0\tSet pid file name", required_argument, NULL, 'p'}, {"foreground\0\t\tDon't fork into background", no_argument, NULL, 'f'}, {"chroot\0\t\tChroot to directory", required_argument, NULL, 'C'}, {"prompt-prog\0Program to execute for user prompt", required_argument, NULL, 'R'}, {"version\0\t\t\tShow version information", no_argument, NULL, 'V'}, {"channel\0\tCommunications channel (netlink or miscdev)", required_argument, NULL, 'd'}, {"help\0\t\t\tShow usage information", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; static char *short_options = "p:fC:R:Vd:h"; int long_options_ret; struct rlimit core = {0, 0}; int foreground = 0; char *chrootdir = NULL; char *tty = NULL; uint32_t channel_type = ECRYPTFS_DEFAULT_MESSAGING_TYPE; int messaging_type_specified = 0; int rc = 0; while ((long_options_ret = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch (long_options_ret) { case 'p': pidfile = strdup(optarg); break; case 'f': foreground = 1; break; case 'C': chrootdir = strdup(optarg); break; case 'R': prompt_prog = strdup(optarg); break; case 'V': printf(("%s (%s) %s\n" "\n" "This is free software. You may " "redistribute copies of it under the " "terms of\n" "the GNU General Public License " "<http://www.gnu.org/licenses/" "gpl.html>.\n" "There is NO WARRANTY, to the extent " "permitted by law.\n"), basename(argv[0]), PACKAGE_NAME, PACKAGE_VERSION); exit(0); break; case 'd': messaging_type_specified = 1; if (strcmp(optarg, "netlink") == 0) channel_type = ECRYPTFS_MESSAGING_TYPE_NETLINK; else if (strcmp(optarg, "miscdev") == 0) channel_type = ECRYPTFS_MESSAGING_TYPE_MISCDEV; break; case 'h': default: usage(basename(argv[0]), long_options, short_options); exit(1); break; } } openlog(argv[0], LOG_PID | (foreground ? LOG_PERROR : 0), 0); if (!messaging_type_specified) { uint32_t version; rc = ecryptfs_get_version(&version); if (rc) { syslog(LOG_WARNING, "%s: Unable to retrieve versioning " "info from kernel module; falling back on " "default values\n", __FUNCTION__); } else { if (version & ECRYPTFS_VERSIONING_MISCDEV) channel_type = ECRYPTFS_MESSAGING_TYPE_MISCDEV; else channel_type = ECRYPTFS_MESSAGING_TYPE_NETLINK; } } tty = ttyname(0); /* We may need the tty name later */ if (tty != NULL) setenv ("TERM_DEVICE", tty, 0); if (!foreground) daemonize(); /* This will exit if cannot be completed */ /* Disallow core file; secret values may be in it */ if (setrlimit(RLIMIT_CORE, &core) == -1) { rc = -errno; syslog(LOG_ERR, "Cannot setrlimit: %m"); goto daemon_out; } if (chrootdir != NULL) { if (chroot(chrootdir) == -1) { rc = -errno; syslog(LOG_ERR, "Failed to chroot to '%s': %m\n", chrootdir); goto daemon_out; } free(chrootdir); chrootdir = NULL; } if (pidfile != NULL) { FILE *fp = fopen(pidfile, "w"); if (fp == NULL) { rc = -errno; syslog(LOG_ERR, "Failed to open pid file '%s': %m\n", pidfile); goto daemon_out; } fprintf(fp, "%d", (int)getpid()); fclose(fp); } if (signal(SIGTERM, sigterm_handler) == SIG_ERR) { rc = -ENOTSUP; syslog(LOG_ERR, "Failed to attach handler to SIGTERM"); goto daemon_out; } if (signal(SIGINT, sigterm_handler) == SIG_ERR) { rc = -ENOTSUP; syslog(LOG_ERR, "Failed to attach handler to SIGINT"); goto daemon_out; } cryptfs_get_ctx_opts()->prompt = prompt_callback; pthread_mutex_init(&mctx_mux, NULL); pthread_mutex_lock(&mctx_mux); rc = ecryptfs_init_messaging(&mctx, channel_type); if (rc) { syslog(LOG_ERR, "%s: Failed to initialize messaging; rc = " "[%d]\n", __FUNCTION__, rc); pthread_mutex_unlock(&mctx_mux); goto daemon_out; } rc = ecryptfs_send_message(&mctx, NULL, ECRYPTFS_MSG_HELO, 0, 0); if (rc) { syslog(LOG_ERR, "%s: Error attempting to send message to " "eCryptfs kernel module via transport of type " "[0x%.8x]; rc = [%d]\n", __FUNCTION__, mctx.type, rc); pthread_mutex_unlock(&mctx_mux); goto daemon_out; } mctx.state |= ECRYPTFS_MESSAGING_STATE_LISTENING; pthread_mutex_unlock(&mctx_mux); rc = ecryptfs_run_daemon(&mctx); pthread_mutex_lock(&mctx_mux); mctx.state &= ~ECRYPTFS_MESSAGING_STATE_LISTENING; pthread_mutex_unlock(&mctx_mux); daemon_out: ecryptfsd_exit(&mctx, rc); return rc; }
long ptyint_getpty_ext(int *fd, char *slave, int slavelength, int do_grantpt) { #if !defined(HAVE__GETPTY) && !defined(HAVE_OPENPTY) char *cp; char *p; int i,ptynum; struct stat stb; char slavebuf[1024]; #endif #ifdef HAVE__GETPTY char *slaveret; /*Temporary to hold pointer to slave*/ #endif /*HAVE__GETPTY*/ #ifdef HAVE_OPENPTY int slavefd; if(openpty(fd, &slavefd, slave, (struct termios *) 0, (struct winsize *) 0)) return 1; close(slavefd); return 0; #else /*HAVE_OPENPTY*/ #ifdef HAVE__GETPTY /* This code is included for Irix; as of version 5.3, Irix has /dev/ptmx, * but it fails to work properly; even after calling unlockpt, * root gets permission denied opening the pty. * The code to support _getpty should be removed if Irix gets working * streams ptys in favor of maintaining the least needed code * paths. */ if ((slaveret = _getpty(fd, O_RDWR|O_NDELAY, 0600, 0)) == 0) { *fd = -1; return PTY_GETPTY_NOPTY; } if (strlen(slaveret) > slavelength - 1) { close(*fd); *fd = -1; return PTY_GETPTY_SLAVE_TOOLONG; } else strcpy(slave, slaveret); return 0; #else /*HAVE__GETPTY*/ *fd = open("/dev/ptym/clone", O_RDWR|O_NDELAY); /* HPUX*/ #ifdef HAVE_STREAMS if (*fd < 0) *fd = open("/dev/ptmx",O_RDWR|O_NDELAY); /*Solaris*/ #endif if (*fd < 0) *fd = open("/dev/ptc", O_RDWR|O_NDELAY); /* AIX */ if (*fd < 0) *fd = open("/dev/pty", O_RDWR|O_NDELAY); /* sysvimp */ if (*fd >= 0) { #if defined(HAVE_GRANTPT)&&defined(HAVE_STREAMS) if (do_grantpt) if (grantpt(*fd) || unlockpt(*fd)) return PTY_GETPTY_STREAMS; #endif #ifdef HAVE_PTSNAME p = ptsname(*fd); #else #ifdef HAVE_TTYNAME p = ttyname(*fd); #else /* XXX If we don't have either what do we do */ #endif #endif if (p) { if (strlen(p) > slavelength - 1) { close (*fd); *fd = -1; return PTY_GETPTY_SLAVE_TOOLONG; } strcpy(slave, p); return 0; } if (fstat(*fd, &stb) < 0) { close(*fd); return PTY_GETPTY_FSTAT; } ptynum = (int)(stb.st_rdev&0xFF); sprintf(slavebuf, "/dev/ttyp%x", ptynum); if (strlen(slavebuf) > slavelength - 1) { close(*fd); *fd = -1; return PTY_GETPTY_SLAVE_TOOLONG; } strncpy(slave, slavebuf, slavelength); return 0; } else { for (cp = "pqrstuvwxyzPQRST";*cp; cp++) { sprintf(slavebuf,"/dev/ptyXX"); slavebuf[sizeof("/dev/pty") - 1] = *cp; slavebuf[sizeof("/dev/ptyp") - 1] = '0'; if (stat(slavebuf, &stb) < 0) break; for (i = 0; i < 16; i++) { slavebuf[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i]; *fd = open(slavebuf, O_RDWR); if (*fd < 0) continue; /* got pty */ slavebuf[sizeof("/dev/") - 1] = 't'; if (strlen(slavebuf) > slavelength -1) { close(*fd); *fd = -1; return PTY_GETPTY_SLAVE_TOOLONG; } strncpy(slave, slavebuf, slavelength); return 0; } } return PTY_GETPTY_NOPTY; } #endif /*HAVE__GETPTY*/ #endif /* HAVE_OPENPTY */ }
int ft_trmgetout(void) { if (g_trm_stdout <= 0) g_trm_stdout = open(ttyname(0), O_WRONLY | O_APPEND | O_CREAT); return (g_trm_stdout); }
void makemsg(char *fname) { int cnt; wchar_t ch; struct tm *lt; struct passwd *pw; struct stat sbuf; time_t now; FILE *fp; int fd; char hostname[MAXHOSTNAMELEN], tmpname[64]; wchar_t *p, *tmp, lbuf[256], codebuf[13]; const char *tty; const char *whom; gid_t egid; (void)snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP); if ((fd = mkstemp(tmpname)) == -1 || !(fp = fdopen(fd, "r+"))) err(1, "can't open temporary file"); (void)unlink(tmpname); if (!nobanner) { tty = ttyname(STDERR_FILENO); if (tty == NULL) tty = "no tty"; if (!(whom = getlogin())) whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???"; (void)gethostname(hostname, sizeof(hostname)); (void)time(&now); lt = localtime(&now); /* * all this stuff is to blank out a square for the message; * we wrap message lines at column 79, not 80, because some * terminals wrap after 79, some do not, and we can't tell. * Which means that we may leave a non-blank character * in column 80, but that can't be helped. */ (void)fwprintf(fp, L"\r%79s\r\n", " "); (void)swprintf(lbuf, sizeof(lbuf)/sizeof(wchar_t), L"Broadcast Message from %s@%s", whom, hostname); (void)fwprintf(fp, L"%-79.79S\007\007\r\n", lbuf); (void)swprintf(lbuf, sizeof(lbuf)/sizeof(wchar_t), L" (%s) at %d:%02d %s...", tty, lt->tm_hour, lt->tm_min, lt->tm_zone); (void)fwprintf(fp, L"%-79.79S\r\n", lbuf); } (void)fwprintf(fp, L"%79s\r\n", " "); if (fname) { egid = getegid(); setegid(getgid()); if (freopen(fname, "r", stdin) == NULL) err(1, "can't read %s", fname); if (setegid(egid) != 0) err(1, "setegid failed"); } cnt = 0; while (fgetws(lbuf, sizeof(lbuf)/sizeof(wchar_t), stdin)) { for (p = lbuf; (ch = *p) != L'\0'; ++p, ++cnt) { if (ch == L'\r') { putwc(L'\r', fp); cnt = 0; continue; } else if (ch == L'\n') { for (; cnt < 79; ++cnt) putwc(L' ', fp); putwc(L'\r', fp); putwc(L'\n', fp); break; } if (cnt == 79) { putwc(L'\r', fp); putwc(L'\n', fp); cnt = 0; } if (iswprint(ch) || iswspace(ch) || ch == L'\a' || ch == L'\b') { putwc(ch, fp); } else { (void)swprintf(codebuf, sizeof(codebuf)/sizeof(wchar_t), L"<0x%X>", ch); for (tmp = codebuf; *tmp != L'\0'; ++tmp) { putwc(*tmp, fp); if (++cnt == 79) { putwc(L'\r', fp); putwc(L'\n', fp); cnt = 0; } } --cnt; } } } (void)fwprintf(fp, L"%79s\r\n", " "); rewind(fp); if (fstat(fd, &sbuf)) err(1, "can't stat temporary file"); mbufsize = sbuf.st_size; if (!(mbuf = malloc((u_int)mbufsize))) err(1, "out of memory"); if ((int)fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) err(1, "can't read temporary file"); (void)close(fd); }
int main(int argc, char* argv[]) { int retval; const char *user, *tty; char hostname[128]; const char *temp=NULL; pam_handle_t *pamh=NULL; do { if (argc > 1) user=argv[1]; else user=getlogin(); if ((retval = pam_start(basename(argv[0]), user, &conv, &pamh)) != PAM_SUCCESS) break; gethostname(hostname, sizeof(hostname)); if ((retval = pam_set_item(pamh, PAM_RHOST, hostname)) != PAM_SUCCESS) break; tty = ttyname(STDERR_FILENO); if ((retval = pam_set_item(pamh, PAM_TTY, tty)) != PAM_SUCCESS) break; /* authenticate the applicant */ if ((retval = pam_authenticate(pamh, 0)) != PAM_SUCCESS) break; if ((retval = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS) { if (retval == PAM_NEW_AUTHTOK_REQD) retval = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); else break; } /* establish the requested credentials */ if ((retval = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) break; /* authentication succeeded; open a session */ if ((retval = pam_open_session(pamh, 0)) != PAM_SUCCESS) break; printf("Authenticate ok\n"); pam_get_item(pamh, PAM_SERVICE, (const void **)&temp); printf(" service %s\n", temp); pam_get_item(pamh, PAM_USER, (const void **)&temp); printf(" user %s\n", temp); pam_get_item(pamh, PAM_AUTHTOK, (const void **)&temp); printf(" password %s\n", temp); }while (0); if (retval != PAM_SUCCESS) { printf("Authenticate failed: %s\n", pam_strerror(pamh,retval)); } else { pam_close_session(pamh,0); } pam_end(pamh,retval); return retval == PAM_SUCCESS ? 0:1; }
struct device * i4b_Create(struct physical *p) { struct i4bdevice *dev; int oldflag, dial; msg_vr_req_t req; telno_t number; if (p->fd < 0 || ioctl(p->fd, I4B_RBCH_VR_REQ, &req)) /* Don't want this */ return NULL; /* * We don't bother validating the version.... all versions of i4b that * support I4B_RBCH_VR_REQ are fair game :-) */ if (*p->name.full == '\0') { physical_SetDevice(p, ttyname(p->fd)); log_Printf(LogDEBUG, "%s: Input is an i4b version %d.%d.%d isdn " "device (%s)\n", p->link.name, req.version, req.release, req.step, p->name.full); dial = 0; } else { log_Printf(LogDEBUG, "%s: Opened %s (i4b version %d.%d.%d)\n", p->link.name, p->name.full, req.version, req.release, req.step); dial = 1; } /* We're gonna return an i4bdevice (unless something goes horribly wrong) */ if ((dev = malloc(sizeof *dev)) == NULL) { /* Complete failure - parent doesn't continue trying to ``create'' */ close(p->fd); p->fd = -1; return NULL; } memcpy(&dev->dev, &basei4bdevice, sizeof dev->dev); memset(&dev->Timer, '\0', sizeof dev->Timer); dev->mbits = -1; switch (p->cfg.cd.necessity) { case CD_VARIABLE: dev->dev.cd.delay = p->cfg.cd.delay; break; case CD_REQUIRED: dev->dev.cd = p->cfg.cd; break; case CD_NOTREQUIRED: log_Printf(LogWARN, "%s: Carrier must be set, using ``set cd %d!''\n", p->link.name, dev->dev.cd.delay); case CD_DEFAULT: break; } oldflag = fcntl(p->fd, F_GETFL, 0); if (oldflag < 0) { /* Complete failure - parent doesn't continue trying to ``create'' */ log_Printf(LogWARN, "%s: Open: Cannot get physical flags: %s\n", p->link.name, strerror(errno)); i4b_Cooked(p); close(p->fd); p->fd = -1; free(dev); return NULL; } else fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK); if (dial) { strncpy(number, datalink_ChoosePhoneNumber(p->dl), sizeof number - 1); number[sizeof number - 1] = '\0'; if (number[0] == '\0') dial = 0; } if (dial && ioctl(p->fd, I4B_RBCH_DIALOUT, number) == -1) { /* Complete failure - parent doesn't continue trying to ``create'' */ log_Printf(LogWARN, "%s: ioctl(I4B_RBCH_DIALOUT): %s\n", p->link.name, strerror(errno)); i4b_Cooked(p); close(p->fd); p->fd = -1; free(dev); return NULL; } physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNC); return &dev->dev; }
int main(int argc, char *argv[]) { struct utmpx ut; char *devName; if (argc < 2 || strcmp(argv[1], "--help") == 0) usageErr("%s username [sleep-time]\n", argv[0]); /* Initialize login record for utmp and wtmp files */ memset(&ut, 0, sizeof(struct utmpx)); ut.ut_type = USER_PROCESS; /* This is a user login */ strncpy(ut.ut_user, argv[1], sizeof(ut.ut_user)); if (time((time_t *) &ut.ut_tv.tv_sec) == -1) errExit("time"); /* Stamp with current time */ ut.ut_pid = getpid(); /* Set ut_line and ut_id based on the terminal associated with 'stdin'. This code assumes terminals named "/dev/[pt]t[sy]*". The "/dev/" dirname is 5 characters; the "[pt]t[sy]" filename prefix is 3 characters (making 8 characters in all). */ devName = ttyname(STDIN_FILENO); if (devName == NULL) errExit("ttyname"); if (strlen(devName) <= 8) /* Should never happen */ fatal("Terminal name is too short: %s", devName); strncpy(ut.ut_line, devName + 5, sizeof(ut.ut_line)); strncpy(ut.ut_id, devName + 8, sizeof(ut.ut_id)); printf("Creating login entries in utmp and wtmp\n"); printf(" using pid %ld, line %.*s, id %.*s\n", (long) ut.ut_pid, (int) sizeof(ut.ut_line), ut.ut_line, (int) sizeof(ut.ut_id), ut.ut_id); setutxent(); /* Rewind to start of utmp file */ if (pututxline(&ut) == NULL) /* Write login record to utmp */ errExit("pututxline"); updwtmpx(_PATH_WTMP, &ut); /* Append login record to wtmp */ /* Sleep a while, so we can examine utmp and wtmp files */ sleep((argc > 2) ? getInt(argv[2], GN_NONNEG, "sleep-time") : 15); /* Now do a "logout"; use values from previously initialized 'ut', except for changes below */ ut.ut_type = DEAD_PROCESS; /* Required for logout record */ time((time_t *) &ut.ut_tv.tv_sec); /* Stamp with logout time */ memset(&ut.ut_user, 0, sizeof(ut.ut_user)); /* Logout record has null username */ printf("Creating logout entries in utmp and wtmp\n"); setutxent(); /* Rewind to start of utmp file */ if (pututxline(&ut) == NULL) /* Overwrite previous utmp record */ errExit("pututxline"); updwtmpx(_PATH_WTMP, &ut); /* Append logout record to wtmp */ endutxent(); exit(EXIT_SUCCESS); }
int pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) { #if defined(HAVE_OPENPTY) || defined(BSD4_4) /* openpty(3) exists in OSF/1 and some other os'es */ char *name; int i; i = openpty(ptyfd, ttyfd, NULL, NULL, NULL); if (i < 0) { error("openpty: %.100s", strerror(errno)); return 0; } name = ttyname(*ttyfd); if (!name) fatal("openpty returns device for which ttyname fails."); strlcpy(namebuf, name, namebuflen); /* possible truncation */ return 1; #else /* HAVE_OPENPTY */ #ifdef HAVE__GETPTY /* * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more * pty's automagically when needed */ char *slave; slave = _getpty(ptyfd, O_RDWR, 0622, 0); if (slave == NULL) { error("_getpty: %.100s", strerror(errno)); return 0; } strlcpy(namebuf, slave, namebuflen); /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { error("%.200s: %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; } return 1; #else /* HAVE__GETPTY */ #if defined(HAVE_DEV_PTMX) /* * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 * also has bsd-style ptys, but they simply do not work.) */ int ptm; char *pts; mysig_t old_signal; ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); if (ptm < 0) { error("/dev/ptmx: %.100s", strerror(errno)); return 0; } old_signal = mysignal(SIGCHLD, SIG_DFL); if (grantpt(ptm) < 0) { error("grantpt: %.100s", strerror(errno)); return 0; } mysignal(SIGCHLD, old_signal); if (unlockpt(ptm) < 0) { error("unlockpt: %.100s", strerror(errno)); return 0; } pts = ptsname(ptm); if (pts == NULL) error("Slave pty side name could not be obtained."); strlcpy(namebuf, pts, namebuflen); *ptyfd = ptm; /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { error("%.100s: %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; } #ifndef HAVE_CYGWIN /* * Push the appropriate streams modules, as described in Solaris pts(7). * HP-UX pts(7) doesn't have ttcompat module. */ if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) error("ioctl I_PUSH ptem: %.100s", strerror(errno)); if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) error("ioctl I_PUSH ldterm: %.100s", strerror(errno)); #ifndef __hpux if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); #endif #endif return 1; #else /* HAVE_DEV_PTMX */ #ifdef HAVE_DEV_PTS_AND_PTC /* AIX-style pty code. */ const char *name; *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); if (*ptyfd < 0) { error("Could not open /dev/ptc: %.100s", strerror(errno)); return 0; } name = ttyname(*ptyfd); if (!name) fatal("Open of /dev/ptc returns device for which ttyname fails."); strlcpy(namebuf, name, namebuflen); *ttyfd = open(name, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { error("Could not open pty slave side %.100s: %.100s", name, strerror(errno)); close(*ptyfd); return 0; } return 1; #else /* HAVE_DEV_PTS_AND_PTC */ #ifdef _UNICOS char buf[64]; int i; int highpty; #ifdef _SC_CRAY_NPTY highpty = sysconf(_SC_CRAY_NPTY); if (highpty == -1) highpty = 128; #else highpty = 128; #endif for (i = 0; i < highpty; i++) { snprintf(buf, sizeof(buf), "/dev/pty/%03d", i); *ptyfd = open(buf, O_RDWR|O_NOCTTY); if (*ptyfd < 0) continue; snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i); /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR|O_NOCTTY); if (*ttyfd < 0) { error("%.100s: %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; } return 1; } return 0; #else /* BSD-style pty code. */ char buf[64]; int i; const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *ptyminors = "0123456789abcdef"; int num_minors = strlen(ptyminors); int num_ptys = strlen(ptymajors) * num_minors; struct termios tio; for (i = 0; i < num_ptys; i++) { snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); snprintf(namebuf, namebuflen, "/dev/tty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd < 0) { /* Try SCO style naming */ snprintf(buf, sizeof buf, "/dev/ptyp%d", i); snprintf(namebuf, namebuflen, "/dev/ttyp%d", i); *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd < 0) continue; } /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { error("%.100s: %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; } /* set tty modes to a sane state for broken clients */ if (tcgetattr(*ptyfd, &tio) < 0) log("Getting tty modes for pty failed: %.100s", strerror(errno)); else { tio.c_lflag |= (ECHO | ISIG | ICANON); tio.c_oflag |= (OPOST | ONLCR); tio.c_iflag |= ICRNL; /* Set the new modes for the terminal. */ if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) log("Setting tty modes for pty failed: %.100s", strerror(errno)); } return 1; } return 0; #endif /* CRAY */ #endif /* HAVE_DEV_PTS_AND_PTC */ #endif /* HAVE_DEV_PTMX */ #endif /* HAVE__GETPTY */ #endif /* HAVE_OPENPTY */ }
QgsGrassShell::QgsGrassShell( QgsGrassTools *tools, QTabWidget * parent, const char * name ): QDialog( parent ), QgsGrassShellBase(), mTools( tools ) { mValid = false; mSkipLines = 2; mTabWidget = parent; #ifdef WIN32 QMessageBox::warning( 0, "Warning", "GRASS Shell is not supported on Windows." ); return; #else setupUi( this ); QGridLayout *layout = new QGridLayout( mTextFrame, 1, 1 ); mText = new QgsGrassShellText( this, mTextFrame ); layout->addWidget( mText, 0, 0 ); mText->show(); connect( mCloseButton, SIGNAL( clicked() ), this, SLOT( closeShell() ) ); mFont = QFont( "Courier", 10 ); mAppDir = mTools->appDir(); #ifndef Q_WS_MAC // Qt4.3.2/Mac Q3TextEdit readOnly property causes keys to be processed as keyboard actions mText->setReadOnly( TRUE ); #endif //mText->setFocusPolicy ( QWidget::NoFocus ); // To get key press directly #ifndef HAVE_OPENPTY mText->append( "GRASS shell is not supported" ); return; #endif // TODO set cursor IbeamCursor // This does not work - the cursor is used for scrollbars -> disabled //mText->setCursor ( QCursor(Qt::IbeamCursor) ); mParagraph = -1; // first will be 0 mIndex = -1; mNewLine = true; for ( int i = 0; i < ModeCount; i++ ) { resetMode( i ); } int uid; seteuid( uid = getuid() ); /* Run unprivileged */ // Get and open pseudo terminal // Note: 0 (stdin), 1 (stdout) or 2 (stderr) int fdSlave; // slave file descriptor seteuid( 0 ); int ret = openpty( &mFdMaster, &fdSlave, NULL, NULL, NULL ); if ( ret != 0 ) { QMessageBox::warning( 0, "Warning", "Cannot open pseudo terminal" ); return; } fchown( fdSlave, uid, ( gid_t ) - 1 ); fchmod( fdSlave, S_IRUSR | S_IWUSR ); seteuid( uid ); QgsDebugMsg( QString( "mFdMaster = %1" ).arg( mFdMaster ) ); QgsDebugMsg( QString( "fdSlave = %1" ).arg( fdSlave ) ); fcntl( mFdMaster, F_SETFL, O_NDELAY ); //fcntl( fdSlave, F_SETFL, O_NDELAY); // enable? QString slaveName = ttyname( fdSlave ); QgsDebugMsg( QString( "master ttyname = %1" ).arg( ttyname( mFdMaster ) ) ); QgsDebugMsg( QString( "slave ttyname = %1" ).arg( ttyname( fdSlave ) ) ); //::close( fdSlave ); // -> crash // Fork slave and open shell int pid = fork(); QgsDebugMsg( QString( "pid = %1" ).arg( pid ) ); if ( pid == -1 ) { QMessageBox::warning( 0, "Warning", "Cannot fork shell" ); return; } // Child - slave if ( pid == 0 ) { QgsDebugMsg( "child ->" ); // TODO close all opened file descriptors - close(0)??? ::close( mFdMaster ); //::close( fdSlave ); // -> freeze setsid(); seteuid( 0 ); int fd = ::open(( char* ) slaveName.ascii(), O_RDWR ); if ( fd < 0 ) { QMessageBox::warning( 0, "Warning", "Cannot open slave file " "in child process" ); return; } fchown( fd, uid, ( gid_t ) - 1 ); fchmod( fd, S_IRUSR | S_IWUSR ); setuid( uid ); dup2( fd, 0 ); /* stdin */ dup2( fd, 1 ); /* stdout */ dup2( fd, 2 ); /* stderr */ // TODO: test if shell is available QString shell = ( getenv( "SHELL" ) ); if ( shell.isEmpty() ) { shell = "/bin/bash"; } const char *norc = ""; QFileInfo si( shell ); if ( si.fileName() == "bash" || si.fileName() == "sh" ) { norc = "--norc"; } else if ( si.fileName() == "tcsh" || si.fileName() == "csh" ) { norc = "-f"; } // Warning: execle + --norc will not inherit not given variables // -> overwrite here const char *env = "GRASS_MESSAGE_FORMAT=gui"; char *envstr = new char[strlen( env )+1]; strcpy( envstr, env ); putenv( envstr ); putenv(( char * ) "GISRC_MODE_MEMORY" ); // unset env = "PS1=GRASS > "; envstr = new char[strlen( env )+1]; strcpy( envstr, env ); putenv( envstr ); env = "TERM=vt100"; envstr = new char[strlen( env )+1]; strcpy( envstr, env ); putenv( envstr ); //char *envar[] = { "PS1=GRASS > ", "TERM=vt100", "GISRC_MODE_MEMORY=", // "GRASS_MESSAGE_FORMAT=gui", (char *)0 }; //execle ( (char*)shell.ascii(), (char *)si.fileName().ascii(), // norc, (char *) 0, envar); execl(( char* )shell.ascii(), ( char * )si.fileName().ascii(), norc, ( char * ) 0 ); // Failed (QMessageBox here does not work) fprintf( stderr, "GRASS_INFO_ERROR(1,1): Cannot start shell %s\n", ( char* )shell.ascii() ); exit( 1 ); } mPid = pid; // Create socket notifier mOutNotifier = new QSocketNotifier( mFdMaster, QSocketNotifier::Read, this ); QObject::connect( mOutNotifier, SIGNAL( activated( int ) ), this, SLOT( readStdout( int ) ) ); // Set tab stops ??? mTabStop.resize( 200 ); for ( int i = 0 ; i * 8 < ( int )mTabStop.size(); i++ ) { mTabStop[i*8] = true; } // Set trap to write history on SIGUSR1 //QString trap = "trap 'history -w' SIGUSR1\015\012"; QString trap = "trap 'history -w' SIGUSR1\015"; write( mFdMaster, trap.ascii(), trap.length() ); mText->clear(); resizeTerminal(); mValid = true; #endif // !WIN32 }
int cray_setup (uid_t uid, char *username, const char *command) { extern struct udb *getudb(); extern char *setlimits(); int err; /* error return */ time_t system_time; /* current system clock */ time_t expiration_time; /* password expiration time */ int maxattempts; /* maximum no. of failed login attempts */ int SecureSys; /* unicos security flag */ int minslevel = 0; /* system minimum security level */ int i, j; int valid_acct = -1; /* flag for reading valid acct */ char acct_name[MAXACID] = { "" }; /* used to read acct name */ struct jtab jtab; /* Job table struct */ struct udb ue; /* udb entry for logging-in user */ struct udb *up; /* pointer to UDB entry */ struct secstat secinfo; /* file security attributes */ struct servprov init_info; /* used for sesscntl() call */ int jid; /* job ID */ int pid; /* process ID */ char *sr; /* status return from setlimits() */ char *ttyn = NULL; /* ttyname or command name*/ char hostname[MAXHOSTNAMELEN]; /* passwd stuff for ia_user */ passwd_t pwdacm, pwddialup, pwdudb, pwdwal, pwddce; ia_user_ret_t uret; /* stuff returned from ia_user */ ia_user_t usent; /* ia_user main structure */ int ia_rcode; /* ia_user return code */ ia_failure_t fsent; /* ia_failure structure */ ia_failure_ret_t fret; /* ia_failure return stuff */ ia_success_t ssent; /* ia_success structure */ ia_success_ret_t sret; /* ia_success return stuff */ int ia_mlsrcode; /* ia_mlsuser return code */ int secstatrc; /* [f]secstat return code */ if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) { getsysv(&sysv, sizeof(struct sysv)); minslevel = sysv.sy_minlvl; if (getusrv(&usrv) < 0) fatal("getusrv() failed, errno = %d", errno); } hostname[0] = '\0'; strlcpy(hostname, (char *)get_canonical_hostname(options.use_dns), MAXHOSTNAMELEN); /* * Fetch user's UDB entry. */ getsysudb(); if ((up = getudbnam(username)) == UDB_NULL) fatal("cannot fetch user's UDB entry"); /* * Prevent any possible fudging so perform a data * safety check and compare the supplied uid against * the udb's uid. */ if (up->ue_uid != uid) fatal("IA uid missmatch"); endudb(); if ((jid = getjtab(&jtab)) < 0) { debug("getjtab"); return(-1); } pid = getpid(); ttyn = ttyname(0); if (SecureSys) { if (ttyn != NULL) secstatrc = secstat(ttyn, &secinfo); else secstatrc = fsecstat(1, &secinfo); if (secstatrc == 0) debug("[f]secstat() successful"); else fatal("[f]secstat() error, rc = %d", secstatrc); } if ((ttyn == NULL) && ((char *)command != NULL)) ttyn = (char *)command; /* * Initialize all structures to call ia_user */ usent.revision = 0; usent.uname = username; usent.host = hostname; usent.ttyn = ttyn; usent.caller = IA_SSHD; usent.pswdlist = &pwdacm; usent.ueptr = &ue; usent.flags = IA_INTERACTIVE | IA_FFLAG; pwdacm.atype = IA_SECURID; pwdacm.pwdp = NULL; pwdacm.next = &pwdudb; pwdudb.atype = IA_UDB; pwdudb.pwdp = NULL; pwdudb.next = &pwddce; pwddce.atype = IA_DCE; pwddce.pwdp = NULL; pwddce.next = &pwddialup; pwddialup.atype = IA_DIALUP; pwddialup.pwdp = NULL; /* pwddialup.next = &pwdwal; */ pwddialup.next = NULL; pwdwal.atype = IA_WAL; pwdwal.pwdp = NULL; pwdwal.next = NULL; uret.revision = 0; uret.pswd = NULL; uret.normal = 0; ia_rcode = ia_user(&usent, &uret); switch (ia_rcode) { /* * These are acceptable return codes from ia_user() */ case IA_UDBWEEK: /* Password Expires in 1 week */ expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage; printf ("WARNING - your current password will expire %s\n", ctime((const time_t *)&expiration_time)); break; case IA_UDBEXPIRED: if (ttyname(0) != NULL) { /* Force a password change */ printf("Your password has expired; Choose a new one.\n"); execl("/bin/passwd", "passwd", username, 0); exit(9); } break; case IA_NORMAL: /* Normal Return Code */ break; case IA_BACKDOOR: /* XXX: can we memset it to zero here so save some of this */ strlcpy(ue.ue_name, "root", sizeof(ue.ue_name)); strlcpy(ue.ue_dir, "/", sizeof(ue.ue_dir)); strlcpy(ue.ue_shell, "/bin/sh", sizeof(ue.ue_shell)); ue.ue_passwd[0] = '\0'; ue.ue_age[0] = '\0'; ue.ue_comment[0] = '\0'; ue.ue_loghost[0] = '\0'; ue.ue_logline[0] = '\0'; ue.ue_uid = -1; ue.ue_nice[UDBRC_INTER] = 0; for (i = 0; i < MAXVIDS; i++) ue.ue_gids[i] = 0; ue.ue_logfails = 0; ue.ue_minlvl = ue.ue_maxlvl = ue.ue_deflvl = minslevel; ue.ue_defcomps = 0; ue.ue_comparts = 0; ue.ue_permits = 0; ue.ue_trap = 0; ue.ue_disabled = 0; ue.ue_logtime = 0; break; case IA_CONSOLE: /* Superuser not from Console */ case IA_TRUSTED: /* Trusted user */ if (options.permit_root_login > PERMIT_NO) break; /* Accept root login */ default: /* * These are failed return codes from ia_user() */ switch (ia_rcode) { case IA_BADAUTH: printf("Bad authorization, access denied.\n"); break; case IA_DISABLED: printf("Your login has been disabled. Contact the system "); printf("administrator for assistance.\n"); break; case IA_GETSYSV: printf("getsysv() failed - errno = %d\n", errno); break; case IA_MAXLOGS: printf("Maximum number of failed login attempts exceeded.\n"); printf("Access denied.\n"); break; case IA_UDBPWDNULL: if (SecureSys) printf("NULL Password not allowed on MLS systems.\n"); break; default: break; } /* * Authentication failed. */ printf("sshd: Login incorrect, (0%o)\n", ia_rcode-IA_ERRORCODE); /* * Initialize structure for ia_failure * which will exit. */ fsent.revision = 0; fsent.uname = username; fsent.host = hostname; fsent.ttyn = ttyn; fsent.caller = IA_SSHD; fsent.flags = IA_INTERACTIVE; fsent.ueptr = &ue; fsent.jid = jid; fsent.errcode = ia_rcode; fsent.pwdp = uret.pswd; fsent.exitcode = 1; fret.revision = 0; fret.normal = 0; /* * Call ia_failure because of an IA failure. * There is no return because ia_failure exits. */ ia_failure(&fsent, &fret); exit(1); } ia_mlsrcode = IA_NORMAL; if (SecureSys) { debug("calling ia_mlsuser()"); ia_mlsrcode = ia_mlsuser(&ue, &secinfo, &usrv, NULL, 0); } if (ia_mlsrcode != IA_NORMAL) { printf("sshd: Login incorrect, (0%o)\n", ia_mlsrcode-IA_ERRORCODE); /* * Initialize structure for ia_failure * which will exit. */ fsent.revision = 0; fsent.uname = username; fsent.host = hostname; fsent.ttyn = ttyn; fsent.caller = IA_SSHD; fsent.flags = IA_INTERACTIVE; fsent.ueptr = &ue; fsent.jid = jid; fsent.errcode = ia_mlsrcode; fsent.pwdp = uret.pswd; fsent.exitcode = 1; fret.revision = 0; fret.normal = 0; /* * Call ia_failure because of an IA failure. * There is no return because ia_failure exits. */ ia_failure(&fsent,&fret); exit(1); } /* Provide login status information */ if (options.print_lastlog && ue.ue_logtime != 0) { printf("Last successful login was : %.*s ", 19, (char *)ctime(&ue.ue_logtime)); if (*ue.ue_loghost != '\0') { printf("from %.*s\n", sizeof(ue.ue_loghost), ue.ue_loghost); } else { printf("on %.*s\n", sizeof(ue.ue_logline), ue.ue_logline); } if (SecureSys && (ue.ue_logfails != 0)) { printf(" followed by %d failed attempts\n", ue.ue_logfails); } } /* * Call ia_success to process successful I/A. */ ssent.revision = 0; ssent.uname = username; ssent.host = hostname; ssent.ttyn = ttyn; ssent.caller = IA_SSHD; ssent.flags = IA_INTERACTIVE; ssent.ueptr = &ue; ssent.jid = jid; ssent.errcode = ia_rcode; ssent.us = NULL; ssent.time = 1; /* Set ue_logtime */ sret.revision = 0; sret.normal = 0; ia_success(&ssent, &sret); /* * Query for account, iff > 1 valid acid & askacid permbit */ if (((ue.ue_permbits & PERMBITS_ACCTID) || (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) && ue.ue_permbits & PERMBITS_ASKACID) { if (ttyname(0) != NULL) { debug("cray_setup: ttyname true case, %.100s", ttyname); while (valid_acct == -1) { printf("Account (? for available accounts)" " [%s]: ", acid2nam(ue.ue_acids[0])); fgets(acct_name, MAXACID, stdin); switch (acct_name[0]) { case EOF: exit(0); break; case '\0': valid_acct = ue.ue_acids[0]; strlcpy(acct_name, acid2nam(valid_acct), MAXACID); break; case '?': /* Print the list 3 wide */ for (i = 0, j = 0; i < MAXVIDS; i++) { if (ue.ue_acids[i] == -1) { printf("\n"); break; } if (++j == 4) { j = 1; printf("\n"); } printf(" %s", acid2nam(ue.ue_acids[i])); } if (ue.ue_permbits & PERMBITS_ACCTID) { printf("\"acctid\" permbit also allows" " you to select any valid " "account name.\n"); } printf("\n"); break; default: valid_acct = nam2acid(acct_name); if (valid_acct == -1) printf( "Account id not found for" " account name \"%s\"\n\n", acct_name); break; } /* * If an account was given, search the user's * acids array to verify they can use this account. */ if ((valid_acct != -1) && !(ue.ue_permbits & PERMBITS_ACCTID)) { for (i = 0; i < MAXVIDS; i++) { if (ue.ue_acids[i] == -1) break; if (valid_acct == ue.ue_acids[i]) break; } if (i == MAXVIDS || ue.ue_acids[i] == -1) { fprintf(stderr, "Cannot set" " account name to " "\"%s\", permission " "denied\n\n", acct_name); valid_acct = -1; } } } } else { /* * The client isn't connected to a terminal and can't * respond to an acid prompt. Use default acid. */ debug("cray_setup: ttyname false case, %.100s", ttyname); valid_acct = ue.ue_acids[0]; } } else { /* * The user doesn't have the askacid permbit set or * only has one valid account to use. */ valid_acct = ue.ue_acids[0]; } if (acctid(0, valid_acct) < 0) { printf ("Bad account id: %d\n", valid_acct); exit(1); } /* * Now set shares, quotas, limits, including CPU time for the * (interactive) job and process, and set up permissions * (for chown etc), etc. */ if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) { printf("Unable to give %d shares to <%s>(%d/%d)\n", ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct); exit(1); } sr = setlimits(username, C_PROC, pid, UDBRC_INTER); if (sr != NULL) { debug("%.200s", sr); exit(1); } sr = setlimits(username, C_JOB, jid, UDBRC_INTER); if (sr != NULL) { debug("%.200s", sr); exit(1); } /* * Place the service provider information into * the session table (Unicos) or job table (Unicos/mk). * There exist double defines for the job/session table in * unicos/mk (jtab.h) so no need for a compile time switch. */ memset(&init_info, '\0', sizeof(init_info)); init_info.s_sessinit.si_id = URM_SPT_LOGIN; init_info.s_sessinit.si_pid = getpid(); init_info.s_sessinit.si_sid = jid; sesscntl(0, S_SETSERVPO, (int)&init_info); /* * Set user and controlling tty security attributes. */ if (SecureSys) { if (setusrv(&usrv) == -1) { debug("setusrv() failed, errno = %d",errno); exit(1); } } return (0); }
/** * main() - IUCV TTY program startup */ int main(int argc, char *argv[]) { struct iucvterm_cfg conf; /* program configuration */ struct sockaddr_iucv saddr, caddr; /* IUCV socket address info */ char client_host[9]; /* client guest name */ int server, client; /* socket file descriptors */ int master, slave; /* pre-allocated PTY fds */ struct sigaction sigact; /* signal handler */ int rc; socklen_t len; /* gettext initialization */ gettext_init(); /* parse command line arguments */ parse_options(PROG_IUCV_TTY, &conf, argc, argv); /* create server socket... */ server = iucvtty_socket(&saddr, NULL, conf.service); if (server == -1) { print_error((errno == EAFNOSUPPORT) ? N_("The AF_IUCV address family is not available") : N_("Creating the AF_IUCV socket failed")); return 1; } if (bind(server, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) { print_error("Binding the AF_IUCV socket failed"); close(server); return 1; } if (listen(server, 1) == -1) { print_error("Listening for incoming connections failed"); close(server); return 1; } /* pre-allocate PTY master/slave file descriptors */ if (openpty(&master, &slave, NULL, NULL, NULL)) { print_error("Opening a new PTY master/slave device pair failed"); close(server); return 1; } /* set close-on-exec for file descriptors */ fcntl(master, F_SETFD, FD_CLOEXEC); fcntl(server, F_SETFD, FD_CLOEXEC); /* syslog */ openlog(SYSLOG_IDENT, LOG_PID, LOG_AUTHPRIV); syslog(LOG_INFO, "Listening on terminal ID: %s, using pts device: %s", conf.service, ttyname(slave)); rc = 0; len = sizeof(struct sockaddr_iucv); /* accept a new client connection */ client = accept(server, (struct sockaddr *) &caddr, &len); if (client == -1) { print_error("An incoming connection could not be accepted"); rc = 2; goto exit_on_error; } /* check if client is allowed to connect */ userid_cpy(client_host, caddr.siucv_user_id); if (is_client_allowed(client_host, &conf)) { iucvtty_tx_error(client, ERR_NOT_AUTHORIZED); syslog(LOG_WARNING, "Rejected client connection from %s; " "Client is not allowed to connect.", client_host); rc = 3; } else { /* client is allowed to connect */ syslog(LOG_INFO, "Accepted client connection from %s", client_host); /* set close-on-exec for client socket */ fcntl(client, F_SETFD, FD_CLOEXEC); /* close server socket */ close(server); /* setup signal handler to notify shutdown signal */ sigemptyset(&sigact.sa_mask); sigact.sa_flags = SA_RESTART; sigact.sa_handler = sig_handler; if (sigaction(SIGCHLD, &sigact, NULL) || sigaction(SIGTERM, &sigact, NULL) || sigaction(SIGINT, &sigact, NULL) || sigaction(SIGPIPE, &sigact, NULL)) { print_error("Registering a signal handler failed"); rc = 4; goto exit_on_error; } /* handle client terminal connection */ rc = iucvtty_worker(client, master, slave, &conf); } close(client); exit_on_error: close(slave); close(master); closelog(); return rc; }
int pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) { #if defined(HAVE_OPENPTY) /* exists in recent (4.4) BSDs and OSF/1 */ char *name; int i; #if !defined(HAVE_TTYNAME) i = openpty(ptyfd, ttyfd, namebuf, NULL, NULL); #else i = openpty(ptyfd, ttyfd, NULL, NULL, NULL); #endif if (i < 0) { dropbear_log(LOG_WARNING, "pty_allocate: openpty: %.100s", strerror(errno)); return 0; } #if defined(HAVE_TTYNAME) name_ptr = ttyname(*ttyfd); if (!name) { dropbear_exit("ttyname fails for openpty device"); } strlcpy(namebuf, name, namebuflen); /* possible truncation */ #endif return 1; #else /* HAVE_OPENPTY */ #ifdef HAVE__GETPTY /* * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more * pty's automagically when needed */ char *slave; slave = _getpty(ptyfd, O_RDWR, 0622, 0); if (slave == NULL) { dropbear_log(LOG_WARNING, "pty_allocate: _getpty: %.100s", strerror(errno)); return 0; } strlcpy(namebuf, slave, namebuflen); /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { dropbear_log(LOG_WARNING, "pty_allocate error: ttyftd open error"); close(*ptyfd); return 0; } return 1; #else /* HAVE__GETPTY */ #if defined(USE_DEV_PTMX) /* * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 * also has bsd-style ptys, but they simply do not work.) * * Linux systems may have the /dev/ptmx device, but this code won't work. */ int ptm; char *pts; ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); if (ptm < 0) { dropbear_log(LOG_WARNING, "pty_allocate: /dev/ptmx: %.100s", strerror(errno)); return 0; } if (grantpt(ptm) < 0) { dropbear_log(LOG_WARNING, "grantpt: %.100s", strerror(errno)); return 0; } if (unlockpt(ptm) < 0) { dropbear_log(LOG_WARNING, "unlockpt: %.100s", strerror(errno)); return 0; } pts = ptsname(ptm); if (pts == NULL) { dropbear_log(LOG_WARNING, "Slave pty side name could not be obtained."); } strlcpy(namebuf, pts, namebuflen); *ptyfd = ptm; /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { dropbear_log(LOG_ERR, "error opening pts %.100s: %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; } #if !defined(HAVE_CYGWIN) && defined(I_PUSH) /* * Push the appropriate streams modules, as described in Solaris pts(7). * HP-UX pts(7) doesn't have ttcompat module. */ if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) { dropbear_log(LOG_WARNING, "ioctl I_PUSH ptem: %.100s", strerror(errno)); } if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) { dropbear_log(LOG_WARNING, "ioctl I_PUSH ldterm: %.100s", strerror(errno)); } #ifndef __hpux if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) { dropbear_log(LOG_WARNING, "ioctl I_PUSH ttcompat: %.100s", strerror(errno)); } #endif #endif return 1; #else /* USE_DEV_PTMX */ #ifdef HAVE_DEV_PTS_AND_PTC /* AIX-style pty code. */ const char *name; *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); if (*ptyfd < 0) { dropbear_log(LOG_ERR, "Could not open /dev/ptc: %.100s", strerror(errno)); return 0; } name = ttyname(*ptyfd); if (!name) { dropbear_exit("ttyname fails for /dev/ptc device"); } strlcpy(namebuf, name, namebuflen); *ttyfd = open(name, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { dropbear_log(LOG_ERR, "Could not open pty slave side %.100s: %.100s", name, strerror(errno)); close(*ptyfd); return 0; } return 1; #else /* HAVE_DEV_PTS_AND_PTC */ /* BSD-style pty code. */ char buf[64]; int i; const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *ptyminors = "0123456789abcdef"; int num_minors = strlen(ptyminors); int num_ptys = strlen(ptymajors) * num_minors; struct termios tio; for (i = 0; i < num_ptys; i++) { snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); snprintf(namebuf, namebuflen, "/dev/tty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd < 0) { /* Try SCO style naming */ snprintf(buf, sizeof buf, "/dev/ptyp%d", i); snprintf(namebuf, namebuflen, "/dev/ttyp%d", i); *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd < 0) { continue; } } /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { dropbear_log(LOG_ERR, "pty_allocate: %.100s: %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; } /* set tty modes to a sane state for broken clients */ if (tcgetattr(*ptyfd, &tio) < 0) { dropbear_log(LOG_WARNING, "ptyallocate: tty modes failed: %.100s", strerror(errno)); } else { tio.c_lflag |= (ECHO | ISIG | ICANON); tio.c_oflag |= (OPOST | ONLCR); tio.c_iflag |= ICRNL; /* Set the new modes for the terminal. */ if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) { dropbear_log(LOG_WARNING, "Setting tty modes for pty failed: %.100s", strerror(errno)); } } return 1; } dropbear_log(LOG_WARNING, "Failed to open any /dev/pty?? devices"); return 0; #endif /* HAVE_DEV_PTS_AND_PTC */ #endif /* USE_DEV_PTMX */ #endif /* HAVE__GETPTY */ #endif /* HAVE_OPENPTY */ }
int main(int argc, char *argv[]) { struct stat sb; char *tty; int ch, verbose = FALSE; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); static const struct option longopts[] = { { "verbose", no_argument, 0, 'v' }, { "version", no_argument, 0, 'V' }, { "help", no_argument, 0, 'h' }, { NULL, 0, 0, 0 } }; while ((ch = getopt_long(argc, argv, "vVh", longopts, NULL)) != -1) switch (ch) { case 'v': verbose = TRUE; break; case 'V': printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING); exit(EXIT_SUCCESS); case 'h': usage(stdout); default: usage(stderr); } argc -= optind; argv += optind; if ((tty = ttyname(STDERR_FILENO)) == NULL) err(MESG_EXIT_FAILURE, _("ttyname failed")); if (stat(tty, &sb) < 0) err(MESG_EXIT_FAILURE, _("stat %s failed"), tty); if (!*argv) { if (sb.st_mode & (S_IWGRP | S_IWOTH)) { puts(_("is y")); return IS_ALLOWED; } puts(_("is n")); return IS_NOT_ALLOWED; } switch (rpmatch(argv[0])) { case 1: #ifdef USE_TTY_GROUP if (chmod(tty, sb.st_mode | S_IWGRP) < 0) #else if (chmod(tty, sb.st_mode | S_IWGRP | S_IWOTH) < 0) #endif err(MESG_EXIT_FAILURE, _("change %s mode failed"), tty); if (verbose) puts(_("write access to your terminal is allowed")); return IS_ALLOWED; case 0: if (chmod(tty, sb.st_mode & ~(S_IWGRP|S_IWOTH)) < 0) err(MESG_EXIT_FAILURE, _("change %s mode failed"), tty); if (verbose) puts(_("write access to your terminal is denied")); return IS_NOT_ALLOWED; case -1: warnx(_("invalid argument: %s"), argv[0]); usage(stderr); default: abort(); } }
int tshd_runshell( int client ) { fd_set rd; struct winsize ws; char *slave, *temp, *shell; int ret, len, pid, pty, tty, n; /* request a pseudo-terminal */ #if defined LINUX || defined FREEBSD || defined OPENBSD || defined OSF if( openpty( &pty, &tty, NULL, NULL, NULL ) < 0 ) { return( 24 ); } slave = ttyname( tty ); if( slave == NULL ) { return( 25 ); } #else #if defined IRIX slave = _getpty( &pty, O_RDWR, 0622, 0 ); if( slave == NULL ) { return( 26 ); } tty = open( slave, O_RDWR | O_NOCTTY ); if( tty < 0 ) { return( 27 ); } #else #if defined CYGWIN || defined SUNOS || defined HPUX pty = open( "/dev/ptmx", O_RDWR | O_NOCTTY ); if( pty < 0 ) { return( 28 ); } if( grantpt( pty ) < 0 ) { return( 29 ); } if( unlockpt( pty ) < 0 ) { return( 30 ); } slave = ptsname( pty ); if( slave == NULL ) { return( 31 ); } tty = open( slave, O_RDWR | O_NOCTTY ); if( tty < 0 ) { return( 32 ); } #if defined SUNOS || defined HPUX if( ioctl( tty, I_PUSH, "ptem" ) < 0 ) { return( 33 ); } if( ioctl( tty, I_PUSH, "ldterm" ) < 0 ) { return( 34 ); } #if defined SUNOS if( ioctl( tty, I_PUSH, "ttcompat" ) < 0 ) { return( 35 ); } #endif #endif #endif #endif #endif /* just in case bash is run, kill the history file */ temp = (char *) malloc( 10 ); if( temp == NULL ) { return( 36 ); } temp[0] = 'H'; temp[5] = 'I'; temp[1] = 'I'; temp[6] = 'L'; temp[2] = 'S'; temp[7] = 'E'; temp[3] = 'T'; temp[8] = '='; temp[4] = 'F'; temp[9] = '\0'; putenv( temp ); /* get the TERM environment variable */ ret = pel_recv_msg( client, message, &len ); if( ret != PEL_SUCCESS ) { return( 37 ); } message[len] = '\0'; temp = (char *) malloc( len + 6 ); if( temp == NULL ) { return( 38 ); } temp[0] = 'T'; temp[3] = 'M'; temp[1] = 'E'; temp[4] = '='; temp[2] = 'R'; strncpy( temp + 5, (char *) message, len + 1 ); putenv( temp ); /* get the window size */ ret = pel_recv_msg( client, message, &len ); if( ret != PEL_SUCCESS || len != 4 ) { return( 39 ); } ws.ws_row = ( (int) message[0] << 8 ) + (int) message[1]; ws.ws_col = ( (int) message[2] << 8 ) + (int) message[3]; ws.ws_xpixel = 0; ws.ws_ypixel = 0; if( ioctl( pty, TIOCSWINSZ, &ws ) < 0 ) { return( 40 ); } /* get the system command */ ret = pel_recv_msg( client, message, &len ); if( ret != PEL_SUCCESS ) { return( 41 ); } message[len] = '\0'; temp = (char *) malloc( len + 1 ); if( temp == NULL ) { return( 42 ); } strncpy( temp, (char *) message, len + 1 ); /* fork to spawn a shell */ pid = fork(); if( pid < 0 ) { return( 43 ); } if( pid == 0 ) { /* close the client socket and the pty (master side) */ close( client ); close( pty ); /* create a new session */ if( setsid() < 0 ) { return( 44 ); } /* set controlling tty, to have job control */ #if defined LINUX || defined FREEBSD || defined OPENBSD || defined OSF if( ioctl( tty, TIOCSCTTY, NULL ) < 0 ) { return( 45 ); } #else #if defined CYGWIN || defined SUNOS || defined IRIX || defined HPUX { int fd; fd = open( slave, O_RDWR ); if( fd < 0 ) { return( 46 ); } close( tty ); tty = fd; } #endif #endif /* tty becomes stdin, stdout, stderr */ dup2( tty, 0 ); dup2( tty, 1 ); dup2( tty, 2 ); if( tty > 2 ) { close( tty ); } /* fire up the shell */ shell = (char *) malloc( 8 ); if( shell == NULL ) { return( 47 ); } shell[0] = '/'; shell[4] = '/'; shell[1] = 'b'; shell[5] = 's'; shell[2] = 'i'; shell[6] = 'h'; shell[3] = 'n'; shell[7] = '\0'; execl( shell, shell + 5, "-c", temp, (char *) 0 ); /* d0h, this shouldn't happen */ return( 48 ); } else { /* tty (slave side) not needed anymore */ close( tty ); /* let's forward the data back and forth */ while( 1 ) { FD_ZERO( &rd ); FD_SET( client, &rd ); FD_SET( pty, &rd ); n = ( pty > client ) ? pty : client; if( select( n + 1, &rd, NULL, NULL, NULL ) < 0 ) { return( 49 ); } if( FD_ISSET( client, &rd ) ) { ret = pel_recv_msg( client, message, &len ); if( ret != PEL_SUCCESS ) { return( 50 ); } if( write( pty, message, len ) != len ) { return( 51 ); } } if( FD_ISSET( pty, &rd ) ) { len = read( pty, message, BUFSIZE ); if( len == 0 ) break; if( len < 0 ) { return( 52 ); } ret = pel_send_msg( client, message, len ); if( ret != PEL_SUCCESS ) { return( 53 ); } } } return( 54 ); } /* not reached */ return( 55 ); }
int main (int argc, char **argv) { mode_t old_umask; cleanup_free char *base_path = NULL; int clone_flags; char *old_cwd = NULL; pid_t pid; int event_fd = -1; const char *new_cwd; uid_t ns_uid; gid_t ns_gid; /* Get the (optional) capabilities we need, drop root */ acquire_caps (); /* Never gain any more privs during exec */ if (prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) die_with_error ("prctl(PR_SET_NO_NEW_CAPS) failed"); /* The initial code is run with high permissions (i.e. CAP_SYS_ADMIN), so take lots of care. */ argv0 = argv[0]; if (isatty (1)) host_tty_dev = ttyname (1); argv++; argc--; if (argc == 0) usage (EXIT_FAILURE); parse_args (&argc, &argv); /* We have to do this if we weren't installed setuid, so let's just DWIM */ if (!is_privileged) opt_unshare_user = TRUE; if (argc == 0) usage (EXIT_FAILURE); __debug__(("Creating root mount point\n")); uid = getuid (); if (opt_sandbox_uid == -1) opt_sandbox_uid = uid; gid = getgid (); if (opt_sandbox_gid == -1) opt_sandbox_gid = gid; if (!opt_unshare_user && opt_sandbox_uid != uid) die ("Specifying --uid requires --unshare-user"); if (!opt_unshare_user && opt_sandbox_gid != gid) die ("Specifying --gid requires --unshare-user"); /* We need to read stuff from proc during the pivot_root dance, etc. Lets keep a fd to it open */ proc_fd = open ("/proc", O_RDONLY | O_PATH); if (proc_fd == -1) die_with_error ("Can't open /proc"); /* We need *some* mountpoint where we can mount the root tmpfs. We first try in /run, and if that fails, try in /tmp. */ base_path = xasprintf ("/run/user/%d/.bubblewrap", uid); if (mkdir (base_path, 0755) && errno != EEXIST) { free (base_path); base_path = xasprintf ("/tmp/.bubblewrap-%d", uid); if (mkdir (base_path, 0755) && errno != EEXIST) die_with_error ("Creating root mountpoint failed"); } __debug__(("creating new namespace\n")); if (opt_unshare_pid) { event_fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK); if (event_fd == -1) die_with_error ("eventfd()"); } /* We block sigchild here so that we can use signalfd in the monitor. */ block_sigchild (); clone_flags = SIGCHLD | CLONE_NEWNS; if (opt_unshare_user) clone_flags |= CLONE_NEWUSER; if (opt_unshare_pid) clone_flags |= CLONE_NEWPID; if (opt_unshare_net) clone_flags |= CLONE_NEWNET; if (opt_unshare_ipc) clone_flags |= CLONE_NEWIPC; if (opt_unshare_uts) clone_flags |= CLONE_NEWUTS; pid = raw_clone (clone_flags, NULL); if (pid == -1) { if (opt_unshare_user) { if (errno == EINVAL) die ("Creating new namespace failed, likely because the kernel does not support user namespaces. bwrap must be installed setuid on such systems."); else if (errno == EPERM && !is_privileged) die ("No permissions to creating new namespace, likely because the kernel does not allow non-privileged user namespaces. On e.g. debian this can be enabled with 'sysctl kernel.unprivileged_userns_clone=1'."); } die_with_error ("Creating new namespace failed"); } if (pid != 0) { /* Initial launched process, wait for exec:ed command to exit */ /* We don't need any caps in the launcher, drop them immediately. */ drop_caps (); monitor_child (event_fd); exit (0); /* Should not be reached, but better safe... */ } if (opt_unshare_net && loopback_setup () != 0) die ("Can't create loopback device"); ns_uid = opt_sandbox_uid; ns_gid = opt_sandbox_gid; if (opt_unshare_user) { if (opt_needs_devpts) { /* This is a bit hacky, but we need to first map the real uid/gid to 0, otherwise we can't mount the devpts filesystem because root is not mapped. Later we will create another child user namespace and map back to the real uid */ ns_uid = 0; ns_gid = 0; } write_uid_gid_map (ns_uid, uid, ns_gid, gid, TRUE); } old_umask = umask (0); /* Mark everything as slave, so that we still * receive mounts from the real root, but don't * propagate mounts to the real root. */ if (mount (NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) die_with_error ("Failed to make / slave"); /* Create a tmpfs which we will use as / in the namespace */ if (mount ("", base_path, "tmpfs", MS_NODEV|MS_NOSUID, NULL) != 0) die_with_error ("Failed to mount tmpfs"); old_cwd = get_current_dir_name (); /* Chdir to the new root tmpfs mount. This will be the CWD during the entire setup. Access old or new root via "oldroot" and "newroot". */ if (chdir (base_path) != 0) die_with_error ("chdir base_path"); /* We create a subdir "$base_path/newroot" for the new root, that * way we can pivot_root to base_path, and put the old root at * "$base_path/oldroot". This avoids problems accessing the oldroot * dir if the user requested to bind mount something over / */ if (mkdir ("newroot", 0755)) die_with_error ("Creating newroot failed"); if (mkdir ("oldroot", 0755)) die_with_error ("Creating oldroot failed"); if (pivot_root (base_path, "oldroot")) die_with_error ("pivot_root"); if (chdir ("/") != 0) die_with_error ("chdir / (base path)"); if (is_privileged) { pid_t child; int privsep_sockets[2]; if (socketpair (AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, privsep_sockets) != 0) die_with_error ("Can't create privsep socket"); child = fork (); if (child == -1) die_with_error ("Can't fork unprivileged helper"); if (child == 0) { /* Unprivileged setup process */ drop_caps (); close (privsep_sockets[0]); setup_newroot (opt_unshare_pid, privsep_sockets[1]); exit (0); } else { uint32_t buffer[2048]; /* 8k, but is int32 to guarantee nice alignment */ uint32_t op, flags; const char *arg1, *arg2; cleanup_fd int unpriv_socket = -1; unpriv_socket = privsep_sockets[0]; close (privsep_sockets[1]); do { op = read_priv_sec_op (unpriv_socket, buffer, sizeof (buffer), &flags, &arg1, &arg2); privileged_op (-1, op, flags, arg1, arg2); if (write (unpriv_socket, buffer, 1) != 1) die ("Can't write to op_socket"); } while (op != PRIV_SEP_OP_DONE); /* Continue post setup */ } } else setup_newroot (opt_unshare_pid, -1); /* The old root better be rprivate or we will send unmount events to the parent namespace */ if (mount ("oldroot", "oldroot", NULL, MS_REC|MS_PRIVATE, NULL) != 0) die_with_error ("Failed to make old root rprivate"); if (umount2 ("oldroot", MNT_DETACH)) die_with_error ("unmount old root"); if (opt_unshare_user && (ns_uid != opt_sandbox_uid || ns_gid != opt_sandbox_gid)) { /* Now that devpts is mounted and we've no need for mount permissions we can create a new userspace and map our uid 1:1 */ if (unshare (CLONE_NEWUSER)) die_with_error ("unshare user ns"); write_uid_gid_map (opt_sandbox_uid, ns_uid, opt_sandbox_gid, ns_gid, FALSE); } /* Now make /newroot the real root */ if (chdir ("/newroot") != 0) die_with_error ("chdir newroot"); if (chroot ("/newroot") != 0) die_with_error ("chroot /newroot"); if (chdir ("/") != 0) die_with_error ("chdir /"); /* Now we have everything we need CAP_SYS_ADMIN for, so drop it */ drop_caps (); if (opt_seccomp_fd != -1) { cleanup_free char *seccomp_data = NULL; size_t seccomp_len; struct sock_fprog prog; seccomp_data = load_file_data (opt_seccomp_fd, &seccomp_len); if (seccomp_data == NULL) die_with_error ("Can't read seccomp data"); if (seccomp_len % 8 != 0) die ("Invalide seccomp data, must be multiple of 8"); prog.len = seccomp_len / 8; prog.filter = (struct sock_filter *)seccomp_data; close (opt_seccomp_fd); if (prctl (PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) != 0) die_with_error ("prctl(PR_SET_SECCOMP)"); } umask (old_umask); new_cwd = "/"; if (opt_chdir_path) { if (chdir (opt_chdir_path)) die_with_error ("Can't chdir to %s", opt_chdir_path); new_cwd = opt_chdir_path; } else if (chdir (old_cwd) == 0) { /* If the old cwd is mapped in the sandbox, go there */ new_cwd = old_cwd; } else { /* If the old cwd is not mapped, go to home */ const char *home = getenv ("HOME"); if (home != NULL && chdir (home) == 0) new_cwd = home; } xsetenv ("PWD", new_cwd, 1); free (old_cwd); __debug__(("forking for child\n")); if (opt_unshare_pid || lock_files != NULL || opt_sync_fd != -1) { /* We have to have a pid 1 in the pid namespace, because * otherwise we'll get a bunch of zombies as nothing reaps * them. Alternatively if we're using sync_fd or lock_files we * need some process to own these. */ pid = fork (); if (pid == -1) die_with_error("Can't fork for pid 1"); if (pid != 0) { /* Close fds in pid 1, except stdio and optionally event_fd (for syncing pid 2 lifetime with monitor_child) and opt_sync_fd (for syncing sandbox lifetime with outside process). Any other fds will been passed on to the child though. */ { int dont_close[3]; int j = 0; if (event_fd != -1) dont_close[j++] = event_fd; if (opt_sync_fd != -1) dont_close[j++] = opt_sync_fd; dont_close[j++] = -1; fdwalk (proc_fd, close_extra_fds, dont_close); } return do_init (event_fd, pid); } } __debug__(("launch executable %s\n", argv[0])); if (proc_fd != -1) close (proc_fd); if (opt_sync_fd != -1) close (opt_sync_fd); /* We want sigchild in the child */ unblock_sigchild (); if (label_exec (opt_exec_label) == -1) die_with_error ("label_exec %s", argv[0]); if (execvp (argv[0], argv) == -1) die_with_error ("execvp %s", argv[0]); return 0; }
static void initialize_mousetype(SCREEN *sp) { T((T_CALLED("initialize_mousetype()"))); /* Try gpm first, because gpm may be configured to run in xterm */ #if USE_GPM_SUPPORT if (allow_gpm_mouse(sp)) { if (!sp->_mouse_gpm_loaded) { #ifdef HAVE_LIBDL load_gpm_library(sp); #else /* !HAVE_LIBDL */ sp->_mouse_gpm_found = TRUE; sp->_mouse_gpm_loaded = TRUE; #endif } /* * The gpm_fd file-descriptor may be negative (xterm). So we have to * maintain our notion of whether the mouse connection is active * without testing the file-descriptor. */ if (sp->_mouse_gpm_found && enable_gpm_mouse(sp, TRUE)) { sp->_mouse_type = M_GPM; sp->_mouse_fd = *(my_gpm_fd); T(("GPM mouse_fd %d", sp->_mouse_fd)); returnVoid; } } #endif /* USE_GPM_SUPPORT */ /* OS/2 VIO */ #if USE_EMX_MOUSE if (!sp->_emxmouse_thread && strstr(TerminalOf(sp)->type.term_names, "xterm") == 0 && key_mouse) { int handles[2]; if (pipe(handles) < 0) { perror("mouse pipe error"); returnVoid; } else { int rc; if (!sp->_emxmouse_buttons[0]) { char *s = getenv("MOUSE_BUTTONS_123"); sp->_emxmouse_buttons[0] = 1; if (s && strlen(s) >= 3) { sp->_emxmouse_buttons[1] = s[0] - '0'; sp->_emxmouse_buttons[2] = s[1] - '0'; sp->_emxmouse_buttons[3] = s[2] - '0'; } else { sp->_emxmouse_buttons[1] = 1; sp->_emxmouse_buttons[2] = 3; sp->_emxmouse_buttons[3] = 2; } } sp->_emxmouse_wfd = handles[1]; M_FD(sp) = handles[0]; /* Needed? */ setmode(handles[0], O_BINARY); setmode(handles[1], O_BINARY); /* Do not use CRT functions, we may single-threaded. */ rc = DosCreateThread((unsigned long *) &sp->_emxmouse_thread, mouse_server, (long) sp, 0, 8192); if (rc) { printf("mouse thread error %d=%#x", rc, rc); } else { sp->_mouse_type = M_XTERM; } returnVoid; } } #endif /* USE_EMX_MOUSE */ #if USE_SYSMOUSE { struct mouse_info the_mouse; char *the_device = 0; if (NC_ISATTY(sp->_ifd)) the_device = ttyname(sp->_ifd); if (the_device == 0) the_device = "/dev/tty"; sp->_mouse_fd = open(the_device, O_RDWR); if (sp->_mouse_fd >= 0) { /* * sysmouse does not have a usable user interface for obtaining * mouse events. The logical way to proceed (reading data on a * stream) only works if one opens the device as root. Even in * that mode, careful examination shows we lose events * occasionally. The interface provided for user programs is to * establish a signal handler. really. * * Take over SIGUSR2 for this purpose since SIGUSR1 is more * likely to be used by an application. getch() will have to * handle the misleading EINTR's. */ signal(SIGUSR2, SIG_IGN); the_mouse.operation = MOUSE_MODE; the_mouse.u.mode.mode = 0; the_mouse.u.mode.signal = SIGUSR2; if (ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse) != -1) { signal(SIGUSR2, handle_sysmouse); the_mouse.operation = MOUSE_SHOW; ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse); #if defined(FBIO_MODEINFO) || defined(CONS_MODEINFO) /* FreeBSD > 2.x */ { #ifndef FBIO_GETMODE /* FreeBSD 3.x */ #define FBIO_GETMODE CONS_GET #define FBIO_MODEINFO CONS_MODEINFO #endif /* FBIO_GETMODE */ video_info_t the_video; if (ioctl(sp->_mouse_fd, FBIO_GETMODE, &the_video.vi_mode) != -1 && ioctl(sp->_mouse_fd, FBIO_MODEINFO, &the_video) != -1) { sp->_sysmouse_char_width = the_video.vi_cwidth; sp->_sysmouse_char_height = the_video.vi_cheight; } } #endif /* defined(FBIO_MODEINFO) || defined(CONS_MODEINFO) */ if (sp->_sysmouse_char_width <= 0) sp->_sysmouse_char_width = 8; if (sp->_sysmouse_char_height <= 0) sp->_sysmouse_char_height = 16; sp->_mouse_type = M_SYSMOUSE; returnVoid; } } } #endif /* USE_SYSMOUSE */ #ifdef USE_TERM_DRIVER CallDriver(sp, td_initmouse); #else /* we know how to recognize mouse events under "xterm" */ if (key_mouse != 0) { if (!strcmp(key_mouse, xterm_kmous) || strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) { init_xterm_mouse(sp); } } else if (strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) { if (_nc_add_to_try(&(sp->_keytry), xterm_kmous, KEY_MOUSE) == OK) init_xterm_mouse(sp); } #endif returnVoid; }
int main(int argc, char *argv[]) { struct kinfo_proc *kp, **kinfo; struct varent *vent; struct winsize ws; struct passwd *pwd; dev_t ttydev; pid_t pid; uid_t uid; int all, ch, flag, i, fmt, lineno, nentries; int prtheader, showthreads, wflag, kflag, what, Uflag, xflg; char *nlistf, *memf, *swapf, errbuf[_POSIX2_LINE_MAX]; if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 && ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 && ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) || ws.ws_col == 0) termwidth = 79; else termwidth = ws.ws_col - 1; if (argc > 1) argv[1] = kludge_oldps_options(argv[1]); all = fmt = prtheader = showthreads = wflag = kflag = Uflag = xflg = 0; pid = -1; uid = 0; ttydev = NODEV; memf = nlistf = swapf = NULL; while ((ch = getopt(argc, argv, "AaCcegHhjkLlM:mN:O:o:p:rSTt:U:uvW:wx")) != -1) switch (ch) { case 'A': all = 1; xflg = 1; break; case 'a': all = 1; break; case 'C': rawcpu = 1; break; case 'c': commandonly = 1; break; case 'e': /* XXX set ufmt */ needenv = 1; break; case 'g': break; /* no-op */ case 'H': showthreads = 1; break; case 'h': prtheader = ws.ws_row > 5 ? ws.ws_row : 22; break; case 'j': parsefmt(jfmt); fmt = 1; jfmt[0] = '\0'; break; case 'k': kflag++; break; case 'L': showkey(); exit(0); case 'l': parsefmt(lfmt); fmt = 1; lfmt[0] = '\0'; break; case 'M': memf = optarg; break; case 'm': sortby = SORTMEM; break; case 'N': nlistf = optarg; break; case 'O': parsefmt(o1); parsefmt(optarg); parsefmt(o2); o1[0] = o2[0] = '\0'; fmt = 1; break; case 'o': parsefmt(optarg); fmt = 1; break; case 'p': pid = atol(optarg); xflg = 1; break; case 'r': sortby = SORTCPU; break; case 'S': sumrusage = 1; break; case 'T': if ((optarg = ttyname(STDIN_FILENO)) == NULL) errx(1, "stdin: not a terminal"); /* FALLTHROUGH */ case 't': { struct stat sb; char *ttypath, pathbuf[MAXPATHLEN]; if (strcmp(optarg, "co") == 0) ttypath = _PATH_CONSOLE; else if (*optarg != '/') (void)snprintf(ttypath = pathbuf, sizeof(pathbuf), "%s%s", _PATH_TTY, optarg); else ttypath = optarg; if (stat(ttypath, &sb) == -1) err(1, "%s", ttypath); if (!S_ISCHR(sb.st_mode)) errx(1, "%s: not a terminal", ttypath); ttydev = sb.st_rdev; break; } case 'U': pwd = getpwnam(optarg); if (pwd == NULL) errx(1, "%s: no such user", optarg); uid = pwd->pw_uid; endpwent(); Uflag = xflg = 1; break; case 'u': parsefmt(ufmt); sortby = SORTCPU; fmt = 1; ufmt[0] = '\0'; break; case 'v': parsefmt(vfmt); sortby = SORTMEM; fmt = 1; vfmt[0] = '\0'; break; case 'W': swapf = optarg; break; case 'w': if (wflag) termwidth = UNLIMITED; else if (termwidth < 131) termwidth = 131; wflag++; break; case 'x': xflg = 1; break; default: usage(); } argc -= optind; argv += optind; #define BACKWARD_COMPATIBILITY #ifdef BACKWARD_COMPATIBILITY if (*argv) { nlistf = *argv; if (*++argv) { memf = *argv; if (*++argv) swapf = *argv; } } #endif if (nlistf == NULL && memf == NULL && swapf == NULL) { kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); kvm_sysctl_only = 1; } else { kd = kvm_openfiles(nlistf, memf, swapf, O_RDONLY, errbuf); } if (kd == NULL) errx(1, "%s", errbuf); if (!fmt) { if (showthreads) parsefmt(tfmt); else parsefmt(dfmt); } /* XXX - should be cleaner */ if (!all && ttydev == NODEV && pid == -1 && !Uflag) { uid = getuid(); Uflag = 1; } /* * scan requested variables, noting what structures are needed, * and adjusting header widths as appropriate. */ scanvars(); if (neednlist && !nlistread) (void) donlist(); /* * get proc list */ if (Uflag) { what = KERN_PROC_UID; flag = uid; } else if (ttydev != NODEV) { what = KERN_PROC_TTY; flag = ttydev; } else if (pid != -1) { what = KERN_PROC_PID; flag = pid; } else if (kflag) { what = KERN_PROC_KTHREAD; flag = 0; } else { what = KERN_PROC_ALL; flag = 0; } if (showthreads) what |= KERN_PROC_SHOW_THREADS; /* * select procs */ kp = kvm_getprocs(kd, what, flag, sizeof(*kp), &nentries); if (kp == NULL) errx(1, "%s", kvm_geterr(kd)); /* * print header */ printheader(); if (nentries == 0) exit(1); /* * sort proc list, we convert from an array of structs to an array * of pointers to make the sort cheaper. */ if ((kinfo = calloc(sizeof(*kinfo), nentries)) == NULL) err(1, "failed to allocate memory for proc pointers"); for (i = 0; i < nentries; i++) kinfo[i] = &kp[i]; qsort(kinfo, nentries, sizeof(*kinfo), pscomp); /* * for each proc, call each variable output function. */ for (i = lineno = 0; i < nentries; i++) { if (showthreads == 0 && (kinfo[i]->p_flag & P_THREAD) != 0) continue; if (xflg == 0 && ((int)kinfo[i]->p_tdev == NODEV || (kinfo[i]->p_psflags & PS_CONTROLT ) == 0)) continue; if (showthreads && kinfo[i]->p_tid == -1) continue; for (vent = vhead; vent; vent = vent->next) { (vent->var->oproc)(kinfo[i], vent); if (vent->next != NULL) (void)putchar(' '); } (void)putchar('\n'); if (prtheader && lineno++ == prtheader - 4) { (void)putchar('\n'); printheader(); lineno = 0; } } exit(eval); }
static int setup_tty(struct weston_launch *wl, const char *tty) { struct stat buf; struct vt_mode mode = { 0 }; char *t; if (!wl->new_user) { wl->tty = STDIN_FILENO; } else if (tty) { t = ttyname(STDIN_FILENO); if (t && strcmp(t, tty) == 0) wl->tty = STDIN_FILENO; else wl->tty = open(tty, O_RDWR | O_NOCTTY); } else { int tty0 = open("/dev/tty0", O_WRONLY | O_CLOEXEC); char filename[16]; if (tty0 < 0) error(1, errno, "could not open tty0"); if (ioctl(tty0, VT_OPENQRY, &wl->ttynr) < 0 || wl->ttynr == -1) error(1, errno, "failed to find non-opened console"); snprintf(filename, sizeof filename, "/dev/tty%d", wl->ttynr); wl->tty = open(filename, O_RDWR | O_NOCTTY); close(tty0); } if (wl->tty < 0) error(1, errno, "failed to open tty"); if (fstat(wl->tty, &buf) == -1 || major(buf.st_rdev) != TTY_MAJOR || minor(buf.st_rdev) == 0) error(1, 0, "weston-launch must be run from a virtual terminal"); if (tty) { if (fstat(wl->tty, &buf) < 0) error(1, errno, "stat %s failed", tty); if (major(buf.st_rdev) != TTY_MAJOR) error(1, 0, "invalid tty device: %s", tty); wl->ttynr = minor(buf.st_rdev); } if (ioctl(wl->tty, KDGKBMODE, &wl->kb_mode)) error(1, errno, "failed to get current keyboard mode: %m\n"); if (ioctl(wl->tty, KDSKBMUTE, 1) && ioctl(wl->tty, KDSKBMODE, K_OFF)) error(1, errno, "failed to set K_OFF keyboard mode: %m\n"); if (ioctl(wl->tty, KDSETMODE, KD_GRAPHICS)) error(1, errno, "failed to set KD_GRAPHICS mode on tty: %m\n"); mode.mode = VT_PROCESS; mode.relsig = SIGUSR1; mode.acqsig = SIGUSR2; if (ioctl(wl->tty, VT_SETMODE, &mode) < 0) error(1, errno, "failed to take control of vt handling\n"); return 0; }
/*{{{ main*/ int main(int argc, char *argv[]) { /*{{{ variables*/ int x, login_y, password_y; char loginstr[9], passwordstr[9], ret; char ttystr[_POSIX_PATH_MAX]; char *background = NULL; char *fontname = NULL; /*}}} */ /*{{{ parse arguments*/ { int c; while ((c = getopt(argc, argv, "b:f:")) != EOF) switch (c) { case 'b': background = optarg; break; case 'f': fontname = optarg; break; } /*{{{ parse tty*/ { int tty; if (optind + 1 > argc) { fprintf(stderr, "Usage: %s tty\n", argv[0]); exit(1); } else { strcpy(ttystr, "/dev/"); strcat(ttystr, argv[optind++]); } close(0); close(1); close(2); setsid(); if ((tty = open(ttystr, O_RDWR)) != 0) { fprintf(stderr, "%s: Can't open controlling terminal on fd 0.\n", argv[0]); exit(1); } fchmod(tty, 0600); fchown(tty, getuid(), getgid()); open(argv[optind], O_RDWR); open(argv[optind], O_RDWR); } /*}}} */ } /*}}} */ /*{{{ get into grafics mode*/ signal(SIGTERM, quit); signal(SIGHUP, quit); set_tty(0); if ((screen = bit_open(SCREEN_DEV)) == NULL) { reset_tty(0); exit(EX_NOPERM); } bit_grafscreen(); /*}}} */ /*{{{ load font*/ if (fontname) { char fontpath[_POSIX_PATH_MAX]; if (*fontname == '/' || *fontname == '.') strcpy(fontpath, fontname); else { strcpy(fontpath, ICONDIR); strcat(fontpath, "/"); strcat(fontpath, fontname); } if ((font = open_font(fontname)) == NULL) font = open_font(NULL); } else font = open_font(NULL); /*}}} */ /*{{{ draw background*/ bit_blit(screen, 0, 0, screen->wide, screen->high, BIT_CLR, NULL, 0, 0); if (background) { BITMAP *bp; FILE *fp; char backgroundpath[_POSIX_PATH_MAX]; if (*background == '/' || *background == '.') strcpy(backgroundpath, background); else { strcpy(backgroundpath, ICONDIR); strcat(backgroundpath, "/"); strcat(backgroundpath, background); } if ((fp = fopen(backgroundpath, "r")) != NULL && (bp = bitmapread(fp)) != NULL) { int x, y; for (x = 0; x < screen->wide; x += bp->wide) bit_blit( screen, x, 0, screen->wide - x < bp->wide ? screen->wide - x : bp->wide, bp->high, BIT_SRC, bp, 0, 0); for (y = 0; y < screen->high; y += bp->high) bit_blit( screen, 0, y, screen->wide, screen->high - y < bp->high ? screen->high - y : bp->high, BIT_SRC, screen, 0, 0); } } /*}}} */ /*{{{ draw hostname*/ { int bx, bw, by, bh; char hostname[_POSIX_PATH_MAX]; struct hostent *h; gethostname(hostname, sizeof(hostname)); if ((h = gethostbyname(hostname)) != NULL) strcpy(hostname, h->h_name); bw = font->head.wide * (strlen(hostname) + 2); bh = 2 * font->head.high; bx = (screen->wide - bw) / 2; by = screen->high / 6 - bh / 2; cutebox(bx, by, bw, bh); printstr(bx + font->head.wide, by + bh - font->head.high / 2, hostname); } /*}}} */ /*{{{ draw login box*/ { int bx, bw, by, bh; bx = (screen->wide - font->head.wide * 40) / 2; by = (screen->high - font->head.high * 8) / 2; bw = font->head.wide * 40; bh = font->head.high * 8; cutebox(bx, by, bw, bh); } /*}}} */ /*{{{ draw login box contents*/ x = (screen->wide - font->head.wide * 18) / 2; login_y = screen->high / 2 - font->head.wide / 6; password_y = screen->high / 2 + font->head.high / 6 + font->head.high; printstr(x, password_y, "Password: "******"Press ESC for terminal login"); /*}}} */ while (1) { /*{{{ get login and password or escape*/ printstr(x, login_y, "Login: "******"mgr", NULL }; int i; sprintf(env_user, "USER=%s", pw->pw_name); sprintf(env_logname, "LOGNAME=%s", pw->pw_name); sprintf(env_home, "HOME=%s", pw->pw_dir); sprintf(env_shell, "SHELL=%s", pw->pw_shell == NULL || pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell); sprintf(env_path, "PATH=%s", PATH); sprintf(env_mail, "MAIL=%s/%s", MAILDIR, pw->pw_name); if (chdir(pw->pw_dir) != 0) chdir("/"); if (ttyname(0)) { chown(ttyname(0), pw->pw_uid, pw->pw_gid); chmod(ttyname(0), 0600); } for (i = 1; i <= _NSIG; i++) signal(i, SIG_DFL); bit_destroy(screen); reset_tty(0); initgroups(pw->pw_name, pw->pw_gid); setgid(pw->pw_gid); setuid(pw->pw_uid); sprintf(mgrlogin, "%s/.mgrlogin", pw->pw_dir); execve(mgrlogin, login_argv, login_env); execve(MGR_BINARY, login_argv, login_env); exit(EX_OSFILE); } /*}}} */ else /*{{{ incorrect login*/ { printstr((screen->wide - font->head.wide * 16) / 2, login_y + 3 * font->head.high, "Login incorrect"); } /*}}} */ } /*}}} */ } }
int main (int argc, char *argv[]) { int starting_line = 0; /* line to start editing at */ char command[QXE_PATH_MAX + 512];/* emacs command buffer */ char fullpath[QXE_PATH_MAX+1];/* full pathname to file */ char *eval_form = NULL; /* form to evaluate with `-eval' */ char *eval_function = NULL; /* function to evaluate with `-f' */ char *load_library = NULL; /* library to load */ int quick = 0; /* quick edit, don't wait for user to finish */ int batch = 0; /* batch mode */ int view = 0; /* view only. */ int nofiles = 0; int errflg = 0; /* option error */ int s; /* socket / msqid to server */ int connect_type; /* CONN_UNIX, CONN_INTERNET, or * CONN_IPC */ int suppress_windows_system = 0; char *display = NULL; #ifdef INTERNET_DOMAIN_SOCKETS char *hostarg = NULL; /* remote hostname */ char *remotearg; char thishost[HOSTNAMSZ]; /* this hostname */ char remotepath[QXE_PATH_MAX+1]; /* remote pathname */ char *path; int rflg = 0; /* pathname given on cmdline */ char *portarg; unsigned short port = 0; /* port to server */ #endif /* INTERNET_DOMAIN_SOCKETS */ #ifdef SYSV_IPC struct msgbuf *msgp; /* message */ #endif /* SYSV_IPC */ char *tty = NULL; char buffer[GSERV_BUFSZ + 1]; /* buffer to read pid */ char result[GSERV_BUFSZ + 1]; int i; #ifdef INTERNET_DOMAIN_SOCKETS memset (remotepath, 0, sizeof (remotepath)); #endif /* INTERNET_DOMAIN_SOCKETS */ progname = strrchr (argv[0], '/'); if (progname) ++progname; else progname = argv[0]; #ifdef WIN32_NATIVE tmpdir = getenv ("TEMP"); if (!tmpdir) tmpdir = getenv ("TMP"); if (!tmpdir) tmpdir = "c:\\"; #else #ifdef USE_TMPDIR tmpdir = getenv ("TMPDIR"); #endif if (!tmpdir) tmpdir = "/tmp"; #endif /* WIN32_NATIVE */ display = getenv ("DISPLAY"); if (display) display = my_strdup (display); #ifndef HAVE_MS_WINDOWS else suppress_windows_system = 1; #endif for (i = 1; argv[i] && !errflg; i++) { if (*argv[i] != '-') break; else if (*argv[i] == '-' && (*(argv[i] + 1) == '\0' || (*(argv[i] + 1) == '-' && *(argv[i] + 2) == '\0'))) { /* `-' or `--' */ ++i; break; } if (!strcmp (argv[i], "-batch") || !strcmp (argv[i], "--batch")) batch = 1; else if (!strcmp (argv[i], "-eval") || !strcmp (argv[i], "--eval")) { if (!argv[++i]) { fprintf (stderr, "%s: `-eval' must be followed by an argument\n", progname); exit (1); } eval_form = argv[i]; } else if (!strcmp (argv[i], "-display") || !strcmp (argv[i], "--display")) { suppress_windows_system = 0; if (!argv[++i]) { fprintf (stderr, "%s: `-display' must be followed by an argument\n", progname); exit (1); } if (display) free (display); /* no need to strdup. */ display = argv[i]; } else if (!strcmp (argv[i], "-nw")) suppress_windows_system = 1; else { /* Iterate over one-letter options. */ char *p; int over = 0; for (p = argv[i] + 1; *p && !over; p++) { switch (*p) { case 'q': quick = 1; break; case 'v': view = 1; break; case 'f': GET_ARGUMENT (eval_function, "-f"); break; case 'l': GET_ARGUMENT (load_library, "-l"); break; #ifdef INTERNET_DOMAIN_SOCKETS case 'h': GET_ARGUMENT (hostarg, "-h"); break; case 'p': GET_ARGUMENT (portarg, "-p"); port = atoi (portarg); break; case 'r': GET_ARGUMENT (remotearg, "-r"); strncpy (remotepath, remotearg, QXE_PATH_MAX); rflg = 1; break; #endif /* INTERNET_DOMAIN_SOCKETS */ default: errflg = 1; } } /* for */ } /* else */ } /* for */ if (errflg) { fprintf (stderr, #ifdef INTERNET_DOMAIN_SOCKETS "Usage: %s [-nw] [-display display] [-q] [-v] [-l library]\n" " [-batch] [-f function] [-eval form]\n" " [-h host] [-p port] [-r remote-path] [[+line] file] ...\n", #else /* !INTERNET_DOMAIN_SOCKETS */ "Usage: %s [-nw] [-q] [-v] [-l library] [-f function] [-eval form] " "[[+line] path] ...\n", #endif /* !INTERNET_DOMAIN_SOCKETS */ progname); exit (1); } if (batch && argv[i]) { fprintf (stderr, "%s: Cannot specify `-batch' with file names\n", progname); exit (1); } #if defined(INTERNET_DOMAIN_SOCKETS) if (suppress_windows_system && hostarg) { fprintf (stderr, "%s: Remote editing is available only on X\n", progname); exit (1); } #endif *result = '\0'; if (eval_function || eval_form || load_library) { #if defined(INTERNET_DOMAIN_SOCKETS) connect_type = make_connection (hostarg, port, &s); #else connect_type = make_connection (NULL, 0, &s); #endif sprintf (command, "(gnuserv-eval%s '(progn ", quick ? "-quickly" : ""); send_string (s, command); if (load_library) { send_string (s , "(load-library "); send_string (s, clean_string(load_library)); send_string (s, ") "); } if (eval_form) { send_string (s, eval_form); } if (eval_function) { send_string (s, "("); send_string (s, eval_function); send_string (s, ")"); } send_string (s, "))"); /* disconnect already sends EOT_STR */ #ifdef SYSV_IPC if (connect_type == (int) CONN_IPC) disconnect_from_ipc_server (s, msgp, batch && !quick); #else /* !SYSV_IPC */ if (connect_type != (int) CONN_IPC) disconnect_from_server (s, batch && !quick); #endif /* !SYSV_IPC */ } /* eval_function || eval_form || load_library */ else if (batch) { /* no sexp on the command line, so read it from stdin */ int nb; #if defined(INTERNET_DOMAIN_SOCKETS) connect_type = make_connection (hostarg, port, &s); #else connect_type = make_connection (NULL, 0, &s); #endif sprintf (command, "(gnuserv-eval%s '(progn ", quick ? "-quickly" : ""); send_string (s, command); while ((nb = read(fileno(stdin), buffer, GSERV_BUFSZ-1)) > 0) { buffer[nb] = '\0'; send_string(s, buffer); } send_string(s,"))"); /* disconnect already sends EOT_STR */ #ifdef SYSV_IPC if (connect_type == (int) CONN_IPC) disconnect_from_ipc_server (s, msgp, batch && !quick); #else /* !SYSV_IPC */ if (connect_type != (int) CONN_IPC) disconnect_from_server (s, batch && !quick); #endif /* !SYSV_IPC */ } if (!batch) { if (suppress_windows_system) { tty = ttyname (0); if (!tty) { fprintf (stderr, "%s: Not connected to a tty", progname); exit (1); } #if defined(INTERNET_DOMAIN_SOCKETS) connect_type = make_connection (hostarg, port, &s); #else connect_type = make_connection (NULL, 0, &s); #endif send_string (s, "(gnuserv-eval '(emacs-pid))"); send_string (s, EOT_STR); if (read_line (s, buffer) == 0) { fprintf (stderr, "%s: Could not establish Emacs process id\n", progname); exit (1); } /* Don't do disconnect_from_server because we have already read data, and disconnect doesn't do anything else. */ #ifdef SYSV_IPC if (connect_type == (int) CONN_IPC) disconnect_from_ipc_server (s, msgp, FALSE); #endif /* !SYSV_IPC */ emacs_pid = (pid_t)atol(buffer); initialize_signals(); } /* suppress_windows_system */ #if defined(INTERNET_DOMAIN_SOCKETS) connect_type = make_connection (hostarg, port, &s); #else connect_type = make_connection (NULL, 0, &s); #endif #ifdef INTERNET_DOMAIN_SOCKETS if (connect_type == (int) CONN_INTERNET) { char *ptr; gethostname (thishost, HOSTNAMSZ); if (!rflg) { /* attempt to generate a path * to this machine */ if ((ptr = getenv ("GNU_NODE")) != NULL) /* user specified a path */ strncpy (remotepath, ptr, QXE_PATH_MAX); } #if 0 /* This is really bogus... re-enable it if you must have it! */ #if defined (hp9000s800) else if (strcmp (thishost,hostarg)) { /* try /net/thishost */ strcpy (remotepath, "/net/"); /* (this fails using internet addresses) */ strcat (remotepath, thishost); } #endif #endif } else { /* same machines, no need for path */ remotepath[0] = '\0'; /* default is the empty path */ } #endif /* INTERNET_DOMAIN_SOCKETS */ #ifdef SYSV_IPC if ((msgp = (struct msgbuf *) malloc (sizeof *msgp + GSERV_BUFSZ)) == NULL) { fprintf (stderr, "%s: not enough memory for message buffer\n", progname); exit (1); } /* if */ msgp->mtext[0] = '\0'; /* ready for later strcats */ #endif /* SYSV_IPC */ if (suppress_windows_system) { char *term = getenv ("TERM"); if (!term) { fprintf (stderr, "%s: unknown terminal type\n", progname); exit (1); } sprintf (command, "(gnuserv-edit-files '(tty %s %s %d) '(", clean_string (tty), clean_string (term), (int)getpid ()); } else /* !suppress_windows_system */ { if (0) ; #ifdef HAVE_X_WINDOWS else if (display) sprintf (command, "(gnuserv-edit-files '(x %s) '(", clean_string (display)); #endif #ifdef HAVE_GTK else if (display) sprintf (command, /* #### We should probably do this sort of thing for other window systems. */ "(gnuserv-edit-files (assoc* t '((gtk nil) (x %s)) " ":key #'valid-device-type-p) '(", clean_string (display)); #endif #ifdef HAVE_MS_WINDOWS else sprintf (command, "(gnuserv-edit-files '(mswindows nil) '("); #endif } /* !suppress_windows_system */ send_string (s, command); if (!argv[i]) nofiles = 1; for (; argv[i]; i++) { if (i < argc - 1 && *argv[i] == '+') starting_line = atoi (argv[i++]); /* If the last argument is +something, treat it as a file. */ if (i == argc) --i; filename_expand (fullpath, argv[i]); #ifdef INTERNET_DOMAIN_SOCKETS path = (char *) malloc (strlen (remotepath) + strlen (fullpath) + 1); sprintf (path, "%s%s", remotepath, fullpath); #else path = my_strdup (fullpath); #endif if ( starting_line ) { sprintf (command, "(%d . %s)", starting_line, clean_string (path)); } else { sprintf (command, "(nil . %s)", clean_string (path)); } send_string (s, command); free (path); } /* for */ sprintf (command, ")%s%s", (quick || (nofiles && !suppress_windows_system)) ? " 'quick" : "", view ? " 'view" : ""); send_string (s, command); send_string (s, ")"); #ifdef SYSV_IPC if (connect_type == (int) CONN_IPC) disconnect_from_ipc_server (s, msgp, FALSE); #else /* !SYSV_IPC */ if (connect_type != (int) CONN_IPC) disconnect_from_server (s, FALSE); #endif /* !SYSV_IPC */ } /* not batch */ return 0; } /* main */
/* * Figure out what kind of terminal we're dealing with, and then read in * its termcap entry. */ static const char * get_termcap_entry(char *userarg) { int errret; char *p; const char *ttype; #if HAVE_GETTTYNAM struct ttyent *t; #else FILE *fp; #endif char *ttypath; if (userarg) { ttype = userarg; goto found; } /* Try the environment. */ if ((ttype = getenv("TERM")) != 0) goto map; if ((ttypath = ttyname(STDERR_FILENO)) != 0) { p = _nc_basename(ttypath); #if HAVE_GETTTYNAM /* * We have the 4.3BSD library call getttynam(3); that means * there's an /etc/ttys to look up device-to-type mappings in. * Try ttyname(3); check for dialup or other mapping. */ if ((t = getttynam(p))) { ttype = t->ty_type; goto map; } #else if ((fp = fopen("/etc/ttytype", "r")) != 0 || (fp = fopen("/etc/ttys", "r")) != 0) { char buffer[BUFSIZ]; char *s, *t, *d; while (fgets(buffer, sizeof(buffer), fp) != NULL) { for (s = buffer, t = d = 0; *s; s++) { if (isspace(UChar(*s))) *s = '\0'; else if (t == 0) t = s; else if (d == 0 && s != buffer && s[-1] == '\0') d = s; } if (t != 0 && d != 0 && !strcmp(d, p)) { ttype = strdup(t); fclose(fp); goto map; } } fclose(fp); } #endif /* HAVE_GETTTYNAM */ } /* If still undefined, use "unknown". */ ttype = "unknown"; map:ttype = mapped(ttype); /* * If not a path, remove TERMCAP from the environment so we get a * real entry from /etc/termcap. This prevents us from being fooled * by out of date stuff in the environment. */ found:if ((p = getenv("TERMCAP")) != 0 && !_nc_is_abs_path(p)) { /* 'unsetenv("TERMCAP")' is not portable. * The 'environ' array is better. */ int n; for (n = 0; environ[n] != 0; n++) { if (!strncmp("TERMCAP=", environ[n], 8)) { while ((environ[n] = environ[n + 1]) != 0) { n++; } break; } } } /* * ttype now contains a pointer to the type of the terminal. * If the first character is '?', ask the user. */ if (ttype[0] == '?') { if (ttype[1] != '\0') ttype = askuser(ttype + 1); else ttype = askuser(0); } /* Find the terminfo entry. If it doesn't exist, ask the user. */ while (setupterm((NCURSES_CONST char *) ttype, STDOUT_FILENO, &errret) != OK) { if (errret == 0) { (void) fprintf(stderr, "%s: unknown terminal type %s\n", _nc_progname, ttype); ttype = 0; } else { (void) fprintf(stderr, "%s: can't initialize terminal type %s (error %d)\n", _nc_progname, ttype, errret); ttype = 0; } ttype = askuser(ttype); } #if BROKEN_LINKER tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */ #endif return (ttype); }
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags , int argc, const char **argv) { const char *service=NULL, *tty=NULL; const char *user=NULL; int retval; unsigned setting; /* only interested in establishing credentials */ setting = flags; if (!(setting & PAM_ESTABLISH_CRED)) { D(("ignoring call - not for establishing credentials")); return PAM_SUCCESS; /* don't fail because of this */ } /* set service name */ if (pam_get_item(pamh, PAM_SERVICE, (const void **)&service) != PAM_SUCCESS || service == NULL) { _log_err("cannot find the current service name"); return PAM_ABORT; } /* set username */ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL || *user == '\0') { _log_err("cannot determine the user's name"); return PAM_USER_UNKNOWN; } /* set tty name */ if (pam_get_item(pamh, PAM_TTY, (const void **)&tty) != PAM_SUCCESS || tty == NULL) { D(("PAM_TTY not set, probing stdin")); tty = ttyname(STDIN_FILENO); if (tty == NULL) { _log_err("couldn't get the tty name"); return PAM_ABORT; } if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) { _log_err("couldn't set tty name"); return PAM_ABORT; } } if (strncmp("/dev/",tty,5) == 0) { /* strip leading /dev/ */ tty += 5; } /* good, now we have the service name, the user and the terminal name */ D(("service=%s", service)); D(("user=%s", user)); D(("tty=%s", tty)); #ifdef WANT_PWDB /* We initialize the pwdb library and check the account */ retval = pwdb_start(); /* initialize */ if (retval == PWDB_SUCCESS) { retval = check_account(service,tty,user); /* get groups */ (void) pwdb_end(); /* tidy up */ } else { D(("failed to initialize pwdb; %s", pwdb_strerror(retval))); _log_err("unable to initialize libpwdb"); retval = PAM_ABORT; } #else /* WANT_PWDB */ retval = check_account(service,tty,user); /* get groups */ #endif /* WANT_PWDB */ return retval; }
int main(int argc, char *argv[]) { FILE *f; char *ptr, *start; struct passwd *pwd; char *term_name; int c; int aflag = 0; int errflg = 0; int zflg = 0; int Zflg = 0; char *zonename = NULL; zoneid_t *zoneidlist = NULL; uint_t nzids_saved, nzids = 0; (void) setlocale(LC_ALL, ""); while ((c = getopt(argc, argv, "g:az:Z")) != EOF) switch (c) { case 'a': aflag++; break; case 'g': if (gflag) { (void) fprintf(stderr, "Only one group allowed\n"); return (1); } if ((pgrp = getgrnam(grpname = optarg)) == NULL) { (void) fprintf(stderr, "Unknown group %s\n", grpname); return (1); } gflag++; break; case 'z': zflg++; zonename = optarg; if (getzoneidbyname(zonename) == -1) { (void) fprintf(stderr, "Specified zone %s " "is invalid", zonename); return (1); } break; case 'Z': Zflg++; break; case '?': errflg++; break; } if (errflg) { (void) fprintf(stderr, "Usage: wall [-a] [-g group] [-z zone] [-Z] [files...]\n"); return (1); } if (zflg && Zflg) { (void) fprintf(stderr, "Cannot use -z with -Z\n"); return (1); } if (optind < argc) infile = argv[optind]; if (uname(&utsn) == -1) { (void) fprintf(stderr, "wall: uname() failed, %s\n", strerror(errno)); return (2); } (void) strcpy(systm, utsn.nodename); /* * Get the name of the terminal wall is running from. */ if ((term_name = ttyname(fileno(stderr))) != NULL) { /* * skip the leading "/dev/" in term_name */ (void) strncpy(line, &term_name[5], sizeof (line) - 1); } if (who[0] == '?') { if (pwd = getpwuid(getuid())) (void) strncpy(&who[0], pwd->pw_name, sizeof (who)); } f = stdin; if (infile) { f = fopen(infile, "r"); if (f == NULL) { (void) fprintf(stderr, "Cannot open %s\n", infile); return (1); } } start = &mesg[0]; ptr = start; while ((ptr - start) < 3000) { size_t n; if (fgets(ptr, &mesg[sizeof (mesg)] - ptr, f) == NULL) break; if ((n = strlen(ptr)) == 0) break; ptr += n; } (void) fclose(f); /* * If the request is from the rwall daemon then use the caller's * name and host. We determine this if all of the following is true: * 1) First 5 characters are "From " * 2) Next non-white characters are of the form "name@host:" */ if (strcmp(line, "???") == 0) { char rwho[MAXNAMLEN+1]; char rsystm[MAXNAMLEN+1]; char *cp; if (strncmp(mesg, "From ", 5) == 0) { cp = &mesg[5]; cp = copy_str_till(rwho, cp, '@', MAXNAMLEN + 1); if (rwho[0] != '\0') { cp = copy_str_till(rsystm, ++cp, ':', MAXNAMLEN + 1); if (rsystm[0] != '\0') { (void) strcpy(systm, rsystm); (void) strncpy(rwho, who, sizeof (who)); (void) strcpy(line, "rpc.rwalld"); } } } } (void) time(&tloc); (void) strftime(time_buf, sizeof (time_buf), DATE_FMT, localtime(&tloc)); if (zflg != 0) { if ((zoneidlist = malloc(sizeof (zoneid_t))) == NULL || (*zoneidlist = getzoneidbyname(zonename)) == -1) return (errno); nzids = 1; } else if (Zflg != 0) { if (zone_list(NULL, &nzids) != 0) return (errno); again: nzids *= 2; if ((zoneidlist = malloc(nzids * sizeof (zoneid_t))) == NULL) exit(errno); nzids_saved = nzids; if (zone_list(zoneidlist, &nzids) != 0) { (void) free(zoneidlist); return (errno); } if (nzids > nzids_saved) { free(zoneidlist); goto again; } } if (zflg || Zflg) { for (; nzids > 0; --nzids) sendmes_tozone(zoneidlist[nzids-1], aflag); free(zoneidlist); } else sendmes_tozone(getzoneid(), aflag); return (0); }