670 lines
19 KiB
Diff
670 lines
19 KiB
Diff
diff -up initscripts-8.54.1/rwtab.olpc initscripts-8.54.1/rwtab
|
|
--- initscripts-8.54.1/rwtab.olpc 2007-08-13 15:31:05.000000000 -0400
|
|
+++ initscripts-8.54.1/rwtab 2007-08-20 16:15:21.000000000 -0400
|
|
@@ -27,7 +27,6 @@ files /etc/adjtime
|
|
files /etc/fstab
|
|
files /etc/mtab
|
|
files /etc/ntp.conf
|
|
-files /etc/resolv.conf
|
|
files /etc/lvm/.cache
|
|
files /etc/lvm/archive
|
|
files /etc/lvm/backup
|
|
@@ -38,3 +37,4 @@ files /var/lib/iscsi
|
|
files /var/lib/logrotate.status
|
|
files /var/lib/ntp
|
|
files /var/lib/xen
|
|
+files /home/olpc/.Xauthority
|
|
diff -up initscripts-8.54.1/inittab.olpc initscripts-8.54.1/inittab
|
|
--- initscripts-8.54.1/inittab.olpc 2006-10-12 13:51:04.000000000 -0400
|
|
+++ initscripts-8.54.1/inittab 2007-08-09 18:15:11.000000000 -0400
|
|
@@ -15,7 +15,7 @@
|
|
# 5 - X11
|
|
# 6 - reboot (Do NOT set initdefault to this)
|
|
#
|
|
-id:3:initdefault:
|
|
+id:5:initdefault:
|
|
|
|
# System initialization.
|
|
si::sysinit:/etc/rc.d/rc.sysinit
|
|
@@ -44,10 +44,7 @@ pr:12345:powerokwait:/sbin/shutdown -c "
|
|
# Run gettys in standard runlevels
|
|
1:2345:respawn:/sbin/mingetty tty1
|
|
2:2345:respawn:/sbin/mingetty tty2
|
|
-3:2345:respawn:/sbin/mingetty tty3
|
|
-4:2345:respawn:/sbin/mingetty tty4
|
|
-5:2345:respawn:/sbin/mingetty tty5
|
|
-6:2345:respawn:/sbin/mingetty tty6
|
|
+3:2345:respawn:/sbin/agetty ttyS0 115200 vt100
|
|
|
|
# Run xdm in runlevel 5
|
|
-x:5:respawn:/etc/X11/prefdm -nodaemon
|
|
+x:5:respawn:/sbin/olpc-dm
|
|
diff -up /dev/null initscripts-8.54.1/src/olpc-dm.c
|
|
--- /dev/null 2007-08-09 20:48:29.426751273 -0400
|
|
+++ initscripts-8.54.1/src/olpc-dm.c 2007-08-09 18:15:11.000000000 -0400
|
|
@@ -0,0 +1,595 @@
|
|
+#include <unistd.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <pwd.h>
|
|
+#include <errno.h>
|
|
+#include <fcntl.h>
|
|
+#include <string.h>
|
|
+#include <time.h>
|
|
+#include <utmp.h>
|
|
+#include <termios.h>
|
|
+#include <setjmp.h>
|
|
+#include <ctype.h>
|
|
+#include <grp.h>
|
|
+#include <sys/ioctl.h>
|
|
+#include <sys/wait.h>
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <sys/file.h>
|
|
+#include <sys/syslog.h>
|
|
+#include <sys/sysmacros.h>
|
|
+#include <sys/param.h>
|
|
+
|
|
+#include <linux/major.h>
|
|
+
|
|
+#define OLPC_USER "olpc"
|
|
+
|
|
+#define TTY_MODE 0620
|
|
+#define TTYGRPNAME "tty"
|
|
+#define _PATH_HUSHLOGIN ".hushlogin"
|
|
+
|
|
+# include <security/pam_appl.h>
|
|
+# include <security/pam_misc.h>
|
|
+# define PAM_MAX_LOGIN_TRIES 3
|
|
+# define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \
|
|
+ fprintf(stderr,"\n%s\n",pam_strerror(pamh, retcode)); \
|
|
+ syslog(LOG_ERR,"%s",pam_strerror(pamh, retcode)); \
|
|
+ pam_end(pamh, retcode); exit(1); \
|
|
+ }
|
|
+# define PAM_END { \
|
|
+ pam_setcred(pamh, PAM_DELETE_CRED); \
|
|
+ retcode = pam_close_session(pamh,0); \
|
|
+ pam_end(pamh,retcode); \
|
|
+}
|
|
+
|
|
+int timeout = 60;
|
|
+
|
|
+struct passwd *pwd;
|
|
+
|
|
+static struct passwd pwdcopy;
|
|
+char hostaddress[16]; /* used in checktty.c */
|
|
+char *hostname; /* idem */
|
|
+static char *username, *tty_name, *tty_number;
|
|
+static char thishost[100];
|
|
+static pid_t pid;
|
|
+
|
|
+static inline void xstrncpy(char *dest, const char *src, size_t n) {
|
|
+ strncpy(dest, src, n-1);
|
|
+ dest[n-1] = 0;
|
|
+}
|
|
+
|
|
+static int childPid = 0;
|
|
+static volatile int got_sig = 0;
|
|
+
|
|
+
|
|
+
|
|
+static void
|
|
+parent_sig_handler(int signal)
|
|
+{
|
|
+ if(childPid)
|
|
+ kill(-childPid, signal);
|
|
+ else
|
|
+ got_sig = 1;
|
|
+ if(signal == SIGTERM)
|
|
+ kill(-childPid, SIGHUP); /* because the shell often ignores SIGTERM */
|
|
+}
|
|
+
|
|
+/* Nice and simple code provided by Linus Torvalds 16-Feb-93 */
|
|
+/* Nonblocking stuff by Maciej W. Rozycki, macro@ds2.pg.gda.pl, 1999.
|
|
+ He writes: "Login performs open() on a tty in a blocking mode.
|
|
+ In some cases it may make login wait in open() for carrier infinitely,
|
|
+ for example if the line is a simplistic case of a three-wire serial
|
|
+ connection. I believe login should open the line in the non-blocking mode
|
|
+ leaving the decision to make a connection to getty (where it actually
|
|
+ belongs). */
|
|
+static void
|
|
+opentty(const char * tty)
|
|
+{
|
|
+ int i, fd, flags;
|
|
+
|
|
+ fd = open(tty, O_RDWR | O_NONBLOCK);
|
|
+ if (fd == -1)
|
|
+ {
|
|
+ syslog(LOG_ERR, "FATAL: can't reopen tty: %s",
|
|
+ strerror(errno));
|
|
+ sleep(1);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ flags = fcntl(fd, F_GETFL);
|
|
+ flags &= ~O_NONBLOCK;
|
|
+ fcntl(fd, F_SETFL, flags);
|
|
+
|
|
+ for (i = 0; i < fd; i++)
|
|
+ close(i);
|
|
+ for (i = 0; i < 3; i++)
|
|
+ if (fd != i)
|
|
+ dup2(fd, i);
|
|
+ if (fd >= 3)
|
|
+ close(fd);
|
|
+}
|
|
+
|
|
+/* true if the filedescriptor fd is a console tty, very Linux specific */
|
|
+static int
|
|
+consoletty(int fd)
|
|
+{
|
|
+ struct stat stb;
|
|
+
|
|
+ if ((fstat(fd, &stb) >= 0)
|
|
+ && (major(stb.st_rdev) == TTY_MAJOR)
|
|
+ && (minor(stb.st_rdev) < 64))
|
|
+ {
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void
|
|
+olpc_login(void)
|
|
+{
|
|
+ extern int optind;
|
|
+ extern char *optarg, **environ;
|
|
+ struct group *gr;
|
|
+ int fflag, hflag, pflag, cnt;
|
|
+ int quietlog;
|
|
+ char *domain, *ttyn;
|
|
+ char tbuf[MAXPATHLEN + 2];
|
|
+ char *termenv;
|
|
+ int retcode;
|
|
+ pam_handle_t *pamh = NULL;
|
|
+ struct pam_conv conv = { misc_conv, NULL };
|
|
+ struct sigaction sa, oldsa_hup, oldsa_term;
|
|
+ char vcsn[20], vcsan[20];
|
|
+ pid = getpid();
|
|
+
|
|
+ signal(SIGQUIT, SIG_IGN);
|
|
+ signal(SIGINT, SIG_IGN);
|
|
+
|
|
+ setpriority(PRIO_PROCESS, 0, 0);
|
|
+
|
|
+ gethostname(tbuf, sizeof(tbuf));
|
|
+ xstrncpy(thishost, tbuf, sizeof(thishost));
|
|
+ domain = index(tbuf, '.');
|
|
+
|
|
+ username = tty_name = hostname = NULL;
|
|
+ fflag = hflag = pflag = 0;
|
|
+
|
|
+ for (cnt = getdtablesize(); cnt > 2; cnt--)
|
|
+ close(cnt);
|
|
+
|
|
+ /* TODO: This is not right, we should open the display :0 but we need
|
|
+ * to start X first. Flow should go like this once we get rid of startx
|
|
+ * seteuid 0, setuid olpc -> start X -> start pam session -> fork ->
|
|
+ * seteuid olpc -> start clients
|
|
+ */
|
|
+ ttyn = "/dev/tty2";
|
|
+
|
|
+ if (strncmp(ttyn, "/dev/", 5) == 0)
|
|
+ tty_name = ttyn+5;
|
|
+ else
|
|
+ tty_name = ttyn;
|
|
+
|
|
+ if (strncmp(ttyn, "/dev/tty", 8) == 0)
|
|
+ tty_number = ttyn+8;
|
|
+ else
|
|
+ {
|
|
+ char *p = ttyn;
|
|
+ while (*p && !isdigit(*p)) p++;
|
|
+ tty_number = p;
|
|
+ }
|
|
+
|
|
+ printf("TTY: %s\n", tty_name);
|
|
+
|
|
+ /* find names of Virtual Console devices, for later mode change */
|
|
+ snprintf(vcsn, sizeof(vcsn), "/dev/vcs%s", tty_number);
|
|
+ snprintf(vcsan, sizeof(vcsan), "/dev/vcsa%s", tty_number);
|
|
+
|
|
+ /* set pgid to pid */
|
|
+ setpgrp();
|
|
+ /* this means that setsid() will fail */
|
|
+
|
|
+ {
|
|
+ struct termios tt, ttt;
|
|
+
|
|
+ tcgetattr(0, &tt);
|
|
+ ttt = tt;
|
|
+ ttt.c_cflag &= ~HUPCL;
|
|
+
|
|
+ /* These can fail, e.g. with ttyn on a read-only filesystem */
|
|
+ chown(ttyn, 0, 0);
|
|
+ chmod(ttyn, TTY_MODE);
|
|
+
|
|
+ /* Kill processes left on this tty */
|
|
+ tcsetattr(0,TCSAFLUSH,&ttt);
|
|
+ signal(SIGHUP, SIG_IGN); /* so vhangup() wont kill us */
|
|
+ vhangup();
|
|
+ signal(SIGHUP, SIG_DFL);
|
|
+
|
|
+ /* open stdin,stdout,stderr to the tty */
|
|
+ opentty(ttyn);
|
|
+
|
|
+ /* restore tty modes */
|
|
+ tcsetattr(0,TCSAFLUSH,&tt);
|
|
+ }
|
|
+
|
|
+ openlog("login", LOG_ODELAY, LOG_AUTHPRIV);
|
|
+
|
|
+ retcode = pam_start("login", OLPC_USER, &conv, &pamh);
|
|
+ if(retcode != PAM_SUCCESS)
|
|
+ {
|
|
+ fprintf(stderr, "login: PAM Failure, aborting: %s\n",
|
|
+ pam_strerror(pamh, retcode));
|
|
+ syslog(LOG_ERR, "Couldn't initialize PAM: %s",
|
|
+ pam_strerror(pamh, retcode));
|
|
+ exit(99);
|
|
+ }
|
|
+ /* hostname & tty are either set to NULL or their correct values,
|
|
+ depending on how much we know */
|
|
+ retcode = pam_set_item(pamh, PAM_RHOST, hostname);
|
|
+ PAM_FAIL_CHECK;
|
|
+ retcode = pam_set_item(pamh, PAM_TTY, tty_name);
|
|
+ PAM_FAIL_CHECK;
|
|
+ retcode = pam_set_item(pamh, PAM_USER_PROMPT, "You shouldn't see this login prompt");
|
|
+ PAM_FAIL_CHECK;
|
|
+
|
|
+ /*
|
|
+ * Authentication may be skipped (for example, during krlogin, rlogin, etc...),
|
|
+ * but it doesn't mean that we can skip other account checks. The account
|
|
+ * could be disabled or password expired (althought kerberos ticket is valid).
|
|
+ * -- kzak@redhat.com (22-Feb-2006)
|
|
+ */
|
|
+ retcode = pam_acct_mgmt(pamh, 0);
|
|
+
|
|
+ if(retcode == PAM_NEW_AUTHTOK_REQD)
|
|
+ retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
|
|
+
|
|
+ PAM_FAIL_CHECK;
|
|
+
|
|
+ /*
|
|
+ * Grab the user information out of the password file for future usage
|
|
+ * First get the username that we are actually using, though.
|
|
+ */
|
|
+ retcode = pam_get_item(pamh, PAM_USER, (const void **) &username);
|
|
+ PAM_FAIL_CHECK;
|
|
+
|
|
+ if (!username || !*username)
|
|
+ {
|
|
+ fprintf(stderr, "\nSession setup problem, abort.\n");
|
|
+ syslog(LOG_ERR, "NULL user name in %s:%d. Abort.",
|
|
+ __FUNCTION__, __LINE__);
|
|
+ pam_end(pamh, PAM_SYSTEM_ERR);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ if (!(pwd = getpwnam(username)))
|
|
+ {
|
|
+ fprintf(stderr, "\nSession setup problem, abort.\n");
|
|
+ syslog(LOG_ERR, "Invalid user name \"%s\" in %s:%d. Abort.",
|
|
+ username, __FUNCTION__, __LINE__);
|
|
+ pam_end(pamh, PAM_SYSTEM_ERR);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Create a copy of the pwd struct - otherwise it may get
|
|
+ * clobbered by PAM
|
|
+ */
|
|
+ memcpy(&pwdcopy, pwd, sizeof(*pwd));
|
|
+ pwd = &pwdcopy;
|
|
+ pwd->pw_name = strdup(pwd->pw_name);
|
|
+ pwd->pw_passwd = strdup(pwd->pw_passwd);
|
|
+ pwd->pw_gecos = strdup(pwd->pw_gecos);
|
|
+ pwd->pw_dir = strdup(pwd->pw_dir);
|
|
+ pwd->pw_shell = strdup(pwd->pw_shell);
|
|
+ if (!pwd->pw_name || !pwd->pw_passwd || !pwd->pw_gecos ||
|
|
+ !pwd->pw_dir || !pwd->pw_shell)
|
|
+ {
|
|
+ fprintf(stderr, "login: Out of memory\n");
|
|
+ syslog(LOG_ERR, "Out of memory");
|
|
+ pam_end(pamh, PAM_SYSTEM_ERR);
|
|
+ exit(1);
|
|
+ }
|
|
+ username = pwd->pw_name;
|
|
+
|
|
+ /*
|
|
+ * Initialize the supplementary group list.
|
|
+ * This should be done before pam_setcred because
|
|
+ * the PAM modules might add groups during pam_setcred.
|
|
+ */
|
|
+ if (initgroups(username, pwd->pw_gid) < 0)
|
|
+ {
|
|
+ syslog(LOG_ERR, "initgroups: %m");
|
|
+ fprintf(stderr, "\nSession setup problem, abort.\n");
|
|
+ pam_end(pamh, PAM_SYSTEM_ERR);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ retcode = pam_open_session(pamh, 0);
|
|
+ PAM_FAIL_CHECK;
|
|
+
|
|
+ retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED);
|
|
+ if (retcode != PAM_SUCCESS)
|
|
+ pam_close_session(pamh, 0);
|
|
+ PAM_FAIL_CHECK;
|
|
+
|
|
+ /* committed to login -- turn off timeout */
|
|
+ alarm((unsigned int)0);
|
|
+
|
|
+ endpwent();
|
|
+
|
|
+ /* This requires some explanation: As root we may not be able to
|
|
+ read the directory of the user if it is on an NFS mounted
|
|
+ filesystem. We temporarily set our effective uid to the user-uid
|
|
+ making sure that we keep root privs. in the real uid.
|
|
+
|
|
+ A portable solution would require a fork(), but we rely on Linux
|
|
+ having the BSD setreuid() */
|
|
+
|
|
+ {
|
|
+ char tmpstr[MAXPATHLEN];
|
|
+ uid_t ruid = getuid();
|
|
+ gid_t egid = getegid();
|
|
+
|
|
+ /* avoid snprintf - old systems do not have it, or worse,
|
|
+ have a libc in which snprintf is the same as sprintf */
|
|
+ if (strlen(pwd->pw_dir) + sizeof(_PATH_HUSHLOGIN) + 2 > MAXPATHLEN)
|
|
+ quietlog = 0;
|
|
+ else
|
|
+ {
|
|
+ sprintf(tmpstr, "%s/%s", pwd->pw_dir, _PATH_HUSHLOGIN);
|
|
+ setregid(-1, pwd->pw_gid);
|
|
+ setreuid(0, pwd->pw_uid);
|
|
+ quietlog = (access(tmpstr, R_OK) == 0);
|
|
+ setuid(0); /* setreuid doesn't do it alone! */
|
|
+ setreuid(ruid, 0);
|
|
+ setregid(-1, egid);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* for linux, write entries in utmp and wtmp */
|
|
+ {
|
|
+ struct utmp ut;
|
|
+ struct utmp *utp;
|
|
+ struct timeval tv;
|
|
+
|
|
+ utmpname(_PATH_UTMP);
|
|
+ setutent();
|
|
+
|
|
+ /* Find pid in utmp.
|
|
+ login sometimes overwrites the runlevel entry in /var/run/utmp,
|
|
+ confusing sysvinit. I added a test for the entry type, and the problem
|
|
+ was gone. (In a runlevel entry, st_pid is not really a pid but some number
|
|
+ calculated from the previous and current runlevel).
|
|
+ Michael Riepe <michael@stud.uni-hannover.de>
|
|
+ */
|
|
+ while ((utp = getutent()))
|
|
+ if (utp->ut_pid == pid
|
|
+ && utp->ut_type >= INIT_PROCESS
|
|
+ && utp->ut_type <= DEAD_PROCESS)
|
|
+ break;
|
|
+
|
|
+ /* If we can't find a pre-existing entry by pid, try by line.
|
|
+ BSD network daemons may rely on this. (anonymous) */
|
|
+ if (utp == NULL)
|
|
+ {
|
|
+ setutent();
|
|
+ ut.ut_type = LOGIN_PROCESS;
|
|
+ strncpy(ut.ut_line, tty_name, sizeof(ut.ut_line));
|
|
+ utp = getutline(&ut);
|
|
+ }
|
|
+
|
|
+ if (utp)
|
|
+ {
|
|
+ memcpy(&ut, utp, sizeof(ut));
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ /* some gettys/telnetds don't initialize utmp... */
|
|
+ memset(&ut, 0, sizeof(ut));
|
|
+ }
|
|
+
|
|
+ if (ut.ut_id[0] == 0)
|
|
+ strncpy(ut.ut_id, tty_number, sizeof(ut.ut_id));
|
|
+
|
|
+ strncpy(ut.ut_user, username, sizeof(ut.ut_user));
|
|
+ xstrncpy(ut.ut_line, tty_name, sizeof(ut.ut_line));
|
|
+ gettimeofday(&tv, NULL);
|
|
+ ut.ut_tv.tv_sec = tv.tv_sec;
|
|
+ ut.ut_tv.tv_usec = tv.tv_usec;
|
|
+ ut.ut_type = USER_PROCESS;
|
|
+ ut.ut_pid = pid;
|
|
+ if (hostname)
|
|
+ {
|
|
+ xstrncpy(ut.ut_host, hostname, sizeof(ut.ut_host));
|
|
+ if (hostaddress[0])
|
|
+ memcpy(&ut.ut_addr_v6, hostaddress, sizeof(ut.ut_addr_v6));
|
|
+ }
|
|
+
|
|
+ pututline(&ut);
|
|
+ endutent();
|
|
+
|
|
+ updwtmp(_PATH_WTMP, &ut);
|
|
+ }
|
|
+
|
|
+ chown(ttyn, pwd->pw_uid,
|
|
+ (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
|
|
+ chmod(ttyn, TTY_MODE);
|
|
+
|
|
+ /* if tty is one of the VC's then change owner and mode of the
|
|
+ special /dev/vcs devices as well */
|
|
+ if (consoletty(0))
|
|
+ {
|
|
+ chown(vcsn, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid));
|
|
+ chown(vcsan, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid));
|
|
+ chmod(vcsn, TTY_MODE);
|
|
+ chmod(vcsan, TTY_MODE);
|
|
+ }
|
|
+
|
|
+
|
|
+ setgid(pwd->pw_gid);
|
|
+
|
|
+ if (*pwd->pw_shell == '\0')
|
|
+ pwd->pw_shell = _PATH_BSHELL;
|
|
+
|
|
+ {
|
|
+ char *ep;
|
|
+
|
|
+ if(!((ep = getenv("TERM")) && (termenv = strdup(ep))))
|
|
+ termenv = "dumb";
|
|
+ }
|
|
+
|
|
+
|
|
+ environ = (char**)malloc(sizeof(char*));
|
|
+ memset(environ, 0, sizeof(char*));
|
|
+
|
|
+ setenv("HOME", pwd->pw_dir, 0); /* legal to override */
|
|
+ setenv("PATH", _PATH_DEFPATH, 1);
|
|
+
|
|
+ setenv("SHELL", pwd->pw_shell, 1);
|
|
+ setenv("TERM", termenv, 1);
|
|
+
|
|
+ /* mailx will give a funny error msg if you forget this one */
|
|
+ {
|
|
+ char tmp[MAXPATHLEN];
|
|
+ /* avoid snprintf */
|
|
+ if (sizeof(_PATH_MAILDIR) + strlen(pwd->pw_name) + 1 < MAXPATHLEN)
|
|
+ {
|
|
+ sprintf(tmp, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
|
|
+ setenv("MAIL",tmp,0);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* LOGNAME is not documented in login(1) but
|
|
+ HP-UX 6.5 does it. We'll not allow modifying it.
|
|
+ */
|
|
+ setenv("LOGNAME", pwd->pw_name, 1);
|
|
+
|
|
+ {
|
|
+ int i;
|
|
+ char ** env = pam_getenvlist(pamh);
|
|
+
|
|
+ if (env != NULL)
|
|
+ {
|
|
+ for (i=0; env[i]; i++)
|
|
+ putenv(env[i]);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!strncmp(tty_name, "ttyS", 4))
|
|
+ syslog(LOG_INFO, "DIALUP AT %s BY %s", tty_name, pwd->pw_name);
|
|
+
|
|
+ /* allow tracking of good logins.
|
|
+ -steve philp (sphilp@mail.alliance.net) */
|
|
+
|
|
+ if (hostname)
|
|
+ syslog(LOG_INFO, "LOGIN ON %s BY %s FROM %s", tty_name,
|
|
+ pwd->pw_name, hostname);
|
|
+ else
|
|
+ syslog(LOG_INFO, "LOGIN ON %s BY %s", tty_name,
|
|
+ pwd->pw_name);
|
|
+
|
|
+ signal(SIGALRM, SIG_DFL);
|
|
+ signal(SIGQUIT, SIG_DFL);
|
|
+ signal(SIGTSTP, SIG_IGN);
|
|
+
|
|
+ /*
|
|
+ * We must fork before setuid() because we need to call
|
|
+ * pam_close_session() as root.
|
|
+ */
|
|
+ memset(&sa, 0, sizeof(sa));
|
|
+ sa.sa_handler = SIG_IGN;
|
|
+ sigaction(SIGINT, &sa, NULL);
|
|
+
|
|
+ sigaction(SIGHUP, &sa, &oldsa_hup); /* ignore while we detach from the tty */
|
|
+ ioctl(0, TIOCNOTTY, NULL);
|
|
+
|
|
+ sa.sa_handler = parent_sig_handler;
|
|
+ sigaction(SIGHUP, &sa, NULL);
|
|
+ sigaction(SIGTERM, &sa, &oldsa_term);
|
|
+
|
|
+ closelog();
|
|
+ childPid = fork();
|
|
+ if (childPid < 0)
|
|
+ {
|
|
+ int errsv = errno;
|
|
+ /* error in fork() */
|
|
+ fprintf(stderr, "login: failure forking: %s", strerror(errsv));
|
|
+ PAM_END;
|
|
+ exit(0);
|
|
+ }
|
|
+
|
|
+ if (childPid)
|
|
+ {
|
|
+ close(0); close(1); close(2);
|
|
+ sa.sa_handler = SIG_IGN;
|
|
+ sigaction(SIGQUIT, &sa, NULL);
|
|
+ sigaction(SIGINT, &sa, NULL);
|
|
+ while(wait(NULL) == -1 && errno == EINTR) /**/ ;
|
|
+ openlog("login", LOG_ODELAY, LOG_AUTHPRIV);
|
|
+ PAM_END;
|
|
+ exit(0);
|
|
+ }
|
|
+
|
|
+ sigaction(SIGHUP, &oldsa_hup, NULL);
|
|
+ sigaction(SIGTERM, &oldsa_term, NULL);
|
|
+ if(got_sig) exit(1);
|
|
+
|
|
+ /* child */
|
|
+ /*
|
|
+ * Problem: if the user's shell is a shell like ash that doesnt do
|
|
+ * setsid() or setpgrp(), then a ctrl-\, sending SIGQUIT to every
|
|
+ * process in the pgrp, will kill us.
|
|
+ */
|
|
+
|
|
+ /* start new session */
|
|
+ setsid();
|
|
+
|
|
+ /* make sure we have a controlling tty */
|
|
+ openlog("login", LOG_ODELAY, LOG_AUTHPRIV); /* reopen */
|
|
+
|
|
+ /*
|
|
+ * TIOCSCTTY: steal tty from other process group.
|
|
+ */
|
|
+ if (ioctl(0, TIOCSCTTY, (char *)1))
|
|
+ {
|
|
+ syslog(LOG_ERR, "Couldn't set controlling terminal: %s", strerror(errno));
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ signal(SIGINT, SIG_DFL);
|
|
+
|
|
+ /* discard permissions last so can't get killed and drop core */
|
|
+ if(setuid(pwd->pw_uid) < 0 && pwd->pw_uid)
|
|
+ {
|
|
+ syslog(LOG_ALERT, "setuid() failed");
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ /* wait until here to change directory! */
|
|
+ if (chdir(pwd->pw_dir) < 0)
|
|
+ {
|
|
+ printf("No directory %s!\n", pwd->pw_dir);
|
|
+ if (chdir("/"))
|
|
+ exit(0);
|
|
+ pwd->pw_dir = "/";
|
|
+ printf("Logging in with home = \"/\".\n");
|
|
+ }
|
|
+
|
|
+ /* fork and exec startx. wait on child to cleanup */
|
|
+ execl("/usr/bin/startx", "startx", "--", "-fp", "built-ins", "-wr", NULL);
|
|
+ exit(0);
|
|
+}
|
|
+
|
|
+int
|
|
+main (int argc,
|
|
+ char **argv)
|
|
+{
|
|
+ /* Use PAM to login as user*/
|
|
+ olpc_login ();
|
|
+
|
|
+ /* fork and exec startx. wait on child to cleanup */
|
|
+ execl("/usr/bin/startx", "startx", "--", "-fp", "built-ins", "-wr", NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
diff -up initscripts-8.54.1/src/Makefile.olpc initscripts-8.54.1/src/Makefile
|
|
--- initscripts-8.54.1/src/Makefile.olpc 2006-09-27 15:59:05.000000000 -0400
|
|
+++ initscripts-8.54.1/src/Makefile 2007-08-09 18:15:11.000000000 -0400
|
|
@@ -1,7 +1,8 @@
|
|
CFLAGS+=$(RPM_OPT_FLAGS) -Wall -D_GNU_SOURCE
|
|
|
|
PROGS=usernetctl doexec netreport testd usleep ipcalc initlog \
|
|
- fstab-decode getkey ppp-watch consoletype genhostid rename_device
|
|
+ fstab-decode getkey ppp-watch consoletype genhostid rename_device \
|
|
+ olpc-dm
|
|
PPPWATCH_OBJS=ppp-watch.o shvar.o
|
|
INITLOG_OBJS=initlog.o process.o
|
|
USLEEP_OBJS=usleep.o
|
|
@@ -28,6 +29,7 @@ install:
|
|
install -m 755 consoletype $(ROOT)/sbin/consoletype
|
|
install -m 755 rename_device $(ROOT)/lib/udev/rename_device
|
|
install -m 755 ccw_init $(ROOT)/lib/udev/ccw_init
|
|
+ install -m 755 olpc-dm $(ROOT)/sbin/olpc-dm
|
|
install -m 644 initlog.1 $(ROOT)$(mandir)/man1
|
|
install -m 644 genhostid.1 $(ROOT)$(mandir)/man1
|
|
install -m 644 doexec.1 $(ROOT)$(mandir)/man1
|
|
@@ -77,5 +79,8 @@ ppp-watch.o: ppp-watch.c
|
|
rename_device: rename_device.c
|
|
$(CC) $(CFLAGS) `pkg-config glib-2.0 --cflags` -o $@ $< `pkg-config glib-2.0 --libs`
|
|
|
|
+olpc-dm: olpc-dm.c
|
|
+ $(CC) $(CFLAGS) olpc-dm.c -o $@ -I/usr/include -lpam -lpam_misc
|
|
+
|
|
kmodule: kmodule.o
|
|
$(CC) $(LDFLAGS) -o $@ $< -Wl,-Bstatic -lpopt -Wl,-Bdynamic -lkudzu -lpci
|