1/* 2 3Copyright 1988, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included 12in all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall 23not be used in advertising or otherwise to promote the sale, use or 24other dealings in this Software without prior written authorization 25from The Open Group. 26 27*/ 28 29/* 30 * xdm - display manager daemon 31 * Author: Keith Packard, MIT X Consortium 32 * 33 * dm.h 34 * 35 * public interfaces for greet/verify functionality 36 */ 37 38#ifndef _DM_H_ 39# define _DM_H_ 1 40 41# ifdef HAVE_CONFIG_H 42# include "config.h" 43# endif 44 45# include <X11/Xos.h> 46# include <X11/Xfuncs.h> 47# include <X11/Xfuncproto.h> 48# include <X11/Xmd.h> 49# include <X11/Xauth.h> 50# include <X11/Intrinsic.h> 51 52# if defined(X_POSIX_C_SOURCE) 53# define _POSIX_C_SOURCE X_POSIX_C_SOURCE 54# include <setjmp.h> 55# include <limits.h> 56# undef _POSIX_C_SOURCE 57# else 58# include <setjmp.h> 59# include <limits.h> 60# endif 61# include <time.h> 62# define Time_t time_t 63 64/* If XDMCP symbol defined, compile to run XDMCP protocol */ 65 66# define XDMCP 67 68# ifdef XDMCP 69# include <X11/Xdmcp.h> 70# endif 71 72 73# ifndef X_NOT_POSIX 74# ifdef _POSIX_SOURCE 75# include <sys/wait.h> 76# else 77# define _POSIX_SOURCE 78# include <sys/wait.h> 79# undef _POSIX_SOURCE 80# endif 81# define waitCode(w) (WIFEXITED(w) ? WEXITSTATUS(w) : 0) 82# define waitSig(w) (WIFSIGNALED(w) ? WTERMSIG(w) : 0) 83# define waitCore(w) 0 /* not in POSIX. so what? */ 84typedef int waitType; 85# else /* X_NOT_POSIX */ 86# include <sys/wait.h> 87# define waitCode(w) ((w).w_T.w_Retcode) 88# define waitSig(w) ((w).w_T.w_Termsig) 89# define waitCore(w) ((w).w_T.w_Coredump) 90typedef union wait waitType; 91# endif /* X_NOT_POSIX */ 92 93# ifdef USE_PAM 94# ifdef HAVE_SECURITY_PAM_TYPES_H 95# include <security/pam_types.h> 96# endif 97# ifdef HAVE_SECURITY_PAM_APPL_H 98# include <security/pam_appl.h> 99# elif defined(HAVE_PAM_PAM_APPL_H) 100# include <pam/pam_appl.h> 101# else 102# error "Unable to determine pam headers" 103# endif 104# endif 105 106# ifdef CSRG_BASED 107# include <sys/param.h> 108# ifdef HAVE_SETUSERCONTEXT 109# include <login_cap.h> 110# include <pwd.h> 111# ifdef USE_BSDAUTH 112# include <bsd_auth.h> 113# endif 114# endif 115# endif 116 117# define waitCompose(sig,core,code) ((sig) * 256 + (core) * 128 + (code)) 118# define waitVal(w) waitCompose(waitSig(w), waitCore(w), waitCode(w)) 119 120typedef enum displayStatus { running, notRunning, zombie, phoenix } DisplayStatus; 121 122# ifndef FD_ZERO 123typedef struct my_fd_set { int fds_bits[1]; } my_fd_set; 124# define FD_ZERO(fdp) bzero ((fdp), sizeof (*(fdp))) 125# define FD_SET(f,fdp) ((fdp)->fds_bits[(f) / (sizeof (int) * 8)] |= (1 << ((f) % (sizeof (int) * 8)))) 126# define FD_CLR(f,fdp) ((fdp)->fds_bits[(f) / (sizeof (int) * 8)] &= ~(1 << ((f) % (sizeof (int) * 8)))) 127# define FD_ISSET(f,fdp) ((fdp)->fds_bits[(f) / (sizeof (int) * 8)] & (1 << ((f) % (sizeof (int) * 8)))) 128# define FD_TYPE my_fd_set 129# else 130# define FD_TYPE fd_set 131# endif 132 133/* 134 * local - server runs on local host 135 * foreign - server runs on remote host 136 * permanent - session restarted when it exits 137 * transient - session not restarted when it exits 138 * fromFile - started via entry in servers file 139 * fromXDMCP - started with XDMCP 140 */ 141 142typedef struct displayType { 143 unsigned int location:1; 144 unsigned int lifetime:1; 145 unsigned int origin:1; 146} DisplayType; 147 148# define Local 1 149# define Foreign 0 150 151# define Permanent 1 152# define Transient 0 153 154# define FromFile 1 155# define FromXDMCP 0 156 157extern DisplayType parseDisplayType (char *string, int *usedDefault); 158 159typedef enum fileState { NewEntry, OldEntry, MissingEntry } FileState; 160 161struct display { 162 struct display *next; 163 /* Xservers file / XDMCP information */ 164 char *name; /* DISPLAY name */ 165 char *class; /* display class (may be NULL) */ 166 DisplayType displayType; /* method to handle with */ 167 char **argv; /* program name and arguments */ 168 169 /* display state */ 170 DisplayStatus status; /* current status */ 171 pid_t pid; /* process id of child */ 172 pid_t serverPid; /* process id of server (-1 if none) */ 173 FileState state; /* state during HUP processing */ 174 int startTries; /* current start try */ 175 Time_t lastReserv; /* time of last reserver crash */ 176 int reservTries; /* current reserver try */ 177# ifdef XDMCP 178 /* XDMCP state */ 179 CARD32 sessionID; /* ID of active session */ 180 XdmcpNetaddr peer; /* display peer address */ 181 int peerlen; /* length of peer address */ 182 XdmcpNetaddr from; /* XDMCP port of display */ 183 int fromlen; 184 CARD16 displayNumber; 185 int useChooser; /* Run the chooser for this display */ 186 ARRAY8 clientAddr; /* for chooser picking */ 187 CARD16 connectionType; /* ... */ 188 int xdmcpFd; 189# endif 190 /* server management resources */ 191 int serverAttempts; /* number of attempts at running X */ 192 int openDelay; /* open delay time */ 193 int openRepeat; /* open attempts to make */ 194 int openTimeout; /* abort open attempt timeout */ 195 int startAttempts; /* number of attempts at starting */ 196 int reservAttempts; /* allowed start-IO error sequences */ 197 int pingInterval; /* interval between XSync */ 198 int pingTimeout; /* timeout for XSync */ 199 int terminateServer;/* restart for each session */ 200 int grabServer; /* keep server grabbed for Login */ 201 int grabTimeout; /* time to wait for grab */ 202 int resetSignal; /* signal to reset server */ 203 int termSignal; /* signal to terminate server */ 204 int resetForAuth; /* server reads auth file at reset */ 205 char *keymaps; /* binary compat with DEC */ 206 char *greeterLib; /* greeter shared library name */ 207 208 /* session resources */ 209 char *resources; /* resource file */ 210 char *xrdb; /* xrdb program */ 211 char *setup; /* Xsetup program */ 212 char *startup; /* Xstartup program */ 213 char *reset; /* Xreset program */ 214 char *session; /* Xsession program */ 215 char *userPath; /* path set for session */ 216 char *systemPath; /* path set for startup/reset */ 217 char *systemShell; /* interpreter for startup/reset */ 218 char *failsafeClient;/* a client to start when the session fails */ 219 char *chooser; /* chooser program */ 220 221 /* authorization resources */ 222 int authorize; /* enable authorization */ 223 char **authNames; /* authorization protocol names */ 224 unsigned short *authNameLens; /* authorization protocol name lens */ 225 char *clientAuthFile;/* client specified auth file */ 226 char *userAuthDir; /* backup directory for tickets */ 227 int authComplain; /* complain when no auth for XDMCP */ 228 229 /* information potentially derived from resources */ 230 int authNameNum; /* number of protocol names */ 231 Xauth **authorizations;/* authorization data */ 232 int authNum; /* number of authorizations */ 233 char *authFile; /* file to store authorization in */ 234 235 int version; /* to keep dynamic greeter clued in */ 236 /* add new fields only after here. And preferably at the end. */ 237 238 /* Hack for making "Willing to manage" configurable */ 239 char *willing; /* "Willing to manage" program */ 240 Display *dpy; /* Display */ 241 char *windowPath; /* path to server "window" */ 242}; 243 244# ifdef XDMCP 245 246# define PROTO_TIMEOUT (30 * 60) /* 30 minutes should be long enough */ 247# define XDM_BROKEN_INTERVAL (120) /* server crashing more than once within */ 248 /* two minutes is assumed to be broken! */ 249struct protoDisplay { 250 struct protoDisplay *next; 251 XdmcpNetaddr address; /* UDP address */ 252 int addrlen; /* UDP address length */ 253 unsigned long date; /* creation date */ 254 CARD16 displayNumber; 255 CARD16 connectionType; 256 ARRAY8 connectionAddress; 257 CARD32 sessionID; 258 Xauth *fileAuthorization; 259 Xauth *xdmcpAuthorization; 260 ARRAY8 authenticationName; 261 ARRAY8 authenticationData; 262 XdmAuthKeyRec key; 263}; 264# endif /* XDMCP */ 265 266struct greet_info { 267 char *name; /* user name */ 268 char *password; /* user password */ 269 char *string; /* random string */ 270 char *passwd; /* binary compat with DEC */ 271 int version; /* for dynamic greeter to see */ 272 /* add new fields below this line, and preferably at the end */ 273 Boolean allow_null_passwd; /* allow null password on login */ 274 Boolean allow_root_login; /* allow direct root login */ 275}; 276 277typedef void (*ChooserFunc)(CARD16 connectionType, ARRAY8Ptr addr, char *closure); 278typedef void (*ListenFunc)(ARRAY8Ptr addr, void **closure); 279 280struct verify_info { 281 int uid; /* user id */ 282 int gid; /* group id */ 283 char **argv; /* arguments to session */ 284 char **userEnviron; /* environment for session */ 285 char **systemEnviron;/* environment for startup/reset */ 286 int version; /* for dynamic greeter to see */ 287 /* add new fields below this line, and preferably at the end */ 288}; 289 290/* display manager exit status definitions */ 291 292# define OBEYSESS_DISPLAY 0 /* obey multipleSessions resource */ 293# define REMANAGE_DISPLAY 1 /* force remanage */ 294# define UNMANAGE_DISPLAY 2 /* force deletion */ 295# define RESERVER_DISPLAY 3 /* force server termination */ 296# define OPENFAILED_DISPLAY 4 /* XOpenDisplay failed, retry */ 297 298# ifndef TRUE 299# define TRUE 1 300# define FALSE 0 301# endif 302 303extern char *config; 304 305extern char *servers; 306extern int request_port; 307extern int debugLevel; 308extern char *errorLogFile; 309extern int daemonMode; 310extern char *pidFile; 311extern int lockPidFile; 312extern char *authDir; 313extern int autoRescan; 314extern int removeDomainname; 315extern char *keyFile; 316extern char *accessFile; 317extern char **exportList; 318# if !defined(HAVE_ARC4RANDOM) 319extern char *randomFile; 320extern char *prngdSocket; 321extern int prngdPort; 322# endif 323 324extern char *greeterLib; 325extern char *willing; 326extern int choiceTimeout; /* chooser choice timeout */ 327 328extern struct display *FindDisplayByName (char *name), 329 *FindDisplayBySessionID (CARD32 sessionID), 330 *FindDisplayByAddress (XdmcpNetaddr addr, int addrlen, CARD16 displayNumber), 331 *FindDisplayByPid (pid_t pid), 332 *FindDisplayByServerPid (pid_t serverPid), 333 *NewDisplay (char *name, char *class); 334 335extern struct protoDisplay *FindProtoDisplay ( 336 XdmcpNetaddr address, 337 int addrlen, 338 CARD16 displayNumber); 339extern struct protoDisplay *NewProtoDisplay ( 340 XdmcpNetaddr address, 341 int addrlen, 342 CARD16 displayNumber, 343 CARD16 connectionType, 344 ARRAY8Ptr connectionAddress, 345 CARD32 sessionID); 346 347/* in Login.c */ 348extern void DrawFail (Widget ctx); 349 350/* in access.c */ 351extern ARRAY8Ptr getLocalAddress (void); 352extern int AcceptableDisplayAddress (ARRAY8Ptr clientAddress, CARD16 connectionType, xdmOpCode type); 353extern int ForEachMatchingIndirectHost (ARRAY8Ptr clientAddress, CARD16 connectionType, ChooserFunc function, char *closure); 354extern int ScanAccessDatabase (void); 355extern int UseChooser (ARRAY8Ptr clientAddress, CARD16 connectionType); 356extern void ForEachChooserHost (ARRAY8Ptr clientAddress, CARD16 connectionType, ChooserFunc function, char *closure); 357extern void ForEachListenAddr(ListenFunc listenfunction, 358 ListenFunc mcastfcuntion, void **closure); 359 360/* in choose.c */ 361extern ARRAY8Ptr IndirectChoice (ARRAY8Ptr clientAddress, CARD16 connectionType); 362extern int IsIndirectClient (ARRAY8Ptr clientAddress, CARD16 connectionType); 363extern int RememberIndirectClient (ARRAY8Ptr clientAddress, CARD16 connectionType); 364extern void ForgetIndirectClient ( ARRAY8Ptr clientAddress, CARD16 connectionType); 365extern void ProcessChooserSocket (int fd); 366 367/* in chooser.c */ 368extern void RunChooser (struct display *d) _X_NORETURN; 369 370/* in daemon.c */ 371extern void BecomeDaemon (void); 372extern void BecomeOrphan (void); 373 374/* in dm.c */ 375extern void CloseOnFork (void); 376extern void RegisterCloseOnFork (int fd); 377extern void StartDisplay (struct display *d); 378# ifndef HAVE_SETPROCTITLE 379extern void SetTitle (char *name, ...); 380# endif 381 382/* in dpylist.c */ 383extern int AnyDisplaysLeft (void); 384extern void ForEachDisplay (void (*f)(struct display *)); 385extern void RemoveDisplay (struct display *old); 386 387/* in file.c */ 388extern void ParseDisplay (char *source, DisplayType *acceptableTypes, int numAcceptable); 389 390/* in netaddr.c */ 391extern char *NetaddrAddress(XdmcpNetaddr netaddrp, int *lenp); 392extern char *NetaddrPort(XdmcpNetaddr netaddrp, int *lenp); 393extern int ConvertAddr (XdmcpNetaddr saddr, int *len, char **addr); 394extern int NetaddrFamily (XdmcpNetaddr netaddrp); 395extern int addressEqual (XdmcpNetaddr a1, int len1, XdmcpNetaddr a2, int len2); 396 397/* in policy.c */ 398extern ARRAY8Ptr ChooseAuthentication (ARRAYofARRAY8Ptr authenticationNames); 399extern int CheckAuthentication (struct protoDisplay *pdpy, ARRAY8Ptr displayID, ARRAY8Ptr name, ARRAY8Ptr data); 400extern int SelectAuthorizationTypeIndex (ARRAY8Ptr authenticationName, ARRAYofARRAY8Ptr authorizationNames); 401extern int SelectConnectionTypeIndex (ARRAY16Ptr connectionTypes, ARRAYofARRAY8Ptr connectionAddresses); 402extern int Willing (ARRAY8Ptr addr, CARD16 connectionType, ARRAY8Ptr authenticationName, ARRAY8Ptr status, xdmOpCode type); 403 404/* in protodpy.c */ 405extern void DisposeProtoDisplay(struct protoDisplay *pdpy); 406 407/* in reset.c */ 408extern void pseudoReset (Display *dpy); 409 410/* in resource.c */ 411extern void InitResources (int argc, char **argv); 412extern void LoadDMResources (void); 413extern void LoadServerResources (struct display *d); 414extern void LoadSessionResources (struct display *d); 415extern void ReinitResources (void); 416 417/* in session.c */ 418# ifdef USE_PAM 419extern pam_handle_t **thepamhp(void); 420extern pam_handle_t *thepamh(void); 421# endif 422extern char **defaultEnv (void); 423extern char **systemEnv (struct display *d, char *user, char *home); 424extern int PingServer(struct display *d, Display *alternateDpy); 425extern int source (char **environ, char *file); 426extern void ClearCloseOnFork (int fd); 427extern void DeleteXloginResources (struct display *d, Display *dpy); 428extern void LoadXloginResources (struct display *d); 429extern void ManageSession (struct display *d) _X_NORETURN; 430extern void SecureDisplay (struct display *d, Display *dpy); 431extern void SessionExit (struct display *d, int status, int removeAuth) _X_NORETURN; 432extern void SessionPingFailed (struct display *d) _X_NORETURN; 433extern void SetupDisplay (struct display *d); 434extern void UnsecureDisplay (struct display *d, Display *dpy); 435extern void execute(char **argv, char **environ); 436 437/* server.c */ 438extern const char *_SysErrorMsg (int n); 439extern int StartServer (struct display *d); 440extern int WaitForServer (struct display *d); 441extern void ResetServer (struct display *d); 442 443/* socket.c */ 444extern int GetChooserAddr (char *addr, int *lenp); 445extern void CreateWellKnownSockets (void); 446extern void UpdateListenSockets (void); 447extern void CloseListenSockets (void); 448extern void ProcessListenSockets (fd_set *readmask); 449 450/* in util.c */ 451# ifndef HAVE_ASPRINTF 452# define asprintf Asprintf 453extern int Asprintf(char ** ret, const char *restrict format, ...) 454 _X_ATTRIBUTE_PRINTF(2,3); 455# endif 456extern char *localHostname (void); 457extern char **parseArgs (char **argv, const char *string); 458extern char **setEnv (char **e, const char *name, const char *value); 459extern char **putEnv(const char *string, char **env); 460extern char *getEnv (char **e, const char *name); 461extern void CleanUpChild (void); 462extern void freeArgs (char **argv); 463extern void freeEnv (char **env); 464extern void printEnv (char **e); 465 466/* in verify.c */ 467extern int Verify (struct display *d, struct greet_info *greet, struct verify_info *verify); 468 469/* in xdmcp.c */ 470extern char *NetworkAddressToHostname (CARD16 connectionType, ARRAY8Ptr connectionAddress); 471extern int AnyWellKnownSockets (void); 472extern void DestroyWellKnownSockets (void); 473extern void SendFailed (struct display *d, const char *reason); 474extern void StopDisplay (struct display *d); 475extern void WaitForChild (void); 476extern void WaitForSomething (void); 477extern void init_session_id(void); 478extern void registerHostname(char *name, int namelen); 479extern void ProcessRequestSocket(int fd); 480 481/* 482 * CloseOnFork flags 483 */ 484 485# define CLOSE_ALWAYS 0 486# define LEAVE_FOR_DISPLAY 1 487 488# include <stdlib.h> 489 490# if defined(X_NOT_POSIX) || defined(__NetBSD__) && defined(__sparc__) 491# define Setjmp(e) setjmp(e) 492# define Longjmp(e,v) longjmp(e,v) 493# define Jmp_buf jmp_buf 494# else 495# define Setjmp(e) sigsetjmp(e,1) 496# define Longjmp(e,v) siglongjmp(e,v) 497# define Jmp_buf sigjmp_buf 498# endif 499 500typedef void (*SIGFUNC)(int); 501 502void (*Signal(int, SIGFUNC Handler))(int); 503 504#endif /* _DM_H_ */ 505