diff options
Diffstat (limited to 'kdm/backend')
40 files changed, 0 insertions, 18277 deletions
diff --git a/kdm/backend/CMakeLists.txt b/kdm/backend/CMakeLists.txt deleted file mode 100644 index cd98b3a9c..000000000 --- a/kdm/backend/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -# FIXME this is far from complete!!! - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_BINARY_DIR} - ${DBUS_TQT_INCLUDE_DIRS} -) - -link_directories( - ${DBUS_TQT_LIBRARY_DIRS} -) - -##### tdm (executable) ########################## - -add_custom_command( OUTPUT config.ci - COMMAND perl -w ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def config.ci - DEPENDS ${CMAKE_SOURCE_DIR}/tdm/confproc.pl ${CMAKE_SOURCE_DIR}/tdm/config.def ) - -set_property( SOURCE auth.c APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/config.ci ) - -if( WITH_XDMCP ) - set( XDMCP_LIBRARIES "Xdmcp" ) -else() - set( XDMCP_LIBRARIES "" ) -endif() - -tde_add_executable( tdm - SOURCES - access.c auth.c bootman.c choose.c client.c consolekit.c - ctrl.c daemon.c dm.c dpylist.c error.c genauth.c - inifile.c krb5auth.c mitauth.c netaddr.c policy.c - process.c protodpy.c reset.c resource.c rpcauth.c - server.c session.c sessreg.c socket.c streams.c - util.c xdmauth.c xdmcp.c - LINK X11 ${XAU_LIBRARIES} ${DBUS_TQT_LIBRARIES} ${CRYPT_LIBRARY} ${PAM_LIBRARY} ${XDMCP_LIBRARIES} - DESTINATION ${BIN_INSTALL_DIR} -) diff --git a/kdm/backend/Imakefile b/kdm/backend/Imakefile deleted file mode 100644 index f3b4e0050..000000000 --- a/kdm/backend/Imakefile +++ /dev/null @@ -1,203 +0,0 @@ -/* well, we have no subdirs ... -#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' -*/ - -#ifdef DEBUG -CDEBUGFLAGS := $(CDEBUGFLAGS) -g -#endif - -#ifndef BuildBoth -#define BuildBoth (defined(LinuxArchitecture) && !UseElfFormat) -#endif - -#ifndef LinuxShadowSuite -#define LinuxShadowSuite NO -#endif - -#if FSUseSyslog -LOG_DEFINES = -DUSE_SYSLOG -#endif - -#ifdef NoXDMCP -XDMCPLIB = -#else -XDMCP_DEFINES = -DXDMCP -#endif - -#if HasXdmAuth -XDMAUTH_DEFINES = -DHASXDMAUTH -XDMAUTHOBJS = xdmauth.o -XDMAUTHSRCS = xdmauth.c -#endif - -#if HasSecureRPC -RPC_DEFINES = -DSECURE_RPC -RPCOBJS = rpcauth.o -RPCSRCS = rpcauth.c -RPCLIB = -lrpcsvc -#endif - -#if HasKrbIV -#if NOAFS -KRBIV_DEFINES = KrbIVDefines -DNO_AFS -#else -KRBIV_DEFINES = KrbIVDefines -#endif -KRBIV_INCLUDES = KrbIVIncludes -KRBIVLIB = KrbIVLibraries -#endif - -#if HasKrb5 -KRB5_DEFINES = Krb5Defines -KRB5_INCLUDE = Krb5Includes -KRB5OBJS = krb5auth.o -KRB5SRCS = krb5auth.c -#endif - -/* This is correct for Linux and FreeBSD */ -#if HasPam -PAM_LIBRARIES = PamLibraries -PAM_DEFINES = -DUSE_PAM -#endif - -#if HasPam -#undef HasShadowPasswd -#define HasShadowPasswd NO -#undef HasLibCrypt -#define HasLibCrypt NO -#endif - -/* -#if HasBSDAuth -BSDAUTH_DEFINES = -DUSE_BSDAUTH -#endif -*/ - -#if SystemV4 || HasShadowPasswd - -#if !LinuxShadowSuite -PWD_DEFINES = -DUSESHADOW -#else -PWD_DEFINES = -DUSESHADOW -DSHADOWSUITE -#endif - -#if !defined(i386IscArchitecture) && !defined(i386ScoArchitecture) && !defined(LinuxArchitecture) && !defined(NTOArchitecture) && !defined(SGIArchitecture) -SYS_LIBRARIES3 = -lresolv -#endif -#if SystemV || defined(SequentArchitecture) -SYS_LIBRARIES1 = -lsec -#endif -#if defined(LinuxArchitecture) && (!UseElfFormat || LinuxShadowSuite) -SYS_LIBRARIES1 = -lshadow -#endif - -#endif - -#if defined(UltrixArchitecture) -SYS_LIBRARIES1 = -lauth -#endif - -#if (defined(AIXArchitecture) && (OSMajorVersion >= 3)) -SYS_LIBRARIES1 = -ls -#endif - -#if HasLibCrypt -#ifdef SpecialLibCrypt -CRYPT_LIBRARIES = SpecialLibCrypt -#else -CRYPT_LIBRARIES = -lcrypt -#if defined(LynxOSArchitecture) -CRYPT_DEFINES = -DHAS_CRYPT -#endif -#endif -#endif - -#if HasBSD44Sockets -SOCK_DEFINES = -DBSD44SOCKETS -#endif - -#if defined(i386Architecture) || defined(AmigaArchitecture) -FRAGILE_DEFINES = -DFRAGILE_DEV_MEM -#endif - -#ifdef RandomDefines -RANDOM_DEFINES = RandomDefines -#elif defined(OpenBSDArchitecture) -RANDOM_DEFINES = -DARC4_RANDOM -#elif defined(LinuxArchitecture) -RANDOM_DEFINES = -DDEV_RANDOM=\"/dev/urandom\" -#elif defined(NetBSDArchitecture) && \ - ((OSMajorVersion > 1) || \ - (OSMajorVersion == 1 && OSMinorVersion > 3)) -RANDOM_DEFINES = -DDEV_RANDOM=\"/dev/urandom\" -#endif - - -#if HasSetUserContext -USER_CONTEXT_DEFINES = -DHAS_SETUSERCONTEXT -# XXX - only FreeBSD has this in libutil -SYS_LIBRARIES1 = -lutil -#endif - -#if HasSetProcTitle -PROCTITLE_DEFINES = -DHAS_SETPROCTITLE -#endif - - SYS_LIBRARIES = $(SYS_LIBRARIES1) $(SYS_LIBRARIES2) $(SYS_LIBRARIES3) - - INCLUDES = $(KRB5_INCLUDE) - DEPLIBS = $(DEPXLIB) $(DEPXAUTHLIB) $(DEPXDMCPLIB) - LOCAL_LIBRARIES = $(XLIB) $(XAUTHLIB) \ - $(XDMCPLIB) $(RPCLIB) $(PAM_LIBRARIES) \ - $(CRYPT_LIBRARIES) $(KRBIVLIB) - - COMMSRCS = auth.c daemon.c server.c dpylist.c dm.c error.c \ - netaddr.c reset.c resource.c protodpy.c policy.c \ - session.c socket.c streams.c util.c xdmcp.c \ - process.c mitauth.c \ - genauth.c access.c choose.c consolekit.c \ - $(XDMAUTHSRCS) $(RPCSRCS) $(KRB5SRCS) - COMMOBJS = auth.o daemon.o server.o dpylist.o dm.o error.o \ - netaddr.o reset.o resource.o protodpy.o policy.o \ - session.o socket.o streams.o util.o xdmcp.o \ - process.o mitauth.o \ - genauth.o access.o choose.o consolekit.o \ - $(XDMAUTHOBJS) $(RPCOBJS) $(KRB5OBJS) - - SRCS1 = $(COMMSRCS) client.c - OBJS1 = $(COMMOBJS) client.o - -#if BuildBoth - SRCS2 = $(COMMSRCS) clientsh.c - OBJS2 = $(COMMOBJS) clientsh.o - - XDM_SHADOW = xdm-shadow -#endif - - PROGRAMS = xdm $(XDM_SHADOW) - - - OSMAJORVERSION = OSMajorVersion - OSMINORVERSION = OSMinorVersion - CONN_DEFINES = $(CONNECTION_FLAGS) - DEFINES = $(SIGNAL_DEFINES) $(LOG_DEFINES) \ - $(CRYPT_DEFINES)$(PWD_DEFINES) \ - $(BSDAUTH_DEFINES) $(PAM_DEFINES) $(USER_CONTEXT_DEFINES) \ - $(XDMAUTH_DEFINES) $(RPC_DEFINES) $(KRB5_DEFINES) \ - $(XDMCP_DEFINES) $(SOCK_DEFINES) $(CONN_DEFINES) \ - $(FRAGILE_DEFINES) $(RANDOM_DEFINES) $(PROCTITLE_DEFINES) \ - -DOSMAJORVERSION=$(OSMAJORVERSION) -DOSMINORVERSION=$(OSMINORVERSION) \ - -Dconst= - -ComplexProgramTarget_1(xdm,$(LOCAL_LIBRARIES),NullParameter) -#if BuildBoth -NormalProgramTarget(xdm-shadow,$(OBJS2),$(DEPLIBS),$(LOCAL_LIBRARIES),-lshadow) -InstallProgram(xdm-shadow,$(BINDIR)) -ObjectFromSpecialSource(clientsh,client,-DUSESHADOW) -#endif - -#if defined(FreeBSDArchitecture) && (OSMajorVersion < 2) -XCOMM only for daemon.c? it's used in some other places, too. -SpecialCObjectRule(daemon,$(ICONFIGFILES),-UCSRG_BASED) -#endif - diff --git a/kdm/backend/Makefile.am b/kdm/backend/Makefile.am deleted file mode 100644 index 6b5779d51..000000000 --- a/kdm/backend/Makefile.am +++ /dev/null @@ -1,47 +0,0 @@ -# forcibly remove thread-related defines & flags -AUTOMAKE_OPTIONS = foreign -CPPFLAGS = $(USER_INCLUDES) $(X_INCLUDES) $(KRB4_INCS) $(KRB5_INCS) $(DBUS_INCS) -I.. -I../.. -LDFLAGS = $(USER_LDFLAGS) $(X_LDFLAGS) $(X_RPATH) $(KRB4_RPATH) $(KRB5_RPATH) -LDADD = $(LIB_X11) -lXau $(LIBXDMCP) $(PASSWDLIBS) $(LIBSHADOW) $(LIBGEN) \ - $(LIB_LIBS) $(KRB4_LIBS) $(KRB5_LIBS) $(DBUS_LIBS) $(LIBSOCKET) $(LIBRESOLV) \ - $(LIBUCB) $(LIBUTIL) $(LIBPOSIX4) - -bin_PROGRAMS = tdm -tdm_SOURCES = \ - access.c \ - auth.c \ - bootman.c \ - choose.c \ - client.c \ - consolekit.c \ - ctrl.c \ - daemon.c \ - dm.c \ - dpylist.c \ - error.c \ - genauth.c \ - inifile.c \ - krb5auth.c \ - mitauth.c \ - netaddr.c \ - policy.c \ - process.c \ - protodpy.c \ - reset.c \ - resource.c \ - rpcauth.c \ - server.c \ - session.c \ - sessreg.c \ - socket.c \ - streams.c \ - util.c \ - xdmauth.c \ - xdmcp.c - -EXTRA_DIST = printf.c - -noinst_HEADERS = dm.h dm_socket.h dm_error.h dm_auth.h greet.h - -# for unsermake (automake is handled by SUBDIRS in ../) -tdm_COMPILE_FIRST = ../config.ci diff --git a/kdm/backend/access.c b/kdm/backend/access.c deleted file mode 100644 index 82736be57..000000000 --- a/kdm/backend/access.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - -Copyright 1990, 1998 The Open Group -Copyright 2001,2004 Oswald Buddenhagen <[email protected]> -Copyright 2002 Sun Microsystems, Inc. All rights reserved. - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * Access control for XDMCP - keep a database of allowable display addresses - * and (potentially) a list of hosts to send ForwardQuery packets to - */ - -#include <config.h> - -#ifdef XDMCP - -#include "dm.h" -#include "dm_error.h" -#include "dm_socket.h" - -#include <stdio.h> -#include <ctype.h> - -#include <netdb.h> -#if defined(IPv6) && defined(AF_INET6) -# include <arpa/inet.h> -#endif - -typedef struct { - short int type; - union { - char *aliasPattern; - char *hostPattern; - struct _displayAddress { - CARD16 connectionType; - ARRAY8 hostAddress; - } displayAddress; - } entry; -} HostEntry; - -typedef struct { - short int iface; - short int mcasts; - short int nmcasts; -} ListenEntry; - -typedef struct { - char *name; - short int hosts; - short int nhosts; -} AliasEntry; - -typedef struct { - short int entries; - short int nentries; - short int hosts; - short int nhosts; - short int flags; -} AclEntry; - -typedef struct { - HostEntry *hostList; - ListenEntry *listenList; - AliasEntry *aliasList; - AclEntry *acList; - short int nHosts, nListens, nAliases, nAcls; - CfgDep dep; -} AccArr; - -static AccArr accData[1]; - - -static ARRAY8 localAddress; - -ARRAY8Ptr -getLocalAddress( void ) -{ - static int haveLocalAddress; - - if (!haveLocalAddress) { -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai; - - if (getaddrinfo( localHostname(), NULL, NULL, &ai )) { - XdmcpAllocARRAY8( &localAddress, 4 ); - localAddress.data[0] = 127; - localAddress.data[1] = 0; - localAddress.data[2] = 0; - localAddress.data[3] = 1; - } else { - if (ai->ai_family == AF_INET) { - XdmcpAllocARRAY8( &localAddress, sizeof(struct in_addr) ); - memcpy( localAddress.data, - &((struct sockaddr_in *)ai->ai_addr)->sin_addr, - sizeof(struct in_addr) ); - } else /* if (ai->ai_family == AF_INET6) */ { - XdmcpAllocARRAY8( &localAddress, sizeof(struct in6_addr) ); - memcpy( localAddress.data, - &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, - sizeof(struct in6_addr) ); - } - freeaddrinfo( ai ); -#else - struct hostent *hostent; - - if ((hostent = gethostbyname( localHostname() ))) { - XdmcpAllocARRAY8( &localAddress, hostent->h_length ); - memmove( localAddress.data, hostent->h_addr, hostent->h_length ); -#endif - haveLocalAddress = 1; - } - } - return &localAddress; -} - - -void -ScanAccessDatabase( int force ) -{ - struct _displayAddress *da; - char *cptr; - int nChars, i; - - Debug( "ScanAccessDatabase\n" ); - if (Setjmp( cnftalk.errjmp )) - return; /* may memleak */ - if (startConfig( GC_gXaccess, &accData->dep, force ) <= 0) - return; - if (accData->hostList) - free( accData->hostList ); - accData->nHosts = GRecvInt(); - accData->nListens = GRecvInt(); - accData->nAliases = GRecvInt(); - accData->nAcls = GRecvInt(); - nChars = GRecvInt(); - if (!(accData->hostList = (HostEntry *) - Malloc( accData->nHosts * sizeof(HostEntry) + - accData->nListens * sizeof(ListenEntry) + - accData->nAliases * sizeof(AliasEntry) + - accData->nAcls * sizeof(AclEntry) + - nChars ))) - { - CloseGetter(); - return; - } - accData->listenList = (ListenEntry *)(accData->hostList + accData->nHosts); - accData->aliasList = (AliasEntry *)(accData->listenList + accData->nListens); - accData->acList = (AclEntry *)(accData->aliasList + accData->nAliases); - cptr = (char *)(accData->acList + accData->nAcls); - for (i = 0; i < accData->nHosts; i++) { - switch ((accData->hostList[i].type = GRecvInt())) { - case HOST_ALIAS: - accData->hostList[i].entry.aliasPattern = cptr; - cptr += GRecvStrBuf( cptr ); - break; - case HOST_PATTERN: - accData->hostList[i].entry.hostPattern = cptr; - cptr += GRecvStrBuf( cptr ); - break; - case HOST_ADDRESS: - da = &accData->hostList[i].entry.displayAddress; - da->hostAddress.data = (unsigned char *)cptr; - cptr += (da->hostAddress.length = GRecvArrBuf( cptr )); - switch (GRecvInt()) - { -#ifdef AF_INET - case AF_INET: - da->connectionType = FamilyInternet; - break; -#endif -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - da->connectionType = FamilyInternet6; - break; -#endif -#ifdef AF_DECnet - case AF_DECnet: - da->connectionType = FamilyDECnet; - break; -#endif -/*#ifdef AF_UNIX - case AF_UNIX: -#endif*/ - default: - da->connectionType = FamilyLocal; - break; - } - break; - case HOST_BROADCAST: - break; - default: - LogError( "Received unknown host type %d from config reader\n", accData->hostList[i].type ); - return; - } - } - for (i = 0; i < accData->nListens; i++) { - accData->listenList[i].iface = GRecvInt(); - accData->listenList[i].mcasts = GRecvInt(); - accData->listenList[i].nmcasts = GRecvInt(); - } - for (i = 0; i < accData->nAliases; i++) { - accData->aliasList[i].name = cptr; - cptr += GRecvStrBuf( cptr ); - accData->aliasList[i].hosts = GRecvInt(); - accData->aliasList[i].nhosts = GRecvInt(); - } - for (i = 0; i < accData->nAcls; i++) { - accData->acList[i].entries = GRecvInt(); - accData->acList[i].nentries = GRecvInt(); - accData->acList[i].hosts = GRecvInt(); - accData->acList[i].nhosts = GRecvInt(); - accData->acList[i].flags = GRecvInt(); - } -} - - -/* Returns non-0 if string is matched by pattern. Does case folding. - */ -static int -patternMatch( const char *string, const char *pattern ) -{ - int p, s; - - if (!string) - string = ""; - - for (;;) { - s = *string++; - switch (p = *pattern++) { - case '*': - if (!*pattern) - return 1; - for (string--; *string; string++) - if (patternMatch( string, pattern )) - return 1; - return 0; - case '?': - if (s == '\0') - return 0; - break; - case '\0': - return s == '\0'; - case '\\': - p = *pattern++; - /* fall through */ - default: - if (tolower( p ) != tolower( s )) - return 0; - } - } -} - - -#define MAX_DEPTH 32 - -static void -scanHostlist( int fh, int nh, - ARRAY8Ptr clientAddress, CARD16 connectionType, - ChooserFunc function, char *closure, - int broadcast, int *haveLocalhost ) -{ - HostEntry *h; - AliasEntry *a; - int na; - - for (h = accData->hostList + fh; nh; nh--, h++) { - switch (h->type) { - case HOST_ALIAS: - for (a = accData->aliasList, na = accData->nAliases; na; na--, a++) - if (patternMatch( a->name, h->entry.aliasPattern )) /* XXX originally swapped, no wildcards in alias name matching */ - scanHostlist( a->hosts, a->nhosts, - clientAddress, connectionType, - function, closure, broadcast, - haveLocalhost ); - break; - case HOST_ADDRESS: - if (XdmcpARRAY8Equal( getLocalAddress(), &h->entry.displayAddress.hostAddress )) - *haveLocalhost = 1; - else if (function) - (*function)( connectionType, &h->entry.displayAddress.hostAddress, closure ); - break; - case HOST_BROADCAST: - if (broadcast && function) - (*function)( FamilyBroadcast, 0, closure ); - break; - default: - break; - } - } -} - -static int -scanEntrylist( int fh, int nh, - ARRAY8Ptr clientAddress, CARD16 connectionType, - char **clientName ) -{ - HostEntry *h; - AliasEntry *a; - int na; - - for (h = accData->hostList + fh; nh; nh--, h++) { - switch (h->type) { - case HOST_ALIAS: - for (a = accData->aliasList, na = accData->nAliases; na; na--, a++) - if (patternMatch( a->name, h->entry.aliasPattern )) - if (scanEntrylist( a->hosts, a->nhosts, - clientAddress, connectionType, - clientName )) - return 1; - break; - case HOST_PATTERN: - if (!*clientName) - *clientName = NetworkAddressToHostname( connectionType, - clientAddress ); - if (patternMatch( *clientName, h->entry.hostPattern )) - return 1; - break; - case HOST_ADDRESS: - if (h->entry.displayAddress.connectionType == connectionType && - XdmcpARRAY8Equal( &h->entry.displayAddress.hostAddress, - clientAddress )) - return 1; - break; - default: - break; - } - } - return 0; -} - -static AclEntry * -matchAclEntry( ARRAY8Ptr clientAddress, CARD16 connectionType, int direct ) -{ - AclEntry *e, *re; - char *clientName = 0; - int ne; - - for (e = accData->acList, ne = accData->nAcls, re = 0; ne; ne--, e++) - if (!e->nhosts == direct) - if (scanEntrylist( e->entries, e->nentries, - clientAddress, connectionType, - &clientName )) - { - re = e; - break; - } - if (clientName) - free( clientName ); - return re; -} - -/* - * calls the given function for each valid indirect entry. Returns TRUE if - * the local host exists on any of the lists, else FALSE - */ -int -ForEachMatchingIndirectHost( ARRAY8Ptr clientAddress, - CARD16 connectionType, - ChooserFunc function, char *closure ) -{ - AclEntry *e; - int haveLocalhost = 0; - - e = matchAclEntry( clientAddress, connectionType, 0 ); - if (e && !(e->flags & a_notAllowed)) { - if (e->flags & a_useChooser) { - ARRAY8Ptr choice; - - choice = IndirectChoice( clientAddress, connectionType ); - if (!choice || XdmcpARRAY8Equal( getLocalAddress(), choice )) - haveLocalhost = 1; - else - (*function)( connectionType, choice, closure ); - } else - scanHostlist( e->hosts, e->nhosts, clientAddress, connectionType, - function, closure, FALSE, &haveLocalhost ); - } - return haveLocalhost; -} - -int -UseChooser( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - AclEntry *e; - - e = matchAclEntry( clientAddress, connectionType, 0 ); - return e && !(e->flags & a_notAllowed) && (e->flags & a_useChooser) && - !IndirectChoice( clientAddress, connectionType ); -} - -void -ForEachChooserHost( ARRAY8Ptr clientAddress, CARD16 connectionType, - ChooserFunc function, char *closure ) -{ - AclEntry *e; - int haveLocalhost = 0; - - e = matchAclEntry( clientAddress, connectionType, 0 ); - if (e && !(e->flags & a_notAllowed) && (e->flags & a_useChooser)) - scanHostlist( e->hosts, e->nhosts, clientAddress, connectionType, - function, closure, TRUE, &haveLocalhost ); - if (haveLocalhost) - (*function)( connectionType, getLocalAddress(), closure ); -} - -/* - * returns TRUE if the given client is acceptable to the local host. The - * given display client is acceptable if it occurs without a host list. - */ -int -AcceptableDisplayAddress( ARRAY8Ptr clientAddress, CARD16 connectionType, - xdmOpCode type ) -{ - AclEntry *e; - - if (type == INDIRECT_QUERY) - return 1; - - e = matchAclEntry( clientAddress, connectionType, 1 ); - return e && !(e->flags & a_notAllowed) && - (type != BROADCAST_QUERY || !(e->flags & a_notBroadcast)); -} - -void -ForEachListenAddr( ListenFunc listenfunction, ListenFunc mcastfunction, - void **closure ) -{ - int i, j, ifc, mc, nmc; - - for (i = 0; i < accData->nListens; i++) { - ifc = accData->listenList[i].iface; - (*listenfunction)( ifc < 0 ? 0 : - &accData->hostList[ifc].entry.displayAddress.hostAddress, - closure ); - mc = accData->listenList[i].mcasts; - nmc = accData->listenList[i].nmcasts; - for (j = 0; j < nmc; j++, mc++) - (*mcastfunction)( &accData->hostList[mc].entry.displayAddress.hostAddress, - closure ); - } -} -#endif /* XDMCP */ diff --git a/kdm/backend/auth.c b/kdm/backend/auth.c deleted file mode 100644 index bd183142c..000000000 --- a/kdm/backend/auth.c +++ /dev/null @@ -1,1238 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * maintain the authorization generation daemon - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> - -#include <sys/ioctl.h> - -#include "dm_socket.h" -#ifdef DNETCONN -# include <netdnet/dnetdb.h> -#endif - -#if (defined(_POSIX_SOURCE) && !defined(_AIX) && !defined(__QNX__)) || defined(__hpux) || defined(__svr4__) /* XXX */ -# define NEED_UTSNAME -# include <sys/utsname.h> -#endif - -#ifdef __GNU__ -# include <netdb.h> -# undef SIOCGIFCONF -#else /* __GNU__ */ -# include <net/if.h> -# ifdef __svr4__ -# include <netdb.h> -# include <sys/sockio.h> -# include <sys/stropts.h> -# endif -# ifdef __EMX__ -# define link rename -# define chown(a,b,c) -# include <io.h> -# endif -#endif /* __GNU__ */ - -struct AuthProtocol { - unsigned short name_length; - const char *name; - void (*InitAuth)( unsigned short len, const char *name ); - Xauth *(*GetAuth)( unsigned short len, const char *name ); -#ifdef XDMCP - void (*GetXdmcpAuth)( struct protoDisplay *pdpy, - unsigned short authorizationNameLen, - const char *authorizationName ); -#endif - int inited; -}; - -#ifdef XDMCP -# define xdmcpauth(arg) , arg -#else -# define xdmcpauth(arg) -#endif - -static struct AuthProtocol AuthProtocols[] = { -{ (unsigned short)18, "MIT-MAGIC-COOKIE-1", - MitInitAuth, MitGetAuth xdmcpauth(NULL), 0 -}, -#ifdef HASXDMAUTH -{ (unsigned short)19, "XDM-AUTHORIZATION-1", - XdmInitAuth, XdmGetAuth xdmcpauth(XdmGetXdmcpAuth), 0 -}, -#endif -#ifdef SECURE_RPC -{ (unsigned short)9, "SUN-DES-1", - SecureRPCInitAuth, SecureRPCGetAuth xdmcpauth(NULL), 0 -}, -#endif -#ifdef K5AUTH -{ (unsigned short)14, "MIT-KERBEROS-5", - Krb5InitAuth, Krb5GetAuth xdmcpauth(NULL), 0 -}, -#endif -}; - -static struct AuthProtocol * -findProtocol( unsigned short name_length, const char *name ) -{ - unsigned i; - - for (i = 0; i < as(AuthProtocols); i++) - if (AuthProtocols[i].name_length == name_length && - memcmp( AuthProtocols[i].name, name, name_length ) == 0) - { - return &AuthProtocols[i]; - } - return (struct AuthProtocol *)0; -} - -int -ValidAuthorization( unsigned short name_length, const char *name ) -{ - if (findProtocol( name_length, name )) - return TRUE; - return FALSE; -} - -static Xauth * -GenerateAuthorization( unsigned short name_length, const char *name ) -{ - struct AuthProtocol *a; - Xauth *auth = 0; - - Debug( "GenerateAuthorization %s\n", name ); - if ((a = findProtocol( name_length, name ))) { - if (!a->inited) { - (*a->InitAuth)( name_length, name ); - a->inited = TRUE; - } - auth = (*a->GetAuth)( name_length, name ); - if (auth) { - Debug( "got %p (%d %.*s) %02[*hhx\n", auth, - auth->name_length, auth->name_length, auth->name, - auth->data_length, auth->data ); - } else - Debug( "got (null)\n" ); - } else - Debug( "unknown authorization %s\n", name ); - return auth; -} - -#ifdef XDMCP - -void -SetProtoDisplayAuthorization( struct protoDisplay *pdpy, - unsigned short authorizationNameLen, - const char *authorizationName ) -{ - struct AuthProtocol *a; - Xauth *auth; - - a = findProtocol( authorizationNameLen, authorizationName ); - pdpy->xdmcpAuthorization = pdpy->fileAuthorization = 0; - if (a) { - if (!a->inited) { - (*a->InitAuth)( authorizationNameLen, authorizationName ); - a->inited = TRUE; - } - if (a->GetXdmcpAuth) { - (*a->GetXdmcpAuth)( pdpy, authorizationNameLen, authorizationName ); - auth = pdpy->xdmcpAuthorization; - } else { - auth = (*a->GetAuth)( authorizationNameLen, authorizationName ); - pdpy->fileAuthorization = auth; - pdpy->xdmcpAuthorization = 0; - } - if (auth) - Debug( "got %p (%d %.*s)\n", auth, - auth->name_length, auth->name_length, auth->name ); - else - Debug( "got (null)\n" ); - } -} - -#endif /* XDMCP */ - -void -CleanUpFileName( const char *src, char *dst, int len ) -{ - while (*src) { - if (--len <= 0) - break; - switch (*src & 0x7f) { - case '/': - *dst++ = '_'; - break; - case '-': - *dst++ = '.'; - break; - default: - *dst++ = (*src & 0x7f); - } - ++src; - } - *dst = '\0'; -} - - -static FILE * -fdOpenW( int fd ) -{ - FILE *f; - - if (fd >= 0) { - if ((f = fdopen( fd, "w" ))) - return f; - close( fd ); - } - return 0; -} - -static FILE * -mkTempFile( char *nambuf, int namelen ) -{ - FILE *f; - int r; - - for (r = 0; r < 100; r++) { - randomStr( nambuf + namelen ); - if ((f = fdOpenW( open( nambuf, O_WRONLY | O_CREAT | O_EXCL, 0600 ) ))) - return f; - if (errno != EEXIST) - break; - } - return 0; -} - -#define NAMELEN 255 - -static FILE * -MakeServerAuthFile( struct display *d ) -{ - FILE *f; - int i; - char cleanname[NAMELEN], nambuf[NAMELEN+128]; - - /* - * Some paranoid, but still not sufficient (DoS was still possible) - * checks used to be here. I removed all this stuff because - * a) authDir is supposed to be /var/run/xauth (=safe) or similar and - * b) even if it's not (say, /tmp), we create files safely (hopefully). - */ - if (mkdir( authDir, 0755 ) < 0 && errno != EEXIST) - return 0; - CleanUpFileName( d->name, cleanname, NAMELEN - 8 ); - i = sprintf( nambuf, "%s/A%s-", authDir, cleanname ); - if ((f = mkTempFile( nambuf, i ))) { - StrDup( &d->authFile, nambuf ); - return f; - } - return 0; -} - -int -SaveServerAuthorizations( struct display *d, Xauth **auths, int count ) -{ - FILE *auth_file; - int i; - - if (!d->authFile && d->clientAuthFile && *d->clientAuthFile) - StrDup( &d->authFile, d->clientAuthFile ); - if (d->authFile) { - if (!(auth_file = fdOpenW( creat( d->authFile, 0600 ) ))) { - LogError( "Cannot open X server authorization file %s\n", d->authFile ); - free( d->authFile ); - d->authFile = NULL; - return FALSE; - } - } else { - if (!(auth_file = MakeServerAuthFile( d ))) { - LogError( "Cannot create X server authorization file\n" ); - return FALSE; - } - } - Debug( "file: %s auth: %p\n", d->authFile, auths ); - for (i = 0; i < count; i++) { - /* - * User-based auths may not have data until - * a user logs in. In which case don't write - * to the auth file so xrdb and setup programs don't fail. - */ - if (auths[i]->data_length > 0) - if (!XauWriteAuth( auth_file, auths[i] ) || - fflush( auth_file ) == EOF) - { - fclose( auth_file ); - LogError( "Cannot write X server authorization file %s\n", - d->authFile ); - free( d->authFile ); - d->authFile = NULL; - return FALSE; - } - } - fclose( auth_file ); - return TRUE; -} - -void -SetLocalAuthorization( struct display *d ) -{ - Xauth *auth, **auths; - int i, j; - - if (d->authorizations) - { - for (i = 0; i < d->authNum; i++) - XauDisposeAuth( d->authorizations[i] ); - free( (char *)d->authorizations ); - d->authorizations = (Xauth **)NULL; - d->authNum = 0; - } - Debug( "SetLocalAuthorization %s, auths %[s\n", d->name, d->authNames ); - if (!d->authNames) - return; - for (i = 0; d->authNames[i]; i++) - ; - d->authNameNum = i; - if (d->authNameLens) - free( (char *)d->authNameLens ); - d->authNameLens = (unsigned short *)Malloc( d->authNameNum * sizeof(unsigned short) ); - if (!d->authNameLens) - return; - for (i = 0; i < d->authNameNum; i++) - d->authNameLens[i] = strlen( d->authNames[i] ); - auths = (Xauth **)Malloc( d->authNameNum * sizeof(Xauth *) ); - if (!auths) - return; - j = 0; - for (i = 0; i < d->authNameNum; i++) { - auth = GenerateAuthorization( d->authNameLens[i], d->authNames[i] ); - if (auth) - auths[j++] = auth; - } - if (SaveServerAuthorizations( d, auths, j )) { - d->authorizations = auths; - d->authNum = j; - } else { - for (i = 0; i < j; i++) - XauDisposeAuth( auths[i] ); - free( (char *)auths ); - } -} - -/* - * Set the authorization to use for xdm's initial connection - * to the X server. Cannot use user-based authorizations - * because no one has logged in yet, so we don't have any - * user credentials. - * Well, actually we could use SUN-DES-1 because we tell the server - * to allow root in. This is bogus and should be fixed. - */ -void -SetAuthorization( struct display *d ) -{ - register Xauth **auth = d->authorizations; - int i; - - for (i = 0; i < d->authNum; i++) { - if (auth[i]->name_length == 9 && - memcmp( auth[i]->name, "SUN-DES-1", 9 ) == 0) - continue; - if (auth[i]->name_length == 14 && - memcmp( auth[i]->name, "MIT-KERBEROS-5", 14 ) == 0) - continue; - XSetAuthorization( auth[i]->name, (int)auth[i]->name_length, - auth[i]->data, (int)auth[i]->data_length ); - } -} - -static int -openFiles( const char *name, char *new_name, FILE **oldp, FILE **newp ) -{ - strcat( strcpy( new_name, name ), "-n" ); - if (!(*newp = - fdOpenW( creat( new_name, 0600 ) ))) { - Debug( "can't open new file %s\n", new_name ); - return 0; - } - *oldp = fopen( name, "r" ); - Debug( "opens succeeded %s %s\n", name, new_name ); - return 1; -} - -struct addrList { - struct addrList *next; - unsigned short family, address_length, number_length; - char data[1]; -}; - -static struct addrList *addrs; - -static void -initAddrs( void ) -{ - addrs = 0; -} - -static void -doneAddrs( void ) -{ - struct addrList *a, *n; - for (a = addrs; a; a = n) { - n = a->next; - free( a ); - } -} - -static void -saveEntry( Xauth *auth ) -{ - struct addrList *new; - - if (!(new = Malloc( offsetof(struct addrList, data) + - auth->address_length + auth->number_length ))) - return; - new->address_length = auth->address_length; - new->number_length = auth->number_length; - memcpy( new->data, auth->address, (int)auth->address_length ); - memcpy( new->data + (int)auth->address_length, - auth->number, (int)auth->number_length ); - new->family = auth->family; - new->next = addrs; - addrs = new; -} - -static int -checkEntry( Xauth *auth ) -{ - struct addrList *a; - - for (a = addrs; a; a = a->next) - if (a->family == auth->family && - a->address_length == auth->address_length && - !memcmp( a->data, auth->address, auth->address_length ) && - a->number_length == auth->number_length && - !memcmp( a->data + a->address_length, - auth->number, auth->number_length )) - return 1; - return 0; -} - -static void -writeAuth( FILE *file, Xauth *auth, int *ok ) -{ - if (debugLevel & DEBUG_AUTH) /* normally too verbose */ - Debug( "writeAuth: doWrite = %d\n" - "family: %d\n" - "addr: %02[*:hhx\n" - "number: %02[*:hhx\n" - "name: %02[*:hhx\n" - "data: %02[*:hhx\n", - ok != 0, auth->family, - auth->address_length, auth->address, - auth->number_length, auth->number, - auth->name_length, auth->name, - auth->data_length, auth->data ); - if (ok && !XauWriteAuth( file, auth )) - *ok = FALSE; -} - -static void -writeAddr( int family, int addr_length, char *addr, - FILE *file, Xauth *auth, int *ok ) -{ - auth->family = (unsigned short)family; - auth->address_length = addr_length; - auth->address = addr; - Debug( "writeAddr: writing and saving an entry\n" ); - writeAuth( file, auth, ok ); - if (!checkEntry( auth )) - saveEntry( auth ); -} - -static void -DefineLocal( FILE *file, Xauth *auth, int *ok ) -{ -#if !defined(NEED_UTSNAME) || defined(__hpux) - char displayname[100]; -#endif -#ifdef NEED_UTSNAME - struct utsname name; -#endif - - /* stolen from xinit.c */ - -/* Make sure this produces the same string as _XGetHostname in lib/X/XlibInt.c. - * Otherwise, Xau will not be able to find your cookies in the Xauthority file. - * - * Note: POSIX says that the ``nodename'' member of utsname does _not_ have - * to have sufficient information for interfacing to the network, - * and so, you may be better off using gethostname (if it exists). - */ - -#ifdef NEED_UTSNAME - - /* hpux: - * Why not use gethostname()? Well, at least on my system, I've had to - * make an ugly kernel patch to get a name longer than 8 characters, and - * uname() lets me access to the whole string (it smashes release, you - * see), whereas gethostname() kindly truncates it for me. - */ - uname( &name ); - writeAddr( FamilyLocal, strlen( name.nodename ), name.nodename, - file, auth, ok ); -#endif - -#if !defined(NEED_UTSNAME) || defined(__hpux) - /* _AIX: - * In _AIX, _POSIX_SOURCE is defined, but uname gives only first - * field of hostname. Thus, we use gethostname instead. - */ - - /* - * For HP-UX, HP's Xlib expects a fully-qualified domain name, which - * is achieved by using gethostname(). For compatability, we must - * also still create the entry using uname() above. - */ - displayname[0] = 0; - if (!gethostname( displayname, sizeof(displayname) )) - displayname[sizeof(displayname) - 1] = 0; - -# ifdef NEED_UTSNAME - /* - * If gethostname and uname both returned the same name, - * do not write a duplicate entry. - */ - if (strcmp( displayname, name.nodename )) -# endif - writeAddr( FamilyLocal, strlen( displayname ), displayname, - file, auth, ok ); -#endif -} - -#ifdef SYSV_SIOCGIFCONF - -/* Deal with different SIOCGIFCONF ioctl semantics on SYSV, SVR4 */ - -int -ifioctl (int fd, int cmd, char *arg) -{ - struct strioctl ioc; - int ret; - - bzero( (char *)&ioc, sizeof(ioc) ); - ioc.ic_cmd = cmd; - ioc.ic_timout = 0; - if (cmd == SIOCGIFCONF) { - ioc.ic_len = ((struct ifconf *)arg)->ifc_len; - ioc.ic_dp = ((struct ifconf *)arg)->ifc_buf; - } else { - ioc.ic_len = sizeof(struct ifreq); - ioc.ic_dp = arg; - } - ret = ioctl( fd, I_STR, (char *)&ioc ); - if (ret >= 0 && cmd == SIOCGIFCONF) - ((struct ifconf *)arg)->ifc_len = ioc.ic_len; - return (ret); -} - -#endif /* SYSV_SIOCGIFCONF */ - -#ifdef HAVE_GETIFADDRS -# include <ifaddrs.h> - -static void -DefineSelf( FILE *file, Xauth *auth, int *ok ) -{ - struct ifaddrs *ifap, *ifr; - char *addr; - int family, len; - - if (getifaddrs( &ifap ) < 0) - return; - for (ifr = ifap; ifr; ifr = ifr->ifa_next) { - if (!ifr->ifa_addr) - continue; - family = ConvertAddr( (char *)(ifr->ifa_addr), &len, &addr ); - if (family == -1 || family == FamilyLocal) - continue; - /* - * don't write out 'localhost' entries, as - * they may conflict with other local entries. - * DefineLocal will always be called to add - * the local entry anyway, so this one can - * be tossed. - */ - if (family == FamilyInternet && - addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1) - { - Debug( "Skipping localhost address\n" ); - continue; - } -# if defined(IPv6) && defined(AF_INET6) - if (family == FamilyInternet6) { - if (IN6_IS_ADDR_LOOPBACK( ((struct in6_addr *)addr) )) { - Debug( "Skipping IPv6 localhost address\n" ); - continue; - } - /* Also skip XDM-AUTHORIZATION-1 */ - if (auth->name_length == 19 && - !memcmp( auth->name, "XDM-AUTHORIZATION-1", 19 )) { - Debug( "Skipping IPv6 XDM-AUTHORIZATION-1\n" ); - continue; - } - } -# endif - writeAddr( family, len, addr, file, auth, ok ); - } - freeifaddrs( ifap ); -} -#else /* GETIFADDRS */ - -#if defined(STREAMSCONN) && !defined(SYSV_SIOCGIFCONF) && !defined(WINTCP) - -#include <tiuser.h> - -/* Define this host for access control. Find all the hosts the OS knows about - * for this fd and add them to the selfhosts list. - * TLI version, written without sufficient documentation. - */ -static void -DefineSelf( int fd, FILE *file, Xauth *auth, int *ok ) -{ - struct netbuf netb; - char addrret[1024]; /* easier than t_alloc */ - - netb.maxlen = sizeof(addrret); - netb.buf = addrret; - if (t_getname( fd, &netb, LOCALNAME ) == -1) - t_error( "t_getname" ); - /* what a kludge */ - writeAddr( FamilyInternet, 4, netb.buf+4, file, auth, ok ); -} - -#else - -#ifdef WINTCP /* NCR with Wollongong TCP */ - -#include <stropts.h> -#include <tiuser.h> - -#include <sys/stream.h> -#include <net/if.h> -#include <netinet/ip.h> -#include <netinet/ip_var.h> -#include <netinet/in.h> -#include <netinet/in_var.h> - -static void -DefineSelf( int fd, FILE *file, Xauth *auth, int *ok ) -{ - /* - * The Wollongong drivers used by NCR SVR4/MP-RAS don't understand the - * socket IO calls that most other drivers seem to like. Because of - * this, this routine must be special cased for NCR. Eventually, - * this will be cleared up. - */ - - struct ipb ifnet; - struct in_ifaddr ifaddr; - struct strioctl str; - unsigned char *addr; - int len, ipfd; - - if ((ipfd = open( "/dev/ip", O_RDWR, 0 )) < 0) { - LogError( "Trouble getting interface configuration\n" ); - return; - } - - /* Indicate that we want to start at the begining */ - ifnet.ib_next = (struct ipb *)1; - - while (ifnet.ib_next) { - str.ic_cmd = IPIOC_GETIPB; - str.ic_timout = 0; - str.ic_len = sizeof(struct ipb); - str.ic_dp = (char *)&ifnet; - - if (ioctl( ipfd, (int)I_STR, (char *)&str ) < 0) { - close( ipfd ); - LogError( "Trouble getting interface configuration\n" ); - return; - } - - ifaddr.ia_next = (struct in_ifaddr *)ifnet.if_addrlist; - str.ic_cmd = IPIOC_GETINADDR; - str.ic_timout = 0; - str.ic_len = sizeof(struct in_ifaddr); - str.ic_dp = (char *)&ifaddr; - - if (ioctl( ipfd, (int)I_STR, (char *)&str ) < 0) { - close( ipfd ); - LogError( "Trouble getting interface configuration\n" ); - return; - } - - /* - * Ignore the 127.0.0.1 entry. - */ - if (IA_SIN( &ifaddr )->sin_addr.s_addr == htonl( 0x7f000001 ) ) - continue; - - writeAddr( FamilyInternet, 4, (char *)&(IA_SIN( &ifaddr )->sin_addr), - file, auth, ok ); - - } - close( ipfd ); -} - -#else /* WINTCP */ - -/* Solaris provides an extended interface SIOCGLIFCONF. Other systems - * may have this as well, but the code has only been tested on Solaris - * so far, so we only enable it there. Other platforms may be added as - * needed. - * - * Test for Solaris commented out -- TSI @ UQV 2003.06.13 - */ -#ifdef SIOCGLIFCONF -/* #if defined(sun) */ -# define USE_SIOCGLIFCONF -/* #endif */ -#endif - -#if defined(SIOCGIFCONF) || defined (USE_SIOCGLIFCONF) - -#if !defined(SYSV_SIOCGIFCONF) || defined(USE_SIOCGLIFCONF) -# define ifioctl ioctl -#endif - -#ifdef USE_SIOCGLIFCONF -# define ifr_type struct lifreq -#else -# define ifr_type struct ifreq -#endif - -/* Handle variable length ifreq in BNR2 and later */ -#ifdef VARIABLE_IFREQ -# define ifr_size(p) (sizeof(struct ifreq) + \ - (p->ifr_addr.sa_len > sizeof(p->ifr_addr) ? \ - p->ifr_addr.sa_len - sizeof(p->ifr_addr) : 0)) -#else -# define ifr_size(p) (sizeof(ifr_type)) -#endif - -#ifdef USE_SIOCGLIFCONF -# define IFC_IOCTL_REQ SIOCGLIFCONF -# define IFC_REQ(ifc) ifc.lifc_req -# define IFC_LEN(ifc) ifc.lifc_len -# define IFR_ADDR(ifr) ifr->lifr_addr -# define IFR_NAME(ifr) ifr->lifr_name -#else -# define IFC_IOCTL_REQ SIOCGIFCONF -# define IFC_REQ(ifc) ifc.ifc_req -# define IFC_LEN(ifc) ifc.ifc_len -# define IFR_ADDR(ifr) ifr->ifr_addr -# define IFR_NAME(ifr) ifr->ifr_name -#endif - -/* Define this host for access control. Find all the hosts the OS knows about - * for this fd and add them to the selfhosts list. - */ -static void -DefineSelf( int fd, FILE *file, Xauth *auth, int *ok ) -{ - char buf[2048], *cp, *cplim; - int len; - char *addr; - int family; - ifr_type *ifr; -#ifdef USE_SIOCGLIFCONF - int n; - void * bufptr = buf; - size_t buflen = sizeof(buf); - struct lifconf ifc; -# ifdef SIOCGLIFNUM - struct lifnum ifn; -# endif -#else - struct ifconf ifc; -#endif - -#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) - ifn.lifn_family = AF_UNSPEC; - ifn.lifn_flags = 0; - if (ioctl( fd, (int)SIOCGLIFNUM, (char *)&ifn ) < 0) - LogError( "Failed getting interface count\n" ); - if (buflen < (ifn.lifn_count * sizeof(struct lifreq))) { - buflen = ifn.lifn_count * sizeof(struct lifreq); - bufptr = Malloc( buflen ); - } -#endif - -#ifdef USE_SIOCGLIFCONF - ifc.lifc_family = AF_UNSPEC; - ifc.lifc_flags = 0; - ifc.lifc_len = buflen; - ifc.lifc_buf = bufptr; -#else - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; -#endif - if (ifioctl (fd, IFC_IOCTL_REQ, (char *)&ifc) < 0) { - LogError( "Trouble getting network interface configuration\n" ); -#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) - if (bufptr != buf) - free( bufptr ); -#endif - return; - } - - cplim = (char *)IFC_REQ( ifc ) + IFC_LEN( ifc ); - - for (cp = (char *)IFC_REQ( ifc ); cp < cplim; cp += ifr_size (ifr)) { - ifr = (ifr_type *) cp; -#ifdef DNETCONN - /* - * this is ugly but SIOCGIFCONF returns decnet addresses in - * a different form from other decnet calls - */ - if (IFR_ADDR( ifr ).sa_family == AF_DECnet) { - len = sizeof(struct dn_naddr); - addr = (char *)IFR_ADDR( ifr ).sa_data; - family = FamilyDECnet; - } else -#endif - { - family = ConvertAddr( (char *)&IFR_ADDR( ifr ), &len, &addr ); - if (family < 0) - continue; - - if (len == 0) { - Debug( "skipping zero length address\n" ); - continue; - } - /* - * don't write out 'localhost' entries, as - * they may conflict with other local entries. - * DefineLocal will always be called to add - * the local entry anyway, so this one can - * be tossed. - */ - if (family == FamilyInternet && - addr[0] == 127 && addr[1] == 0 && - addr[2] == 0 && addr[3] == 1) - { - Debug( "skipping localhost address\n" ); - continue; - } -#if defined(IPv6) && defined(AF_INET6) - if (family == FamilyInternet6) { - if (IN6_IS_ADDR_LOOPBACK( ((struct in6_addr *)addr) )) { - Debug( "Skipping IPv6 localhost address\n" ); - continue; - } - /* Also skip XDM-AUTHORIZATION-1 */ - if (auth->name_length == 19 && - !memcmp( auth->name, "XDM-AUTHORIZATION-1", 19 )) { - Debug( "Skipping IPv6 XDM-AUTHORIZATION-1\n" ); - continue; - } - } -#endif - } - Debug( "DefineSelf: write network address, length %d\n", len ); - writeAddr( family, len, addr, file, auth, ok ); - } -#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) - if (bufptr != buf) - free( bufptr ); -#endif -} - -#else /* SIOCGIFCONF */ - -/* Define this host for access control. Find all the hosts the OS knows about - * for this fd and add them to the selfhosts list. - */ -static void -DefineSelf( int fd, int file, int auth, int *ok ) -{ - int len; - caddr_t addr; - int family; - - struct utsname name; - register struct hostent *hp; - - union { - struct sockaddr sa; - struct sockaddr_in in; - } saddr; - - struct sockaddr_in *inetaddr; - - /* hpux: - * Why not use gethostname()? Well, at least on my system, I've had to - * make an ugly kernel patch to get a name longer than 8 characters, and - * uname() lets me access to the whole string (it smashes release, you - * see), whereas gethostname() kindly truncates it for me. - */ - uname( &name ); - if ((hp = gethostbyname( name.nodename ))) { - saddr.sa.sa_family = hp->h_addrtype; - inetaddr = (struct sockaddr_in *)(&(saddr.sa)); - memmove( (char *)&(inetaddr->sin_addr), (char *)hp->h_addr, - (int)hp->h_length ); - if ( (family = ConvertAddr( &(saddr.sa), &len, &addr )) >= 0) - writeAddr( FamilyInternet, sizeof(inetaddr->sin_addr), - (char *)(&inetaddr->sin_addr), file, auth, ok ); - } -} - -#endif /* SIOCGIFCONF else */ -#endif /* WINTCP else */ -#endif /* STREAMSCONN && !SYSV_SIOCGIFCONF else */ -#endif /* HAVE_GETIFADDRS */ - -static void -setAuthNumber( Xauth *auth, const char *name ) -{ - char *colon; - char *dot; - - Debug( "setAuthNumber %s\n", name ); - colon = strrchr( name, ':' ); - if (colon) { - ++colon; - dot = strchr( colon, '.' ); - if (dot) - auth->number_length = dot - colon; - else - auth->number_length = strlen( colon ); - if (!StrNDup( &auth->number, colon, auth->number_length )) - auth->number_length = 0; - Debug( "setAuthNumber: %s\n", auth->number ); - } -} - -static void -writeLocalAuth( FILE *file, Xauth *auth, const char *name, int *ok ) -{ -#if defined(STREAMSCONN) || !defined(HAVE_GETIFADDRS) - int fd; -#endif - - Debug( "writeLocalAuth: %s %.*s\n", name, auth->name_length, auth->name ); - setAuthNumber( auth, name ); -# ifdef STREAMSCONN - fd = t_open( "/dev/tcp", O_RDWR, 0 ); - t_bind( fd, NULL, NULL ); - DefineSelf( fd, file, auth, ok ); - t_unbind( fd ); - t_close( fd ); -# elif defined(HAVE_GETIFADDRS) - DefineSelf( file, auth, ok ); -# else -# ifdef TCPCONN -# if defined(IPv6) && defined(AF_INET6) - fd = socket( AF_INET6, SOCK_STREAM, 0 ); - if (fd < 0) -# endif - fd = socket( AF_INET, SOCK_STREAM, 0 ); - DefineSelf( fd, file, auth, ok ); - close( fd ); -# endif -# ifdef DNETCONN - fd = socket( AF_DECnet, SOCK_STREAM, 0 ); - DefineSelf( fd, file, auth, ok ); - close( fd ); -# endif -# endif /* HAVE_GETIFADDRS */ - DefineLocal( file, auth, ok ); -} - -#ifdef XDMCP - -/* - * Call ConvertAddr(), and if it returns an IPv4 localhost, convert it - * to a local display name. Meets the _XTransConvertAddress's localhost - * hack. - */ - -static int -ConvertAuthAddr( char *saddr, int *len, char **addr ) -{ - int ret = ConvertAddr( saddr, len, addr ); - if (ret == FamilyInternet && - ((struct in_addr *)*addr)->s_addr == htonl( 0x7F000001L )) - ret = FamilyLocal; - return ret; -} - -static void -writeRemoteAuth( FILE *file, Xauth *auth, XdmcpNetaddr peer, int peerlen, - const char *name, int *ok ) -{ - int family = FamilyLocal; - char *addr; - - Debug( "writeRemoteAuth: %s %.*s\n", name, auth->name_length, auth->name ); - if (!peer || peerlen < 2) - return; - setAuthNumber( auth, name ); - family = ConvertAuthAddr( peer, &peerlen, &addr ); - Debug( "writeRemoteAuth: family %d\n", family ); - if (family != FamilyLocal) { - Debug( "writeRemoteAuth: %d, %02[*:hhx\n", - family, peerlen, addr ); - writeAddr( family, peerlen, addr, file, auth, ok ); - } else - writeLocalAuth( file, auth, name, ok ); -} - -#endif /* XDMCP */ - -#define NBSIZE 1024 - -static void -startUserAuth( char *buf, char *nbuf, FILE **old, FILE **new ) -{ - const char *home; - int lockStatus; - - initAddrs(); - *new = 0; - if ((home = getEnv( userEnviron, "HOME" )) && strlen( home ) < NBSIZE - 12) { - sprintf( buf, "%s/.Xauthority", home ); - Debug( "XauLockAuth %s\n", buf ); - lockStatus = XauLockAuth( buf, 1, 2, 10 ); - Debug( "lock is %d\n", lockStatus ); - if (lockStatus == LOCK_SUCCESS) - if (!openFiles( buf, nbuf, old, new )) - XauUnlockAuth( buf ); - } - if (!*new) - LogWarn( "Can't update authorization file in home dir %s\n", home ); -} - -static int -endUserAuth( FILE *old, FILE *new, const char *nname, int ok ) -{ - Xauth *entry; - struct stat statb; - - if (old) { - if (fstat( fileno( old ), &statb ) != -1) - chmod( nname, (int)(statb.st_mode & 0777) ); - /*SUPPRESS 560*/ - while ((entry = XauReadAuth( old ))) { - if (!checkEntry( entry )) { - Debug( "writing an entry\n" ); - writeAuth( new, entry, &ok ); - } - XauDisposeAuth( entry ); - } - fclose( old ); - } - if (fclose( new ) == EOF) - ok = FALSE; - doneAddrs(); - return ok; -} - -static void -undoUserAuth( const char *name, const char *new_name ) -{ - LogWarn( "Can't save user authorization in home dir\n" ); - unlink( new_name ); - XauUnlockAuth( name ); -} - -static char * -moveUserAuth( const char *name, char *new_name, char *envname ) -{ - if (unlink( name )) - Debug( "unlink %s failed\n", name ); - if (link( new_name, name )) { - Debug( "link failed %s %s\n", new_name, name ); - LogError( "Can't move user authorization into place\n" ); - envname = new_name; - } else { - Debug( "new authorization moved into place\n" ); - unlink( new_name ); - } - XauUnlockAuth( name ); - return envname; -} - -void -SetUserAuthorization( struct display *d ) -{ - FILE *old, *new; - char *name; - char *envname; - Xauth **auths; - int i, ok; - int magicCookie; - int data_len; - char name_buf[NBSIZE], new_name[NBSIZE + 2]; - - Debug( "SetUserAuthorization\n" ); - auths = d->authorizations; - if (auths) { - startUserAuth( name_buf, new_name, &old, &new ); - if (new) { - envname = 0; - name = name_buf; - } else { - fallback: - if (strlen( d->userAuthDir ) >= NBSIZE - 13) - return; - /* - * Note, that we don't lock the auth file here, as it's - * temporary - we can assume, that we are the only ones - * knowing about this file anyway. - */ - i = sprintf( name_buf, "%s/.Xauth", d->userAuthDir ); - new = mkTempFile( name_buf, i ); - if (!new) { - LogError( "Can't create authorization file in %s\n", - d->userAuthDir ); - return; - } - name = 0; - envname = name_buf; - old = 0; - } - ok = TRUE; - Debug( "%d authorization protocols for %s\n", d->authNum, d->name ); - /* - * Write MIT-MAGIC-COOKIE-1 authorization first, so that - * R4 clients which only knew that, and used the first - * matching entry will continue to function - */ - magicCookie = -1; - for (i = 0; i < d->authNum; i++) { - if (auths[i]->name_length == 18 && - !memcmp( auths[i]->name, "MIT-MAGIC-COOKIE-1", 18 )) - { - magicCookie = i; - if ((d->displayType & d_location) == dLocal) - writeLocalAuth( new, auths[i], d->name, &ok ); -#ifdef XDMCP - else - writeRemoteAuth( new, auths[i], (XdmcpNetaddr)d->peer.data, - d->peer.length, d->name, &ok ); -#endif - break; - } - } - /* now write other authorizations */ - for (i = 0; i < d->authNum; i++) { - if (i != magicCookie) { - data_len = auths[i]->data_length; - /* client will just use default Kerberos cache, so don't - * even write cache info into the authority file. - */ - if (auths[i]->name_length == 14 && - !strncmp( auths[i]->name, "MIT-KERBEROS-5", 14 )) - auths[i]->data_length = 0; - if ((d->displayType & d_location) == dLocal) - writeLocalAuth( new, auths[i], d->name, &ok ); -#ifdef XDMCP - else - writeRemoteAuth( new, auths[i], (XdmcpNetaddr)d->peer.data, - d->peer.length, d->name, &ok ); -#endif - auths[i]->data_length = data_len; - } - } - if (!endUserAuth( old, new, new_name, ok )) { - if (!name) { - LogError( "Can't save user authorization\n" ); - return; - } - undoUserAuth( name, new_name ); - initAddrs(); - goto fallback; - } - if (name) - envname = moveUserAuth( name, new_name, envname ); - if (envname) { - userEnviron = setEnv( userEnviron, "XAUTHORITY", envname ); - systemEnviron = setEnv( systemEnviron, "XAUTHORITY", envname ); - } - /* a chown() used to be here, but this code runs as user anyway */ - } - Debug( "done SetUserAuthorization\n" ); -} - -void -RemoveUserAuthorization( struct display *d ) -{ - Xauth **auths; - FILE *old, *new; - int i; - char name[NBSIZE], new_name[NBSIZE + 2]; - - if (!(auths = d->authorizations)) - return; - Debug( "RemoveUserAuthorization\n" ); - startUserAuth( name, new_name, &old, &new ); - if (new) { - for (i = 0; i < d->authNum; i++) { - if ((d->displayType & d_location) == dLocal) - writeLocalAuth( new, auths[i], d->name, 0 ); -#ifdef XDMCP - else - writeRemoteAuth( new, auths[i], (XdmcpNetaddr)d->peer.data, - d->peer.length, d->name, 0 ); -#endif - } - if (endUserAuth( old, new, new_name, TRUE )) - (void)moveUserAuth( name, new_name, 0 ); - else - undoUserAuth( name, new_name ); - } - Debug( "done RemoveUserAuthorization\n" ); -} diff --git a/kdm/backend/bootman.c b/kdm/backend/bootman.c deleted file mode 100644 index 291164ea7..000000000 --- a/kdm/backend/bootman.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - -Copyright 2005 Stephan Kulow <[email protected]> -Copyright 2005 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * Boot options - */ - -#include "dm.h" -#include "dm_error.h" - -#include <string.h> -#include <unistd.h> -#include <stdio.h> -#include <ctype.h> - -extern char **environ; - -static int -getNull( char ***opts ATTR_UNUSED, int *def ATTR_UNUSED, int *cur ATTR_UNUSED ) -{ - return BO_NOMAN; -} - -static int -setNull( const char *opt ATTR_UNUSED, SdRec *sdr ATTR_UNUSED ) -{ - return BO_NOMAN; -} - -static char * -match( char *obuf, int *blen, const char *key, int klen ) -{ - char *buf = obuf; - if (memcmp( buf, key, klen ) || !isspace( buf[klen] )) - return 0; - buf += klen + 1; - for (; isspace( *buf ); buf++); - if (!*buf) - return 0; - *blen -= buf - obuf; - return buf; -} - -#define GRUB_MENU "/boot/grub/menu.lst" - -static char *grub; - -static int -getGrub( char ***opts, int *def, int *cur ) -{ - FILE *f; - char *ptr, *linp; - int len; - char line[1000]; - - if (!grub && !(grub = locate( "grub-set-default" ))) - return BO_NOMAN; - - *def = 0; - *cur = -1; - *opts = initStrArr( 0 ); - - if (!(f = fopen( GRUB_MENU, "r" ))) - return errno == ENOENT ? BO_NOMAN : BO_IO; - while ((len = fGets( line, sizeof(line), f )) != -1) { - for (linp = line; isspace(*linp); linp++, len--); - if ((ptr = match( linp, &len, "default", 7 ))) - *def = atoi( ptr ); - else if ((ptr = match( linp, &len, "title", 5 ))) { - for (; isspace( ptr[len - 1] ); len--); - *opts = addStrArr( *opts, ptr, len ); - } - } - fclose( f ); - - return BO_OK; -} - -static int -setGrub( const char *opt, SdRec *sdr ) -{ - FILE *f; - char *ptr; - int len, i; - char line[1000]; - - if (!(f = fopen( GRUB_MENU, "r" ))) - return errno == ENOENT ? BO_NOMAN : BO_IO; - for (i = 0; (len = fGets( line, sizeof(line), f )) != -1; ) - if ((ptr = match( line, &len, "title", 5 ))) { - if (!strcmp( ptr, opt )) { - fclose( f ); - sdr->osindex = i; - sdr->bmstamp = mTime( GRUB_MENU ); - return BO_OK; - } - i++; - } - fclose( f ); - return BO_NOENT; -} - -static void -commitGrub( void ) -{ - char command[256]; - - if (sdRec.bmstamp != mTime( GRUB_MENU ) && - setGrub( sdRec.osname, &sdRec ) != BO_OK) - return; - - sprintf(command, "%s %d", grub, sdRec.osindex); - system(command); -} - -static char *lilo; - -static int -getLilo( char ***opts, int *def, int *cur ) -{ - FILE *f; - int cdef, pid, len, ret = BO_OK; - static const char *args[5] = { 0, "-w", "-v", "-q", 0 }; - char buf[256], next[256]; - - if (!lilo && !(lilo = locate( "lilo" ))) - return BO_NOMAN; - - args[0] = lilo; - if (!(f = pOpen( (char **)args, 'r', &pid ))) - return BO_IO; - *opts = 0; - next[0] = 0; - for (;;) { - if ((len = fGets( buf, sizeof(buf), f)) == -1) { - ret = BO_NOMAN; - goto out; - } - if (!memcmp( buf, "Images:", 7 )) - break; -#define Ldeflin " Default boot command line:" - if (!memcmp( buf, Ldeflin, strlen(Ldeflin) )) { - memcpy( next, buf + strlen(Ldeflin) + 2, len - strlen(Ldeflin) - 3 ); - next[len - strlen(Ldeflin) - 3] = 0; - } - } - cdef = *def = 0; - *cur = -1; - *opts = initStrArr( 0 ); - while ((len = fGets( buf, sizeof(buf), f)) != -1) - if (buf[0] == ' ' && buf[1] == ' ' && buf[2] != ' ') { - if (buf[len - 1] == '*') { - *def = cdef; - len--; - } - for (; buf[len - 1] == ' '; len--); - *opts = addStrArr( *opts, buf + 2, len - 2 ); - if (!strcmp( (*opts)[cdef], next )) - *cur = cdef; - cdef++; - } - out: - if (pClose( f, pid )) { - if (*opts) - freeStrArr( *opts ); - return BO_IO; - } - return ret; -} - -static int -setLilo( const char *opt, SdRec *sdr ATTR_UNUSED ) -{ - char **opts; - int def, cur, ret, i; - - if ((ret = getLilo( &opts, &def, &cur )) != BO_OK) - return ret; - if (!*opt) - opt = 0; - else { - for (i = 0; opts[i]; i++) - if (!strcmp( opts[i], opt )) - goto oke; - freeStrArr( opts ); - return BO_NOENT; - } - oke: - freeStrArr( opts ); - return BO_OK; -} - -static void -commitLilo( void ) -{ - static const char *args[5] = { 0, "-w", "-R", 0, 0 }; - - args[0] = lilo; - args[3] = sdRec.osname; - runAndWait( (char **)args, environ ); -} - -static struct { - int (*get)( char ***, int *, int * ); - int (*set)( const char *, SdRec * ); - void (*commit)( void ); -} bootOpts[] = { - { getNull, setNull, 0 }, - { getGrub, setGrub, commitGrub }, - { getLilo, setLilo, commitLilo }, -}; - -int -getBootOptions( char ***opts, int *def, int *cur ) -{ - return bootOpts[bootManager].get( opts, def, cur ); -} - -int -setBootOption( const char *opt, SdRec *sdr ) -{ - int ret; - - if (sdr->osname) { - free( sdr->osname ); - sdr->osname = 0; - } - if (opt) { - if ((ret = bootOpts[bootManager].set( opt, sdr )) != BO_OK) - return ret; - if (!StrDup( &sdr->osname, opt )) - return BO_IO; /* BO_NOMEM */ - } - return BO_OK; -} - -void -commitBootOption( void ) -{ - if (sdRec.osname) { - bootOpts[bootManager].commit(); -/* - free( sdRec.osname ); - sdRec.osname = 0; -*/ - } -} - diff --git a/kdm/backend/choose.c b/kdm/backend/choose.c deleted file mode 100644 index ead841228..000000000 --- a/kdm/backend/choose.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* - -Copyright 1990, 1998 The Open Group -Copyright 2002-2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * chooser backend - */ - -#include <config.h> - -#ifdef XDMCP - -#include "dm.h" -#include "dm_error.h" -#include "dm_socket.h" - -#include <ctype.h> - -#ifdef __svr4__ -# include <sys/sockio.h> -#endif -#include <arpa/inet.h> - -#include <sys/ioctl.h> -#ifdef STREAMSCONN -# ifdef WINTCP /* NCR with Wollongong TCP */ -# include <netinet/ip.h> -# endif -# include <stropts.h> -# include <tiuser.h> -# include <netconfig.h> -# include <netdir.h> -#endif - -#if !defined(__GNU__) && !defined(__hpux) /* XXX __hpux might be wrong */ -# include <net/if.h> -#endif - -#include <netdb.h> - -typedef struct _IndirectUsers { - struct _IndirectUsers *next; - ARRAY8 client; - CARD16 connectionType; -} IndirectUsersRec, *IndirectUsersPtr; - -static IndirectUsersPtr indirectUsers; - -int -RememberIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - IndirectUsersPtr i; - - for (i = indirectUsers; i; i = i->next) - if (XdmcpARRAY8Equal( clientAddress, &i->client ) && - connectionType == i->connectionType) - return 1; - if (!(i = (IndirectUsersPtr)Malloc( sizeof(IndirectUsersRec) ))) - return 0; - if (!XdmcpCopyARRAY8( clientAddress, &i->client )) { - free( (char *)i ); - return 0; - } - i->connectionType = connectionType; - i->next = indirectUsers; - indirectUsers = i; - return 1; -} - -void -ForgetIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - IndirectUsersPtr *i, ni; - - for (i = &indirectUsers; *i; i = &(*i)->next) - if (XdmcpARRAY8Equal( clientAddress, &(*i)->client ) && - connectionType == (*i)->connectionType) - { - ni = (*i)->next; - XdmcpDisposeARRAY8( &(*i)->client ); - free( (char *)(*i) ); - (*i) = ni; - break; - } -} - -int -IsIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - IndirectUsersPtr i; - - for (i = indirectUsers; i; i = i->next) - if (XdmcpARRAY8Equal( clientAddress, &i->client ) && - connectionType == i->connectionType) - return 1; - return 0; -} - -typedef struct _Choices { - struct _Choices *next; - ARRAY8 client; - CARD16 connectionType; - ARRAY8 choice; - Time_t time; -} ChoiceRec, *ChoicePtr; - -static ChoicePtr choices; - -ARRAY8Ptr -IndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - ChoicePtr c, next, prev; - - prev = 0; - for (c = choices; c; c = next) { - next = c->next; - Debug( "choice checking timeout: %ld >? %d\n", - (long)(now - c->time), choiceTimeout ); - if (now - c->time > (Time_t)choiceTimeout) { - Debug( "timeout choice %ld > %d\n", - (long)(now - c->time), choiceTimeout ); - if (prev) - prev->next = next; - else - choices = next; - XdmcpDisposeARRAY8( &c->client ); - XdmcpDisposeARRAY8( &c->choice ); - free( (char *)c ); - } else { - if (XdmcpARRAY8Equal( clientAddress, &c->client ) && - connectionType == c->connectionType) - return &c->choice; - prev = c; - } - } - return 0; -} - -int -RegisterIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType, - ARRAY8Ptr choice ) -{ - ChoicePtr c; - int insert; -#if 0 - int found = 0; -#endif - - Debug( "got indirect choice back\n" ); - for (c = choices; c; c = c->next) { - if (XdmcpARRAY8Equal( clientAddress, &c->client ) && - connectionType == c->connectionType) { -#if 0 - found = 1; -#endif - break; - } - } -#if 0 - if (!found) - return 0; -#endif - - insert = 0; - if (!c) { - insert = 1; - c = (ChoicePtr)Malloc( sizeof(ChoiceRec) ); - if (!c) - return 0; - c->connectionType = connectionType; - if (!XdmcpCopyARRAY8( clientAddress, &c->client )) { - free( (char *)c ); - return 0; - } - } else - XdmcpDisposeARRAY8( &c->choice ); - if (!XdmcpCopyARRAY8( choice, &c->choice )) { - XdmcpDisposeARRAY8( &c->client ); - free( (char *)c ); - return 0; - } - if (insert) { - c->next = choices; - choices = c; - } - c->time = now; - return 1; -} - -#if 0 -static void -RemoveIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - ChoicePtr c, prev; - - prev = 0; - for (c = choices; c; c = c->next) { - if (XdmcpARRAY8Equal( clientAddress, &c->client ) && - connectionType == c->connectionType) - { - if (prev) - prev->next = c->next; - else - choices = c->next; - XdmcpDisposeARRAY8( &c->client ); - XdmcpDisposeARRAY8( &c->choice ); - free( (char *)c ); - return; - } - prev = c; - } -} -#endif - - -/* ####################### */ - - -typedef struct _hostAddr { - struct _hostAddr *next; - struct sockaddr *addr; - int addrlen; - xdmOpCode type; -} HostAddr; - -static HostAddr *hostAddrdb; - -typedef struct _hostName { - struct _hostName *next; - unsigned willing:1, alive:1; - ARRAY8 hostname, status; - CARD16 connectionType; - ARRAY8 hostaddr; -} HostName; - -static HostName *hostNamedb; - -static XdmcpBuffer directBuffer, broadcastBuffer; -static XdmcpBuffer buffer; - -static int socketFD; -#if defined(IPv6) && defined(AF_INET6) -static int socket6FD; -#endif - - -static void -doPingHosts() -{ - HostAddr *hosts; - - for (hosts = hostAddrdb; hosts; hosts = hosts->next) -#if defined(IPv6) && defined(AF_INET6) - XdmcpFlush( hosts->addr->sa_family == AF_INET6 ? socket6FD : socketFD, -#else - XdmcpFlush( socketFD, -#endif - hosts->type == QUERY ? &directBuffer : &broadcastBuffer, - (XdmcpNetaddr)hosts->addr, hosts->addrlen ); -} - -static int -addHostname( ARRAY8Ptr hostname, ARRAY8Ptr status, - struct sockaddr *addr, int will ) -{ - HostName **names, *name; - ARRAY8 hostAddr; - CARD16 connectionType; - - switch (addr->sa_family) { - case AF_INET: - hostAddr.data = - (CARD8 *)& ((struct sockaddr_in *)addr)->sin_addr; - hostAddr.length = 4; - connectionType = FamilyInternet; - break; -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - hostAddr.data = - (CARD8 *)&((struct sockaddr_in6 *)addr)->sin6_addr; - hostAddr.length = 16; - connectionType = FamilyInternet6; - break; -#endif - default: - hostAddr.data = (CARD8 *)""; - hostAddr.length = 0; - connectionType = FamilyLocal; - break; - } - for (names = &hostNamedb; *names; names = &(*names)->next) { - name = *names; - if (connectionType == name->connectionType && - XdmcpARRAY8Equal( &hostAddr, &name->hostaddr )) - { - if (XdmcpARRAY8Equal( status, &name->status )) - return 0; - XdmcpDisposeARRAY8( &name->status ); - XdmcpDisposeARRAY8( hostname ); - - GSendInt( G_Ch_ChangeHost ); - goto gotold; - } - } - if (!(name = (HostName *)Malloc( sizeof(*name) ))) - return 0; - if (hostname->length) { - switch (addr->sa_family) { - case AF_INET: -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: -#endif - { - struct hostent *hostent; - char *host; - - hostent = gethostbyaddr( (char *)hostAddr.data, - hostAddr.length, addr->sa_family ); - if (hostent) { - XdmcpDisposeARRAY8( hostname ); - host = hostent->h_name; - XdmcpAllocARRAY8( hostname, strlen( host ) ); - memmove( hostname->data, host, hostname->length ); - } - } - } - } - if (!XdmcpAllocARRAY8( &name->hostaddr, hostAddr.length )) { - free( (char *)name ); - return 0; - } - memmove( name->hostaddr.data, hostAddr.data, hostAddr.length ); - name->connectionType = connectionType; - name->hostname = *hostname; - - *names = name; - name->next = 0; - - GSendInt( G_Ch_AddHost ); - gotold: - name->alive = 1; - name->willing = will; - name->status = *status; - - GSendInt( (int)name ); /* just an id */ - GSendNStr( (char *)name->hostname.data, name->hostname.length ); - GSendNStr( (char *)name->status.data, name->status.length ); - GSendInt( will ); - - return 1; -} - -static void -disposeHostname( HostName *host ) -{ - XdmcpDisposeARRAY8( &host->hostname ); - XdmcpDisposeARRAY8( &host->hostaddr ); - XdmcpDisposeARRAY8( &host->status ); - free( (char *)host ); -} - -static void -emptyHostnames( void ) -{ - HostName *host, *nhost; - - for (host = hostNamedb; host; host = nhost) { - nhost = host->next; - disposeHostname( host ); - } - hostNamedb = 0; -} - -static void -receivePacket( int sfd ) -{ - XdmcpHeader header; - ARRAY8 authenticationName; - ARRAY8 hostname; - ARRAY8 status; - int saveHostname = 0; -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_storage addr; -#else - struct sockaddr addr; -#endif - int addrlen; - - addrlen = sizeof(addr); - if (!XdmcpFill( sfd, &buffer, (XdmcpNetaddr)&addr, &addrlen )) - return; - if (!XdmcpReadHeader( &buffer, &header )) - return; - if (header.version != XDM_PROTOCOL_VERSION) - return; - hostname.data = 0; - status.data = 0; - authenticationName.data = 0; - switch (header.opcode) { - case WILLING: - if (XdmcpReadARRAY8( &buffer, &authenticationName ) && - XdmcpReadARRAY8( &buffer, &hostname ) && - XdmcpReadARRAY8( &buffer, &status )) { - if (header.length == 6 + authenticationName.length + - hostname.length + status.length) { - if (addHostname( &hostname, &status, - (struct sockaddr *)&addr, 1 )) - saveHostname = 1; - } - } - XdmcpDisposeARRAY8( &authenticationName ); - break; - case UNWILLING: - if (XdmcpReadARRAY8( &buffer, &hostname ) && - XdmcpReadARRAY8( &buffer, &status )) { - if (header.length == 4 + hostname.length + status.length) { - if (addHostname( &hostname, &status, - (struct sockaddr *)&addr, 0 )) - saveHostname = 1; - } - } - break; - default: - break; - } - if (!saveHostname) { - XdmcpDisposeARRAY8( &hostname ); - XdmcpDisposeARRAY8( &status ); - } -} - -static void -addHostaddr( HostAddr **hosts, struct sockaddr *addr, int len, xdmOpCode type ) -{ - HostAddr *host; - - Debug( "adding host %[*hhu, type %d\n", len, addr, type ); - for (host = *hosts; host; host = host->next) - if (host->type == type && host->addr->sa_family == addr->sa_family) - switch (addr->sa_family) { - case AF_INET: - { - struct sockaddr_in *na = (struct sockaddr_in *)addr; - struct sockaddr_in *oa = (struct sockaddr_in *)host->addr; - if (na->sin_port == oa->sin_port && - na->sin_addr.s_addr == oa->sin_addr.s_addr) - return; - break; - } -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - { - struct sockaddr_in6 *na = (struct sockaddr_in6 *)addr; - struct sockaddr_in6 *oa = (struct sockaddr_in6 *)host->addr; - if (na->sin6_port == oa->sin6_port && - !memcmp( &na->sin6_addr, &oa->sin6_addr, 16 )) - return; - break; - } -#endif - default: /* ... */ - break; - } - Debug( " not dupe\n" ); - if (!(host = (HostAddr *)Malloc( sizeof(*host) ))) - return; - if (!(host->addr = (struct sockaddr *)Malloc( len ))) { - free( (char *)host ); - return; - } - memcpy( (char *)host->addr, (char *)addr, len ); - host->addrlen = len; - host->type = type; - host->next = *hosts; - *hosts = host; -} - -static void -registerHostaddr( struct sockaddr *addr, int len, xdmOpCode type ) -{ - addHostaddr( &hostAddrdb, addr, len, type ); -} - -static void -emptyPingHosts( void ) -{ - HostAddr *host, *nhost; - - for (host = hostAddrdb; host; host = nhost) { - nhost = host->next; - free( host->addr ); - free( host ); - } - hostAddrdb = 0; -} - -/* Handle variable length ifreq in BNR2 and later */ -#ifdef VARIABLE_IFREQ -# define ifr_size(p) \ - (sizeof(struct ifreq) + \ - (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \ - p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0)) -#else -# define ifr_size(p) (sizeof(struct ifreq)) -#endif - -#define IFC_REQ(ifc) ifc.ifc_req - -#ifndef SYSV_SIOCGIFCONF -# define ifioctl ioctl -#endif - -static void -registerBroadcastForPing( void ) -{ - struct sockaddr_in in_addr; - -#ifdef __GNU__ - in_addr.sin_addr.s_addr = htonl( 0xFFFFFFFF ); - in_addr.sin_port = htons( XDM_UDP_PORT ); - registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), - BROADCAST_QUERY ); -#else /* __GNU__ */ - struct ifconf ifc; - register struct ifreq *ifr; - struct sockaddr broad_addr; - char buf[2048], *cp, *cplim; -# ifdef WINTCP /* NCR with Wollongong TCP */ - int ipfd; - struct ifconf *ifcp; - struct strioctl ioc; - int n; - - ifcp = (struct ifconf *)buf; - ifcp->ifc_buf = buf + 4; - ifcp->ifc_len = sizeof(buf) - 4; - - if ((ipfd = open( "/dev/ip", O_RDONLY )) < 0) { - t_error( "RegisterBroadcastForPing() t_open(/dev/ip) failed" ); - return; - } - - ioc.ic_cmd = IPIOC_GETIFCONF; - ioc.ic_timout = 60; - ioc.ic_len = sizeof(buf); - ioc.ic_dp = (char *)ifcp; - - if (ioctl( ipfd, (int)I_STR, (char *)&ioc ) < 0) { - perror( "RegisterBroadcastForPing() ioctl(I_STR(IPIOC_GETIFCONF)) failed" ); - close( ipfd ); - return; - } - - for (ifr = ifcp->ifc_req, n = ifcp->ifc_len / sizeof(struct ifreq); - --n >= 0; ifr++) -# else /* WINTCP */ - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - if (ifioctl(socketFD, (int)SIOCGIFCONF, (char *)&ifc) < 0) - return; - - cplim = (char *)IFC_REQ( ifc ) + ifc.ifc_len; - - for (cp = (char *)IFC_REQ( ifc ); cp < cplim; cp += ifr_size(ifr)) -# endif /* WINTCP */ - { -# ifndef WINTCP - ifr = (struct ifreq *)cp; -# endif - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - - broad_addr = ifr->ifr_addr; - ((struct sockaddr_in *)&broad_addr)->sin_addr.s_addr = - htonl( INADDR_BROADCAST ); -# ifdef SIOCGIFBRDADDR - { - struct ifreq broad_req; - - broad_req = *ifr; -# ifdef WINTCP /* NCR with Wollongong TCP */ - ioc.ic_cmd = IPIOC_GETIFFLAGS; - ioc.ic_timout = 0; - ioc.ic_len = sizeof(broad_req); - ioc.ic_dp = (char *)&broad_req; - - if (ioctl (ipfd, I_STR, (char *) &ioc ) != -1 && -# else /* WINTCP */ - if (ifioctl( socketFD, SIOCGIFFLAGS, (char *)&broad_req ) != - -1 && -# endif /* WINTCP */ - (broad_req.ifr_flags & IFF_BROADCAST) && - (broad_req.ifr_flags & IFF_UP)) - { - broad_req = *ifr; -# ifdef WINTCP /* NCR with Wollongong TCP */ - ioc.ic_cmd = IPIOC_GETIFBRDADDR; - ioc.ic_timout = 0; - ioc.ic_len = sizeof(broad_req); - ioc.ic_dp = (char *)&broad_req; - - if (ioctl( ipfd, I_STR, (char *) &ioc) != -1 ) -# else /* WINTCP */ - if (ifioctl( socketFD, SIOCGIFBRDADDR, (char *)&broad_req ) - != -1) -# endif /* WINTCP */ - broad_addr = broad_req.ifr_addr; - else - continue; - } else - continue; - } -# endif - in_addr = *((struct sockaddr_in *)&broad_addr); - in_addr.sin_port = htons( XDM_UDP_PORT ); -# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -# endif - registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), - BROADCAST_QUERY ); - } -#endif -} - -static int -makeSockAddrs( const char *name, HostAddr **hosts ) -{ -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai, *nai, hints; - bzero( &hints, sizeof(hints) ); - hints.ai_socktype = SOCK_DGRAM; - if (getaddrinfo( name, stringify( XDM_UDP_PORT ), &hints, &ai )) - return 0; - for (nai = ai; nai; nai = nai->ai_next) - if ((nai->ai_family == AF_INET) || (nai->ai_family == AF_INET6)) - addHostaddr( hosts, nai->ai_addr, nai->ai_addrlen, - (nai->ai_family == AF_INET ? - IN_MULTICAST( ((struct sockaddr_in *)nai->ai_addr)->sin_addr.s_addr ) : - IN6_IS_ADDR_MULTICAST( &((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr )) ? - BROADCAST_QUERY : QUERY ); -#else - struct sockaddr_in in_addr; - /* Per RFC 1123, check first for IP address in dotted-decimal form */ - if ((in_addr.sin_addr.s_addr = inet_addr( name )) == (unsigned)-1) { - struct hostent *hostent; - if (!(hostent = gethostbyname( name )) || - hostent->h_addrtype != AF_INET) - return 0; - memcpy( &in_addr.sin_addr, hostent->h_addr, 4 ); - } - in_addr.sin_family = AF_INET; - in_addr.sin_port = htons( XDM_UDP_PORT ); -# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -# endif - addHostaddr( hosts, (struct sockaddr *)&in_addr, sizeof(in_addr), -# ifdef IN_MULTICAST - IN_MULTICAST( in_addr.sin_addr.s_addr ) ? - BROADCAST_QUERY : -# endif - QUERY ); -#endif - return 1; -} - -/* - * Register the address for this host. - * Called for interactively specified hosts. - * The special names "BROADCAST" and "*" look up all the broadcast - * addresses on the local host. - */ - -static int -registerForPing( const char *name ) -{ - Debug( "manual host registration: %s\n", name ); - if (!strcmp( name, "BROADCAST" ) || !strcmp( name, "*" )) - registerBroadcastForPing(); - else if (!makeSockAddrs( name, &hostAddrdb )) - return 0; - return 1; -} - -/*ARGSUSED*/ -static void -AddChooserHost( - CARD16 connectionType, - ARRAY8Ptr addr, - char *closure ATTR_UNUSED ) -{ - if (connectionType == FamilyBroadcast) { - registerBroadcastForPing(); - return; - } - Debug( "internal host registration: %[*hhu, family %hx\n", - addr->length, addr->data, connectionType ); - if (connectionType == FamilyInternet) { - struct sockaddr_in in_addr; - in_addr.sin_family = AF_INET; - memmove( &in_addr.sin_addr, addr->data, 4 ); - in_addr.sin_port = htons( XDM_UDP_PORT ); -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -#endif - registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), -#ifdef IN_MULTICAST - IN_MULTICAST( in_addr.sin_addr.s_addr ) ? - BROADCAST_QUERY : -#endif - QUERY ); - } -#if defined(IPv6) && defined(AF_INET6) - else if (connectionType == FamilyInternet6) { - struct sockaddr_in6 in6_addr; - in6_addr.sin6_family = AF_INET6; - memmove( &in6_addr.sin6_addr, addr->data, 16 ); - in6_addr.sin6_port = htons( XDM_UDP_PORT ); -#ifdef SIN6_LEN - in6_addr.sin6_len = sizeof(in6_addr); -#endif - registerHostaddr( (struct sockaddr *)&in6_addr, sizeof(in6_addr), - IN6_IS_ADDR_MULTICAST( &in6_addr.sin6_addr ) ? - BROADCAST_QUERY : QUERY ); - } -#endif -} - -static ARRAYofARRAY8 AuthenticationNames; - -#if 0 -static void RegisterAuthenticationName( char *name, int namelen ) -{ - ARRAY8Ptr authName; - if (!XdmcpReallocARRAYofARRAY8( &AuthenticationNames, - AuthenticationNames.length + 1 )) - return; - authName = &AuthenticationNames.data[AuthenticationNames.length - 1]; - if (!XdmcpAllocARRAY8( authName, namelen )) - return; - memmove( authName->data, name, namelen ); -} -#endif - -static int -initXDMCP() -{ - XdmcpHeader header; -#if 0 - int i; -#endif -#ifndef STREAMSCONN -#ifdef SO_BROADCAST - int soopts; -#endif -#endif - - header.version = XDM_PROTOCOL_VERSION; - header.length = 1; -#if 0 - for (i = 0; i < (int)AuthenticationNames.length; i++) - header.length += 2 + AuthenticationNames.data[i].length; -#endif - - header.opcode = (CARD16)BROADCAST_QUERY; - XdmcpWriteHeader( &broadcastBuffer, &header ); - XdmcpWriteARRAYofARRAY8( &broadcastBuffer, &AuthenticationNames ); - - header.opcode = (CARD16)QUERY; - XdmcpWriteHeader( &directBuffer, &header ); - XdmcpWriteARRAYofARRAY8( &directBuffer, &AuthenticationNames ); - -#if defined(STREAMSCONN) - if ((socketFD = t_open( "/dev/udp", O_RDWR, 0 )) < 0) - return 0; - - if (t_bind( socketFD, NULL, NULL ) < 0) { - t_close( socketFD ); - return 0; - } - - /* - * This part of the code looks contrived. It will actually fit in nicely - * when the CLTS part of Xtrans is implemented. - */ - { - struct netconfig *nconf; - - if ((nconf = getnetconfigent( "udp" )) == NULL) { - t_unbind( socketFD ); - t_close( socketFD ); - return 0; - } - - if (netdir_options( nconf, ND_SET_BROADCAST, socketFD, NULL )) { - freenetconfigent( nconf ); - t_unbind( socketFD ); - t_close( socketFD ); - return 0; - } - - freenetconfigent( nconf ); - } -#else - if ((socketFD = socket( AF_INET, SOCK_DGRAM, 0 )) < 0) - return 0; -#if defined(IPv6) && defined(AF_INET6) - socket6FD = socket( AF_INET6, SOCK_DGRAM, 0 ); -#endif -# ifdef SO_BROADCAST - soopts = 1; - if (setsockopt( socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, - sizeof(soopts) ) < 0) - perror( "setsockopt" ); -# endif -#endif - - return 1; -} - -static void ATTR_NORETURN -chooseHost( int hid ) -{ - HostName *h; -#if defined(IPv6) && defined(AF_INET6) - char addr[64]; -#endif - - for (h = hostNamedb; h; h = h->next) - if ((int)h == hid) { - /* XXX error handling */ - GSet( &mstrtalk ); - if ((td->displayType & d_location) == dLocal) { - GSendInt( D_RemoteHost ); -#if defined(IPv6) && defined(AF_INET6) - switch (h->connectionType) { - case FamilyInternet6: - inet_ntop( AF_INET6, h->hostaddr.data, addr, sizeof(addr) ); - break; - default: /* FamilyInternet */ - inet_ntop( AF_INET, h->hostaddr.data, addr, sizeof(addr) ); - break; - } - GSendStr( addr ); -#else - GSendStr( inet_ntoa( *(struct in_addr *)h->hostaddr.data ) ); -#endif - CloseGreeter( FALSE ); - SessionExit( EX_REMOTE ); - } else { - GSendInt( D_ChooseHost ); - GSendArr( td->clientAddr.length, (char *)td->clientAddr.data ); - GSendInt( td->connectionType ); - GSendArr( h->hostaddr.length, (char *)h->hostaddr.data ); - CloseGreeter( FALSE ); - goto bout; - } - break; - } -/* LogError( "Internal error: chose unexisting host\n" ); */ - bout: - SessionExit( EX_NORMAL ); -} - -static void -directChooseHost( const char *name ) -{ - HostAddr *hosts = 0; - - if (!makeSockAddrs( name, &hosts )) - return; - GSendInt( G_Ch_Exit ); - /* XXX error handling */ - GSet( &mstrtalk ); - if ((td->displayType & d_location) == dLocal) { - GSendInt( D_RemoteHost ); - GSendStr( name ); - CloseGreeter( FALSE ); - SessionExit( EX_REMOTE ); - } else { - GSendInt( D_ChooseHost ); - GSendArr( td->clientAddr.length, (char *)td->clientAddr.data ); - GSendInt( td->connectionType ); - GSendArr( hosts->addrlen, (char *)hosts->addr ); - CloseGreeter( FALSE ); - SessionExit( EX_NORMAL ); - } -} - -#define PING_TRIES 3 - -int -DoChoose() -{ - HostName **hp, *h; - char *host, **hostp; - struct timeval *to, tnow, nextPing; - int pingTry, n, cmd; - FD_TYPE rfds; - static int xdmcpInited; - - OpenGreeter(); - GSendInt( G_Choose ); - switch (cmd = CtrlGreeterWait( TRUE )) { - case G_Ready: - break; - default: /* error */ - return cmd; - } - - if (!xdmcpInited) { - if (!initXDMCP()) - SessionExit( EX_UNMANAGE_DPY ); - xdmcpInited = 1; - } - if ((td->displayType & d_location) == dLocal) { - /* XXX the config reader should do the lookup already */ - for (hostp = td->chooserHosts; *hostp; hostp++) - if (!registerForPing( *hostp )) - LogError( "Unkown host %\"s specified for local chooser preload of display %s\n", *hostp, td->name ); - } else - ForEachChooserHost( &td->clientAddr, td->connectionType, - AddChooserHost, 0 ); - - GSendInt( 0 ); /* entering async mode signal */ - - reping: - for (h = hostNamedb; h; h = h->next) - h->alive = 0; - pingTry = 0; - goto pingen; - - for (;;) { - to = 0; - if (pingTry <= PING_TRIES) { - gettimeofday( &tnow, 0 ); - if (nextPing.tv_sec < tnow.tv_sec || - (nextPing.tv_sec == tnow.tv_sec && - nextPing.tv_usec < tnow.tv_usec)) { - if (pingTry < PING_TRIES) { - pingen: - pingTry++; - doPingHosts(); - gettimeofday( &tnow, 0 ); - nextPing = tnow; - nextPing.tv_sec++; - } else { - for (hp = &hostNamedb; *hp; ) - if (!(*hp)->alive) { - h = (*hp)->next; - disposeHostname( *hp ); - GSendInt( G_Ch_RemoveHost ); - GSendInt( (int)*hp ); /* just an id */ - *hp = h; - } else - hp = &(*hp)->next; - goto noto; - } - } - to = &tnow; - tnow.tv_sec = nextPing.tv_sec - tnow.tv_sec; - tnow.tv_usec = nextPing.tv_usec - tnow.tv_usec; - if (tnow.tv_usec < 0) { - tnow.tv_usec += 1000000; - tnow.tv_sec--; - } - } - noto: - FD_ZERO( &rfds ); - FD_SET( grtproc.pipe.rfd, &rfds ); - FD_SET( socketFD, &rfds ); -#if defined(IPv6) && defined(AF_INET6) - if (socket6FD >= 0) - FD_SET( socket6FD, &rfds ); -#endif - n = grtproc.pipe.rfd; - if (socketFD > n) - n = socketFD; -#if defined(IPv6) && defined(AF_INET6) - if (socket6FD > n) - n = socket6FD; -#endif - if (select( n + 1, &rfds, 0, 0, to ) > 0) { - if (FD_ISSET( grtproc.pipe.rfd, &rfds )) - switch (cmd = CtrlGreeterWait( FALSE )) { - case -1: - break; - case G_Ch_Refresh: - goto reping; - case G_Ch_RegisterHost: - host = GRecvStr(); - if (!registerForPing( host )) { - GSendInt( G_Ch_BadHost ); - GSendStr( host ); - } - free( host ); - goto reping; - case G_Ch_DirectChoice: - host = GRecvStr(); - directChooseHost( host ); - GSendInt( G_Ch_BadHost ); - GSendStr( host ); - free( host ); - break; - case G_Ready: - chooseHost( GRecvInt() ); - /* NOTREACHED */ - default: - emptyHostnames(); - emptyPingHosts(); - return cmd; - } - if (FD_ISSET( socketFD, &rfds )) - receivePacket( socketFD ); -#if defined(IPv6) && defined(AF_INET6) - if (socket6FD >= 0 && FD_ISSET( socket6FD, &rfds )) - receivePacket( socket6FD ); -#endif - } - } - -} - -#endif /* XDMCP */ diff --git a/kdm/backend/client.c b/kdm/backend/client.c deleted file mode 100644 index 0cf4e216b..000000000 --- a/kdm/backend/client.c +++ /dev/null @@ -1,1865 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * user verification and session initiation. - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include <sys/stat.h> -#include <pwd.h> -#include <grp.h> -#ifdef SECURE_RPC -# include <rpc/rpc.h> -# include <rpc/key_prot.h> -extern int key_setnet( struct key_netstarg *arg ); -#endif -#ifdef K5AUTH -# include <krb5/krb5.h> -#endif -#ifdef HAVE_SETUSERCONTEXT -# include <login_cap.h> -#endif -#ifdef USE_PAM -# ifdef HAVE_PAM_PAM_APPL_H -# include <pam/pam_appl.h> -# else -# include <security/pam_appl.h> -# endif -#elif defined(_AIX) /* USE_PAM */ -# include <login.h> -# include <usersec.h> -extern int loginrestrictions( const char *Name, const int Mode, const char *Tty, char **Msg ); -extern int loginfailed( const char *User, const char *Host, const char *Tty ); -extern int loginsuccess( const char *User, const char *Host, const char *Tty, char **Msg ); -#else /* USE_PAM || _AIX */ -# ifdef KERBEROS -# include <sys/param.h> -# include <krb.h> -# ifndef NO_AFS -# include <kafs.h> -# endif -# endif -/* for nologin */ -# include <sys/types.h> -# include <unistd.h> -/* for expiration */ -# include <time.h> -#endif /* USE_PAM || _AIX */ -#ifdef HAVE_SHADOW -# include <shadow.h> -#endif -#include <signal.h> - -#ifdef WITH_CONSOLE_KIT -#include "consolekit.h" -#endif - -#define AU_FAILED 0 -#define AU_SUCCESS 1 -#ifdef HAVE_LIBAUDIT -#include <libaudit.h> -#else -#define log_to_audit_system(l,h,d,s) do { ; } while (0) -#endif - -#ifdef WITH_CONSOLE_KIT -#include "consolekit.h" -#endif - -/* - * Session data, mostly what struct verify_info was for - */ -char *curuser; -char *curpass; -char *curtype; -char *newpass; -char **userEnviron; -char **systemEnviron; -static int curuid; -static int curgid; -int cursource; - -char *dmrcuser; -char *curdmrc; -char *newdmrc; - -static struct passwd *p; -#ifdef HAVE_SETUSERCONTEXT -# ifdef HAVE_LOGIN_GETCLASS -login_cap_t *lc; -# else -struct login_cap *lc; -# endif -#endif -#ifdef USE_PAM -static pam_handle_t *pamh; -#elif defined(_AIX) -static char tty[16], hostname[100]; -#else -# ifdef USESHADOW -static struct spwd *sp; -# endif -# ifdef KERBEROS -static char krbtkfile[MAXPATHLEN]; -# endif -#endif - -#define V_RET_AUTH \ - do { \ - PrepErrorGreet (); \ - GSendInt (V_AUTH); \ - return 0; \ - } while(0) - -#define V_RET_FAIL(m) \ - do { \ - PrepErrorGreet (); \ - GSendInt (V_MSG_ERR); \ - GSendStr (m); \ - GSendInt (V_FAIL); \ - return 0; \ - } while(0) - -#ifdef USE_PAM - -# ifdef PAM_MESSAGE_NONCONST -typedef struct pam_message pam_message_type; -typedef void *pam_gi_type; -# else -typedef const struct pam_message pam_message_type; -typedef const void *pam_gi_type; -# endif - -struct pam_data { - GConvFunc gconv; - int usecur; - int abort; -}; - -static int -PAM_conv( int num_msg, - pam_message_type **msg, - struct pam_response **resp, - void *appdata_ptr ) -{ - int count; - struct pam_response *reply; - struct pam_data *pd = (struct pam_data *)appdata_ptr; - - if (!(reply = Calloc( num_msg, sizeof(*reply) ))) - return PAM_CONV_ERR; - - ReInitErrorLog(); - Debug( "PAM_conv\n" ); - for (count = 0; count < num_msg; count++) - switch (msg[count]->msg_style) { - case PAM_TEXT_INFO: - Debug( " PAM_TEXT_INFO: %s\n", msg[count]->msg ); - PrepErrorGreet(); - GSendInt( V_MSG_INFO ); - GSendStr( msg[count]->msg ); - continue; - case PAM_ERROR_MSG: - Debug( " PAM_ERROR_MSG: %s\n", msg[count]->msg ); - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( msg[count]->msg ); - continue; - default: - /* could do better error handling here, but see below ... */ - if (pd->usecur) { - switch (msg[count]->msg_style) { - /* case PAM_PROMPT_ECHO_ON: cannot happen */ - case PAM_PROMPT_ECHO_OFF: - Debug( " PAM_PROMPT_ECHO_OFF (usecur): %s\n", msg[count]->msg ); - if (!curpass) - pd->gconv( GCONV_PASS, 0 ); - StrDup( &reply[count].resp, curpass ); - break; - default: - LogError( "Unknown PAM message style <%d>\n", msg[count]->msg_style ); - goto conv_err; - } - } else { - switch (msg[count]->msg_style) { - case PAM_PROMPT_ECHO_ON: - Debug( " PAM_PROMPT_ECHO_ON: %s\n", msg[count]->msg ); - reply[count].resp = pd->gconv( GCONV_NORMAL, msg[count]->msg ); - break; - case PAM_PROMPT_ECHO_OFF: - Debug( " PAM_PROMPT_ECHO_OFF: %s\n", msg[count]->msg ); - reply[count].resp = pd->gconv( GCONV_HIDDEN, msg[count]->msg ); - break; -#ifdef PAM_BINARY_PROMPT - case PAM_BINARY_PROMPT: - Debug( " PAM_BINARY_PROMPT\n" ); - reply[count].resp = pd->gconv( GCONV_BINARY, msg[count]->msg ); - break; -#endif - default: - LogError( "Unknown PAM message style <%d>\n", msg[count]->msg_style ); - goto conv_err; - } - } - if (!reply[count].resp) { - Debug( " PAM_conv aborted\n" ); - pd->abort = TRUE; - goto conv_err; - } - reply[count].resp_retcode = PAM_SUCCESS; /* unused in linux-pam */ - } - Debug( " PAM_conv success\n" ); - *resp = reply; - return PAM_SUCCESS; - - conv_err: - for (; count >= 0; count--) - if (reply[count].resp) - switch (msg[count]->msg_style) { - case PAM_PROMPT_ECHO_ON: - case PAM_PROMPT_ECHO_OFF: /* could wipe ... */ -#ifdef PAM_BINARY_PROMPT - case PAM_BINARY_PROMPT: /* ... that too ... */ -#endif - free( reply[count].resp ); - break; - } - free( reply ); - return PAM_CONV_ERR; -} - -static int -PAM_conv_null( int num_msg, - pam_message_type **msg, - struct pam_response **resp, - void *appdata_ptr ATTR_UNUSED ) -{ - int count; - struct pam_response *reply; - - if (!(reply = Calloc( num_msg, sizeof(*reply) ))) - return PAM_CONV_ERR; - - ReInitErrorLog(); - Debug( "PAM_conv_null\n" ); - for (count = 0; count < num_msg; count++) { - switch (msg[count]->msg_style) { - case PAM_TEXT_INFO: - Debug( " PAM_TEXT_INFO: %s\n", msg[count]->msg ); - continue; - case PAM_ERROR_MSG: - LogError( "PAM error message: %s\n", msg[count]->msg ); - continue; - default: - /* unknown */ - Debug( " PAM_<%d>\n", msg[count]->msg_style ); - free( reply ); - return PAM_CONV_ERR; - } - reply[count].resp_retcode = PAM_SUCCESS; /* unused in linux-pam */ - } - Debug( " PAM_conv_null success\n" ); - *resp = reply; - return PAM_SUCCESS; -} - -# ifdef PAM_FAIL_DELAY -static void -fail_delay( int retval ATTR_UNUSED, unsigned usec_delay ATTR_UNUSED, - void *appdata_ptr ATTR_UNUSED ) -{} -# endif - - /** - * log_to_audit_system: - * @login: Name of user - * @hostname: Name of host machine - * @tty: Name of display - * @success: 1 for success, 0 for failure - * - * Logs the success or failure of the login attempt with the linux kernel - * audit system. The intent is to capture failed events where the user - * fails authentication or otherwise is not permitted to login. There are - * many other places where pam could potentially fail and cause login to - * fail, but these are system failures rather than the signs of an account - * being hacked. - * - * Returns nothing. - */ - -#ifdef HAVE_LIBAUDIT -static void -log_to_audit_system (const char *loginname, - const char *hostname, - const char *tty, - int success) -{ - struct passwd *pw; - char buf[64]; - int audit_fd; - - audit_fd = audit_open(); - if (loginname) - pw = getpwnam(loginname); - else { - loginname = "unknown"; - pw = NULL; - } - Debug("log_to_audit %p %s\n", pw, loginname); - - if (pw) { - snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid); - audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, - buf, hostname, NULL, tty, (int)success); - } else { - snprintf(buf, sizeof(buf), "acct=%s", loginname); - audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, - buf, hostname, NULL, tty, (int)success); - } - close(audit_fd); -} -#endif - -static int -doPAMAuth( const char *psrv, struct pam_data *pdata ) -{ - pam_gi_type pitem; - struct pam_conv pconv; - int pretc; - - pdata->abort = FALSE; - pconv.conv = PAM_conv; - pconv.appdata_ptr = (void *)pdata; - Debug( " PAM service %s\n", psrv ); - if ((pretc = pam_start( psrv, curuser, &pconv, &pamh )) != PAM_SUCCESS) - goto pam_bail2; - if ((pretc = pam_set_item( pamh, PAM_TTY, td->name )) != PAM_SUCCESS) { - pam_bail: - pam_end( pamh, pretc ); - pamh = 0; - pam_bail2: - ReInitErrorLog(); - LogError( "PAM error: %s\n", pam_strerror( 0, pretc ) ); - V_RET_FAIL( 0 ); - } - if ((td->displayType & d_location) == dForeign) { - char *cp = strchr( td->name, ':' ); - *cp = 0; - pretc = pam_set_item( pamh, PAM_RHOST, td->name ); - *cp = ':'; - if (pretc != PAM_SUCCESS) - goto pam_bail; - } -# ifdef __sun__ /* Only Solaris <= 9, but checking it does not seem worth it. */ - else if (pam_set_item( pamh, PAM_RHOST, 0 ) != PAM_SUCCESS) - goto pam_bail; -# endif -# ifdef PAM_FAIL_DELAY - pam_set_item( pamh, PAM_FAIL_DELAY, (void *)fail_delay ); -# endif - ReInitErrorLog(); - - Debug( " pam_authenticate() ...\n" ); - pretc = pam_authenticate( pamh, - td->allowNullPasswd ? 0 : PAM_DISALLOW_NULL_AUTHTOK ); - ReInitErrorLog(); - Debug( " pam_authenticate() returned: %s\n", pam_strerror( pamh, pretc ) ); - if (pdata->abort) { - pam_end( pamh, PAM_SUCCESS ); - pamh = 0; - return 0; - } - if (!curuser) { - Debug( " asking PAM for user ...\n" ); - pam_get_item( pamh, PAM_USER, &pitem ); - ReInitErrorLog(); - StrDup( &curuser, (const char *)pitem ); - GSendInt( V_PUT_USER ); - GSendStr( curuser ); - } - if (pretc != PAM_SUCCESS) { - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - switch (pretc) { - case PAM_USER_UNKNOWN: - case PAM_AUTH_ERR: - case PAM_MAXTRIES: /* should handle this better ... */ - case PAM_AUTHINFO_UNAVAIL: /* returned for unknown users ... bogus */ - pam_end( pamh, pretc ); - pamh = 0; - V_RET_AUTH; - default: - pam_end( pamh, pretc ); - pamh = 0; - V_RET_FAIL( 0 ); - } - } - return 1; -} - -#endif /* USE_PAM */ - -static int -#if defined(USE_PAM) || defined(_AIX) -AccNoPass( const char *un ) -{ - struct passwd *pw = 0; -# ifdef HAVE_SHADOW /* (sic!) - not USESHADOW */ - struct spwd *spw; -# endif -#else -AccNoPass( const char *un, struct passwd *pw ) -{ -#endif - struct group *gr; - char **fp; - int hg; - - if (!*un) - return 0; - - if (cursource != PWSRC_MANUAL) - return 1; - - for (hg = 0, fp = td->noPassUsers; *fp; fp++) - if (**fp == '@') - hg = 1; - else if (!strcmp( un, *fp )) - return 1; - else if (!strcmp( "*", *fp )) { -#if defined(USE_PAM) || defined(_AIX) - if (!(pw = getpwnam( un ))) - return 0; - if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') - continue; -# ifdef HAVE_SHADOW /* (sic!) - not USESHADOW */ - if ((spw = getspnam( un )) && - (spw->sp_pwdp[0] == '!' || spw->sp_pwdp[0] == '*')) - continue; -# endif -#endif - if (pw->pw_uid) - return 1; - } - -#if defined(USE_PAM) || defined(_AIX) - if (hg && (pw || (pw = getpwnam( un )))) { -#else - if (hg) { -#endif - for (setgrent(); (gr = getgrent()); ) - for (fp = td->noPassUsers; *fp; fp++) - if (**fp == '@' && !strcmp( gr->gr_name, *fp + 1 )) { - if (pw->pw_gid == gr->gr_gid) { - endgrent(); - return 1; - } - for (; *gr->gr_mem; gr->gr_mem++) - if (!strcmp( un, *gr->gr_mem )) { - endgrent(); - return 1; - } - } - endgrent(); - } - - return 0; -} - -#if !defined(USE_PAM) && !defined(_AIX) && defined(HAVE_SETUSERCONTEXT) -# define LC_RET0 do { login_close(lc); return 0; } while(0) -#else -# define LC_RET0 return 0 -#endif - -int -Verify( GConvFunc gconv, int rootok ) -{ -#ifdef USE_PAM - const char *psrv; - struct pam_data pdata; - int pretc, pnopass; - char psrvb[64]; -#elif defined(_AIX) - char *msg, *curret; - int i, reenter; -#else - struct stat st; - const char *nolg; - char *buf; - int fd; -# ifdef HAVE_GETUSERSHELL - char *s; -# endif -# if defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || defined(USESHADOW) - int tim, expir, warntime, quietlog; -# endif -#endif - - Debug( "Verify ...\n" ); - -#ifdef USE_PAM - - pnopass = FALSE; - if (!strcmp( curtype, "classic" )) { - if (!gconv( GCONV_USER, 0 )) - return 0; - if (AccNoPass( curuser )) { - gconv( GCONV_PASS_ND, 0 ); - if (!*curpass) { - pnopass = TRUE; - sprintf( psrvb, "%.31s-np", PAMService ); - psrv = psrvb; - } else - psrv = PAMService; - } else - psrv = PAMService; - pdata.usecur = TRUE; - } else if (!strcmp( curtype, "pam" )) { - psrv = PAMService; - pdata.usecur = FALSE; - } else { - sprintf( psrvb, "%.31s-%.31s", PAMService, curtype ); - psrv = psrvb; - pdata.usecur = FALSE; - } - pdata.gconv = gconv; - if (!doPAMAuth( psrv, &pdata )) - return 0; - -#elif defined(_AIX) - - if ((td->displayType & d_location) == dForeign) { - char *tmpch; - strncpy( hostname, td->name, sizeof(hostname) - 1 ); - hostname[sizeof(hostname)-1] = '\0'; - if ((tmpch = strchr( hostname, ':' ))) - *tmpch = '\0'; - } else - hostname[0] = '\0'; - - /* tty names should only be 15 characters long */ -# if 0 - for (i = 0; i < 15 && td->name[i]; i++) { - if (td->name[i] == ':' || td->name[i] == '.') - tty[i] = '_'; - else - tty[i] = td->name[i]; - } - tty[i] = '\0'; -# else - memcpy( tty, "/dev/xdm/", 9 ); - for (i = 0; i < 6 && td->name[i]; i++) { - if (td->name[i] == ':' || td->name[i] == '.') - tty[9 + i] = '_'; - else - tty[9 + i] = td->name[i]; - } - tty[9 + i] = '\0'; -# endif - - if (!strcmp( curtype, "classic" )) { - if (!gconv( GCONV_USER, 0 )) - return 0; - if (AccNoPass( curuser )) { - gconv( GCONV_PASS_ND, 0 ); - if (!*curpass) { - Debug( "accepting despite empty password\n" ); - goto done; - } - } else - if (!gconv( GCONV_PASS, 0 )) - return 0; - enduserdb(); - msg = NULL; - if ((i = authenticate( curuser, curpass, &reenter, &msg ))) { - Debug( "authenticate() failed: %s\n", msg ); - if (msg) - free( msg ); - loginfailed( curuser, hostname, tty ); - if (i == ENOENT || i == ESAD) - V_RET_AUTH; - else - V_RET_FAIL( 0 ); - } - if (reenter) { - LogError( "authenticate() requests more data: %s\n", msg ); - free( msg ); - V_RET_FAIL( 0 ); - } - } else if (!strcmp( curtype, "generic" ) || !strcmp(curtype, "pam")) { - if (!gconv( GCONV_USER, 0 )) - return 0; - for (curret = 0;;) { - msg = NULL; - if ((i = authenticate( curuser, curret, &reenter, &msg ))) { - Debug( "authenticate() failed: %s\n", msg ); - if (msg) - free( msg ); - loginfailed( curuser, hostname, tty ); - if (i == ENOENT || i == ESAD) - V_RET_AUTH; - else - V_RET_FAIL( 0 ); - } - if (curret) - free( curret ); - if (!reenter) - break; - if (!(curret = gconv( GCONV_HIDDEN, msg ))) - return 0; - free( msg ); - } - } else { - LogError( "Unsupported authentication type %\"s requested\n", curtype ); - V_RET_FAIL( 0 ); - } - if (msg) { - PrepErrorGreet(); - GSendInt( V_MSG_INFO ); - GSendStr( msg ); - free( msg ); - } - - done: - -#else - - if (strcmp( curtype, "classic" )) { - LogError( "Unsupported authentication type %\"s requested\n", curtype ); - V_RET_FAIL( 0 ); - } - - if (!gconv( GCONV_USER, 0 )) - return 0; - - if (!(p = getpwnam( curuser ))) { - Debug( "getpwnam() failed.\n" ); - gconv( GCONV_PASS, 0 ); - V_RET_AUTH; - } - if (p->pw_passwd[0] == '!' || p->pw_passwd[0] == '*') { - Debug( "account is locked\n" ); - gconv( GCONV_PASS, 0 ); - V_RET_AUTH; - } - -# ifdef USESHADOW - if ((sp = getspnam( curuser ))) { - p->pw_passwd = sp->sp_pwdp; - if (p->pw_passwd[0] == '!' || p->pw_passwd[0] == '*') { - Debug( "account is locked\n" ); - gconv( GCONV_PASS, 0 ); - V_RET_AUTH; - } - } else - Debug( "getspnam() failed: %m. Are you root?\n" ); -# endif - - if (!*p->pw_passwd) { - if (!td->allowNullPasswd) { - Debug( "denying user with empty password\n" ); - gconv( GCONV_PASS, 0 ); - V_RET_AUTH; - } - goto nplogin; - } - - if (AccNoPass( curuser, p )) { - nplogin: - gconv( GCONV_PASS_ND, 0 ); - if (!*curpass) { - Debug( "accepting password-less login\n" ); - goto done; - } - } else - if (!gconv( GCONV_PASS, 0 )) - return 0; - -# ifdef KERBEROS - if (p->pw_uid) { - int ret; - char realm[REALM_SZ]; - - if (krb_get_lrealm( realm, 1 )) { - LogError( "Can't get KerberosIV realm.\n" ); - V_RET_FAIL( 0 ); - } - - sprintf( krbtkfile, "%s.%.*s", TKT_ROOT, MAXPATHLEN - strlen( TKT_ROOT ) - 2, td->name ); - krb_set_tkt_string( krbtkfile ); - unlink( krbtkfile ); - - ret = krb_verify_user( curuser, "", realm, curpass, 1, "rcmd" ); - if (ret == KSUCCESS) { - chown( krbtkfile, p->pw_uid, p->pw_gid ); - Debug( "KerberosIV verify succeeded\n" ); - goto done; - } else if (ret != KDC_PR_UNKNOWN && ret != SKDC_CANT) { - LogError( "KerberosIV verification failure %\"s for %s\n", - krb_get_err_text( ret ), curuser ); - krbtkfile[0] = '\0'; - V_RET_FAIL( 0 ); - } - Debug( "KerberosIV verify failed: %s\n", krb_get_err_text( ret ) ); - } - krbtkfile[0] = '\0'; -# endif /* KERBEROS */ - -# if defined(ultrix) || defined(__ultrix__) - if (authenticate_user( p, curpass, NULL ) < 0) -# elif defined(HAVE_CRYPT) - if (strcmp( crypt( curpass, p->pw_passwd ), p->pw_passwd )) -# else - if (strcmp( curpass, p->pw_passwd )) -# endif - { - Debug( "password verify failed\n" ); - V_RET_AUTH; - } - - done: - -#endif /* !defined(USE_PAM) && !defined(_AIX) */ - - Debug( "restrict %s ...\n", curuser ); - -#if defined(USE_PAM) || defined(_AIX) - if (!(p = getpwnam( curuser ))) { - LogError( "getpwnam(%s) failed.\n", curuser ); - V_RET_FAIL( 0 ); - } -#endif - if (!p->pw_uid) { - if (!rootok && !td->allowRootLogin) - V_RET_FAIL( "Root logins are not allowed" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - return 1; /* don't deny root to log in */ - } - -#ifdef USE_PAM - - Debug( " pam_acct_mgmt() ...\n" ); - pretc = pam_acct_mgmt( pamh, 0 ); - ReInitErrorLog(); - Debug( " pam_acct_mgmt() returned: %s\n", pam_strerror( pamh, pretc ) ); - if (pretc == PAM_NEW_AUTHTOK_REQD) { - pdata.usecur = FALSE; - pdata.gconv = conv_interact; - /* pam will have output a message already, so no PrepErrorGreet () */ - if (gconv != conv_interact || pnopass) { - pam_end( pamh, PAM_SUCCESS ); - pamh = 0; - GSendInt( V_CHTOK_AUTH ); - /* this cannot auth the wrong user, as only classic auths get here */ - while (!doPAMAuth( PAMService, &pdata )) - if (pdata.abort) - return 0; - GSendInt( V_PRE_OK ); - } else - GSendInt( V_CHTOK ); - for (;;) { - Debug( " pam_chauthtok() ...\n" ); - pretc = pam_chauthtok( pamh, PAM_CHANGE_EXPIRED_AUTHTOK ); - ReInitErrorLog(); - Debug( " pam_chauthtok() returned: %s\n", pam_strerror( pamh, pretc ) ); - if (pdata.abort) { - pam_end( pamh, PAM_SUCCESS ); - pamh = 0; - return 0; - } - if (pretc == PAM_SUCCESS) - break; - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - /* effectively there is only PAM_AUTHTOK_ERR */ - GSendInt( V_FAIL ); - } - if (curpass) - free( curpass ); - curpass = newpass; - newpass = 0; - } else if (pretc != PAM_SUCCESS) { - pam_end( pamh, pretc ); - pamh = 0; - V_RET_AUTH; - } - -#elif defined(_AIX) /* USE_PAM */ - - msg = NULL; - if (loginrestrictions( curuser, - ((td->displayType & d_location) == dForeign) ? S_RLOGIN : S_LOGIN, - tty, &msg ) == -1) - { - Debug( "loginrestrictions() - %s\n", msg ? msg : "error" ); - loginfailed( curuser, hostname, tty ); - PrepErrorGreet(); - if (msg) { - GSendInt( V_MSG_ERR ); - GSendStr( msg ); - } - GSendInt( V_AUTH ); - return 0; - } - if (msg) - free( (void *)msg ); - -#endif /* USE_PAM || _AIX */ - -#ifndef _AIX - -# ifdef HAVE_SETUSERCONTEXT -# ifdef HAVE_LOGIN_GETCLASS - lc = login_getclass( p->pw_class ); -# else - lc = login_getpwclass( p ); -# endif - if (!lc) - V_RET_FAIL( 0 ); - - p->pw_shell = login_getcapstr( lc, "shell", p->pw_shell, p->pw_shell ); -# endif - -# ifndef USE_PAM - -/* restrict_expired */ -# if defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || defined(USESHADOW) - -# if !defined(HAVE_STRUCT_PASSWD_PW_EXPIRE) || (!defined(HAVE_SETUSERCONTEXT) && defined(USESHADOW)) - if (sp) -# endif - { - -# define DEFAULT_WARN (2L * 7L) /* Two weeks */ - - tim = time( NULL ) / 86400L; - -# ifdef HAVE_SETUSERCONTEXT - quietlog = login_getcapbool( lc, "hushlogin", 0 ); - warntime = login_getcaptime( lc, "warnexpire", - DEFAULT_WARN * 86400L, - DEFAULT_WARN * 86400L ) / 86400L; -# else - quietlog = 0; -# ifdef USESHADOW - warntime = sp->sp_warn != -1 ? sp->sp_warn : DEFAULT_WARN; -# else - warntime = DEFAULT_WARN; -# endif -# endif - -# ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE - if (p->pw_expire) { - expir = p->pw_expire / 86400L; -# else - if (sp->sp_expire != -1) { - expir = sp->sp_expire; -# endif - if (tim > expir) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "Your account has expired;" - " please contact your system administrator" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - GSendInt( V_FAIL ); - LC_RET0; - } else if (tim > (expir - warntime) && !quietlog) { - ASPrintf( &buf, - "Warning: your account will expire in %d day(s)", - expir - tim ); - if (buf) { - PrepErrorGreet(); - GSendInt( V_MSG_INFO ); - GSendStr( buf ); - free( buf ); - } - } - } - -# ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE - if (p->pw_change) { - expir = p->pw_change / 86400L; -# else - if (!sp->sp_lstchg) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "You are required to change your password immediately" - " (root enforced)" ); - /* XXX todo password change */ - GSendInt( V_FAIL ); - LC_RET0; - } else if (sp->sp_max != -1) { - expir = sp->sp_lstchg + sp->sp_max; - if (sp->sp_inact != -1 && tim > expir + sp->sp_inact) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "Your account has expired;" - " please contact your system administrator" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - GSendInt( V_FAIL ); - LC_RET0; - } -# endif - if (tim > expir) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "You are required to change your password immediately" - " (password aged)" ); - /* XXX todo password change */ - GSendInt( V_FAIL ); - LC_RET0; - } else if (tim > (expir - warntime) && !quietlog) { - ASPrintf( &buf, - "Warning: your password will expire in %d day(s)", - expir - tim ); - if (buf) { - PrepErrorGreet(); - GSendInt( V_MSG_INFO ); - GSendStr( buf ); - free( buf ); - } - } - } - - } - -# endif /* HAVE_STRUCT_PASSWD_PW_EXPIRE || USESHADOW */ - -/* restrict_nologin */ -# ifndef _PATH_NOLOGIN -# define _PATH_NOLOGIN "/etc/nologin" -# endif - - if (( -# ifdef HAVE_SETUSERCONTEXT - /* Do we ignore a nologin file? */ - !login_getcapbool( lc, "ignorenologin", 0 )) && - (!stat( (nolg = login_getcapstr( lc, "nologin", "", NULL )), &st ) || -# endif - !stat( (nolg = _PATH_NOLOGIN), &st ))) - { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - if (st.st_size && (fd = open( nolg, O_RDONLY )) >= 0) { - if ((buf = Malloc( st.st_size + 1 ))) { - if (read( fd, buf, st.st_size ) == st.st_size) { - buf[st.st_size] = 0; - GSendStr( buf ); - free( buf ); - close( fd ); - GSendInt( V_FAIL ); - LC_RET0; - } - free( buf ); - } - close( fd ); - } - GSendStr( "Logins are not allowed at the moment.\nTry again later" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - GSendInt( V_FAIL ); - LC_RET0; - } - -/* restrict_time */ -# if defined(HAVE_SETUSERCONTEXT) && defined(HAVE_AUTH_TIMEOK) - if (!auth_timeok( lc, time( NULL ) )) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "You are not allowed to login at the moment" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - GSendInt( V_FAIL ); - LC_RET0; - } -# endif - -# ifdef HAVE_GETUSERSHELL - for (;;) { - if (!(s = getusershell())) { - Debug( "shell not in /etc/shells\n" ); - endusershell(); - V_RET_FAIL( "Your login shell is not listed in /etc/shells" ); - /* Log the failed login attempt */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); - } - if (!strcmp( s, p->pw_shell )) { - endusershell(); - break; - } - } -# endif - -# endif /* !USE_PAM */ - -/* restrict_nohome */ -# ifdef HAVE_SETUSERCONTEXT - if (login_getcapbool( lc, "requirehome", 0 )) { - struct stat st; - if (!*p->pw_dir || stat( p->pw_dir, &st ) || st.st_uid != p->pw_uid) { - PrepErrorGreet(); - GSendInt( V_MSG_ERR ); - GSendStr( "Home folder not available" ); - GSendInt( V_FAIL ); - LC_RET0; - } - } -# endif - -#endif /* !_AIX */ - - return 1; - -} - - -static const char *envvars[] = { - "TZ", /* SYSV and SVR4, but never hurts */ -#ifdef _AIX - "AUTHSTATE", /* for kerberos */ -#endif - NULL -}; - - -#if defined(USE_PAM) && defined(HAVE_INITGROUPS) -static int num_saved_gids; -static gid_t *saved_gids; - -static int -saveGids( void ) -{ - num_saved_gids = getgroups( 0, 0 ); - if (!(saved_gids = Malloc( sizeof(gid_t) * num_saved_gids ))) - return 0; - if (getgroups( num_saved_gids, saved_gids ) < 0) { - LogError( "saving groups failed: %m\n" ); - return 0; - } - return 1; -} - -static int -restoreGids( void ) -{ - if (setgroups( num_saved_gids, saved_gids ) < 0) { - LogError( "restoring groups failed: %m\n" ); - return 0; - } - if (setgid( p->pw_gid ) < 0) { - LogError( "restoring gid failed: %m\n" ); - return 0; - } - return 1; -} -#endif /* USE_PAM && HAVE_INITGROUPS */ - -static int -resetGids( void ) -{ -#ifdef HAVE_INITGROUPS - if (setgroups( 0, &p->pw_gid /* anything */ ) < 0) { - LogError( "restoring groups failed: %m\n" ); - return 0; - } -#endif - if (setgid( 0 ) < 0) { - LogError( "restoring gid failed: %m\n" ); - return 0; - } - return 1; -} - -static int -SetGid( const char *name, int gid ) -{ - if (setgid( gid ) < 0) { - LogError( "setgid(%d) (user %s) failed: %m\n", gid, name ); - return 0; - } -#ifdef HAVE_INITGROUPS - if (initgroups( name, gid ) < 0) { - LogError( "initgroups for %s failed: %m\n", name ); - setgid( 0 ); - return 0; - } -#endif /* QNX4 doesn't support multi-groups, no initgroups() */ - return 1; -} - -static int -SetUid( const char *name, int uid ) -{ - if (setuid( uid ) < 0) { - LogError( "setuid(%d) (user %s) failed: %m\n", uid, name ); - return 0; - } - return 1; -} - -static int -SetUser( const char *name, int uid, int gid ) -{ - if (SetGid( name, gid )) { - if (SetUid( name, uid )) - return 1; - resetGids(); - } - return 0; -} - -#if defined(SECURE_RPC) || defined(K5AUTH) -static void -NukeAuth( int len, const char *name ) -{ - int i; - - for (i = 0; i < td->authNum; i++) - if (td->authorizations[i]->name_length == len && - !memcmp( td->authorizations[i]->name, name, len )) - { - memcpy( &td->authorizations[i], &td->authorizations[i+1], - sizeof(td->authorizations[i]) * (--td->authNum - i) ); - break; - } -} -#endif - -static void -mergeSessionArgs( int cansave ) -{ - char *mfname; - const char *fname; - int i, needsave; - - mfname = 0; - fname = ".dmrc"; - if ((!curdmrc || newdmrc) && *dmrcDir) - if (StrApp( &mfname, dmrcDir, "/", curuser, fname, (char *)0 )) - fname = mfname; - needsave = 0; - if (!curdmrc) { - curdmrc = iniLoad( fname ); - if (!curdmrc) { - StrDup( &curdmrc, "[Desktop]\nSession=default\n" ); - needsave = 1; - } - } - if (newdmrc) { - curdmrc = iniMerge( curdmrc, newdmrc ); - needsave = 1; - } - if (needsave && cansave) - if (!iniSave( curdmrc, fname ) && errno == ENOENT && mfname) { - for (i = 0; mfname[i]; i++) - if (mfname[i] == '/') { - mfname[i] = 0; - mkdir( mfname, 0755 ); - mfname[i] = '/'; - } - iniSave( curdmrc, mfname ); - } - if (mfname) - free( mfname ); -} - -static int removeAuth; -#ifdef USE_PAM -static int removeSession; -static int removeCreds; -#endif - -#ifdef WITH_CONSOLE_KIT -int -StartClient( const char *ck_session_cookie ) -#else -int -StartClient() -#endif -{ - const char *home, *sessargs, *desksess; - char **env, *xma; - char **argv, *fname, *str; -#ifdef USE_PAM - char **pam_env; -# ifdef _AIX - char **saved_env; -# endif - struct pam_conv pconv; - int pretc; -#else -# ifdef _AIX - char *msg; - char **theenv; - extern char **newenv; /* from libs.a, this is set up by setpenv */ -# endif -#endif -#ifdef HAVE_SETUSERCONTEXT - extern char **environ; -#endif - char *failsafeArgv[2], *lname; - int i, pid, lfd; - - if (StrCmp( dmrcuser, curuser )) { - if (curdmrc) { free( curdmrc ); curdmrc = 0; } - if (dmrcuser) { free( dmrcuser ); dmrcuser = 0; } - } - -#if defined(USE_PAM) || defined(_AIX) - if (!(p = getpwnam( curuser ))) { - LogError( "getpwnam(%s) failed.\n", curuser ); - return 0; - } -#endif - -#ifndef USE_PAM -# ifdef _AIX - msg = NULL; - loginsuccess( curuser, hostname, tty, &msg ); - if (msg) { - Debug( "loginsuccess() - %s\n", msg ); - free( (void *)msg ); - } -# else /* _AIX */ -# if defined(KERBEROS) && !defined(NO_AFS) - if (krbtkfile[0] != '\0') { - if (k_hasafs()) { - if (k_setpag() == -1) - LogError( "setpag() for %s failed\n", curuser ); - if ((ret = k_afsklog( NULL, NULL )) != KSUCCESS) - LogError( "AFS Warning: %s\n", krb_get_err_text( ret ) ); - } - } -# endif /* KERBEROS && AFS */ -# endif /* _AIX */ -#endif /* !PAM */ - - curuid = p->pw_uid; - curgid = p->pw_gid; - - env = baseEnv( curuser ); - xma = 0; - if (td->ctrl.fpath && StrDup( &xma, td->ctrl.fpath )) { - if ((td->allowShutdown == SHUT_ALL || - (td->allowShutdown == SHUT_ROOT && !curuser)) && - StrApp( &xma, ",maysd", (char *)0 )) - { - if (td->allowNuke == SHUT_ALL || - (td->allowNuke == SHUT_ROOT && !curuser)) - StrApp( &xma, ",mayfn", (char *)0 ); - StrApp( &xma, td->defSdMode == SHUT_FORCENOW ? ",fn" : - td->defSdMode == SHUT_TRYNOW ? ",tn" : ",sched", - (char *)0 ); - } - if ((td->displayType & d_location) == dLocal && AnyReserveDisplays()) - StrApp( &xma, ",rsvd", (char *)0 ); - } else - StrDup( &xma, "true" ); - StrApp( &xma, ",method=", curtype, (char *)0 ); - if (td_setup) - StrApp( &xma, ",auto", (char *)0 ); - if (xma) { - env = setEnv( env, "XDM_MANAGED", xma ); - free( xma ); - } - if (td->autoLock && cursource == PWSRC_AUTOLOGIN) - env = setEnv( env, "DESKTOP_LOCKED", "true" ); - env = setEnv( env, "PATH", curuid ? td->userPath : td->systemPath ); - env = setEnv( env, "SHELL", p->pw_shell ); - env = setEnv( env, "HOME", p->pw_dir ); - if (cursource == PWSRC_AUTOLOGIN) - env = setEnv (env, "TDM_AUTOLOGIN", curuser); -#if !defined(USE_PAM) && !defined(_AIX) && defined(KERBEROS) - if (krbtkfile[0] != '\0') - env = setEnv( env, "KRBTKFILE", krbtkfile ); -#endif -#ifdef WITH_CONSOLE_KIT - if (ck_session_cookie != NULL) { - env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie ); - } -#endif -#ifdef WITH_CONSOLE_KIT - if (ck_session_cookie != NULL) { - env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie ); - } -#endif - userEnviron = inheritEnv( env, envvars ); - env = systemEnv( p->pw_name ); - systemEnviron = setEnv( env, "HOME", p->pw_dir ); - Debug( "user environment:\n%[|''>'\n's" - "system environment:\n%[|''>'\n's" - "end of environments\n", - userEnviron, - systemEnviron ); - - /* - * for user-based authorization schemes, - * add the user to the server's allowed "hosts" list. - */ - for (i = 0; i < td->authNum; i++) { -#ifdef SECURE_RPC - if (td->authorizations[i]->name_length == 9 && - !memcmp( td->authorizations[i]->name, "SUN-DES-1", 9 )) - { - XHostAddress addr; - char netname[MAXNETNAMELEN+1]; - char domainname[MAXNETNAMELEN+1]; - - getdomainname( domainname, sizeof(domainname) ); - user2netname( netname, curuid, domainname ); - addr.family = FamilyNetname; - addr.length = strlen( netname ); - addr.address = netname; - XAddHost( dpy, &addr ); - } -#endif -#ifdef K5AUTH - if (td->authorizations[i]->name_length == 14 && - !memcmp( td->authorizations[i]->name, "MIT-KERBEROS-5", 14 )) - { - /* Update server's auth file with user-specific info. - * Don't need to AddHost because X server will do that - * automatically when it reads the cache we are about - * to point it at. - */ - XauDisposeAuth( td->authorizations[i] ); - td->authorizations[i] = - Krb5GetAuthFor( 14, "MIT-KERBEROS-5", td->name ); - SaveServerAuthorizations( td, td->authorizations, td->authNum ); - } -#endif - } - - if (*dmrcDir) - mergeSessionArgs( TRUE ); - - Debug( "now starting the session\n" ); - -#ifdef USE_PAM - /* the greeter is gone by now ... */ - pconv.conv = PAM_conv_null; - pconv.appdata_ptr = 0; - if ((pretc = pam_set_item( pamh, PAM_CONV, &pconv )) != PAM_SUCCESS) { - ReInitErrorLog(); - LogError( "pam_set_item() for %s failed: %s\n", - curuser, pam_strerror( pamh, pretc ) ); - return 0; - } - ReInitErrorLog(); -#endif - -#ifdef USE_PAM - -# ifdef HAVE_SETUSERCONTEXT - if (setusercontext( lc, p, p->pw_uid, LOGIN_SETGROUP )) { - LogError( "setusercontext(groups) for %s failed: %m\n", - curuser ); - return 0; - } -# else - if (!SetGid( curuser, curgid )) - return 0; -# endif - -# ifdef _AIX - if (!(pam_env = initStrArr( 0 ))) { - resetGids(); - return 0; - } - saved_env = environ; - environ = pam_env; -# endif - removeCreds = 1; /* set it first - i don't trust PAM's rollback */ - pretc = pam_setcred( pamh, 0 ); - ReInitErrorLog(); -# ifdef _AIX - pam_env = environ; - environ = saved_env; -# endif -# ifdef HAVE_INITGROUPS - /* This seems to be a strange place for it, but do it: - - after the initial groups are set - - after pam_setcred might have set something, even in the error case - - before pam_setcred(DELETE_CRED) might need it - */ - if (!saveGids()) - return 0; -# endif - if (pretc != PAM_SUCCESS) { - LogError( "pam_setcred() for %s failed: %s\n", - curuser, pam_strerror( pamh, pretc ) ); - resetGids(); - return 0; - } - - removeSession = 1; /* set it first - same as above */ - pretc = pam_open_session( pamh, 0 ); - ReInitErrorLog(); - if (pretc != PAM_SUCCESS) { - LogError( "pam_open_session() for %s failed: %s\n", - curuser, pam_strerror( pamh, pretc ) ); - resetGids(); - return 0; - } - - /* we don't want sessreg and the startup/reset scripts run with user - credentials. unfortunately, we can reset only the gids. */ - resetGids(); - -# define D_LOGIN_SETGROUP LOGIN_SETGROUP -#else /* USE_PAM */ -# define D_LOGIN_SETGROUP 0 -#endif /* USE_PAM */ - - /* Login succeeded */ - log_to_audit_system (curuser, td->remoteHost, td->name, AU_SUCCESS); - - removeAuth = 1; - chownCtrl( &td->ctrl, curuid ); - endpwent(); -#if !defined(USE_PAM) && defined(USESHADOW) && !defined(_AIX) - endspent(); -#endif - ClearCloseOnFork( mstrtalk.pipe->wfd ); - switch (pid = Fork()) { - case 0: - - sessreg( td, getpid(), curuser, curuid ); - - if (source( systemEnviron, td->startup, td_setup )) { - LogError( "Cannot execute startup script %\"s\n", td->startup ); - exit( 1 ); - } - - if (Setjmp( mstrtalk.errjmp )) - exit( 1 ); - GSet( &mstrtalk ); - - setsid(); - Signal( SIGINT, SIG_DFL ); - - /* Memory leaks are ok here as we exec() soon. */ - -#if defined(USE_PAM) || !defined(_AIX) - -# ifdef USE_PAM - /* pass in environment variables set by libpam and modules it called */ -# ifndef _AIX - pam_env = pam_getenvlist( pamh ); - ReInitErrorLog(); -# endif - if (pam_env) - for (; *pam_env; pam_env++) - userEnviron = putEnv( *pam_env, userEnviron ); -# endif - -# ifdef HAVE_SETLOGIN - if (setlogin( curuser ) < 0) { - LogError( "setlogin for %s failed: %m\n", curuser ); - exit( 1 ); - } -# define D_LOGIN_SETLOGIN LOGIN_SETLOGIN -# else -# define D_LOGIN_SETLOGIN 0 -# endif - -# if defined(USE_PAM) && defined(HAVE_INITGROUPS) - if (!restoreGids()) - exit( 1 ); -# endif - -# ifndef HAVE_SETUSERCONTEXT - -# ifdef USE_PAM - if (!SetUid( curuser, curuid )) - exit( 1 ); -# else - if (!SetUser( curuser, curuid, curgid )) - exit( 1 ); -# endif - -# else /* !HAVE_SETUSERCONTEXT */ - - /* - * Destroy environment. - * We need to do this before setusercontext() because that may - * set or reset some environment variables. - */ - if (!(environ = initStrArr( 0 ))) - exit( 1 ); - - /* - * Set the user's credentials: uid, gid, groups, - * environment variables, resource limits, and umask. - */ - if (setusercontext( lc, p, p->pw_uid, - LOGIN_SETALL & ~(D_LOGIN_SETGROUP|D_LOGIN_SETLOGIN) ) < 0) - { - LogError( "setusercontext for %s failed: %m\n", curuser ); - exit( 1 ); - } - - for (i = 0; environ[i]; i++) - userEnviron = putEnv( environ[i], userEnviron ); - -# endif /* !HAVE_SETUSERCONTEXT */ - -#else /* PAM || !_AIX */ - /* - * Set the user's credentials: uid, gid, groups, - * audit classes, user limits, and umask. - */ - if (setpcred( curuser, NULL ) == -1) { - LogError( "setpcred for %s failed: %m\n", curuser ); - exit( 1 ); - } - - /* - * Set the users process environment. Store protected variables and - * obtain updated user environment list. This call will initialize - * global 'newenv'. - */ - if (setpenv( curuser, PENV_INIT | PENV_ARGV | PENV_NOEXEC, - userEnviron, NULL ) != 0) - { - LogError( "Can't set %s's process environment\n", curuser ); - exit( 1 ); - } - userEnviron = newenv; - -#endif /* _AIX */ - - /* - * for user-based authorization schemes, - * use the password to get the user's credentials. - */ -#ifdef SECURE_RPC - /* do like "keylogin" program */ - if (!curpass[0]) - LogInfo( "No password for NIS provided.\n" ); - else { - char netname[MAXNETNAMELEN+1], secretkey[HEXKEYBYTES+1]; - int nameret, keyret; - int len; - int key_set_ok = 0; - struct key_netstarg netst; - - nameret = getnetname( netname ); - Debug( "user netname: %s\n", netname ); - len = strlen( curpass ); - if (len > 8) - bzero( curpass + 8, len - 8 ); - keyret = getsecretkey( netname, secretkey, curpass ); - Debug( "getsecretkey returns %d, key length %d\n", - keyret, strlen( secretkey ) ); - netst.st_netname = netname; - memcpy( netst.st_priv_key, secretkey, HEXKEYBYTES ); - memset( netst.st_pub_key, 0, HEXKEYBYTES ); - if (key_setnet( &netst ) < 0) - Debug( "Could not set secret key.\n" ); - /* is there a key, and do we have the right password? */ - if (keyret == 1) { - if (*secretkey) { - keyret = key_setsecret( secretkey ); - Debug( "key_setsecret returns %d\n", keyret ); - if (keyret == -1) - LogError( "Failed to set NIS secret key\n" ); - else - key_set_ok = 1; - } else { - /* found a key, but couldn't interpret it */ - LogError( "Password incorrect for NIS principal %s\n", - nameret ? netname : curuser ); - } - } - if (!key_set_ok) - NukeAuth( 9, "SUN-DES-1" ); - bzero( secretkey, strlen( secretkey ) ); - } -#endif -#ifdef K5AUTH - /* do like "kinit" program */ - if (!curpass[0]) - LogInfo( "No password for Kerberos5 provided.\n" ); - else - if ((str = Krb5Init( curuser, curpass, td->name ))) - userEnviron = setEnv( userEnviron, "KRB5CCNAME", str ); - else - NukeAuth( 14, "MIT-KERBEROS-5" ); -#endif /* K5AUTH */ - if (td->autoReLogin) { - GSendInt( D_ReLogin ); - GSendStr( curuser ); - GSendStr( curpass ); - GSendStr( newdmrc ); - } - if (curpass) - bzero( curpass, strlen( curpass ) ); - SetUserAuthorization( td ); - home = getEnv( userEnviron, "HOME" ); - if (home) { - if (chdir( home ) < 0) { - LogError( "Cannot chdir to %s's home %s: %m, using /\n", - curuser, home ); - home = 0; - userEnviron = setEnv( userEnviron, "HOME", "/" ); - goto cdroot; - } - ASPrintf( &lname, td->clientLogFile, td->name ); - if ((lfd = creat( lname, 0600 )) < 0) { - LogWarn( "Cannot create session log file %s: %m\n", lname ); - free( lname ); - goto tmperr; - } - } else { - cdroot: - chdir( "/" ); - tmperr: - ASPrintf( &lname, "/tmp/xerr-%s-%s", curuser, td->name ); - unlink( lname ); - if ((lfd = open( lname, O_WRONLY|O_CREAT|O_EXCL, 0600 )) < 0) { - LogError( "Cannot create fallback session log file %s: %m\n", - lname ); - goto logerr; - } - } - dup2( lfd, 1 ); - dup2( lfd, 2 ); - close( lfd ); - logerr: - free( lname ); - if (!*dmrcDir) - mergeSessionArgs( home != 0 ); - if (!(desksess = iniEntry( curdmrc, "Desktop", "Session", 0 ))) - desksess = "failsafe"; /* only due to OOM */ - GSendInt( D_User ); - GSendInt( curuid ); - GSendStr( curuser ); - GSendStr( desksess ); - close( mstrtalk.pipe->wfd ); - userEnviron = setEnv( userEnviron, "DESKTOP_SESSION", desksess ); - for (i = 0; td->sessionsDirs[i]; i++) { - fname = 0; - if (StrApp( &fname, td->sessionsDirs[i], "/", desksess, ".desktop", (char *)0 )) { - if ((str = iniLoad( fname ))) { - if (!StrCmp( iniEntry( str, "Desktop Entry", "Hidden", 0 ), "true" ) || - !(sessargs = iniEntry( str, "Desktop Entry", "Exec", 0 ))) - sessargs = ""; - free( str ); - free( fname ); - goto gotit; - } - free( fname ); - } - } - if (!strcmp( desksess, "failsafe" ) || - !strcmp( desksess, "default" ) || - !strcmp( desksess, "custom" )) - sessargs = desksess; - else - sessargs = ""; - gotit: - if (!(argv = parseArgs( (char **)0, td->session )) || - !(argv = addStrArr( argv, sessargs, -1 ))) - exit( 1 ); - if (argv[0] && *argv[0]) { - Debug( "executing session %\"[s\n", argv ); - execute( argv, userEnviron ); - LogError( "Session %\"s execution failed: %m\n", argv[0] ); - } else - LogError( "Session has no command/arguments\n" ); - failsafeArgv[0] = td->failsafeClient; - failsafeArgv[1] = 0; - execute( failsafeArgv, userEnviron ); - LogError( "Failsafe client %\"s execution failed: %m\n", - failsafeArgv[0] ); - exit( 1 ); - case -1: - RegisterCloseOnFork( mstrtalk.pipe->wfd ); - LogError( "Forking session on %s failed: %m\n", td->name ); - return 0; - default: - RegisterCloseOnFork( mstrtalk.pipe->wfd ); - Debug( "StartSession, fork succeeded %d\n", pid ); - return pid; - } -} - -void -SessionExit( int status ) -{ - int pid; -#ifdef USE_PAM - int pretc; -#endif - - Signal( SIGTERM, SIG_IGN ); - - if (removeAuth) { - if (source( systemEnviron, td->reset, td_setup )) - LogError( "Cannot execute reset script %\"s\n", td->reset ); - sessreg( td, 0, 0, 0 ); - - switch ((pid = Fork())) { - case 0: -#if defined(USE_PAM) && defined(HAVE_INITGROUPS) - if (restoreGids() && SetUid( curuser, curuid )) -#else - if (SetUser( curuser, curuid, curgid )) -#endif - - { - RemoveUserAuthorization( td ); -#ifdef K5AUTH - Krb5Destroy( td->name ); -#endif /* K5AUTH */ -#if !defined(USE_PAM) && !defined(_AIX) -# ifdef KERBEROS - if (krbtkfile[0]) { - (void)dest_tkt(); -# ifndef NO_AFS - if (k_hasafs()) - (void)k_unlog(); -# endif - } -# endif -#endif /* !USE_PAM && !_AIX*/ - } - exit( 0 ); - case -1: - LogError( "Cannot clean up session: fork() failed: %m" ); - break; - default: - Wait4( pid ); - break; - } - } - -#ifdef USE_PAM - if (removeCreds) { -# ifdef HAVE_INITGROUPS - restoreGids(); -# endif - if (removeSession) - if ((pretc = pam_close_session( pamh, 0 )) != PAM_SUCCESS) - LogError( "pam_close_session() failed: %s\n", - pam_strerror( pamh, pretc ) ); - if ((pretc = pam_setcred( pamh, PAM_DELETE_CRED )) != PAM_SUCCESS) - LogError( "pam_setcred(DELETE_CRED) failed: %s\n", - pam_strerror( pamh, pretc ) ); - resetGids(); - } - if (pamh) { - pam_end( pamh, PAM_SUCCESS ); - ReInitErrorLog(); - } -#endif - - /* make sure the server gets reset after the session is over */ - if (td->serverPid >= 2) { - if (!td->terminateServer && td->resetSignal) - TerminateProcess( td->serverPid, td->resetSignal ); - } else - ResetServer( td ); - Debug( "display %s exiting with status %d\n", td->name, status ); - exit( status ); -} - -int -ReadDmrc() -{ - char *data, *fname = 0; - int len, pid, pfd[2], err; - - if (!dmrcuser || !dmrcuser[0] || !(p = getpwnam( dmrcuser ))) - return GE_NoUser; - - if (*dmrcDir) { - if (!StrApp( &fname, dmrcDir, "/", dmrcuser, ".dmrc", (char *)0 )) - return GE_Error; - if (!(curdmrc = iniLoad( fname ))) { - free( fname ); - return GE_Ok; - } - free( fname ); - return GE_NoFile; - } - - if (!StrApp( &fname, p->pw_dir, "/.dmrc", (char *)0 )) - return GE_Error; - if (pipe( pfd )) - return GE_Error; - if ((pid = Fork()) < 0) { - close( pfd[0] ); - close( pfd[1] ); - return GE_Error; - } - if (!pid) { - if (!SetUser( p->pw_name, p->pw_uid, p->pw_gid )) - exit( 0 ); - if (!(data = iniLoad( fname ))) { - static const int m1 = -1; - write( pfd[1], &m1, sizeof(int) ); - exit( 0 ); - } - len = strlen( data ); - write( pfd[1], &len, sizeof(int) ); - write( pfd[1], data, len + 1 ); - exit( 0 ); - } - close( pfd[1] ); - free( fname ); - err = GE_Error; - if (Reader( pfd[0], &len, sizeof(int) ) == sizeof(int)) { - if (len == -1) - err = GE_Denied; - else if ((curdmrc = Malloc( len + 1 ))) { - if (Reader( pfd[0], curdmrc, len + 1 ) == len + 1) - err = GE_Ok; - else { - free( curdmrc ); - curdmrc = 0; - } - } - } - close( pfd[0] ); - (void)Wait4( pid ); - return err; -} diff --git a/kdm/backend/consolekit.c b/kdm/backend/consolekit.c deleted file mode 100644 index 61d0b165e..000000000 --- a/kdm/backend/consolekit.c +++ /dev/null @@ -1,557 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - - Copyright (C) 2006-2007 William Jon McCann <[email protected]> - Copyright (C) 2007 Kevin Kofler <[email protected]> - - 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. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include <stdlib.h> -#include <string.h> -#include <pwd.h> - -#define DBUS_API_SUBJECT_TO_CHANGE -#include <dbus/dbus.h> - -#include "consolekit.h" - - -#define CK_NAME "org.freedesktop.ConsoleKit" -#define CK_PATH "/org/freedesktop/ConsoleKit" -#define CK_INTERFACE "org.freedesktop.ConsoleKit" -#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" -#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" -#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" - -static DBusConnection *private_connection = NULL; - -static void -add_param_int (DBusMessageIter *iter_struct, - const char *key, - int value) -{ - DBusMessageIter iter_struct_entry; - DBusMessageIter iter_var; - - dbus_message_iter_open_container (iter_struct, - DBUS_TYPE_STRUCT, - NULL, - &iter_struct_entry); - - dbus_message_iter_append_basic (&iter_struct_entry, - DBUS_TYPE_STRING, - &key); - - dbus_message_iter_open_container (&iter_struct_entry, - DBUS_TYPE_VARIANT, - DBUS_TYPE_INT32_AS_STRING, - &iter_var); - - dbus_message_iter_append_basic (&iter_var, - DBUS_TYPE_INT32, - &value); - - dbus_message_iter_close_container (&iter_struct_entry, - &iter_var); - - dbus_message_iter_close_container (iter_struct, &iter_struct_entry); -} - -static void -add_param_boolean (DBusMessageIter *iter_struct, - const char *key, - int value) -{ - DBusMessageIter iter_struct_entry; - DBusMessageIter iter_var; - - dbus_message_iter_open_container (iter_struct, - DBUS_TYPE_STRUCT, - NULL, - &iter_struct_entry); - - dbus_message_iter_append_basic (&iter_struct_entry, - DBUS_TYPE_STRING, - &key); - - dbus_message_iter_open_container (&iter_struct_entry, - DBUS_TYPE_VARIANT, - DBUS_TYPE_BOOLEAN_AS_STRING, - &iter_var); - - dbus_message_iter_append_basic (&iter_var, - DBUS_TYPE_BOOLEAN, - &value); - - dbus_message_iter_close_container (&iter_struct_entry, - &iter_var); - - dbus_message_iter_close_container (iter_struct, &iter_struct_entry); -} - -static void -add_param_string (DBusMessageIter *iter_struct, - const char *key, - const char *value) -{ - DBusMessageIter iter_struct_entry; - DBusMessageIter iter_var; - - dbus_message_iter_open_container (iter_struct, - DBUS_TYPE_STRUCT, - NULL, - &iter_struct_entry); - - dbus_message_iter_append_basic (&iter_struct_entry, - DBUS_TYPE_STRING, - &key); - - dbus_message_iter_open_container (&iter_struct_entry, - DBUS_TYPE_VARIANT, - DBUS_TYPE_STRING_AS_STRING, - &iter_var); - - dbus_message_iter_append_basic (&iter_var, - DBUS_TYPE_STRING, - &value); - - dbus_message_iter_close_container (&iter_struct_entry, - &iter_var); - - dbus_message_iter_close_container (iter_struct, &iter_struct_entry); -} - -static int -session_get_x11_display (DBusConnection *connection, - const char *ssid, - char **str) -{ - DBusError error; - DBusMessage *message; - DBusMessage *reply; - DBusMessageIter iter; - const char *value; - - if (str != NULL) { - *str = NULL; - } - - message = dbus_message_new_method_call (CK_NAME, - ssid, - CK_SESSION_INTERFACE, - "GetX11Display"); - if (message == NULL) { - Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); - return FALSE; - } - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connection, - message, - -1, &error); - if (dbus_error_is_set (&error)) { - Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); - reply = NULL; - } - - dbus_connection_flush (connection); - dbus_message_unref (message); - - if (reply == NULL) { - return FALSE; - } - - dbus_message_iter_init (reply, &iter); - dbus_message_iter_get_basic (&iter, &value); - if (str != NULL) { - *str = strdup (value); - } - dbus_message_unref (reply); - - return TRUE; -} - -static int -session_unlock (DBusConnection *connection, - const char *ssid) -{ - DBusError error; - DBusMessage *message; - DBusMessage *reply; - - Debug ("ConsoleKit: Unlocking session %s", ssid); - message = dbus_message_new_method_call (CK_NAME, - ssid, - CK_SESSION_INTERFACE, - "Unlock"); - if (message == NULL) { - Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); - return FALSE; - } - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connection, - message, - -1, &error); - dbus_message_unref (message); - dbus_message_unref (reply); - dbus_connection_flush (connection); - - if (dbus_error_is_set (&error)) { - Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); - return FALSE; - } - - return TRUE; -} - -/* from libhal */ -static char ** -get_path_array_from_iter (DBusMessageIter *iter, - int *num_elements) -{ - int count; - char **buffer; - - count = 0; - buffer = (char **)malloc (sizeof (char *) * 8); - - if (buffer == NULL) - goto oom; - - buffer[0] = NULL; - while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_OBJECT_PATH) { - const char *value; - char *str; - - if ((count % 8) == 0 && count != 0) { - buffer = realloc (buffer, sizeof (char *) * (count + 8)); - if (buffer == NULL) - goto oom; - } - - dbus_message_iter_get_basic (iter, &value); - str = strdup (value); - if (str == NULL) - goto oom; - - buffer[count] = str; - - dbus_message_iter_next (iter); - count++; - } - - if ((count % 8) == 0) { - buffer = realloc (buffer, sizeof (char *) * (count + 1)); - if (buffer == NULL) - goto oom; - } - - buffer[count] = NULL; - if (num_elements != NULL) - *num_elements = count; - return buffer; - -oom: - LogWarn ("%s %d : error allocating memory\n", __FILE__, __LINE__); - return NULL; - -} - -static char ** -get_sessions_for_user (DBusConnection *connection, - const char *user, - const char *x11_display) -{ - DBusError error; - DBusMessage *message; - DBusMessage *reply; - DBusMessageIter iter; - DBusMessageIter iter_reply; - DBusMessageIter iter_array; - struct passwd *pwent; - char **sessions; - - sessions = NULL; - message = NULL; - reply = NULL; - - pwent = getpwnam (user); - - dbus_error_init (&error); - message = dbus_message_new_method_call (CK_NAME, - CK_MANAGER_PATH, - CK_MANAGER_INTERFACE, - "GetSessionsForUser"); - if (message == NULL) { - Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); - goto out; - } - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, - DBUS_TYPE_UINT32, - &pwent->pw_uid); - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connection, - message, - -1, &error); - dbus_connection_flush (connection); - - if (dbus_error_is_set (&error)) { - Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); - goto out; - } - - if (reply == NULL) { - Debug ("ConsoleKit: No reply for GetSessionsForUser"); - goto out; - } - - dbus_message_iter_init (reply, &iter_reply); - if (dbus_message_iter_get_arg_type (&iter_reply) != DBUS_TYPE_ARRAY) { - Debug ("ConsoleKit: Wrong reply for GetSessionsForUser - expecting an array."); - goto out; - } - - dbus_message_iter_recurse (&iter_reply, &iter_array); - sessions = get_path_array_from_iter (&iter_array, NULL); - - out: - if (message != NULL) { - dbus_message_unref (message); - } - if (reply != NULL) { - dbus_message_unref (reply); - } - - return sessions; -} - -void -unlock_ck_session (const char *user, - const char *x11_display) -{ - DBusError error; - DBusConnection *connection; - char **sessions; - int i; - - Debug ("ConsoleKit: Unlocking session for %s on %s", user, x11_display); - - dbus_error_init (&error); - connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); - if (connection == NULL) { - Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); - dbus_error_free (&error); - return; - } - - sessions = get_sessions_for_user (connection, user, x11_display); - if (sessions == NULL || sessions[0] == NULL) { - Debug ("ConsoleKit: no sessions found"); - return; - } - - for (i = 0; sessions[i] != NULL; i++) { - char *ssid; - char *xdisplay; - - ssid = sessions[i]; - session_get_x11_display (connection, ssid, &xdisplay); - Debug ("ConsoleKit: session %s has DISPLAY %s", ssid, xdisplay); - - if (xdisplay != NULL - && x11_display != NULL - && strcmp (xdisplay, x11_display) == 0) { - int res; - - res = session_unlock (connection, ssid); - if (! res) { - LogError ("ConsoleKit: Unable to unlock %s", ssid); - } - } - - free (xdisplay); - } - - freeStrArr (sessions); -} - -char * -open_ck_session (struct passwd *pwent, - struct display *d) -{ - DBusConnection *connection; - DBusError error; - DBusMessage *message; - DBusMessage *reply; - DBusMessageIter iter; - DBusMessageIter iter_struct; - char *cookie; - - cookie = NULL; - - if (pwent == NULL) { - Debug ("ConsoleKit: NULL user passed as parameter"); - return NULL; - } - - Debug ("ConsoleKit: Opening session for %s", pwent->pw_name); - - dbus_error_init (&error); - connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error); - private_connection = connection; - - if (connection == NULL) { - Debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); - dbus_error_free (&error); - return NULL; - } - - dbus_connection_set_exit_on_disconnect (connection, FALSE); - /* FIXME: What to do about these? - dbus_connection_set_watch_functions( connection, - dbusAddWatch, - dbusRemoveWatch, - dbusToggleWatch, - data, 0 ); - dbus_connection_set_timeout_functions( connection, - dbusAddTimeout, - dbusRemoveTimeout, - dbusToggleTimeout, - data, 0 ); - dbus_connection_set_wakeup_main_function( connection, - dbusWakeupMain, - data, 0 ); */ - - dbus_error_init (&error); - message = dbus_message_new_method_call (CK_NAME, - CK_MANAGER_PATH, - CK_MANAGER_INTERFACE, - "OpenSessionWithParameters"); - if (message == NULL) { - Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); - return NULL; - } - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_open_container (&iter, - DBUS_TYPE_ARRAY, - DBUS_STRUCT_BEGIN_CHAR_AS_STRING - DBUS_TYPE_STRING_AS_STRING - DBUS_TYPE_VARIANT_AS_STRING - DBUS_STRUCT_END_CHAR_AS_STRING, - &iter_struct); - - add_param_int (&iter_struct, "user", pwent->pw_uid); - add_param_string (&iter_struct, "x11-display", d->name); - add_param_boolean (&iter_struct, "is-local", ((d->displayType & d_location) == dLocal)); -#ifdef XDMCP - if ((d->displayType & d_location) != dLocal) { - add_param_string (&iter_struct, "remote-host-name", d->remoteHost); - } -#endif - -#ifdef HAVE_VTS - if (d->serverVT > 0) { - char device[20]; - - /* FIXME: how does xorg construct this */ - sprintf(device, "/dev/tty%d", d->serverVT); - add_param_string (&iter_struct, "x11-display-device", device); - } -#endif - - dbus_message_iter_close_container (&iter, &iter_struct); - - reply = dbus_connection_send_with_reply_and_block (connection, - message, - -1, &error); - if (dbus_error_is_set (&error)) { - Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); - reply = NULL; - } - - dbus_connection_flush (connection); - - dbus_message_unref (message); - dbus_error_free (&error); - - if (reply != NULL) { - const char *value; - - dbus_message_iter_init (reply, &iter); - dbus_message_iter_get_basic (&iter, &value); - cookie = strdup (value); - dbus_message_unref (reply); - } - - return cookie; -} - -void -close_ck_session (const char *cookie) -{ - DBusError error; - DBusMessage *message; - DBusMessage *reply; - DBusMessageIter iter; - - if (cookie == NULL) { - return; - } - - if (private_connection == NULL) { - return; - } - - dbus_error_init (&error); - message = dbus_message_new_method_call (CK_NAME, - CK_MANAGER_PATH, - CK_MANAGER_INTERFACE, - "CloseSession"); - if (message == NULL) { - Debug ("ConsoleKit: Couldn't allocate the D-Bus message"); - return; - } - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, - DBUS_TYPE_STRING, - &cookie); - - reply = dbus_connection_send_with_reply_and_block (private_connection, - message, - -1, &error); - if (dbus_error_is_set (&error)) { - Debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); - reply = NULL; - } - - dbus_connection_flush (private_connection); - - dbus_message_unref (message); - dbus_error_free (&error); - - dbus_connection_close (private_connection); - private_connection = NULL; -} diff --git a/kdm/backend/consolekit.h b/kdm/backend/consolekit.h deleted file mode 100644 index e385e3f91..000000000 --- a/kdm/backend/consolekit.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - - Copyright (C) 2006 William Jon McCann <[email protected]> - Copyright (C) 2007 Kevin Kofler <[email protected]> - - 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. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - */ - - -#ifndef __CONSOLE_KIT_H -#define __CONSOLE_KIT_H - -#include <pwd.h> - -struct display; - -char * open_ck_session (struct passwd *pwent, - struct display *display); -void close_ck_session (const char *cookie); -void unlock_ck_session (const char *user, - const char *x11_display); - -#endif /* __CONSOLE_KIT_H */ diff --git a/kdm/backend/ctrl.c b/kdm/backend/ctrl.c deleted file mode 100644 index 622c9370d..000000000 --- a/kdm/backend/ctrl.c +++ /dev/null @@ -1,1015 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2001-2005 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * display manager - */ - -#include "dm.h" -#include "dm_socket.h" -#include "dm_error.h" - -#include <string.h> -#include <signal.h> -#include <pwd.h> - -static void -acceptSock( CtrlRec *cr ) -{ - struct cmdsock *cs; - int fd; - - if ((fd = accept( cr->fd, 0, 0 )) < 0) { - bust: - LogError( "Error accepting command connection\n" ); - return; - } - if (!(cs = Malloc( sizeof(*cs) ))) { - close( fd ); - goto bust; - } - cs->sock.fd = fd; - cs->sock.buffer = 0; - cs->sock.buflen = 0; - cs->next = cr->css; - cr->css = cs; - fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ); - RegisterCloseOnFork( fd ); - RegisterInput( fd ); -} - -static void -nukeSock( struct cmdsock *cs ) -{ - UnregisterInput( cs->sock.fd ); - CloseNClearCloseOnFork( cs->sock.fd ); - if (cs->sock.buffer) - free( cs->sock.buffer ); - free( cs ); -} - -#ifdef HONORS_SOCKET_PERMS -static CtrlRec ctrl = { 0, 0, -1, 0, 0, { -1, 0, 0 } }; -#else -static CtrlRec ctrl = { 0, 0, 0, -1, 0, 0, { -1, 0, 0 } }; - -static int mkTempDir( char *dir ) -{ - int i, l = strlen( dir ) - 6; - - for (i = 0; i < 100; i++) { - randomStr( dir + l ); - if (!mkdir( dir, 0700 )) - return True; - if (errno != EEXIST) - break; - } - return False; -} -#endif - -void -openCtrl( struct display *d ) -{ - CtrlRec *cr; - const char *dname; - char *sockdir; - struct sockaddr_un sa; - - if (!*fifoDir) - return; - if (d) { - cr = &d->ctrl, dname = d->name; - if (!memcmp( dname, "localhost:", 10 )) - dname += 9; - } else - cr = &ctrl, dname = 0; - if (cr->fifo.fd < 0) { - if (mkdir( fifoDir, 0755 )) { - if (errno != EEXIST) { - LogError( "mkdir %\"s failed; no control FiFos will be available\n", - fifoDir ); - return; - } - } else - chmod( fifoDir, 0755 ); /* override umask */ - StrApp( &cr->fpath, fifoDir, dname ? "/xdmctl-" : "/xdmctl", - dname, (char *)0 ); - if (cr->fpath) { - unlink( cr->fpath ); - if (mkfifo( cr->fpath, 0 ) < 0) - LogError( "Cannot create control FiFo %\"s\n", cr->fpath ); - else { - cr->gid = fifoGroup; - if (!d) - chown( cr->fpath, -1, fifoGroup ); - chmod( cr->fpath, 0620 ); - if ((cr->fifo.fd = open( cr->fpath, O_RDWR | O_NONBLOCK )) >= 0) { - RegisterCloseOnFork( cr->fifo.fd ); - RegisterInput( cr->fifo.fd ); - goto fifok; - } - unlink( cr->fpath ); - LogError( "Cannot open control FiFo %\"s\n", cr->fpath ); - } - free( cr->fpath ); - cr->fpath = 0; - } - } - fifok: - if (cr->fd < 0) { - /* fifoDir is created above already */ - sockdir = 0; - StrApp( &sockdir, fifoDir, dname ? "/dmctl-" : "/dmctl", - dname, (char *)0 ); - if (sockdir) { - StrApp( &cr->path, sockdir, "/socket", (char *)0 ); - if (cr->path) { - if (strlen( cr->path ) >= sizeof(sa.sun_path)) - LogError( "path %\"s too long; no control sockets will be available\n", - cr->path ); -#ifdef HONORS_SOCKET_PERMS - else if (mkdir( sockdir, 0700 ) && errno != EEXIST) - LogError( "mkdir %\"s failed; no control sockets will be available\n", - sockdir ); - else if (unlink( cr->path ) && errno != ENOENT) - LogError( "unlink %\"s failed: %m; control socket will not be available\n", - cr->path ); - else { -#else - else if (unlink( sockdir ) && errno != ENOENT) - LogError( "unlink %\"s failed: %m; control socket will not be available\n", - sockdir ); - else if (!StrApp( &cr->realdir, sockdir, "-XXXXXX", (char *)0)) - ; - else if (!mkTempDir( cr->realdir )) { - LogError( "mkdir %\"s failed: %m; control socket will not be available\n", - cr->realdir ); - free( cr->realdir ); - cr->realdir = 0; - } else if (symlink( cr->realdir, sockdir )) { - LogError( "symlink %\"s => %\"s failed: %m; control socket will not be available\n", - sockdir, cr->realdir ); - rmdir( cr->realdir ); - free( cr->realdir ); - cr->realdir = 0; - } else { - chown( sockdir, 0, d ? 0 : fifoGroup ); - chmod( sockdir, 0750 ); -#endif - if ((cr->fd = socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) - LogError( "Cannot create control socket\n" ); - else { - sa.sun_family = AF_UNIX; - strcpy( sa.sun_path, cr->path ); - if (!bind( cr->fd, (struct sockaddr *)&sa, sizeof(sa) )) { - if (!listen( cr->fd, 5 )) { -#ifdef HONORS_SOCKET_PERMS - chmod( cr->path, 0660 ); - if (!d) - chown( cr->path, -1, fifoGroup ); - chmod( sockdir, 0755 ); -#else - chmod( cr->path, 0666 ); -#endif - RegisterCloseOnFork( cr->fd ); - RegisterInput( cr->fd ); - free( sockdir ); - return; - } - unlink( cr->path ); - LogError( "Cannot listen on control socket %\"s\n", - cr->path ); - } else - LogError( "Cannot bind control socket %\"s\n", - cr->path ); - close( cr->fd ); - cr->fd = -1; - } -#ifdef HONORS_SOCKET_PERMS - rmdir( sockdir ); -#else - unlink( sockdir ); - rmdir( cr->realdir ); - free( cr->realdir ); - cr->realdir = 0; -#endif - } - free( cr->path ); - cr->path = 0; - } - free( sockdir ); - } - } -} - -void -closeCtrl( struct display *d ) -{ - CtrlRec *cr = d ? &d->ctrl : &ctrl; - - if (cr->fd >= 0) { - UnregisterInput( cr->fd ); - CloseNClearCloseOnFork( cr->fd ); - cr->fd = -1; - unlink( cr->path ); - *strrchr( cr->path, '/' ) = 0; -#ifdef HONORS_SOCKET_PERMS - rmdir( cr->path ); -#else - unlink( cr->path ); - rmdir( cr->realdir ); - free( cr->realdir ); - cr->realdir = 0; -#endif - free( cr->path ); - cr->path = 0; - while (cr->css) { - struct cmdsock *cs = cr->css; - cr->css = cs->next; - nukeSock( cs ); - } - } - if (cr->fifo.fd >= 0) { - UnregisterInput( cr->fifo.fd ); - CloseNClearCloseOnFork( cr->fifo.fd ); - cr->fifo.fd = -1; - unlink( cr->fpath ); - free( cr->fpath ); - cr->fpath = 0; - if (cr->fifo.buffer) - free( cr->fifo.buffer ); - cr->fifo.buffer = 0; - cr->fifo.buflen = 0; - } -} - -void -chownCtrl( CtrlRec *cr, int uid ) -{ - if (cr->fpath) - chown( cr->fpath, uid, -1 ); - if (cr->path) -#ifdef HONORS_SOCKET_PERMS - chown( cr->path, uid, -1 ); -#else - chown( cr->realdir, uid, -1 ); -#endif -} - -void -updateCtrl( void ) -{ - unsigned ffl, slc; - - ffl = 0; - if (ctrl.path) - for (ffl = strlen( ctrl.path ), slc = 2; ;) - if (ctrl.path[--ffl] == '/') - if (!--slc) - break; - if (ffl != strlen( fifoDir ) || memcmp( fifoDir, ctrl.path, ffl ) || - ctrl.gid != fifoGroup) - { - closeCtrl( 0 ); - openCtrl( 0 ); - } -} - - -static void -fLog( struct display *d, int fd, const char *sts, const char *msg, ... ) -{ - char *fmsg, *otxt; - const char *what; - int olen; - va_list va; - - va_start( va, msg ); - VASPrintf( &fmsg, msg, va ); - va_end( va ); - if (!fmsg) - return; - if (fd >= 0) { - olen = ASPrintf( &otxt, "%s\t%\\s\n", sts, fmsg ); - if (otxt) { - Writer( fd, otxt, olen ); - free( otxt ); - } - what = "socket"; - } else - what = "FiFo"; - if (d) - Debug( "control %s for %s: %s - %s", what, d->name, sts, fmsg ); - else - Debug( "global control %s: %s - %s", what, sts, fmsg ); - free( fmsg ); -} - - -static char * -unQuote( const char *str ) -{ - char *ret, *adp; - - if (!(ret = Malloc( strlen( str ) + 1 ))) - return 0; - for (adp = ret; *str; str++, adp++) - if (*str == '\\') - switch (*++str) { - case 0: str--; /* fallthrough */ - case '\\': *adp = '\\'; break; - case 'n': *adp = '\n'; break; - case 't': *adp = '\t'; break; - default: *adp++ = '\\'; *adp = *str; break; - } - else - *adp = *str; - *adp = 0; - return ret; -} - -static void -str_cat_l( char **bp, const char *str, int max ) -{ - int dnl = StrNLen( str, max ); - memcpy( *bp, str, dnl ); - *bp += dnl; -} - -static void -str_cat( char **bp, const char *str ) -{ - int dnl = strlen( str ); - memcpy( *bp, str, dnl ); - *bp += dnl; -} - -static void -sd_cat( char **bp, SdRec *sdr ) -{ - if (sdr->how == SHUT_HALT) - str_cat( bp, "halt," ); - else - str_cat( bp, "reboot," ); - if (sdr->start == TO_INF) - str_cat( bp, "0," ); - else - *bp += sprintf( *bp, "%d,", sdr->start ); - if (sdr->timeout == TO_INF) - str_cat( bp, "-1," ); - else - *bp += sprintf( *bp, "%d,", sdr->timeout ); - if (sdr->force == SHUT_ASK) - str_cat( bp, "ask" ); - else if (sdr->force == SHUT_FORCE) - str_cat( bp, "force" ); - else if (sdr->force == SHUT_FORCEMY) - str_cat( bp, "forcemy" ); - else - str_cat( bp, "cancel" ); - *bp += sprintf( *bp, ",%d,%s", sdr->uid, sdr->osname ? sdr->osname : "-" ); -} - -static void -emitXSessC( struct display *di, struct display *d, void *ctx ) -{ - char *dname, *bp; - char cbuf[1024]; - - bp = cbuf; - *bp++ = '\t'; - dname = di->name; - if (!memcmp( dname, "localhost:", 10 )) - dname += 9; - str_cat_l( &bp, dname, sizeof(cbuf)/2 ); - *bp++ = ','; -#ifdef HAVE_VTS - if (di->serverVT) - bp += sprintf( bp, "vt%d", di->serverVT ); -#endif - *bp++ = ','; -#ifdef XDMCP - if (di->status == remoteLogin) { - *bp++ = ','; - str_cat_l( &bp, di->remoteHost, sizeof(cbuf)/3 ); - } else -#endif - { - if (di->userName) - str_cat_l( &bp, di->userName, sizeof(cbuf)/5 ); - *bp++ = ','; - if (di->sessName) - str_cat_l( &bp, di->sessName, sizeof(cbuf)/5 ); - } - *bp++ = ','; - if (di == d) - *bp++ = '*'; - if (di->userSess >= 0 && - (d ? (d->userSess != di->userSess && - (d->allowNuke == SHUT_NONE || - (d->allowNuke == SHUT_ROOT && d->userSess))) : - !fifoAllowNuke)) - *bp++ = '!'; - Writer( (int)ctx, cbuf, bp - cbuf ); -} - -static void -emitTTYSessC( STRUCTUTMP *ut, struct display *d, void *ctx ) -{ - struct passwd *pw; - char *bp; - int vt, l; - char cbuf[sizeof(ut->ut_line) + sizeof(ut->ut_user) + sizeof(ut->ut_host) + 16]; - char user[sizeof(ut->ut_user) + 1]; - -#ifndef BSD_UTMP - if (ut->ut_type != USER_PROCESS) - l = 0; - else -#endif - { - l = StrNLen( ut->ut_user, sizeof(ut->ut_user) ); - memcpy( user, ut->ut_user, l ); - } - user[l] = 0; - bp = cbuf; - *bp++ = '\t'; - str_cat_l( &bp, ut->ut_line, sizeof(ut->ut_line) ); - *bp++ = ','; - if (*ut->ut_host) { - *bp++ = '@'; - str_cat_l( &bp, ut->ut_host, sizeof(ut->ut_host) ); - } -#ifdef HAVE_VTS - else if ((vt = TTYtoVT( ut->ut_line ))) - bp += sprintf( bp, "vt%d", vt ); -#endif - *bp++ = ','; - str_cat( &bp, user ); - *bp++ = ','; - /* blank: session type unknown */ - *bp++ = ','; - /* blank: certainly not querying display */ - *bp++ = 't'; - if (*user && - (d ? ((d->allowNuke == SHUT_NONE || - (d->allowNuke == SHUT_ROOT && d->userSess)) && - (!(pw = getpwnam( user )) || d->userSess != (int)pw->pw_uid)) : - !fifoAllowNuke)) - *bp++ = '!'; - Writer( (int)ctx, cbuf, bp - cbuf ); -} - -static void -processCtrl( const char *string, int len, int fd, struct display *d ) -{ -#define Reply(t) Writer (fd, t, strlen (t)) - - struct display *di; - const char *word; - char **ar, **ap, *args, *bp; - SdRec sdr; - char cbuf[1024]; - - if (!(ar = initStrArr( 0 ))) - return; - for (word = string; ; string++, len--) - if (!len || *string == '\t') { - if (!(ar = addStrArr( ar, word, string - word ))) - return; - if (!len) - break; - word = string + 1; - } - word = fd >= 0 ? "socket" : "FiFo"; - if (d) - Debug( "control %s for %s received %'[s\n", word, d->name, ar ); - else - Debug( "global control %s received %'[s\n", word, ar ); - if (ar[0]) { - if (fd >= 0 && !strcmp( ar[0], "caps" )) { - if (ar[1]) - goto exce; - Reply( "ok\ttdm\tlist\t" ); - if (bootManager != BO_NONE) - Reply( "bootoptions\t" ); - if (d) { - if ((d->displayType & d_location) == dLocal) -#ifdef HAVE_VTS - Reply( "local\tactivate\t" ); -#else - Reply( "local\t" ); -#endif - if (d->allowShutdown != SHUT_NONE) { - if (d->allowShutdown == SHUT_ROOT && d->userSess) - Reply( "shutdown root\t" ); - else - Reply( "shutdown\t" ); - Reply( "shutdown ask\t" ); - if (d->allowNuke != SHUT_NONE) { - if (d->allowNuke == SHUT_ROOT && d->userSess) - Reply( "nuke root\t" ); - else - Reply( "nuke\t" ); - } - } - if ((d->displayType & d_location) == dLocal && - AnyReserveDisplays()) - Writer( fd, cbuf, sprintf( cbuf, "reserve %d\t", - idleReserveDisplays() ) ); - Reply( "lock\tsuicide\n" ); - } else { - if (fifoAllowShutdown) { - Reply( "shutdown\t" ); - if (fifoAllowNuke) - Reply( "nuke\t" ); - } - if (AnyReserveDisplays()) - Writer( fd, cbuf, sprintf( cbuf, "reserve %d\t", - idleReserveDisplays() ) ); -#ifdef HAVE_VTS - Reply( "login\tactivate\n" ); -#else - Reply( "login\n" ); -#endif - } - goto bust; - } else if (fd >= 0 && !strcmp( ar[0], "list" )) { - int flags = lstRemote | lstTTY; - if (ar[1]) { - if (!strcmp( ar[1], "all" )) - flags = lstRemote | lstPassive | lstTTY; - else if (!strcmp( ar[1], "alllocal" )) - flags = lstPassive | lstTTY; - else { - fLog( d, fd, "bad", "invalid list scope %\"s", ar[1] ); - goto bust; - } - if (ar[2]) - goto exce; - } - Reply( "ok" ); - ListSessions( flags, d, (void *)fd, emitXSessC, emitTTYSessC ); - Reply( "\n" ); - goto bust; - } else if (!strcmp( ar[0], "reserve" )) { - int lt = 60; /* XXX make default timeout configurable? */ - if (ar[1]) { - lt = strtol( ar[1], &bp, 10 ); - if (lt < 15 || *bp) { - fLog( d, fd, "bad", "invalid timeout %\"s", ar[1] ); - goto bust; - } - if (ar[2]) - goto exce; - } - if (d && (d->displayType & d_location) != dLocal) { - fLog( d, fd, "perm", "display is not local" ); - goto bust; - } - if (!StartReserveDisplay( lt )) { - fLog( d, fd, "noent", "no reserve display available" ); - goto bust; - } -#ifdef HAVE_VTS - } else if (!strcmp( ar[0], "activate" )) { - int vt; - if (!ar[1]) - goto miss; - if (ar[2]) - goto exce; - if (d && (d->displayType & d_location) != dLocal) { - fLog( d, fd, "perm", "display is not local" ); - goto bust; - } - if (ar[1][0] != 'v' || ar[1][1] != 't' || - (vt = atoi( ar[1] + 2 )) <= 0) - { - if (!(di = FindDisplayByName( ar[1] ))) { - fLog( d, fd, "noent", "display not found" ); - goto bust; - } - if ((di->displayType & d_location) != dLocal) { - fLog( d, fd, "inval", "target display is not local" ); - goto bust; - } - if (!di->serverVT) { - fLog( d, fd, "noent", "target display has no VT assigned" ); - goto bust; - } - vt = di->serverVT; - } - if (!activateVT( vt )) { - fLog( d, fd, "inval", "VT switch failed" ); - goto bust; - } -#endif - } else if (!strcmp( ar[0], "shutdown" )) { - ap = ar; - if (!*++ap) - goto miss; - sdr.force = SHUT_CANCEL; - sdr.osname = 0; - if (!strcmp( *ap, "status" )) { - if (fd < 0) - goto bust; - if (*++ap) - goto exce; - bp = cbuf; - *bp++ = 'o'; - *bp++ = 'k'; - if (sdRec.how) { - str_cat( &bp, "\tglobal," ); - sd_cat( &bp, &sdRec ); - } - if (d && d->hstent->sdRec.how) { - str_cat( &bp, "\tlocal," ); - sd_cat( &bp, &d->hstent->sdRec ); - } - *bp++ = '\n'; - Writer( fd, cbuf, bp - cbuf ); - goto bust; - } else if (!strcmp( *ap, "cancel" )) { - sdr.how = 0; - sdr.start = 0; - if (ap[1]) { - if (!d) - goto exce; - if (!strcmp( *++ap, "global" )) - sdr.start = TO_INF; - else if (strcmp( *ap, "local" )) { - fLog( d, fd, "bad", "invalid cancel scope %\"s", *ap ); - goto bust; - } - } - } else { - if (!strcmp( *ap, "reboot" )) - sdr.how = SHUT_REBOOT; - else if (!strcmp( *ap, "halt" )) - sdr.how = SHUT_HALT; - else { - fLog( d, fd, "bad", "invalid type %\"s", *ap ); - goto bust; - } - sdr.uid = -1; - if (!*++ap) - goto miss; - if (**ap == '=') { - switch (setBootOption( *ap + 1, &sdr )) { - case BO_NOMAN: - fLog( d, fd, "notsup", "boot options unavailable" ); - goto bust; - case BO_NOENT: - fLog( d, fd, "noent", "no such boot option" ); - goto bust; - case BO_IO: - fLog( d, fd, "io", "io error" ); - goto bust; - } - if (!*++ap) - goto miss; - } - sdr.start = strtol( *ap, &bp, 10 ); - if (bp != *ap && !*bp) { - if (**ap == '+') - sdr.start += now; - if (!*++ap) - goto miss; - sdr.timeout = strtol( *ap, &bp, 10 ); - if (bp == *ap || *bp) { - fLog( d, fd, "bad", "invalid timeout %\"s", ar[3] ); - goto bust; - } - if (**ap == '+') - sdr.timeout += sdr.start ? sdr.start : now; - if (sdr.timeout < 0) - sdr.timeout = TO_INF; - else { - if (!*++ap) - goto miss; - if (!strcmp( *ap, "force" )) - sdr.force = SHUT_FORCE; - else if (d && !strcmp( *ap, "forcemy" )) - sdr.force = SHUT_FORCEMY; - else if (strcmp( *ap, "cancel" )) { - fLog( d, fd, "bad", "invalid timeout action %\"s", - *ap ); - goto bust; - } - } - } else { - sdr.timeout = 0; - if (d && !strcmp( *ap, "ask" )) - sdr.force = SHUT_ASK; - else if (!strcmp( *ap, "forcenow" )) - sdr.force = SHUT_FORCE; - else if (!strcmp( *ap, "schedule" )) - sdr.timeout = TO_INF; - else if (strcmp( *ap, "trynow" )) { - fLog( d, fd, "bad", "invalid mode %\"s", *ap ); - goto bust; - } - } - } - if (*++ap) - goto exce; - if (d) { - sdr.uid = d->userSess >= 0 ? d->userSess : 0; - if (d->allowShutdown == SHUT_NONE || - (d->allowShutdown == SHUT_ROOT && sdr.uid && - sdr.force != SHUT_ASK)) - { - fLog( d, fd, "perm", "shutdown forbidden" ); - goto bust; - } - if (!sdr.how && !sdr.start) { - if (d->hstent->sdRec.osname) - free( d->hstent->sdRec.osname ); - d->hstent->sdRec = sdr; - } else { - if (sdRec.how && sdRec.force == SHUT_FORCE && - ((d->allowNuke == SHUT_NONE && sdRec.uid != sdr.uid) || - (d->allowNuke == SHUT_ROOT && sdr.uid))) - { - fLog( d, fd, "perm", "overriding forced shutdown forbidden" ); - goto bust; - } - if (sdr.force == SHUT_FORCE && - (d->allowNuke == SHUT_NONE || - (d->allowNuke == SHUT_ROOT && sdr.uid))) - { - fLog( d, fd, "perm", "forced shutdown forbidden" ); - goto bust; - } - if (!sdr.start) { - if (d->hstent->sdRec.osname) - free( d->hstent->sdRec.osname ); - d->hstent->sdRec = sdr; - } else { - if (!sdr.how) - cancelShutdown(); - else { - if (sdRec.osname) - free( sdRec.osname ); - sdRec = sdr; - } - } - } - } else { - if (!fifoAllowShutdown) { - fLog( d, fd, "perm", "shutdown forbidden" ); - goto bust; - } - if (sdRec.how && sdRec.force == SHUT_FORCE && - sdRec.uid != -1 && !fifoAllowNuke) - { - fLog( d, fd, "perm", "overriding forced shutdown forbidden" ); - goto bust; - } - if (!sdr.how) - cancelShutdown(); - else { - if (sdr.force != SHUT_CANCEL) { - if (!fifoAllowNuke) { - fLog( d, fd, "perm", "forced shutdown forbidden" ); - goto bust; - } - } else { - if (!sdr.start && !sdr.timeout && AnyActiveDisplays()) { - fLog( d, fd, "busy", "user sessions running" ); - goto bust; - } - } - sdr.uid = -1; - if (sdRec.osname) - free( sdRec.osname ); - sdRec = sdr; - } - } - } else if (fd >= 0 && !strcmp( ar[0], "listbootoptions" )) { - char **opts; - int def, cur, i, j; - - if (ar[1]) - goto exce; - switch (getBootOptions( &opts, &def, &cur )) { - case BO_NOMAN: - fLog( d, fd, "notsup", "boot options unavailable" ); - goto bust; - case BO_IO: - fLog( d, fd, "io", "io error" ); - goto bust; - } - Reply( "ok\t" ); - for (i = 0; opts[i]; i++) { - bp = cbuf; - if (i) - *bp++ = ' '; - for (j = 0; opts[i][j]; j++) - if (opts[i][j] == ' ') { - *bp++ = '\\'; - *bp++ = 's'; - } else - *bp++ = opts[i][j]; - Writer( fd, cbuf, bp - cbuf ); - } - freeStrArr( opts ); - Writer( fd, cbuf, sprintf( cbuf, "\t%d\t%d\n", def, cur ) ); - goto bust; - } else if (d) { - if (!strcmp( ar[0], "lock" )) { - if (ar[1]) - goto exce; - d->hstent->lock = 1; - } else if (!strcmp( ar[0], "unlock" )) { - if (ar[1]) - goto exce; - d->hstent->lock = 0; - } else if (!strcmp( ar[0], "suicide" )) { - if (ar[1]) - goto exce; - if (d->status == running && d->pid != -1) { - TerminateProcess( d->pid, SIGTERM ); - d->status = raiser; - } - } else { - fLog( d, fd, "nosys", "unknown command" ); - goto bust; - } - } else { - if (!strcmp( ar[0], "login" )) { - int nuke; - if (arrLen( ar ) < 5) { - miss: - fLog( d, fd, "bad", "missing argument(s)" ); - goto bust; - } - if (!(di = FindDisplayByName( ar[1] ))) { - fLog( d, fd, "noent", "display %s not found", ar[1] ); - goto bust; - } - if (ar[5]) { - if (!(args = unQuote( ar[5] ))) { - fLog( d, fd, "nomem", "out of memory" ); - goto bust; - } - if (ar[6]) { - free( args ); - exce: - fLog( d, fd, "bad", "excess argument(s)" ); - goto bust; - } - setNLogin( di, ar[3], ar[4], args, 2 ); - free( args ); - } else - setNLogin( di, ar[3], ar[4], 0, 2 ); - nuke = !strcmp( ar[2], "now" ); - switch (di->status) { - case running: - if (di->pid != -1 && (di->userSess < 0 || nuke)) { - TerminateProcess( di->pid, SIGTERM ); - di->status = raiser; - } - break; - case remoteLogin: - if (di->serverPid != -1 && nuke) - TerminateProcess( di->serverPid, di->termSignal ); - break; - case reserve: - di->status = notRunning; - break; - case textMode: -#ifndef HAVE_VTS - SwitchToX( di ); -#endif - break; - default: - break; - } - } else { - fLog( d, fd, "nosys", "unknown command" ); - goto bust; - } - } - if (fd >= 0) - Reply( "ok\n" ); - } - bust: - freeStrArr( ar ); -} - -static int -handleChan( struct display *d, struct bsock *cs, int fd, FD_TYPE *reads ) -{ - char *bufp, *nbuf, *obuf, *eol; - int len, bl, llen; - char buf[1024]; - - bl = cs->buflen; - obuf = cs->buffer; - if (bl <= 0 && FD_ISSET( cs->fd, reads )) { - FD_CLR( cs->fd, reads ); - bl = -bl; - memcpy( buf, obuf, bl ); - if ((len = Reader( cs->fd, buf + bl, sizeof(buf) - bl )) <= 0) - return -1; - bl += len; - bufp = buf; - } else { - len = 0; - bufp = obuf; - } - if (bl > 0) { - if ((eol = memchr( bufp, '\n', bl ))) { - llen = eol - bufp + 1; - bl -= llen; - if (bl) { - if (!(nbuf = Malloc( bl ))) - return -1; - memcpy( nbuf, bufp + llen, bl ); - } else - nbuf = 0; - cs->buffer = nbuf; - cs->buflen = bl; - processCtrl( bufp, llen - 1, fd, d ); - if (obuf) - free( obuf ); - return 1; - } else if (!len) { - if (fd >= 0) - cs->buflen = -bl; - else - fLog( d, -1, "bad", "unterminated command" ); - } - } - return 0; -} - -int -handleCtrl( FD_TYPE *reads, struct display *d ) -{ - CtrlRec *cr = d ? &d->ctrl : &ctrl; - struct cmdsock *cs, **csp; - - if (cr->fifo.fd >= 0) { - switch (handleChan( d, &cr->fifo, -1, reads )) { - case -1: - if (cr->fifo.buffer) - free( cr->fifo.buffer ); - cr->fifo.buflen = 0; - break; - case 1: - return 1; - default: - break; - } - } - if (cr->fd >= 0 && FD_ISSET( cr->fd, reads )) - acceptSock( cr ); - else { - for (csp = &cr->css; (cs = *csp); ) { - switch (handleChan( d, &cs->sock, cs->sock.fd, reads )) { - case -1: - *csp = cs->next; - nukeSock( cs ); - continue; - case 1: - return 1; - default: - break; - } - csp = &cs->next; - } - } - return 0; -} diff --git a/kdm/backend/daemon.c b/kdm/backend/daemon.c deleted file mode 100644 index 79d9e47ff..000000000 --- a/kdm/backend/daemon.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000,2001,2003 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - */ - -#include "dm.h" -#include "dm_error.h" - -void -BecomeDaemon( void ) -{ - int pfd[2]; - - /* - * fork so that the process goes into the background automatically. Also - * has a nice side effect of having the child process get inherited by - * init (pid 1). - * Create a pipe and block on it, so the parent knows when the child is - * done with detaching. This eliminates the possibility that the child - * might get killed when the init script that's running xdm exits. - */ - - if (pipe( pfd )) - pfd[0] = pfd[1] = -1; /* so what ...? */ - switch (fork ()) { - case 0: - /* child */ - break; - case -1: - /* error */ - LogError( "Daemon fork failed: %m\n" ); - break; - - default: - /* parent */ - close( pfd[1] ); - read( pfd[0], &pfd[1] /* dummy */, 1 ); - exit( 0 ); - } - - /* don't use daemon() - it doesn't buy us anything but an additional fork */ - - setsid(); - - close( pfd[0] ); - close( pfd[1] ); /* tell parent that we're done with detaching */ - - chdir( "/" ); -} diff --git a/kdm/backend/dm.c b/kdm/backend/dm.c deleted file mode 100644 index d372dd472..000000000 --- a/kdm/backend/dm.c +++ /dev/null @@ -1,1669 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2005 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * display manager - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <signal.h> -#include <sys/stat.h> - -#ifdef HAVE_VTS -# include <sys/ioctl.h> -# include <sys/vt.h> -#endif - -static void SigHandler( int n ); -static int ScanConfigs( int force ); -static void StartDisplays( void ); -#define XS_KEEP 0 -#define XS_RESTART 1 -#define XS_RETRY 2 -static void ExitDisplay( struct display *d, int endState, int serverCmd, int goodExit ); -static void rStopDisplay( struct display *d, int endState ); -static void MainLoop( void ); - -static int signalFds[2]; - -#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) -static char *Title; -static int TitleLen; -#endif - -static int StorePid( void ); - -static int Stopping; -SdRec sdRec = { 0, 0, 0, TO_INF, TO_INF, 0, 0, 0 }; - -time_t now; - -char *prog, *progpath; - -int -main( int argc, char **argv ) -{ - int oldpid, oldumask, fd, noDaemonMode; - char *pt, *errorLogFile, **opts; - - /* make sure at least world write access is disabled */ - if (((oldumask = umask( 022 )) & 002) == 002) - (void)umask( oldumask ); - - /* give /dev/null as stdin */ - if ((fd = open( "/dev/null", O_RDONLY )) > 0) { - dup2( fd, 0 ); - close( fd ); - } - if (fcntl( 1, F_GETFD ) < 0) - dup2( 0, 1 ); - if (fcntl( 2, F_GETFD ) < 0) - dup2( 0, 2 ); - - if (argv[0][0] == '/') { - if (!StrDup( &progpath, argv[0] )) - Panic( "Out of memory" ); - } else -#ifdef __linux__ - { - /* note that this will resolve symlinks ... */ - int len; - char fullpath[PATH_MAX]; - if ((len = readlink( "/proc/self/exe", fullpath, sizeof(fullpath) )) < 0) - Panic( "Invoke with full path specification or mount /proc" ); - if (!StrNDup( &progpath, fullpath, len )) - Panic( "Out of memory" ); - } -#else -# if 0 - Panic( "Must be invoked with full path specification" ); -# else - { - char directory[PATH_MAX+1]; - if (!getcwd( directory, sizeof(directory) )) - Panic( "Can't find myself (getcwd failed)" ); - if (strchr( argv[0], '/' )) - StrApp( &progpath, directory, "/", argv[0], (char *)0 ); - else { - int len; - char *path, *name, *thenam, nambuf[PATH_MAX+1]; - char *pathe; - - if (!(path = getenv( "PATH" ))) - Panic( "Can't find myself (no PATH)" ); - len = strlen( argv[0] ); - name = nambuf + PATH_MAX - len; - memcpy( name, argv[0], len + 1 ); - *--name = '/'; - do { - if (!(pathe = strchr( path, ':' ))) - pathe = path + strlen( path ); - len = pathe - path; - if (!len || (len == 1 && *path == '.')) { - len = strlen( directory ); - path = directory; - } - thenam = name - len; - if (thenam >= nambuf) { - memcpy( thenam, path, len ); - if (!access( thenam, X_OK )) - goto found; - } - path = pathe; - } while (*path++ != '\0'); - Panic( "Can't find myself (not in PATH)" ); - found: - if (!StrDup( &progpath, thenam )) - Panic( "Out of memory" ); - } - } -# endif -#endif - prog = strrchr( progpath, '/' ) + 1; - -#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) - Title = argv[0]; - TitleLen = (argv[argc - 1] + strlen( argv[argc - 1] )) - Title; -#endif - - /* - * Parse command line options - */ - noDaemonMode = getppid(); - errorLogFile = 0; - if (!(opts = Malloc( 2 * sizeof(char *) ))) - return 1; - opts[0] = (char *)""; - opts[1] = 0; - while (*++argv) { - if (**argv != '-') - break; - pt = *argv + 1; - if (*pt == '-') - pt++; - if (!strcmp( pt, "help" ) || !strcmp( pt, "h" )) { - printf( "Usage: %s [options] [tty]\n" -" -daemon\t - Daemonize even when started by init\n" -" -nodaemon\t - Don't daemonize even when started from command line\n" -" -config <file> - Use alternative master configuration file\n" -" -xrm <res>\t - Override frontend-specific resource\n" -" -error <file>\t - Use alternative log file\n" -" -debug <num>\t - Debug option bitfield:\n" -"\t\t\t0x1 - core log\n" -"\t\t\t0x2 - config reader log\n" -"\t\t\t0x4 - greeter log\n" -"\t\t\t0x8 - IPC log\n" -"\t\t\t0x10 - session sub-daemon post-fork delay\n" -"\t\t\t0x20 - config reader post-start delay\n" -"\t\t\t0x40 - greeter post-start delay\n" -"\t\t\t0x80 - don't use syslog\n" -"\t\t\t0x100 - core Xauth log\n" -"\t\t\t0x400 - valgrind config reader and greeter\n" -"\t\t\t0x800 - strace config reader and greeter\n" - , prog ); - exit( 0 ); - } else if (!strcmp( pt, "daemon" )) - noDaemonMode = 0; - else if (!strcmp( pt, "nodaemon" )) - noDaemonMode = 1; - else if (argv[1] && !strcmp( pt, "config" )) - StrDup( opts, *++argv ); - else if (argv[1] && !strcmp( pt, "xrm" )) - opts = addStrArr( opts, *++argv, -1 ); - else if (argv[1] && !strcmp( pt, "debug" )) - sscanf( *++argv, "%i", &debugLevel ); - else if (argv[1] && (!strcmp( pt, "error" ) || !strcmp( pt, "logfile" ))) - errorLogFile = *++argv; - else { - fprintf( stderr, "\"%s\" is an unknown option or is missing a parameter\n", *argv ); - exit( 1 ); - } - } - - /* - * Only allow root to run in non-debug mode to avoid problems - */ - if (!debugLevel && getuid()) { - fprintf( stderr, "Only root wants to run %s\n", prog ); - exit( 1 ); - } - - InitErrorLog( errorLogFile ); - - if (noDaemonMode != 1) - BecomeDaemon(); - - /* - * Step 1 - load configuration parameters - */ - if (!InitResources( opts ) || ScanConfigs( FALSE ) < 0) - LogPanic( "Config reader failed. Aborting ...\n" ); - - /* SUPPRESS 560 */ - if ((oldpid = StorePid())) { - if (oldpid == -1) - LogError( "Can't create/lock pid file %s\n", pidFile ); - else - LogError( "Can't lock pid file %s, another xdm is running (pid %d)\n", - pidFile, oldpid ); - exit( 1 ); - } - -#ifdef NEED_ENTROPY - AddOtherEntropy(); -#endif - - /* - * We used to clean up old authorization files here. As authDir is - * supposed to be /var/run/xauth or /tmp, we needn't to care for it. - */ - -#ifdef XDMCP - init_session_id(); -#else - Debug( "not compiled for XDMCP\n" ); -#endif - if (pipe( signalFds )) - LogPanic( "Unable to create signal notification pipe.\n" ); - RegisterInput( signalFds[0] ); - RegisterCloseOnFork( signalFds[0] ); - RegisterCloseOnFork( signalFds[1] ); - (void)Signal( SIGTERM, SigHandler ); - (void)Signal( SIGINT, SigHandler ); - (void)Signal( SIGHUP, SigHandler ); - (void)Signal( SIGCHLD, SigHandler ); - (void)Signal( SIGUSR1, SigHandler ); - - /* - * Step 2 - run a sub-daemon for each entry - */ -#ifdef XDMCP - UpdateListenSockets(); -#endif - openCtrl( 0 ); - MainLoop(); - closeCtrl( 0 ); - if (sdRec.how) { - commitBootOption(); - if (Fork() <= 0) { - char *cmd = sdRec.how == SHUT_HALT ? cmdHalt : cmdReboot; - execute( parseArgs( (char **)0, cmd ), (char **)0 ); - LogError( "Failed to execute shutdown command %\"s\n", cmd ); - exit( 1 ); - } else { - sigset_t mask; - sigemptyset( &mask ); - sigaddset( &mask, SIGCHLD ); - sigaddset( &mask, SIGHUP ); - sigsuspend( &mask ); - } - } - Debug( "nothing left to do, exiting\n" ); - return 0; -} - - -#ifdef HAVE_VTS -int -TTYtoVT( const char *tty ) -{ - return memcmp( tty, "tty", 3 ) ? 0 : atoi( tty + 3 ); -} - -int -activateVT( int vt ) -{ - int ret = 0; - int con = open( "/dev/console", O_RDONLY ); - if (con >= 0) { - if (!ioctl( con, VT_ACTIVATE, vt )) - ret = 1; - close( con ); - } - return ret; -} - - -static void -WakeDisplay( struct display *d ) -{ - if (d->status == textMode) - d->status = (d->displayType & d_lifetime) == dReserve ? reserve : notRunning; -} -#endif - -enum utState { UtDead, UtWait, UtActive }; - -struct utmps { - struct utmps *next; -#ifndef HAVE_VTS - struct display *d; -#endif - time_t time; - enum utState state; - int hadSess; -}; - -#define TIME_LOG 40 -#define TIME_RELOG 10 - -static struct utmps *utmpList; -static time_t utmpTimeout = TO_INF; - -static void -bombUtmp( void ) -{ - struct utmps *utp; - - while ((utp = utmpList)) { -#ifdef HAVE_VTS - ForEachDisplay( WakeDisplay ); -#else - utp->d->status = notRunning; -#endif - utmpList = utp->next; - free( utp ); - } -} - -static void -CheckUtmp( void ) -{ - static time_t modtim; - time_t nck; - time_t ends; - struct utmps *utp, **utpp; - struct stat st; -#ifdef BSD_UTMP - int fd; - struct utmp ut[1]; -#else - STRUCTUTMP *ut; -#endif - - if (!utmpList) - return; - if (stat( UTMP_FILE, &st )) { - LogError( UTMP_FILE " not found - cannot use console mode\n" ); - bombUtmp(); - return; - } - if (modtim != st.st_mtime) { - Debug( "rescanning " UTMP_FILE "\n" ); - for (utp = utmpList; utp; utp = utp->next) - utp->state = UtDead; -#ifdef BSD_UTMP - if ((fd = open( UTMP_FILE, O_RDONLY )) < 0) { - LogError( "Cannot open " UTMP_FILE " - cannot use console mode\n" ); - bombUtmp(); - return; - } - while (Reader( fd, ut, sizeof(ut[0]) ) == sizeof(ut[0])) -#else - SETUTENT(); - while ((ut = GETUTENT())) -#endif - { - for (utp = utmpList; utp; utp = utp->next) { -#ifdef HAVE_VTS - char **line; - for (line = consoleTTYs; *line; line++) - if (!strncmp( *line, ut->ut_line, sizeof(ut->ut_line) )) - goto hitlin; - continue; - hitlin: -#else - if (strncmp( utp->d->console, ut->ut_line, sizeof(ut->ut_line) )) - continue; -#endif -#ifdef BSD_UTMP - if (!*ut->ut_user) { -#else - if (ut->ut_type != USER_PROCESS) { -#endif -#ifdef HAVE_VTS - if (utp->state == UtActive) - break; -#endif - utp->state = UtWait; - } else { - utp->hadSess = 1; - utp->state = UtActive; - } - if (utp->time < ut->ut_time) /* theoretically superfluous */ - utp->time = ut->ut_time; - break; - } - } -#ifdef BSD_UTMP - close( fd ); -#else - ENDUTENT(); -#endif - modtim = st.st_mtime; - } - for (utpp = &utmpList; (utp = *utpp); ) { - if (utp->state != UtActive) { - if (utp->state == UtDead) /* shouldn't happen ... */ - utp->time = 0; - ends = utp->time + (utp->hadSess ? TIME_RELOG : TIME_LOG); - if (ends <= now) { -#ifdef HAVE_VTS - ForEachDisplay( WakeDisplay ); - Debug( "console login timed out\n" ); -#else - utp->d->status = notRunning; - Debug( "console login for %s at %s timed out\n", - utp->d->name, utp->d->console ); -#endif - *utpp = utp->next; - free( utp ); - continue; - } else - nck = ends; - } else - nck = TIME_RELOG + now; - if (nck < utmpTimeout) - utmpTimeout = nck; - utpp = &(*utpp)->next; - } -} - -static void -#ifdef HAVE_VTS -SwitchToTty( void ) -#else -SwitchToTty( struct display *d ) -#endif -{ - struct utmps *utp; -#ifdef HAVE_VTS - int vt; -#endif - - if (!(utp = Malloc( sizeof(*utp) ))) { -#ifdef HAVE_VTS - ForEachDisplay( WakeDisplay ); -#else - d->status = notRunning; -#endif - return; - } -#ifndef HAVE_VTS - d->status = textMode; - utp->d = d; -#endif - utp->time = now; - utp->hadSess = 0; - utp->next = utmpList; - utmpList = utp; - CheckUtmp(); - -#ifdef HAVE_VTS - if ((vt = TTYtoVT( *consoleTTYs ))) - activateVT( vt ); -#endif - - /* XXX output something useful here */ -} - -#ifdef HAVE_VTS -static void -StopToTTY( struct display *d ) -{ - if ((d->displayType & d_location) == dLocal) - switch (d->status) { - default: - rStopDisplay( d, DS_TEXTMODE | 0x100 ); - case reserve: - case textMode: - break; - } -} - -static void -CheckTTYMode( void ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (d->status == zombie) - return; - - SwitchToTty(); -} - -#else - -void -SwitchToX( struct display *d ) -{ - struct utmps *utp, **utpp; - - for (utpp = &utmpList; (utp = *utpp); utpp = &(*utpp)->next) - if (utp->d == d) { - *utpp = utp->next; - free( utp ); - d->status = notRunning; - return; - } -} -#endif - -#ifdef XDMCP -static void -StartRemoteLogin( struct display *d ) -{ - char **argv; - int pid; - - Debug( "StartRemoteLogin for %s\n", d->name ); - /* HACK: omitting LoadDisplayResources( d ) here! */ - switch (pid = Fork()) { - case 0: - argv = PrepServerArgv( d, d->serverArgsRemote ); - if (!(argv = addStrArr( argv, "-once", 5 )) || - !(argv = addStrArr( argv, "-query", 6 )) || - !(argv = addStrArr( argv, d->remoteHost, -1 ))) - exit( 1 ); - Debug( "exec %\"[s\n", argv ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - - /* Let's try again with some standard paths */ - argv[0] = (char *)realloc(argv[0], strlen("/usr/X11R6/bin/X") + 1); - if (argv[0] != NULL) { - argv[0] = "/usr/X11R6/bin/X"; - Debug( "exec %\"[s\n", argv ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - - argv[0] = "/usr/bin/X"; /* Shorter than the previous file name */ - Debug( "exec %\"[s\n", argv ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - } - - exit( 1 ); - case -1: - LogError( "Forking X server for remote login failed: %m" ); - d->status = notRunning; - return; - default: - break; - } - Debug( "X server forked, pid %d\n", pid ); - d->serverPid = pid; - - d->status = remoteLogin; -} -#endif - - -static void -StopInactiveDisplay( struct display *d ) -{ - if (d->status != remoteLogin && d->userSess < 0) - StopDisplay( d ); -} - -static void -stoppen( int force ) -{ -#ifdef XDMCP - request_port = 0; - UpdateListenSockets(); -#endif - if (force) - ForEachDisplay( StopDisplay ); - else - ForEachDisplay( StopInactiveDisplay ); - Stopping = 1; -} - - -void -setNLogin( struct display *d, - const char *nuser, const char *npass, char *nargs, int rl ) -{ - struct disphist *he = d->hstent; - he->rLogin = - (ReStr( &he->nuser, nuser ) && - ReStr( &he->npass, npass ) && - ReStr( &he->nargs, nargs )) ? rl : 0; - Debug( "set next login for %s, level %d\n", nuser, rl ); -} - -static void -processDPipe( struct display *d ) -{ - char *user, *pass, *args; - int cmd; - GTalk dpytalk; -#ifdef XDMCP - int ct, len; - ARRAY8 ca, ha; -#endif - - dpytalk.pipe = &d->pipe; - if (Setjmp( dpytalk.errjmp )) { - StopDisplay( d ); - return; - } - GSet( &dpytalk ); - if (!GRecvCmd( &cmd )) { - /* process already exited */ - UnregisterInput( d->pipe.rfd ); - return; - } - switch (cmd) { - case D_User: - d->userSess = GRecvInt(); - d->userName = GRecvStr(); - d->sessName = GRecvStr(); - break; - case D_ReLogin: - user = GRecvStr(); - pass = GRecvStr(); - args = GRecvStr(); - setNLogin( d, user, pass, args, 1 ); - free( args ); - free( pass ); - free( user ); - break; -#ifdef XDMCP - case D_ChooseHost: - ca.data = (unsigned char *)GRecvArr( &len ); - ca.length = (CARD16)len; - ct = GRecvInt(); - ha.data = (unsigned char *)GRecvArr( &len ); - ha.length = (CARD16)len; - RegisterIndirectChoice( &ca, ct, &ha ); - XdmcpDisposeARRAY8( &ha ); - XdmcpDisposeARRAY8( &ca ); - break; - case D_RemoteHost: - if (d->remoteHost) - free( d->remoteHost ); - d->remoteHost = GRecvStr(); - break; -#endif - case D_XConnOk: - startingServer = 0; - break; - default: - LogError( "Internal error: unknown D_* command %d\n", cmd ); - StopDisplay( d ); - break; - } -} - -static void -emitXSessG( struct display *di, struct display *d, void *ctx ATTR_UNUSED ) -{ - GSendStr( di->name ); - GSendStr( "" ); -#ifdef HAVE_VTS - GSendInt( di->serverVT ); -#endif -#ifdef XDMCP - if (di->status == remoteLogin) { - GSendStr( "" ); - GSendStr( di->remoteHost ); - } else -#endif - { - GSendStr( di->userName ); - GSendStr( di->sessName ); - } - GSendInt( di == d ? isSelf : 0 ); -} - -static void -emitTTYSessG( STRUCTUTMP *ut, struct display *d ATTR_UNUSED, void *ctx ATTR_UNUSED ) -{ - GSendStrN( ut->ut_line, sizeof(ut->ut_line) ); - GSendStrN( ut->ut_host, sizeof(ut->ut_host) ); -#ifdef HAVE_VTS - GSendInt( TTYtoVT( ut->ut_line ) ); -#endif -#ifdef BSD_UTMP - GSendStrN( *ut->ut_user ? ut->ut_user : 0, sizeof(ut->ut_user) ); -#else - GSendStrN( ut->ut_type == USER_PROCESS ? ut->ut_user : 0, sizeof(ut->ut_user) ); -#endif - GSendStr( 0 ); /* session type unknown */ - GSendInt( isTTY ); -} - -static void -processGPipe( struct display *d ) -{ - char **opts, *option; - int cmd, ret, dflt, curr; - GTalk dpytalk; - - dpytalk.pipe = &d->gpipe; - if (Setjmp( dpytalk.errjmp )) { - StopDisplay( d ); - return; - } - GSet( &dpytalk ); - if (!GRecvCmd( &cmd )) { - /* process already exited */ - UnregisterInput( d->gpipe.rfd ); - return; - } - switch (cmd) { - case G_ListBootOpts: - ret = getBootOptions( &opts, &dflt, &curr ); - GSendInt( ret ); - if (ret == BO_OK) { - GSendArgv( opts ); - freeStrArr( opts ); - GSendInt( dflt ); - GSendInt( curr ); - } - break; - case G_Shutdown: - sdRec.how = GRecvInt(); - sdRec.start = GRecvInt(); - sdRec.timeout = GRecvInt(); - sdRec.force = GRecvInt(); - sdRec.uid = GRecvInt(); - option = GRecvStr(); - setBootOption( option, &sdRec ); - if (option) - free( option ); - break; - case G_QueryShutdown: - GSendInt( sdRec.how ); - GSendInt( sdRec.start ); - GSendInt( sdRec.timeout ); - GSendInt( sdRec.force ); - GSendInt( sdRec.uid ); - GSendStr( sdRec.osname ); - break; - case G_List: - ListSessions( GRecvInt(), d, 0, emitXSessG, emitTTYSessG ); - GSendInt( 0 ); - break; -#ifdef HAVE_VTS - case G_Activate: - activateVT( GRecvInt() ); - break; -#endif - case G_Console: -#ifdef HAVE_VTS - if (*consoleTTYs) { /* sanity check against greeter */ - ForEachDisplay( StopToTTY ); - CheckTTYMode(); - } -#else - if (*d->console) /* sanity check against greeter */ - rStopDisplay( d, DS_TEXTMODE ); -#endif - break; - default: - LogError( "Internal error: unknown G_* command %d\n", cmd ); - StopDisplay( d ); - break; - } -} - - -static int -ScanConfigs( int force ) -{ - int ret; - - if ((ret = LoadDMResources( force )) <= 0) - return ret; - ScanServers(); -#ifdef XDMCP - ScanAccessDatabase( force ); -#endif - return 1; -} - -static void -MarkDisplay( struct display *d ) -{ - d->stillThere = 0; -} - -static void -RescanConfigs( int force ) -{ - if (ScanConfigs( force ) > 0) { -#ifdef XDMCP - UpdateListenSockets(); -#endif - updateCtrl(); - } -} - -void -cancelShutdown( void ) -{ - sdRec.how = 0; - if (sdRec.osname) { - free( sdRec.osname ); - sdRec.osname = 0; - } - Stopping = 0; - RescanConfigs( TRUE ); -} - - -static void -ReapChildren( void ) -{ - int pid; - struct display *d; - waitType status; - - while ((pid = waitpid( -1, &status, WNOHANG )) > 0) - { - Debug( "manager wait returns pid %d sig %d core %d code %d\n", - pid, waitSig( status ), waitCore( status ), waitCode( status ) ); - /* SUPPRESS 560 */ - if ((d = FindDisplayByPid( pid ))) { - d->pid = -1; - UnregisterInput( d->pipe.rfd ); - GClosen (&d->pipe); - UnregisterInput( d->gpipe.rfd ); - GClosen (&d->gpipe); - closeCtrl( d ); - switch (waitVal( status )) { -#ifdef XDMCP - case EX_REMOTE: - Debug( "display exited with EX_REMOTE\n" ); - ExitDisplay( d, DS_REMOTE, 0, 0 ); - break; -#endif - case EX_NORMAL: - /* (any type of) session ended */ - Debug( "display exited with EX_NORMAL\n" ); - if ((d->displayType & d_lifetime) == dReserve) - ExitDisplay( d, DS_RESERVE, 0, 0 ); - else - ExitDisplay( d, DS_RESTART, XS_KEEP, TRUE ); - break; -#if 0 - case EX_REMANAGE_DPY: - /* user session ended */ - Debug( "display exited with EX_REMANAGE_DPY\n" ); - ExitDisplay( d, DS_RESTART, XS_KEEP, TRUE ); - break; -#endif - case EX_OPENFAILED_DPY: - /* WaitForServer() failed */ - LogError( "Display %s cannot be opened\n", d->name ); -#ifdef XDMCP - /* - * no display connection was ever made, tell the - * terminal that the open attempt failed - */ - if ((d->displayType & d_origin) == dFromXDMCP) - SendFailed( d, "cannot open display" ); -#endif - ExitDisplay( d, DS_RESTART, XS_RETRY, FALSE ); - break; - case waitCompose( SIGTERM,0,0 ): - /* killed before/during WaitForServer() - - local Xserver died - - display stopped (is zombie) - - "login now" and "suicide" pipe commands (is raiser) - */ - Debug( "display exited on SIGTERM\n" ); - ExitDisplay( d, DS_RESTART, XS_RETRY, FALSE ); - break; - case EX_AL_RESERVER_DPY: - /* - killed after WaitForServer() - - Xserver dead after remote session exit - */ - Debug( "display exited with EX_AL_RESERVER_DPY\n" ); - ExitDisplay( d, DS_RESTART, XS_RESTART, FALSE ); - break; - case EX_RESERVER_DPY: - /* induced by greeter: - - could not secure display - - requested by user - */ - Debug( "display exited with EX_RESERVER_DPY\n" ); - ExitDisplay( d, DS_RESTART, XS_RESTART, TRUE ); - break; - case EX_UNMANAGE_DPY: - /* some fatal error */ - Debug( "display exited with EX_UNMANAGE_DPY\n" ); - ExitDisplay( d, DS_REMOVE, 0, 0 ); - break; - default: - /* prolly crash */ - LogError( "Unknown session exit code %d (sig %d) from manager process\n", - waitCode( status ), waitSig( status ) ); - ExitDisplay( d, DS_REMOVE, 0, 0 ); - break; - } - } else if ((d = FindDisplayByServerPid( pid ))) { - d->serverPid = -1; - switch (d->status) { - case zombie: - Debug( "zombie X server for display %s reaped\n", d->name ); -#ifdef HAVE_VTS - if (d->serverVT && d->zstatus != DS_REMOTE) { - if (d->follower) { - d->follower->serverVT = d->serverVT; - d->follower = 0; - } else { - int con = open( "/dev/console", O_RDONLY ); - if (con >= 0) { - struct vt_stat vtstat; - ioctl( con, VT_GETSTATE, &vtstat ); - if (vtstat.v_active == d->serverVT) { - int vt = 1; - struct display *di; - for (di = displays; di; di = di->next) - if (di != d && di->serverVT) - vt = di->serverVT; - for (di = displays; di; di = di->next) - if (di != d && di->serverVT && - (di->userSess >= 0 || - di->status == remoteLogin)) - vt = di->serverVT; - ioctl( con, VT_ACTIVATE, vt ); - } - ioctl( con, VT_DISALLOCATE, d->serverVT ); - close( con ); - } - } - d->serverVT = 0; - } -#endif - rStopDisplay( d, d->zstatus ); - break; - case phoenix: - Debug( "phoenix X server arises, restarting display %s\n", - d->name ); - d->status = notRunning; - break; - case remoteLogin: - Debug( "remote login X server for display %s exited\n", - d->name ); - d->status = ((d->displayType & d_lifetime) == dReserve) ? - reserve : notRunning; - break; - case raiser: - LogError( "X server for display %s terminated unexpectedly\n", - d->name ); - /* don't kill again */ - break; - case running: - if (startingServer == d && d->serverStatus != ignore) { - if (d->serverStatus == starting && waitCode( status ) != 47) - LogError( "X server died during startup\n" ); - StartServerFailed(); - break; - } - LogError( "X server for display %s terminated unexpectedly\n", - d->name ); - if (d->pid != -1) { - Debug( "terminating session pid %d\n", d->pid ); - TerminateProcess( d->pid, SIGTERM ); - } - break; - case notRunning: - case textMode: - case reserve: - /* this cannot happen */ - Debug( "X server exited for passive (%d) session on display %s\n", - (int)d->status, d->name ); - break; - } - } else - Debug( "unknown child termination\n" ); - } -#ifdef NEED_ENTROPY - AddOtherEntropy(); -#endif -} - -static int -wouldShutdown( void ) -{ - struct display *d; - - if (sdRec.force != SHUT_CANCEL) { - if (sdRec.force == SHUT_FORCEMY) - for (d = displays; d; d = d->next) - if (d->status == remoteLogin || - (d->userSess >= 0 && d->userSess != sdRec.uid)) - return 0; - return 1; - } - return !AnyActiveDisplays(); -} - -FD_TYPE WellKnownSocketsMask; -int WellKnownSocketsMax; -int WellKnownSocketsCount; - -void -RegisterInput( int fd ) -{ - /* can be omited, as it is always called right after opening a socket - if (!FD_ISSET (fd, &WellKnownSocketsMask)) - */ - { - FD_SET( fd, &WellKnownSocketsMask ); - if (fd > WellKnownSocketsMax) - WellKnownSocketsMax = fd; - WellKnownSocketsCount++; - } -} - -void -UnregisterInput( int fd ) -{ - /* the check _is_ necessary, as some handles are unregistered before - the regular close sequence. - */ - if (FD_ISSET( fd, &WellKnownSocketsMask )) { - FD_CLR( fd, &WellKnownSocketsMask ); - WellKnownSocketsCount--; - } -} - -static void -SigHandler( int n ) -{ - int olderrno = errno; - char buf = (char)n; - /* Debug( "caught signal %d\n", n ); this hangs in syslog() */ - write( signalFds[1], &buf, 1 ); -#ifdef __EMX__ - (void)Signal( n, SigHandler ); -#endif - errno = olderrno; -} - -static void -MainLoop( void ) -{ - struct display *d; - struct timeval *tvp, tv; - time_t to; - int nready; - char buf; - FD_TYPE reads; - - Debug( "MainLoop\n" ); - time( &now ); - while ( -#ifdef XDMCP - AnyListenSockets() || -#endif - (Stopping ? AnyRunningDisplays() : AnyDisplaysLeft())) - { - if (!Stopping) - StartDisplays(); - to = TO_INF; - if (sdRec.how) { - if (sdRec.start != TO_INF && now < sdRec.start) { - /*if (sdRec.start < to)*/ - to = sdRec.start; - } else { - sdRec.start = TO_INF; - if (now >= sdRec.timeout) { - sdRec.timeout = TO_INF; - if (wouldShutdown()) - stoppen( TRUE ); - else - cancelShutdown(); - } else { - stoppen( FALSE ); - /*if (sdRec.timeout < to)*/ - to = sdRec.timeout; - } - } - } - if (serverTimeout < to) - to = serverTimeout; - if (utmpTimeout < to) - to = utmpTimeout; - if (to == TO_INF) - tvp = 0; - else { - to -= now; - if (to < 0) - to = 0; - tv.tv_sec = to; - tv.tv_usec = 0; - tvp = &tv; - } - reads = WellKnownSocketsMask; - nready = select( WellKnownSocketsMax + 1, &reads, 0, 0, tvp ); - Debug( "select returns %d\n", nready ); - time( &now ); -#ifdef NEED_ENTROPY - AddTimerEntropy(); -#endif - if (now >= serverTimeout) { - serverTimeout = TO_INF; - StartServerTimeout(); - } - if (now >= utmpTimeout) { - utmpTimeout = TO_INF; - CheckUtmp(); - } - if (nready > 0) { - /* - * we restart after the first handled fd, as - * a) it makes things simpler - * b) the probability that multiple fds trigger at once is - * ridiculously small. we handle it in the next iteration. - */ - /* XXX a cleaner solution would be a callback mechanism */ - if (FD_ISSET( signalFds[0], &reads )) { - if (read( signalFds[0], &buf, 1 ) != 1) - LogPanic( "Signal notification pipe broken.\n" ); - switch (buf) { - case SIGTERM: - case SIGINT: - Debug( "shutting down entire manager\n" ); - stoppen( TRUE ); - break; - case SIGHUP: - LogInfo( "Rescanning all config files\n" ); - ForEachDisplay( MarkDisplay ); - RescanConfigs( TRUE ); - break; - case SIGCHLD: - ReapChildren(); - if (!Stopping && autoRescan) - RescanConfigs( FALSE ); - break; - case SIGUSR1: - if (startingServer && - startingServer->serverStatus == starting) - StartServerSuccess(); - break; - } - continue; - } -#ifdef XDMCP - if (ProcessListenSockets( &reads )) - continue; -#endif /* XDMCP */ - if (handleCtrl( &reads, 0 )) - continue; - /* Must be last (because of the breaks)! */ - again: - for (d = displays; d; d = d->next) { - if (handleCtrl( &reads, d )) - goto again; - if (d->pipe.rfd >= 0 && FD_ISSET( d->pipe.rfd, &reads )) { - processDPipe( d ); - break; - } - if (d->gpipe.rfd >= 0 && FD_ISSET( d->gpipe.rfd, &reads )) { - processGPipe( d ); - break; - } - } - } - } -} - -static void -CheckDisplayStatus( struct display *d ) -{ - if ((d->displayType & d_origin) == dFromFile && !d->stillThere) - StopDisplay( d ); - else if ((d->displayType & d_lifetime) == dReserve && - d->status == running && d->userSess < 0 && !d->idleTimeout) - rStopDisplay( d, DS_RESERVE ); - else if (d->status == notRunning) - if (LoadDisplayResources( d ) < 0) { - LogError( "Unable to read configuration for display %s; " - "stopping it.\n", d->name ); - StopDisplay( d ); - return; - } -} - -static void -KickDisplay( struct display *d ) -{ - if (d->status == notRunning) - StartDisplay( d ); - if (d->serverStatus == awaiting && !startingServer) - StartServer( d ); -} - -#ifdef HAVE_VTS -static int active_vts; - -static int -GetBusyVTs( void ) -{ - struct vt_stat vtstat; - int con; - - if (active_vts == -1) { - vtstat.v_state = 0; - if ((con = open( "/dev/console", O_RDONLY )) >= 0) { - ioctl( con, VT_GETSTATE, &vtstat ); - close( con ); - } - active_vts = vtstat.v_state; - } - return active_vts; -} - -static void -AllocateVT( struct display *d ) -{ - struct display *cd; - int i, tvt, volun; - - if ((d->displayType & d_location) == dLocal && - d->status == notRunning && !d->serverVT && d->reqSrvVT >= 0) - { - if (d->reqSrvVT && d->reqSrvVT < 16) - d->serverVT = d->reqSrvVT; - else { - for (i = tvt = 0;;) { - if (serverVTs[i]) { - tvt = atoi( serverVTs[i++] ); - volun = 0; - if (tvt < 0) { - tvt = -tvt; - volun = 1; - } - if (!tvt || tvt >= 16) - continue; - } else { - if (++tvt >= 16) - break; - volun = 1; - } - for (cd = displays; cd; cd = cd->next) { - if (cd->reqSrvVT == tvt && /* protect from lusers */ - (cd->status != zombie || cd->zstatus != DS_REMOVE)) - goto next; - if (cd->serverVT == tvt) { - if (cd->status != zombie || cd->zstatus == DS_REMOTE) - goto next; - if (!cd->follower) { - d->serverVT = -1; - cd->follower = d; - return; - } - } - } - if (!volun || !((1 << tvt) & GetBusyVTs())) { - d->serverVT = tvt; - return; - } - next: ; - } - } - } -} -#endif - -static void -StartDisplays( void ) -{ - ForEachDisplay( CheckDisplayStatus ); - CloseGetter(); -#ifdef HAVE_VTS - active_vts = -1; - ForEachDisplayRev( AllocateVT ); -#endif - ForEachDisplay( KickDisplay ); -} - -void -StartDisplay( struct display *d ) -{ - if (Stopping) { - Debug( "stopping display %s because shutdown is scheduled\n", d->name ); - StopDisplay( d ); - return; - } - -#ifdef HAVE_VTS - if (d->serverVT < 0) - return; -#endif - - d->status = running; - if ((d->displayType & d_location) == dLocal) { - Debug( "StartDisplay %s\n", d->name ); - /* don't bother pinging local displays; we'll - * certainly notice when they exit - */ - d->pingInterval = 0; - if (d->authorize) { - SetLocalAuthorization( d ); - /* - * reset the server after writing the authorization information - * to make it read the file (for compatibility with old - * servers which read auth file only on reset instead of - * at first connection) - */ - if (d->serverPid != -1 && d->resetForAuth && d->resetSignal) - kill( d->serverPid, d->resetSignal ); - } - if (d->serverPid == -1) { - d->serverStatus = awaiting; - return; - } - } else { - Debug( "StartDisplay %s, try %d\n", d->name, d->startTries + 1 ); - /* this will only happen when using XDMCP */ - if (d->authorizations) - SaveServerAuthorizations( d, d->authorizations, d->authNum ); - } - StartDisplayP2( d ); -} - -void -StartDisplayP2( struct display *d ) -{ - char *cname, *cgname; - int pid; - - openCtrl( d ); - Debug( "forking session\n" ); - ASPrintf( &cname, "sub-daemon for display %s", d->name ); - ASPrintf( &cgname, "greeter for display %s", d->name ); - pid = GFork( &d->pipe, "master daemon", cname, - &d->gpipe, cgname ); - switch (pid) { - case 0: - SetTitle( d->name ); - if (debugLevel & DEBUG_WSESS) - sleep( 100 ); - mstrtalk.pipe = &d->pipe; - (void)Signal( SIGPIPE, SIG_IGN ); - SetAuthorization( d ); - WaitForServer( d ); - if ((d->displayType & d_location) == dLocal) { - GSet( &mstrtalk ); - GSendInt( D_XConnOk ); - } - ManageSession( d ); - /* NOTREACHED */ - case -1: - closeCtrl( d ); - d->status = notRunning; - break; - default: - Debug( "forked session, pid %d\n", pid ); - - /* (void) fcntl (d->pipe.rfd, F_SETFL, O_NONBLOCK); */ - /* (void) fcntl (d->gpipe.rfd, F_SETFL, O_NONBLOCK); */ - RegisterInput( d->pipe.rfd ); - RegisterInput( d->gpipe.rfd ); - - d->pid = pid; - d->hstent->lock = d->hstent->rLogin = d->hstent->goodExit = - d->hstent->sdRec.how = 0; - d->lastStart = now; - break; - } -} - -/* - * transition from running to zombie, textmode, reserve or deleted - */ - -static void -rStopDisplay( struct display *d, int endState ) -{ - Debug( "stopping display %s to state %d\n", d->name, endState ); - AbortStartServer( d ); - d->idleTimeout = 0; - if (d->serverPid != -1 || d->pid != -1) { - if (d->pid != -1) - TerminateProcess( d->pid, SIGTERM ); - if (d->serverPid != -1) - TerminateProcess( d->serverPid, d->termSignal ); - d->status = zombie; - d->zstatus = endState & 0xff; - Debug( " zombiefied\n" ); - } else if (endState == DS_TEXTMODE) { -#ifdef HAVE_VTS - d->status = textMode; - CheckTTYMode(); - } else if (endState == (DS_TEXTMODE | 0x100)) { - d->status = textMode; -#else - SwitchToTty( d ); -#endif - } else if (endState == DS_RESERVE) - d->status = reserve; -#ifdef XDMCP - else if (endState == DS_REMOTE) - StartRemoteLogin( d ); -#endif - else { -#ifndef HAVE_VTS - SwitchToX( d ); -#endif - RemoveDisplay( d ); - } -} - -void -StopDisplay( struct display *d ) -{ - rStopDisplay( d, DS_REMOVE ); -} - -static void -ExitDisplay( - struct display *d, - int endState, - int serverCmd, - int goodExit ) -{ - struct disphist *he; - - if (d->status == raiser) { - serverCmd = XS_KEEP; - goodExit = TRUE; - } - - Debug( "ExitDisplay %s, " - "endState = %d, serverCmd = %d, GoodExit = %d\n", - d->name, endState, serverCmd, goodExit ); - - d->userSess = -1; - if (d->userName) - free( d->userName ); - d->userName = 0; - if (d->sessName) - free( d->sessName ); - d->sessName = 0; - he = d->hstent; - he->lastExit = now; - he->goodExit = goodExit; - if (he->sdRec.how) { - if (he->sdRec.force == SHUT_ASK && - (AnyActiveDisplays() || d->allowShutdown == SHUT_ROOT)) - { - endState = DS_RESTART; - } else { - if (!sdRec.how || sdRec.force != SHUT_FORCE || - !((d->allowNuke == SHUT_NONE && sdRec.uid != he->sdRec.uid) || - (d->allowNuke == SHUT_ROOT && he->sdRec.uid))) - { - if (sdRec.osname) - free( sdRec.osname ); - sdRec = he->sdRec; - if (now < sdRec.timeout || wouldShutdown()) - endState = DS_REMOVE; - } else if (he->sdRec.osname) - free( he->sdRec.osname ); - he->sdRec.how = 0; - he->sdRec.osname = 0; - } - } - if (d->status == zombie) - rStopDisplay( d, d->zstatus ); - else { - if (Stopping) { - StopDisplay( d ); - return; - } - if (endState != DS_RESTART || - (d->displayType & d_origin) != dFromFile) - { - rStopDisplay( d, endState ); - } else { - if (serverCmd == XS_RETRY) { - if ((d->displayType & d_location) == dLocal) { - if (he->lastExit - d->lastStart < 120) { - LogError( "Unable to fire up local display %s;" - " disabling.\n", d->name ); - StopDisplay( d ); - return; - } - } else { - if (++d->startTries > d->startAttempts) { - LogError( "Disabling foreign display %s" - " (too many attempts)\n", d->name ); - StopDisplay( d ); - return; - } - } - } else - d->startTries = 0; - if (d->serverPid != -1 && - (serverCmd != XS_KEEP || d->terminateServer)) - { - Debug( "killing X server for %s\n", d->name ); - TerminateProcess( d->serverPid, d->termSignal ); - d->status = phoenix; - } else - d->status = notRunning; - } - } -} - - -static int pidFd; -static FILE *pidFilePtr; - -static int -StorePid( void ) -{ - int oldpid; - - if (pidFile[0] != '\0') { - pidFd = open( pidFile, O_RDWR ); - if (pidFd == -1 && errno == ENOENT) - pidFd = open( pidFile, O_RDWR|O_CREAT, 0666 ); - if (pidFd == -1 || !(pidFilePtr = fdopen( pidFd, "r+" ))) { - LogError( "process-id file %s cannot be opened\n", - pidFile ); - return -1; - } - if (fscanf( pidFilePtr, "%d\n", &oldpid ) != 1) - oldpid = -1; - fseek( pidFilePtr, 0l, 0 ); - if (lockPidFile) { -#ifdef F_SETLK -# ifndef SEEK_SET -# define SEEK_SET 0 -# endif - struct flock lock_data; - lock_data.l_type = F_WRLCK; - lock_data.l_whence = SEEK_SET; - lock_data.l_start = lock_data.l_len = 0; - if (fcntl( pidFd, F_SETLK, &lock_data ) == -1) { - if (errno == EAGAIN) - return oldpid; - else - return -1; - } -#else -# ifdef LOCK_EX - if (flock( pidFd, LOCK_EX|LOCK_NB ) == -1) { - if (errno == EWOULDBLOCK) - return oldpid; - else - return -1; - } -# else - if (lockf( pidFd, F_TLOCK, 0 ) == -1) { - if (errno == EACCES) - return oldpid; - else - return -1; - } -# endif -#endif - } - fprintf( pidFilePtr, "%ld\n", (long)getpid() ); - (void)fflush( pidFilePtr ); - RegisterCloseOnFork( pidFd ); - } - return 0; -} - -#if 0 -void -UnlockPidFile( void ) -{ - if (lockPidFile) -# ifdef F_SETLK - { - struct flock lock_data; - lock_data.l_type = F_UNLCK; - lock_data.l_whence = SEEK_SET; - lock_data.l_start = lock_data.l_len = 0; - (void)fcntl( pidFd, F_SETLK, &lock_data ); - } -# else -# ifdef F_ULOCK - lockf( pidFd, F_ULOCK, 0 ); -# else - flock( pidFd, LOCK_UN ); -# endif -# endif - close( pidFd ); - fclose( pidFilePtr ); -} -#endif - -void -SetTitle( const char *name ) -{ -#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) - char *p; - int left; -#endif - - ASPrintf( &prog, "%s: %s", prog, name ); - ReInitErrorLog(); -#ifdef HAVE_SETPROCTITLE - setproctitle( "%s", name ); -#elif !defined(NOXDMTITLE) - p = Title; - left = TitleLen; - - *p++ = '-'; - --left; - while (*name && left > 0) { - *p++ = *name++; - --left; - } - while (left > 0) { - *p++ = '\0'; - --left; - } -#endif -} diff --git a/kdm/backend/dm.h b/kdm/backend/dm.h deleted file mode 100644 index c05d4c865..000000000 --- a/kdm/backend/dm.h +++ /dev/null @@ -1,630 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2005 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * global xdm core declarations - */ - -#ifndef _DM_H_ -#define _DM_H_ 1 - -#define WITH_CONSOLE_KIT - -#include "greet.h" -#include <config.ci> - -#include <X11/X.h> /* FamilyInternet6 */ -#include <X11/Xos.h> -#include <X11/Xfuncs.h> -#include <X11/Xmd.h> -#include <X11/Xauth.h> -#include <X11/Intrinsic.h> - -#include <sys/param.h> -#ifdef HAVE_LIMITS_H -# include <limits.h> -#endif - -#include <time.h> -#define Time_t time_t - -#include <stdlib.h> -#include <errno.h> - -#ifdef XDMCP -# if defined(__osf__) -/* someone somewhere defines QUERY under Tru64 which confuses Xdmcp.h */ -# undef QUERY -# endif -# include <X11/Xdmcp.h> -#endif - -#ifndef PATH_MAX -# ifdef MAXPATHLEN -# define PATH_MAX MAXPATHLEN -# else -# define PATH_MAX 1024 -# endif -#endif - -#include <sys/wait.h> -#define waitCode(w) (WIFEXITED(w) ? WEXITSTATUS(w) : 0) -#define waitSig(w) (WIFSIGNALED(w) ? WTERMSIG(w) : 0) -#ifdef WCOREDUMP -# define waitCore(w) (WCOREDUMP(w)) -#else -# define waitCore(w) 0 /* not in POSIX. so what? */ -#endif -typedef int waitType; - -#define waitCompose(sig,core,code) ((sig) * 256 + (core) * 128 + (code)) -#define waitVal(w) waitCompose(waitSig(w), waitCore(w), waitCode(w)) -#define WaitCode(w) ((w) & 0x7f) -#define WaitCore(w) (((w) >> 7) & 1) -#define WaitSig(w) (((w) >> 8) & 0xff) - -#include <sys/time.h> -#define FD_TYPE fd_set - -#include <setjmp.h> -#if defined(__EMX__) || (defined(__NetBSD__) && defined(__sparc__)) /* XXX netbsd? */ -# define Setjmp(e) setjmp(e) -# define Longjmp(e,v) longjmp(e,v) -# define Jmp_buf jmp_buf -#else -# define Setjmp(e) sigsetjmp(e,1) -# define Longjmp(e,v) siglongjmp(e,v) -# define Jmp_buf sigjmp_buf -#endif - -#include <utmp.h> -#ifdef HAVE_UTMPX -# include <utmpx.h> -# define STRUCTUTMP struct utmpx -# define UTMPNAME utmpxname -# define SETUTENT setutxent -# define GETUTENT getutxent -# define PUTUTLINE pututxline -# define ENDUTENT endutxent -# define LASTLOG lastlogx -# define ut_time ut_tv.tv_sec -# define ll_time ll_tv.tv_sec -#else -# define STRUCTUTMP struct utmp -# define UTMPNAME utmpname -# define SETUTENT setutent -# define GETUTENT getutent -# define PUTUTLINE pututline -# define ENDUTENT endutent -# define LASTLOG lastlog -#endif -#ifndef HAVE_STRUCT_UTMP_UT_USER -# define ut_user ut_name -#endif -#ifndef WTMP_FILE -# ifdef _PATH_WTMPX -# define WTMP_FILE _PATH_WTMPX -# elif defined(_PATH_WTMP) -# define WTMP_FILE _PATH_WTMP -# else -# define WTMP_FILE "/usr/adm/wtmp" -# endif -#endif -#ifndef UTMP_FILE -# ifdef _PATH_UTMPX -# define UTMP_FILE _PATH_UTMPX -# elif defined(_PATH_UTMP) -# define UTMP_FILE _PATH_UTMP -# else -# define UTMP_FILE "/etc/utmp" -# endif -#endif - -#ifdef HAVE_NETCONFIG_H -# define STREAMSCONN -#else -# define UNIXCONN -# define TCPCONN -# ifdef FamilyInternet6 -# define IPv6 -# endif -# ifdef HAVE_NETDNET_DN_H -# define DNETCONN -# endif -#endif - -#if !defined(HAVE_ARC4RANDOM) && !defined(DEV_RANDOM) -# define NEED_ENTROPY -#endif - -typedef struct GPipe { - int wfd, rfd; - char *who; -} GPipe; - -typedef struct GTalk { - GPipe *pipe; - Jmp_buf errjmp; -} GTalk; - -typedef struct GProc { - GPipe pipe; - int pid; -} GProc; - -typedef enum displayStatus { notRunning = 0, running, zombie, phoenix, raiser, - textMode, reserve, remoteLogin } DisplayStatus; - -typedef enum serverStatus { ignore = 0, awaiting, starting, - terminated, killed, pausing } ServerStatus; - -typedef struct RcStr { - struct RcStr *next; - char *str; - int cnt; -} RcStr; - -typedef struct CfgDep { - RcStr *name; - long time; -} CfgDep; - -typedef struct CfgArr { - char *data; /* config value array; allocated */ - long *idx; /* config index array; alias */ - CfgDep dep; /* filestamp */ - int numCfgEnt; /* number of config entries */ -} CfgArr; - -struct bsock { - int fd; - int buflen; - char *buffer; -}; - -struct cmdsock { - struct cmdsock *next; - struct bsock sock; /* buffered fd of the socket */ -}; - -typedef struct { - struct cmdsock *css; /* open connections */ - - char *path; /* filename of the socket */ -#ifndef HONORS_SOCKET_PERMS - char *realdir; /* real dirname of the socket */ -#endif - int fd; /* fd of the socket */ - int gid; /* owner group of the socket */ - - char *fpath; /* filename of the fifo */ - struct bsock fifo; /* buffered fd of the fifo */ -} CtrlRec; - -struct display { - struct display *next; - struct disphist *hstent; /* display history entry */ - - /* basic display information */ - char *name; /* DISPLAY name -- also referenced in hstent */ - char *class2; /* display class (may be NULL) */ - int displayType; /* location/origin/lifetime */ - CfgArr cfg; /* config data array */ - - /* display state */ - DisplayStatus status; /* current status */ - int zstatus; /* substatus while zombie */ - int pid; /* process id of child */ - int serverPid; /* process id of server (-1 if none) */ -#ifdef HAVE_VTS - int serverVT; /* server VT (0 = none, -1 = pending) */ - struct display *follower; /* on exit, hand VT to this display */ -#endif - ServerStatus serverStatus; /* X server startup state */ - Time_t lastStart; /* time of last display start */ - int startTries; /* current start try */ - int stillThere; /* state during HUP processing */ - int userSess; /* -1=nobody, otherwise uid */ - char *userName; - char *sessName; - CtrlRec ctrl; /* command socket & fifo */ - GPipe pipe; /* comm master <-> slave */ - GPipe gpipe; /* comm master <-> greeter */ -#ifdef XDMCP - char *remoteHost; /* for X -query type remote login */ - /* XDMCP state */ - unsigned sessionID; /* ID of active session */ - ARRAY8 peer; /* display peer address */ - ARRAY8 from; /* XDMCP port of display */ - unsigned displayNumber; /* numerical part of name */ - int useChooser; /* Run the chooser for this display */ - ARRAY8 clientAddr; /* for chooser picking */ - unsigned connectionType; /* ... */ - int xdmcpFd; -#endif - - CONF_CORE_LOCAL_DEFS - - int idleTimeout; /* abort login after that time */ - - unsigned short *authNameLens; /* authorization protocol name lens */ - - /* information potentially derived from resources */ - int authNameNum; /* number of protocol names */ - Xauth **authorizations; /* authorization data */ - int authNum; /* number of authorizations */ - char *authFile; /* file to store authorization in */ -}; - -typedef struct { - unsigned how:2, /* 0=none 1=reboot 2=halt (SHUT_*) */ - force:2; - int uid; - int start; - int timeout; - char *osname; - time_t bmstamp; - int osindex; -} SdRec; - -struct disphist { - struct disphist *next; - char *name; - Time_t lastExit; /* time of last display exit */ - unsigned rLogin:2, /* 0=nothing 1=relogin 2=login */ - lock:1, /* screen locker running */ - goodExit:1; /* was the last exit "peaceful"? */ - SdRec sdRec; - char *nuser, *npass, *nargs; -}; - -#ifdef XDMCP - -#define PROTO_TIMEOUT (30 * 60) /* 30 minutes should be long enough */ - -struct protoDisplay { - struct protoDisplay *next; - XdmcpNetaddr address; /* UDP address */ - int addrlen; /* UDP address length */ - unsigned long date; /* creation date */ - CARD16 displayNumber; - CARD16 connectionType; - ARRAY8 connectionAddress; - CARD32 sessionID; - Xauth *fileAuthorization; - Xauth *xdmcpAuthorization; - ARRAY8 authenticationName; - ARRAY8 authenticationData; - XdmAuthKeyRec key; -}; -#endif /* XDMCP */ - -/* status code for RStopDisplay */ -#define DS_RESTART 0 -#define DS_TEXTMODE 1 -#define DS_RESERVE 2 -#define DS_REMOTE 3 -#define DS_REMOVE 4 - -/* command codes dpy process -> master process */ -#define D_User 1 -#define D_ReLogin 2 -#define D_ChooseHost 4 -#define D_RemoteHost 5 -#define D_XConnOk 6 - -extern int debugLevel; - -CONF_CORE_GLOBAL_DECLS - -/* in daemon.c */ -void BecomeDaemon( void ); - -/* in dm.c */ -extern char *prog, *progpath; -extern time_t now; -extern SdRec sdRec; -void StartDisplay( struct display *d ); -void StartDisplayP2( struct display *d ); -void StopDisplay( struct display *d ); -void SetTitle( const char *name ); -void SwitchToX( struct display *d ); -void setNLogin( struct display *d, - const char *nuser, const char *npass, char *nargs, - int rl ); -void cancelShutdown( void ); -int TTYtoVT( const char *tty ); -int activateVT( int vt ); - -/* in ctrl.c */ -void openCtrl( struct display *d ); -void closeCtrl( struct display *d ); -int handleCtrl( FD_TYPE *reads, struct display *d ); -void chownCtrl( CtrlRec *cr, int uid ); -void updateCtrl( void ); - -/* in dpylist.c */ -extern struct display *displays; /* that's ugly ... */ -int AnyDisplaysLeft( void ); -void ForEachDisplay( void (*f)( struct display * ) ); -#ifdef HAVE_VTS -void ForEachDisplayRev( void (*f)( struct display * ) ); -#endif -void RemoveDisplay( struct display *old ); -struct display - *FindDisplayByName( const char *name ), -#ifdef XDMCP - *FindDisplayBySessionID( CARD32 sessionID ), - *FindDisplayByAddress( XdmcpNetaddr addr, int addrlen, CARD16 displayNumber ), -#endif /* XDMCP */ - *FindDisplayByPid( int pid ), - *FindDisplayByServerPid( int serverPid ), - *NewDisplay( const char *name ); -int AnyActiveDisplays( void ); -int AnyRunningDisplays( void ); -int AnyReserveDisplays( void ); -int idleReserveDisplays( void ); -int AllLocalDisplaysLocked( struct display *dp ); -int StartReserveDisplay( int lt ); -void ReapReserveDisplays( void ); - -/* in reset.c */ -void pseudoReset( void ); - -/* in resource.c */ -char **FindCfgEnt( struct display *d, int id ); -int InitResources( char **argv ); -int LoadDMResources( int force ); -int LoadDisplayResources( struct display *d ); -void ScanServers( void ); -void CloseGetter( void ); -int startConfig( int what, CfgDep *dep, int force ); -RcStr *newStr( char *str ); -void delStr( RcStr *str ); -extern GTalk cnftalk; - -/* in session.c */ -extern struct display *td; -extern const char *td_setup; -char **baseEnv( const char *user ); -char **inheritEnv( char **env, const char **what ); -char **systemEnv( const char *user ); -int source( char **env, const char *file, const char *arg ); -void ManageSession( struct display *d ); - -extern GTalk mstrtalk, grttalk; -extern GProc grtproc; -void OpenGreeter( void ); -int CloseGreeter( int force ); -int CtrlGreeterWait( int wreply ); -void PrepErrorGreet( void ); -char *conv_interact( int what, const char *prompt ); - -/* process.c */ -typedef void (*SIGFUNC)( int ); -SIGFUNC Signal( int, SIGFUNC Handler ); - -void RegisterInput( int fd ); -void UnregisterInput( int fd ); -void RegisterCloseOnFork( int fd ); -void ClearCloseOnFork( int fd ); -void CloseNClearCloseOnFork( int fd ); -int Fork( void ); -int Wait4( int pid ); -void execute( char **argv, char **env ); -int runAndWait( char **args, char **env ); -FILE *pOpen( char **what, char m, int *pid ); -int pClose( FILE *f, int pid ); -char *locate( const char *exe ); -void TerminateProcess( int pid, int sig ); - -void GSet( GTalk *talk); /* call before GOpen! */ -int GFork( GPipe *pajp, const char *pname, char *cname, - GPipe *ogp, char *cgname ); -void GClosen( GPipe *pajp ); -int GOpen( GProc *proc, - char **argv, const char *what, char **env, char *cname, - GPipe *gp ); -int GClose( GProc *proc, GPipe *gp, int force ); - -void GSendInt( int val ); -int GRecvInt( void ); -int GRecvCmd( int *cmd ); -void GSendArr( int len, const char *data ); -char *GRecvArr( int *len ); -int GRecvStrBuf( char *buf ); -int GRecvArrBuf( char *buf ); -void GSendStr( const char *buf ); -void GSendNStr( const char *buf, int len ); /* exact len, buf != 0 */ -void GSendStrN( const char *buf, int len ); /* maximal len */ -char *GRecvStr( void ); -void GSendArgv( char **argv ); -void GSendStrArr( int len, char **data ); -char **GRecvStrArr( int *len ); -char **GRecvArgv( void ); - -/* client.c */ -#define GCONV_NORMAL 0 -#define GCONV_HIDDEN 1 -#define GCONV_USER 2 -#define GCONV_PASS 3 -#define GCONV_PASS_ND 4 -#define GCONV_BINARY 5 -typedef char *(*GConvFunc)( int what, const char *prompt ); -int Verify( GConvFunc gconv, int rootok ); -#ifdef WITH_CONSOLE_KIT -int StartClient( const char *ck_session_cookie ); -#else -int StartClient( void ); -#endif -void SessionExit( int status ) ATTR_NORETURN; -int ReadDmrc( void ); -extern char **userEnviron, **systemEnviron; -extern char *curuser, *curpass, *curtype, *newpass, - *dmrcuser, *curdmrc, *newdmrc; -extern int cursource; -#define PWSRC_MANUAL 0 -#define PWSRC_AUTOLOGIN 1 -#define PWSRC_RELOGIN 2 - -/* server.c */ -char **PrepServerArgv( struct display *d, const char *args ); -void StartServer( struct display *d ); -void AbortStartServer( struct display *d ); -void StartServerSuccess( void ); -void StartServerFailed( void ); -void StartServerTimeout( void ); -extern struct display *startingServer; -extern time_t serverTimeout; - -void WaitForServer( struct display *d ); -void ResetServer( struct display *d ); -int PingServer(struct display *d ); -extern Display *dpy; - -/* in util.c */ -void *Calloc( size_t nmemb, size_t size ); -void *Malloc( size_t size ); -void *Realloc( void *ptr, size_t size ); -void WipeStr( char *str ); -int StrCmp( const char *s1, const char *s2 ); -#ifdef HAVE_STRNLEN -# define StrNLen(s, m) strnlen(s, m) -#else -int StrNLen( const char *s, int max ); -#endif -int StrNDup( char **dst, const char *src, int len ); -int StrDup( char **dst, const char *src ); -int arrLen( char **arr ); -void freeStrArr( char **arr ); -char **initStrArr( char **arr ); -char **xCopyStrArr( int rn, char **arr ); -/* Note: the following functions free the old data even in case of failure */ -int ReStrN( char **dst, const char *src, int len ); -int ReStr( char **dst, const char *src ); -int StrApp( char **dst, ... ); -char **addStrArr( char **arr, const char *str, int len ); -char **parseArgs( char **argv, const char *string ); -/* End note */ -char **setEnv( char **e, const char *name, const char *value ); -char **putEnv( const char *string, char **env ); -const char *getEnv( char **e, const char *name ); -const char *localHostname( void ); -int Reader( int fd, void *buf, int len ); -int Writer( int fd, const void *buf, int len ); -int fGets( char *buf, int max, FILE *f ); -void randomStr( char *s ); -time_t mTime( const char *fn ); -void ListSessions( int flags, struct display *d, void *ctx, - void (*emitXSess)( struct display *, struct display *, void * ), - void (*emitTTYSess)( STRUCTUTMP *, struct display *, void * ) ); - -/* in inifile.c */ -char *iniLoad( const char *fname ); -int iniSave( const char *data, const char *fname ); -char *iniEntry( char *data, const char *section, const char *key, const char *value ); -char *iniMerge( char *data, const char *newdata ); - -/* in bootman.c */ -int getBootOptions( char ***opts, int *def, int *cur ); -int setBootOption( const char *opt, SdRec *sdr ); -void commitBootOption( void ); - -/* in netaddr.c */ -char *NetaddrAddress( char *netaddrp, int *lenp ); -char *NetaddrPort( char *netaddrp, int *lenp ); -int ConvertAddr( char *saddr, int *len, char **addr ); -int NetaddrFamily( char *netaddrp ); -int addressEqual( char *a1, int len1, char *a2, int len2 ); - -#ifdef XDMCP - -/* in xdmcp.c */ -char *NetworkAddressToHostname( CARD16 connectionType, ARRAY8Ptr connectionAddress ); -void SendFailed( struct display *d, const char *reason ); -void init_session_id( void ); - -/* in policy.c */ -struct sockaddr; -ARRAY8Ptr Accept( struct sockaddr *from, int fromlen, CARD16 displayNumber ); -ARRAY8Ptr ChooseAuthentication( ARRAYofARRAY8Ptr authenticationNames ); -int CheckAuthentication( struct protoDisplay *pdpy, ARRAY8Ptr displayID, ARRAY8Ptr name, ARRAY8Ptr data ); -int SelectAuthorizationTypeIndex( ARRAY8Ptr authenticationName, ARRAYofARRAY8Ptr authorizationNames ); -int SelectConnectionTypeIndex( ARRAY16Ptr connectionTypes, ARRAYofARRAY8Ptr connectionAddresses ); -int Willing( ARRAY8Ptr addr, CARD16 connectionType, ARRAY8Ptr authenticationName, ARRAY8Ptr status, xdmOpCode type ); - -/* in protodpy.c */ -void DisposeProtoDisplay( struct protoDisplay *pdpy ); - -struct protoDisplay *FindProtoDisplay( XdmcpNetaddr address, int addrlen, - CARD16 displayNumber ); -struct protoDisplay *NewProtoDisplay( XdmcpNetaddr address, int addrlen, - CARD16 displayNumber, - CARD16 connectionType, - ARRAY8Ptr connectionAddress, - CARD32 sessionID ); - -#define FamilyBroadcast 0xffff -typedef void (*ChooserFunc)( CARD16 connectionType, ARRAY8Ptr addr, char *closure ); -typedef void (*ListenFunc)( ARRAY8Ptr addr, void **closure ); - -/* in access.c */ -ARRAY8Ptr getLocalAddress( void ); -int AcceptableDisplayAddress( ARRAY8Ptr clientAddress, CARD16 connectionType, xdmOpCode type ); -int ForEachMatchingIndirectHost( ARRAY8Ptr clientAddress, CARD16 connectionType, ChooserFunc function, char *closure ); -void ScanAccessDatabase( int force ); -int UseChooser( ARRAY8Ptr clientAddress, CARD16 connectionType ); -void ForEachChooserHost( ARRAY8Ptr clientAddress, CARD16 connectionType, ChooserFunc function, char *closure ); -void ForEachListenAddr( ListenFunc listenfunction, ListenFunc mcastfcuntion, void **closure ); - -/* in choose.c */ -ARRAY8Ptr IndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ); -int IsIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ); -int RememberIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ); -void ForgetIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ); -int RegisterIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType, ARRAY8Ptr choice ); -int DoChoose( void ); - -/* socket.c or streams.c */ -void UpdateListenSockets( void ); -int AnyListenSockets( void ); -int ProcessListenSockets( FD_TYPE *reads ); - -/* in xdmcp.c */ -void ProcessRequestSocket( int fd ); - -#endif /* XDMCP */ - -/* in sessreg.c */ -void sessreg( struct display *d, int pid, const char *user, int uid ); - -#endif /* _DM_H_ */ diff --git a/kdm/backend/dm_auth.h b/kdm/backend/dm_auth.h deleted file mode 100644 index 28725ee8d..000000000 --- a/kdm/backend/dm_auth.h +++ /dev/null @@ -1,105 +0,0 @@ -/************************************************************ - -Copyright 1998 by Thomas E. Dickey <[email protected]> - - All Rights Reserved - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name(s) of the above copyright -holders shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without prior written -authorization. - -********************************************************/ - -#ifndef _DM_AUTH_H_ -#define _DM_AUTH_H_ 1 - -#include "dm.h" - -void MitInitAuth( unsigned short name_len, const char *name ); -Xauth *MitGetAuth( unsigned short namelen, const char *name ); - -#ifdef HASXDMAUTH -void XdmInitAuth( unsigned short name_len, const char *name ); -Xauth *XdmGetAuth( unsigned short namelen, const char *name ); -# ifdef XDMCP -void XdmGetXdmcpAuth( struct protoDisplay *pdpy, - unsigned short authorizationNameLen, - const char *authorizationName ); -int XdmCheckAuthentication( struct protoDisplay *pdpy, - ARRAY8Ptr displayID, - ARRAY8Ptr authenticationName, - ARRAY8Ptr authenticationData ); -# else -# define XdmGetXdmcpAuth NULL -# endif -#endif - -#ifdef SECURE_RPC -void SecureRPCInitAuth( unsigned short name_len, const char *name ); -Xauth *SecureRPCGetAuth( unsigned short name_len, const char *name ); -#endif - -#ifdef K5AUTH -void Krb5InitAuth( unsigned short name_len, const char *name ); -Xauth *Krb5GetAuth( unsigned short name_len, const char *name ); - -Xauth *Krb5GetAuthFor( unsigned short name_len, const char *name, const char *dname ); -char *Krb5Init( const char *user, const char *passwd, const char *dname ); -void Krb5Destroy( const char *dname ); -#endif - -/* auth.c */ -int ValidAuthorization( unsigned short name_length, const char *name ); - - -#ifdef XDMCP - -void -SetProtoDisplayAuthorization( struct protoDisplay *pdpy, - unsigned short authorizationNameLen, - const char *authorizationName ); - -#endif /* XDMCP */ - -int SaveServerAuthorizations( struct display *d, Xauth **auths, int count ); -void CleanUpFileName( const char *src, char *dst, int len ); -void RemoveUserAuthorization( struct display *d ); -void SetAuthorization( struct display *d ); -void SetLocalAuthorization( struct display *d ); -void SetUserAuthorization( struct display *d ); - -/* genauth.c */ -int GenerateAuthData( char *auth, int len ); -#ifdef NEED_ENTROPY -void AddPreGetEntropy( void ); -void AddOtherEntropy( void ); -void AddTimerEntropy( void ); -#endif - -#ifdef HAVE_ARC4RANDOM -# define secureRandom() arc4random() -#else -int secureRandom( void ); -#endif - -#endif /* _DM_AUTH_H_ */ diff --git a/kdm/backend/dm_error.h b/kdm/backend/dm_error.h deleted file mode 100644 index 3570c18fc..000000000 --- a/kdm/backend/dm_error.h +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************ - -Copyright 1998 by Thomas E. Dickey <[email protected]> - - All Rights Reserved - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name(s) of the above copyright -holders shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without prior written -authorization. - -********************************************************/ - - -#ifndef _DM_ERROR_H_ -#define _DM_ERROR_H_ 1 - -#include "greet.h" - -#include <stdarg.h> - -void GDebug( const char *fmt, ... ); -void Debug( const char *fmt, ... ); -void LogInfo( const char *fmt, ... ); -void LogWarn( const char *fmt, ... ); -void LogError( const char *fmt, ... ); -void LogPanic( const char *fmt, ... ) ATTR_NORETURN; -void LogOutOfMem( void ); -void Panic( const char *mesg ) ATTR_NORETURN; -void InitErrorLog( const char *errorLogFile ); -#ifdef USE_SYSLOG -void ReInitErrorLog( void ); -#else -# define ReInitErrorLog() while(0) -#endif -int ASPrintf( char **strp, const char *fmt, ... ); -int VASPrintf( char **strp, const char *fmt, va_list args ); - -#endif /* _DM_ERROR_H_ */ diff --git a/kdm/backend/dm_socket.h b/kdm/backend/dm_socket.h deleted file mode 100644 index 56a39fd0e..000000000 --- a/kdm/backend/dm_socket.h +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************ - -Copyright 1998 by Thomas E. Dickey <[email protected]> -Copyright 2002-2004 Oswald Buddenhagen <[email protected]> - - All Rights Reserved - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name(s) of the above copyright -holders shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without prior written -authorization. - -********************************************************/ - -#ifndef _DM_SOCKET_H_ -#define _DM_SOCKET_H_ 1 - -#ifndef __Lynx__ -# include <sys/socket.h> -#else -# include <socket.h> -#endif - -#ifdef TCPCONN -# include <netinet/in.h> -#endif - -#ifdef UNIXCONN -# ifndef __Lynx__ -# include <sys/un.h> -# else -# include <un.h> -# endif -#endif - -#ifdef DNETCONN -# include <netdnet/dn.h> -#endif - -#if (defined(__svr4__) && !defined(__sun__)) && defined(SIOCGIFCONF) -# define SYSV_SIOCGIFCONF -int ifioctl( int fd, int cmd, char *arg ); -#else -# define ifioctl ioctl -#endif - -#ifdef BSD -# if (BSD >= 199103) -# define VARIABLE_IFREQ -# endif -#endif - -#endif /* _DM_SOCKET_H_ */ diff --git a/kdm/backend/dpylist.c b/kdm/backend/dpylist.c deleted file mode 100644 index b512293f7..000000000 --- a/kdm/backend/dpylist.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2005 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * a simple linked list of known displays - */ - -#include "dm.h" -#include "dm_error.h" - -struct display *displays; -static struct disphist *disphist; - -int -AnyDisplaysLeft( void ) -{ - return displays != (struct display *)0; -} - -int -AnyActiveDisplays( void ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (d->status == remoteLogin || d->userSess >= 0) - return 1; - return 0; -} - -int -AnyRunningDisplays( void ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - switch (d->status) { - case notRunning: - case textMode: - case reserve: - break; - default: - return 1; - } - return 0; -} - -int -AnyReserveDisplays( void ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if ((d->displayType & d_lifetime) == dReserve) - return 1; - return 0; -} - -int -idleReserveDisplays( void ) -{ - struct display *d; - int cnt = 0; - - for (d = displays; d; d = d->next) - if (d->status == reserve) - cnt++; - return cnt; -} - -int -StartReserveDisplay( int lt ) -{ - struct display *d, *rd; - - for (rd = 0, d = displays; d; d = d->next) - if (d->status == reserve) - rd = d; - if (rd) { - rd->idleTimeout = lt; - rd->status = notRunning; - return 1; - } - return 0; -} - -void -ForEachDisplay( void (*f)( struct display * ) ) -{ - struct display *d, *next; - - for (d = displays; d; d = next) { - next = d->next; - (*f)( d ); - } -} - -#ifdef HAVE_VTS -static void -_forEachDisplayRev( struct display *d, void (*f)( struct display * ) ) -{ - if (d) { - if (d->next) - _forEachDisplayRev( d->next, f ); - (*f)( d ); - } -} - -void -ForEachDisplayRev( void (*f)( struct display * ) ) -{ - _forEachDisplayRev( displays, f ); -} -#endif - -struct display * -FindDisplayByName( const char *name ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (!strcmp( name, d->name )) - return d; - return 0; -} - -struct display * -FindDisplayByPid( int pid ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (pid == d->pid) - return d; - return 0; -} - -struct display * -FindDisplayByServerPid( int serverPid ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (serverPid == d->serverPid) - return d; - return 0; -} - -#ifdef XDMCP - -struct display * -FindDisplayBySessionID( CARD32 sessionID ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if (sessionID == d->sessionID) - return d; - return 0; -} - -struct display * -FindDisplayByAddress( XdmcpNetaddr addr, int addrlen, CARD16 displayNumber ) -{ - struct display *d; - - for (d = displays; d; d = d->next) - if ((d->displayType & d_origin) == dFromXDMCP && - d->displayNumber == displayNumber && - addressEqual( (XdmcpNetaddr)d->from.data, d->from.length, - addr, addrlen )) - return d; - return 0; -} - -#endif /* XDMCP */ - -#define IfFree(x) if (x) free( (char *)x ) - -void -RemoveDisplay( struct display *old ) -{ - struct display *d, **dp; - int i; - - for (dp = &displays; (d = *dp); dp = &(*dp)->next) { - if (d == old) { - Debug( "Removing display %s\n", d->name ); - *dp = d->next; - IfFree( d->class2 ); - IfFree( d->cfg.data ); - delStr( d->cfg.dep.name ); -#ifdef XDMCP - IfFree( d->remoteHost ); -#endif - if (d->authorizations) { - for (i = 0; i < d->authNum; i++) - XauDisposeAuth( d->authorizations[i] ); - free( (char *)d->authorizations ); - } - if (d->authFile) { - (void)unlink( d->authFile ); - free( d->authFile ); - } - IfFree( d->authNameLens ); -#ifdef XDMCP - XdmcpDisposeARRAY8( &d->peer ); - XdmcpDisposeARRAY8( &d->from ); - XdmcpDisposeARRAY8( &d->clientAddr ); -#endif - free( (char *)d ); - break; - } - } -} - -static struct disphist * -FindHist( const char *name ) -{ - struct disphist *hstent; - - for (hstent = disphist; hstent; hstent = hstent->next) - if (!strcmp( hstent->name, name )) - return hstent; - return 0; -} - -struct display * -NewDisplay( const char *name ) -{ - struct display *d; - struct disphist *hstent; - - if (!(hstent = FindHist( name ))) { - if (!(hstent = Calloc( 1, sizeof(*hstent) ))) - return 0; - if (!StrDup( &hstent->name, name )) { - free( hstent ); - return 0; - } - hstent->next = disphist; disphist = hstent; - } - - if (!(d = (struct display *)Calloc( 1, sizeof(*d) ))) - return 0; - d->next = displays; - d->hstent = hstent; - d->name = hstent->name; - /* initialize fields (others are 0) */ - d->pid = -1; - d->serverPid = -1; - d->ctrl.fd = -1; - d->ctrl.fifo.fd = -1; - d->pipe.rfd = -1; - d->pipe.wfd = -1; - d->gpipe.rfd = -1; - d->gpipe.wfd = -1; - d->userSess = -1; -#ifdef XDMCP - d->xdmcpFd = -1; -#endif - displays = d; - Debug( "created new display %s\n", d->name ); - return d; -} diff --git a/kdm/backend/error.c b/kdm/backend/error.c deleted file mode 100644 index 93ec40e70..000000000 --- a/kdm/backend/error.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * Log display manager errors to a file as - * we generally do not have a terminal to talk to - * or use syslog if it exists - */ - -#include "dm.h" -#include "dm_error.h" - -#include <unistd.h> -#include <stdio.h> - -#define PRINT_QUOTES -#define PRINT_ARRAYS -#define LOG_DEBUG_MASK DEBUG_CORE -#define LOG_PANIC_EXIT 1 -#define NEED_ASPRINTF -#define STATIC -#include "printf.c" - -void -GDebug( const char *fmt, ... ) -{ - va_list args; - - if (debugLevel & DEBUG_HLPCON) { - va_start( args, fmt ); - Logger( DM_DEBUG, fmt, args ); - va_end( args ); - } -} - -void -Panic( const char *mesg ) -{ - int fd = open( "/dev/console", O_WRONLY ); - write( fd, "xdm panic: ", 11 ); - write( fd, mesg, strlen( mesg ) ); - write( fd, "\n", 1 ); -#ifdef USE_SYSLOG - ReInitErrorLog(); - syslog( LOG_ALERT, "%s", mesg ); -#endif - exit( 1 ); -} - -#ifdef USE_SYSLOG -void -ReInitErrorLog() -{ - if (!(debugLevel & DEBUG_NOSYSLOG)) - InitLog(); -} -#endif - -void -InitErrorLog( const char *errorLogFile ) -{ - int fd; - char buf[128]; - -#ifdef USE_SYSLOG - ReInitErrorLog(); -#endif - /* We do this independently of using syslog, as we cannot redirect - * the output of external programs to syslog. - */ - if (!errorLogFile || strcmp( errorLogFile, "-" )) { - if (!errorLogFile) { - sprintf( buf, "/var/log/%s.log", prog ); - errorLogFile = buf; - } - if ((fd = open( errorLogFile, O_CREAT | O_APPEND | O_WRONLY, 0666 )) < 0) - LogError( "Cannot open log file %s\n", errorLogFile ); - else { -#ifdef USE_SYSLOG -# ifdef USE_PAM -# define PAMLOG " PAM logs messages related to authentication to authpriv.*." -# else -# define PAMLOG -# endif -# define WARNMSG \ - "********************************************************************************\n" \ - "Note that your system uses syslog. All of tdm's internally generated messages\n" \ - "(i.e., not from libraries and external programs/scripts it uses) go to the\n" \ - "daemon.* syslog facility; check your syslog configuration to find out to which\n" \ - "file(s) it is logged." PAMLOG "\n" \ - "********************************************************************************\n\n" - if (!lseek( fd, 0, SEEK_END )) - write( fd, WARNMSG, sizeof(WARNMSG) - 1 ); -#endif - dup2( fd, 1 ); - close( fd ); - dup2( 1, 2 ); - } - } -} - diff --git a/kdm/backend/genauth.c b/kdm/backend/genauth.c deleted file mode 100644 index 6da95cce0..000000000 --- a/kdm/backend/genauth.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2003-2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#ifdef NEED_ENTROPY - -# include <signal.h> - -/* ####################################################################### */ - -/* - * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. - * Copyright (c) 2001-2002 Damien Miller. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "dm_socket.h" - -#include <string.h> - -#ifndef INADDR_LOOPBACK -# define INADDR_LOOPBACK 0x7F000001U -#endif - -#ifndef offsetof -# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif - -static int -getPrngdBytes( char *buf, int len, - unsigned short tcp_port, const char *socket_path ) -{ - int fd, addr_len, rval, errors; - char msg[2]; - struct sockaddr *addr; - struct sockaddr_in addr_in; - struct sockaddr_un addr_un; - int af; - SIGFUNC old_sigpipe; - - if (tcp_port) { - memset( &addr_in, 0, sizeof(addr_in) ); - af = addr_in.sin_family = AF_INET; - addr_in.sin_addr.s_addr = htonl( INADDR_LOOPBACK ); - addr_in.sin_port = htons( tcp_port ); - addr_len = sizeof(addr_in); - addr = (struct sockaddr *)&addr_in; - } else if (*socket_path) { - unsigned spl = strlen( socket_path ); - if (spl >= sizeof(addr_un.sun_path)) { - LogError( "get_random_prngd: " - "Random pool path is too long\n" ); - return -1; - } - af = addr_un.sun_family = AF_UNIX; - strncpy( addr_un.sun_path, socket_path, - sizeof(addr_un.sun_path) ); - addr_len = offsetof( struct sockaddr_un, sun_path ) + spl + 1; - addr = (struct sockaddr *)&addr_un; - } else - return -1; - - old_sigpipe = Signal( SIGPIPE, SIG_IGN ); - - errors = 0; - rval = -1; -reopen: - if ((fd = socket( af, SOCK_STREAM, 0 )) < 0) { - LogError( "Couldn't create socket: %m\n" ); - goto done; - } - - if (connect( fd, (struct sockaddr *)addr, addr_len )) { - if (af == AF_INET) - LogError( "Couldn't connect to PRNGD port %d: %m\n", - tcp_port ); - else - LogError( "Couldn't connect to PRNGD socket %\"s: %m\n", - socket_path ); - goto done; - } - - /* Send blocking read request to PRNGD */ - msg[0] = 0x02; - msg[1] = len; - - if (Writer( fd, msg, sizeof(msg) ) != sizeof(msg)) { - if (errno == EPIPE && errors < 10) { - close( fd ); - errors++; - goto reopen; - } - LogError( "Couldn't write to PRNGD socket: %m\n" ); - goto done; - } - - if (Reader( fd, buf, len ) != len) { - if (errno == EPIPE && errors < 10) { - close( fd ); - errors++; - goto reopen; - } - LogError( "Couldn't read from PRNGD socket: %m\n" ); - goto done; - } - - rval = 0; -done: - Signal( SIGPIPE, old_sigpipe ); - if (fd != -1) - close( fd ); - return rval; -} - -/* ####################################################################### */ - -/* - * Stolen from the Linux kernel. - * - * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All - * rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF - * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - */ - -static unsigned epool[32], erotate, eadd_ptr; - -static void -add_entropy( unsigned const *in, int nwords ) -{ - static unsigned const twist_table[8] = { - 0, 0x3b6e20c8, 0x76dc4190, 0x4db26158, - 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; - unsigned i, w; - int new_rotate; - - while (nwords--) { - w = *in++; - w = (w<<erotate | w>>(32-erotate)) & 0xffffffff; - i = eadd_ptr = (eadd_ptr - 1) & 31; - new_rotate = erotate + 14; - if (i) - new_rotate = erotate + 7; - erotate = new_rotate & 31; - w ^= epool[(i + 26) & 31]; - w ^= epool[(i + 20) & 31]; - w ^= epool[(i + 14) & 31]; - w ^= epool[(i + 7) & 31]; - w ^= epool[(i + 1) & 31]; - w ^= epool[i]; - epool[i] = (w >> 3) ^ twist_table[w & 7]; - } -} - -/* ####################################################################### */ - -/* - * This code implements something close to the MD5 message-digest - * algorithm. This code is based on code written by Colin Plumb - * in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - */ - -/* The four core functions - F1 is optimized somewhat */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1 (z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define pmd5_step(f, w, x, y, z, data, s) \ - (w += (f(x, y, z) + data) & 0xffffffff, w = w<<s | w>>(32-s), w += x) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. - */ -static void -pmd5_hash( unsigned *out, unsigned const in[16] ) -{ - unsigned a, b, c, d; - - a = out[0]; - b = out[1]; - c = out[2]; - d = out[3]; - - pmd5_step( F1, a, b, c, d, in[0] + 0xd76aa478, 7 ); - pmd5_step( F1, d, a, b, c, in[1] + 0xe8c7b756, 12 ); - pmd5_step( F1, c, d, a, b, in[2] + 0x242070db, 17 ); - pmd5_step( F1, b, c, d, a, in[3] + 0xc1bdceee, 22 ); - pmd5_step( F1, a, b, c, d, in[4] + 0xf57c0faf, 7 ); - pmd5_step( F1, d, a, b, c, in[5] + 0x4787c62a, 12 ); - pmd5_step( F1, c, d, a, b, in[6] + 0xa8304613, 17 ); - pmd5_step( F1, b, c, d, a, in[7] + 0xfd469501, 22 ); - pmd5_step( F1, a, b, c, d, in[8] + 0x698098d8, 7 ); - pmd5_step( F1, d, a, b, c, in[9] + 0x8b44f7af, 12 ); - pmd5_step( F1, c, d, a, b, in[10] + 0xffff5bb1, 17 ); - pmd5_step( F1, b, c, d, a, in[11] + 0x895cd7be, 22 ); - pmd5_step( F1, a, b, c, d, in[12] + 0x6b901122, 7 ); - pmd5_step( F1, d, a, b, c, in[13] + 0xfd987193, 12 ); - pmd5_step( F1, c, d, a, b, in[14] + 0xa679438e, 17 ); - pmd5_step( F1, b, c, d, a, in[15] + 0x49b40821, 22 ); - - pmd5_step( F2, a, b, c, d, in[1] + 0xf61e2562, 5 ); - pmd5_step( F2, d, a, b, c, in[6] + 0xc040b340, 9 ); - pmd5_step( F2, c, d, a, b, in[11] + 0x265e5a51, 14 ); - pmd5_step( F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20 ); - pmd5_step( F2, a, b, c, d, in[5] + 0xd62f105d, 5 ); - pmd5_step( F2, d, a, b, c, in[10] + 0x02441453, 9 ); - pmd5_step( F2, c, d, a, b, in[15] + 0xd8a1e681, 14 ); - pmd5_step( F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20 ); - pmd5_step( F2, a, b, c, d, in[9] + 0x21e1cde6, 5 ); - pmd5_step( F2, d, a, b, c, in[14] + 0xc33707d6, 9 ); - pmd5_step( F2, c, d, a, b, in[3] + 0xf4d50d87, 14 ); - pmd5_step( F2, b, c, d, a, in[8] + 0x455a14ed, 20 ); - pmd5_step( F2, a, b, c, d, in[13] + 0xa9e3e905, 5 ); - pmd5_step( F2, d, a, b, c, in[2] + 0xfcefa3f8, 9 ); - pmd5_step( F2, c, d, a, b, in[7] + 0x676f02d9, 14 ); - pmd5_step( F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20 ); - - pmd5_step( F3, a, b, c, d, in[5] + 0xfffa3942, 4 ); - pmd5_step( F3, d, a, b, c, in[8] + 0x8771f681, 11 ); - pmd5_step( F3, c, d, a, b, in[11] + 0x6d9d6122, 16 ); - pmd5_step( F3, b, c, d, a, in[14] + 0xfde5380c, 23 ); - pmd5_step( F3, a, b, c, d, in[1] + 0xa4beea44, 4 ); - pmd5_step( F3, d, a, b, c, in[4] + 0x4bdecfa9, 11 ); - pmd5_step( F3, c, d, a, b, in[7] + 0xf6bb4b60, 16 ); - pmd5_step( F3, b, c, d, a, in[10] + 0xbebfbc70, 23 ); - pmd5_step( F3, a, b, c, d, in[13] + 0x289b7ec6, 4 ); - pmd5_step( F3, d, a, b, c, in[0] + 0xeaa127fa, 11 ); - pmd5_step( F3, c, d, a, b, in[3] + 0xd4ef3085, 16 ); - pmd5_step( F3, b, c, d, a, in[6] + 0x04881d05, 23 ); - pmd5_step( F3, a, b, c, d, in[9] + 0xd9d4d039, 4 ); - pmd5_step( F3, d, a, b, c, in[12] + 0xe6db99e5, 11 ); - pmd5_step( F3, c, d, a, b, in[15] + 0x1fa27cf8, 16 ); - pmd5_step( F3, b, c, d, a, in[2] + 0xc4ac5665, 23 ); - - pmd5_step( F4, a, b, c, d, in[0] + 0xf4292244, 6 ); - pmd5_step( F4, d, a, b, c, in[7] + 0x432aff97, 10 ); - pmd5_step( F4, c, d, a, b, in[14] + 0xab9423a7, 15 ); - pmd5_step( F4, b, c, d, a, in[5] + 0xfc93a039, 21 ); - pmd5_step( F4, a, b, c, d, in[12] + 0x655b59c3, 6 ); - pmd5_step( F4, d, a, b, c, in[3] + 0x8f0ccc92, 10 ); - pmd5_step( F4, c, d, a, b, in[10] + 0xffeff47d, 15 ); - pmd5_step( F4, b, c, d, a, in[1] + 0x85845dd1, 21 ); - pmd5_step( F4, a, b, c, d, in[8] + 0x6fa87e4f, 6 ); - pmd5_step( F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10 ); - pmd5_step( F4, c, d, a, b, in[6] + 0xa3014314, 15 ); - pmd5_step( F4, b, c, d, a, in[13] + 0x4e0811a1, 21 ); - pmd5_step( F4, a, b, c, d, in[4] + 0xf7537e82, 6 ); - pmd5_step( F4, d, a, b, c, in[11] + 0xbd3af235, 10 ); - pmd5_step( F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15 ); - pmd5_step( F4, b, c, d, a, in[9] + 0xeb86d391, 21 ); - - out[0] += a; - out[1] += b; - out[2] += c; - out[3] += d; -} - -/* ####################################################################### */ - - -static int -sumFile( const char *name, int len, int whence, long offset ) -{ - int fd, i, cnt, readlen = 0; - unsigned char buf[0x1000]; - - if ((fd = open( name, O_RDONLY )) < 0) { - Debug( "cannot open entropy source %\"s: %m\n", name ); - return -1; - } - lseek( fd, offset, whence ); - while (readlen < len) { - if (!(cnt = read( fd, buf, sizeof(buf) ))) - break; - if (cnt < 0) { - close( fd ); - Debug( "cannot read entropy source %\"s: %m\n", name ); - return -1; - } - readlen += cnt; - if (sizeof(unsigned) == 4) - add_entropy( (unsigned *)buf, (cnt + 3) / 4 ); - else { - unsigned buf2[sizeof(buf) / 4]; - for (i = 0; i < cnt; i += 8) { - buf2[i / 4] = *(unsigned *)(buf + i) & 0xffffffff; - buf2[i / 4 + 1] = *(unsigned *)(buf + i) >> 32; - } - add_entropy( buf2, (cnt + 3) / 4 ); - } - } - close( fd ); - Debug( "read %d bytes from entropy source %\"s\n", readlen, name ); - return readlen; -} - -void -AddTimerEntropy( void ) -{ - struct timeval now; - gettimeofday( &now, 0 ); - add_entropy( (unsigned *)&now, sizeof(now)/sizeof(unsigned) ); -} - -#define BSIZ 0x10000 - -void -AddOtherEntropy( void ) -{ - AddTimerEntropy(); - /* XXX -- setup-specific ... use some common ones */ - sumFile( "/var/log/messages", 0x1000, SEEK_END, -0x1000 ); - sumFile( "/var/log/syslog", 0x1000, SEEK_END, -0x1000 ); - sumFile( "/var/log/debug", 0x1000, SEEK_END, -0x1000 ); - sumFile( "/var/log/kern.log", 0x1000, SEEK_END, -0x1000 ); - sumFile( "/var/log/daemon.log", 0x1000, SEEK_END, -0x1000 ); -/* root hardly ever has an own box ... maybe pick a random mailbox instead? eek ... - sumFile( "/var/spool/mail/root", 0x1000, SEEK_END, -0x1000 ); -*/ -} - -void -AddPreGetEntropy( void ) -{ - static long offset; - int readlen; - - AddTimerEntropy(); - if ((readlen = sumFile( randomFile, BSIZ, SEEK_SET, offset )) == BSIZ) { - offset += readlen; -#if defined(__i386__) || defined(amiga) - if (!strcmp( randomFile, "/dev/mem" )) { - if (offset == 0xa0000) /* skip 640kB-1MB ROM mappings */ - offset = 0x100000; - else if (offset == 0xf00000) /* skip 15-16MB memory hole */ - offset = 0x1000000; - } -#endif - return; - } else if (readlen >= 0 && offset) { - if ((offset = sumFile( randomFile, BSIZ, SEEK_SET, 0 )) == BSIZ) - return; - } - LogError( "Cannot read randomFile %\"s; " - "X cookies may be easily guessable\n", randomFile ); -} -#endif - -/* ONLY 8 or 16 bytes! */ -/* auth MUST be sizeof(unsigned)-aligned! */ -int -GenerateAuthData( char *auth, int len ) -{ -#ifdef HAVE_ARC4RANDOM - int i; - unsigned *rnd = (unsigned *)auth; - if (sizeof(unsigned) == 4) - for (i = 0; i < len; i += 4) - rnd[i / 4] = arc4random(); - else - for (i = 0; i < len; i += 8) - rnd[i / 8] = arc4random() | (arc4random() << 32); - return 1; -#else - int fd; - const char *rd = randomDevice; -# ifdef DEV_RANDOM - if (!*rd) - rd = DEV_RANDOM; -# else - if (*rd) { -# endif - if ((fd = open( rd, O_RDONLY )) >= 0) { - if (read( fd, auth, len ) == len) { - close( fd ); - return 1; - } - close( fd ); - LogError( "Cannot read randomDevice %\"s: %m\n", rd ); - } else - LogError( "Cannot open randomDevice %\"s: %m\n", rd ); -# ifdef DEV_RANDOM - return 0; -# else - } - - if (!getPrngdBytes( auth, len, prngdPort, prngdSocket )) - return 1; - - { - unsigned *rnd = (unsigned *)auth; - unsigned tmp[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; - AddPreGetEntropy(); - pmd5_hash( tmp, epool ); - add_entropy( tmp, 1 ); - pmd5_hash( tmp, epool + 16 ); - add_entropy( tmp + 2, 1 ); - if (sizeof(unsigned) == 4) - memcpy( auth, tmp, len ); - else { - int i; - for (i = 0; i < len; i += 8) - rnd[i / 8] = tmp[i / 4] | (tmp[i / 4 + 1] << 32); - } - } - return 1; -# endif -#endif -} - -#ifndef HAVE_ARC4RANDOM -int -secureRandom( void ) -{ - int rslt; - GenerateAuthData( (char *)&rslt, sizeof(int) ); - return rslt & 0x7fffffff; -} -#endif
\ No newline at end of file diff --git a/kdm/backend/greet.h b/kdm/backend/greet.h deleted file mode 100644 index 985edc29c..000000000 --- a/kdm/backend/greet.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - -Copyright 2001-2005 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * interface to xdm's external greeter and config reader - */ - -#ifndef GREET_H -#define GREET_H - -#include <config.h> - -#define DEBUG_CORE 0x01 -#define DEBUG_CONFIG 0x02 -#define DEBUG_GREET 0x04 -#define DEBUG_HLPCON 0x08 -#define DEBUG_WSESS 0x10 -#define DEBUG_WCONFIG 0x20 -#define DEBUG_WGREET 0x40 -#define DEBUG_NOSYSLOG 0x80 -#define DEBUG_AUTH 0x100 -#define DEBUG_VALGRIND 0x400 -#define DEBUG_STRACE 0x800 - -#ifndef TRUE -# define TRUE 1 -# define FALSE 0 -#endif - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) -# define ATTR_UNUSED __attribute__((unused)) -# define ATTR_NORETURN __attribute__((noreturn)) -# define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) -#else -# define ATTR_UNUSED -# define ATTR_NORETURN -# define ATTR_PRINTFLIKE(fmt,var) -#endif - -#define as(ar) ((int)(sizeof(ar)/sizeof(ar[0]))) - -#define __stringify(x) #x -#define stringify(x) __stringify(x) - -/* - * Exit codes for fork()ed session process, greeter, and config reader - */ -#define EX_NORMAL 30 /* do whatever seems appropriate */ -#define EX_REMANAGE_DPY 31 /* force remanage; same as EX_NORMAL, but cannot return to reserve mode immediately */ -#define EX_UNMANAGE_DPY 32 /* force deletion */ -#define EX_RESERVER_DPY 33 /* force server termination */ -#define EX_AL_RESERVER_DPY 34 /* reserver; maybe, auto-(re-)login */ -#define EX_OPENFAILED_DPY 35 /* XOpenDisplay failed, retry */ -#define EX_RESERVE 37 /* put in reserve mode */ -#ifdef XDMCP -#define EX_REMOTE 38 /* start -query-ing X-server */ -#define EX_MAX EX_REMOTE -#else -#define EX_MAX EX_RESERVE -#endif - -/* - * Command codes core -> greeter - */ -#define G_Greet 1 /* get login; bidi */ -#define G_ErrorGreet 2 /* print failed auto-login */ -#ifdef XDMCP -#define G_Choose 3 /* run chooser; bidi */ -# define G_Ch_AddHost 301 -# define G_Ch_ChangeHost 302 -# define G_Ch_RemoveHost 303 -# define G_Ch_BadHost 304 -# define G_Ch_Exit 305 -#endif -#define G_SessMan 4 /* start "session manager" */ -#define G_ConfShutdown 5 /* confirm forced shutdown */ -#define G_GreetTimed 6 /* get login; timed login permitted */ - -#ifdef XDMCP -#define G_Ch_Refresh 10 /* XXX change */ -#define G_Ch_RegisterHost 11 /* str name XXX change */ -#define G_Ch_DirectChoice 12 /* str name XXX change */ -#endif - -/* - * Status/command codes greeter -> core - */ -#define G_Ready 0 /* nop */ -#define G_Cancel 1 /* abort login, etc. */ - -#define G_DGreet 2 /* get login */ -#ifdef XDMCP -#define G_DChoose 3 /* run chooser */ -#endif - -#define G_Shutdown 101 /* 5*int, string; async */ -# define SHUT_REBOOT 1 /* how */ -# define SHUT_HALT 2 -# define SHUT_CONSOLE -1 /* pseudo-code */ -# define SHUT_SCHEDULE 0 /* when; config only */ -# define SHUT_TRYNOW 1 -# define SHUT_FORCENOW 2 -# define SHUT_CANCEL 0 /* force */ -# define SHUT_FORCEMY 1 -# define SHUT_FORCE 2 -# define SHUT_ASK 3 -# define TO_INF 0x7fffffff -#define G_SessionExit 102 /* int code; async */ -#define G_GetCfg 103 /* int what; int sts, <variable> */ -#define G_SetupDpy 104 /* ; int <syncer> */ -#define G_ReadDmrc 105 /* str user; int sts - curdmrc */ -#define G_GetDmrc 106 /* str key; str value - curdmrc */ -/*#define G_ResetDmrc 107*/ /* ; async - newdmrc */ -#define G_PutDmrc 108 /* str key, str value; async - newdmrc */ -#define G_Verify 109 /* str type; ..., int V_ret */ -#define G_VerifyRootOK 110 /* str type; ..., int V_ret */ -#define G_List 111 /* int flags; ?*(str,str,[int,]str,str,int), int 0 */ -# define lstRemote 1 -# define lstPassive 2 -# define lstTTY 4 -# define isSelf 1 -# define isTTY 2 -#define G_QueryShutdown 112 /* ; 5*int; string */ -#define G_Activate 113 /* int vt; async */ -#define G_ListBootOpts 114 /* ; int sts, [argv opts, int dflt, int cur] */ -# define BO_OK 0 -# define BO_NOMAN -1 -# define BO_NOENT -2 -# define BO_IO -3 -#define G_Console 116 /* ; async */ -#define G_AutoLogin 117 /* ; async */ - -/* - * Command codes core -> config reader - */ -#define GC_Files 1 /* get file list */ -#define GC_GetConf 2 /* get a config group */ -# define GC_gGlobal 1 /* get global config array */ -#ifdef XDMCP -# define GC_gXaccess 3 /* get Xaccess equivalent */ -#endif -# define GC_gDisplay 4 /* get per-display config array */ - -/* - * Error code core -> greeter - */ -#define GE_Ok 0 -#define GE_NoFkt 1 /* no such function (only for extensions!) */ -#define GE_Error 2 /* internal error, like OOM */ -/* for config reading */ -#define GE_NoEnt 10 /* no such config entry */ -#define GE_BadType 11 /* unknown config entry type */ -/* for dmrc reading */ -#define GE_NoUser 20 /* no such user */ -#define GE_NoFile 21 /* no such file */ -#define GE_Denied 22 /* permission denied */ - -/* - * Log levels. - * Used independently in core, greeter & config reader. - */ -#define DM_DEBUG 0 -#define DM_INFO 1 -#define DM_WARN 2 -#define DM_ERR 3 -#define DM_PANIC 4 - -/* - * Status codes from Verify - */ -/* terminal status codes */ -#define V_OK 0 -#define V_FAIL 10 /* whatever, already reported with V_MSG_* */ -#define V_AUTH 11 /* authentication failed */ -/* non-terminal status codes */ -#define V_MSG_INFO 110 /* info message attached */ -#define V_MSG_ERR 111 /* error message attached (null for generic) */ -#define V_PUT_USER 112 /* user name attached; only with pam & no user send */ -#define V_CHTOK 113 /* password expired; change now */ -#define V_CHTOK_AUTH 114 /* password expired; change now, but authenticate first */ -#define V_PRE_OK 115 /* authentication succeeded, continue with password change */ -/* queries */ -#define V_GET_TEXT 200 /* str prompt, int echo, int ndelay; str return, int tag */ -# define V_IS_SECRET 1 -# define V_IS_USER 2 -# define V_IS_PASSWORD 4 -# define V_IS_OLDPASSWORD 8 -# define V_IS_NEWPASSWORD 16 -#define V_GET_BINARY 201 /* array prompt, int ndelay; array return */ - -/* - * Config/Runtime data keys - */ -#define C_WHO_MASK 0x00ff0000 /* Non-zero for proprietary extensions (see manufacturer table [to be written]) */ -#define C_TYPE_MASK 0x0f000000 /* Type of the value */ -# define C_TYPE_INT 0x00000000 /* Integer */ -# define C_TYPE_STR 0x01000000 /* String */ -# define C_TYPE_ARGV 0x02000000 /* 0-terminated Array of Strings */ -# define C_TYPE_ARR 0x03000000 /* Array (only when XDCMP is enabled) */ -#define C_PRIVATE 0xf0000000 /* Private, don't make it visible to interfaces! */ - -/* display variables */ -#define C_isLocal (C_TYPE_INT | 0x200) -#define C_hasConsole (C_TYPE_INT | 0x201) -#define C_isAuthorized (C_TYPE_INT | 0x202) - -/** - ** for struct display - **/ - -#define d_location 1 -#define dLocal 1 /* server runs on local host */ -#define dForeign 0 /* server runs on remote host */ - -#define d_lifetime 6 -#define dPermanent 4 /* display restarted when session exits */ -#define dReserve 2 /* display not restarted when session exits */ -#define dTransient 0 /* display removed when session exits */ - -#ifdef XDMCP -#define d_origin 8 -#else -#define d_origin 0 /* clever, huh? :) */ -#endif -#define dFromXDMCP 8 /* started with XDMCP */ -#define dFromFile 0 /* started via entry in servers file */ - -#ifdef XDMCP -/** - ** for xdmcp acls - **/ - -/* - * flags in acl entries - */ -#define a_notAllowed 1 /* both direct and indirect */ -#define a_notBroadcast 2 /* only direct */ -#define a_useChooser 2 /* only indirect */ - -/* - * type of host entries - */ -#define HOST_ALIAS 0 -#define HOST_ADDRESS 1 -#define HOST_PATTERN 2 -#define HOST_BROADCAST 3 - -#endif - -#endif /* GREET_H */ diff --git a/kdm/backend/inifile.c b/kdm/backend/inifile.c deleted file mode 100644 index b5426de75..000000000 --- a/kdm/backend/inifile.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - -Copyright 2003 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * load, save and manipulate ini-style config files - */ - -#include "dm.h" -#include "dm_error.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> - -char * -iniLoad( const char *fname ) -{ - char *data; - int fd, len; - struct stat st; - - if ((fd = open( fname, O_RDONLY | O_NONBLOCK )) < 0) { - Debug( "cannot open ini-file %\"s: %m", fname ); - return 0; - } - if (fstat( fd, &st ) || !S_ISREG( st.st_mode )) { - LogWarn( "Ini-file %\"s is no regular file\n", fname ); - close( fd ); - return 0; - } - if (st.st_size >= 0x10000) { - LogWarn( "Ini-file %\"s is too big\n", fname ); - close( fd ); - return 0; - } - len = st.st_size; - if (!(data = Malloc( len + 2 ))) { - close( fd ); - return 0; - } - if (read( fd, data, len ) != len) { - Debug( "cannot read ini-file %\"s: %m", fname ); - free( data ); - close( fd ); - return 0; - } - close( fd ); - if (data[len - 1] != '\n') - data[len++] = '\n'; - data[len] = 0; - return data; -} - -int -iniSave( const char *data, const char *fname ) -{ - int fd, cnt, len; - - if ((fd = open( fname, O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, 0600 )) < 0) { - Debug( "cannot create ini-file %\"s: %m", fname ); - return 0; - } - len = strlen( data ); - if ((cnt = write( fd, data, len )) == len) { - close( fd ); - return 1; - } - if (cnt == -1) - Debug( "cannot write ini-file %\"s: %m", fname ); - else - Debug( "cannot write ini-file %\"s: partial write", fname ); - close( fd ); - return 0; -} - -#define apparr(d,s,n) do { memcpy (d, s, n); d += n; } while(0) -#define appbyte(d,b) *d++ = b - -char * -iniEntry( char *data, const char *section, const char *key, const char *value ) -{ - char *p = data, *secinsert = 0, *pastinsert = 0, *cb, *ce, *ndata; - const char *t; - int insect = 0, ll, sl, kl, vl, len, nlen; - - if (p) { - while (*p) { - for (; *p == ' ' || *p == '\t'; p++); - if (*p == '\n') { - p++; - continue; - } - if (*p == '[') { - for (t = section; *++p == *t; t++); - insect = !*t && *p == ']'; - } else if (insect) { - for (t = key; *p == *t; t++, p++); - for (; *p == ' ' || *p == '\t'; p++); - if (!*t && *p == '=') { - for (p++; *p == ' ' || *p == '\t'; p++); - cb = p; - while (*p++ != '\n'); - ce = p; - if (value) { - ll = sl = kl = 0; - len = (ce - data) + strlen( ce ); - goto insert; - } else { - for (ce--; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--); - if (!StrNDup( &p, cb, ce - cb )) - return 0; - return p; - } - } - } - for (; *p != '\n'; p++); - p++; - if (insect) - secinsert = p; - else - pastinsert = p; - } - } - if (!value) - return 0; - len = p - data; - if (secinsert) { - ce = cb = secinsert; - sl = ll = 0; - } else { - sl = strlen( section ) + 3; - if (pastinsert) { - ce = cb = pastinsert; - ll = 1; - } else { - ce = cb = data; - ll = 0; - } - } - kl = strlen( key ) + 1; - insert: - vl = strlen( value ); - nlen = len - (ce - cb) + ll + sl + kl + vl + 1; - if (!(p = ndata = Malloc( nlen + 1 ))) - return data; - apparr( p, data, cb - data ); - if (kl) { - if (sl) { - if (ll) - appbyte( p, '\n' ); - appbyte( p, '[' ); - apparr( p, section, sl - 3 ); - appbyte( p, ']' ); - appbyte( p, '\n' ); - } - apparr( p, key, kl - 1 ); - appbyte( p, '=' ); - } - apparr( p, value, vl ); - appbyte( p, '\n' ); - if (data) { - apparr( p, ce, len - (ce - data) ); - free( data ); - } - appbyte( p, 0 ); - return ndata; -} - -char * -iniMerge( char *data, const char *newdata ) -{ - const char *p, *cb, *ce; - char *section = 0, *key, *value; - - if (!newdata) - return data; - for (p = newdata;;) { - for (; *p == ' ' || *p == '\t'; p++); - if (!*p) - break; - if (*p == '\n') { - p++; - continue; - } - if (*p == '#') { - for (p++; *p != '\n'; p++) - if (!*p) - goto bail; - p++; - continue; - } - if (*p == '[') { - cb = ++p; - for (; *p != ']'; p++) - if (!*p || *p == '\n') /* missing ] */ - goto bail; - if (!ReStrN( §ion, cb, p - cb )) - break; - p++; - } else { - cb = p; - for (; *p != '='; p++) - if (!*p || *p == '\n') /* missing = */ - goto bail; - for (ce = p; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--); - if (!StrNDup( &key, cb, ce - cb )) - break; - for (p++; *p == ' ' || *p == '\t'; p++); - cb = p; - for (; *p && *p != '\n'; p++); - for (ce = p; ce != cb && (*(ce - 1) == ' ' || *(ce - 1) == '\t'); ce--); - if (!StrNDup( &value, cb, ce - cb )) - break; - if (section) - data = iniEntry( data, section, key, value ); - free( value ); - free( key ); - } - } - bail: - if (section) - free( section ); - return data; -} diff --git a/kdm/backend/krb5auth.c b/kdm/backend/krb5auth.c deleted file mode 100644 index 16b640a35..000000000 --- a/kdm/backend/krb5auth.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - -Copyright 1994, 1998 The Open Group -Copyright 2003 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Stephen Gildea, The Open Group - * - * generate Kerberos Version 5 authorization records - */ - -#include <config.h> - -#ifdef K5AUTH - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include <sys/types.h> -#include <sys/stat.h> - -#include <krb5/krb5.h> - -static krb5_context ctx; - -/*ARGSUSED*/ -void -Krb5InitAuth( unsigned short name_len ATTR_UNUSED, const char *name ATTR_UNUSED ) -{ - if (krb5_init_context( &ctx )) - LogError( "Error while initializing Krb5 context\n" ); -} - -/* - * Returns malloc'ed string that is the credentials cache name. - * name should be freed by caller. - */ -static char * -Krb5CCacheName( const char *dname ) -{ - char *name; - const char *tmpdir; - int dnl, nl; - - tmpdir = getenv( "TMPDIR" ); - if (!tmpdir) - tmpdir = "/tmp"; - dnl = strlen( dname ); - name = Malloc( strlen( tmpdir ) + dnl + 20 ); - if (!name) - return NULL; - nl = sprintf( name, "FILE:%s/K5C", tmpdir ); - CleanUpFileName( dname, name + nl, dnl + 1 ); - return name; -} - -Xauth * -Krb5GetAuthFor( unsigned short namelen, const char *name, const char *dname ) -{ - Xauth *new; - char *filename; - - if (!(new = (Xauth *)Malloc( sizeof(*new) ))) - return (Xauth *)0; - new->family = FamilyWild; - new->address_length = 0; - new->address = 0; - new->number_length = 0; - new->number = 0; - - if (dname) { - if (!(filename = Krb5CCacheName( dname ))) { - free( (char *)new ); - return (Xauth *)0; - } - new->data = 0; - if (!StrApp( &new->data, "UU:", filename, (char *)0 )) { - free( filename ); - free( (char *)new ); - return (Xauth *)0; - } - free( filename ); - new->data_length = strlen( new->data ); - } else { - new->data = NULL; - new->data_length = 0; - } - - if (!(new->name = (char *)Malloc( namelen ))) { - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - memmove( new->name, name, namelen ); - new->name_length = namelen; - return new; -} - - -Xauth * -Krb5GetAuth( unsigned short namelen, const char *name ) -{ - return Krb5GetAuthFor( namelen, name, NULL ); -} - - -static krb5_error_code -Krb5DisplayCCache( const char *dname, krb5_ccache *ccache_return, char **name ) -{ - char *ccname; - krb5_error_code code; - - if (!(ccname = Krb5CCacheName( dname ))) - return ENOMEM; - Debug( "resolving Kerberos cache %s\n", ccname ); - if ((code = krb5_cc_resolve( ctx, ccname, ccache_return )) || !name) - free( ccname ); - else - *name = ccname; - return code; -} - -char * -Krb5Init( const char *user, const char *passwd, const char *dname ) -{ - krb5_error_code code; - krb5_get_init_creds_opt options; - krb5_principal me; - krb5_creds my_creds; - krb5_ccache ccache; - char *ccname; - - if (!ctx) - return 0; - - if ((code = krb5_parse_name( ctx, user, &me ))) { - LogError( "%s while parsing Krb5 user %\"s\n", - error_message( code ), user ); - return 0; - } - - krb5_get_init_creds_opt_init( &options ); - /*krb5_get_init_creds_opt_set_tkt_life (&options, 60*60*8);*/ /* 8 hours */ - - if ((code = krb5_get_init_creds_password( ctx, &my_creds, - me, /* principal */ - (char * /* for MIT */) passwd, - 0, /* prompter */ - 0, /* prompter ctx */ - 0, /* start time delta */ - 0, /* service */ - &options ))) - { - char *my_name = NULL; - int code2 = krb5_unparse_name( ctx, me, &my_name ); - if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) - LogError( "Password incorrect for Krb5 principal %\"s\n", - code2 ? user : my_name ); - else - LogError( "%s while getting initial Krb5 credentials for %\"s\n", - error_message( code ), code2 ? user : my_name ); - if (my_name) - free( my_name ); - goto err3; - } - - if ((code = Krb5DisplayCCache( dname, &ccache, &ccname ))) { - LogError( "%s while getting Krb5 ccache for %\"s\n", - error_message( code ), dname ); - goto err2; - } - - if ((code = krb5_cc_initialize( ctx, ccache, me ))) { - LogError( "%s while initializing Krb5 cache %\"s\n", - error_message( code ), ccname ); - goto err1; - } - - if ((code = krb5_cc_store_cred( ctx, ccache, &my_creds ))) { - LogError( "%s while storing Krb5 credentials to cache %\"s\n", - error_message( code ), ccname ); - err1: - krb5_cc_close( ctx, ccache ); - free( ccname ); - err2: - krb5_free_cred_contents( ctx, &my_creds ); - err3: - krb5_free_principal( ctx, me ); - return 0; - } - - krb5_cc_close( ctx, ccache ); - krb5_free_cred_contents( ctx, &my_creds ); - krb5_free_principal( ctx, me ); - return ccname; -} - -void -Krb5Destroy( const char *dname ) -{ - krb5_error_code code; - krb5_ccache ccache; - - if (!ctx) - return; - - if ((code = Krb5DisplayCCache( dname, &ccache, 0 ))) - LogError( "%s while getting Krb5 ccache to destroy\n", - error_message( code ) ); - else { - if ((code = krb5_cc_destroy( ctx, ccache ))) { - if (code == KRB5_FCC_NOFILE) - Debug( "no Kerberos ccache file found to destroy\n" ); - else - LogError( "%s while destroying Krb5 credentials cache\n", - error_message( code ) ); - } else - Debug( "kerberos ccache destroyed\n" ); - } -} - -#endif diff --git a/kdm/backend/mitauth.c b/kdm/backend/mitauth.c deleted file mode 100644 index fd18d41df..000000000 --- a/kdm/backend/mitauth.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2003 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * generate authorization keys - * for MIT-MAGIC-COOKIE-1 type authorization - */ - -#include "dm.h" -#include "dm_auth.h" - -#define AUTH_DATA_LEN 16 /* bytes of authorization data */ -static char auth_name[256]; - -void -MitInitAuth( unsigned short name_len, const char *name ) -{ - if (name_len > 256) - name_len = 256; - memmove( auth_name, name, name_len ); -} - -Xauth * -MitGetAuth( unsigned short namelen, const char *name ) -{ - Xauth *new; - new = (Xauth *)Malloc( sizeof(Xauth) ); - - if (!new) - return (Xauth *)0; - new->family = FamilyWild; - new->address_length = 0; - new->address = 0; - new->number_length = 0; - new->number = 0; - - new->data = (char *)Malloc( AUTH_DATA_LEN ); - if (!new->data) { - free( (char *)new ); - return (Xauth *)0; - } - new->name = (char *)Malloc( namelen ); - if (!new->name) { - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - memmove( (char *)new->name, name, namelen ); - new->name_length = namelen; - if (!GenerateAuthData( new->data, AUTH_DATA_LEN )) { - free( (char *)new->name ); - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - new->data_length = AUTH_DATA_LEN; - return new; -} diff --git a/kdm/backend/netaddr.c b/kdm/backend/netaddr.c deleted file mode 100644 index 349a53528..000000000 --- a/kdm/backend/netaddr.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - -Copyright 1991, 1998 The Open Group -Copyright 2002 Sun Microsystems, Inc. All rights reserved. - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * netaddr.c - Interpretation of XdmcpNetaddr object. - */ - -#include "dm.h" -#include "dm_socket.h" -#include "dm_error.h" - -/* given an char *, returns the socket protocol family used, - e.g., AF_INET */ - -int -NetaddrFamily( char *netaddrp ) -{ -#ifdef STREAMSCONN - short family = *(short *)netaddrp; - return family; -#else - return ((struct sockaddr *)netaddrp)->sa_family; -#endif -} - - -/* given an char *, returns a pointer to the TCP/UDP port used - and sets *lenp to the length of the address - or 0 if not using TCP or UDP. */ - -char * -NetaddrPort( char *netaddrp, int *lenp ) -{ -#ifdef STREAMSCONN - *lenp = 2; - return netaddrp+2; -#else - switch (NetaddrFamily( netaddrp )) - { - case AF_INET: - *lenp = 2; - return (char *)&(((struct sockaddr_in *)netaddrp)->sin_port); -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - *lenp = 2; - return (char *)&(((struct sockaddr_in6 *)netaddrp)->sin6_port); -#endif - default: - *lenp = 0; - return NULL; - } -#endif -} - - -/* given an char *, returns a pointer to the network address - and sets *lenp to the length of the address */ - -char * -NetaddrAddress( char *netaddrp, int *lenp ) -{ -#ifdef STREAMSCONN - *lenp = 4; - return netaddrp+4; -#else - switch (NetaddrFamily( netaddrp )) { -#ifdef UNIXCONN - case AF_UNIX: - *lenp = strlen( ((struct sockaddr_un *)netaddrp)->sun_path ); - return (char *)(((struct sockaddr_un *)netaddrp)->sun_path); -#endif -#ifdef TCPCONN - case AF_INET: - *lenp = sizeof(struct in_addr); - return (char *)&(((struct sockaddr_in *)netaddrp)->sin_addr); -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - { - struct in6_addr *a = &(((struct sockaddr_in6 *)netaddrp)->sin6_addr); - if (IN6_IS_ADDR_V4MAPPED( a )) { - *lenp = sizeof(struct in_addr); - return ((char *)&(a->s6_addr))+12; - } else { - *lenp = sizeof(struct in6_addr); - return (char *)&(a->s6_addr); - } - } -#endif -#endif -#ifdef DNETCONN - case AF_DECnet: - *lenp = sizeof(struct dn_naddr); - return (char *)&(((struct sockaddr_dn *)netaddrp)->sdn_add); -#endif -#ifdef AF_CHAOS - case AF_CHAOS: -#endif - default: - *lenp = 0; - return NULL; - } -#endif /* STREAMSCONN else */ -} - - -/* given an char *, sets *addr to the network address used and - sets *len to the number of bytes in addr. - Returns the X protocol family used, e.g., FamilyInternet */ - -int -ConvertAddr( char *saddr, int *len, char **addr ) -{ - int retval; - - if (len == NULL) - return -1; - *addr = NetaddrAddress( saddr, len ); -#ifdef STREAMSCONN - /* kludge */ - if (NetaddrFamily( saddr ) == 2) - retval = FamilyInternet; -#else - switch (NetaddrFamily( saddr )) { -#ifdef AF_UNSPEC - case AF_UNSPEC: - retval = FamilyLocal; - break; -#endif -#ifdef AF_UNIX -#ifndef __hpux - case AF_UNIX: - retval = FamilyLocal; - break; -#endif -#endif -#ifdef TCPCONN - case AF_INET: - retval = FamilyInternet; - break; -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - if (*len == sizeof(struct in_addr)) - retval = FamilyInternet; - else - retval = FamilyInternet6; - break; -#endif -#endif -#ifdef DNETCONN - case AF_DECnet: - retval = FamilyDECnet; - break; -#endif -#ifdef AF_CHAOS - case AF_CHAOS: - retval = FamilyChaos; - break; -#endif - default: - retval = -1; - break; - } -#endif /* STREAMSCONN else */ - Debug( "ConvertAddr returning %d for family %d\n", retval, - NetaddrFamily( saddr ) ); - return retval; -} - -#ifdef XDMCP -int -addressEqual( char *a1, int len1, char *a2, int len2 ) -{ - int partlen1, partlen2; - char *part1, *part2; - - if (len1 != len2) - return FALSE; - if (NetaddrFamily( a1 ) != NetaddrFamily( a2 )) - return FALSE; - part1 = NetaddrPort( a1, &partlen1 ); - part2 = NetaddrPort( a2, &partlen2 ); - if (partlen1 != partlen2 || memcmp( part1, part2, partlen1 ) != 0) - return FALSE; - part1 = NetaddrAddress( a1, &partlen1 ); - part2 = NetaddrAddress( a2, &partlen2 ); - if (partlen1 != partlen2 || memcmp( part1, part2, partlen1 ) != 0) - return FALSE; - return TRUE; -} -#endif diff --git a/kdm/backend/policy.c b/kdm/backend/policy.c deleted file mode 100644 index cabee7088..000000000 --- a/kdm/backend/policy.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2001 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * policy.c. Implement site-dependent policy for XDMCP connections - */ - -#include <config.h> - -#ifdef XDMCP - -#include "dm.h" -#include "dm_auth.h" -#include "dm_socket.h" - -static ARRAY8 noAuthentication = { (CARD16)0, (CARD8Ptr) 0 }; - -typedef struct _XdmAuth { - ARRAY8 authentication; - ARRAY8 authorization; -} XdmAuthRec, *XdmAuthPtr; - -static XdmAuthRec auth[] = { -#ifdef HASXDMAUTH -{ {(CARD16)20, (CARD8 *)"XDM-AUTHENTICATION-1"}, - {(CARD16)19, (CARD8 *)"XDM-AUTHORIZATION-1"}, -}, -#endif -{ {(CARD16)0, (CARD8 *)0}, - {(CARD16)0, (CARD8 *)0}, -} -}; - -#define NumAuth as(auth) - -ARRAY8Ptr -ChooseAuthentication( ARRAYofARRAY8Ptr authenticationNames ) -{ - int i, j; - - for (i = 0; i < (int)authenticationNames->length; i++) - for (j = 0; j < NumAuth; j++) - if (XdmcpARRAY8Equal( &authenticationNames->data[i], - &auth[j].authentication )) - return &authenticationNames->data[i]; - return &noAuthentication; -} - -int -CheckAuthentication( - struct protoDisplay *pdpy ATTR_UNUSED, - ARRAY8Ptr displayID ATTR_UNUSED, - ARRAY8Ptr name ATTR_UNUSED, - ARRAY8Ptr data ATTR_UNUSED ) -{ -#ifdef HASXDMAUTH - if (name->length && !memcmp( (char *)name->data, "XDM-AUTHENTICATION-1", 20 )) - return XdmCheckAuthentication( pdpy, displayID, name, data ); -#endif - return TRUE; -} - -int -SelectAuthorizationTypeIndex( ARRAY8Ptr authenticationName, - ARRAYofARRAY8Ptr authorizationNames ) -{ - int i, j; - - for (j = 0; j < NumAuth; j++) - if (XdmcpARRAY8Equal( authenticationName, - &auth[j].authentication )) - break; - if (j < NumAuth) - for (i = 0; i < (int)authorizationNames->length; i++) - if (XdmcpARRAY8Equal( &authorizationNames->data[i], - &auth[j].authorization )) - return i; - for (i = 0; i < (int)authorizationNames->length; i++) - if (ValidAuthorization( authorizationNames->data[i].length, - (char *)authorizationNames->data[i].data )) - return i; - return -1; -} - - -/*#define WILLING_INTERNAL*/ - -#ifdef WILLING_INTERNAL -/* Report the loadavg to chooser. Nice feature ... - * - * Wed Mar 10 1999 -- Steffen Hansen - */ -static void -Willing_msg( char *mbuf ) -{ -#ifdef __linux__ - int fd; - int numcpu; - const char *fail_msg = "Willing to manage"; - FILE *f; - float load[3]; - float mhz = 0.0; - char buf[1024]; - - fd = open( "/proc/loadavg", O_RDONLY ); - if (fd == -1) { - sprintf( mbuf, fail_msg ); - return; - } else if (read( fd, buf, 100 ) < 4) { - close( fd ); - sprintf( mbuf, fail_msg ); - return; - } - close( fd ); - - sscanf( buf, "%f %f %f", &load[0], &load[1], &load[2] ); - sprintf( mbuf, "Available (load: %0.2f, %0.2f, %0.2f)", - load[0], load[1], load[2] ); - - numcpu = 0; - - if (!(f = fopen( "/proc/cpuinfo", "r" ))) - return; - - while (fGets( buf, sizeof(buf), f ) != -1) { - float m; - if (sscanf( buf, "cpu MHz : %f", &m )) { - numcpu++; - mhz = m; - } - } - - fclose( f ); - - if (numcpu) { - if (numcpu > 1) - sprintf( buf, " %d*%0.0f MHz", numcpu, mhz ); - else - sprintf( buf, " %0.0f MHz", mhz ); - - strncat( mbuf, buf, 256 ); - - mbuf[255] = 0; - } -#elif HAVE_GETLOADAVG /* !__linux__ */ -#ifdef __GNUC__ -# warning This code is untested... -#endif - double load[3]; - getloadavg( load, 3 ); - sprintf( mbuf, "Available (load: %0.2f, %0.2f, %0.2f)", load[0], - load[1], load[2] ); -#else /* !__linux__ && !GETLOADAVG */ - strcpy( mbuf, "Willing to manage" ); -#endif -} -#endif - -/*ARGSUSED*/ -int -Willing( ARRAY8Ptr addr, CARD16 connectionType, - ARRAY8Ptr authenticationName ATTR_UNUSED, - ARRAY8Ptr status, xdmOpCode type ) -{ - int ret; - char statusBuf[256]; - static time_t lastscan; - - if (autoRescan && lastscan + 15 < now) { - lastscan = now; - ScanAccessDatabase( FALSE ); - } - ret = AcceptableDisplayAddress( addr, connectionType, type ); - if (!ret) - sprintf( statusBuf, "Display not authorized to connect" ); - else { - if (*willing) { - FILE *fd; - int len, ok = 0; - if ((fd = popen( willing, "r" ))) { - for (;;) { - if ((len = fGets( statusBuf, sizeof(statusBuf), fd )) != -1) { - if (len) { - ok = 1; - break; - } - } - if (feof( fd ) || errno != EINTR) - break; - } - pclose( fd ); - } - if (!ok) - sprintf( statusBuf, "Willing, but %.*s failed", - sizeof(statusBuf) - 21, willing ); - } else -#ifdef WILLING_INTERNAL - Willing_msg( statusBuf ); -#else - strcpy( statusBuf, "Willing to manage" ); -#endif - } - status->length = strlen( statusBuf ); - status->data = (CARD8Ptr) Malloc( status->length ); - if (!status->data) - status->length = 0; - else - memmove( status->data, statusBuf, status->length ); - return ret; -} - -/*ARGSUSED*/ -ARRAY8Ptr -Accept( struct sockaddr *from ATTR_UNUSED, int fromlen ATTR_UNUSED, - CARD16 displayNumber ATTR_UNUSED ) -{ - return 0; -} - -/*ARGSUSED*/ -int -SelectConnectionTypeIndex( ARRAY16Ptr connectionTypes, - ARRAYofARRAY8Ptr connectionAddresses ATTR_UNUSED ) -{ - int i; - - /* - * Select one supported connection type - */ - - for (i = 0; i < connectionTypes->length; i++) { - switch (connectionTypes->data[i]) { - case FamilyLocal: -#if defined(TCPCONN) - case FamilyInternet: -# if defined(IPv6) && defined(AF_INET6) - case FamilyInternet6: -# endif /* IPv6 */ -#endif /* TCPCONN */ -#if defined(DNETCONN) - case FamilyDECnet: -#endif /* DNETCONN */ - return i; - } - } /* for */ - return -1; -} - -#endif /* XDMCP */ diff --git a/kdm/backend/printf.c b/kdm/backend/printf.c deleted file mode 100644 index d7220642b..000000000 --- a/kdm/backend/printf.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - -Copyright 2001,2002,2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * printf.c - working horse of error.c - */ - -/* - * NOTE: this file is meant to be included, not linked, - * so it can be used in the helper programs without much voodoo. - */ - -/* ########## printf core implementation with some extensions ########## */ -/* - * How to use the extensions: - * - put ' or " in the flags field to quote a string with this char and - * escape special characters (only available, if PRINT_QUOTES is defined) - * - put \\ in the flags field to quote special characters and leading and - * trailing spaces (only available, if PRINT_QUOTES is defined) - * - arrays (only available, if PRINT_ARRAYS is defined) - * - the array modifier [ comes after the maximal field width specifier - * - the array length can be specified literally, with the '*' modifier - * (in which case an argument is expected) or will be automatically - * determined (stop values are -1 for ints and 0 for strings) - * - these modifiers expect their argument to be an in-line string quoted - * with an arbitrary character: - * - (, ) -> array pre-/suf-fix; default "" - * - <, > -> element pre-/suf-fix; default "" - * - | -> element separator; default " " - * - these modifiers expect no argument: - * - : -> print '<number of elements>: ' before an array - * - , -> short for |',' - * - { -> short for ('{')' }'<' '|'' - * - the pointer to the array is the last argument to the format - * - the %m conversion from syslog() is supported - */ - -/************************************************************** - * Partially stolen from OpenSSH's OpenBSD compat directory. - * (C) Patrick Powell, Brandon Long, Thomas Roessler, - * Michael Elkins, Ben Lindstrom - **************************************************************/ - -#include <ctype.h> -#include <string.h> -#include <stdarg.h> - -/* format flags - Bits */ -#define DP_F_MINUS (1 << 0) -#define DP_F_PLUS (1 << 1) -#define DP_F_SPACE (1 << 2) -#define DP_F_NUM (1 << 3) -#define DP_F_ZERO (1 << 4) -#define DP_F_UPCASE (1 << 5) -#define DP_F_UNSIGNED (1 << 6) -#define DP_F_SQUOTE (1 << 7) -#define DP_F_DQUOTE (1 << 8) -#define DP_F_BACKSL (1 << 9) -#define DP_F_ARRAY (1 << 10) -#define DP_F_COLON (1 << 11) - -/* Conversion Flags */ -#define DP_C_INT 0 -#define DP_C_BYTE 1 -#define DP_C_SHORT 2 -#define DP_C_LONG 3 -#define DP_C_STR 10 - -typedef void (*OutCh)( void *bp, char c ); - - -static void -fmtint( OutCh dopr_outch, void *bp, - long value, int base, int min, int max, int flags ) -{ - const char *ctab; - unsigned long uvalue; - int signvalue = 0; - int place = 0; - int spadlen = 0; /* amount to space pad */ - int zpadlen = 0; /* amount to zero pad */ - char convert[20]; - - if (max < 0) - max = 0; - - uvalue = value; - - if (!(flags & DP_F_UNSIGNED)) { - if (value < 0) { - signvalue = '-'; - uvalue = -value; - } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; - } - - ctab = (flags & DP_F_UPCASE) ? "0123456789ABCDEF" : "0123456789abcdef"; - do { - convert[place++] = ctab[uvalue % (unsigned)base]; - uvalue = uvalue / (unsigned)base; - } while (uvalue); - - zpadlen = max - place; - spadlen = min - (max > place ? max : place) - - (signvalue ? 1 : 0) - ((flags & DP_F_NUM) ? 2 : 0); - if (zpadlen < 0) - zpadlen = 0; - if (spadlen < 0) - spadlen = 0; - if (flags & DP_F_ZERO) { - zpadlen = zpadlen > spadlen ? zpadlen : spadlen; - spadlen = 0; - } - if (flags & DP_F_MINUS) - spadlen = -spadlen; /* Left Justifty */ - - - /* Spaces */ - while (spadlen > 0) { - dopr_outch( bp, ' ' ); - --spadlen; - } - - /* Sign */ - if (signvalue) - dopr_outch( bp, signvalue ); - - /* Prefix */ - if (flags & DP_F_NUM) { - dopr_outch( bp, '0' ); - dopr_outch( bp, 'x' ); - } - - /* Zeros */ - if (zpadlen > 0) - while (zpadlen > 0) { - dopr_outch( bp, '0' ); - --zpadlen; - } - - /* Digits */ - while (place > 0) - dopr_outch( bp, convert[--place] ); - - /* Left Justified spaces */ - while (spadlen < 0) { - dopr_outch( bp, ' ' ); - ++spadlen; - } -} - -typedef struct { - const char *str; - size_t len; -} str_t; - -static void -putstr( OutCh dopr_outch, void *bp, str_t *st ) -{ - size_t pt; - - for (pt = 0; pt < st->len; pt++) - dopr_outch( bp, st->str[pt] ); -} - -static str_t _null_parents = { "(null)", 6 }; -#ifdef PRINT_ARRAYS -static str_t _null_dparents = { "((null))", 8 }; -#endif -#if defined(PRINT_QUOTES) || defined(PRINT_ARRAYS) -static str_t _null_caps = { "NULL", 4 }; -#endif - -static void -fmtstr( OutCh dopr_outch, void *bp, - const char *value, int flags, int min, int max ) -{ - int padlen, strln, curcol; -#ifdef PRINT_QUOTES - int lastcol; -#endif - char ch; - - if (!value) { -#ifdef PRINT_QUOTES - if (flags & (DP_F_SQUOTE | DP_F_DQUOTE)) - putstr( dopr_outch, bp, &_null_caps ); - else -#endif - putstr( dopr_outch, bp, &_null_parents ); - return; - } - - for (strln = 0; (unsigned)strln < (unsigned)max && value[strln]; strln++); - padlen = min - strln; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justify */ - - for (; padlen > 0; padlen--) - dopr_outch( bp, ' ' ); -#ifdef PRINT_QUOTES -# if 0 /* gcc's flow analyzer is not the smartest ... */ - lastcol = 0; -# endif - if (flags & DP_F_SQUOTE) - dopr_outch( bp, '\'' ); - else if (flags & DP_F_DQUOTE) - dopr_outch( bp, '"'); - else if (flags & DP_F_BACKSL) - for (lastcol = strln; lastcol && value[lastcol - 1] == ' '; lastcol--); -#endif - for (curcol = 0; curcol < strln; curcol++) { - ch = value[curcol]; -#ifdef PRINT_QUOTES - if (flags & (DP_F_SQUOTE | DP_F_DQUOTE | DP_F_BACKSL)) { - switch (ch) { - case '\r': ch = 'r'; break; - case '\n': ch = 'n'; break; - case '\t': ch = 't'; break; - case '\a': ch = 'a'; break; - case '\b': ch = 'b'; break; - case '\v': ch = 'v'; break; - case '\f': ch = 'f'; break; - default: - if (ch < 32 || - ((unsigned char)ch >= 0x7f && (unsigned char)ch < 0xa0)) - { - dopr_outch( bp, '\\' ); - fmtint( dopr_outch, bp, (unsigned char)ch, 8, 3, 3, DP_F_ZERO ); - continue; - } else { - if ((ch == '\'' && (flags & DP_F_SQUOTE)) || - (ch == '"' && (flags & DP_F_DQUOTE) ) || - (ch == ' ' && (flags & DP_F_BACKSL) && - (!curcol || curcol >= lastcol)) || - ch == '\\') - dopr_outch( bp, '\\' ); - dopr_outch( bp, ch ); - continue; - } - } - dopr_outch( bp, '\\' ); - } -#endif - dopr_outch( bp, ch ); - } -#ifdef PRINT_QUOTES - if (flags & DP_F_SQUOTE) - dopr_outch( bp, '\'' ); - else if (flags & DP_F_DQUOTE) - dopr_outch( bp, '"' ); -#endif - for (; padlen < 0; padlen++) - dopr_outch( bp, ' ' ); -} - -static void -DoPr( OutCh dopr_outch, void *bp, const char *format, va_list args ) -{ - const char *strvalue; -#ifdef PRINT_ARRAYS - str_t arpr, arsf, arepr, aresf, aresp, *arp; - void *arptr; -#endif - unsigned long value; - int radix, min, max, flags, cflags, errn; -#ifdef PRINT_ARRAYS - int arlen; - unsigned aridx; - char sch; -#endif - char ch; -#define NCHR if (!(ch = *format++)) return - -#if 0 /* gcc's flow analyzer is not the smartest ... */ -# ifdef PRINT_ARRAYS - arlen = 0; -# endif - radix = 0; -#endif - errn = errno; - for (;;) { - for (;;) { - NCHR; - if (ch == '%') - break; - dopr_outch (bp, ch); - } - flags = cflags = min = 0; - max = -1; - for (;;) { - NCHR; - switch (ch) { - case '#': flags |= DP_F_NUM; continue; - case '-': flags |= DP_F_MINUS; continue; - case '+': flags |= DP_F_PLUS; continue; - case ' ': flags |= DP_F_SPACE; continue; - case '0': flags |= DP_F_ZERO; continue; -#ifdef PRINT_QUOTES - case '"': flags |= DP_F_DQUOTE; continue; - case '\'': flags |= DP_F_SQUOTE; continue; - case '\\': flags |= DP_F_BACKSL; continue; -#endif - } - break; - } - for (;;) { - if (isdigit( (unsigned char)ch )) { - min = 10 * min + (ch - '0'); - NCHR; - continue; - } else if (ch == '*') { - min = va_arg( args, int ); - NCHR; - } - break; - } - if (ch == '.') { - max = 0; - for (;;) { - NCHR; - if (isdigit( (unsigned char)ch )) { - max = 10 * max + (ch - '0'); - continue; - } else if (ch == '*') { - max = va_arg( args, int ); - NCHR; - } - break; - } - } -#ifdef PRINT_ARRAYS - if (ch == '[') { - flags |= DP_F_ARRAY; - arlen = -1; - arpr.len = arsf.len = arepr.len = aresf.len = 0; - aresp.len = 1, aresp.str = " "; - for (;;) { - NCHR; - if (isdigit( (unsigned char)ch )) { - arlen = 0; - for (;;) { - arlen += (ch - '0'); - NCHR; - if (!isdigit( (unsigned char)ch )) - break; - arlen *= 10; - } - } - switch (ch) { - case ':': flags |= DP_F_COLON; continue; - case '*': arlen = va_arg( args, int ); continue; - case '(': arp = &arpr; goto rar; - case ')': arp = &arsf; goto rar; - case '<': arp = &arepr; goto rar; - case '>': arp = &aresf; goto rar; - case '|': arp = &aresp; - rar: - NCHR; - sch = ch; - arp->str = format; - do { - NCHR; - } while (ch != sch); - arp->len = format - arp->str - 1; - continue; - case ',': - aresp.len = 1, aresp.str = ","; - continue; - case '{': - aresp.len = 0, arpr.len = arepr.len = 1, arsf.len = 2; - arpr.str = "{", arepr.str = " ", arsf.str = " }"; - continue; - } - break; - } - } -#endif - for (;;) { - switch (ch) { - case 'h': - cflags = DP_C_SHORT; - NCHR; - if (ch == 'h') { - cflags = DP_C_BYTE; - NCHR; - } - continue; - case 'l': - cflags = DP_C_LONG; - NCHR; - continue; - } - break; - } - switch (ch) { - case '%': - dopr_outch( bp, ch ); - break; - case 'm': - fmtstr( dopr_outch, bp, strerror( errn ), flags, min, max ); - break; - case 'c': - dopr_outch( bp, va_arg( args, int ) ); - break; - case 's': -#ifdef PRINT_ARRAYS - cflags = DP_C_STR; - goto printit; -#else - strvalue = va_arg( args, char * ); - fmtstr( dopr_outch, bp, strvalue, flags, min, max ); - break; -#endif - case 'u': - flags |= DP_F_UNSIGNED; - case 'd': - case 'i': - radix = 10; - goto printit; - case 'X': - flags |= DP_F_UPCASE; - case 'x': - flags |= DP_F_UNSIGNED; - radix = 16; - printit: -#ifdef PRINT_ARRAYS - if (flags & DP_F_ARRAY) { - if (!(arptr = va_arg( args, void * ))) - putstr( dopr_outch, bp, - arpr.len ? &_null_caps : &_null_dparents ); - else { - if (arlen == -1) { - arlen = 0; - switch (cflags) { - case DP_C_STR: while (((char **)arptr)[arlen]) arlen++; break; - case DP_C_BYTE: while (((unsigned char *)arptr)[arlen] != (unsigned char)-1) arlen++; break; - case DP_C_SHORT: while (((unsigned short int *)arptr)[arlen] != (unsigned short int)-1) arlen++; break; - case DP_C_LONG: while (((unsigned long int *)arptr)[arlen] != (unsigned long int)-1) arlen++; break; - default: while (((unsigned int *)arptr)[arlen] != (unsigned int)-1) arlen++; break; - } - } - if (flags & DP_F_COLON) { - fmtint( dopr_outch, bp, (long)arlen, 10, 0, -1, DP_F_UNSIGNED ); - dopr_outch( bp, ':' ); - dopr_outch( bp, ' ' ); - } - putstr( dopr_outch, bp, &arpr ); - for (aridx = 0; aridx < (unsigned)arlen; aridx++) { - if (aridx) - putstr( dopr_outch, bp, &aresp ); - putstr( dopr_outch, bp, &arepr ); - if (cflags == DP_C_STR) { - strvalue = ((char **)arptr)[aridx]; - fmtstr( dopr_outch, bp, strvalue, flags, min, max ); - } else { - if (flags & DP_F_UNSIGNED) { - switch (cflags) { - case DP_C_BYTE: value = ((unsigned char *)arptr)[aridx]; break; - case DP_C_SHORT: value = ((unsigned short int *)arptr)[aridx]; break; - case DP_C_LONG: value = ((unsigned long int *)arptr)[aridx]; break; - default: value = ((unsigned int *)arptr)[aridx]; break; - } - } else { - switch (cflags) { - case DP_C_BYTE: value = ((signed char *)arptr)[aridx]; break; - case DP_C_SHORT: value = ((short int *)arptr)[aridx]; break; - case DP_C_LONG: value = ((long int *)arptr)[aridx]; break; - default: value = ((int *)arptr)[aridx]; break; - } - } - fmtint( dopr_outch, bp, value, radix, min, max, flags ); - } - putstr( dopr_outch, bp, &aresf ); - } - putstr( dopr_outch, bp, &arsf ); - } - } else { - if (cflags == DP_C_STR) { - strvalue = va_arg( args, char * ); - fmtstr( dopr_outch, bp, strvalue, flags, min, max ); - } else { -#endif - if (flags & DP_F_UNSIGNED) { - switch (cflags) { - case DP_C_LONG: value = va_arg( args, unsigned long int ); break; - default: value = va_arg( args, unsigned int ); break; - } - } else { - switch (cflags) { - case DP_C_LONG: value = va_arg( args, long int ); break; - default: value = va_arg( args, int ); break; - } - } - fmtint( dopr_outch, bp, value, radix, min, max, flags ); -#ifdef PRINT_ARRAYS - } - } -#endif - break; - case 'p': - value = (long)va_arg( args, void * ); - fmtint( dopr_outch, bp, value, 16, sizeof(long) * 2 + 2, - max, flags | DP_F_UNSIGNED | DP_F_ZERO | DP_F_NUM ); - break; - } - } -} - -/* ########## end of printf core implementation ########## */ - - -/* - * Logging function for xdm and helper programs. - */ -#ifndef NO_LOGGER - -#include <stdio.h> -#include <time.h> - -#ifdef USE_SYSLOG -# include <syslog.h> -# ifdef LOG_NAME -# define InitLog() openlog(LOG_NAME, LOG_PID, LOG_DAEMON) -# else -# define InitLog() openlog(prog, LOG_PID, LOG_DAEMON) -# endif -static int lognums[] = { LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT }; -#else -# define InitLog() while(0) -#endif - -static const char *lognams[] = { "debug", "info", "warning", "error", "panic" }; - -static void -logTime( char *dbuf ) -{ - time_t tim; - (void)time( &tim ); - strftime( dbuf, 20, "%b %e %H:%M:%S", localtime( &tim ) ); -} - -#if defined(LOG_DEBUG_MASK) || defined(USE_SYSLOG) -STATIC int debugLevel; -#endif - -#define OOMSTR "Out of memory. Expect problems.\n" - -STATIC void -LogOutOfMem( void ) -{ - static time_t last; - time_t tnow; - - time( &tnow ); - if (last + 100 > tnow) { /* don't log bursts */ - last = tnow; - return; - } - last = tnow; -#ifdef USE_SYSLOG - if (!(debugLevel & DEBUG_NOSYSLOG)) - syslog( LOG_CRIT, OOMSTR ); - else -#endif - { - int el; - char dbuf[24], sbuf[128]; - logTime( dbuf ); - el = sprintf( sbuf, "%s " -#ifdef LOG_NAME - LOG_NAME "[%ld]: " OOMSTR, dbuf, -#else - "%s[%ld]: " OOMSTR, dbuf, prog, -#endif - (long)getpid() ); - write( 2, sbuf, el ); - } -} - -typedef struct { - char *buf; - int clen, blen, type; - char lmbuf[128]; -} OCLBuf; - -static void -OutChLFlush( OCLBuf *oclbp ) -{ - if (oclbp->clen) { -#ifdef USE_SYSLOG - if (!(debugLevel & DEBUG_NOSYSLOG)) - syslog( lognums[oclbp->type], "%.*s", oclbp->clen, oclbp->buf ); - else -#endif - { - oclbp->buf[oclbp->clen] = '\n'; - write( 2, oclbp->buf, oclbp->clen + 1 ); - } - oclbp->clen = 0; - } -} - -static void -OutChL( void *bp, char c ) -{ - OCLBuf *oclbp = (OCLBuf *)bp; - char *nbuf; - int nlen; - - if (c == '\n') - OutChLFlush( oclbp ); - else { - if (oclbp->clen >= oclbp->blen - 1) { - if (oclbp->buf == oclbp->lmbuf) { - OutChLFlush( oclbp ); - oclbp->buf = 0; - oclbp->blen = 0; - } - nlen = oclbp->blen * 3 / 2 + 128; - nbuf = Realloc( oclbp->buf, nlen ); - if (nbuf) { - oclbp->buf = nbuf; - oclbp->blen = nlen; - } else { - OutChLFlush( oclbp ); - oclbp->buf = oclbp->lmbuf; - oclbp->blen = sizeof(oclbp->lmbuf); - } - } -#ifdef USE_SYSLOG - if (!oclbp->clen && (debugLevel & DEBUG_NOSYSLOG)) { -#else - if (!oclbp->clen) { -#endif - char dbuf[24]; - logTime( dbuf ); - oclbp->clen = sprintf( oclbp->buf, "%s " -#ifdef LOG_NAME - LOG_NAME "[%ld] %s: ", dbuf, -#else - "%s[%ld] %s: ", dbuf, prog, -#endif - (long)getpid(), lognams[oclbp->type] ); - } - oclbp->buf[oclbp->clen++] = c; - } -} - -static void -Logger( int type, const char *fmt, va_list args ) -{ - OCLBuf oclb; - - oclb.buf = 0; - oclb.blen = oclb.clen = 0; - oclb.type = type; - DoPr( OutChL, &oclb, fmt, args ); - /* no flush, every message is supposed to be \n-terminated */ - if (oclb.buf && oclb.buf != oclb.lmbuf) - free( oclb.buf ); -} - -#ifdef LOG_DEBUG_MASK -STATIC void -Debug( const char *fmt, ... ) -{ - if (debugLevel & LOG_DEBUG_MASK) { - va_list args; - int olderrno = errno; - va_start( args, fmt ); - Logger( DM_DEBUG, fmt, args ); - va_end( args ); - errno = olderrno; - } -} -#endif - -#ifndef LOG_NO_INFO -STATIC void -LogInfo( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_INFO, fmt, args ); - va_end( args ); -} -#endif - -#ifndef LOG_NO_WARN -STATIC void -LogWarn( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_WARN, fmt, args ); - va_end( args ); -} -#endif - -#ifndef LOG_NO_ERROR -STATIC void -LogError( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_ERR, fmt, args ); - va_end( args ); -} -#endif - -#ifdef LOG_PANIC_EXIT -STATIC void -LogPanic( const char *fmt, ... ) -{ - va_list args; - - va_start( args, fmt ); - Logger( DM_PANIC, fmt, args ); - va_end( args ); - exit( LOG_PANIC_EXIT ); -} -#endif - -#endif /* NO_LOGGER */ - -#ifdef NEED_FDPRINTF - -typedef struct { - char *buf; - int clen, blen, tlen; -} OCFBuf; - -static void -OutCh_OCF( void *bp, char c ) -{ - OCFBuf *ocfbp = (OCFBuf *)bp; - char *nbuf; - int nlen; - - ocfbp->tlen++; - if (ocfbp->clen >= ocfbp->blen) { - if (ocfbp->blen < 0) - return; - nlen = ocfbp->blen * 3 / 2 + 100; - nbuf = Realloc( ocfbp->buf, nlen ); - if (!nbuf) { - free( ocfbp->buf ); - ocfbp->blen = -1; - ocfbp->buf = 0; - ocfbp->clen = 0; - return; - } - ocfbp->blen = nlen; - ocfbp->buf = nbuf; - } - ocfbp->buf[ocfbp->clen++] = c; -} - -STATIC int -FdPrintf( int fd, const char *fmt, ... ) -{ - va_list args; - OCFBuf ocfb = { 0, 0, 0, -1 }; - - va_start( args, fmt ); - DoPr( OutCh_OCF, &ocfb, fmt, args ); - va_end( args ); - if (ocfb.buf) { - Debug( "FdPrintf %\".*s to %d\n", ocfb.clen, ocfb.buf, fd ); - (void)write( fd, ocfb.buf, ocfb.clen ); - free( ocfb.buf ); - } - return ocfb.tlen; -} - -#endif /* NEED_FDPRINTF */ - -#ifdef NEED_ASPRINTF - -typedef struct { - char *buf; - int clen, blen, tlen; -} OCABuf; - -static void -OutCh_OCA( void *bp, char c ) -{ - OCABuf *ocabp = (OCABuf *)bp; - char *nbuf; - int nlen; - - ocabp->tlen++; - if (ocabp->clen >= ocabp->blen) { - if (ocabp->blen < 0) - return; - nlen = ocabp->blen * 3 / 2 + 100; - nbuf = Realloc( ocabp->buf, nlen ); - if (!nbuf) { - free( ocabp->buf ); - ocabp->blen = -1; - ocabp->buf = 0; - ocabp->clen = 0; - return; - } - ocabp->blen = nlen; - ocabp->buf = nbuf; - } - ocabp->buf[ocabp->clen++] = c; -} - -STATIC int -VASPrintf( char **strp, const char *fmt, va_list args ) -{ - OCABuf ocab = { 0, 0, 0, -1 }; - - DoPr( OutCh_OCA, &ocab, fmt, args ); - OutCh_OCA( &ocab, 0 ); - *strp = Realloc( ocab.buf, ocab.clen ); - if (!*strp) - *strp = ocab.buf; - return ocab.tlen; -} - -STATIC int -ASPrintf( char **strp, const char *fmt, ... ) -{ - va_list args; - int len; - - va_start( args, fmt ); - len = VASPrintf( strp, fmt, args ); - va_end( args ); - return len; -} - -#endif /* NEED_ASPRINTF */ diff --git a/kdm/backend/process.c b/kdm/backend/process.c deleted file mode 100644 index f9d34fe7f..000000000 --- a/kdm/backend/process.c +++ /dev/null @@ -1,762 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2001-2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * subdaemon and external process management and communication - */ - -#include "dm.h" -#include "dm_error.h" - -#include <ctype.h> -#include <stdio.h> -#include <stdarg.h> -#include <signal.h> -#include <unistd.h> -#ifdef _POSIX_PRIORITY_SCHEDULING -# include <sched.h> -#endif - -extern char **environ; - - -SIGFUNC Signal( int sig, SIGFUNC handler ) -{ -#ifndef __EMX__ - struct sigaction sigact, osigact; - sigact.sa_handler = handler; - sigemptyset( &sigact.sa_mask ); -# ifdef SA_RESTART - sigact.sa_flags = SA_RESTART; -# else - sigact.sa_flags = 0; -# endif - sigaction( sig, &sigact, &osigact ); - return osigact.sa_handler; -#else - return signal( sig, handler ); -#endif -} - - -void -TerminateProcess( int pid, int sig ) -{ - kill( pid, sig ); -#ifdef SIGCONT - kill( pid, SIGCONT ); -#endif -} - - -static FD_TYPE CloseMask; -static int max = -1; - -void -RegisterCloseOnFork( int fd ) -{ - FD_SET( fd, &CloseMask ); - if (fd > max) - max = fd; -} - -void -ClearCloseOnFork( int fd ) -{ - FD_CLR( fd, &CloseMask ); -} - -void -CloseNClearCloseOnFork( int fd ) -{ - close( fd ); - FD_CLR( fd, &CloseMask ); -} - -static void -CloseOnFork( void ) -{ - int fd; - - for (fd = 0; fd <= max; fd++) - if (FD_ISSET( fd, &CloseMask )) - close( fd ); - FD_ZERO( &CloseMask ); - max = -1; -} - -int -Fork() -{ - int pid; - - sigset_t ss, oss; - sigfillset( &ss ); - sigprocmask( SIG_SETMASK, &ss, &oss ); - - if (!(pid = fork())) { -#ifdef SIGCHLD - (void)Signal( SIGCHLD, SIG_DFL ); -#endif - (void)Signal( SIGTERM, SIG_DFL ); - (void)Signal( SIGINT, SIG_IGN ); /* for -nodaemon */ - (void)Signal( SIGPIPE, SIG_DFL ); - (void)Signal( SIGALRM, SIG_DFL ); - (void)Signal( SIGHUP, SIG_DFL ); - sigemptyset( &ss ); - sigprocmask( SIG_SETMASK, &ss, NULL ); - CloseOnFork(); - return 0; - } - - sigprocmask( SIG_SETMASK, &oss, 0 ); - - return pid; -} - -int -Wait4( int pid ) -{ - waitType result; - - while (waitpid( pid, &result, 0 ) < 0) - if (errno != EINTR) { - Debug( "Wait4(%d) failed: %m\n", pid ); - return 0; - } - return waitVal( result ); -} - - -void -execute( char **argv, char **env ) -{ - Debug( "execute: %[s ; %[s\n", argv, env ); - execve( argv[0], argv, env ); - /* - * In case this is a shell script which hasn't been - * made executable (or this is a SYSV box), do - * a reasonable thing - */ - if (errno != ENOENT) { - char **newargv; - FILE *f; - int nu; - char program[1024]; - - /* - * emulate BSD kernel behaviour -- read - * the first line; check if it starts - * with "#!", in which case it uses - * the rest of the line as the name of - * program to run. Else use "/bin/sh". - */ - if (!(f = fopen( argv[0], "r" ))) - return; - if (!fGets( program, sizeof(program), f )) { - fclose( f ); - return; - } - fclose( f ); - if (!strncmp( program, "#!", 2 )) - newargv = parseArgs( 0, program + 2 ); - else - newargv = addStrArr( 0, "/bin/sh", 7 ); - if (!newargv) - return; - nu = arrLen( newargv ); - if (!(argv = xCopyStrArr( nu, argv ))) - return; - memcpy( argv, newargv, sizeof(char *) * nu ); - Debug( "shell script execution: %[s\n", argv ); - execve( argv[0], argv, env ); - } -} - -int -runAndWait( char **args, char **env ) -{ - int pid, ret; - - switch (pid = Fork()) { - case 0: - execute( args, env ); - LogError( "Can't execute %\"s: %m\n", args[0] ); - exit( 127 ); - case -1: - LogError( "Can't fork to execute %\"s: %m\n", args[0] ); - return 1; - } - ret = Wait4( pid ); - return waitVal( ret ); -} - -FILE * -pOpen( char **what, char m, int *pid ) -{ - int dp[2]; - - if (pipe( dp )) - return 0; - switch ((*pid = Fork())) { - case 0: - if (m == 'r') - dup2( dp[1], 1 ); - else - dup2( dp[0], 0 ); - close( dp[0] ); - close( dp[1] ); - execute( what, environ ); - LogError( "Can't execute %\"s: %m\n", what[0] ); - exit( 127 ); - case -1: - close( dp[0] ); - close( dp[1] ); - LogError( "Can't fork to execute %\"s: %m\n", what[0] ); - return 0; - } - if (m == 'r') { - close( dp[1] ); - return fdopen( dp[0], "r" ); - } else { - close( dp[0] ); - return fdopen( dp[1], "w" ); - } -} - -int -pClose( FILE *f, int pid ) -{ - fclose( f ); - return Wait4( pid ); -} - -char * -locate( const char *exe ) -{ - int len; - char *path, *name, *thenam, nambuf[PATH_MAX+1]; - char *pathe; - - if (!(path = getenv( "PATH" ))) { - LogError( "Can't execute %'s: $PATH not set.\n", exe ); - return 0; - } - len = strlen( exe ); - name = nambuf + PATH_MAX - len; - memcpy( name, exe, len + 1 ); - *--name = '/'; - do { - if (!(pathe = strchr( path, ':' ))) - pathe = path + strlen( path ); - len = pathe - path; - if (len && !(len == 1 && *path == '.')) { - thenam = name - len; - if (thenam >= nambuf) { - memcpy( thenam, path, len ); - if (!access( thenam, X_OK )) { - StrDup( &name, thenam ); - return name; - } - } - } - path = pathe; - } while (*path++ != '\0'); - LogError( "Can't execute %'s: not in $PATH.\n", exe ); - return 0; -} - - -static GTalk *curtalk; - -void -GSet( GTalk *tlk ) -{ - curtalk = tlk; -} - -int -GFork( GPipe *pajp, const char *pname, char *cname, - GPipe *ogp, char *cgname ) -{ - int opipe[2], ipipe[2], ogpipe[2], igpipe[2], pid; - - if (pipe( opipe )) - goto badp1; - if (pipe( ipipe )) - goto badp2; - if (ogp) { - if (pipe( ogpipe )) - goto badp3; - if (pipe( igpipe )) { - close( ogpipe[0] ); - close( ogpipe[1] ); - badp3: - close( ipipe[0] ); - close( ipipe[1] ); - badp2: - close( opipe[0] ); - close( opipe[1] ); - badp1: - LogError( "Cannot start %s, pipe() failed", cname ); - if (cname) - free( cname ); - return -1; - } - } - RegisterCloseOnFork( opipe[1] ); - RegisterCloseOnFork( ipipe[0] ); - if (ogp) { - RegisterCloseOnFork( ogpipe[1] ); - RegisterCloseOnFork( igpipe[0] ); - } - switch (pid = Fork()) { - case -1: - close( opipe[0] ); - close( ipipe[1] ); - CloseNClearCloseOnFork( opipe[1] ); - CloseNClearCloseOnFork( ipipe[0] ); - if (ogp) { - close( ogpipe[0] ); - close( igpipe[1] ); - CloseNClearCloseOnFork( ogpipe[1] ); - CloseNClearCloseOnFork( igpipe[0] ); - } - LogError( "Cannot start %s, fork() failed\n", cname ); - if (cname) - free( cname ); - return -1; - case 0: - pajp->wfd = ipipe[1]; - RegisterCloseOnFork( ipipe[1] ); - pajp->rfd = opipe[0]; - RegisterCloseOnFork( opipe[0] ); - pajp->who = (char *)pname; - if (ogp) { - ogp->wfd = igpipe[1]; - RegisterCloseOnFork( igpipe[1] ); - ogp->rfd = ogpipe[0]; - RegisterCloseOnFork( ogpipe[0] ); - ogp->who = (char *)pname; - } - break; - default: - close( opipe[0] ); - close( ipipe[1] ); - pajp->rfd = ipipe[0]; - pajp->wfd = opipe[1]; - pajp->who = cname; - if (ogp) { - close( ogpipe[0] ); - close( igpipe[1] ); - ogp->rfd = igpipe[0]; - ogp->wfd = ogpipe[1]; - ogp->who = cgname; - } - break; - } - return pid; -} - -int -GOpen( GProc *proc, char **argv, const char *what, char **env, char *cname, - GPipe *gp ) -{ - char **margv; - int pip[2]; - char coninfo[32]; - -/* ### GSet (proc->pipe); */ - if (proc->pid) { - LogError( "%s already running\n", cname ); - if (cname) - free( cname ); - return -1; - } - if (!(margv = xCopyStrArr( 1, argv ))) { - if (cname) - free( cname ); - return -1; - } - if (!StrApp( margv, progpath, what, (char *)0 )) { - free( margv ); - if (cname) - free( cname ); - return -1; - } - if (pipe( pip )) { - LogError( "Cannot start %s, pipe() failed\n", cname ); - if (cname) - free( cname ); - goto fail; - } - if (gp) { - ClearCloseOnFork( gp->rfd ); - ClearCloseOnFork( gp->wfd ); - } - proc->pid = GFork( &proc->pipe, 0, cname, 0, 0 ); - if (proc->pid) { - close( pip[1] ); - if (gp) { - RegisterCloseOnFork( gp->rfd ); - RegisterCloseOnFork( gp->wfd ); - } - } - switch (proc->pid) { - case -1: - fail1: - close( pip[0] ); - fail: - free( margv[0] ); - free( margv ); - return -1; - case 0: - (void)Signal( SIGPIPE, SIG_IGN ); - close( pip[0] ); - fcntl( pip[1], F_SETFD, FD_CLOEXEC ); - if (gp) - sprintf( coninfo, "CONINFO=%d %d %d %d", - proc->pipe.rfd, proc->pipe.wfd, gp->rfd, gp->wfd ); - else - sprintf( coninfo, "CONINFO=%d %d", - proc->pipe.rfd, proc->pipe.wfd ); - env = putEnv( coninfo, env ); - if (debugLevel & DEBUG_VALGRIND) { - char **nmargv = xCopyStrArr( 1, margv ); - nmargv[0] = locate( "valgrind" ); - execute( nmargv, env ); - } else if (debugLevel & DEBUG_STRACE) { - char **nmargv = xCopyStrArr( 1, margv ); - nmargv[0] = locate( "strace" ); - execute( nmargv, env ); - } else - execute( margv, env ); - write( pip[1], "", 1 ); - exit( 1 ); - default: - (void)Signal( SIGPIPE, SIG_IGN ); - if (Reader( pip[0], coninfo, 1 )) { - Wait4( proc->pid ); - LogError( "Cannot execute %\"s (%s)\n", margv[0], cname ); - GClosen (&proc->pipe); - goto fail1; - } - close( pip[0] ); - Debug( "started %s (%\"s), pid %d\n", cname, margv[0], proc->pid ); - free( margv[0] ); - free( margv ); - GSendInt( debugLevel ); - return 0; - } -} - -static void -iGClosen( GPipe *pajp ) -{ - CloseNClearCloseOnFork( pajp->rfd ); - CloseNClearCloseOnFork( pajp->wfd ); - pajp->rfd = pajp->wfd = -1; -} - -void -GClosen (GPipe *pajp) -{ - iGClosen( pajp ); - if (pajp->who) - free( pajp->who ); - pajp->who = 0; -} - -int -GClose (GProc *proc, GPipe *gp, int force) -{ - int ret; - - if (!proc->pid) { - Debug( "whoops, GClose while helper not running\n" ); - return 0; - } - iGClosen( &proc->pipe ); - if (gp) - GClosen (gp); - if (force) - TerminateProcess( proc->pid, SIGTERM ); - ret = Wait4( proc->pid ); - proc->pid = 0; - if (WaitSig( ret ) ? WaitSig( ret ) != SIGTERM : - (WaitCode( ret ) < EX_NORMAL || WaitCode( ret ) > EX_MAX)) - LogError( "Abnormal termination of %s, code %d, signal %d\n", - proc->pipe.who, WaitCode( ret ), WaitSig( ret ) ); - Debug( "closed %s\n", proc->pipe.who ); - if (proc->pipe.who) - free( proc->pipe.who ); - proc->pipe.who = 0; - return ret; -} - -static void ATTR_NORETURN -GErr( void ) -{ - Longjmp( curtalk->errjmp, 1 ); -} - -static void -GRead( void *buf, int len ) -{ - if (Reader( curtalk->pipe->rfd, buf, len ) != len) { - LogError( "Cannot read from %s\n", curtalk->pipe->who ); - GErr(); - } -} - -static void -GWrite( const void *buf, int len ) -{ - if (Writer( curtalk->pipe->wfd, buf, len ) != len) { - LogError( "Cannot write to %s\n", curtalk->pipe->who ); - GErr(); - } -#ifdef _POSIX_PRIORITY_SCHEDULING - if ((debugLevel & DEBUG_HLPCON)) - sched_yield(); -#endif -} - -void -GSendInt( int val ) -{ - GDebug( "sending int %d (%#x) to %s\n", val, val, curtalk->pipe->who ); - GWrite( &val, sizeof(val) ); -} - -int -GRecvInt() -{ - int val; - - GDebug( "receiving int from %s ...\n", curtalk->pipe->who ); - GRead( &val, sizeof(val) ); - GDebug( " -> %d (%#x)\n", val, val ); - return val; -} - -int -GRecvCmd( int *cmd ) -{ - GDebug( "receiving command from %s ...\n", curtalk->pipe->who ); - if (Reader( curtalk->pipe->rfd, cmd, sizeof(*cmd) ) == sizeof(*cmd)) { - GDebug( " -> %d\n", *cmd ); - return 1; - } - GDebug( " -> no data\n" ); - return 0; -} - -void -GSendArr( int len, const char *data ) -{ - GDebug( "sending array[%d] %02[*{hhx to %s\n", - len, len, data, curtalk->pipe->who ); - GWrite( &len, sizeof(len) ); - GWrite( data, len ); -} - -static char * -iGRecvArr( int *rlen ) -{ - int len; - char *buf; - - GRead( &len, sizeof(len) ); - *rlen = len; - GDebug( " -> %d bytes\n", len ); - if (!len) - return (char *)0; - if (!(buf = Malloc( len ))) - GErr(); - GRead( buf, len ); - return buf; -} - -char * -GRecvArr( int *rlen ) -{ - char *buf; - - GDebug( "receiving array from %s ...\n", curtalk->pipe->who ); - buf = iGRecvArr( rlen ); - GDebug( " -> %02[*{hhx\n", *rlen, buf ); - return buf; -} - -static int -iGRecvArrBuf( char *buf ) -{ - int len; - - GRead( &len, sizeof(len) ); - GDebug( " -> %d bytes\n", len ); - if (len) - GRead( buf, len ); - return len; -} - -int -GRecvArrBuf( char *buf ) -{ - int len; - - GDebug( "receiving already allocated array from %s ...\n", - curtalk->pipe->who ); - len = iGRecvArrBuf( buf ); - GDebug( " -> %02[*{hhx\n", len, buf ); - return len; -} - -int -GRecvStrBuf( char *buf ) -{ - int len; - - GDebug( "receiving already allocated string from %s ...\n", - curtalk->pipe->who ); - len = iGRecvArrBuf( buf ); - GDebug( " -> %\".*s\n", len, buf ); - return len; -} - -void -GSendStr( const char *buf ) -{ - int len; - - GDebug( "sending string %\"s to %s\n", buf, curtalk->pipe->who ); - if (buf) { - len = strlen( buf ) + 1; - GWrite( &len, sizeof(len) ); - GWrite( buf, len ); - } else - GWrite( &buf, sizeof(int) ); -} - -void -GSendNStr( const char *buf, int len ) -{ - int tlen = len + 1; - GDebug( "sending string %\".*s to %s\n", len, buf, curtalk->pipe->who ); - GWrite( &tlen, sizeof(tlen) ); - GWrite( buf, len ); - GWrite( "", 1 ); -} - -void -GSendStrN( const char *buf, int len ) -{ - if (buf) - GSendNStr( buf, StrNLen( buf, len ) ); - else - GSendStr( buf ); -} - -char * -GRecvStr() -{ - int len; - char *buf; - - GDebug( "receiving string from %s ...\n", curtalk->pipe->who ); - buf = iGRecvArr( &len ); - GDebug( " -> %\".*s\n", len, buf ); - return buf; -} - -static void -iGSendStrArr( int num, char **data ) -{ - char **cdata; - - GWrite( &num, sizeof(num) ); - for (cdata = data; --num >= 0; cdata++) - GSendStr( *cdata ); -} - -/* -void -GSendStrArr (int num, char **data) -{ - GDebug( "sending string array[%d] to %s\n", num, curtalk->pipe->who ); - iGSendStrArr( num, data ); -} -*/ - -char ** -GRecvStrArr( int *rnum ) -{ - int num; - char **argv, **cargv; - - GDebug( "receiving string array from %s ...\n", curtalk->pipe->who ); - GRead( &num, sizeof(num) ); - GDebug( " -> %d strings\n", num ); - *rnum = num; - if (!num) - return (char **)0; - if (!(argv = Malloc( num * sizeof(char *) ))) - GErr(); - for (cargv = argv; --num >= 0; cargv++) - *cargv = GRecvStr(); - return argv; -} - -void -GSendArgv( char **argv ) -{ - int num; - - if (argv) { - for (num = 0; argv[num]; num++); - GDebug( "sending argv[%d] to %s ...\n", num, curtalk->pipe->who ); - iGSendStrArr( num + 1, argv ); - } else { - GDebug( "sending NULL argv to %s\n", curtalk->pipe->who ); - GWrite( &argv, sizeof(int) ); - } -} - -char ** -GRecvArgv() -{ - int num; - - return GRecvStrArr( &num ); -} - diff --git a/kdm/backend/protodpy.c b/kdm/backend/protodpy.c deleted file mode 100644 index 08c38fbd1..000000000 --- a/kdm/backend/protodpy.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * manage a collection of proto-displays. These are displays for - * which sessionID's have been generated, but no session has been - * started. - */ - -#include <config.h> - -#ifdef XDMCP - -#include "dm.h" -#include "dm_error.h" - -static struct protoDisplay *protoDisplays; - -struct protoDisplay * -FindProtoDisplay( - XdmcpNetaddr address, - int addrlen, - CARD16 displayNumber ) -{ - struct protoDisplay *pdpy; - - Debug( "FindProtoDisplay\n" ); - for (pdpy = protoDisplays; pdpy; pdpy=pdpy->next) { - if (pdpy->displayNumber == displayNumber && - addressEqual( address, addrlen, pdpy->address, pdpy->addrlen )) - { - return pdpy; - } - } - return (struct protoDisplay *)0; -} - -static void -TimeoutProtoDisplays (void) -{ - struct protoDisplay *pdpy, *next; - - for (pdpy = protoDisplays; pdpy; pdpy = next) { - next = pdpy->next; - if (pdpy->date < (unsigned long)(now - PROTO_TIMEOUT)) - DisposeProtoDisplay( pdpy ); - } -} - -struct protoDisplay * -NewProtoDisplay( XdmcpNetaddr address, int addrlen, CARD16 displayNumber, - CARD16 connectionType, ARRAY8Ptr connectionAddress, - CARD32 sessionID ) -{ - struct protoDisplay *pdpy; - - Debug( "NewProtoDisplay\n" ); - TimeoutProtoDisplays (); - pdpy = (struct protoDisplay *)Malloc( sizeof(*pdpy) ); - if (!pdpy) - return NULL; - pdpy->address = (XdmcpNetaddr)Malloc( addrlen ); - if (!pdpy->address) { - free( (char *)pdpy ); - return NULL; - } - pdpy->addrlen = addrlen; - memmove( pdpy->address, address, addrlen ); - pdpy->displayNumber = displayNumber; - pdpy->connectionType = connectionType; - pdpy->date = now; - if (!XdmcpCopyARRAY8( connectionAddress, &pdpy->connectionAddress )) { - free( (char *)pdpy->address ); - free( (char *)pdpy ); - return NULL; - } - pdpy->sessionID = sessionID; - pdpy->fileAuthorization = (Xauth *)NULL; - pdpy->xdmcpAuthorization = (Xauth *)NULL; - pdpy->next = protoDisplays; - protoDisplays = pdpy; - return pdpy; -} - -void -DisposeProtoDisplay( pdpy ) - struct protoDisplay *pdpy; -{ - struct protoDisplay *p, *prev; - - prev = 0; - for (p = protoDisplays; p; p=p->next) { - if (p == pdpy) - break; - prev = p; - } - if (!p) - return; - if (prev) - prev->next = pdpy->next; - else - protoDisplays = pdpy->next; - bzero( &pdpy->key, sizeof(pdpy->key) ); - if (pdpy->fileAuthorization) - XauDisposeAuth( pdpy->fileAuthorization ); - if (pdpy->xdmcpAuthorization) - XauDisposeAuth( pdpy->xdmcpAuthorization ); - XdmcpDisposeARRAY8( &pdpy->connectionAddress ); - free( (char *)pdpy->address ); - free( (char *)pdpy ); -} - -#endif /* XDMCP */ diff --git a/kdm/backend/reset.c b/kdm/backend/reset.c deleted file mode 100644 index 2c2100870..000000000 --- a/kdm/backend/reset.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * pseudoReset -- pretend to reset the server by killing all clients - * with windows. It will reset the server most of the time, unless - * a client remains connected with no windows. - */ - -#include "dm.h" -#include "dm_error.h" - -#include <X11/Xlib.h> - -#include <signal.h> - -/*ARGSUSED*/ -static int -ignoreErrors( Display *dspl ATTR_UNUSED, XErrorEvent *event ATTR_UNUSED ) -{ - Debug( "ignoring error\n" ); - return 0; -} - -/* - * this is mostly bogus -- but quite useful. I wish the protocol - * had some way of enumerating and identifying clients, that way - * this code wouldn't have to be this kludgy. - */ - -static void -killWindows( Window window ) -{ - Window root, parent, *children; - unsigned int child, nchildren = 0; - - while (XQueryTree( dpy, window, &root, &parent, &children, &nchildren ) - && nchildren > 0) - { - for (child = 0; child < nchildren; child++) { - Debug( "XKillClient %p\n", children[child] ); - XKillClient( dpy, children[child] ); - } - XFree( (char *)children ); - } -} - -static Jmp_buf resetJmp; - -/* ARGSUSED */ -static void -abortReset( int n ATTR_UNUSED ) -{ - Longjmp( resetJmp, 1 ); -} - -/* - * this display connection better not have any windows... - */ - -void -pseudoReset() -{ - int screen; - - if (Setjmp( resetJmp )) { - LogError( "pseudoReset timeout\n" ); - } else { - (void)Signal( SIGALRM, abortReset ); - (void)alarm( 30 ); - XSetErrorHandler( ignoreErrors ); - for (screen = 0; screen < ScreenCount (dpy); screen++) { - Debug( "pseudoReset screen %d\n", screen ); - killWindows( RootWindow( dpy, screen ) ); - } - Debug( "before XSync\n" ); - XSync( dpy, False ); - (void)alarm( 0 ); - } - Signal( SIGALRM, SIG_DFL ); - XSetErrorHandler( (XErrorHandler)0 ); - Debug( "pseudoReset done\n" ); -} diff --git a/kdm/backend/resource.c b/kdm/backend/resource.c deleted file mode 100644 index f17db78ec..000000000 --- a/kdm/backend/resource.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2005 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * obtain configuration data - */ - -#include "dm.h" -#include "dm_error.h" - -#include <sys/stat.h> - - -static char **originalArgv; - -static GProc getter; -GTalk cnftalk; - -static void -OpenGetter() -{ - GSet( &cnftalk ); - if (!getter.pid) { - if (GOpen( &getter, - originalArgv, "_config", 0, strdup( "config reader" ), - 0 )) - LogPanic( "Cannot run config reader\n" ); - Debug( "getter now ready\n" ); - } -} - -void -CloseGetter() -{ - if (getter.pid) { - GSet( &cnftalk ); - (void)GClose (&getter, 0, 0); - Debug( "getter now closed\n" ); - } -} - -/* - * ref-counted, unique-instance strings - */ -static RcStr *strs; - -/* - * make a ref-counted string of the argument. the new string will - * have a ref-count of 1. the passed string pointer is no longer valid. - */ -RcStr * -newStr( char *str ) -{ - RcStr *cs; - - for (cs = strs; cs; cs = cs->next) - if (!strcmp( str, cs->str )) { - free( str ); - cs->cnt++; - return cs; - } - if (!(cs = Malloc( sizeof(*cs) ))) - return 0; - cs->cnt = 1; - cs->str = str; - cs->next = strs; - strs = cs; - return cs; -} - -/* - * decrement ref-count and delete string when count drops to 0. - */ -void -delStr( RcStr *str ) -{ - RcStr **cs; - - if (!str || --str->cnt) - return; - for (cs = &strs; *cs; cs = &((*cs)->next)) - if (str == *cs) { - *cs = (*cs)->next; - free( (*cs)->str ); - free( *cs ); - break; - } -} - - -typedef struct CfgFile { - RcStr *name; - int depidx; - long deptime; -} CfgFile; - -static int numCfgFiles; -static CfgFile *cfgFiles; - -static int cfgMapT[] = { - GC_gGlobal, - GC_gDisplay, -#ifdef XDMCP - GC_gXaccess, -#endif -}; -static int cfgMap[as(cfgMapT)]; - -static int -GetDeps() -{ - int ncf, i, dep, ret; - CfgFile *cf; - - OpenGetter(); - GSendInt( GC_Files ); - ncf = GRecvInt(); - if (!(cf = Malloc( ncf * sizeof(*cf) ))) { - CloseGetter(); - return 0; - } - for (i = 0; i < ncf; i++) { - cf[i].name = newStr( GRecvStr() ); - if ((dep = cf[i].depidx = GRecvInt()) != -1) - cf[i].deptime = mTime( cf[dep].name->str ); - } - if (cfgFiles) { - for (i = 0; i < numCfgFiles; i++) - delStr( cfgFiles[i].name ); - free( cfgFiles ); - } - ret = 1; - cfgFiles = cf; - numCfgFiles = ncf; - for (i = 0; i < as(cfgMapT); i++) { - GSendInt( cfgMapT[i] ); - if ((cfgMap[i] = GRecvInt()) < 0) { - LogError( "Config reader does not support config cathegory %#x\n", - cfgMapT[i] ); - ret = 0; - } - } - GSendInt( -1 ); - return ret; -} - -static int -checkDep( int idx ) -{ - int dep; - - if ((dep = cfgFiles[idx].depidx) == -1) - return 0; - if (checkDep( dep )) - return 1; - return mTime( cfgFiles[dep].name->str ) != cfgFiles[idx].deptime; -} - -static int -needsReScan( int what, CfgDep *dep ) -{ - int widx, idx; - long mt; - - for (widx = 0; cfgMapT[widx] != what; widx++); - idx = cfgMap[widx]; - if (checkDep( idx )) { - if (!GetDeps()) - return -1; - idx = cfgMap[widx]; - } - mt = mTime( cfgFiles[idx].name->str ); - if (dep->name != cfgFiles[idx].name) { - if (dep->name) - delStr( dep->name ); - dep->name = cfgFiles[idx].name; - dep->name->cnt++; - dep->time = mt; - return 1; - } else if (dep->time != mt) { - dep->time = mt; - return 1; - } else - return 0; -} - -int -startConfig( int what, CfgDep *dep, int force ) -{ - int ret; - - if ((ret = needsReScan( what, dep )) < 0 || (!ret && !force)) - return ret; - OpenGetter(); - GSendInt( GC_GetConf ); - GSendInt( what ); - GSendStr( dep->name->str ); - return 1; -} - -static void -LoadResources( CfgArr *conf ) -{ - char **vptr, **pptr, *cptr; - long *iptr, i, id, nu, j, nptr, nint, nchr; - - if (conf->data) - free( conf->data ); - conf->numCfgEnt = GRecvInt(); - nptr = GRecvInt(); - nint = GRecvInt(); - nchr = GRecvInt(); - if (!(conf->data = Malloc( conf->numCfgEnt * - (sizeof(long) + - sizeof(char *)) + - nptr * sizeof(char *) + - nint * sizeof(long) + - nchr ))) - { - CloseGetter(); - return; - } - vptr = (char **)conf->data; - pptr = vptr + conf->numCfgEnt; - conf->idx = (long *)(pptr + nptr); - iptr = conf->idx + conf->numCfgEnt; - cptr = (char *)(iptr + nint); - for (i = 0; i < conf->numCfgEnt; i++) { - id = GRecvInt(); - conf->idx[i] = id; - switch (id & C_TYPE_MASK) { - case C_TYPE_INT: - vptr[i] = (char *)((unsigned long)GRecvInt()); - break; - case C_TYPE_STR: - vptr[i] = cptr; - cptr += GRecvStrBuf( cptr ); - break; - case C_TYPE_ARGV: - nu = GRecvInt(); - vptr[i] = (char *)pptr; - for (j = 0; j < nu; j++) { - *pptr++ = cptr; - cptr += GRecvStrBuf( cptr ); - } - *pptr++ = (char *)0; - break; - default: - LogError( "Config reader supplied unknown data type in id %#x\n", - id ); - break; - } - } -} - -static void -ApplyResource( int id, char **src, char **dst ) -{ - switch (id & C_TYPE_MASK) { - case C_TYPE_INT: - *(int *)dst = *(long *)src; - break; - case C_TYPE_STR: - case C_TYPE_ARGV: - *dst = *src; - break; - } -} - - -#define boffset(f) XtOffsetOf(struct display, f) - -/* no global variables exported currently -struct globEnts { - int id; - char **off; -} globEnt[] = { -}; - */ - -/* no per-display variables exported currently -struct dpyEnts { - int id; - int off; -} dpyEnt[] = { -}; - */ - -CfgArr cfg; - -char ** -FindCfgEnt( struct display *d, int id ) -{ - int i; - -/* no global variables exported currently - for (i = 0; i < as(globEnt); i++) - if (globEnt[i].id == id) - return globEnt[i].off; - */ - for (i = 0; i < cfg.numCfgEnt; i++) - if (cfg.idx[i] == id) - return ((char **)cfg.data) + i; - if (d) { -/* no per-display variables exported currently - for (i = 0; i < as(dpyEnt); i++) - if (dpyEnt[i].id == id) - return (char **)(((char *)d) + dpyEnt[i].off); - */ - for (i = 0; i < d->cfg.numCfgEnt; i++) - if (d->cfg.idx[i] == id) - return ((char **)d->cfg.data) + i; - } - Debug( "unknown config entry %#x requested\n", id ); - return (char **)0; -} - - -CONF_CORE_GLOBAL_DEFS - -struct globVals { - int id; - char **off; -} globVal[] = { -CONF_CORE_GLOBALS -}; - -int -LoadDMResources( int force ) -{ - int i, ret; - char **ent; - - if (Setjmp( cnftalk.errjmp )) - return -1; /* may memleak, but we probably have to abort anyway */ - if ((ret = startConfig( GC_gGlobal, &cfg.dep, force )) <= 0) - return ret; - LoadResources( &cfg ); -/* Debug( "manager resources: %[*x\n", - cfg.numCfgEnt, ((char **)cfg.data) + cfg.numCfgEnt );*/ - ret = 1; - for (i = 0; i < as(globVal); i++) { - if (!(ent = FindCfgEnt( 0, globVal[i].id ))) - ret = -1; - else - ApplyResource( globVal[i].id, ent, globVal[i].off ); - } - if (ret < 0) - LogError( "Internal error: config reader supplied incomplete data\n" ); - return ret; -} - - -struct dpyVals { - int id; - int off; -} dpyVal[] = { -CONF_CORE_LOCALS -}; - -int -LoadDisplayResources( struct display *d ) -{ - int i, ret; - char **ent; - - if (Setjmp( cnftalk.errjmp )) - return -1; /* may memleak */ - if ((ret = startConfig( GC_gDisplay, &d->cfg.dep, FALSE )) <= 0) - return ret; - GSendStr( d->name ); - GSendStr( d->class2 ); - LoadResources( &d->cfg ); -/* Debug( "display(%s, %s) resources: %[*x\n", d->name, d->class2, - d->cfg.numCfgEnt, ((char **)d->cfg.data) + d->cfg.numCfgEnt );*/ - ret = 1; - for (i = 0; i < as(dpyVal); i++) { - if (!(ent = FindCfgEnt( d, dpyVal[i].id ))) - ret = -1; - else - ApplyResource( dpyVal[i].id, ent, - (char **)(((char *)d) + dpyVal[i].off) ); - } - if (ret < 0) - LogError( "Internal error: config reader supplied incomplete data\n" ); - return ret; -} - -int -InitResources( char **argv ) -{ - originalArgv = argv; - cnftalk.pipe = &getter.pipe; - if (Setjmp( cnftalk.errjmp )) - return 0; /* may memleak */ - return GetDeps(); -} - -static void -addServers( char **srv, int bType ) -{ - char *name, *class2; - const char *dtx, *cls; - struct display *d; - - for (; *srv; srv++) { - if ((cls = strchr( *srv, '_' ))) { - if (!StrNDup( &name, *srv, cls - *srv )) - return; - if (!StrDup( &class2, cls )) { - free( name ); - return; - } - } else { - if (!StrDup( &name, *srv )) - return; - class2 = 0; - } - if ((d = FindDisplayByName( name ))) { - if (d->class2) - free( d->class2 ); - dtx = "existing"; - } else { - if (!(d = NewDisplay( name ))) { - free( name ); - if (class2) - free( class2 ); - return; - } - dtx = "new"; - } - d->stillThere = 1; - d->class2 = class2; - d->displayType = (*name == ':' ? dLocal : dForeign) | bType; - if ((bType & d_lifetime) == dReserve) { - if (d->status == notRunning) - d->status = reserve; - } else { - if (d->status == reserve) - d->status = notRunning; - } - Debug( "found %s %s%s display: %s %s\n", dtx, - ((d->displayType & d_location) == dLocal) ? "local" : "foreign", - ((d->displayType & d_lifetime) == dReserve) ? " reserve" : "", - d->name, d->class2 ); - free( name ); - } -} - -void -ScanServers( void ) -{ - Debug( "ScanServers\n" ); - addServers( staticServers, dFromFile | dPermanent ); - addServers( reserveServers, dFromFile | dReserve ); -} - diff --git a/kdm/backend/rpcauth.c b/kdm/backend/rpcauth.c deleted file mode 100644 index 1186f72c2..000000000 --- a/kdm/backend/rpcauth.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * generate SecureRPC authorization records - */ - -#include <config.h> - -#ifdef SECURE_RPC - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include <rpc/rpc.h> -#include <rpc/key_prot.h> - -/*ARGSUSED*/ -void -SecureRPCInitAuth( unsigned short name_len ATTR_UNUSED, - const char *name ATTR_UNUSED ) -{ -} - -Xauth * -SecureRPCGetAuth( unsigned short namelen, const char *name ) -{ - Xauth *new; - char key[MAXNETNAMELEN+1]; - - new = (Xauth *)Malloc( sizeof(*new) ); - if (!new) - return (Xauth *)0; - new->family = FamilyWild; - new->address_length = 0; - new->address = 0; - new->number_length = 0; - new->number = 0; - - getnetname( key ); - Debug( "system netname %s\n", key ); - new->data_length = strlen( key ); - new->data = (char *)Malloc( new->data_length ); - if (!new->data) { - free( (char *)new ); - return (Xauth *)0; - } - new->name = (char *)Malloc( namelen ); - if (!new->name) { - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - memmove( new->name, name, namelen ); - new->name_length = namelen; - memmove( new->data, key, new->data_length ); - return new; -} - -#endif diff --git a/kdm/backend/server.c b/kdm/backend/server.c deleted file mode 100644 index e78d8a66c..000000000 --- a/kdm/backend/server.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2001,2003,2005 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * server.c - manage the X server - */ - -#include "dm.h" -#include "dm_error.h" -#include "dm_socket.h" - -#include <X11/Xlib.h> - -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> - - -struct display *startingServer; -time_t serverTimeout = TO_INF; - -char ** -PrepServerArgv( struct display *d, const char *args ) -{ - char **argv; -#ifdef HAVE_VTS - char vtstr[8]; -#endif - - if (!(argv = parseArgs( 0, d->serverCmd )) || - !(argv = parseArgs( argv, args )) || - !(argv = addStrArr( argv, d->name, -1 ))) - exit( 47 ); -#ifdef HAVE_VTS - if (d->serverVT && - !(argv = addStrArr( argv, vtstr, - sprintf( vtstr, "vt%d", d->serverVT ) ))) - exit( 47 ); -#endif - return argv; -} - -static void -StartServerOnce( void ) -{ - struct display *d = startingServer; - char **argv; - int pid; - - Debug( "StartServerOnce for %s, try %d\n", d->name, ++d->startTries ); - d->serverStatus = starting; - switch (pid = Fork()) { - case 0: - argv = PrepServerArgv( d, d->serverArgsLocal ); - if (d->authFile) { - if (!(argv = addStrArr( argv, "-auth", 5 )) || - !(argv = addStrArr( argv, d->authFile, -1 ))) - exit( 47 ); - } - Debug( "exec %\"[s\n", argv ); - /* - * give the server SIGUSR1 ignored, - * it will notice that and send SIGUSR1 - * when ready - */ - (void)Signal( SIGUSR1, SIG_IGN ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - - /* Let's try again with some standard paths */ - argv[0] = (char *)realloc(argv[0], strlen("/usr/X11R6/bin/X") + 1); - if (argv[0] != NULL) { - argv[0] = "/usr/X11R6/bin/X"; - Debug( "exec %\"[s\n", argv ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - - argv[0] = "/usr/bin/X"; /* Shorter than the previous file name */ - Debug( "exec %\"[s\n", argv ); - (void)execv( argv[0], argv ); - LogError( "X server %\"s cannot be executed\n", argv[0] ); - } - - exit( 47 ); - case -1: - LogError( "X server fork failed\n" ); - StartServerFailed(); - break; - default: - Debug( "X server forked, pid %d\n", pid ); - d->serverPid = pid; - serverTimeout = d->serverTimeout + now; - break; - } -} - -void -StartServer( struct display *d ) -{ - startingServer = d; - d->startTries = 0; - StartServerOnce(); -} - -void -AbortStartServer( struct display *d ) -{ - if (startingServer == d) - { - if (d->serverStatus != ignore) - { - d->serverStatus = ignore; - serverTimeout = TO_INF; - Debug( "aborting X server start\n" ); - } - startingServer = 0; - } -} - -void -StartServerSuccess() -{ - struct display *d = startingServer; - d->serverStatus = ignore; - serverTimeout = TO_INF; - Debug( "X server ready, starting session\n" ); - StartDisplayP2( d ); -} - -void -StartServerFailed() -{ - struct display *d = startingServer; - if (!d->serverAttempts || d->startTries < d->serverAttempts) { - d->serverStatus = pausing; - serverTimeout = d->openDelay + now; - } else { - d->serverStatus = ignore; - serverTimeout = TO_INF; - startingServer = 0; - LogError( "X server for display %s can't be started," - " session disabled\n", d->name ); - StopDisplay( d ); - } -} - -void -StartServerTimeout() -{ - struct display *d = startingServer; - switch (d->serverStatus) { - case ignore: - case awaiting: - break; /* cannot happen */ - case starting: - LogError( "X server startup timeout, terminating\n" ); - kill( d->serverPid, d->termSignal ); - d->serverStatus = d->termSignal == SIGKILL ? killed : terminated; - serverTimeout = d->serverTimeout + now; - break; - case terminated: - LogInfo( "X server termination timeout, killing\n" ); - kill( d->serverPid, SIGKILL ); - d->serverStatus = killed; - serverTimeout = 10 + now; - break; - case killed: - LogInfo( "X server is stuck in D state; leaving it alone\n" ); - StartServerFailed(); - break; - case pausing: - StartServerOnce(); - break; - } -} - - -Display *dpy; - -/* - * this code is complicated by some TCP failings. On - * many systems, the connect will occasionally hang forever, - * this trouble is avoided by setting up a timeout to Longjmp - * out of the connect (possibly leaving piles of garbage around - * inside Xlib) and give up, terminating the server. - */ - -static Jmp_buf openAbort; - -/* ARGSUSED */ -static void -abortOpen( int n ATTR_UNUSED ) -{ - Longjmp( openAbort, 1 ); -} - -#ifdef XDMCP - -#ifdef STREAMSCONN -# include <tiuser.h> -#endif - -static void -GetRemoteAddress( struct display *d, int fd ) -{ - char buf[512]; - int len = sizeof(buf); -#ifdef STREAMSCONN - struct netbuf netb; -#endif - - XdmcpDisposeARRAY8( &d->peer ); -#ifdef STREAMSCONN - netb.maxlen = sizeof(buf); - netb.buf = buf; - t_getname( fd, &netb, REMOTENAME ); - len = 8; - /* lucky for us, t_getname returns something that looks like a sockaddr */ -#else - getpeername( fd, (struct sockaddr *)buf, (void *)&len ); -#endif - if (len && XdmcpAllocARRAY8( &d->peer, len )) - memmove( (char *)d->peer.data, buf, len ); - Debug( "got remote address %s %d\n", d->name, d->peer.length ); -} - -#endif /* XDMCP */ - -static int -openErrorHandler( Display *dspl ATTR_UNUSED ) -{ - LogError( "IO Error in XOpenDisplay\n" ); - exit( EX_OPENFAILED_DPY ); - /*NOTREACHED*/ - return (0); -} - -void -WaitForServer( struct display *d ) -{ - volatile int i; - /* static int i; */ - - i = 0; - do { - (void)Signal( SIGALRM, abortOpen ); - (void)alarm( (unsigned)d->openTimeout ); - if (!Setjmp( openAbort )) { - Debug( "before XOpenDisplay(%s)\n", d->name ); - errno = 0; - (void)XSetIOErrorHandler( openErrorHandler ); - dpy = XOpenDisplay( d->name ); -#ifdef STREAMSCONN - { - /* For some reason, the next XOpenDisplay we do is - going to fail, so we might as well get that out - of the way. There is something broken here. */ - Display *bogusDpy = XOpenDisplay( d->name ); - Debug( "bogus XOpenDisplay %s\n", - bogusDpy ? "succeeded" : "failed" ); - if (bogusDpy) XCloseDisplay( bogusDpy ); /* just in case */ - } -#endif - (void)alarm( (unsigned)0 ); - (void)Signal( SIGALRM, SIG_DFL ); - (void)XSetIOErrorHandler( (int (*)( Display * )) 0 ); - Debug( "after XOpenDisplay(%s)\n", d->name ); - if (dpy) { -#ifdef XDMCP - if ((d->displayType & d_location) == dForeign) - GetRemoteAddress( d, ConnectionNumber( dpy ) ); -#endif - RegisterCloseOnFork( ConnectionNumber( dpy ) ); - return; - } - Debug( "OpenDisplay(%s) attempt %d failed: %m\n", d->name, i + 1 ); - sleep( (unsigned)d->openDelay ); - } else { - LogError( "Hung in XOpenDisplay(%s), aborting\n", d->name ); - (void)Signal( SIGALRM, SIG_DFL ); - break; - } - } while (++i < d->openRepeat); - LogError( "Cannot connect to %s, giving up\n", d->name ); - exit( EX_OPENFAILED_DPY ); -} - - -void -ResetServer( struct display *d ) -{ - if (dpy && (d->displayType & d_origin) != dFromXDMCP) - pseudoReset(); -} - - -static Jmp_buf pingTime; - -static void -PingLost( void ) -{ - Longjmp( pingTime, 1 ); -} - -/* ARGSUSED */ -static int -PingLostIOErr( Display *dspl ATTR_UNUSED ) -{ - PingLost(); - return 0; -} - -/* ARGSUSED */ -static void -PingLostSig( int n ATTR_UNUSED ) -{ - PingLost(); -} - -int -PingServer( struct display *d ) -{ - int (*oldError)( Display * ); - void (*oldSig)( int ); - int oldAlarm; - - oldError = XSetIOErrorHandler( PingLostIOErr ); - oldAlarm = alarm( 0 ); - oldSig = Signal( SIGALRM, PingLostSig ); - (void)alarm( d->pingTimeout * 60 ); - if (!Setjmp( pingTime )) { - Debug( "ping X server\n" ); - XSync( dpy, 0 ); - } else { - Debug( "X server dead\n" ); - (void)alarm( 0 ); - (void)Signal( SIGALRM, SIG_DFL ); - XSetIOErrorHandler( oldError ); - return 0; - } - (void)alarm( 0 ); - (void)Signal( SIGALRM, oldSig ); - (void)alarm( oldAlarm ); - Debug( "X server alive\n" ); - XSetIOErrorHandler( oldError ); - return 1; -} diff --git a/kdm/backend/session.c b/kdm/backend/session.c deleted file mode 100644 index 9a12ce312..000000000 --- a/kdm/backend/session.c +++ /dev/null @@ -1,813 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2000-2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * subdaemon event loop, etc. - */ - -#include "dm.h" -#include "dm_error.h" - -#include <X11/Xlib.h> -#include <X11/Xatom.h> -#include <X11/cursorfont.h> - -#include <stdio.h> -#include <ctype.h> -#include <signal.h> - -#ifdef WITH_CONSOLE_KIT -#include "consolekit.h" -#endif - -struct display *td; -const char *td_setup = "auto"; - -static void DeleteXloginResources( void ); -static void LoadXloginResources( void ); -static void SetupDisplay( const char *arg ); - - -static Jmp_buf pingTime; - -/* ARGSUSED */ -static void -catchAlrm( int n ATTR_UNUSED ) -{ - Longjmp( pingTime, 1 ); -} - -static Jmp_buf tenaciousClient; - -/* ARGSUSED */ -static void -waitAbort( int n ATTR_UNUSED ) -{ - Longjmp( tenaciousClient, 1 ); -} - -static void -AbortClient( int pid ) -{ - int sig = SIGTERM; - volatile int i; - int retId; - - for (i = 0; i < 4; i++) { - if (kill( -pid, sig ) == -1) { - switch (errno) { - case EPERM: - LogError( "Can't kill client\n" ); - case EINVAL: - case ESRCH: - return; - } - } - if (!Setjmp( tenaciousClient )) { - (void)Signal( SIGALRM, waitAbort ); - (void)alarm( (unsigned)10 ); - retId = wait( (waitType *)0 ); - (void)alarm( (unsigned)0 ); - (void)Signal( SIGALRM, SIG_DFL ); - if (retId == pid) - break; - } else - (void)Signal( SIGALRM, SIG_DFL ); - sig = SIGKILL; - } -} - - -static char * -conv_auto( int what, const char *prompt ATTR_UNUSED ) -{ - switch (what) { - case GCONV_USER: - return curuser; - case GCONV_PASS: - case GCONV_PASS_ND: - return curpass; - default: - LogError( "Unknown authentication data type requested for autologin.\n" ); - return 0; - } -} - -static void -DoAutoLogon( void ) -{ - ReStr( &curuser, td->autoUser ); - ReStr( &curpass, td->autoPass ); - ReStr( &curtype, "classic" ); - cursource = PWSRC_AUTOLOGIN; -} - -static int -AutoLogon( Time_t tdiff ) -{ - Debug( "autoLogon, tdiff = %d, rLogin = %d, goodexit = %d, nuser = %s\n", - tdiff, td->hstent->rLogin, td->hstent->goodExit, td->hstent->nuser ); - if (td->hstent->rLogin == 2 || - (td->hstent->rLogin == 1 && - tdiff <= 0 && !td->hstent->goodExit && !td->hstent->lock)) - { - curuser = td->hstent->nuser; - td->hstent->nuser = 0; - curpass = td->hstent->npass; - td->hstent->npass = 0; - newdmrc = td->hstent->nargs; - td->hstent->nargs = 0; - ReStr( &curtype, "classic" ); - cursource = (td->hstent->rLogin == 1) ? PWSRC_RELOGIN : PWSRC_MANUAL; - return 1; - } else if (*td->autoUser && !td->autoDelay && - ((tdiff > 0 && ((td->displayType & d_lifetime) == dTransient || - !td->hstent->lastExit)) || - td->autoAgain)) - { - unsigned int lmask; - Window dummy1, dummy2; - int dummy3, dummy4, dummy5, dummy6; - XQueryPointer( dpy, DefaultRootWindow( dpy ), - &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, - &lmask ); - if (lmask & ShiftMask) - return 0; - DoAutoLogon(); - return 1; - } - return 0; -} - - -static const struct { - int vcode, echo, ndelay; -} grqs[] = { - { V_GET_TEXT, TRUE, FALSE }, - { V_GET_TEXT, FALSE, FALSE }, - { V_GET_TEXT, TRUE, FALSE }, - { V_GET_TEXT, FALSE, FALSE }, - { V_GET_TEXT, FALSE, TRUE }, - { V_GET_BINARY, 0, 0 } -}; - -char * -conv_interact( int what, const char *prompt ) -{ - char *ret; - int tag; - - GSendInt( grqs[what].vcode ); - if (what == GCONV_BINARY) { - unsigned const char *up = (unsigned const char *)prompt; - int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24); - GSendArr( len, prompt ); - GSendInt( FALSE ); /* ndelay */ - return GRecvArr( &len ); - } else { - GSendStr( prompt ); - GSendInt( grqs[what].echo ); - GSendInt( grqs[what].ndelay ); - ret = GRecvStr(); - if (ret) { - tag = GRecvInt(); - switch (what) { - case GCONV_USER: - /* assert(tag & V_IS_USER); */ - if (curuser) - free( curuser ); - curuser = ret; - break; - case GCONV_PASS: - case GCONV_PASS_ND: - /* assert(tag & V_IS_PASSWORD); */ - if (curpass) - free( curpass ); - curpass = ret; - break; - default: - if (tag & V_IS_USER) - ReStr( &curuser, ret ); - else if (tag & V_IS_PASSWORD) - ReStr( &curpass, ret ); - else if (tag & V_IS_NEWPASSWORD) - ReStr( &newpass, ret ); - else if (tag & V_IS_OLDPASSWORD) - ReStr( &ret, curpass ); - } - } - return ret; - } -} - -static int greeter; -GProc grtproc; -GTalk grttalk; - -GTalk mstrtalk; /* make static; see dm.c */ - -int -CtrlGreeterWait( int wreply ) -{ - int i, cmd, type, rootok; - char *name, *pass, **avptr; -#ifdef XDMCP - ARRAY8Ptr aptr; -#endif - - if (Setjmp( mstrtalk.errjmp )) { - CloseGreeter( TRUE ); - SessionExit( EX_UNMANAGE_DPY ); - } - - while (GRecvCmd( &cmd )) { - switch (cmd) - { - case G_Ready: - Debug( "G_Ready\n" ); - return 0; - case G_GetCfg: - /*Debug ("G_GetCfg\n");*/ - type = GRecvInt(); - /*Debug (" index %#x\n", type);*/ - if (type == C_isLocal) - i = (td->displayType & d_location) == dLocal; - else if (type == C_hasConsole) -#ifdef HAVE_VTS - i = *consoleTTYs != 0; -#else - i = td->console != 0; -#endif - else if (type == C_isAuthorized) - i = td->authorizations != 0; - else - goto normal; - GSendInt( GE_Ok ); - /*Debug (" -> bool %d\n", i);*/ - GSendInt( i ); - break; - normal: - if (!(avptr = FindCfgEnt( td, type ))) { - /*Debug (" -> not found\n");*/ - GSendInt( GE_NoEnt ); - break; - } - switch (type & C_TYPE_MASK) { - default: - /*Debug (" -> unknown type\n");*/ - GSendInt( GE_BadType ); - break; - case C_TYPE_INT: - case C_TYPE_STR: - case C_TYPE_ARGV: -#ifdef XDMCP - case C_TYPE_ARR: -#endif - GSendInt( GE_Ok ); - switch (type & C_TYPE_MASK) { - case C_TYPE_INT: - /*Debug (" -> int %#x (%d)\n", *(int *)avptr, *(int *)avptr);*/ - GSendInt( *(long *)avptr ); - break; - case C_TYPE_STR: - /*Debug (" -> string %\"s\n", *avptr);*/ - GSendStr( *avptr ); - break; - case C_TYPE_ARGV: - /*Debug (" -> sending argv %\"[{s\n", *(char ***)avptr);*/ - GSendArgv( *(char ***)avptr ); - break; -#ifdef XDMCP - case C_TYPE_ARR: - aptr = *(ARRAY8Ptr *)avptr; - /*Debug (" -> sending array %02[*:hhx\n", - aptr->length, aptr->data);*/ - GSendArr( aptr->length, (char *)aptr->data ); - break; -#endif - } - break; - } - break; - case G_ReadDmrc: - Debug( "G_ReadDmrc\n" ); - name = GRecvStr(); - Debug( " user %\"s\n", name ); - if (StrCmp( dmrcuser, name )) { - if (curdmrc) { free( curdmrc ); curdmrc = 0; } - if (dmrcuser) - free( dmrcuser ); - dmrcuser = name; - i = ReadDmrc(); - Debug( " -> status %d\n", i ); - GSendInt( i ); - Debug( " => %\"s\n", curdmrc ); - } else { - if (name) - free( name ); - Debug( " -> status " stringify( GE_Ok ) "\n" ); - GSendInt( GE_Ok ); - Debug( " => keeping old\n" ); - } - break; - case G_GetDmrc: - Debug( "G_GetDmrc\n" ); - name = GRecvStr(); - Debug( " key %\"s\n", name ); - pass = iniEntry( curdmrc, "Desktop", name, 0 ); - Debug( " -> %\"s\n", pass ); - GSendStr( pass ); - if (pass) - free( pass ); - free( name ); - break; -/* case G_ResetDmrc: - Debug ("G_ResetDmrc\n"); - if (newdmrc) { free (newdmrc); newdmrc = 0; } - break; */ - case G_PutDmrc: - Debug( "G_PutDmrc\n" ); - name = GRecvStr(); - Debug( " key %\"s\n", name ); - pass = GRecvStr(); - Debug( " value %\"s\n", pass ); - newdmrc = iniEntry( newdmrc, "Desktop", name, pass ); - free( pass ); - free( name ); - break; - case G_VerifyRootOK: - Debug( "G_VerifyRootOK\n" ); - rootok = TRUE; - goto doverify; - case G_Verify: - Debug( "G_Verify\n" ); - rootok = FALSE; - doverify: - if (curuser) { free( curuser ); curuser = 0; } - if (curpass) { free( curpass ); curpass = 0; } - if (curtype) free( curtype ); - curtype = GRecvStr(); - Debug( " type %\"s\n", curtype ); - cursource = PWSRC_MANUAL; - if (Verify( conv_interact, rootok )) { - Debug( " -> return success\n" ); - GSendInt( V_OK ); - } else - Debug( " -> failure returned\n" ); - break; - case G_AutoLogin: - Debug( "G_AutoLogin\n" ); - DoAutoLogon(); - if (Verify( conv_auto, FALSE )) { - Debug( " -> return success\n" ); - GSendInt( V_OK ); - } else - Debug( " -> failure returned\n" ); - break; - case G_SetupDpy: - Debug( "G_SetupDpy\n" ); - SetupDisplay( 0 ); - td_setup = 0; - GSendInt( 0 ); - break; - default: - return cmd; - } - if (!wreply) - return -1; - } - Debug( "lost connection to greeter\n" ); - return -2; -} - -void -OpenGreeter() -{ - char *name, **env; - static Time_t lastStart; - int cmd; - Cursor xcursor; - - GSet( &grttalk ); - if (greeter) - return; - if (time( 0 ) < lastStart + 10) /* XXX should use some readiness indicator instead */ - SessionExit( EX_UNMANAGE_DPY ); - greeter = 1; - ASPrintf( &name, "greeter for display %s", td->name ); - Debug( "starting %s\n", name ); - - /* Hourglass cursor */ - if ((xcursor = XCreateFontCursor( dpy, XC_watch ))) { - XDefineCursor( dpy, DefaultRootWindow( dpy ), xcursor ); - XFreeCursor( dpy, xcursor ); - } - XFlush( dpy ); - - /* Load system default Resources (if any) */ - LoadXloginResources(); - - grttalk.pipe = &grtproc.pipe; - env = systemEnv( (char *)0 ); - if (GOpen( &grtproc, (char **)0, "_greet", env, name, &td->gpipe )) - SessionExit( EX_UNMANAGE_DPY ); - freeStrArr( env ); - if ((cmd = CtrlGreeterWait( TRUE ))) { - if (cmd != -2) - LogError( "Received unknown or unexpected command %d from greeter\n", cmd ); - CloseGreeter( TRUE ); - SessionExit( EX_UNMANAGE_DPY ); - } - Debug( "%s ready\n", name ); - time( &lastStart ); -} - -int -CloseGreeter( int force ) -{ - int ret; - - if (!greeter) - return EX_NORMAL; - greeter = 0; - ret = GClose (&grtproc, 0, force); - Debug( "greeter for %s stopped\n", td->name ); - if (WaitCode( ret ) > EX_NORMAL && WaitCode( ret ) <= EX_MAX) { - Debug( "greeter-initiated session exit, code %d\n", WaitCode( ret ) ); - SessionExit( WaitCode( ret ) ); - } - return ret; -} - -void -PrepErrorGreet() -{ - if (!greeter) { - OpenGreeter(); - GSendInt( G_ErrorGreet ); - GSendStr( curuser ); - } -} - -static Jmp_buf idleTOJmp; - -/* ARGSUSED */ -static void -IdleTOJmp( int n ATTR_UNUSED ) -{ - Longjmp( idleTOJmp, 1 ); -} - - -static Jmp_buf abortSession; - -/* ARGSUSED */ -static void -catchTerm( int n ATTR_UNUSED ) -{ - Signal( SIGTERM, SIG_IGN ); - Longjmp( abortSession, EX_AL_RESERVER_DPY ); -} - -/* - * We need our own error handlers because we can't be sure what exit code Xlib - * will use, and our Xlib does exit(1) which matches EX_REMANAGE_DPY, which - * can cause a race condition leaving the display wedged. We need to use - * EX_RESERVER_DPY for IO errors, to ensure that the manager waits for the - * server to terminate. For other X errors, we should give up. - */ - -/*ARGSUSED*/ -static int -IOErrorHandler( Display *dspl ATTR_UNUSED ) -{ - LogError( "Fatal X server IO error: %m\n" ); - /* The only X interaction during the session are pings, and those - have an own IOErrorHandler -> not EX_AL_RESERVER_DPY */ - Longjmp( abortSession, EX_RESERVER_DPY ); - /*NOTREACHED*/ - return 0; -} - -/*ARGSUSED*/ -static int -ErrorHandler( Display *dspl ATTR_UNUSED, XErrorEvent *event ) -{ - LogError( "X error\n" ); - if (event->error_code == BadImplementation) - Longjmp( abortSession, EX_UNMANAGE_DPY ); - return 0; -} - -void -ManageSession( struct display *d ) -{ - int ex, cmd; - volatile int clientPid = 0; - volatile Time_t tdiff = 0; -#ifdef WITH_CONSOLE_KIT - char *ck_session_cookie; -#endif - - - td = d; - Debug( "ManageSession %s\n", d->name ); - if ((ex = Setjmp( abortSession ))) { - CloseGreeter( TRUE ); - if (clientPid) - AbortClient( clientPid ); - SessionExit( ex ); - /* NOTREACHED */ - } - (void)XSetIOErrorHandler( IOErrorHandler ); - (void)XSetErrorHandler( ErrorHandler ); - (void)Signal( SIGTERM, catchTerm ); - - (void)Signal( SIGHUP, SIG_IGN ); - - if (Setjmp( grttalk.errjmp )) - Longjmp( abortSession, EX_RESERVER_DPY ); /* EX_RETRY_ONCE */ - -#ifdef XDMCP - if (d->useChooser) - DoChoose(); - /* NOTREACHED */ -#endif - - if (d->hstent->sdRec.how) { - OpenGreeter(); - GSendInt( G_ConfShutdown ); - GSendInt( d->hstent->sdRec.how ); - GSendInt( d->hstent->sdRec.uid ); - GSendStr( d->hstent->sdRec.osname ); - if ((cmd = CtrlGreeterWait( TRUE )) != G_Ready) { - LogError( "Received unknown command %d from greeter\n", cmd ); - CloseGreeter( TRUE ); - } - goto regreet; - } - - tdiff = time( 0 ) - td->hstent->lastExit - td->openDelay; - if (AutoLogon( tdiff )) { - if (!Verify( conv_auto, FALSE )) - goto gcont; - if (greeter) - GSendInt( V_OK ); - } else { - regreet: - OpenGreeter(); - if (Setjmp( idleTOJmp )) { - CloseGreeter( TRUE ); - SessionExit( EX_NORMAL ); - } - Signal( SIGALRM, IdleTOJmp ); - alarm( td->idleTimeout ); -#ifdef XDMCP - if (((d->displayType & d_location) == dLocal) && - d->loginMode >= LOGIN_DEFAULT_REMOTE) - goto choose; -#endif - for (;;) { - Debug( "ManageSession, greeting, tdiff = %d\n", tdiff ); - GSendInt( (*td->autoUser && td->autoDelay && - (tdiff > 0 || td->autoAgain)) ? - G_GreetTimed : G_Greet ); - gcont: - cmd = CtrlGreeterWait( TRUE ); -#ifdef XDMCP - recmd: - if (cmd == G_DChoose) { - choose: - cmd = DoChoose(); - goto recmd; - } - if (cmd == G_DGreet) - continue; -#endif - alarm( 0 ); - if (cmd == G_Ready) - break; - if (cmd == -2) - CloseGreeter( FALSE ); - else { - LogError( "Received unknown command %d from greeter\n", cmd ); - CloseGreeter( TRUE ); - } - goto regreet; - } - } - - if (CloseGreeter( FALSE ) != EX_NORMAL) - goto regreet; - - DeleteXloginResources(); - - if (td_setup) - SetupDisplay( td_setup ); - -#ifdef WITH_CONSOLE_KIT - ck_session_cookie = open_ck_session (getpwnam(curuser), d); - if (!(clientPid = StartClient(ck_session_cookie))) { -#else - if (!(clientPid = StartClient())) { -#endif - LogError( "Client start failed\n" ); - SessionExit( EX_NORMAL ); /* XXX maybe EX_REMANAGE_DPY? -- enable in dm.c! */ - } - Debug( "client Started\n" ); - - /* - * Wait for session to end, - */ - for (;;) { - if (!Setjmp( pingTime )) { - (void)Signal( SIGALRM, catchAlrm ); - (void)alarm( d->pingInterval * 60 ); /* may be 0 */ - (void)Wait4( clientPid ); - (void)alarm( 0 ); - break; - } else { - (void)alarm( 0 ); - if (!PingServer( d )) - catchTerm( SIGTERM ); - } - } - -#ifdef WITH_CONSOLE_KIT - if (ck_session_cookie != NULL) { - close_ck_session (ck_session_cookie); - free (ck_session_cookie); - } -#endif - - /* - * Sometimes the Xsession somehow manages to exit before - * a server crash is noticed - so we sleep a bit and wait - * for being killed. - */ - if (!PingServer( d )) { - Debug( "X server dead upon session exit.\n" ); - if ((d->displayType & d_location) == dLocal) - sleep( 10 ); - SessionExit( EX_AL_RESERVER_DPY ); - } - SessionExit( EX_NORMAL ); /* XXX maybe EX_REMANAGE_DPY? -- enable in dm.c! */ -} - -static int xResLoaded; - -void -LoadXloginResources() -{ - char **args; - char **env; - - if (!xResLoaded && td->resources[0] && access( td->resources, 4 ) == 0) { - env = systemEnv( (char *)0 ); - if ((args = parseArgs( (char **)0, td->xrdb )) && - (args = addStrArr( args, td->resources, -1 ))) - { - Debug( "loading resource file: %s\n", td->resources ); - (void)runAndWait( args, env ); - freeStrArr( args ); - } - freeStrArr( env ); - xResLoaded = TRUE; - } -} - -void -SetupDisplay( const char *arg ) -{ - char **env; - - env = systemEnv( (char *)0 ); - (void)source( env, td->setup, arg ); - freeStrArr( env ); -} - -void -DeleteXloginResources() -{ - int i; - Atom prop; - - if (!xResLoaded) - return; - xResLoaded = FALSE; - prop = XInternAtom( dpy, "SCREEN_RESOURCES", True ); - XDeleteProperty( dpy, RootWindow( dpy, 0 ), XA_RESOURCE_MANAGER ); - if (prop) - for (i = ScreenCount(dpy); --i >= 0; ) - XDeleteProperty( dpy, RootWindow( dpy, i ), prop ); - XSync( dpy, 0 ); -} - - -int -source( char **env, const char *file, const char *arg ) -{ - char **args; - int ret; - - if (file && file[0]) { - Debug( "source %s\n", file ); - if (!(args = parseArgs( (char **)0, file ))) - return waitCompose( 0,0,3 ); - if (arg && !(args = addStrArr( args, arg, -1 ))) - return waitCompose( 0,0,3 ); - ret = runAndWait( args, env ); - freeStrArr( args ); - return ret; - } - return 0; -} - -char ** -inheritEnv( char **env, const char **what ) -{ - char *value; - - for (; *what; ++what) - if ((value = getenv( *what ))) - env = setEnv( env, *what, value ); - return env; -} - -char ** -baseEnv( const char *user ) -{ - char **env; - - env = 0; - -#ifdef _AIX - /* we need the tags SYSENVIRON: and USRENVIRON: in the call to setpenv() */ - env = setEnv( env, "SYSENVIRON:", 0 ); -#endif - - if (user) { - env = setEnv( env, "USER", user ); -#ifdef _AIX - env = setEnv( env, "LOGIN", user ); -#endif - env = setEnv( env, "LOGNAME", user ); - } - -#ifdef _AIX - env = setEnv( env, "USRENVIRON:", 0 ); -#endif - - env = inheritEnv( env, (const char **)exportList ); - - env = setEnv( env, "DISPLAY", - memcmp( td->name, "localhost:", 10 ) ? - td->name : td->name + 9 ); - - if (td->ctrl.path) - env = setEnv( env, "DM_CONTROL", fifoDir ); - - return env; -} - -char ** -systemEnv( const char *user ) -{ - char **env; - - env = baseEnv( user ); - if (td->authFile) - env = setEnv( env, "XAUTHORITY", td->authFile ); - env = setEnv( env, "PATH", td->systemPath ); - env = setEnv( env, "SHELL", td->systemShell ); - return env; -} diff --git a/kdm/backend/sessreg.c b/kdm/backend/sessreg.c deleted file mode 100644 index b507f8141..000000000 --- a/kdm/backend/sessreg.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - -Copyright 1990, 1998 The Open Group -Copyright 2005 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -*/ - -/* - - Author: Keith Packard, MIT X Consortium - Lastlog support and dynamic utmp entry allocation - by Andreas Stolcke <[email protected]> - -*/ - -#define _FILE_OFFSET_BITS 64 -#include "dm.h" -#include "dm_error.h" - -#if defined(__svr4__) || defined(__Lynx__) || defined(__QNX__) || defined(__APPLE__) || defined(_SEQUENT_) /*|| defined(USE_PAM)*/ -# define NO_LASTLOG -#endif - -#ifndef NO_LASTLOG -# ifdef HAVE_LASTLOG_H -# include <lastlog.h> -# endif -# ifndef LLOG_FILE -# ifdef _PATH_LASTLOGX -# define LLOG_FILE _PATH_LASTLOGX -# elif defined(_PATH_LASTLOG) -# define LLOG_FILE _PATH_LASTLOG -# else -# define LLOG_FILE "/usr/adm/lastlog" -# endif -# endif -#endif - -#if !defined(__svr4__) && !defined(__QNX__) -# define SESSREG_HOST -#endif - -#ifdef BSD -# if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -/* *BSD doesn't like a ':0' type entry in utmp */ -# define NO_UTMP -# endif -#endif - -#ifdef BSD_UTMP -# ifndef TTYS_FILE -# define TTYS_FILE "/etc/ttys" -# endif -#endif - -#ifdef _AIX -# define UTL_PFX "xdm/" -# define UTL_OFF strlen(UTL_PFX) -#else -# define UTL_OFF 0 -#endif - -#ifndef BSD_UTMP -static unsigned -crc32s( const unsigned char *str ) -{ - int b; - unsigned crc = 0xffffffff, by; - - for (; *str; str++) { - by = (crc & 255) ^ *str; - for (b = 0; b < 8; b++) - by = (by >> 1) ^ (-(by & 1) & 0xedb88320); - crc = (crc >> 8) ^ by; - } - return crc; -} -#endif - -void -sessreg( struct display *d, int pid, const char *user, int uid ) -{ - char *dot, *colon; - int left, clen; -#ifdef BSD_UTMP - FILE *ttys; - int utmp, slot, freeslot; - STRUCTUTMP entry; -#else - unsigned crc, i; -#endif - int wtmp, c; -#ifndef NO_LASTLOG - int llog; - struct LASTLOG ll; -#endif - STRUCTUTMP ut_ent; - - if (!d->useSessReg) - return; - - bzero( &ut_ent, sizeof(ut_ent) ); - - if (pid) { - strncpy( ut_ent.ut_user, user, sizeof(ut_ent.ut_user) ); -#ifndef BSD_UTMP - ut_ent.ut_pid = pid; - ut_ent.ut_type = USER_PROCESS; - } else { - ut_ent.ut_type = DEAD_PROCESS; -#endif - } - ut_ent.ut_time = time( 0 ); - - colon = strchr( d->name, ':' ); - clen = strlen( colon ); - if (clen > (int)(sizeof(ut_ent.ut_line) - UTL_OFF) - 2) - return; /* uhm, well ... */ - if (colon == d->name) { -#ifndef BSD_UTMP - strncpy( ut_ent.ut_id, d->name, sizeof(ut_ent.ut_id) ); -#endif - left = 0; - } else { -#ifdef SESSREG_HOST -# ifndef BSD_UTMP - if (pid) -# endif - { - if (colon - d->name > (int)sizeof(ut_ent.ut_host)) { - ut_ent.ut_host[0] = '~'; - memcpy( ut_ent.ut_host + 1, - colon - (sizeof(ut_ent.ut_host) - 1), - sizeof(ut_ent.ut_host) - 1 ); - } else - memcpy( ut_ent.ut_host, d->name, colon - d->name ); - } -#endif -#ifndef BSD_UTMP - crc = crc32s( d->name ); - ut_ent.ut_id[0] = crc % 26 + 'A'; - crc /= 26; - for (i = 1; i < sizeof(ut_ent.ut_id); i++) { - c = crc % 62; - crc /= 62; - ut_ent.ut_id[i] = c < 26 ? c + 'A' : - c < 52 ? c - 26 + 'a' : c - 52 + '0'; - } -#endif - left = sizeof(ut_ent.ut_line) - UTL_OFF - clen; - if (colon - d->name <= left) { - clen += colon - d->name; - colon = d->name; - left = 0; - } else { - dot = strchr( d->name, '.' ); - if (dot && dot - d->name < left) { - memcpy( ut_ent.ut_line + UTL_OFF, d->name, left - 1 ); - ut_ent.ut_line[UTL_OFF + left - 1] = '~'; - } else { - memcpy( ut_ent.ut_line + UTL_OFF, d->name, left/2 - 1 ); - ut_ent.ut_line[UTL_OFF + left/2 - 1] = '~'; - if (dot) { - memcpy( ut_ent.ut_line + UTL_OFF + left/2, - dot - (left - left/2 - 1), - left - left/2 - 1 ); - ut_ent.ut_line[UTL_OFF + left - 1] = '~'; - } else - memcpy( ut_ent.ut_line + UTL_OFF + left/2, - colon - (left - left/2), left - left/2 ); - } - } - } -#ifdef UTL_PFX - memcpy( ut_ent.ut_line, UTL_PFX, UTL_OFF ); -#endif - memcpy( ut_ent.ut_line + UTL_OFF + left, colon, clen ); - -#ifndef NO_UTMP -# ifdef BSD_UTMP - if ((utmp = open( UTMP_FILE, O_RDWR )) < 0) - Debug( "cannot open utmp file " UTMP_FILE ": %m\n" ); - else { - - slot = 1; - if (pid) { - if (!(ttys = fopen( TTYS_FILE, "r" ))) - LogWarn( "Cannot open tty file " TTYS_FILE ": %m\n" ); - else { - int column0 = 1; - while ((c = getc( ttys )) != EOF) - if (c == '\n') { - slot++; - column0 = 1; - } else - column0 = 0; - if (!column0) - slot++; - fclose( ttys ); - } - } - freeslot = -1; - lseek( utmp, slot * sizeof(entry), SEEK_SET ); - while (read( utmp, (char *)&entry, sizeof(entry) ) == sizeof(entry)) { - if (!strncmp( entry.ut_line, ut_ent.ut_line, - sizeof(entry.ut_line) )) -# ifdef SESSREG_HOST - if (!strncmp( entry.ut_host, ut_ent.ut_host, - sizeof(entry.ut_host) )) -# endif - goto found; - if (freeslot < 0 && *entry.ut_user == '\0') - freeslot = slot; - slot++; - } - if (!pid) { - Debug( "utmp entry for display %s vanished\n", d->name ); - goto skip; - } - if (freeslot >= 0) - slot = freeslot; - found: - -# ifdef SESSREG_HOST - if (!pid) - bzero( ut_ent.ut_host, sizeof(ut_ent.ut_host) ); -# endif - lseek( utmp, slot * sizeof(ut_ent), SEEK_SET ); - if (write( utmp, (char *)&ut_ent, sizeof(ut_ent) ) != sizeof(ut_ent)) - LogError( "Cannot write utmp file " UTMP_FILE ": %m\n" ); - skip: - close( utmp ); - } -# else - UTMPNAME( UTMP_FILE ); - SETUTENT(); - PUTUTLINE( &ut_ent ); - ENDUTENT(); -# endif -#endif - - if ((wtmp = open( WTMP_FILE, O_WRONLY|O_APPEND )) < 0) - Debug( "cannot open wtmp file " WTMP_FILE ": %m\n" ); - else { - if (write( wtmp, (char *)&ut_ent, sizeof(ut_ent) ) != sizeof(ut_ent)) - LogError( "Cannot write wtmp file " WTMP_FILE ": %m\n" ); - close( wtmp ); - } - -#ifndef NO_LASTLOG - if (pid) { - bzero( (char *)&ll, sizeof(ll) ); - ll.ll_time = ut_ent.ut_time; - memcpy( ll.ll_line, ut_ent.ut_line, sizeof(ll.ll_line) ); - memcpy( ll.ll_host, ut_ent.ut_host, sizeof(ll.ll_host) ); -# ifdef HAVE_UTMPX - updlastlogx( LLOG_FILE, uid, &ll ); -# else - if ((llog = open( LLOG_FILE, O_RDWR )) < 0) - Debug( "cannot open lastlog file " LLOG_FILE ": %m\n" ); - else { - lseek( llog, (off_t)uid * sizeof(ll), SEEK_SET ); - if (write( llog, (char *)&ll, sizeof(ll) ) != sizeof(ll)) - LogError( "Cannot write llog file " WTMP_FILE ": %m\n" ); - close( llog ); - } -# endif - } -#else - (void)uid; -#endif - -#ifdef UTL_PFX - { - char tmp[sizeof("/dev/") + sizeof(ut_ent.ut_line)]; - mkdir( "/dev/" UTL_PFX, 0755 ); - chmod( "/dev/" UTL_PFX, 0755 ); - sprintf( tmp, "/dev/%.*s", sizeof(ut_ent.ut_line), ut_ent.ut_line ); - if (pid) - close( creat( tmp, 0644 ) ); - else - unlink( tmp ); - } -#endif -} diff --git a/kdm/backend/socket.c b/kdm/backend/socket.c deleted file mode 100644 index 677a3d32f..000000000 --- a/kdm/backend/socket.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2002 Sun Microsystems, Inc. All rights reserved. -Copyright 2002,2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * socket.c - Support for BSD sockets - */ - -#include "dm.h" - -#if defined(XDMCP) && !defined(STREAMSCONN) - -#include "dm_error.h" -#include "dm_socket.h" - -#include <netdb.h> -#include <arpa/inet.h> - -static int c_request_port; - -static int -CreateListeningSocket( struct sockaddr *sock_addr, int salen ) -{ - int fd; -#if defined(IPv6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) - int on = 0; -#endif - const char *addrstring = "unknown"; -#if defined(IPv6) && defined(AF_INET6) - char addrbuf[INET6_ADDRSTRLEN]; -#endif - - if (!request_port) - return -1; - - if (debugLevel & DEBUG_CORE) { -#if defined(IPv6) && defined(AF_INET6) - void *ipaddr; - if (sock_addr->sa_family == AF_INET6) - ipaddr = & ((struct sockaddr_in6 *)sock_addr)->sin6_addr; - else - ipaddr = & ((struct sockaddr_in *)sock_addr)->sin_addr; - addrstring = - inet_ntop( sock_addr->sa_family, ipaddr, addrbuf, sizeof(addrbuf) ); - -#else - addrstring = inet_ntoa( ((struct sockaddr_in *)sock_addr)->sin_addr ); -#endif - - Debug( "creating socket to listen on port %d of address %s\n", - request_port, addrstring ); - } - - if ((fd = socket( sock_addr->sa_family, SOCK_DGRAM, 0 )) == -1) { - LogError( "XDMCP socket creation failed, errno %d\n", errno ); - return -1; - } -#if defined(IPv6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) - setsockopt( fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on) ); -#endif - - if (bind( fd, sock_addr, salen ) == -1) { - LogError( "error %d binding socket address %d\n", errno, request_port ); - close( fd ); - return -1; - } - - RegisterCloseOnFork( fd ); - RegisterInput( fd ); - return fd; -} - -struct socklist { - struct socklist *next; - struct socklist *mcastgroups; - struct sockaddr *addr; - int salen; - int addrlen; - int fd; - int ref; /* referenced bit - see UpdateListenSockets */ -}; - -static struct socklist *listensocks; - -static void -DestroyListeningSocket( struct socklist *s ) -{ - struct socklist *g, *n; - - if (s->fd >= 0) { - CloseNClearCloseOnFork( s->fd ); - UnregisterInput( s->fd ); - s->fd = -1; - } - if (s->addr) { - free( s->addr ); - s->addr = NULL; - } - for (g = s->mcastgroups; g; g = n) { - n = g->next; - if (g->addr) - free( g->addr ); - free( g ); - } - s->mcastgroups = NULL; -} - -static struct socklist* -FindInList( struct socklist *list, ARRAY8Ptr addr ) -{ - struct socklist *s; - - for (s = list; s; s = s->next) { - if (s->addrlen == addr->length) { - char *addrdata; - - switch (s->addr->sa_family) { - case AF_INET: - addrdata = (char *) - &(((struct sockaddr_in *)s->addr)->sin_addr.s_addr); - break; -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - addrdata = (char *) - &(((struct sockaddr_in6 *)s->addr)->sin6_addr.s6_addr); - break; -#endif - default: - /* Unrecognized address family */ - continue; - } - if (!memcmp( addrdata, addr->data, addr->length )) - return s; - } - } - return NULL; -} - -static struct socklist * -CreateSocklistEntry( ARRAY8Ptr addr ) -{ - struct socklist *s; - - if (!(s = Calloc( 1, sizeof(struct socklist) ))) - return NULL; - - if (addr->length == 4) { /* IPv4 */ - struct sockaddr_in *sin4; - sin4 = Calloc( 1, sizeof(struct sockaddr_in) ); -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin4->sin_len = sizeof(struct sockaddr_in); -#endif - s->addr = (struct sockaddr *)sin4; - s->salen = sizeof(struct sockaddr_in); - s->addrlen = sizeof(struct in_addr); - sin4->sin_family = AF_INET; - sin4->sin_port = htons( (short)request_port ); - memcpy( &sin4->sin_addr, addr->data, addr->length ); - } -#if defined(IPv6) && defined(AF_INET6) - else if (addr->length == 16) { /* IPv6 */ - struct sockaddr_in6 *sin6; - sin6 = Calloc( 1, sizeof(struct sockaddr_in6) ); -#ifdef SIN6_LEN - sin6->sin6_len = sizeof(struct sockaddr_in6); -#endif - s->addr = (struct sockaddr *)sin6; - s->salen = sizeof(struct sockaddr_in6); - s->addrlen = sizeof(struct in6_addr); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = htons( (short)request_port ); - memcpy( &sin6->sin6_addr, addr->data, addr->length ); - } -#endif - else { - /* Unknown address type */ - free( s ); - s = NULL; - } - return s; -} - -static void -UpdateListener( ARRAY8Ptr addr, void **closure ) -{ - struct socklist *s; - - *closure = NULL; - - if (addr == NULL) { - ARRAY8 tmpaddr; - struct in_addr in; -#if defined(IPv6) && defined(AF_INET6) - struct in6_addr in6 = in6addr_any; - tmpaddr.length = sizeof(in6); - tmpaddr.data = (CARD8Ptr) &in6; - UpdateListener( &tmpaddr, closure ); - if (*closure) - return; -#endif - in.s_addr = htonl( INADDR_ANY ); - tmpaddr.length = sizeof(in); - tmpaddr.data = (CARD8Ptr) ∈ - UpdateListener( &tmpaddr, closure ); - return; - } - - if (c_request_port == request_port && - (s = FindInList( listensocks, addr ))) - { - *closure = (void *)s; - s->ref = 1; - return; - } - - if (!(s = CreateSocklistEntry( addr ))) - return; - - if ((s->fd = CreateListeningSocket( s->addr, s->salen )) < 0) { - free( s->addr ); - free( s ); - return; - } - s->ref = 1; - s->next = listensocks; - listensocks = s; - *closure = (void *)s; -} - -#define JOIN_MCAST_GROUP 0 -#define LEAVE_MCAST_GROUP 1 - -static void -ChangeMcastMembership( struct socklist *s, struct socklist *g, int op ) -{ - int sockopt; - - switch (s->addr->sa_family) - { - case AF_INET: - { - struct ip_mreq mreq; - memcpy( &mreq.imr_multiaddr, - &((struct sockaddr_in *)g->addr)->sin_addr, - sizeof(struct in_addr) ); - memcpy( &mreq.imr_interface, - &((struct sockaddr_in *)s->addr)->sin_addr, - sizeof(struct in_addr) ); - if (op == JOIN_MCAST_GROUP) - sockopt = IP_ADD_MEMBERSHIP; - else - sockopt = IP_DROP_MEMBERSHIP; - if (setsockopt( s->fd, IPPROTO_IP, sockopt, - &mreq, sizeof(mreq) ) < 0) { - LogError( "XDMCP socket multicast %s to %s failed, errno %d\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", - inet_ntoa( ((struct sockaddr_in *)g->addr)->sin_addr ), - errno ); - } else if (debugLevel & DEBUG_CORE) { - Debug( "XDMCP socket multicast %s to %s succeeded\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", - inet_ntoa( ((struct sockaddr_in *)g->addr)->sin_addr ) ); - } - return; - } -#if defined(IPv6) && defined(AF_INET6) -# ifndef IPV6_JOIN_GROUP -# define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP -# endif -# ifndef IPV6_LEAVE_GROUP -# define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP -# endif - case AF_INET6: - { - struct ipv6_mreq mreq6; - memcpy( &mreq6.ipv6mr_multiaddr, - &((struct sockaddr_in6 *)g->addr)->sin6_addr, - sizeof(struct in6_addr) ); - mreq6.ipv6mr_interface = 0; /* TODO: fix this */ - if (op == JOIN_MCAST_GROUP) - sockopt = IPV6_JOIN_GROUP; - else - sockopt = IPV6_LEAVE_GROUP; - if (setsockopt( s->fd, IPPROTO_IPV6, sockopt, - &mreq6, sizeof(mreq6) ) < 0) - { - int saveerr = errno; - char addrbuf[INET6_ADDRSTRLEN]; - - inet_ntop( s->addr->sa_family, - &((struct sockaddr_in6 *)g->addr)->sin6_addr, - addrbuf, sizeof(addrbuf) ); - - LogError( "XDMCP socket multicast %s to %s failed, errno %d\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf, - saveerr ); - } else if (debugLevel & DEBUG_CORE) { - char addrbuf[INET6_ADDRSTRLEN]; - - inet_ntop( s->addr->sa_family, - &((struct sockaddr_in6 *)g->addr)->sin6_addr, - addrbuf, sizeof(addrbuf) ); - - Debug( "XDMCP socket multicast %s to %s succeeded\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf ); - } - return; - } -#endif - } -} - -static void -UpdateMcastGroup( ARRAY8Ptr addr, void **closure ) -{ - struct socklist *s = (struct socklist *)*closure; - struct socklist *g; - - if (!s) - return; - - /* Already in the group, mark & continue */ - if ((g = FindInList( s->mcastgroups, addr ))) { - g->ref = 1; - return; - } - - /* Need to join the group */ - if (!(g = CreateSocklistEntry( addr ))) - return; - - ChangeMcastMembership( s, g, JOIN_MCAST_GROUP ); - free( g ); -} - -/* Open or close listening sockets to match the current settings read in - from the access database. */ -void -UpdateListenSockets( void ) -{ - struct socklist *s, *g, **ls, **lg; - void *tmpPtr = NULL; - - /* Clear Ref bits - any not marked by UpdateCallback will be closed */ - for (s = listensocks; s; s = s->next) { - s->ref = 0; - for (g = s->mcastgroups; g; g = g->next) - g->ref = 0; - } - ForEachListenAddr( UpdateListener, UpdateMcastGroup, &tmpPtr ); - c_request_port = request_port; - for (ls = &listensocks; (s = *ls); ) - if (!s->ref) { - DestroyListeningSocket( s ); - *ls = s->next; - free( s ); - } else { - ls = &s->next; - for (lg = &s->mcastgroups; (g = *lg); ) - if (!g->ref) { - ChangeMcastMembership( s, g, LEAVE_MCAST_GROUP ); - *lg = g->next; - free( g ); - } else - lg = &g->next; - } -} - -int -AnyListenSockets( void ) -{ - return listensocks != NULL; -} - -int -ProcessListenSockets( FD_TYPE *reads ) -{ - struct socklist *s; - int ret = 0; - - for (s = listensocks; s; s = s->next) - if (FD_ISSET( s->fd, reads )) { - ProcessRequestSocket( s->fd ); - ret = 1; - } - return ret; -} - -#endif /* !STREAMSCONN && XDMCP */ diff --git a/kdm/backend/streams.c b/kdm/backend/streams.c deleted file mode 100644 index f60fb955e..000000000 --- a/kdm/backend/streams.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2002,2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * streams.c - Support for STREAMS - */ - -#include "dm.h" - -#if defined(XDMCP) && defined(STREAMSCONN) - -#include "dm_error.h" - -#include <fcntl.h> -#include <tiuser.h> -#include <netconfig.h> -#include <netdir.h> - -static int xdmcpFd = -1, c_request_port; - -void -UpdateListenSockets( void ) -{ - struct t_bind bind_addr; - struct netconfig *nconf; - struct nd_hostserv service; - struct nd_addrlist *servaddrs; - char bindbuf[15]; - int it; - - if (c_request_port == request_port) - return; - c_request_port = request_port; - - if (xdmcpFd != -1) { - CloseNClearCloseOnFork( xdmcpFd ); - UnregisterInput( xdmcpFd ); - xdmcpFd = -1; - } - - if (!request_port) - return; - - Debug( "creating UDP stream %d\n", request_port ); - - nconf = getnetconfigent( "udp" ); - if (!nconf) { - t_error( "getnetconfigent udp" ); - return; - } - - xdmcpFd = t_open( nconf->nc_device, O_RDWR, NULL ); - if (xdmcpFd == -1) { - LogError( "XDMCP stream creation failed\n" ); - t_error( "CreateWellKnownSockets(xdmcpFd): t_open failed" ); - return; - } - - service.h_host = HOST_SELF; - sprintf( bindbuf, "%d", request_port ); - service.h_serv = bindbuf; - netdir_getbyname( nconf, &service, &servaddrs ); - freenetconfigent( nconf ); - - bind_addr.qlen = 5; - bind_addr.addr.buf = servaddrs->n_addrs[0].buf; - bind_addr.addr.len = servaddrs->n_addrs[0].len; - bind_addr.addr.maxlen = servaddrs->n_addrs[0].len; - it = t_bind( xdmcpFd, &bind_addr, &bind_addr ); - netdir_free( (char *)servaddrs, ND_ADDRLIST ); - if (it < 0) { - LogError( "Error binding UDP port %d\n", request_port ); - t_error( "CreateWellKnownSockets(xdmcpFd): t_bind failed" ); - t_close( xdmcpFd ); - xdmcpFd = -1; - return; - } - RegisterCloseOnFork( xdmcpFd ); - RegisterInput( xdmcpFd ); -} - -int -AnyListenSockets( void ) -{ - return xdmcpFd != -1; -} - -int -ProcessRequestSockets( FD_TYPE *reads ) -{ - if (xdmcpFd >= 0 && FD_ISSET( xdmcpFd, reads )) { - ProcessRequestSocket( xdmcpFd ); - return 1; - } - return 0; -} - -#endif /* STREAMSCONN && XDMCP */ diff --git a/kdm/backend/util.c b/kdm/backend/util.c deleted file mode 100644 index 7dd58f031..000000000 --- a/kdm/backend/util.c +++ /dev/null @@ -1,637 +0,0 @@ -/* - -Copyright 1989, 1998 The Open Group -Copyright 2000-2005 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * various utility routines - */ - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -#include <string.h> -#include <unistd.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> - -#if 0 /*def USG; this was hpux once upon a time */ -# define NEED_UTSNAME -#endif - -#ifdef NEED_UTSNAME -# include <sys/utsname.h> -#endif - -void * -Calloc( size_t nmemb, size_t size ) -{ - void *ret; - - if (!(ret = calloc( nmemb, size ))) - LogOutOfMem(); - return ret; -} - -void * -Malloc( size_t size ) -{ - void *ret; - - if (!(ret = malloc( size ))) - LogOutOfMem(); - return ret; -} - -void * -Realloc( void *ptr, size_t size ) -{ - void *ret; - - if (!(ret = realloc( ptr, size )) && size) - LogOutOfMem(); - return ret; -} - -int -StrCmp( const char *s1, const char *s2 ) -{ - if (s1 == s2) - return 0; - if (!s1) - return -1; - if (!s2) - return 1; - return strcmp( s1, s2 ); -} - -void -WipeStr( char *str ) -{ - if (str) { - bzero( str, strlen( str ) ); - free( str ); - } -} - -#ifndef HAVE_STRNLEN -int -StrNLen( const char *s, int max ) -{ - unsigned l; - - for (l = 0; l < (unsigned)max && s[l]; l++); - return l; -} -#endif - -/* duplicate src; wipe & free old dst string */ -int -ReStrN( char **dst, const char *src, int len ) -{ - char *ndst = 0; - - if (src) { - if (len < 0) - len = strlen( src ); - if (*dst && !memcmp( *dst, src, len ) && !(*dst)[len]) - return 1; - if (!(ndst = Malloc( len + 1 ))) { - WipeStr( *dst ); - *dst = 0; - return 0; - } - memcpy( ndst, src, len ); - ndst[len] = 0; - } - WipeStr( *dst ); /* make an option, if we should become heavily used */ - *dst = ndst; - return 2; -} - -int -ReStr( char **dst, const char *src ) -{ - return ReStrN( dst, src, -1 ); -} - -/* duplicate src */ -int -StrNDup( char **dst, const char *src, int len ) -{ - if (src) { - if (len < 0) - len = strlen( src ); - if (!(*dst = Malloc( len + 1 ))) - return 0; - memcpy( *dst, src, len ); - (*dst)[len] = 0; - } else - *dst = 0; - return 1; -} - -int -StrDup( char **dst, const char *src ) -{ - return StrNDup( dst, src, -1 ); -} - -/* append any number of strings to dst */ -int -StrApp( char **dst, ... ) -{ - int len; - char *bk, *pt, *dp; - va_list va; - - len = 1; - if (*dst) - len += strlen( *dst ); - va_start( va, dst ); - for (;;) { - pt = va_arg( va, char * ); - if (!pt) - break; - len += strlen( pt ); - } - va_end( va ); - if (!(bk = Malloc( len ))) { - if (*dst) { - free( *dst ); - *dst = 0; - } - return 0; - } - dp = bk; - if (*dst) { - len = strlen( *dst ); - memcpy( dp, *dst, len ); - dp += len; - free( *dst ); - } - va_start( va, dst ); - for (;;) { - pt = va_arg( va, char * ); - if (!pt) - break; - len = strlen( pt ); - memcpy( dp, pt, len ); - dp += len; - } - va_end( va ); - *dp = '\0'; - *dst = bk; - return 1; -} - - -char ** -initStrArr( char **arr ) -{ - if (!arr && (arr = Malloc( sizeof(char *) ))) - arr[0] = 0; - return arr; -} - -int -arrLen( char **arr ) -{ - int nu = 0; - if (arr) - for (; arr[nu]; nu++); - return nu; -} - -static char ** -extStrArr( char **arr, char ***strp ) -{ - char **rarr; - int nu; - - nu = arrLen( arr ); - if ((rarr = Realloc( arr, sizeof(char *) * (nu + 2) ))) { - rarr[nu + 1] = 0; - *strp = rarr + nu; - return rarr; - } - freeStrArr( arr ); - return 0; -} - -char ** -addStrArr( char **arr, const char *str, int len ) -{ - char **strp; - - if ((arr = extStrArr( arr, &strp ))) { - if (StrNDup( strp, str, len )) - return arr; - freeStrArr( arr ); - } - return 0; -} - -char ** -xCopyStrArr( int rn, char **arr ) -{ - char **rarr; - int nu; - - nu = arrLen( arr ); - if ((rarr = Calloc( sizeof(char *), nu + rn + 1 ))) - memcpy( rarr + rn, arr, sizeof(char *) * nu ); - return rarr; -} - -void -freeStrArr( char **arr ) -{ - char **a; - - if (arr) { - for (a = arr; *a; a++) - free( *a ); - free( arr ); - } -} - - -char ** -parseArgs( char **argv, const char *string ) -{ - const char *word; - char **strp, *str; - int wlen; - - if (!(argv = initStrArr( argv ))) - return 0; - while (*string) { - if (isspace( *string )) { - string++; - continue; - } - word = string; - wlen = 0; - do { - if (*string == '\\') { - if (!*++string) - string--; - wlen++; - } else if (*string == '\'') { - while (*++string != '\'' && *string) - wlen++; - } else if (*string == '"') { - while (*++string != '"' && *string) { - if (*string == '\\') { - if (!*++string) - string--; - } - wlen++; - } - } else - wlen++; - } while (*++string && !isspace( *string )); - if (!(argv = extStrArr( argv, &strp ))) - return 0; - if (!(*strp = str = Malloc( wlen + 1 ))) { - freeStrArr( argv ); - return 0; - } - do { - if (*word == '\\') { - if (!*++word) - word--; - *str++ = *word; - } else if (*word == '\'') { - while (*++word != '\'' && *word) - *str++ = *word; - } else if (*word == '"') { - while (*++word != '"' && *word) { - if (*word == '\\') { - if (!*++word) - word--; - } - *str++ = *word; - } - } else - *str++ = *word; - } while (*++word && !isspace( *word )); - *str = 0; - } - return argv; -} - - -const char * -getEnv( char **e, const char *name ) -{ - if (e) { - int l = strlen( name ); - for (; *e; e++) - if (!memcmp( *e, name, l ) && (*e)[l] == '=') - return (*e) + l + 1; - } - return 0; -} - -char ** -setEnv( char **e, const char *name, const char *value ) -{ - char **new, **old; - char *newe; - int envsize; - int l; - -#ifdef _AIX - /* setpenv() depends on "SYSENVIRON:", not "SYSENVIRON:=" */ - if (!value) { - if (!StrDup( &newe, name )) - return e; - } else -#endif - { - newe = 0; - if (!StrApp( &newe, name, "=", value, (char *)0 )) - return e; - } - envsize = 0; - if (e) { - l = strlen( name ); - for (old = e; *old; old++) - if (!memcmp( *old, name, l ) && ((*old)[l] == '=' || !(*old)[l])) - { - free( *old ); - *old = newe; - return e; - } - envsize = old - e; - } - if (!(new = (char **) - Realloc( (char *)e, (unsigned)((envsize + 2) * sizeof(char *)) ))) - { - free( newe ); - return e; - } - new[envsize] = newe; - new[envsize + 1] = 0; - return new; -} - -char ** -putEnv( const char *string, char **env ) -{ - char *n; - char *b; - - if (!(b = strchr( string, '=' ))) - return NULL; - if (!StrNDup( &n, string, b - string )) - return NULL; - env = setEnv( env, n, b + 1 ); - free( n ); - return env; -} - -static int -GetHostname( char *buf, int maxlen ) -{ - int len; - -#ifdef NEED_UTSNAME - /* - * same host name crock as in server and xinit. - */ - struct utsname name; - - uname( &name ); - len = strlen( name.nodename ); - if (len >= maxlen) len = maxlen - 1; - memcpy( buf, name.nodename, len ); - buf[len] = '\0'; -#else - buf[0] = '\0'; - (void)gethostname( buf, maxlen ); - buf[maxlen - 1] = '\0'; - len = strlen( buf ); -#endif /* NEED_UTSNAME */ - return len; -} - -static char localHostbuf[256]; -static int gotLocalHostname; - -const char * -localHostname( void ) -{ - if (!gotLocalHostname) - { - GetHostname( localHostbuf, sizeof(localHostbuf) - 1 ); - gotLocalHostname = 1; - } - return localHostbuf; -} - -static int -AtomicIO( ssize_t (*f)( int, void *, size_t ), int fd, void *buf, int count ) -{ - int ret, rlen; - - for (rlen = 0; rlen < count; ) { - dord: - ret = f( fd, (void *)((char *)buf + rlen), count - rlen ); - if (ret < 0) { - if (errno == EINTR) - goto dord; - if (errno == EAGAIN) - break; - return -1; - } - if (!ret) - break; - rlen += ret; - } - return rlen; -} - -int -Reader( int fd, void *buf, int count ) -{ - return AtomicIO( read, fd, buf, count ); -} - -int -Writer( int fd, const void *buf, int count ) -{ - return AtomicIO( (ssize_t(*)( int, void *, size_t ))write, - fd, (void *)buf, count ); -} - -int -fGets( char *buf, int max, FILE *f ) -{ - int len; - - if (!fgets( buf, max, f )) - return -1; - len = strlen( buf ); - if (len && buf[len - 1] == '\n') - buf[--len] = 0; - return len; -} - -time_t -mTime( const char *fn ) -{ - struct stat st; - - if (stat( fn, &st )) - return -1; - else - return st.st_mtime; -} - -void -randomStr( char *s ) -{ - static const char letters[] = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - unsigned i, rn = secureRandom(); - - for (i = 0; i < 6; i++) { - *s++ = letters[rn % 62]; - rn /= 62; - } - *s = 0; -} - -static int -StrNChrCnt( const char *s, int slen, char c ) -{ - int i, cnt; - - for (i = cnt = 0; i < slen && s[i]; i++) - if (s[i] == c) - cnt++; - return cnt; -} - -/* X -from ip6-addr does not work here, so i don't know whether this is needed. -#define IP6_MAGIC -*/ - -void -ListSessions( int flags, struct display *d, void *ctx, - void (*emitXSess)( struct display *, struct display *, void * ), - void (*emitTTYSess)( STRUCTUTMP *, struct display *, void * ) ) -{ - struct display *di; -#ifdef IP6_MAGIC - int le, dot; -#endif -#ifdef BSD_UTMP - int fd; - struct utmp ut[1]; -#else - STRUCTUTMP *ut; -#endif - - for (di = displays; di; di = di->next) - if (((flags & lstRemote) || (di->displayType & d_location) == dLocal) && - (di->status == remoteLogin || - ((flags & lstPassive) ? di->status == running : di->userSess >= 0))) - emitXSess( di, d, ctx ); - - if (!(flags & lstTTY)) - return; - -#ifdef BSD_UTMP - if ((fd = open( UTMP_FILE, O_RDONLY )) < 0) - return; - while (Reader( fd, ut, sizeof(ut[0]) ) == sizeof(ut[0])) { - if (*ut->ut_user) { /* no idea how to list passive TTYs on BSD */ -#else - SETUTENT(); - while ((ut = GETUTENT())) { - if (ut->ut_type == USER_PROCESS -# if 0 /* list passive TTYs at all? not too sensible, i think. */ - || ((flags & lstPassive) && ut->ut_type == LOGIN_PROCESS) -# endif - ) - { -#endif - if (*ut->ut_host) { /* from remote or x */ - if (!(flags & lstRemote)) - continue; - } else { - /* hack around broken konsole which does not set ut_host. */ - /* this check is probably linux-specific. */ - /* alternatively we could open the device and try VT_OPENQRY. */ - if (memcmp( ut->ut_line, "tty", 3 ) || - !isdigit( ut->ut_line[3] )) - continue; - } - if (StrNChrCnt( ut->ut_line, sizeof(ut->ut_line), ':' )) - continue; /* x login */ - switch (StrNChrCnt( ut->ut_host, sizeof(ut->ut_host), ':' )) { - case 1: /* x terminal */ - continue; - default: -#ifdef IP6_MAGIC - /* unknown - IPv6 makes things complicated */ - le = StrNLen( ut->ut_host, sizeof(ut->ut_host) ); - /* cut off screen number */ - for (dot = le; ut->ut_host[--dot] != ':'; ) - if (ut->ut_host[dot] == '.') { - le = dot; - break; - } - for (di = displays; di; di = di->next) - if (!memcmp( di->name, ut->ut_host, le ) && !di->name[le]) - goto cont; /* x terminal */ - break; - cont: - continue; - case 0: /* no x terminal */ -#endif - break; - } - emitTTYSess( ut, d, ctx ); - } - } -#ifdef BSD_UTMP - close( fd ); -#else - ENDUTENT(); -#endif -} - diff --git a/kdm/backend/xdmauth.c b/kdm/backend/xdmauth.c deleted file mode 100644 index 86257c651..000000000 --- a/kdm/backend/xdmauth.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2001,2003 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * generate authorization data for XDM-AUTHORIZATION-1 as per XDMCP spec - */ - -#include <config.h> - -#ifdef HASXDMAUTH - -#include "dm.h" -#include "dm_auth.h" -#include "dm_error.h" - -static char auth_name[256]; -static int auth_name_len; - -void -XdmInitAuth( unsigned short name_len, const char *name ) -{ - if (name_len > 256) - name_len = 256; - auth_name_len = name_len; - memmove( auth_name, name, name_len ); -} - -/* - * Generate authorization for XDM-AUTHORIZATION-1 - * - * When being used with XDMCP, 8 bytes are generated for the session key - * (sigma), as the random number (rho) is already shared between xdm and - * the server. Otherwise, we'll prepend a random number to pass in the file - * between xdm and the server (16 bytes total) - */ - -static Xauth * -XdmGetAuthHelper( unsigned short namelen, const char *name, int includeRho ) -{ - Xauth *new; - - if (!(new = (Xauth *)Malloc( sizeof(Xauth) ))) - return (Xauth *)0; - new->family = FamilyWild; - new->address_length = 0; - new->address = 0; - new->number_length = 0; - new->number = 0; - if (includeRho) - new->data_length = 16; - else - new->data_length = 8; - - new->data = (char *)Malloc( new->data_length ); - if (!new->data) { - free( (char *)new ); - return (Xauth *)0; - } - new->name = (char *)Malloc( namelen ); - if (!new->name) { - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - memmove( (char *)new->name, name, namelen ); - new->name_length = namelen; - if (!GenerateAuthData( (char *)new->data, new->data_length )) { - free( (char *)new->name ); - free( (char *)new->data ); - free( (char *)new ); - return (Xauth *)0; - } - /* - * set the first byte of the session key to zero as it - * is a DES key and only uses 56 bits - */ - ((char *)new->data)[new->data_length - 8] = '\0'; - Debug( "local server auth %02[*hhx\n", new->data_length, new->data ); - return new; -} - -Xauth * -XdmGetAuth( unsigned short namelen, const char *name ) -{ - return XdmGetAuthHelper( namelen, name, TRUE ); -} - -#ifdef XDMCP - -void -XdmGetXdmcpAuth( struct protoDisplay *pdpy, - unsigned short authorizationNameLen, - const char *authorizationName ) -{ - Xauth *fileauth, *xdmcpauth; - - if (pdpy->fileAuthorization && pdpy->xdmcpAuthorization) - return; - xdmcpauth = XdmGetAuthHelper( authorizationNameLen, authorizationName, - FALSE ); - if (!xdmcpauth) - return; - fileauth = (Xauth *)Malloc( sizeof(Xauth) ); - if (!fileauth) { - XauDisposeAuth( xdmcpauth ); - return; - } - /* build the file auth from the XDMCP auth */ - *fileauth = *xdmcpauth; - fileauth->name = Malloc( xdmcpauth->name_length ); - fileauth->data = Malloc( 16 ); - fileauth->data_length = 16; - if (!fileauth->name || !fileauth->data) { - XauDisposeAuth( xdmcpauth ); - if (fileauth->name) - free( (char *)fileauth->name ); - if (fileauth->data) - free( (char *)fileauth->data ); - free( (char *)fileauth ); - return; - } - /* - * for the file authorization, prepend the random number (rho) - * which is simply the number we've been passing back and - * forth via XDMCP - */ - memmove( fileauth->name, xdmcpauth->name, xdmcpauth->name_length ); - memmove( fileauth->data, pdpy->authenticationData.data, 8 ); - memmove( fileauth->data + 8, xdmcpauth->data, 8 ); - Debug( "accept packet auth %02[*hhx\nauth file auth %02[*hhx\n", - xdmcpauth->data_length, xdmcpauth->data, - fileauth->data_length, fileauth->data ); - /* encrypt the session key for its trip back to the server */ - XdmcpWrap( (unsigned char *)xdmcpauth->data, (unsigned char *)&pdpy->key, - (unsigned char *)xdmcpauth->data, 8 ); - pdpy->fileAuthorization = fileauth; - pdpy->xdmcpAuthorization = xdmcpauth; -} - -#define atox(c) ('0' <= c && c <= '9' ? c - '0' : \ - 'a' <= c && c <= 'f' ? c - 'a' + 10 : \ - 'A' <= c && c <= 'F' ? c - 'A' + 10 : -1) - -static int -HexToBinary( char *key ) -{ - char *out, *in; - int top, bottom; - - in = key + 2; - out= key; - while (in[0] && in[1]) { - top = atox( in[0] ); - if (top == -1) - return 0; - bottom = atox( in[1] ); - if (bottom == -1) - return 0; - *out++ = (top << 4) | bottom; - in += 2; - } - if (in[0]) - return 0; - *out++ = '\0'; - return 1; -} - -/* - * Search the Keys file for the entry matching this display. This - * routine accepts either plain ascii strings for keys, or hex-encoded numbers - */ - -static int -XdmGetKey( struct protoDisplay *pdpy, ARRAY8Ptr displayID ) -{ - FILE *keys; - char line[1024], id[1024], key[1024]; - int keylen; - - Debug( "lookup key for %.*s\n", displayID->length, displayID->data ); - keys = fopen( keyFile, "r" ); - if (!keys) - return FALSE; - while (fgets( line, sizeof(line), keys )) { - if (line[0] == '#' || sscanf( line, "%s %s", id, key ) != 2) - continue; - bzero( line, sizeof(line) ); - Debug( "key entry for %\"s %d bytes\n", id, strlen( key ) ); - if (strlen( id ) == displayID->length && - !strncmp( id, (char *)displayID->data, displayID->length )) - { - if (!strncmp( key, "0x", 2 ) || !strncmp( key, "0X", 2 )) - if (!HexToBinary( key )) - break; - keylen = strlen( key ); - while (keylen < 7) - key[keylen++] = '\0'; - pdpy->key.data[0] = '\0'; - memmove( pdpy->key.data + 1, key, 7 ); - bzero( key, sizeof(key) ); - fclose( keys ); - return TRUE; - } - } - bzero( line, sizeof(line) ); - bzero( key, sizeof(key) ); - fclose( keys ); - return FALSE; -} - -/*ARGSUSED*/ -int -XdmCheckAuthentication( struct protoDisplay *pdpy, - ARRAY8Ptr displayID, - ARRAY8Ptr authenticationName ATTR_UNUSED, - ARRAY8Ptr authenticationData ) -{ - XdmAuthKeyPtr incoming; - - if (!XdmGetKey( pdpy, displayID )) - return FALSE; - if (authenticationData->length != 8) - return FALSE; - XdmcpUnwrap( authenticationData->data, (unsigned char *)&pdpy->key, - authenticationData->data, 8 ); - Debug( "request packet auth %02[*hhx\n", - authenticationData->length, authenticationData->data ); - if (!XdmcpCopyARRAY8( authenticationData, &pdpy->authenticationData )) - return FALSE; - incoming = (XdmAuthKeyPtr)authenticationData->data; - XdmcpIncrementKey( incoming ); - XdmcpWrap( authenticationData->data, (unsigned char *)&pdpy->key, - authenticationData->data, 8 ); - return TRUE; -} - -#endif /* XDMCP */ -#endif /* HASXDMAUTH (covering the entire file) */ diff --git a/kdm/backend/xdmcp.c b/kdm/backend/xdmcp.c deleted file mode 100644 index 6abaf5fc8..000000000 --- a/kdm/backend/xdmcp.c +++ /dev/null @@ -1,1165 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2002 Sun Microsystems, Inc. All rights reserved. -Copyright 2001-2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * xdmcp.c - Support for XDMCP - */ - -#include <config.h> - -#ifdef XDMCP - -#include "dm.h" -#include "dm_error.h" -#include "dm_auth.h" -#include "dm_socket.h" - -#include <sys/types.h> -#include <ctype.h> - -#include <netdb.h> -#if defined(IPv6) && defined(AF_INET6) -# include <arpa/inet.h> -#endif - -/* - * Forward reference - */ -static void broadcast_respond( struct sockaddr *from, int fromlen, int length, int fd ); -static void forward_respond (struct sockaddr *from, int fromlen, int length, int fd); -static void manage( struct sockaddr *from, int fromlen, int length, int fd ); -static void query_respond( struct sockaddr *from, int fromlen, int length, int fd ); -static void request_respond( struct sockaddr *from, int fromlen, int length, int fd ); -static void send_accept( struct sockaddr *to, int tolen, CARD32 sessionID, ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, ARRAY8Ptr authorizationName, ARRAY8Ptr authorizationData, int fd ); -static void send_alive( struct sockaddr *from, int fromlen, int length, int fd ); -static void send_decline( struct sockaddr *to, int tolen, ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, ARRAY8Ptr status, int fd ); -static void send_failed( struct sockaddr *from, int fromlen, const char *name, CARD32 sessionID, const char *reason, int fd ); -static void send_refuse( struct sockaddr *from, int fromlen, CARD32 sessionID, int fd ); -static void send_unwilling( struct sockaddr *from, int fromlen, ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ); -static void send_willing( struct sockaddr *from, int fromlen, ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ); - - -static XdmcpBuffer buffer; - -static void -sendForward( CARD16 connectionType, ARRAY8Ptr address, char *closure ) -{ -#ifdef AF_INET - struct sockaddr_in in_addr; -#endif -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_in6 in6_addr; -#endif -#ifdef AF_DECnet -#endif - struct sockaddr *addr; - int addrlen; - - switch (connectionType) { -#ifdef AF_INET - case FamilyInternet: - addr = (struct sockaddr *)&in_addr; - bzero( (char *)&in_addr, sizeof(in_addr) ); -# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -# endif - in_addr.sin_family = AF_INET; - in_addr.sin_port = htons( (short)XDM_UDP_PORT ); - if (address->length != 4) - return; - memmove( (char *)&in_addr.sin_addr, address->data, address->length ); - addrlen = sizeof(struct sockaddr_in); - break; -#endif -#if defined(IPv6) && defined(AF_INET6) - case FamilyInternet6: - addr = (struct sockaddr *)&in6_addr; - bzero( (char *)&in6_addr, sizeof(in6_addr) ); -# ifdef SIN6_LEN - in6_addr.sin6_len = sizeof(in6_addr); -# endif - in6_addr.sin6_family = AF_INET6; - in6_addr.sin6_port = htons( (short)XDM_UDP_PORT ); - if (address->length != 16) - return; - memmove( (char *)&in6_addr.sin6_addr, address->data, address->length ); - addrlen = sizeof(struct sockaddr_in6); - break; -#endif -#ifdef AF_DECnet - case FamilyDECnet: -#endif - default: - return; - } - XdmcpFlush( (int)closure, &buffer, (XdmcpNetaddr)addr, addrlen ); - return; -} - -static void -ClientAddress( struct sockaddr *from, - ARRAY8Ptr addr, /* return */ - ARRAY8Ptr port, /* return */ - CARD16 *type ) /* return */ -{ - int length, family; - char *data; - - data = NetaddrPort( (XdmcpNetaddr)from, &length ); - XdmcpAllocARRAY8( port, length ); - memmove( port->data, data, length ); - port->length = length; - - family = ConvertAddr( (XdmcpNetaddr)from, &length, &data ); - XdmcpAllocARRAY8( addr, length ); - memmove( addr->data, data, length ); - addr->length = length; - - *type = family; -} - -static void -all_query_respond( struct sockaddr *from, int fromlen, - ARRAYofARRAY8Ptr authenticationNames, - xdmOpCode type, int fd ) -{ - ARRAY8Ptr authenticationName; - ARRAY8 status; - ARRAY8 addr; - CARD16 connectionType; - int family; - int length; - - family = ConvertAddr( (XdmcpNetaddr)from, &length, &(addr.data) ); - addr.length = length; /* convert int to short */ - Debug( "all_query_respond: conntype=%d, addr=%02[*:hhx\n", - family, addr.length, addr.data ); - if (family < 0) - return; - connectionType = family; - - if (type == INDIRECT_QUERY) - RememberIndirectClient( &addr, connectionType ); - else - ForgetIndirectClient( &addr, connectionType ); - - authenticationName = ChooseAuthentication( authenticationNames ); - if (Willing( &addr, connectionType, authenticationName, &status, type )) - send_willing( from, fromlen, authenticationName, &status, fd ); - else - if (type == QUERY) - send_unwilling( from, fromlen, authenticationName, &status, fd ); - XdmcpDisposeARRAY8( &status ); -} - -static void -indirect_respond( struct sockaddr *from, int fromlen, int length, int fd ) -{ - ARRAYofARRAY8 queryAuthenticationNames; - ARRAY8 clientAddress; - ARRAY8 clientPort; - CARD16 connectionType; - int expectedLen; - int i; - XdmcpHeader header; - int localHostAsWell; - - Debug( "<indirect> respond %d\n", length ); - if (!XdmcpReadARRAYofARRAY8( &buffer, &queryAuthenticationNames )) - return; - expectedLen = 1; - for (i = 0; i < (int)queryAuthenticationNames.length; i++) - expectedLen += 2 + queryAuthenticationNames.data[i].length; - if (length == expectedLen) { - ClientAddress( from, &clientAddress, &clientPort, &connectionType ); - /* - * set up the forward query packet - */ - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)FORWARD_QUERY; - header.length = 0; - header.length += 2 + clientAddress.length; - header.length += 2 + clientPort.length; - header.length += 1; - for (i = 0; i < (int)queryAuthenticationNames.length; i++) - header.length += 2 + queryAuthenticationNames.data[i].length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteARRAY8( &buffer, &clientAddress ); - XdmcpWriteARRAY8( &buffer, &clientPort ); - XdmcpWriteARRAYofARRAY8( &buffer, &queryAuthenticationNames ); - - localHostAsWell = - ForEachMatchingIndirectHost( &clientAddress, connectionType, - sendForward, (char *)fd ); - - XdmcpDisposeARRAY8( &clientAddress ); - XdmcpDisposeARRAY8( &clientPort ); - if (localHostAsWell) - all_query_respond( from, fromlen, &queryAuthenticationNames, - INDIRECT_QUERY, fd ); - } else - Debug( "<indirect> length error got %d expect %d\n", - length, expectedLen ); - XdmcpDisposeARRAYofARRAY8( &queryAuthenticationNames ); -} - -void -ProcessRequestSocket( int fd ) -{ - XdmcpHeader header; -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_storage addr; -#else - struct sockaddr addr; -#endif - int addrlen = sizeof(addr); - - Debug( "ProcessRequestSocket\n" ); - bzero( (char *)&addr, sizeof(addr) ); - if (!XdmcpFill( fd, &buffer, (XdmcpNetaddr)&addr, &addrlen )) { - Debug( "XdmcpFill failed\n" ); - return; - } - if (!XdmcpReadHeader( &buffer, &header )) { - Debug( "XdmcpReadHeader failed\n" ); - return; - } - if (header.version != XDM_PROTOCOL_VERSION) { - Debug( "XDMCP header version read was %d, expected %d\n", - header.version, XDM_PROTOCOL_VERSION ); - return; - } - Debug( "header: %d %d %d\n", header.version, header.opcode, header.length ); - switch (header.opcode) { - case BROADCAST_QUERY: - broadcast_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - case QUERY: - query_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - case INDIRECT_QUERY: - indirect_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - case FORWARD_QUERY: - forward_respond ((struct sockaddr *)&addr, addrlen, header.length, fd); - break; - case REQUEST: - request_respond( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - case MANAGE: - manage( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - case KEEPALIVE: - send_alive( (struct sockaddr *)&addr, addrlen, header.length, fd ); - break; - } -} - -/* - * respond to a request on the UDP socket. - */ - -static void -direct_query_respond( struct sockaddr *from, int fromlen, - int length, xdmOpCode type, int fd ) -{ - ARRAYofARRAY8 queryAuthenticationNames; - int expectedLen; - int i; - - if (!XdmcpReadARRAYofARRAY8( &buffer, &queryAuthenticationNames )) - return; - expectedLen = 1; - for (i = 0; i < (int)queryAuthenticationNames.length; i++) - expectedLen += 2 + queryAuthenticationNames.data[i].length; - if (length == expectedLen) - all_query_respond( from, fromlen, &queryAuthenticationNames, type, fd ); - XdmcpDisposeARRAYofARRAY8( &queryAuthenticationNames ); -} - -static void -query_respond( struct sockaddr *from, int fromlen, int length, int fd ) -{ - Debug( "<query> respond %d\n", length ); - direct_query_respond( from, fromlen, length, QUERY, fd ); -} - -static void -broadcast_respond( struct sockaddr *from, int fromlen, int length, int fd ) -{ - direct_query_respond( from, fromlen, length, BROADCAST_QUERY, fd ); -} - -/* computes an X display name */ - -static char * -NetworkAddressToName( CARD16 connectionType, ARRAY8Ptr connectionAddress, - struct sockaddr *originalAddress, CARD16 displayNumber ) -{ - switch (connectionType) { - case FamilyInternet: -#if defined(IPv6) && defined(AF_INET6) - case FamilyInternet6: -#endif - { - CARD8 *data; - struct hostent *hostent; - char *hostname = NULL; - char *name; - const char *localhost; - int multiHomed = 0; - int type; -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai = NULL, *nai, hints; - char dotted[INET6_ADDRSTRLEN]; - - if (connectionType == FamilyInternet6) - type = AF_INET6; - else -#endif - type = AF_INET; - - data = connectionAddress->data; - hostent = gethostbyaddr( (char *)data, - connectionAddress->length, type ); - if (hostent) { - if (sourceAddress) { -#if defined(IPv6) && defined(AF_INET6) - bzero( &hints, sizeof(hints) ); - hints.ai_flags = AI_CANONNAME; - if (!getaddrinfo( hostent->h_name, NULL, &hints, &ai )) { - hostname = ai->ai_canonname; - for (nai = ai->ai_next; nai; nai = nai->ai_next) - if (ai->ai_protocol == nai->ai_protocol && - memcmp( ai->ai_addr, nai->ai_addr, - ai->ai_addrlen )) - multiHomed = 1; - } -#else - hostent = gethostbyname( hostent->h_name ); - if (hostent && hostent->h_addrtype == AF_INET) { - multiHomed = hostent->h_addr_list[1] != NULL; - hostname = hostent->h_name; - } -#endif - } else - hostname = hostent->h_name; - } - - localhost = localHostname(); - - /* - * protect against bogus host names - */ - if (hostname && *hostname && *hostname != '.' && !multiHomed) { - if (!strcmp( localhost, hostname )) - ASPrintf( &name, "localhost:%d", displayNumber ); - else { - if (removeDomainname) { - char *remoteDot; - char *localDot; - - /* check for a common domain name. This - * could reduce names by recognising common - * super-domain names as well, but I don't think - * this is as useful, and will confuse more - * people - */ - if ((localDot = strchr( localhost, '.' )) && - (remoteDot = strchr( hostname, '.' ))) - { - /* smash the name in place; it won't - * be needed later. - */ - if (!strcmp( localDot+1, remoteDot+1 )) - *remoteDot = '\0'; - } - } - - ASPrintf( &name, "%s:%d", hostname, displayNumber ); - } - } else { -#if defined(IPv6) && defined(AF_INET6) - if (multiHomed) { - if (connectionType == FamilyInternet) { - data = (CARD8 *) - &((struct sockaddr_in *)originalAddress)->sin_addr; - } else { - data = (CARD8 *) - &((struct sockaddr_in6 *)originalAddress)->sin6_addr; - } - } - inet_ntop( type, data, dotted, sizeof(dotted) ); - ASPrintf( &name, "%s:%d", dotted, displayNumber ); -#else - if (multiHomed) - data = (CARD8 *) - &((struct sockaddr_in *)originalAddress)->sin_addr; - ASPrintf( &name, "%[4|'.'hhu:%d", data, displayNumber ); -#endif - } -#if defined(IPv6) && defined(AF_INET6) - if (ai) - freeaddrinfo( ai ); -#endif - return name; - } -#ifdef DNET - case FamilyDECnet: - return NULL; -#endif /* DNET */ - default: - return NULL; - } -} - -/*ARGSUSED*/ -static void -forward_respond ( struct sockaddr *from, int fromlen ATTR_UNUSED, - int length, int fd) -{ - ARRAY8 clientAddress; - ARRAY8 clientPort; - ARRAYofARRAY8 authenticationNames; - struct sockaddr *client; - int clientlen; - int expectedLen; - int i; - - Debug( "<forward> respond %d\n", length ); - clientAddress.length = 0; - clientAddress.data = 0; - clientPort.length = 0; - clientPort.data = 0; - authenticationNames.length = 0; - authenticationNames.data = 0; - if (XdmcpReadARRAY8( &buffer, &clientAddress ) && - XdmcpReadARRAY8( &buffer, &clientPort ) && - XdmcpReadARRAYofARRAY8( &buffer, &authenticationNames )) - { - expectedLen = 0; - expectedLen += 2 + clientAddress.length; - expectedLen += 2 + clientPort.length; - expectedLen += 1; /* authenticationNames */ - for (i = 0; i < (int)authenticationNames.length; i++) - expectedLen += 2 + authenticationNames.data[i].length; - if (length == expectedLen) { - int j; - - j = 0; - for (i = 0; i < (int)clientPort.length; i++) - j = j * 256 + clientPort.data[i]; - Debug( "<forward> client address (port %d) %[*hhu\n", j, - clientAddress.length, clientAddress.data ); - switch (from->sa_family) { -#ifdef AF_INET - case AF_INET: - { - struct sockaddr_in in_addr; - - if (clientAddress.length != 4 || clientPort.length != 2) - goto badAddress; - bzero( (char *)&in_addr, sizeof(in_addr) ); -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -#endif - in_addr.sin_family = AF_INET; - memmove( &in_addr.sin_addr, clientAddress.data, 4 ); - memmove( (char *)&in_addr.sin_port, clientPort.data, 2 ); - client = (struct sockaddr *)&in_addr; - clientlen = sizeof(in_addr); - all_query_respond( client, clientlen, &authenticationNames, - FORWARD_QUERY, fd ); - } - break; -#endif -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - { - struct sockaddr_in6 in6_addr; - - if (clientAddress.length != 16 || clientPort.length != 2) - goto badAddress; - bzero( (char *)&in6_addr, sizeof(in6_addr) ); -#ifdef SIN6_LEN - in6_addr.sin6_len = sizeof(in6_addr); -#endif - in6_addr.sin6_family = AF_INET6; - memmove( &in6_addr,clientAddress.data,clientAddress.length ); - memmove( (char *)&in6_addr.sin6_port, clientPort.data, 2 ); - client = (struct sockaddr *)&in6_addr; - clientlen = sizeof(in6_addr); - all_query_respond( client, clientlen, &authenticationNames, - FORWARD_QUERY, fd ); - } - break; -#endif -#ifdef AF_UNIX - case AF_UNIX: - { - struct sockaddr_un un_addr; - - if (clientAddress.length >= sizeof(un_addr.sun_path)) - goto badAddress; - bzero( (char *)&un_addr, sizeof(un_addr) ); - un_addr.sun_family = AF_UNIX; - memmove( un_addr.sun_path, clientAddress.data, clientAddress.length ); - un_addr.sun_path[clientAddress.length] = '\0'; - client = (struct sockaddr *)&un_addr; -#if defined(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN) && !defined(__Lynx__) && defined(UNIXCONN) - un_addr.sun_len = strlen( un_addr.sun_path ); - clientlen = SUN_LEN( &un_addr ); -#else - clientlen = sizeof(un_addr); -#endif - all_query_respond( client, clientlen, &authenticationNames, - FORWARD_QUERY, fd ); - } - break; -#endif -#ifdef AF_CHAOS - case AF_CHAOS: - goto badAddress; -#endif -#ifdef AF_DECnet - case AF_DECnet: - goto badAddress; -#endif - } - } else - Debug( "<forward> length error got %d expect %d\n", length, expectedLen ); - } - badAddress: - XdmcpDisposeARRAY8( &clientAddress ); - XdmcpDisposeARRAY8( &clientPort ); - XdmcpDisposeARRAYofARRAY8( &authenticationNames ); -} - -static ARRAY8 Hostname; - -static void -send_willing( struct sockaddr *from, int fromlen, - ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ) -{ - XdmcpHeader header; - - Debug( "send <willing> %.*s %.*s\n", authenticationName->length, - authenticationName->data, - status->length, - status->data ); - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)WILLING; - header.length = - 6 + authenticationName->length + Hostname.length + status->length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteARRAY8( &buffer, authenticationName ); - XdmcpWriteARRAY8( &buffer, &Hostname ); - XdmcpWriteARRAY8( &buffer, status ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); -} - -static void -send_unwilling( struct sockaddr *from, int fromlen, - ARRAY8Ptr authenticationName, ARRAY8Ptr status, int fd ) -{ - XdmcpHeader header; - - Debug( "send <unwilling> %.*s %.*s\n", authenticationName->length, - authenticationName->data, - status->length, - status->data ); - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)UNWILLING; - header.length = 4 + Hostname.length + status->length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteARRAY8( &buffer, &Hostname ); - XdmcpWriteARRAY8( &buffer, status ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); -} - -static unsigned long globalSessionID; - -#define NextSessionID() (++globalSessionID) - -void init_session_id( void ) -{ - /* Set randomly so we are unlikely to reuse id's from a previous - * incarnation so we don't say "Alive" to those displays. - * Start with low digits 0 to make debugging easier. - */ - globalSessionID = (time( (Time_t *)0 ) & 0x7fff) * 16000; - - Hostname.data = (char *)localHostname(); - Hostname.length = strlen( Hostname.data ); -} - -static ARRAY8 outOfMemory = { (CARD16)13, (CARD8Ptr)"Out of memory" }; -static ARRAY8 noValidAddr = { (CARD16)16, (CARD8Ptr)"No valid address" }; -static ARRAY8 noValidAuth = { (CARD16)22, (CARD8Ptr)"No valid authorization" }; -static ARRAY8 noAuthentic = { (CARD16)29, (CARD8Ptr)"XDM has no authentication key" }; - -static void -request_respond( struct sockaddr *from, int fromlen, int length, int fd ) -{ - CARD16 displayNumber; - ARRAY16 connectionTypes; - ARRAYofARRAY8 connectionAddresses; - ARRAY8 authenticationName; - ARRAY8 authenticationData; - ARRAYofARRAY8 authorizationNames; - ARRAY8 manufacturerDisplayID; - ARRAY8Ptr reason = 0; - int expectlen; - int i, j; - struct protoDisplay *pdpy; - ARRAY8 authorizationName, authorizationData; - ARRAY8Ptr connectionAddress; - - Debug( "<request> respond %d\n", length ); - connectionTypes.data = 0; - connectionAddresses.data = 0; - authenticationName.data = 0; - authenticationData.data = 0; - authorizationNames.data = 0; - authorizationName.length = 0; - authorizationData.length = 0; - manufacturerDisplayID.data = 0; - if (XdmcpReadCARD16( &buffer, &displayNumber ) && - XdmcpReadARRAY16( &buffer, &connectionTypes ) && - XdmcpReadARRAYofARRAY8( &buffer, &connectionAddresses ) && - XdmcpReadARRAY8( &buffer, &authenticationName ) && - XdmcpReadARRAY8( &buffer, &authenticationData ) && - XdmcpReadARRAYofARRAY8( &buffer, &authorizationNames ) && - XdmcpReadARRAY8( &buffer, &manufacturerDisplayID )) - { - expectlen = 0; - expectlen += 2; /* displayNumber */ - expectlen += 1 + 2 * connectionTypes.length; /* connectionTypes */ - expectlen += 1; /* connectionAddresses */ - for (i = 0; i < (int)connectionAddresses.length; i++) - expectlen += 2 + connectionAddresses.data[i].length; - expectlen += 2 + authenticationName.length; /* authenticationName */ - expectlen += 2 + authenticationData.length; /* authenticationData */ - expectlen += 1; /* authoriationNames */ - for (i = 0; i < (int)authorizationNames.length; i++) - expectlen += 2 + authorizationNames.data[i].length; - expectlen += 2 + manufacturerDisplayID.length; /* displayID */ - if (expectlen != length) { - Debug( "<request> length error got %d expect %d\n", - length, expectlen ); - goto abort; - } - if (connectionTypes.length == 0 || - connectionAddresses.length != connectionTypes.length) - { - reason = &noValidAddr; - pdpy = 0; - goto decline; - } - pdpy = FindProtoDisplay( (XdmcpNetaddr)from, fromlen, displayNumber ); - if (!pdpy) { - - /* Check this Display against the Manager's policy */ - reason = Accept( from, fromlen, displayNumber ); - if (reason) - goto decline; - - /* Check the Display's stream services against Manager's policy */ - i = SelectConnectionTypeIndex( &connectionTypes, - &connectionAddresses ); - if (i < 0) { - reason = &noValidAddr; - goto decline; - } - - /* The Manager considers this a new session */ - connectionAddress = &connectionAddresses.data[i]; - pdpy = NewProtoDisplay( (XdmcpNetaddr)from, fromlen, displayNumber, - connectionTypes.data[i], connectionAddress, - NextSessionID() ); - Debug( "NewProtoDisplay %p\n", pdpy ); - if (!pdpy) { - reason = &outOfMemory; - goto decline; - } - } - if (authorizationNames.length == 0) - j = 0; - else - j = SelectAuthorizationTypeIndex( &authenticationName, - &authorizationNames ); - if (j < 0) { - reason = &noValidAuth; - goto decline; - } - if (!CheckAuthentication( pdpy, - &manufacturerDisplayID, - &authenticationName, - &authenticationData )) - { - reason = &noAuthentic; - goto decline; - } - if (j < (int)authorizationNames.length) { - Xauth *auth; - SetProtoDisplayAuthorization( pdpy, - (unsigned short)authorizationNames.data[j].length, - (char *)authorizationNames.data[j].data ); - auth = pdpy->xdmcpAuthorization; - if (!auth) - auth = pdpy->fileAuthorization; - if (auth) { - authorizationName.length = auth->name_length; - authorizationName.data = (CARD8Ptr) auth->name; - authorizationData.length = auth->data_length; - authorizationData.data = (CARD8Ptr) auth->data; - } - } - if (pdpy) { - send_accept( from, fromlen, pdpy->sessionID, - &authenticationName, - &authenticationData, - &authorizationName, - &authorizationData, fd ); - } else { - decline: - send_decline( from, fromlen, &authenticationName, - &authenticationData, - reason, fd ); - if (pdpy) - DisposeProtoDisplay( pdpy ); - } - } - abort: - XdmcpDisposeARRAY16( &connectionTypes ); - XdmcpDisposeARRAYofARRAY8( &connectionAddresses ); - XdmcpDisposeARRAY8( &authenticationName ); - XdmcpDisposeARRAY8( &authenticationData ); - XdmcpDisposeARRAYofARRAY8( &authorizationNames ); - XdmcpDisposeARRAY8( &manufacturerDisplayID ); -} - -static void -send_accept( struct sockaddr *to, int tolen, CARD32 sessionID, - ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, - ARRAY8Ptr authorizationName, ARRAY8Ptr authorizationData, - int fd ) -{ - XdmcpHeader header; - - Debug( "<accept> session ID %ld\n", (long)sessionID ); - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)ACCEPT; - header.length = 4; /* session ID */ - header.length += 2 + authenticationName->length; - header.length += 2 + authenticationData->length; - header.length += 2 + authorizationName->length; - header.length += 2 + authorizationData->length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteCARD32( &buffer, sessionID ); - XdmcpWriteARRAY8( &buffer, authenticationName ); - XdmcpWriteARRAY8( &buffer, authenticationData ); - XdmcpWriteARRAY8( &buffer, authorizationName ); - XdmcpWriteARRAY8( &buffer, authorizationData ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)to, tolen ); -} - -static void -send_decline( struct sockaddr *to, int tolen, - ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData, - ARRAY8Ptr status, int fd ) -{ - XdmcpHeader header; - - Debug( "<decline> %.*s\n", status->length, status->data ); - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)DECLINE; - header.length = 0; - header.length += 2 + status->length; - header.length += 2 + authenticationName->length; - header.length += 2 + authenticationData->length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteARRAY8( &buffer, status ); - XdmcpWriteARRAY8( &buffer, authenticationName ); - XdmcpWriteARRAY8( &buffer, authenticationData ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)to, tolen ); -} - -static void -manage( struct sockaddr *from, int fromlen, int length, int fd ) -{ - CARD32 sessionID; - CARD16 displayNumber; - ARRAY8 displayClass; - int expectlen; - struct protoDisplay *pdpy; - struct display *d; - char *name = NULL; - char *class2 = NULL; - XdmcpNetaddr from_save; - ARRAY8 clientAddress, clientPort; - CARD16 connectionType; - - Debug( "<manage> %d\n", length ); - displayClass.data = 0; - displayClass.length = 0; - if (XdmcpReadCARD32( &buffer, &sessionID ) && - XdmcpReadCARD16( &buffer, &displayNumber ) && - XdmcpReadARRAY8( &buffer, &displayClass )) - { - expectlen = 4 + /* session ID */ - 2 + /* displayNumber */ - 2 + displayClass.length; /* displayClass */ - if (expectlen != length) { - Debug( "<manage> length error got %d expect %d\n", length, expectlen ); - goto abort; - } - pdpy = FindProtoDisplay( (XdmcpNetaddr)from, fromlen, displayNumber ); - Debug( "<manage> session ID %ld, pdpy %p\n", (long)sessionID, pdpy ); - if (!pdpy || pdpy->sessionID != sessionID) { - /* - * We may have already started a session for this display - * but it hasn't seen the response in the form of an - * XOpenDisplay() yet. So check if it is in the list of active - * displays, and if so check that the session id's match. - * If all this is true, then we have a duplicate request that - * can be ignored. - */ - if (!pdpy && - (d = FindDisplayByAddress( (XdmcpNetaddr)from, fromlen, - displayNumber )) && - d->sessionID == sessionID) - { - Debug( "manage: got duplicate pkt, ignoring\n" ); - goto abort; - } - Debug( "session ID %ld refused\n", (long)sessionID ); - if (pdpy) - Debug( "existing session ID %ld\n", (long)pdpy->sessionID ); - send_refuse( from, fromlen, sessionID, fd ); - } else { - name = NetworkAddressToName( pdpy->connectionType, - &pdpy->connectionAddress, - from, - pdpy->displayNumber ); - if (!name) { - Debug( "could not compute display name\n" ); - send_failed( from, fromlen, "(no name)", sessionID, - "out of memory", fd ); - goto abort; - } - Debug( "computed display name: %s\n", name ); - if ((d = FindDisplayByName( name ))) { - Debug( "terminating active session for %s\n", d->name ); - StopDisplay( d ); - } - if (displayClass.length) { - if (!StrNDup( &class2, (char *)displayClass.data, - displayClass.length )) - { - send_failed( from, fromlen, name, sessionID, - "out of memory", fd ); - goto abort; - } - } - if (!(from_save = (XdmcpNetaddr)Malloc( fromlen ))) { - send_failed( from, fromlen, name, sessionID, - "out of memory", fd ); - goto abort; - } - memmove( from_save, from, fromlen ); - if (!(d = NewDisplay( name ))) { - free( (char *)from_save ); - send_failed( from, fromlen, name, sessionID, - "out of memory", fd ); - goto abort; - } - d->class2 = class2; - class2 = 0; - d->displayType = dForeign | dTransient | dFromXDMCP; - d->sessionID = pdpy->sessionID; - d->from.data = (unsigned char *)from_save; - d->from.length = fromlen; - d->displayNumber = pdpy->displayNumber; - ClientAddress( from, &clientAddress, &clientPort, - &connectionType ); - d->useChooser = 0; - d->xdmcpFd = fd; - if (IsIndirectClient( &clientAddress, connectionType )) { - Debug( "IsIndirectClient\n" ); - ForgetIndirectClient( &clientAddress, connectionType ); - if (UseChooser( &clientAddress, connectionType )) { - d->useChooser = 1; - Debug( "use chooser for %s\n", d->name ); - } - } - d->clientAddr = clientAddress; - d->connectionType = connectionType; - d->remoteHost = NetworkAddressToHostname (pdpy->connectionType, - &pdpy->connectionAddress); - - XdmcpDisposeARRAY8( &clientPort ); - if (pdpy->fileAuthorization) { - d->authorizations = (Xauth **)Malloc( sizeof(Xauth *) ); - if (!d->authorizations) { - free( (char *)from_save ); - free( (char *)d ); - send_failed( from, fromlen, name, sessionID, - "out of memory", fd ); - goto abort; - } - d->authorizations[0] = pdpy->fileAuthorization; - d->authNum = 1; - pdpy->fileAuthorization = 0; - } - DisposeProtoDisplay( pdpy ); - Debug( "starting display %s,%s\n", d->name, d->class2 ); - if (LoadDisplayResources( d ) < 0) { - LogError( "Unable to read configuration for display %s; " - "stopping it.\n", d->name ); - StopDisplay( d ); - } else - StartDisplay( d ); - CloseGetter(); - } - } -abort: - XdmcpDisposeARRAY8( &displayClass ); - if (name) - free( (char *)name ); - if (class2) - free( (char *)class2 ); -} - -void -SendFailed( struct display *d, const char *reason ) -{ - Debug( "display start failed, sending <failed>\n" ); - send_failed( (struct sockaddr *)(d->from.data), d->from.length, d->name, - d->sessionID, reason, d->xdmcpFd ); -} - -static void -send_failed( struct sockaddr *from, int fromlen, - const char *name, CARD32 sessionID, const char *reason, int fd ) -{ - char buf[360]; - XdmcpHeader header; - ARRAY8 status; - - sprintf( buf, "Session %ld failed for display %.260s: %s", - (long)sessionID, name, reason ); - Debug( "send_failed(%\"s)\n", buf ); - status.length = strlen( buf ); - status.data = (CARD8Ptr) buf; - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)FAILED; - header.length = 6 + status.length; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteCARD32( &buffer, sessionID ); - XdmcpWriteARRAY8( &buffer, &status ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); -} - -static void -send_refuse( struct sockaddr *from, int fromlen, CARD32 sessionID, int fd ) -{ - XdmcpHeader header; - - Debug( "send <refuse> %ld\n", (long)sessionID ); - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)REFUSE; - header.length = 4; - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteCARD32( &buffer, sessionID ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); -} - -static void -send_alive( struct sockaddr *from, int fromlen, int length, int fd ) -{ - CARD32 sessionID; - CARD16 displayNumber; - struct display *d; - XdmcpHeader header; - CARD8 sendRunning; - CARD32 sendSessionID; - - Debug( "send <alive>\n" ); - if (XdmcpReadCARD16( &buffer, &displayNumber ) && - XdmcpReadCARD32( &buffer, &sessionID )) - { - if (length == 6) { - if (!(d = FindDisplayBySessionID( sessionID ))) - d = FindDisplayByAddress( (XdmcpNetaddr)from, fromlen, - displayNumber ); - sendRunning = 0; - sendSessionID = 0; - if (d && d->status == running) { - if (d->sessionID == sessionID) - sendRunning = 1; - sendSessionID = d->sessionID; - } - header.version = XDM_PROTOCOL_VERSION; - header.opcode = (CARD16)ALIVE; - header.length = 5; - Debug( "<alive>: %d %ld\n", sendRunning, (long)sendSessionID ); - XdmcpWriteHeader( &buffer, &header ); - XdmcpWriteCARD8( &buffer, sendRunning ); - XdmcpWriteCARD32( &buffer, sendSessionID ); - XdmcpFlush( fd, &buffer, (XdmcpNetaddr)from, fromlen ); - } - } -} - -char * -NetworkAddressToHostname( CARD16 connectionType, ARRAY8Ptr connectionAddress ) -{ - switch (connectionType) { - case FamilyInternet: -#if defined(IPv6) && defined(AF_INET6) - case FamilyInternet6: -#endif - { - struct hostent *he; - char *name, *lname; - char *myDot; - int af_type; -#if defined(IPv6) && defined(AF_INET6) - char dotted[INET6_ADDRSTRLEN]; - - if (connectionType == FamilyInternet6) - af_type = AF_INET6; - else -#endif - af_type = AF_INET; - - he = gethostbyaddr( (char *)connectionAddress->data, - connectionAddress->length, af_type ); - if (he) { -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai, *nai; - if (!getaddrinfo( he->h_name, NULL, NULL, &ai )) { - for (nai = ai; nai; nai = nai->ai_next) { - if (af_type == nai->ai_family && - !memcmp( nai->ai_family == AF_INET ? - (char *)&((struct sockaddr_in *)nai->ai_addr)->sin_addr : - (char *)&((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr, - connectionAddress->data, - connectionAddress->length )) - { - freeaddrinfo( ai ); - goto oki; - } - } - freeaddrinfo( ai ); -#else - if ((he = gethostbyname( he->h_name )) && - he->h_addrtype == AF_INET) - { - int i; - for (i = 0; he->h_addr_list[i]; i++) - if (!memcmp( he->h_addr_list[i], - connectionAddress->data, 4 )) - goto oki; -#endif - LogError( "DNS spoof attempt or misconfigured resolver.\n" ); - } - goto gotnone; - oki: - if (StrDup( &name, he->h_name ) && - !strchr( name, '.' ) && - (myDot = strchr( localHostname(), '.' ))) - { - if (ASPrintf( &lname, "%s%s", name, myDot )) { -#if defined(IPv6) && defined(AF_INET6) - if (!getaddrinfo( lname, NULL, NULL, &ai )) { - for (nai = ai; nai; nai = nai->ai_next) { - if (af_type == nai->ai_family && - !memcmp( nai->ai_family == AF_INET ? - (char *)&((struct sockaddr_in *)nai->ai_addr)->sin_addr : - (char *)&((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr, - connectionAddress->data, - connectionAddress->length )) - { - freeaddrinfo( ai ); - free( name ); - return lname; - } - } - freeaddrinfo( ai ); - } -#else - if ((he = gethostbyname( lname )) && - he->h_addrtype == AF_INET) - { - int i; - for (i = 0; he->h_addr_list[i]; i++) - if (!memcmp( he->h_addr_list[i], - connectionAddress->data, 4 )) - { - free( name ); - return lname; - } - } -#endif - free( lname ); - } - } - } else { - gotnone: - /* can't get name, so use emergency fallback */ -#if defined(IPv6) && defined(AF_INET6) - inet_ntop( af_type, connectionAddress->data, - dotted, sizeof(dotted) ); - StrDup( &name, dotted ); -#else - ASPrintf( &name, "%[4|'.'hhu", connectionAddress->data ); -#endif - LogWarn( "Cannot convert Internet address %s to host name\n", - name ); - } - return name; - } -#ifdef DNET - case FamilyDECnet: - break; -#endif /* DNET */ - default: - break; - } - return 0; -} - -#endif /* XDMCP */ - |