summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorGeorge Lebl <jirka@5z.com>2001-08-22 23:11:55 +0000
committerGeorge Lebl <jirka@src.gnome.org>2001-08-22 23:11:55 +0000
commit6addcb9098b45bf43074de34157812c77822bd4d (patch)
tree215d0a2ea5a97551314fafdb66a16e013bf977f0 /utils
parent2ea344ca665dbe6faa9d6058ed989ff59eb8d8e7 (diff)
downloadgdm-6addcb9098b45bf43074de34157812c77822bd4d.tar.gz
Add two new small sbin utils. gdmopen is like open (based on it) but
Wed Aug 22 23:01:59 2001 George Lebl <jirka@5z.com> * configure.in, Makefile.am, utils/gdmopen.c, utils/gdmaskpass.c: Add two new small sbin utils. gdmopen is like open (based on it) but better suited for gdm. Exitcode is returned so no temp files are needed. Process is cleaned up on a signal, the new vt is deallocated after use. And unlike openvt this thing actually waits for the child. Gdmaskpass just asks for the root password, for use in the XKeepsCrashing script. Both of these things will only run as root as I'm too paranoid and it doesn't make sense for them to run otherwise for gdm anyway. * configure.in: Fix sbin expansion. * daemon/gdm.c, daemon/misc.[ch], daemon/slave.c, daemon/server.c: Use gdmopen to run dialog and add helper functions for doing this. * daemon/gdm.h, daemon/slave.c, daemon/server.[ch]: When a server is busy, ask the user if we want to run it on a new display number or retry. * daemon/gdm.c, daemon/misc.c, daemon/slave.c: Make sure to whack any extra helper processes we launch when we are killed so that we don't leave things like 'dialog' processes around * daemon/gdm.c, config/XKeepsCrashing: Use gdmaskpass, ask if the user wants to view X logs if X is crashing. And use gdmopen in the script and correctly abort with exit 32. Also make it not use the ugly tempfile stuff (Though a tempfile is still given to the script for now) * gdm.spec.in: raise epoch to 1, people abuse this field, and if they do abuse it again and raise it beyond 1, I'll just max it out since it makes package upgrading not work. * daemon/slave.c, daemon/verify-(pam|crypt|shadow).c: add /sbin/nologin as a thing to test for for disabled logins in addition to /bin/false and /bin/true (it worked, but this adds a nicer message) * daemon/xdmcp.c: fix a warning. * gui/gdmflexiserver.desktop.in: kill TryExec here
Diffstat (limited to 'utils')
-rw-r--r--utils/.cvsignore6
-rw-r--r--utils/Makefile.am41
-rw-r--r--utils/gdmaskpass.c58
-rw-r--r--utils/gdmopen.c201
4 files changed, 306 insertions, 0 deletions
diff --git a/utils/.cvsignore b/utils/.cvsignore
new file mode 100644
index 00000000..005306fe
--- /dev/null
+++ b/utils/.cvsignore
@@ -0,0 +1,6 @@
+Makefile
+Makefile.in
+.libs
+.deps
+gdmaskpass
+gdmopen
diff --git a/utils/Makefile.am b/utils/Makefile.am
new file mode 100644
index 00000000..d24fce3e
--- /dev/null
+++ b/utils/Makefile.am
@@ -0,0 +1,41 @@
+## Process this file with automake to produce makefile.in
+CFLAGS += -g -Wall \
+ -Wpointer-arith \
+ -Wmissing-prototypes -Wmissing-declarations
+
+DEFS += -DGDM_CONFIG_FILE=\"@sysconfdir@/gdm/gdm.conf\" \
+ -DGDM_FACTORY_CONFIG_FILE=\"@sysconfdir@/gdm/factory-gdm.conf\" \
+ -DGDM_GLADE_DIR=\"@datadir@/gdm\"
+
+INCLUDES = \
+ -I. \
+ -I.. \
+ -I$(top_srcdir)/daemon \
+ -I$(top_srcdir)/vicious-extensions \
+ -I$(includedir) \
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
+ @LIBGLADE_CFLAGS@ \
+ @PIXBUF_CFLAGS@ \
+ $(GNOME_CFLAGS) \
+ $(GNOME_INCLUDEDIR)
+
+sbin_PROGRAMS = \
+ @GDMASKPASS@ \
+ @GDMOPEN@
+EXTRA_PROGRAMS = gdmaskpass gdmopen
+
+gdmaskpass_SOURCES = \
+ gdmaskpass.c
+
+gdmopen_SOURCES = \
+ gdmopen.c
+
+gdmaskpass_LDADD = \
+ $(GNOME_LIBDIR) \
+ $(INTLLIBS) \
+ -lpam \
+ -lpam_misc
+
+gdmopen_LDADD = \
+ $(GNOME_LIBDIR) \
+ $(INTLLIBS)
diff --git a/utils/gdmaskpass.c b/utils/gdmaskpass.c
new file mode 100644
index 00000000..8c083a68
--- /dev/null
+++ b/utils/gdmaskpass.c
@@ -0,0 +1,58 @@
+/* Simple pam thingie to ask the root password, for use in XKeepsCrashing
+ * script. */
+#include "config.h"
+#include <gnome.h>
+#include <stdio.h>
+#include <locale.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+
+static struct pam_conv conv = {
+ misc_conv,
+ NULL
+};
+
+int
+main (int argc, char *argv[])
+{
+ pam_handle_t *pamh;
+ const char *username = "root";
+ int retval;
+ int tries = 3;
+
+ if (getuid () != geteuid () ||
+ getuid () != 0) {
+ fprintf (stderr, _("gdmaskpass only runs as root\n"));
+ return 1;
+ }
+
+ if (argc >= 2) {
+ username = argv[1];
+ }
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, GNOMELOCALEDIR);
+ textdomain (PACKAGE);
+
+ for (tries = 3; tries > 0; tries --) {
+ if ((retval = pam_start ("gdm", username, &conv, &pamh)) != PAM_SUCCESS) {
+ pam_end (pamh, retval);
+ pamh = NULL;
+ printf (_("Authentication failure!\n"));
+ continue;
+ }
+ if ((retval = pam_authenticate (pamh, 0)) != PAM_SUCCESS) {
+ pam_end (pamh, retval);
+ pamh = NULL;
+ printf (_("Authentication failure!\n"));
+ continue;
+ }
+ break;
+ }
+
+ if (pamh != NULL)
+ pam_end (pamh, retval);
+
+ return (retval == PAM_SUCCESS) ? 0 : 1;
+}
diff --git a/utils/gdmopen.c b/utils/gdmopen.c
new file mode 100644
index 00000000..d5c8574d
--- /dev/null
+++ b/utils/gdmopen.c
@@ -0,0 +1,201 @@
+/*
+ * gdmopen.c by the Queen of England, based upon original open.
+ * Simplified for the purposes of gdm. All useless (to me)
+ * functionality stripped. Also returns what the command returns.
+ * Return of 66 means error with open.
+ *
+ * Original header:
+ *
+ * open.c open a vt to run a new command (or shell).
+ *
+ * Copyright (c) 1994 by Jon Tombs <jon@gtex02.us.es>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <pwd.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/vt.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE !FALSE
+#endif
+
+
+/*
+ * Where your VTs are hidden
+ */
+#ifdef __linux__
+#define VTNAME "/dev/tty%d"
+#endif
+
+#ifdef ESIX_5_3_2_D
+#define VTBASE "/dev/vt%02d"
+#endif
+
+const char *GDMOPENversion = "gdmopen " VERSION " simplified (was: open: 1.4 (c) Jon Tombs 1994)";
+
+#ifndef VTNAME
+#error vt device name must be defined in open.c
+#endif
+
+static pid_t child_pid = -1;
+struct vt_stat vt;
+static int vtno;
+static int fd = 0;
+static int do_dealloc = FALSE;
+
+static void
+sighandler (int sig)
+{
+ if (child_pid > 1) {
+ if (kill (child_pid, sig) == 0)
+ waitpid (child_pid, NULL, 0);
+ }
+
+ if (do_dealloc) {
+ /* Switch back... */
+ (void) ioctl(fd, VT_ACTIVATE, vt.v_active);
+ /* wait to be really sure we have switched */
+ (void) ioctl(fd, VT_WAITACTIVE, vt.v_active);
+
+ /* Now deallocate our new one */
+ (void) ioctl(fd, VT_DISALLOCATE, vtno);
+ }
+
+ /* Kill myself with this signal */
+ signal (sig, SIG_DFL);
+ kill (getpid (), sig);
+}
+
+int
+main (int argc, char *argv[])
+{
+ char vtname[256];
+ int status;
+
+ if (getuid () != geteuid () ||
+ getuid () != 0) {
+ fprintf (stderr, "gdmopen: Only root wants to run me\n");
+ return 66;
+ }
+
+ signal (SIGTERM, sighandler);
+ signal (SIGINT, sighandler);
+ signal (SIGHUP, sighandler);
+
+ if (argc <= 1) {
+ fprintf (stderr, "gdmopen: must supply a command!\n");
+ return 66;
+ }
+
+ fd = open ("/dev/console", O_WRONLY, 0);
+ if (fd < 0) {
+ perror ("gdmopen: Failed to open /dev/console");
+ return 66;
+ }
+
+ errno = 0;
+ if ((ioctl(fd, VT_OPENQRY, &vtno) < 0) || (vtno == -1)) {
+ perror ("gdmopen: Cannot find a free VT");
+ close (fd);
+ return 66;
+ }
+
+ if (ioctl(fd, VT_GETSTATE, &vt) < 0) {
+ perror ("gdmopen: can't get VTstate");
+ close(fd);
+ return 66;
+ }
+
+ snprintf (vtname, sizeof (vtname), VTNAME, vtno);
+
+ chown (vtname, 0, -1);
+
+ child_pid = fork();
+ if (child_pid == 0) {
+
+ signal (SIGTERM, SIG_DFL);
+ signal (SIGINT, SIG_DFL);
+ signal (SIGHUP, SIG_DFL);
+
+ /* leave current vt */
+ if (
+#ifdef ESIX_5_3_2_D
+ setpgrp() < 0
+#else
+ setsid() < 0
+#endif
+ ) {
+ fprintf(stderr, "open: Unable to set new session (%s)\n",
+ strerror(errno));
+ }
+ close(0);
+ close(1);
+ close(2);
+ close(fd);
+
+ /* and grab new one */
+ fd = open (vtname, O_RDWR);
+ if (fd < 0) { /* Shouldn't happen */
+ _exit (66); /* silently die */
+ }
+ dup(fd);
+ dup(fd);
+
+ /*
+ * Can't tell anyone if any of these fail, so throw away
+ * the return values
+ */
+ (void) ioctl(fd, VT_ACTIVATE, vtno);
+ /* wait to be really sure we have switched */
+ (void) ioctl(fd, VT_WAITACTIVE, vtno);
+
+ execvp (argv[1], &argv[1]);
+
+ _exit (66); /* failed */
+ }
+
+ if (child_pid < 0) {
+ perror ("gdmopen: fork() error");
+ return 66;
+ }
+
+ do_dealloc = TRUE;
+
+ waitpid (child_pid, &status, 0);
+ child_pid = -1;
+
+ do_dealloc = FALSE;
+
+ /* Switch back... */
+ (void) ioctl(fd, VT_ACTIVATE, vt.v_active);
+ /* wait to be really sure we have switched */
+ (void) ioctl(fd, VT_WAITACTIVE, vt.v_active);
+
+ /* Now deallocate our new one */
+ (void) ioctl(fd, VT_DISALLOCATE, vtno);
+
+ close (fd);
+
+ if (WIFEXITED (status))
+ return WEXITSTATUS (status);
+ else
+ return 66;
+}