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 )
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 = {};
1949 # define U_NAMELEN sizeof(rgy_$name_t)
1953 static char name_short[U_NAMELEN];
1959 char *argv[] = { "dtlogin", 0 };
1960 char *hostName = NULL;
1961 char *loginName = NULL;
1968 if (d->serverPid == -1)
1971 siaStatus = sia_ses_init(&siaHandle, argc, argv, hostName,
1972 loginName, d->name, 1, NULL);
1973 if (siaStatus != SIASUCCESS)
1975 Debug("sia_ses_init failure status %d\n", siaStatus);
1982 if (!setjmp (abortSession)) {
1983 signal(SIGTERM, catchTerm);
1986 * We've changed dtlogin to pass HUP's down to the children
1987 * so ignore any HUP's once the client has started.
1990 signal(SIGHUP, catchHUP);
1993 * set up communication pipes...
1996 if(-1 == pipe(response)) {
1997 perror(strerror(errno));
1999 if(-1 == pipe(request)) {
2000 perror(strerror(errno));
2005 switch (greeterPid = fork ()) {
2009 * pass some information in the environment...
2013 sprintf(msg,"%d", d->grabServer);
2014 env = setEnv(env, GRABSERVER, msg);
2016 sprintf(msg,"%d", d->grabTimeout);
2017 env = setEnv(env, GRABTIMEOUT, msg);
2020 if (timeZone && strlen(timeZone) > 0 )
2021 env = setEnv(env, "TZ", timeZone);
2023 if (errorLogFile && errorLogFile[0])
2024 env = setEnv(env, ERRORLOG, errorLogFile);
2027 env = setEnv(env, "XAUTHORITY", d->authFile);
2030 env = setEnv(env, DTLITE, "True");
2033 env = setEnv(env, SESSION, d->session);
2036 env = setEnv(env, SESSION_SET, "True");
2038 if (d->pmSearchPath)
2039 env = setEnv(env, "XMICONSEARCHPATH", d->pmSearchPath);
2041 if (d->bmSearchPath)
2042 env = setEnv(env, "XMICONBMSEARCHPATH", d->bmSearchPath);
2044 #if defined (__KERBEROS) || defined (__AFS)
2045 if (d->verifyName) {
2046 if ( (strcmp(d->verifyName, VN_AFS) == 0) ||
2047 (strcmp(d->verifyName, VN_KRB) == 0) ) {
2049 env = setEnv(env, VERIFYNAME, d->verifyName );
2052 LogError(ReadCatalog(
2053 MC_LOG_SET,MC_LOG_IMPROP_AUTH,MC_DEF_LOG_IMPROP_AUTH),
2055 d->verifyName = NULL;
2060 if((path = getenv("NLSPATH")) != NULL)
2061 env = setEnv(env, "NLSPATH", path);
2063 env = setEnv(env, "NLSPATH", "/usr/lib/nls/msg/%L/%N.cat");
2068 * ping remote displays...
2072 if (d->displayType.location == Local) {
2073 GettyRunning(d); /* refresh gettyState */
2074 if (d->gettyState != DM_GETTY_USER)
2075 env = setEnv(env, LOCATION, "local");
2078 sprintf(msg,"%d", d->pingInterval);
2079 env = setEnv(env, PINGINTERVAL, msg);
2081 sprintf(msg,"%d", d->pingTimeout);
2082 env = setEnv(env, PINGTIMEOUT, msg);
2086 if ( d->langList && strlen(d->langList) > 0 )
2087 env = setEnv(env, LANGLIST, d->langList);
2088 #if !defined (ENABLE_DYNAMIC_LANGLIST)
2089 else if (languageList && strlen(languageList) > 0 )
2090 env = setEnv(env, LANGLIST, languageList);
2091 #endif /* ENABLE_DYNAMIC_LANGLIST */
2094 char *language = NULL;
2096 #if defined (ENABLE_DYNAMIC_LANGLIST)
2097 language = d->language;
2098 #endif /* ENABLE_DYNAMIC_LANGLIST */
2100 if ( d->language && strlen(d->language) > 0 )
2101 env = setLang(d, env, language);
2104 if((path = getenv("XKEYSYMDB")) != NULL)
2105 env = setEnv(env, "XKEYSYMDB", path);
2108 if((path = getenv("OPENWINHOME")) != NULL)
2109 env = setEnv(env, "OPENWINHOME", path);
2114 * set environment for Domain machines...
2116 env = setEnv(env, "ENVIRONMENT", "bsd");
2117 env = setEnv(env, "SYSTYPE", "bsd4.3");
2121 Debug ("Greeter environment:\n");
2123 Debug ("End of Greeter environment:\n");
2126 * Writing to file descriptor 1 goes to response pipe instead.
2129 if(-1 == dup(response[1])) {
2130 perror(strerror(errno));
2136 * Reading from file descriptor 0 reads from request pipe instead.
2139 if(-1 == dup(request[0])) {
2140 perror(strerror(errno));
2148 * figure out path to dtgreet...
2151 strcpy(msg, progName);
2153 if ((p = (char *) strrchr(msg, '/')) == NULL)
2158 strcat(msg,"dtgreet");
2160 execle(msg, "dtgreet", "-display", d->name, (char *)0, env);
2161 LogError(ReadCatalog(
2162 MC_LOG_SET,MC_LOG_NO_DTGREET,MC_DEF_LOG_NO_DTGREET),
2164 exit (NOTIFY_ABORT_DISPLAY);
2167 Debug ("Fork of Greeter failed.\n");
2168 LogError(ReadCatalog(
2169 MC_LOG_SET,MC_LOG_NO_FORKCG,MC_DEF_LOG_NO_FORKCG),d->name);
2174 exit (UNMANAGE_DISPLAY);
2177 Debug ("Greeter started\n");
2179 close(response[1]); /* Close write end of response pipe */
2180 close(request[0]); /* Close read end of request pipe */
2184 * Retrieve information from greeter and authenticate.
2186 globalDisplayName = d->name;
2187 state.id = GREET_STATE_ENTER;
2188 state.waitForResponse = FALSE;
2192 * atexit() registers this function to be called if exit() is
2193 * called. This is needed because in enhanced security mode, SIA
2194 * may call exit() whn the user fails to enter or change a
2197 sia_greeter_pid = greeterPid;
2198 if (!sia_exit_proc_reg)
2200 atexit(KillGreeter);
2201 sia_exit_proc_reg = TRUE;
2204 siaGreeterInfo.d = d;
2205 siaGreeterInfo.greet = greet;
2206 siaGreeterInfo.verify = verify;
2207 siaGreeterInfo.state = &state;
2208 siaGreeterInfo.status = TRUE;
2211 while(siaStatus != SIASUCCESS)
2213 while(siaStatus != SIASUCCESS && siaGreeterInfo.status)
2215 Debug ("RunGreeter: before sia_ses_authent\n");
2216 dt_in_sia_ses_authent = True;
2217 siaStatus = sia_ses_authent(SiaManageGreeter, NULL,
2219 dt_in_sia_ses_authent = False;
2220 Debug ("RunGreeter: after sia_ses_authent status = %d\n",
2222 if (siaStatus == SIAFAIL && siaGreeterInfo.status)
2224 state.id = GREET_STATE_ERRORMESSAGE;
2225 state.vf = VF_INVALID;
2226 ManageGreeter(d, greet, verify, &state);
2228 if (!siaGreeterInfo.status || siaStatus == SIASTOP)
2231 if (!siaGreeterInfo.status || siaStatus == SIASTOP)
2233 sia_ses_release(&siaHandle);
2237 Debug("RunGreeter: before sia_ses_estab\n");
2238 siaStatus = sia_ses_estab(SiaManageGreeter, siaHandle);
2239 Debug ("RunGreeter: after sia_ses_estab status = %d\n",
2242 if (!siaGreeterInfo.status)
2245 if (siaStatus == SIASUCCESS)
2247 Debug("RunGreeter: before sia_ses_launch\n");
2248 siaStatus = sia_ses_launch(SiaManageGreeter, siaHandle);
2249 Debug("RunGreeter: after sia_ses_launch status = %d\n",
2252 if (!siaGreeterInfo.status)
2255 if (siaStatus != SIASUCCESS)
2257 Debug("RunGreeter: sia_ses_launch failure\n");
2258 /* establish & launch failures do a release */
2260 siaStatus = sia_ses_init(&siaHandle, argc, argv, hostName,
2261 loginName, d->name, 1, NULL);
2262 if (siaStatus != SIASUCCESS)
2264 Debug("sia_ses_init failure status %d\n", siaStatus);
2265 exit(RESERVER_DISPLAY);
2270 * sia_ses_launch() wil probably seteuid to that of the
2271 * user, but we don't want that now.
2275 * extract necessary info from SIA context struct
2279 if (siaStatus == SIASUCCESS)
2280 CopySiaInfo(siaHandle, greet);
2281 sia_ses_release(&siaHandle);
2283 state.id = GREET_STATE_TERMINATEGREET;
2284 if (siaGreeterInfo.status)
2286 while (ManageGreeter(d, greet, verify, &state))
2289 sia_greeter_pid = 0;
2291 while (ManageGreeter(d, greet, verify, &state))
2296 * Wait for Greeter to end...
2299 pid = wait (&status);
2300 if (pid == greeterPid)
2306 * Greeter exited. Check return code...
2309 Debug("Greeter return status; exit = %d, signal = %d\n",
2310 waitCode(status), waitSig(status));
2314 * remove authorization file if used...
2317 if (d->authorizations && d->authFile &&
2318 waitVal(status) != NOTIFY_LANG_CHANGE
2320 && waitVal(status) != NOTIFY_BAD_SECLEVEL
2325 Debug ("Done with authorization file %s, removing\n",
2327 (void) unlink (d->authFile);
2332 if(waitVal(status) > NOTIFY_ALT_DTS)
2333 d->sessionType = waitVal(status);
2336 switch (waitVal(status)) {
2337 case NOTIFY_FAILSAFE:
2338 greet->string = "failsafe";
2340 case NOTIFY_PASSWD_EXPIRED:
2341 greet->string = "password";
2346 case NOTIFY_LAST_DT:
2347 d->sessionType = waitVal(status);
2353 Debug("waitVal - status is %d\n", waitVal(status));
2354 if(waitVal(status) > NOTIFY_ALT_DTS)
2355 notify_dt = NOTIFY_ALT_DTS; /* It is alt desktops */
2357 notify_dt = waitVal(status);
2359 switch (notify_dt) {
2360 case NOTIFY_FAILSAFE:
2361 case NOTIFY_PASSWD_EXPIRED:
2365 case NOTIFY_LAST_DT:
2366 case NOTIFY_ALT_DTS:
2368 if (NULL == greet->name) return;
2371 * greet->name, greet->password set in ManageGreeter().
2373 Debug("Greeter returned name '%s'\n", greet->name);
2376 greet->name_full = greet->name;
2377 /* get just person name out of full SID */
2379 while (i < sizeof(rgy_$name_t)
2380 && greet->name_full[i] != '.'
2381 && greet->name_full[i] != '\0') {
2382 name_short[i] = greet->name_full[i];
2385 name_short[i] = '\0';
2386 greet->name = name_short;
2391 * groups[] set in Authenticate().
2393 if ( IsVerifyName(VN_AFS) ) {
2394 verify->groups[0] = groups[0];
2395 verify->groups[1] = groups[1];
2396 Debug("Greeter returned groups[0] '%d'\n", verify->groups[0]);
2397 Debug("Greeter returned groups[1] '%d'\n", verify->groups[1]);
2403 * sensitivityLevel set in BLS_Verify()
2405 greet->b1security = sensitivityLevel;
2408 Verify(d, greet, verify);
2412 Debug ("Greeter Xlib error or SIGTERM\n");
2413 SessionExit(d, OPENFAILED_DISPLAY);
2415 case NOTIFY_RESTART:
2416 Debug ("Greeter requested RESTART_DISPLAY\n");
2417 SessionExit(d, RESERVER_DISPLAY);
2419 case NOTIFY_ABORT_DISPLAY:
2420 Debug ("Greeter requested UNMANAGE_DISPLAY\n");
2421 SessionExit(d, UNMANAGE_DISPLAY);
2423 case NOTIFY_NO_WINDOWS:
2424 Debug ("Greeter requested NO_WINDOWS mode\n");
2425 if (d->serverPid >= 2)
2427 * Don't do a SessionExit() here since that causes
2428 * the X-server to be reset. We know we are going to
2429 * terminate it anyway, so just go do that...
2431 exit(SUSPEND_DISPLAY);
2435 case NOTIFY_LANG_CHANGE:
2436 Debug ("Greeter requested LANG_CHANGE\n");
2439 * copy requested language into display struct "d". Note,
2440 * this only happens in this child's copy of "d", not in
2441 * the master struct. When the user logs out, the
2442 * resource-specified language (if any) will reactivate.
2445 Debug("Greeter returned language '%s'\n", d->language);
2447 Debug("Greeter returned language (NULL)\n");
2450 if (strcmp(d->language, "default") == 0) {
2451 int len = strlen(defaultLanguage) + 1;
2452 d->language = (d->language == NULL ?
2453 malloc(len) : realloc (d->language, len));
2454 strcpy(d->language, defaultLanguage);
2458 case NOTIFY_BAD_SECLEVEL:
2461 case waitCompose (SIGTERM,0,0):
2462 Debug ("Greeter exited on SIGTERM\n");
2463 SessionExit(d, OPENFAILED_DISPLAY);
2466 Debug ("Greeter returned unknown status %d\n",
2468 SessionExit(d, REMANAGE_DISPLAY);
2471 signal(SIGHUP, SIG_DFL);
2474 AbortClient(greeterPid);
2475 SessionExit(d, UNMANAGE_DISPLAY);
2479 /*****************************************************************************
2485 This is the entry into greeter state processing. Allocate and initialize
2489 Display the login screen. Upon display, the login screen can be 'reset'. If
2490 reset is true, the username and password fields are cleared and the focus
2491 is set to the username field. If reset is false, the username and password
2492 field is untouched and the focus is set to the password field.
2494 LOGIN -> AUTHENTICATE:
2495 Authenticate the username entered on login screen.
2497 AUTHENTICATE -> TERMINATEGREET:
2498 User passed authentication so terminate the greeter.
2500 AUTHENTICATE -> EXPASSWORD:
2501 User passed authentication, but the their password has expired.
2502 Display old password message. This message allows the user to
2503 change their password by starting a getty and running passwd(1).
2505 AUTHENTICATE -> BAD_HOSTNAME:
2506 User passed authentication, but the their hostname is empty.
2507 Display a dialog that allows the user to run a getty to fix the
2508 problem, or start the desktop anyway.
2510 AUTHENTICATE -> ERRORMESSAGE:
2511 User failed authentication, so display error message.
2513 AUTHENTICATE -> LOGIN
2514 User failed authentication, but did not enter a password. Instead
2515 of displaying an error message, redisplay the login screen with
2516 the focus set to the password field. If the user authenticates again
2517 without the password field set, display an error. This allows a user
2518 to type the ubiquitous "username<ENTER>password<ENTER>" sequence.
2521 Free state structure and return false to stop state transitions.
2523 ERRORMESSAGE -> LOGIN
2524 Display error message base on return code from last authentication
2525 attempt. Redisplay login screen with reset set to true.
2527 (state) -> LANG -> (state)
2528 User has chosen a new language. Transition to LANG state to save off
2529 the new language, and transition back to original state.
2531 *****************************************************************************/
2533 #define SETMC(M, ID) M.id = MC_##ID; M.def = MC_DEF_##ID
2536 ManageGreeter( struct display *d, struct greet_info *greet,
2537 struct verify_info *verify, struct greet_state *state )
2544 if (state->waitForResponse)
2546 if (!AskGreeter(NULL, (char *)state->response, REQUEST_LIM_MAXLEN))
2549 * Dtgreet has terminated.
2551 state->id = GREET_STATE_EXIT;
2552 state->waitForResponse = FALSE;
2556 if (state->request->opcode != state->response->opcode)
2559 * An unrequested event arrived. See if it's one we
2562 switch(state->response->opcode)
2564 case REQUEST_OP_LANG:
2567 * User has changed language. Recursively handle this state
2568 * and return to current state.
2570 struct greet_state lang_state;
2572 lang_state = *state;
2573 lang_state.id = GREET_STATE_LANG;
2574 lang_state.waitForResponse = FALSE;
2575 ManageGreeter(d, greet, verify, &lang_state);
2576 Debug("Response opcode REQUEST_OP_LANG\n");
2581 case REQUEST_OP_CLEAR:
2584 * User has requested the screen be cleared.
2586 state->id = GREET_STATE_USERNAME;
2587 state->waitForResponse = TRUE;
2588 Debug("Response opcode REQUEST_OP_CLEAR\n");
2593 Debug("Response opcode UNEXPECTED RESPONSE!\n");
2603 * Got the response we were expecting.
2605 state->waitForResponse = FALSE;
2611 case GREET_STATE_ENTER:
2614 * Enter - initialize state
2616 Debug("GREET_STATE_ENTER\n");
2618 state->request = (RequestHeader *)malloc(REQUEST_LIM_MAXLEN);
2619 state->response= (ResponseHeader *)malloc(REQUEST_LIM_MAXLEN);
2620 state->authenticated = FALSE;
2623 state->id = GREET_STATE_USERNAME;
2627 case GREET_STATE_USERNAME:
2632 RequestChallenge *r;
2634 Debug("GREET_STATE_USERNAME\n");
2636 Authenticate(d, NULL, NULL, NULL);
2638 SETMC(msg, LOGIN_LABEL);
2640 r = (RequestChallenge *)state->request;
2641 r->hdr.opcode = REQUEST_OP_CHALLENGE;
2642 r->hdr.reserved = 0;
2645 r->hdr.length = sizeof(*r);
2647 r->offChallenge = sizeof(*r);
2648 strcpy(((char *)r) + r->offChallenge, msg.def);
2649 r->hdr.length += strlen(msg.def) + 1;
2653 r->offUserNameSeed = r->hdr.length;
2654 strcpy(((char *)r) + r->offUserNameSeed, greet->name);
2655 r->hdr.length += strlen(greet->name) + 1;
2656 Debug("Greet name: %s\n", greet->name);
2660 r->offUserNameSeed = 0;
2665 free(greet->name); greet->name = NULL;
2667 if (greet->password)
2669 free(greet->password); greet->password = NULL;
2672 TellGreeter((RequestHeader *)r);
2673 state->waitForResponse = TRUE;
2675 state->id = GREET_STATE_AUTHENTICATE;
2679 case GREET_STATE_CHALLENGE:
2684 RequestChallenge *r;
2686 Debug("GREET_STATE_CHALLENGE\n");
2688 if (greet->password)
2690 free(greet->password); greet->password = NULL;
2693 SETMC(msg, PASSWD_LABEL);
2695 r = (RequestChallenge *)state->request;
2696 r->hdr.opcode = REQUEST_OP_CHALLENGE;
2697 r->hdr.reserved = 0;
2700 r->offUserNameSeed = 0;
2701 r->offChallenge = sizeof(*r);
2702 strcpy(((char *)r) + r->offChallenge, msg.def);
2703 r->hdr.length = sizeof(*r) + strlen(msg.def) + 1;
2705 TellGreeter((RequestHeader *)r);
2706 state->waitForResponse = TRUE;
2708 state->id = GREET_STATE_AUTHENTICATE;
2712 case GREET_STATE_AUTHENTICATE:
2715 * Attempt to authenticate.
2717 ResponseChallenge *r;
2719 Debug("GREET_STATE_AUTHENTICATE\n");
2721 r = (ResponseChallenge *)state->response;
2723 if (greet->name == NULL)
2725 greet->name = strdup(((char *)r) + r->offResponse);
2726 if (strlen(greet->name) == 0)
2728 state->id = GREET_STATE_USERNAME;
2734 greet->password = strdup(((char *)r) + r->offResponse);
2744 * Attempt to authenticate user. 'username' should be a
2745 * non-empty string. 'password' may be an empty string.
2747 state->vf = Authenticate(d, greet->name, greet->password, &state->msg);
2749 if (state->vf == VF_OK ||
2750 state->vf == VF_PASSWD_AGED ||
2751 state->vf == VF_BAD_HOSTNAME)
2753 state->authenticated = TRUE;
2757 * General transitions.
2761 case VF_OK: state->id = GREET_STATE_TERMINATEGREET; break;
2762 case VF_PASSWD_AGED: state->id = GREET_STATE_EXPASSWORD; break;
2763 case VF_BAD_HOSTNAME: state->id = GREET_STATE_BAD_HOSTNAME; break;
2764 case VF_CHALLENGE: state->id = GREET_STATE_CHALLENGE; break;
2765 default: state->id = GREET_STATE_ERRORMESSAGE; break;
2770 case GREET_STATE_EXIT:
2773 * Free resources and leave.
2775 Debug("GREET_STATE_EXIT\n");
2782 if (!state->authenticated)
2786 free(greet->name); greet->name = NULL;
2788 if (greet->password)
2790 free(greet->password); greet->password = NULL;
2794 free(state->request);
2795 free(state->response);
2800 case GREET_STATE_ERRORMESSAGE:
2803 * Display error message.
2807 Debug("GREET_STATE_ERRORMESSAGE\n");
2809 r = (RequestMessage *)state->request;
2813 case VF_INVALID: SETMC(msg, LOGIN); break;
2814 case VF_HOME: SETMC(msg, HOME); break;
2815 case VF_MAX_USERS: SETMC(msg, MAX_USERS); break;
2816 case VF_BAD_UID: SETMC(msg, BAD_UID); break;
2817 case VF_BAD_GID: SETMC(msg, BAD_GID); break;
2818 case VF_BAD_AID: SETMC(msg, BAD_AID); break;
2819 case VF_BAD_AFLAG: SETMC(msg, BAD_AFLAG); break;
2820 case VF_NO_LOGIN: SETMC(msg, NO_LOGIN); break;
2822 case VF_BAD_SEN_LEVEL: SETMC(msg, BAD_SEN_LEVEL); break;
2824 case VF_MESSAGE: msg.id=0; msg.def=state->msg; break;
2825 default: msg.id=0; msg.def=""; break;
2828 r->hdr.opcode = REQUEST_OP_MESSAGE;
2829 r->hdr.reserved = 0;
2831 r->offMessage = sizeof(*r);
2832 strcpy(((char *)r) + r->offMessage, msg.def);
2833 r->hdr.length = sizeof(*r) + strlen(msg.def) + 1;
2835 TellGreeter((RequestHeader *)r);
2836 state->waitForResponse = TRUE;
2838 state->id = GREET_STATE_USERNAME;
2842 case GREET_STATE_LANG:
2845 * User selected new language.
2851 Debug("GREET_STATE_LANG\n");
2853 r = (ResponseLang *)state->response;
2854 lang = ((char *)r) + r->offLang;
2855 len = strlen(lang) + 1;
2857 d->language = (d->language == NULL ?
2858 malloc(len) : realloc(d->language, len));
2859 strcpy(d->language, lang);
2860 Debug("Language returned: %s\n", d->language);
2864 case GREET_STATE_TERMINATEGREET:
2867 * Terminate dtgreet.
2871 Debug("GREET_STATE_TERMINATEGREET\n");
2873 r = (RequestExit *)state->request;
2875 r->hdr.opcode = REQUEST_OP_EXIT;
2876 r->hdr.reserved = 0;
2877 r->hdr.length = sizeof(*r);
2879 TellGreeter((RequestHeader *)r);
2880 state->waitForResponse = TRUE;
2882 state->id = GREET_STATE_EXIT;
2886 case GREET_STATE_EXPASSWORD:
2889 * Display password expired message.
2891 RequestExpassword *r;
2893 Debug("GREET_STATE_EXPASSWORD\n");
2895 r = (RequestExpassword *)state->request;
2897 r->hdr.opcode = REQUEST_OP_EXPASSWORD;
2898 r->hdr.reserved = 0;
2899 r->hdr.length = sizeof(*r);
2901 TellGreeter((RequestHeader *)r);
2902 state->waitForResponse = TRUE;
2904 state->id = GREET_STATE_USERNAME;
2908 case GREET_STATE_BAD_HOSTNAME:
2911 * Display password expired message.
2915 Debug("GREET_STATE_BAD_HOSTNAME\n");
2917 r = (RequestHostname *)state->request;
2919 r->hdr.opcode = REQUEST_OP_HOSTNAME;
2920 r->hdr.reserved = 0;
2921 r->hdr.length = sizeof(*r);
2923 TellGreeter((RequestHeader *)r);
2924 state->waitForResponse = TRUE;
2926 state->id = GREET_STATE_USERNAME;
2931 case GREET_STATE_FORM:
2934 * Get arbitrary number of answers.
2937 Debug("GREET_STATE_FORM\n");
2939 AskGreeter(state->request, (char *)state->response, REQUEST_LIM_MAXLEN);
2941 state->waitForResponse = FALSE;
2942 state->id = GREET_STATE_USERNAME;
2954 RequestHeader *phdr)
2956 if(-1 == write(request[1], phdr, phdr->length)) {
2957 perror(strerror(errno));
2963 RequestHeader *preqhdr,
2969 ResponseHeader *phdr = (ResponseHeader *)buf;
2971 if (preqhdr) TellGreeter(preqhdr);
2973 phdr->opcode = REQUEST_OP_NONE;
2975 count = read(response[0], buf, sizeof(*phdr));
2977 if (count == sizeof(*phdr))
2980 * Calculate amount of data after header.
2982 remainder = phdr->length - sizeof(*phdr);
2986 * Read remainder of response.
2988 count += read(response[0], buf+sizeof(*phdr), remainder);
2993 if (debugLevel) PrintResponse(phdr, count);
3002 ResponseHeader *phdr,
3005 char *opstr = "UNKNOWN";
3009 Debug("opcode = (EOF)\n");
3013 switch(phdr->opcode)
3015 case REQUEST_OP_EXIT: opstr = "EXIT"; break;
3016 case REQUEST_OP_MESSAGE: opstr = "MESSAGE"; break;
3017 case REQUEST_OP_CHPASS: opstr = "CHPASS"; break;
3018 case REQUEST_OP_CHALLENGE: opstr = "CHALLENGE"; break;
3019 case REQUEST_OP_LANG: opstr = "LANG"; break;
3020 case REQUEST_OP_DEBUG: opstr = "DEBUG"; break;
3023 Debug("opcode = %d (%s)\n", phdr->opcode, opstr);
3024 Debug(" reserved = %d\n", phdr->reserved);
3025 Debug(" length = %d\n", phdr->length);
3027 switch(phdr->opcode)
3029 case REQUEST_OP_EXIT: break;
3030 case REQUEST_OP_LANG:
3031 Debug(" offLang=%d\n", ((ResponseLang *)phdr)->offLang);
3032 Debug(" lang='%s'\n",
3033 ((char *)phdr)+((ResponseLang *)phdr)->offLang);
3035 case REQUEST_OP_MESSAGE: break;
3036 case REQUEST_OP_CHPASS: break;
3037 case REQUEST_OP_CHALLENGE:
3038 Debug(" offResponse=%d\n", ((ResponseChallenge *)phdr)->offResponse);
3039 Debug(" response='%s'\n",
3040 ((char *)phdr)+((ResponseChallenge *)phdr)->offResponse);
3042 case REQUEST_OP_DEBUG:
3043 Debug(" offString=%d\n", ((ResponseDebug *)phdr)->offString);
3044 Debug(" string='%s'\n",
3045 ((char *)phdr)+((ResponseDebug *)phdr)->offString);
3053 /***************************************************************************
3057 * generate kerberos ticket file name. Name is returned in the static
3058 * global variable "krb_ticket_string".
3060 ***************************************************************************/
3063 SetTicketFileName(uid_t uid)
3072 * generate ticket file pathname (/tmp/tkt<uid>.<host>) ...
3075 if (env = (char *)getenv("KRBTKFILE")) {
3076 (void) strncpy(krb_ticket_string, env, sizeof(krb_ticket_string)-1);
3077 krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
3080 if (gethostname(lhost, sizeof(lhost)) != -1) {
3081 if (p = index(lhost, '.')) *p = '\0';
3082 (void)sprintf(krb_ticket_string, "%s%ld.%s", TKT_ROOT, (long)uid, lhost);
3084 /* 32 bits of signed integer will always fit in 11 characters
3085 (including the sign), so no need to worry about overflow */
3086 (void) sprintf(krb_ticket_string, "%s%ld", TKT_ROOT, (long)uid);
3091 #endif /* __KERBEROS */
3093 #if defined (_AIX) && !defined (_POWER)
3095 /***************************************************************************
3099 * If this is an authenticated process (LOGNAME set), set user's
3100 * process environment by calling setpenv().
3102 * If this is not an authenticated process, just call execve()
3104 ***************************************************************************/
3113 char *user = getEnv (envp, "LOGNAME");
3117 rc = execve(path, argv, envp);
3121 char *usrTag, *sysTag;
3124 * Save pointers to tags. The setpenv() function clears the pointers
3125 * to the tags in userEnviron as a side-effect.
3127 sysTag = envp[SYS_ENV_TAG];
3128 usrTag = envp[USR_ENV_TAG];
3131 * Set the users process environment. This call execs arvg so it
3132 * should not return. It it should return, restore the envp tags.
3134 rc = setpenv(user, PENV_INIT | PENV_ARGV, envp, argv);
3137 * Restore pointers to tags.
3139 envp[SYS_ENV_TAG] = sysTag;
3140 envp[USR_ENV_TAG] = usrTag;
3145 #endif /* _AIX && !_POWER */
3149 /* collect the SIA parameters from a window system. */
3151 static int SiaManageGreeter(
3154 unsigned char *title,
3160 RequestMessage greeter_message;
3161 char msg_buffer[256];
3162 } greeter_msg_and_buffer;
3163 RequestForm *request_form;
3171 if (rendition == SIAFORM && dt_in_sia_ses_authent
3172 && (num_prompts == 2))
3174 /* Normal login, Password case */
3175 Debug ("SIAFORM Normal login, Password case\n");
3176 while (siaGreeterInfo.state->id != GREET_STATE_TERMINATEGREET
3177 && siaGreeterInfo.state->id != GREET_STATE_EXIT
3178 && (siaGreeterInfo.status = ManageGreeter(
3179 siaGreeterInfo.d, siaGreeterInfo.greet,
3180 siaGreeterInfo.verify, siaGreeterInfo.state)))
3183 if (!siaGreeterInfo.status
3184 || siaGreeterInfo.state->id == GREET_STATE_EXIT)
3185 return(SIACOLABORT);
3187 strncpy((char *)prompt[0].result, siaGreeterInfo.greet->name,
3188 prompt[0].max_result_length);
3189 strncpy((char *)prompt[1].result,siaGreeterInfo.greet->password,
3190 prompt[1].max_result_length);
3197 ResponseForm *response_form;
3202 Debug("SIAMENUONE num_prompts = %d\n", num_prompts);
3205 Debug("SIAMENUANY num_prompts = %d\n", num_prompts);
3208 Debug("SIAONELINER num_prompts = %d\n", num_prompts);
3211 Debug("SIAFORM num_prompts = %d\n", num_prompts);
3215 /* need to display form */
3217 req_form_size = sizeof(RequestForm)
3218 + strlen((const char *)title) + 1;
3219 for (i=0; i<num_prompts; i++)
3220 req_form_size += strlen((const char *)prompt[i].prompt) + 1;
3221 request_form = (RequestForm *) alloca(req_form_size);
3223 siaGreeterInfo.state->id = GREET_STATE_FORM;
3224 siaGreeterInfo.state->request = (RequestHeader *)request_form;
3225 /* siaGreeterInfo.state->vf = VF_MESSAGE; */
3227 request_form->hdr.opcode = REQUEST_OP_FORM;
3228 request_form->hdr.reserved = 0;
3229 request_form->hdr.length = req_form_size;
3230 request_form->num_prompts = num_prompts;
3231 request_form->rendition = rendition;
3232 request_form->offTitle = sizeof(RequestForm);
3233 request_form->offPrompts = sizeof(RequestForm) +
3234 strlen((const char *)title) + 1;
3235 strcpy((char *)request_form + request_form->offTitle,
3236 (const char *)title);
3238 pmpt_ptr = (char *)request_form + request_form->offPrompts;
3239 for (i=0; i<num_prompts; i++)
3241 if (!prompt[i].prompt || prompt[i].prompt[0] == '\0')
3245 Debug(" prompt[%d]: %s\n", i, prompt[i].prompt);
3246 strcpy(pmpt_ptr, (const char *)prompt[i].prompt);
3247 pmpt_ptr += strlen((const char *)prompt[i].prompt);
3249 request_form->visible[i] =
3250 (prompt[i].control_flags & SIARESINVIS) ? False : True;
3253 siaGreeterInfo.status = ManageGreeter(siaGreeterInfo.d,
3254 siaGreeterInfo.greet,
3255 siaGreeterInfo.verify,
3256 siaGreeterInfo.state);
3258 response_form = (ResponseForm *)siaGreeterInfo.state->response;
3259 res_ptr = (char *)response_form + response_form->offAnswers;
3260 for (i = 0; i < response_form->num_answers; i++)
3262 if (rendition == SIAMENUONE || rendition == SIAMENUANY)
3265 prompt[i].result = (unsigned char *)1;
3267 prompt[i].result = NULL;
3271 strcpy((char *)prompt[0].result, res_ptr);
3273 res_ptr += strlen(res_ptr) + 1;
3275 if (!response_form->collect_status)
3276 siaGreeterInfo.status = FALSE;
3282 Debug("SIAINFO or SIAWARNING %s\n", prompt[0].prompt);
3284 siaGreeterInfo.state->id = GREET_STATE_ERRORMESSAGE;
3285 siaGreeterInfo.state->request = (RequestHeader *)
3286 &greeter_msg_and_buffer.greeter_message;
3287 siaGreeterInfo.state->vf = VF_MESSAGE;
3288 siaGreeterInfo.state->msg = (char *)prompt[0].prompt;
3290 siaGreeterInfo.status = ManageGreeter(siaGreeterInfo.d,
3291 siaGreeterInfo.greet,
3292 siaGreeterInfo.verify,
3293 siaGreeterInfo.state);
3296 return(SIACOLABORT);
3299 if (!siaGreeterInfo.status)
3300 return(SIACOLABORT);
3301 return(SIACOLSUCCESS);
3304 static CopySiaInfo(SIAENTITY *siaHandle, struct greet_info *greet)
3307 greet->name = malloc(strlen(siaHandle->name) + 1);
3308 strcpy (greet->name, siaHandle->name);
3310 greet->password = malloc(strlen(siaHandle->password) + 1);
3311 strcpy (greet->password, siaHandle->password);
3316 static void KillGreeter( void )
3318 if (sia_greeter_pid)
3319 AbortClient(sia_greeter_pid);
3320 sia_greeter_pid = 0;