2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* (c) Copyright 1997 The Open Group */
25 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
26 * (c) Copyright 1993, 1994 International Business Machines Corp. *
27 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
28 * (c) Copyright 1993, 1994 Novell, Inc. *
31 * Xdm - display manager daemon
33 * $TOG: session.c /main/21 1998/11/02 14:32:42 mgreess $
35 * Copyright 1988 Massachusetts Institute of Technology
37 * Permission to use, copy, modify, and distribute this software and its
38 * documentation for any purpose and without fee is hereby granted, provided
39 * that the above copyright notice appear in all copies and that both that
40 * copyright notice and this permission notice appear in supporting
41 * documentation, and that the name of M.I.T. not be used in advertising or
42 * publicity pertaining to distribution of the software without specific,
43 * written prior permission. M.I.T. makes no representations about the
44 * suitability of this software for any purpose. It is provided "as is"
45 * without express or implied warranty.
47 * Author: Keith Packard, MIT X Consortium
67 # include <X11/Xatom.h>
69 #if defined(__FreeBSD__) && OSMAJORVERSION > 8
82 #include <X11/Intrinsic.h>
85 # include <X11/Xresource.h>
96 # include <sys/security.h>
102 #endif /* __KERBEROS */
105 #include "rgy_base.h"
110 static SIAENTITY *siaHandle = NULL;
111 static Boolean dt_in_sia_ses_authent = False;
113 static struct sia_greeter_info {
115 struct greet_info *greet;
116 struct verify_info *verify;
117 struct greet_state *state;
121 static int SiaManageGreeter(
124 unsigned char *title,
128 static CopySiaInfo(SIAENTITY *siaHandle, struct greet_info *greet);
130 static void KillGreeter( void );
132 static int sia_greeter_pid;
133 static int sia_exit_proc_reg = FALSE;
139 extern char *getenv();
142 #define GREET_STATE_LOGIN 0
143 #define GREET_STATE_AUTHENTICATE 1
144 #define GREET_STATE_EXIT 2
145 #define GREET_STATE_EXPASSWORD 3
146 #define GREET_STATE_ERRORMESSAGE 4
147 #define GREET_STATE_LANG 5
148 #define GREET_STATE_BAD_HOSTNAME 6
149 #define GREET_STATE_ENTER 7
150 #define GREET_STATE_TERMINATEGREET 8
151 #define GREET_STATE_USERNAME 9
152 #define GREET_STATE_CHALLENGE 10
153 #define GREET_STATE_FORM 11
156 #define DEF_SESSION CDE_INSTALLATION_TOP "/bin/Xsession"
164 int waitForResponse; /* TRUE=wait for response from dtgreet */
165 RequestHeader *request; /* request buffer */
166 ResponseHeader *response; /* response buffer */
167 int authenticated; /* TRUE=user is authenticated */
168 int vf; /* last return code from Authenticate() */
169 int loginReset; /* reset flag for LOGIN state */
170 char *msg; /* message for VF_MESSAGE */
173 char *globalDisplayName;
175 /***************************************************************************
177 * Local procedure declarations
179 ***************************************************************************/
181 static int AbortClient( int pid) ;
182 static void DeleteXloginResources( struct display *d, Display *dpy) ;
183 int LoadXloginResources( struct display *d) ;
184 static int ErrorHandler( Display *dpy, XErrorEvent *event) ;
185 static int IOErrorHandler( Display *dpy) ;
186 static int ManageGreeter( struct display *d, struct greet_info *greet,
187 struct verify_info *verify, struct greet_state *state) ;
188 static void RunGreeter( struct display *d, struct greet_info *greet,
189 struct verify_info *verify) ;
190 static void SessionExit( struct display *d, int status) ;
191 static void SessionPingFailed( struct display *d) ;
192 static int StartClient(struct verify_info *verify, struct display *d,
194 static SIGVAL catchAlrm( int arg ) ;
195 static SIGVAL catchHUP( int arg ) ;
196 static SIGVAL catchTerm( int arg ) ;
197 static SIGVAL waitAbort( int arg ) ;
198 static void SetupDisplay(struct display *d);
200 static void TellGreeter(RequestHeader *phdr);
201 static int AskGreeter(RequestHeader *preqhdr, char *b, int blen);
203 static void PrintResponse(ResponseHeader *phdr, int count);
206 #if defined (_AIX) && defined (_POWER)
207 static void release_aix_lic(void);
210 #if defined (_AIX) && !defined (_POWER)
211 static int session_execve(char *path, char *argv[], char *envp[]);
213 #define session_execve(A,B,C) execve(A,B,C)
217 static void SetTicketFileName(uid_t uid);
218 # endif /* __KERBEROS */
220 static void LoadAltDtsResources( struct display *d);
221 char * _ExpandLang(char *string, char *lang);
225 /***************************************************************************
229 ***************************************************************************/
231 static int clientPid;
232 static struct greet_info greet;
233 static struct verify_info verify;
234 static char *defaultLanguage = NULL;
236 static jmp_buf abortSession;
239 static char *sensitivityLevel;
243 static char krb_ticket_string[MAXPATHLEN];
244 #endif /* __KERBEROS */
247 XrmDatabase XresourceDB;
254 longjmp (abortSession, 1);
257 static jmp_buf pingTime;
262 longjmp (pingTime, 1);
266 FileNameCompare (a, b)
267 #if defined(__STDC__)
273 return strcoll (*(char **)a, *(char **)b);
277 SessionPingFailed( struct display *d )
281 AbortClient (clientPid);
282 source (&verify, d->reset);
284 #if defined (PAM) || defined(SUNAUTH)
286 char* user = getEnv (verify.userEnviron, "USER");
287 char* ttyLine = d->gettyLine;
289 #ifdef DEF_NETWORK_DEV
291 * If location is not local (remote XDMCP dtlogin) and
292 * remote accouting is enabled (networkDev start with /dev/...)
293 * Set tty line name to match network device for accouting.
294 * Unless the resource was specifically set, default is value
295 * of DEF_NETWORK_DEV define (/dev/dtremote)
298 if ( d->displayType.location != Local &&
299 networkDev && !strncmp(networkDev,"/dev/",5)) {
300 ttyLine = networkDev+5;
305 PamAccounting( verify.argv[0], d->name, d->utmpId, user,
306 ttyLine, clientPid, ACCOUNTING, NULL);
308 solaris_accounting( verify.argv[0], d->name, d->utmpId, user,
309 ttyLine, clientPid, ACCOUNTING, NULL);
313 solaris_resetdevperm(ttyLine);
319 SessionExit (d, RESERVER_DISPLAY);
324 * We need our own error handlers because we can't be sure what exit code Xlib
325 * will use, and our Xlib does exit(1) which matches REMANAGE_DISPLAY, which
326 * can cause a race condition leaving the display wedged. We need to use
327 * RESERVER_DISPLAY for IO errors, to ensure that the manager waits for the
328 * server to terminate. For other X errors, we should give up.
332 IOErrorHandler( Display *dpy )
335 const char *s = strerror(errno);
337 LogError(ReadCatalog(
338 MC_LOG_SET,MC_LOG_FATAL_IO,MC_DEF_LOG_FATAL_IO),
340 exit(RESERVER_DISPLAY);
345 ErrorHandler( Display *dpy, XErrorEvent *event )
347 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_X_ERR,MC_DEF_LOG_X_ERR));
348 if (XmuPrintDefaultErrorMessage (dpy, event, stderr) == 0) return 0;
349 exit(UNMANAGE_DISPLAY);
355 ManageSession( struct display *d )
361 char *BypassUsername;
363 #endif /* BYPASSLOGIN */
366 Debug ("ManageSession():\n");
368 /***********************************/
369 /** remember the default language **/
370 /***********************************/
371 if (defaultLanguage == NULL) {
372 if ( (d->language != NULL) && (strlen(d->language) > 0) ) {
373 defaultLanguage = strdup(d->language);
375 defaultLanguage = "C";
381 if ((BypassUsername = BypassLogin(d->name)) != NULL) {
383 Debug("Login bypassed, running as %s\n",BypassUsername);
384 greet.name = BypassUsername;
385 if (!Verify (d, &greet, &verify)) {
386 Debug ("Login bypass verify failed!\n");
387 SessionExit (d, GREETLESS_FAILED);
389 Debug("Login bypass verify succeded!\n");
391 #endif /* BYPASSLOGIN */
396 (void)XSetIOErrorHandler(IOErrorHandler);
397 (void)XSetErrorHandler(ErrorHandler);
398 SetTitle(d->name, (char *) 0);
401 * set root background to black...
404 dpy = XOpenDisplay(d->name);
405 for (i = ScreenCount(dpy) - 1; i >= 0; i--)
407 Window tmproot = RootWindow(dpy, i);
409 if (i == DefaultScreen(dpy))
412 XSetWindowBackground(dpy, tmproot, BlackPixel(dpy, i));
413 XClearWindow(dpy, tmproot);
419 ** Invoke Greet program, wait for completion.
420 ** If this routine returns, the user will have been
421 ** verified, otherwise the routine will exit inter-
422 ** nally with an appropriate exit code for the master
427 greet.name = greet.string = NULL;
429 while (greet.name == NULL) {
430 SetHourGlassCursor(dpy, root);
431 LoadXloginResources (d);
433 ApplyFontPathMods(d, dpy);
434 (void)XSetErrorHandler(ErrorHandler);
435 RunGreeter(d, &greet, &verify);
437 DeleteXloginResources (d, dpy);
439 XSetInputFocus(dpy, root, RevertToNone, CurrentTime);
445 * Generate Kerberos ticket file name. Put in system and user
449 if ( IsVerifyName(VN_KRB)) {
450 SetTicketFileName(verify.uid);
451 krb_set_tkt_string(krb_ticket_string);
452 verify.systemEnviron = setEnv (verify.systemEnviron,
456 verify.userEnviron = setEnv (verify.userEnviron,
460 #endif /* __KERBEROS */
462 /* set LOCATION env var */
463 if(d->displayType.location == Local) {
464 verify.systemEnviron = setEnv (verify.systemEnviron,
467 /* ITE is needed only for Local displays */
468 /* set ITE env var */
470 verify.systemEnviron = setEnv (verify.systemEnviron,
475 verify.systemEnviron = setEnv (verify.systemEnviron,
482 sprintf(gid,"%ld",(long)getgid());
483 /* set user group id (USER_GID) env var */
484 verify.systemEnviron = setEnv (verify.systemEnviron,
488 /* set root group id (ROOT_GID) env var */
489 pwd = getpwnam("root");
491 sprintf(gid,"%ld",(long)pwd->pw_gid);
492 verify.systemEnviron = setEnv (verify.systemEnviron,
499 * Run system-wide initialization file
501 if (source (&verify, d->startup) != 0)
503 Debug ("Startup program %s exited with non-zero status\n",
505 SessionExit (d, OBEYSESS_DISPLAY);
509 if ( solaris_setdevperm(d->gettyLine, verify.uid, verify.gid) == 0 ) {
510 SessionExit (d, OBEYSESS_DISPLAY);
515 if (!setjmp (abortSession)) {
516 signal (SIGTERM, catchTerm);
518 * Start the clients, changing uid/groups
519 * setting up environment and running the session
521 if (StartClient (&verify, d, &clientPid)) {
522 Debug ("Client started\n");
525 * We've changed dtlogin to pass HUP's down to the children
526 * so ignore any HUP's once the client has started.
528 signal(SIGHUP, SIG_IGN);
531 * Wait for session to end,
536 if (!setjmp (pingTime))
538 signal (SIGALRM, catchAlrm);
539 alarm (d->pingInterval * 60);
540 pid = wait ((waitType *) 0);
546 if (!PingServer (d, (Display *) NULL))
547 SessionPingFailed (d);
552 pid = wait ((waitType *) 0);
554 if (pid == clientPid)
559 * We've changed dtlogin to pass HUP's down to the children
560 * so ignore any HUP's once the client has started.
562 signal(SIGHUP, SIG_DFL);
564 LogError(ReadCatalog(
565 MC_LOG_SET,MC_LOG_FAIL_START,MC_DEF_LOG_FAIL_START));
569 * when terminating the session, nuke
570 * the child and then run the reset script
572 AbortClient (clientPid);
576 * on foreign displays without XDMCP, send a SIGTERM to the process
577 * group of the session manager. This augments the "resetServer()"
578 * routine and helps get all clients killed. It is possible for a client
579 * to have a connection to the server, but not have a window.
582 if (d->displayType.location == Foreign &&
583 d->displayType.origin != FromXDMCP )
584 AbortClient(clientPid);
589 * remove ticket file...
592 if ( IsVerifyName(VN_KRB) ) {
596 #endif /* __KERBEROS */
600 * run system-wide reset file
602 Debug ("Source reset program %s\n", d->reset);
603 source (&verify, d->reset);
605 #if defined(PAM) || defined(SUNAUTH)
607 char* user = getEnv (verify.userEnviron, "USER");
608 char* ttyLine = d->gettyLine;
610 # ifdef DEF_NETWORK_DEV
612 * If location is not local (remote XDMCP dtlogin) and
613 * remote accouting is enabled (networkDev start with /dev/...)
614 * Set tty line name to match network device for accouting.
615 * Unless the resource was specifically set, default is value
616 * of DEF_NETWORK_DEV define (/dev/dtremote)
619 if ( d->displayType.location != Local &&
620 networkDev && !strncmp(networkDev,"/dev/",5)) {
621 ttyLine = networkDev+5;
626 PamAccounting( verify.argv[0], d->name, d->utmpId, user,
627 ttyLine, clientPid, ACCOUNTING, NULL);
629 solaris_accounting( verify.argv[0], d->name, d->utmpId, user,
630 ttyLine, clientPid, ACCOUNTING, NULL);
634 solaris_resetdevperm(ttyLine);
639 SessionExit (d, OBEYSESS_DISPLAY);
644 LoadXloginResources( struct display *d )
647 char *language = NULL;
651 char *resources = NULL;
655 if (d->resources && d->resources[0]) {
656 resources = _ExpandLang(d->resources, d->language);
657 if (access (resources, R_OK) != 0) {
658 /** fallback to the C locale for resources **/
659 Debug("LoadXloginResources - cant access %s\n", resources);
660 Debug("\t %s. Falling back to C.\n", strerror(errno));
662 resources = _ExpandLang(d->resources, "C");
663 if (access (resources, R_OK) != 0) {
664 /** can't find a resource file, so bail **/
665 Debug("LoadXloginResources - cant access %s.\n", resources);
666 Debug("\t %s. Unable to find resource file.\n",
673 if (d->authFile && strlen(d->authFile) > 0 ) {
674 authority = d->authFile;
675 auth_key = "XAUTHORITY=";
678 if (d->language && strlen(d->language) > 0 ) {
679 language = strdup(d->language);
684 * replace any "-" or "." in the language name with "_". The C
685 * preprocessor used by xrdb does not accept "-" or "." in a name.
688 while ( (p = strchr(language, '-')) != NULL ) {
692 while ( (p = strchr(language, '.')) != NULL ) {
699 Debug("LoadXloginResources - loading resource db from %s\n", resources);
700 if((XresourceDB = XrmGetFileDatabase(resources)) == NULL)
701 Debug("LoadXloginResources - Loading resource db from %s failed\n",
704 LoadAltDtsResources(d);
706 strcpy(tmpname,"/var/dt/dtlogin_XXXXXX");
707 (void) mktemp(tmpname);
709 XrmPutFileDatabase(XresourceDB, tmpname);
711 sprintf (cmd, "%s%s %s -display %s -load %s",
712 auth_key, authority, d->xrdb, d->name, tmpname);
713 Debug ("Loading resource file: %s\n", cmd);
715 if(-1 == system (cmd)) {
716 Debug ("system() failed on cmd '%s'\n", cmd);
720 if (debugLevel <= 10)
721 if (unlink (tmpname) == -1)
722 Debug ("unlink() on %s failed\n", tmpname);
725 if (resources) free (resources);
730 /***************************************************************************
732 * LoadAltDtsResources
735 * set up alternate desktop resources..
737 ***************************************************************************/
740 LoadAltDtsResources(struct display *d)
744 char dirname[2][MAXPATHLEN];
745 char res_file[MAXPATHLEN];
746 char *rmtype; /* for XrmGetResource() */
747 XrmValue rmvalue; /* for XrmGetResource() */
748 char buf[MAXPATHLEN];
749 char tempbuf[MAXPATHLEN];
752 char altdtres[MAXPATHLEN];
753 char Altdtres[MAXPATHLEN];
756 char *resources = NULL;
758 int num_allocated = 0;
759 char **file_list = NULL;
762 if ( XrmGetResource(XresourceDB,
763 "Dtlogin*altDts", "Dtlogin*AltDts",
764 &rmtype, &rmvalue ) ) {
765 strcpy(tempbuf,rmvalue.addr);
769 strcpy(dirname[0],CDE_INSTALLATION_TOP "/config/%L/Xresources.d/");
770 strcpy(dirname[1],CDE_CONFIGURATION_TOP "/config/%L/Xresources.d/");
772 for(j = 0; j < 2 ; ++j)
774 resources = _ExpandLang(dirname[j], d->language);
775 if (access (resources, R_OK) != 0)
777 Debug("LoadAltDtsResources- cant access %s.\n", resources);
778 Debug("\t %s. Falling back to C.\n", strerror(errno));
786 resources = _ExpandLang(dirname[j], "C");
787 if (access (resources, R_OK) != 0)
789 Debug("LoadAltDtsResources- cant access %s.\n", resources);
790 Debug("\t %s.\n", strerror(errno));
793 strcpy(dirname[j], resources);
796 strcpy(dirname[j],resources);
797 Debug("LoadAltDtsResources- found resource dir %s\n", dirname[j]);
809 * Create a list of the alt DT files
811 * NOTE - an assumption made here is that files in /etc/dt
812 * should take precedence over files in /usr/dt. This precedence
813 * is maintained during the sort becase /etc/dt will come before
817 for(j = 0; j < 2 ; ++j) {
819 if((dirp = opendir(dirname[j])) != NULL) {
821 while((dp = readdir(dirp)) != NULL) {
823 if ((strcmp(dp->d_name, DOT) != 0) &&
824 (strcmp(dp->d_name, DOTDOT) != 0)) {
826 sprintf (res_file, "%s%s", dirname[j],dp->d_name);
827 if ((access (res_file, R_OK)) != 0)
829 Debug("LoadAltDtsResources- cant access %s.\n",
831 Debug("\t %s.\n", strerror(errno));
835 if (file_count == 0) {
836 file_list = malloc (list_incr * sizeof(char **));
837 num_allocated += list_incr;
839 if (file_count + 1 > num_allocated) {
840 num_allocated += list_incr;
841 file_list = realloc (file_list,
842 num_allocated * sizeof(char **));
844 file_list[file_count] = strdup (res_file);
853 qsort (file_list, file_count, sizeof (char *), FileNameCompare);
855 for (j = 0; j < file_count ; j++) {
857 userDb = XrmGetFileDatabase(file_list[j]);
858 XrmMergeDatabases(userDb,&XresourceDB);
860 if ( XrmGetResource(XresourceDB, "Dtlogin*altDtsIncrement",
861 "Dtlogin*AltDtsIncrement", &rmtype, &rmvalue ) ) {
864 * remove the trailing spaces
866 if(strchr(rmvalue.addr,' '))
867 strcpy(tempbuf, strtok(rmvalue.addr," "));
869 strcpy(tempbuf, rmvalue.addr);
871 if ((strcmp(tempbuf, "True") == 0) ||
872 (strcmp(tempbuf, "TRUE") == 0)) {
874 if ( XrmGetResource(XresourceDB,
875 "Dtlogin*altDtKey", "Dtlogin*AltDtKey",
876 &rmtype, &rmvalue ) ) {
878 sprintf(altdtres,"Dtlogin*altDtKey%d",i);
879 XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
884 if ( XrmGetResource(XresourceDB,
885 "Dtlogin*altDtName", "Dtlogin*AltDtName",
886 &rmtype, &rmvalue ) ) {
887 sprintf(altdtres,"Dtlogin*altDtName%d",i);
888 XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
890 if ( XrmGetResource(XresourceDB,
891 "Dtlogin*altDtStart", "Dtlogin*AltDtStart",
892 &rmtype, &rmvalue ) ) {
893 sprintf(altdtres,"Dtlogin*altDtStart%d",i);
894 XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
896 if ( XrmGetResource(XresourceDB,
897 "Dtlogin*altDtLogo", "Dtlogin*AltDtLogo",
898 &rmtype, &rmvalue ) ) {
899 sprintf(altdtres,"Dtlogin*altDtLogo%d",i);
900 XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
906 sprintf(tempbuf,"%d",i);
907 XrmPutStringResource(&XresourceDB, "Dtlogin*altDts", tempbuf);
909 if (file_count > 0) {
910 for (i = 0; i < file_count; i++) {
911 Debug ("Loading resource file: %s\n", file_list[i]);
921 * Function Name: _ExpandLang
925 * This function takes the string "string", searches for occurences of
926 * "%L" in the string and if found, the "%L" is substituted with
927 * the value of the $LANG environment variable.
929 * If $LANG is not defined, the %L is replace with NULL.
933 * _ExpandLang() is based on the DtSvc _DtExpandLang() static routine.
937 * ret_string = _ExpandLang (string);
939 * char *ret_string; Returns NULL if "string" is NULL or it points
940 * to the expanded string.
942 * char *string; The first part of the pathname. Typically
943 * the directory containing the item of interest.
945 * Note: The caller is responsible for free'ing the returned string.
967 * Count the number of expansions that will occur.
971 for (n = 0, pch = string ; pch != NULL ; ) {
972 if ((pch = strchr (pch, '%')) != NULL) {
979 return (strdup(string));
982 * We should really be calling setlocale to determine the "default"
983 * locale but setlocale's return value is not standardized across
984 * the various vendor platforms nor is it consistent within differnt
985 * revs of individual OS's. (e.g. its changing between HP-UX 9.0 and
986 * HP-UX 10.0). The "right" call would be the following line:
988 * if ((lang = getenv ("LANG")) || (lang = setlocale(LC_C_TYPE,NULL)))
990 * Here we hard code the default to "C" instead of leaving it NULL.
992 if (lang || (lang = getenv ("LANG")) || (lang = "C"))
993 lang_len = strlen (lang);
996 * Create the space needed.
998 tmp_len = strlen (string) + (n * lang_len) + n + 1;
999 tmp = (char *) malloc (tmp_len);
1000 for (i = 0; i < tmp_len; tmp[i] = '\0', i++);
1004 while (pch != NULL) {
1007 if ((pch = strchr (pch, '%')) != NULL) {
1012 (void) strncat (tmp, trail, ((pch - 1) - trail) + 1);
1014 else if ((pch != NULL) && *pch == 'L') {
1015 if (lang_len == 0) {
1016 if (((pch - trail) >=2) && (*(pch-2) == '/'))
1018 * Remove the "/" as well as the "%L".
1020 (void) strncat (tmp, trail, (pch - trail) - 2);
1022 (void) strncat (tmp, trail, (pch - trail) - 1);
1026 * Remove the "%L" and then append the LANG.
1028 (void) strncat (tmp, trail, (pch - trail) - 1);
1029 (void) strcat (tmp, lang);
1033 (void) strncat (tmp, trail, (pch - trail) + 1);
1040 * A '%' was not found.
1042 (void) strcat (tmp, trail);
1051 SetupDisplay (struct display *d)
1053 char **env = 0, **crt_systemEnviron;
1055 if (d->setup && d->setup[0] && (access(d->setup, R_OK ) == 0))
1057 crt_systemEnviron = verify.systemEnviron;
1058 env = systemEnv (d, (char *) 0, (char *) 0);
1059 if (d->authFile && strlen(d->authFile) > 0 )
1060 env = setEnv( env, "XAUTHORITY", d->authFile );
1061 if(d->displayType.location == Local)
1062 env = setEnv (env, LOCATION, "local");
1064 env = setEnv (env, LOCATION, "remote");
1065 verify.systemEnviron = env;
1066 source (&verify, d->setup);
1067 verify.systemEnviron = crt_systemEnviron;
1074 DeleteXloginResources( struct display *d, Display *dpy )
1076 XDeleteProperty(dpy, RootWindow (dpy, 0), XA_RESOURCE_MANAGER);
1079 #if 0 /* dead code: transferred to Dtgreet */
1081 static jmp_buf syncJump;
1086 longjmp (syncJump, 1);
1090 SecureDisplay (d, dpy)
1094 Debug ("SecureDisplay():\n");
1095 signal (SIGALRM, syncTimeout);
1096 if (setjmp (syncJump)) {
1097 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SECDPY,MC_DEF_LOG_NO_SECDPY),
1099 SessionExit (d, RESERVER_DISPLAY);
1101 alarm ((unsigned) d->grabTimeout);
1102 Debug ("Before XGrabServer()\n");
1104 if (XGrabKeyboard (dpy, DefaultRootWindow (dpy), True, GrabModeAsync,
1105 GrabModeAsync, CurrentTime) != GrabSuccess)
1108 signal (SIGALRM, SIG_DFL);
1109 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SECKEY,MC_DEF_LOG_NO_SECKEY),
1111 SessionExit (d, RESERVER_DISPLAY);
1113 Debug ("XGrabKeyboard() succeeded\n");
1115 signal (SIGALRM, SIG_DFL);
1119 XUngrabServer (dpy);
1122 Debug ("Done secure %s\n", d->name);
1125 UnsecureDisplay (d, dpy)
1129 Debug ("Unsecure display %s\n", d->name);
1131 XUngrabServer (dpy);
1140 release_aix_lic(void)
1143 * Release AIX iFOR/LS license (if any)
1151 release_me.request_type = -1;
1152 release_me.login_pid = getpid();
1153 if ((fd = open("/etc/security/monitord_pipe", O_RDWR, 0600)) >= 0)
1155 write(fd, &release_me, sizeof(release_me));
1158 Debug("release message to monitord: %s\n", (fd >= 0) ? "OK" : "failed");
1166 SessionExit( struct display *d, int status )
1175 /* make sure the server gets reset after the session is over */
1176 if (d->serverPid >= 2) {
1177 Debug("Reseting server: pid %d signal %d\n",
1178 d->serverPid, d->resetSignal);
1180 if (d->terminateServer == 0 && d->resetSignal)
1181 kill (d->serverPid, d->resetSignal);
1186 Debug("Exiting Session with status: %d\n", status);
1191 StartClient( struct verify_info *verify, struct display *d, int *pidp )
1194 char currentdir[PATH_MAX+1];
1195 char *failsafeArgv[20];
1196 char *user; /* users name */
1197 char *lang, *font; /* failsafe LANG and font */
1200 int failsafe = FALSE; /* do we run the failsafe session? */
1201 int password = FALSE; /* do we run /bin/passwd? */
1204 char lastsessfile[MAXPATHLEN];
1207 struct pr_passwd *b1_pwd;
1211 #define NOPAG 0xffffffff
1213 long ngroups, groups[NGROUPS];
1219 Debug ("StartSession %s: ", verify->argv[0]);
1220 for (f = verify->argv; *f; f++) {
1222 if ( strcmp(*f, "failsafe") == 0) failsafe = TRUE;
1223 if ( strcmp(*f, "password") == 0) failsafe = password = TRUE;
1227 if (verify->userEnviron) {
1228 for (f = verify->userEnviron; *f; f++)
1233 user = getEnv (verify->userEnviron, "USER");
1235 switch (pid = fork ()) {
1238 /* Force a failsafe session if we can't touch the home directory
1239 * SIA has already attempted to chdir to HOME, and the current dir
1240 * will be set to / if it failed. We just check to see if the HOME
1241 * path is our current directory or not.
1243 home = getEnv (verify->userEnviron, "HOME");
1244 getcwd(currentdir, PATH_MAX+1);
1245 Debug("Current directory is: %s\n", currentdir);
1249 * The following little check doesn't really work. For example,
1250 * here at the XC, NIS reports my home directory as
1251 * "/site/guests/montyb" while getcwd comes up with
1252 * "/net/nexus/site/guests/montyb".
1254 if (strcmp(home, currentdir)) {
1255 Debug("Can't access home directory, setting failsafe to TRUE\n");
1257 LogError (ReadCatalog(
1258 MC_LOG_SET,MC_LOG_NO_HMDIR,MC_DEF_LOG_NO_HMDIR),
1259 home, getEnv (verify->userEnviron, "USER"));
1260 verify->userEnviron = setEnv(verify->userEnviron, "HOME", "/");
1268 * do process accounting...
1270 #if defined(PAM) || defined(SUNAUTH)
1272 char* ttyLine = d->gettyLine;
1274 # ifdef DEF_NETWORK_DEV
1276 * If location is not local (remote XDMCP dtlogin) and
1277 * remote accouting is enabled (networkDev start with /dev/...)
1278 * Set tty line name to match network device for accouting.
1279 * Unless the resource was specifically set, default is value
1280 * of DEF_NETWORK_DEV define (/dev/dtremote)
1283 if ( d->displayType.location != Local &&
1284 networkDev && !strncmp(networkDev,"/dev/",5)) {
1285 ttyLine = networkDev+5;
1290 PamAccounting(verify->argv[0], d->name, d->utmpId, user,
1291 ttyLine, getpid(), USER_PROCESS, NULL);
1293 solaris_accounting(verify->argv[0], d->name, d->utmpId, user,
1294 ttyLine, getpid(), USER_PROCESS, NULL);
1299 #if !defined(sun) && !defined(CSRG_BASED)
1300 Account(d, user, NULL, getpid(), USER_PROCESS, status);
1305 * In _AIX _POWER, the PENV_NOEXEC flag was added. This tells
1306 * setpenv() to set up the user's process environment and return
1307 * without execing. This allows us to set up the process environment
1308 * and proceed to the execute() call as do the other platforms.
1310 * Unfortunately, for AIXV3, the PENV_NOEXEC does not exist, so
1311 * we have to pospone the setpenv() to the actual execute().
1315 * These defines are the tag locations in userEnviron.
1316 * IMPORTANT: changes to the locations of these tags in verify.c
1317 * must be reflected here by adjusting SYS_ENV_TAG or USR_ENV_TAG.
1319 #define SYS_ENV_TAG 0
1320 #define USR_ENV_TAG 3
1323 * Set the user's credentials: uid, gid, groups,
1324 * audit classes, user limits, and umask.
1327 if (setpcred(user, NULL) == -1)
1329 Debug("Can't set User's Credentials (user=%s)\n",user);
1334 char *usrTag, *sysTag;
1335 extern char **newenv;
1338 * Save pointers to tags. The setpenv() function clears the pointers
1339 * to the tags in userEnviron as a side-effect.
1341 sysTag = verify->userEnviron[SYS_ENV_TAG];
1342 usrTag = verify->userEnviron[USR_ENV_TAG];
1345 * Set the users process environment. Store protected variables and
1346 * obtain updated user environment list. This call will initialize
1349 #define SESSION_PENV (PENV_INIT | PENV_ARGV | PENV_NOEXEC)
1350 if (setpenv(user, SESSION_PENV, verify->userEnviron, NULL) != 0)
1352 Debug("Can't set process environment (user=%s)\n",user);
1357 * Restore pointers to tags.
1359 verify->userEnviron[SYS_ENV_TAG] = sysTag;
1360 verify->userEnviron[USR_ENV_TAG] = usrTag;
1363 * Free old userEnviron and replace with newenv from setpenv().
1365 freeEnv(verify->userEnviron);
1366 verify->userEnviron = newenv;
1376 if (PamSetCred( verify->argv[0],
1377 user, verify->uid, verify->gid) > 0 ) {
1378 Debug("Can't set User's Credentials (user=%s)\n",user);
1384 if ( solaris_setcred(verify->argv[0],
1385 user, verify->uid, verify->gid) > 0 ) {
1386 Debug("Can't set User's Credentials (user=%s)\n",user);
1389 #endif /* SUNAUTH */
1396 * HP BLS B1 session setup...
1398 * 1. look up user's protected account information.
1399 * 2. set the session sensitivity/clearance levels
1400 * 3. set the logical UID (LUID)
1404 Debug("BLS - Setting user's clearance, security level and luid.\n");
1405 set_auth_parameters(1, verify->argv);
1408 verify->user_name = user;
1409 strncpy(verify->terminal,d->name,15);
1410 verify->terminal[15]='\0';
1411 verify->pwd = getpwnam(user);
1413 if ( verify->pwd == NULL || strlen(user) == 0 ) {
1414 LogError(ReadCatalog(
1415 MC_LOG_SET,MC_LOG_NO_BLSACCT,MC_DEF_LOG_NO_BLSACCT));
1418 verify->prpwd= b1_pwd = getprpwnam(user);
1419 verify->uid = b1_pwd->ufld.fd_uid;
1421 if ( b1_pwd == NULL || strlen(user) == 0 ) {
1422 LogError(ReadCatalog(
1423 MC_LOG_SET,MC_LOG_NO_BLSPACCT,MC_DEF_LOG_NO_BLSPACCT));
1428 * This has already been done successfully by dtgreet
1429 * but we need to get all the information again for the
1432 if ( verify_user_seclevel(verify,sensitivityLevel) != 1 ) {
1433 Debug("BLS - Could not verify sensitivity level.\n");
1434 LogError(ReadCatalog(
1435 MC_LOG_SET,MC_LOG_NO_VFYLVL,MC_DEF_LOG_NO_VFYLVL));
1439 if ( change_to_user(verify) != 1 ) {
1440 Debug("BLS - Could not change to user: %s.\n",verify->user_name);
1441 LogError(ReadCatalog(
1442 MC_LOG_SET,MC_LOG_NO_BLSUSR,MC_DEF_LOG_NO_BLSUSR),
1447 Debug("BLS - Session setup complete.\n");
1454 * This should never fail since everything has been verified already.
1455 * If it does it must mean registry strangeness, so exit, and try
1459 if (!DoLogin (user, greet.password, d->name)) exit (1);
1462 * extract the SYSTYPE and ISP environment values and set into user's
1463 * environment. This is necessary since we do an execve below...
1466 verify->userEnviron = setEnv(verify->userEnviron, "SYSTYPE",
1469 verify->userEnviron = setEnv(verify->userEnviron, "ISP",
1472 #else /* ! __apollo */
1476 if ( IsVerifyName(VN_AFS) ) {
1477 pagval = get_pag_from_groups(verify->groups[0], verify->groups[1]);
1478 Debug("AFS - get_pag_from_groups() returned pagval = %d\n", pagval);
1480 initgroups(greet.name, verify->groups[2]);
1481 ngroups = getgroups(NGROUPS, groups);
1482 Debug("AFS - getgroups() returned ngroups = %d\n", ngroups);
1483 for (i=0; i < ngroups; i++)
1484 Debug("AFS - groups[%d] = %d\n", i, groups[i]);
1486 if ((pagval != NOPAG) &&
1487 (get_pag_from_groups(groups[0], groups[1])) == NOPAG ) {
1488 /* we will have to shift grouplist to make room for pag */
1489 if (ngroups+2 > NGROUPS)
1491 for (j=ngroups-1; j >= 0; j--) {
1492 groups[j+2] = groups[j];
1495 get_groups_from_pag(pagval, &groups[0], &groups[1]);
1496 if (setgroups(ngroups, groups) == -1) {
1499 MC_LOG_SET,MC_LOG_AFS_FAIL,MC_DEF_LOG_AFS_FAIL));
1504 # else /* ! __AFS */
1505 /* If SIA is enabled, the initgroups and setgid calls are redundant
1512 * if your system does not support "initgroups(3C)", use
1513 * the "setgroups()" call instead...
1516 # if (defined(__hpux) || defined(__osf__))
1517 initgroups(user, -1);
1519 setgroups (verify->ngroups, verify->groups);
1522 /* setpenv() will set gid for AIX */
1524 if(-1 == setgid (verify->groups[0])) {
1525 perror(strerror(errno));
1529 # else /* ! NGROUPS */
1531 /* setpenv() will set gid for AIX */
1533 setgid (verify->gid);
1536 # endif /* NGROUPS */
1542 setaudid(verify->audid);
1543 setaudproc(verify->audflg);
1546 /* setpenv() will set uid for AIX */
1548 if (setuid(verify->uid) != 0) {
1549 Debug( "Setuid failed for user %s, errno = %d\n", user, errno);
1550 LogError(ReadCatalog(
1551 MC_LOG_SET,MC_LOG_FAIL_SETUID,MC_DEF_LOG_FAIL_SETUID),
1557 #endif /* __apollo */
1560 } /* ends the else clause of if ( ISSECURE ) */
1566 * check home directory again...
1570 /* Don't need to do this if SIA is enabled, already been done.
1572 home = getEnv (verify->userEnviron, "HOME");
1574 if (chdir (home) == -1) {
1575 LogError (ReadCatalog(
1576 MC_LOG_SET,MC_LOG_NO_HMDIR,MC_DEF_LOG_NO_HMDIR),
1577 home, getEnv (verify->userEnviron, "USER"));
1578 if(-1 == chdir ("/")) {
1579 perror(strerror(errno));
1581 verify->userEnviron = setEnv(verify->userEnviron,
1584 else if(!failsafe) {
1585 strcpy(lastsessfile,home); /* save user's last session */
1586 strcat(lastsessfile,LAST_SESSION_FILE);
1587 if((lastsession = fopen(lastsessfile,"w")) == NULL)
1588 Debug("Unable to open file for writing: %s\n",lastsessfile);
1590 fputs(verify->argv[0],lastsession);
1591 fclose(lastsession);
1598 SetUserAuthorization (d, verify);
1604 bzero(greet.password, strlen(greet.password));
1608 * Write login information to a file
1609 * The file name should really be settable by some kind of resource
1610 * but time is short so we hard-wire it to ".dtlogininfo".
1612 if ( ! writeLoginInfo( ".dtlogininfo" , verify ) )
1613 Debug("Unable to write \".dtlogininfo\"\n");
1615 /* extra debugging */
1616 if(!dump_sec_debug_info(verify)) {
1617 Debug("Something wrong with environment\n");
1620 # endif /* ! NDEBUG */
1628 Debug ("Executing session %s\n", verify->argv[0]);
1629 execute (verify->argv, verify->userEnviron);
1630 LogError(ReadCatalog(
1631 MC_LOG_SET,MC_LOG_SES_EXEFAIL,MC_DEF_LOG_SES_EXEFAIL),
1635 LogError(ReadCatalog(
1636 MC_LOG_SET,MC_LOG_NO_CMDARG,MC_DEF_LOG_NO_CMDARG));
1643 * specify a font for the multi-byte languages...
1647 lang = getEnv (verify->userEnviron, "LANG");
1654 failsafeArgv[i++] = "/usr/bin/X11/aixterm";
1656 failsafeArgv[i++] = "/usr/openwin/bin/xterm";
1657 #elif defined (USL) || defined(__uxp__)
1658 failsafeArgv[i++] = "/usr/X/bin/xterm";
1659 #elif defined(__hpux)
1660 failsafeArgv[i++] = "/usr/bin/X11/hpterm";
1661 #elif defined(__OpenBSD__)
1662 failsafeArgv[i++] = "/usr/X11R6/bin/xterm";
1663 #elif defined(__NetBSD__)
1664 failsafeArgv[i++] = "/usr/X11R7/bin/xterm";
1665 #elif defined(__FreeBSD__)
1666 failsafeArgv[i++] = "/usr/local/bin/xterm";
1668 failsafeArgv[i++] = "/usr/bin/X11/xterm";
1670 failsafeArgv[i++] = "-geometry";
1671 failsafeArgv[i++] = "80x10";
1672 failsafeArgv[i++] = "-bg";
1673 failsafeArgv[i++] = "white";
1674 failsafeArgv[i++] = "-fg";
1675 failsafeArgv[i++] = "black";
1677 /* aixterm requires -lang option. */
1678 failsafeArgv[i++] = "-lang";
1679 failsafeArgv[i++] = lang;
1681 failsafeArgv[i++] = "-fn";
1683 if (font == NULL) font = "fixed";
1684 failsafeArgv[i++] = font;
1687 failsafeArgv[i++] = "-e";
1688 failsafeArgv[i++] = "/bin/passwd";
1689 #if defined (__apollo) || defined(__PASSWD_ETC)
1690 failsafeArgv[i++] = "-n";
1692 failsafeArgv[i++] = getEnv (verify->userEnviron, "USER");
1695 failsafeArgv[i++] = d->failsafeClient;
1697 failsafeArgv[i++] = "-C";
1699 failsafeArgv[i++] = "-ls";
1702 failsafeArgv[i++] = "-fn";
1703 failsafeArgv[i++] = font;
1707 failsafeArgv[i] = 0;
1708 Debug ("Executing failsafe session\n", failsafeArgv[0]);
1709 execute (failsafeArgv, verify->userEnviron);
1712 Debug ("StartSession(): fork failed\n");
1713 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SESFORK,MC_DEF_LOG_NO_SESFORK),
1717 Debug ("StartSession(): fork succeeded, pid = %d\n", pid);
1724 static jmp_buf tenaciousClient;
1727 waitAbort( int arg )
1729 longjmp (tenaciousClient, 1);
1732 #if defined(SYSV) || defined(SVR4)
1734 #define killpg(pgrp, sig) kill(-(pgrp), sig)
1738 AbortClient( int pid )
1747 for (i = 0; i < 4; i++) {
1748 if (killpg (pid, sig) == -1) {
1751 LogError(ReadCatalog(
1752 MC_LOG_SET,MC_LOG_NO_KILLCL,MC_DEF_LOG_NO_KILLCL));
1758 if (!setjmp (tenaciousClient)) {
1759 (void) signal (SIGALRM, waitAbort);
1760 (void) alarm ((unsigned) 10);
1761 retId = wait ((waitType *) 0);
1762 (void) alarm ((unsigned) 0);
1763 (void) signal (SIGALRM, SIG_DFL);
1767 signal (SIGALRM, SIG_DFL);
1774 source( struct verify_info *verify, char *file )
1780 if (file && file[0]) {
1781 Debug ("Source(): %s\n", file);
1782 switch (pid = fork ()) {
1787 execute (args, verify->systemEnviron);
1788 LogError(ReadCatalog(
1789 MC_LOG_SET,MC_LOG_NO_EXE,MC_DEF_LOG_NO_EXE),args[0]);
1792 Debug ("Source(): fork failed\n");
1793 LogError(ReadCatalog(
1794 MC_LOG_SET,MC_LOG_NO_FORK,MC_DEF_LOG_NO_FORK),file);
1798 while (wait (&result) != pid)
1802 return waitVal (result);
1807 /* returns 0 on failure, -1 on out of mem, and 1 on success */
1809 execute(char **argv, char **environ )
1813 * make stdout follow stderr to the log file...
1818 session_execve (argv[0], argv, environ);
1821 * In case this is a shell script which hasn't been made executable
1822 * (or this is a SYSV box), do a reasonable thing...
1826 /* errno is EACCES if not executable */
1827 if (errno == ENOEXEC || errno == EACCES) {
1829 if (errno == ENOEXEC) {
1831 char program[1024], *e, *p, *optarg;
1833 char **newargv, **av;
1837 * emulate BSD kernel behaviour -- read
1838 * the first line; check if it starts
1839 * with "#!", in which case it uses
1840 * the rest of the line as the name of
1841 * program to run. Else use "/bin/sh".
1843 f = fopen (argv[0], "r");
1846 if (fgets (program, sizeof (program) - 1, f) == NULL)
1852 e = program + strlen (program) - 1;
1855 if (!strncmp (program, "#!", 2)) {
1857 while (*p && isspace (*p))
1860 while (*optarg && !isspace (*optarg))
1866 while (*optarg && isspace (*optarg));
1873 Debug ("Shell script execution: %s (optarg %s)\n",
1874 p, optarg ? optarg : "(null)");
1875 for (av = argv, argc = 0; *av; av++, argc++)
1877 newargv = (char **) malloc ((argc + (optarg ? 3 : 2)) * sizeof (char *));
1884 while (*av++ = *argv++)
1886 session_execve (newargv[0], newargv, environ);
1895 /*****************************************************************************
1898 * Invoke the Greeter process and wait for completion. If the user was
1899 * successfully verified, return to the calling process. If the user
1900 * selected a restart or abort option, or there was an error invoking the
1901 * Greeter, exit this entire process with appropriate status.
1903 *****************************************************************************/
1907 extern int session_set;
1908 extern char *progName; /* Global argv[0]; dtlogin name and path */
1910 int response[2], request[2];
1912 /* Fixes problem with dtlogin signal handling */
1913 static int greeterPid = 0;
1914 static struct display *greeter_d = NULL;
1919 Debug("Caught SIGHUP\n");
1922 Debug("Killing greeter process: %d\n", greeterPid);
1923 kill(greeterPid, SIGHUP);
1926 SessionExit(greeter_d, REMANAGE_DISPLAY);
1928 exit(REMANAGE_DISPLAY);
1932 RunGreeter( struct display *d, struct greet_info *greet,
1933 struct verify_info *verify )
1940 static char msg[MSGSIZE];
1944 struct greet_state state = {};
1951 # define U_NAMELEN sizeof(rgy_$name_t)
1955 static char name_short[U_NAMELEN];
1961 char *argv[] = { "dtlogin", 0 };
1962 char *hostName = NULL;
1963 char *loginName = NULL;
1970 if (d->serverPid == -1)
1973 siaStatus = sia_ses_init(&siaHandle, argc, argv, hostName,
1974 loginName, d->name, 1, NULL);
1975 if (siaStatus != SIASUCCESS)
1977 Debug("sia_ses_init failure status %d\n", siaStatus);
1984 if (!setjmp (abortSession)) {
1985 signal(SIGTERM, catchTerm);
1988 * We've changed dtlogin to pass HUP's down to the children
1989 * so ignore any HUP's once the client has started.
1992 signal(SIGHUP, catchHUP);
1995 * set up communication pipes...
1998 if(-1 == pipe(response)) {
1999 perror(strerror(errno));
2001 if(-1 == pipe(request)) {
2002 perror(strerror(errno));
2007 switch (greeterPid = fork ()) {
2011 * pass some information in the environment...
2015 sprintf(msg,"%d", d->grabServer);
2016 env = setEnv(env, GRABSERVER, msg);
2018 sprintf(msg,"%d", d->grabTimeout);
2019 env = setEnv(env, GRABTIMEOUT, msg);
2022 if (timeZone && strlen(timeZone) > 0 )
2023 env = setEnv(env, "TZ", timeZone);
2025 if (errorLogFile && errorLogFile[0])
2026 env = setEnv(env, ERRORLOG, errorLogFile);
2029 env = setEnv(env, "XAUTHORITY", d->authFile);
2032 env = setEnv(env, DTLITE, "True");
2035 env = setEnv(env, SESSION, d->session);
2038 env = setEnv(env, SESSION_SET, "True");
2040 if (d->pmSearchPath)
2041 env = setEnv(env, "XMICONSEARCHPATH", d->pmSearchPath);
2043 if (d->bmSearchPath)
2044 env = setEnv(env, "XMICONBMSEARCHPATH", d->bmSearchPath);
2046 #if defined (__KERBEROS) || defined (__AFS)
2047 if (d->verifyName) {
2048 if ( (strcmp(d->verifyName, VN_AFS) == 0) ||
2049 (strcmp(d->verifyName, VN_KRB) == 0) ) {
2051 env = setEnv(env, VERIFYNAME, d->verifyName );
2054 LogError(ReadCatalog(
2055 MC_LOG_SET,MC_LOG_IMPROP_AUTH,MC_DEF_LOG_IMPROP_AUTH),
2057 d->verifyName = NULL;
2062 if((path = getenv("NLSPATH")) != NULL)
2063 env = setEnv(env, "NLSPATH", path);
2065 env = setEnv(env, "NLSPATH", "/usr/lib/nls/msg/%L/%N.cat");
2070 * ping remote displays...
2074 if (d->displayType.location == Local) {
2075 GettyRunning(d); /* refresh gettyState */
2076 if (d->gettyState != DM_GETTY_USER)
2077 env = setEnv(env, LOCATION, "local");
2080 sprintf(msg,"%d", d->pingInterval);
2081 env = setEnv(env, PINGINTERVAL, msg);
2083 sprintf(msg,"%d", d->pingTimeout);
2084 env = setEnv(env, PINGTIMEOUT, msg);
2088 if ( d->langList && strlen(d->langList) > 0 )
2089 env = setEnv(env, LANGLIST, d->langList);
2090 #if !defined (ENABLE_DYNAMIC_LANGLIST)
2091 else if (languageList && strlen(languageList) > 0 )
2092 env = setEnv(env, LANGLIST, languageList);
2093 #endif /* ENABLE_DYNAMIC_LANGLIST */
2096 char *language = NULL;
2098 #if defined (ENABLE_DYNAMIC_LANGLIST)
2099 language = d->language;
2100 #endif /* ENABLE_DYNAMIC_LANGLIST */
2102 if ( d->language && strlen(d->language) > 0 )
2103 env = setLang(d, env, language);
2106 if((path = getenv("XKEYSYMDB")) != NULL)
2107 env = setEnv(env, "XKEYSYMDB", path);
2110 if((path = getenv("OPENWINHOME")) != NULL)
2111 env = setEnv(env, "OPENWINHOME", path);
2116 * set environment for Domain machines...
2118 env = setEnv(env, "ENVIRONMENT", "bsd");
2119 env = setEnv(env, "SYSTYPE", "bsd4.3");
2123 Debug ("Greeter environment:\n");
2125 Debug ("End of Greeter environment:\n");
2128 * Writing to file descriptor 1 goes to response pipe instead.
2131 dupfp = dup(response[1]);
2133 perror(strerror(errno));
2139 * Reading from file descriptor 0 reads from request pipe instead.
2142 dupfp2 = dup(request[0]);
2144 perror(strerror(errno));
2152 * figure out path to dtgreet...
2155 strcpy(msg, progName);
2157 if ((p = (char *) strrchr(msg, '/')) == NULL)
2162 strcat(msg,"dtgreet");
2164 execle(msg, "dtgreet", "-display", d->name, (char *)0, env);
2165 LogError(ReadCatalog(
2166 MC_LOG_SET,MC_LOG_NO_DTGREET,MC_DEF_LOG_NO_DTGREET),
2168 exit (NOTIFY_ABORT_DISPLAY);
2171 Debug ("Fork of Greeter failed.\n");
2172 LogError(ReadCatalog(
2173 MC_LOG_SET,MC_LOG_NO_FORKCG,MC_DEF_LOG_NO_FORKCG),d->name);
2178 exit (UNMANAGE_DISPLAY);
2181 Debug ("Greeter started\n");
2183 close(response[1]); /* Close write end of response pipe */
2184 close(request[0]); /* Close read end of request pipe */
2188 * Retrieve information from greeter and authenticate.
2190 globalDisplayName = d->name;
2191 state.id = GREET_STATE_ENTER;
2192 state.waitForResponse = FALSE;
2196 * atexit() registers this function to be called if exit() is
2197 * called. This is needed because in enhanced security mode, SIA
2198 * may call exit() whn the user fails to enter or change a
2201 sia_greeter_pid = greeterPid;
2202 if (!sia_exit_proc_reg)
2204 atexit(KillGreeter);
2205 sia_exit_proc_reg = TRUE;
2208 siaGreeterInfo.d = d;
2209 siaGreeterInfo.greet = greet;
2210 siaGreeterInfo.verify = verify;
2211 siaGreeterInfo.state = &state;
2212 siaGreeterInfo.status = TRUE;
2215 while(siaStatus != SIASUCCESS)
2217 while(siaStatus != SIASUCCESS && siaGreeterInfo.status)
2219 Debug ("RunGreeter: before sia_ses_authent\n");
2220 dt_in_sia_ses_authent = True;
2221 siaStatus = sia_ses_authent(SiaManageGreeter, NULL,
2223 dt_in_sia_ses_authent = False;
2224 Debug ("RunGreeter: after sia_ses_authent status = %d\n",
2226 if (siaStatus == SIAFAIL && siaGreeterInfo.status)
2228 state.id = GREET_STATE_ERRORMESSAGE;
2229 state.vf = VF_INVALID;
2230 ManageGreeter(d, greet, verify, &state);
2232 if (!siaGreeterInfo.status || siaStatus == SIASTOP)
2235 if (!siaGreeterInfo.status || siaStatus == SIASTOP)
2237 sia_ses_release(&siaHandle);
2241 Debug("RunGreeter: before sia_ses_estab\n");
2242 siaStatus = sia_ses_estab(SiaManageGreeter, siaHandle);
2243 Debug ("RunGreeter: after sia_ses_estab status = %d\n",
2246 if (!siaGreeterInfo.status)
2249 if (siaStatus == SIASUCCESS)
2251 Debug("RunGreeter: before sia_ses_launch\n");
2252 siaStatus = sia_ses_launch(SiaManageGreeter, siaHandle);
2253 Debug("RunGreeter: after sia_ses_launch status = %d\n",
2256 if (!siaGreeterInfo.status)
2259 if (siaStatus != SIASUCCESS)
2261 Debug("RunGreeter: sia_ses_launch failure\n");
2262 /* establish & launch failures do a release */
2264 siaStatus = sia_ses_init(&siaHandle, argc, argv, hostName,
2265 loginName, d->name, 1, NULL);
2266 if (siaStatus != SIASUCCESS)
2268 Debug("sia_ses_init failure status %d\n", siaStatus);
2269 exit(RESERVER_DISPLAY);
2274 * sia_ses_launch() wil probably seteuid to that of the
2275 * user, but we don't want that now.
2279 * extract necessary info from SIA context struct
2283 if (siaStatus == SIASUCCESS)
2284 CopySiaInfo(siaHandle, greet);
2285 sia_ses_release(&siaHandle);
2287 state.id = GREET_STATE_TERMINATEGREET;
2288 if (siaGreeterInfo.status)
2290 while (ManageGreeter(d, greet, verify, &state))
2293 sia_greeter_pid = 0;
2295 while (ManageGreeter(d, greet, verify, &state))
2300 * Wait for Greeter to end...
2303 pid = wait (&status);
2304 if (pid == greeterPid)
2310 * Greeter exited. Check return code...
2313 Debug("Greeter return status; exit = %d, signal = %d\n",
2314 waitCode(status), waitSig(status));
2318 * remove authorization file if used...
2321 if (d->authorizations && d->authFile &&
2322 waitVal(status) != NOTIFY_LANG_CHANGE
2324 && waitVal(status) != NOTIFY_BAD_SECLEVEL
2329 Debug ("Done with authorization file %s, removing\n",
2331 (void) unlink (d->authFile);
2336 if(waitVal(status) > NOTIFY_ALT_DTS)
2337 d->sessionType = waitVal(status);
2340 switch (waitVal(status)) {
2341 case NOTIFY_FAILSAFE:
2342 greet->string = "failsafe";
2344 case NOTIFY_PASSWD_EXPIRED:
2345 greet->string = "password";
2350 case NOTIFY_LAST_DT:
2351 d->sessionType = waitVal(status);
2357 Debug("waitVal - status is %d\n", waitVal(status));
2358 if(waitVal(status) > NOTIFY_ALT_DTS)
2359 notify_dt = NOTIFY_ALT_DTS; /* It is alt desktops */
2361 notify_dt = waitVal(status);
2363 switch (notify_dt) {
2364 case NOTIFY_FAILSAFE:
2365 case NOTIFY_PASSWD_EXPIRED:
2369 case NOTIFY_LAST_DT:
2370 case NOTIFY_ALT_DTS:
2372 if (NULL == greet->name) return;
2375 * greet->name, greet->password set in ManageGreeter().
2377 Debug("Greeter returned name '%s'\n", greet->name);
2380 greet->name_full = greet->name;
2381 /* get just person name out of full SID */
2383 while (i < sizeof(rgy_$name_t)
2384 && greet->name_full[i] != '.'
2385 && greet->name_full[i] != '\0') {
2386 name_short[i] = greet->name_full[i];
2389 name_short[i] = '\0';
2390 greet->name = name_short;
2395 * groups[] set in Authenticate().
2397 if ( IsVerifyName(VN_AFS) ) {
2398 verify->groups[0] = groups[0];
2399 verify->groups[1] = groups[1];
2400 Debug("Greeter returned groups[0] '%d'\n", verify->groups[0]);
2401 Debug("Greeter returned groups[1] '%d'\n", verify->groups[1]);
2407 * sensitivityLevel set in BLS_Verify()
2409 greet->b1security = sensitivityLevel;
2412 Verify(d, greet, verify);
2416 Debug ("Greeter Xlib error or SIGTERM\n");
2417 SessionExit(d, OPENFAILED_DISPLAY);
2419 case NOTIFY_RESTART:
2420 Debug ("Greeter requested RESTART_DISPLAY\n");
2421 SessionExit(d, RESERVER_DISPLAY);
2423 case NOTIFY_ABORT_DISPLAY:
2424 Debug ("Greeter requested UNMANAGE_DISPLAY\n");
2425 SessionExit(d, UNMANAGE_DISPLAY);
2427 case NOTIFY_NO_WINDOWS:
2428 Debug ("Greeter requested NO_WINDOWS mode\n");
2429 if (d->serverPid >= 2)
2431 * Don't do a SessionExit() here since that causes
2432 * the X-server to be reset. We know we are going to
2433 * terminate it anyway, so just go do that...
2435 exit(SUSPEND_DISPLAY);
2439 case NOTIFY_LANG_CHANGE:
2440 Debug ("Greeter requested LANG_CHANGE\n");
2443 * copy requested language into display struct "d". Note,
2444 * this only happens in this child's copy of "d", not in
2445 * the master struct. When the user logs out, the
2446 * resource-specified language (if any) will reactivate.
2449 Debug("Greeter returned language '%s'\n", d->language);
2451 Debug("Greeter returned language (NULL)\n");
2454 if (strcmp(d->language, "default") == 0) {
2455 int len = strlen(defaultLanguage) + 1;
2456 d->language = (d->language == NULL ?
2457 malloc(len) : realloc (d->language, len));
2458 strcpy(d->language, defaultLanguage);
2462 case NOTIFY_BAD_SECLEVEL:
2465 case waitCompose (SIGTERM,0,0):
2466 Debug ("Greeter exited on SIGTERM\n");
2467 SessionExit(d, OPENFAILED_DISPLAY);
2470 Debug ("Greeter returned unknown status %d\n",
2472 SessionExit(d, REMANAGE_DISPLAY);
2475 signal(SIGHUP, SIG_DFL);
2478 AbortClient(greeterPid);
2479 SessionExit(d, UNMANAGE_DISPLAY);
2483 /*****************************************************************************
2489 This is the entry into greeter state processing. Allocate and initialize
2493 Display the login screen. Upon display, the login screen can be 'reset'. If
2494 reset is true, the username and password fields are cleared and the focus
2495 is set to the username field. If reset is false, the username and password
2496 field is untouched and the focus is set to the password field.
2498 LOGIN -> AUTHENTICATE:
2499 Authenticate the username entered on login screen.
2501 AUTHENTICATE -> TERMINATEGREET:
2502 User passed authentication so terminate the greeter.
2504 AUTHENTICATE -> EXPASSWORD:
2505 User passed authentication, but the their password has expired.
2506 Display old password message. This message allows the user to
2507 change their password by starting a getty and running passwd(1).
2509 AUTHENTICATE -> BAD_HOSTNAME:
2510 User passed authentication, but the their hostname is empty.
2511 Display a dialog that allows the user to run a getty to fix the
2512 problem, or start the desktop anyway.
2514 AUTHENTICATE -> ERRORMESSAGE:
2515 User failed authentication, so display error message.
2517 AUTHENTICATE -> LOGIN
2518 User failed authentication, but did not enter a password. Instead
2519 of displaying an error message, redisplay the login screen with
2520 the focus set to the password field. If the user authenticates again
2521 without the password field set, display an error. This allows a user
2522 to type the ubiquitous "username<ENTER>password<ENTER>" sequence.
2525 Free state structure and return false to stop state transitions.
2527 ERRORMESSAGE -> LOGIN
2528 Display error message base on return code from last authentication
2529 attempt. Redisplay login screen with reset set to true.
2531 (state) -> LANG -> (state)
2532 User has chosen a new language. Transition to LANG state to save off
2533 the new language, and transition back to original state.
2535 *****************************************************************************/
2537 #define SETMC(M, ID) M.id = MC_##ID; M.def = MC_DEF_##ID
2540 ManageGreeter( struct display *d, struct greet_info *greet,
2541 struct verify_info *verify, struct greet_state *state )
2548 if (state->waitForResponse)
2550 if (!AskGreeter(NULL, (char *)state->response, REQUEST_LIM_MAXLEN))
2553 * Dtgreet has terminated.
2555 state->id = GREET_STATE_EXIT;
2556 state->waitForResponse = FALSE;
2560 if (state->request->opcode != state->response->opcode)
2563 * An unrequested event arrived. See if it's one we
2566 switch(state->response->opcode)
2568 case REQUEST_OP_LANG:
2571 * User has changed language. Recursively handle this state
2572 * and return to current state.
2574 struct greet_state lang_state;
2576 lang_state = *state;
2577 lang_state.id = GREET_STATE_LANG;
2578 lang_state.waitForResponse = FALSE;
2579 ManageGreeter(d, greet, verify, &lang_state);
2580 Debug("Response opcode REQUEST_OP_LANG\n");
2585 case REQUEST_OP_CLEAR:
2588 * User has requested the screen be cleared.
2590 state->id = GREET_STATE_USERNAME;
2591 state->waitForResponse = TRUE;
2592 Debug("Response opcode REQUEST_OP_CLEAR\n");
2597 Debug("Response opcode UNEXPECTED RESPONSE!\n");
2607 * Got the response we were expecting.
2609 state->waitForResponse = FALSE;
2615 case GREET_STATE_ENTER:
2618 * Enter - initialize state
2620 Debug("GREET_STATE_ENTER\n");
2622 state->request = (RequestHeader *)malloc(REQUEST_LIM_MAXLEN);
2623 state->response= (ResponseHeader *)malloc(REQUEST_LIM_MAXLEN);
2624 state->authenticated = FALSE;
2627 state->id = GREET_STATE_USERNAME;
2631 case GREET_STATE_USERNAME:
2636 RequestChallenge *r;
2638 Debug("GREET_STATE_USERNAME\n");
2640 Authenticate(d, NULL, NULL, NULL);
2642 SETMC(msg, LOGIN_LABEL);
2644 r = (RequestChallenge *)state->request;
2645 r->hdr.opcode = REQUEST_OP_CHALLENGE;
2646 r->hdr.reserved = 0;
2649 r->hdr.length = sizeof(*r);
2651 r->offChallenge = sizeof(*r);
2652 strcpy(((char *)r) + r->offChallenge, msg.def);
2653 r->hdr.length += strlen(msg.def) + 1;
2657 r->offUserNameSeed = r->hdr.length;
2658 strcpy(((char *)r) + r->offUserNameSeed, greet->name);
2659 r->hdr.length += strlen(greet->name) + 1;
2660 Debug("Greet name: %s\n", greet->name);
2664 r->offUserNameSeed = 0;
2669 free(greet->name); greet->name = NULL;
2671 if (greet->password)
2673 free(greet->password); greet->password = NULL;
2676 TellGreeter((RequestHeader *)r);
2677 state->waitForResponse = TRUE;
2679 state->id = GREET_STATE_AUTHENTICATE;
2683 case GREET_STATE_CHALLENGE:
2688 RequestChallenge *r;
2690 Debug("GREET_STATE_CHALLENGE\n");
2692 if (greet->password)
2694 free(greet->password); greet->password = NULL;
2697 SETMC(msg, PASSWD_LABEL);
2699 r = (RequestChallenge *)state->request;
2700 r->hdr.opcode = REQUEST_OP_CHALLENGE;
2701 r->hdr.reserved = 0;
2704 r->offUserNameSeed = 0;
2705 r->offChallenge = sizeof(*r);
2706 strcpy(((char *)r) + r->offChallenge, msg.def);
2707 r->hdr.length = sizeof(*r) + strlen(msg.def) + 1;
2709 TellGreeter((RequestHeader *)r);
2710 state->waitForResponse = TRUE;
2712 state->id = GREET_STATE_AUTHENTICATE;
2716 case GREET_STATE_AUTHENTICATE:
2719 * Attempt to authenticate.
2721 ResponseChallenge *r;
2723 Debug("GREET_STATE_AUTHENTICATE\n");
2725 r = (ResponseChallenge *)state->response;
2727 if (greet->name == NULL)
2729 greet->name = strdup(((char *)r) + r->offResponse);
2730 if (strlen(greet->name) == 0)
2732 state->id = GREET_STATE_USERNAME;
2738 greet->password = strdup(((char *)r) + r->offResponse);
2748 * Attempt to authenticate user. 'username' should be a
2749 * non-empty string. 'password' may be an empty string.
2751 state->vf = Authenticate(d, greet->name, greet->password, &state->msg);
2753 if (state->vf == VF_OK ||
2754 state->vf == VF_PASSWD_AGED ||
2755 state->vf == VF_BAD_HOSTNAME)
2757 state->authenticated = TRUE;
2761 * General transitions.
2765 case VF_OK: state->id = GREET_STATE_TERMINATEGREET; break;
2766 case VF_PASSWD_AGED: state->id = GREET_STATE_EXPASSWORD; break;
2767 case VF_BAD_HOSTNAME: state->id = GREET_STATE_BAD_HOSTNAME; break;
2768 case VF_CHALLENGE: state->id = GREET_STATE_CHALLENGE; break;
2769 default: state->id = GREET_STATE_ERRORMESSAGE; break;
2774 case GREET_STATE_EXIT:
2777 * Free resources and leave.
2779 Debug("GREET_STATE_EXIT\n");
2786 if (!state->authenticated)
2790 free(greet->name); greet->name = NULL;
2792 if (greet->password)
2794 free(greet->password); greet->password = NULL;
2798 free(state->request);
2799 free(state->response);
2804 case GREET_STATE_ERRORMESSAGE:
2807 * Display error message.
2811 Debug("GREET_STATE_ERRORMESSAGE\n");
2813 r = (RequestMessage *)state->request;
2817 case VF_INVALID: SETMC(msg, LOGIN); break;
2818 case VF_HOME: SETMC(msg, HOME); break;
2819 case VF_MAX_USERS: SETMC(msg, MAX_USERS); break;
2820 case VF_BAD_UID: SETMC(msg, BAD_UID); break;
2821 case VF_BAD_GID: SETMC(msg, BAD_GID); break;
2822 case VF_BAD_AID: SETMC(msg, BAD_AID); break;
2823 case VF_BAD_AFLAG: SETMC(msg, BAD_AFLAG); break;
2824 case VF_NO_LOGIN: SETMC(msg, NO_LOGIN); break;
2826 case VF_BAD_SEN_LEVEL: SETMC(msg, BAD_SEN_LEVEL); break;
2828 case VF_MESSAGE: msg.id=0; msg.def=state->msg; break;
2829 default: msg.id=0; msg.def=""; break;
2832 r->hdr.opcode = REQUEST_OP_MESSAGE;
2833 r->hdr.reserved = 0;
2835 r->offMessage = sizeof(*r);
2836 strcpy(((char *)r) + r->offMessage, msg.def);
2837 r->hdr.length = sizeof(*r) + strlen(msg.def) + 1;
2839 TellGreeter((RequestHeader *)r);
2840 state->waitForResponse = TRUE;
2842 state->id = GREET_STATE_USERNAME;
2846 case GREET_STATE_LANG:
2849 * User selected new language.
2855 Debug("GREET_STATE_LANG\n");
2857 r = (ResponseLang *)state->response;
2858 lang = ((char *)r) + r->offLang;
2859 len = strlen(lang) + 1;
2861 d->language = (d->language == NULL ?
2862 malloc(len) : realloc(d->language, len));
2863 strcpy(d->language, lang);
2864 Debug("Language returned: %s\n", d->language);
2868 case GREET_STATE_TERMINATEGREET:
2871 * Terminate dtgreet.
2875 Debug("GREET_STATE_TERMINATEGREET\n");
2877 r = (RequestExit *)state->request;
2879 r->hdr.opcode = REQUEST_OP_EXIT;
2880 r->hdr.reserved = 0;
2881 r->hdr.length = sizeof(*r);
2883 TellGreeter((RequestHeader *)r);
2884 state->waitForResponse = TRUE;
2886 state->id = GREET_STATE_EXIT;
2890 case GREET_STATE_EXPASSWORD:
2893 * Display password expired message.
2895 RequestExpassword *r;
2897 Debug("GREET_STATE_EXPASSWORD\n");
2899 r = (RequestExpassword *)state->request;
2901 r->hdr.opcode = REQUEST_OP_EXPASSWORD;
2902 r->hdr.reserved = 0;
2903 r->hdr.length = sizeof(*r);
2905 TellGreeter((RequestHeader *)r);
2906 state->waitForResponse = TRUE;
2908 state->id = GREET_STATE_USERNAME;
2912 case GREET_STATE_BAD_HOSTNAME:
2915 * Display password expired message.
2919 Debug("GREET_STATE_BAD_HOSTNAME\n");
2921 r = (RequestHostname *)state->request;
2923 r->hdr.opcode = REQUEST_OP_HOSTNAME;
2924 r->hdr.reserved = 0;
2925 r->hdr.length = sizeof(*r);
2927 TellGreeter((RequestHeader *)r);
2928 state->waitForResponse = TRUE;
2930 state->id = GREET_STATE_USERNAME;
2935 case GREET_STATE_FORM:
2938 * Get arbitrary number of answers.
2941 Debug("GREET_STATE_FORM\n");
2943 AskGreeter(state->request, (char *)state->response, REQUEST_LIM_MAXLEN);
2945 state->waitForResponse = FALSE;
2946 state->id = GREET_STATE_USERNAME;
2958 RequestHeader *phdr)
2960 if(-1 == write(request[1], phdr, phdr->length)) {
2961 perror(strerror(errno));
2967 RequestHeader *preqhdr,
2973 ResponseHeader *phdr = (ResponseHeader *)buf;
2975 if (preqhdr) TellGreeter(preqhdr);
2977 phdr->opcode = REQUEST_OP_NONE;
2979 count = read(response[0], buf, sizeof(*phdr));
2981 if (count == sizeof(*phdr))
2984 * Calculate amount of data after header.
2986 remainder = phdr->length - sizeof(*phdr);
2990 * Read remainder of response.
2992 count += read(response[0], buf+sizeof(*phdr), remainder);
2997 if (debugLevel) PrintResponse(phdr, count);
3006 ResponseHeader *phdr,
3009 char *opstr = "UNKNOWN";
3013 Debug("opcode = (EOF)\n");
3017 switch(phdr->opcode)
3019 case REQUEST_OP_EXIT: opstr = "EXIT"; break;
3020 case REQUEST_OP_MESSAGE: opstr = "MESSAGE"; break;
3021 case REQUEST_OP_CHPASS: opstr = "CHPASS"; break;
3022 case REQUEST_OP_CHALLENGE: opstr = "CHALLENGE"; break;
3023 case REQUEST_OP_LANG: opstr = "LANG"; break;
3024 case REQUEST_OP_DEBUG: opstr = "DEBUG"; break;
3027 Debug("opcode = %d (%s)\n", phdr->opcode, opstr);
3028 Debug(" reserved = %d\n", phdr->reserved);
3029 Debug(" length = %d\n", phdr->length);
3031 switch(phdr->opcode)
3033 case REQUEST_OP_EXIT: break;
3034 case REQUEST_OP_LANG:
3035 Debug(" offLang=%d\n", ((ResponseLang *)phdr)->offLang);
3036 Debug(" lang='%s'\n",
3037 ((char *)phdr)+((ResponseLang *)phdr)->offLang);
3039 case REQUEST_OP_MESSAGE: break;
3040 case REQUEST_OP_CHPASS: break;
3041 case REQUEST_OP_CHALLENGE:
3042 Debug(" offResponse=%d\n", ((ResponseChallenge *)phdr)->offResponse);
3043 Debug(" response='%s'\n",
3044 ((char *)phdr)+((ResponseChallenge *)phdr)->offResponse);
3046 case REQUEST_OP_DEBUG:
3047 Debug(" offString=%d\n", ((ResponseDebug *)phdr)->offString);
3048 Debug(" string='%s'\n",
3049 ((char *)phdr)+((ResponseDebug *)phdr)->offString);
3057 /***************************************************************************
3061 * generate kerberos ticket file name. Name is returned in the static
3062 * global variable "krb_ticket_string".
3064 ***************************************************************************/
3067 SetTicketFileName(uid_t uid)
3076 * generate ticket file pathname (/tmp/tkt<uid>.<host>) ...
3079 if (env = (char *)getenv("KRBTKFILE")) {
3080 (void) strncpy(krb_ticket_string, env, sizeof(krb_ticket_string)-1);
3081 krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
3084 if (gethostname(lhost, sizeof(lhost)) != -1) {
3085 if (p = index(lhost, '.')) *p = '\0';
3086 (void)sprintf(krb_ticket_string, "%s%ld.%s", TKT_ROOT, (long)uid, lhost);
3088 /* 32 bits of signed integer will always fit in 11 characters
3089 (including the sign), so no need to worry about overflow */
3090 (void) sprintf(krb_ticket_string, "%s%ld", TKT_ROOT, (long)uid);
3095 #endif /* __KERBEROS */
3097 #if defined (_AIX) && !defined (_POWER)
3099 /***************************************************************************
3103 * If this is an authenticated process (LOGNAME set), set user's
3104 * process environment by calling setpenv().
3106 * If this is not an authenticated process, just call execve()
3108 ***************************************************************************/
3117 char *user = getEnv (envp, "LOGNAME");
3121 rc = execve(path, argv, envp);
3125 char *usrTag, *sysTag;
3128 * Save pointers to tags. The setpenv() function clears the pointers
3129 * to the tags in userEnviron as a side-effect.
3131 sysTag = envp[SYS_ENV_TAG];
3132 usrTag = envp[USR_ENV_TAG];
3135 * Set the users process environment. This call execs arvg so it
3136 * should not return. It it should return, restore the envp tags.
3138 rc = setpenv(user, PENV_INIT | PENV_ARGV, envp, argv);
3141 * Restore pointers to tags.
3143 envp[SYS_ENV_TAG] = sysTag;
3144 envp[USR_ENV_TAG] = usrTag;
3149 #endif /* _AIX && !_POWER */
3153 /* collect the SIA parameters from a window system. */
3155 static int SiaManageGreeter(
3158 unsigned char *title,
3164 RequestMessage greeter_message;
3165 char msg_buffer[256];
3166 } greeter_msg_and_buffer;
3167 RequestForm *request_form;
3175 if (rendition == SIAFORM && dt_in_sia_ses_authent
3176 && (num_prompts == 2))
3178 /* Normal login, Password case */
3179 Debug ("SIAFORM Normal login, Password case\n");
3180 while (siaGreeterInfo.state->id != GREET_STATE_TERMINATEGREET
3181 && siaGreeterInfo.state->id != GREET_STATE_EXIT
3182 && (siaGreeterInfo.status = ManageGreeter(
3183 siaGreeterInfo.d, siaGreeterInfo.greet,
3184 siaGreeterInfo.verify, siaGreeterInfo.state)))
3187 if (!siaGreeterInfo.status
3188 || siaGreeterInfo.state->id == GREET_STATE_EXIT)
3189 return(SIACOLABORT);
3191 strncpy((char *)prompt[0].result, siaGreeterInfo.greet->name,
3192 prompt[0].max_result_length);
3193 strncpy((char *)prompt[1].result,siaGreeterInfo.greet->password,
3194 prompt[1].max_result_length);
3201 ResponseForm *response_form;
3206 Debug("SIAMENUONE num_prompts = %d\n", num_prompts);
3209 Debug("SIAMENUANY num_prompts = %d\n", num_prompts);
3212 Debug("SIAONELINER num_prompts = %d\n", num_prompts);
3215 Debug("SIAFORM num_prompts = %d\n", num_prompts);
3219 /* need to display form */
3221 req_form_size = sizeof(RequestForm)
3222 + strlen((const char *)title) + 1;
3223 for (i=0; i<num_prompts; i++)
3224 req_form_size += strlen((const char *)prompt[i].prompt) + 1;
3225 request_form = (RequestForm *) alloca(req_form_size);
3227 siaGreeterInfo.state->id = GREET_STATE_FORM;
3228 siaGreeterInfo.state->request = (RequestHeader *)request_form;
3229 /* siaGreeterInfo.state->vf = VF_MESSAGE; */
3231 request_form->hdr.opcode = REQUEST_OP_FORM;
3232 request_form->hdr.reserved = 0;
3233 request_form->hdr.length = req_form_size;
3234 request_form->num_prompts = num_prompts;
3235 request_form->rendition = rendition;
3236 request_form->offTitle = sizeof(RequestForm);
3237 request_form->offPrompts = sizeof(RequestForm) +
3238 strlen((const char *)title) + 1;
3239 strcpy((char *)request_form + request_form->offTitle,
3240 (const char *)title);
3242 pmpt_ptr = (char *)request_form + request_form->offPrompts;
3243 for (i=0; i<num_prompts; i++)
3245 if (!prompt[i].prompt || prompt[i].prompt[0] == '\0')
3249 Debug(" prompt[%d]: %s\n", i, prompt[i].prompt);
3250 strcpy(pmpt_ptr, (const char *)prompt[i].prompt);
3251 pmpt_ptr += strlen((const char *)prompt[i].prompt);
3253 request_form->visible[i] =
3254 (prompt[i].control_flags & SIARESINVIS) ? False : True;
3257 siaGreeterInfo.status = ManageGreeter(siaGreeterInfo.d,
3258 siaGreeterInfo.greet,
3259 siaGreeterInfo.verify,
3260 siaGreeterInfo.state);
3262 response_form = (ResponseForm *)siaGreeterInfo.state->response;
3263 res_ptr = (char *)response_form + response_form->offAnswers;
3264 for (i = 0; i < response_form->num_answers; i++)
3266 if (rendition == SIAMENUONE || rendition == SIAMENUANY)
3269 prompt[i].result = (unsigned char *)1;
3271 prompt[i].result = NULL;
3275 strcpy((char *)prompt[0].result, res_ptr);
3277 res_ptr += strlen(res_ptr) + 1;
3279 if (!response_form->collect_status)
3280 siaGreeterInfo.status = FALSE;
3286 Debug("SIAINFO or SIAWARNING %s\n", prompt[0].prompt);
3288 siaGreeterInfo.state->id = GREET_STATE_ERRORMESSAGE;
3289 siaGreeterInfo.state->request = (RequestHeader *)
3290 &greeter_msg_and_buffer.greeter_message;
3291 siaGreeterInfo.state->vf = VF_MESSAGE;
3292 siaGreeterInfo.state->msg = (char *)prompt[0].prompt;
3294 siaGreeterInfo.status = ManageGreeter(siaGreeterInfo.d,
3295 siaGreeterInfo.greet,
3296 siaGreeterInfo.verify,
3297 siaGreeterInfo.state);
3300 return(SIACOLABORT);
3303 if (!siaGreeterInfo.status)
3304 return(SIACOLABORT);
3305 return(SIACOLSUCCESS);
3308 static CopySiaInfo(SIAENTITY *siaHandle, struct greet_info *greet)
3311 greet->name = malloc(strlen(siaHandle->name) + 1);
3312 strcpy (greet->name, siaHandle->name);
3314 greet->password = malloc(strlen(siaHandle->password) + 1);
3315 strcpy (greet->password, siaHandle->password);
3320 static void KillGreeter( void )
3322 if (sia_greeter_pid)
3323 AbortClient(sia_greeter_pid);
3324 sia_greeter_pid = 0;