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
66 # include <X11/Xatom.h>
68 #if defined(__FreeBSD__) && OSMAJORVERSION > 8
81 #include <X11/Intrinsic.h>
84 # include <X11/Xresource.h>
95 # include <sys/security.h>
101 #endif /* __KERBEROS */
104 #include "rgy_base.h"
109 static SIAENTITY *siaHandle = NULL;
110 static Boolean dt_in_sia_ses_authent = False;
112 static struct sia_greeter_info {
114 struct greet_info *greet;
115 struct verify_info *verify;
116 struct greet_state *state;
120 static int SiaManageGreeter(
123 unsigned char *title,
127 static CopySiaInfo(SIAENTITY *siaHandle, struct greet_info *greet);
129 static void KillGreeter( void );
131 static int sia_greeter_pid;
132 static int sia_exit_proc_reg = FALSE;
138 extern char *getenv();
141 #define GREET_STATE_LOGIN 0
142 #define GREET_STATE_AUTHENTICATE 1
143 #define GREET_STATE_EXIT 2
144 #define GREET_STATE_EXPASSWORD 3
145 #define GREET_STATE_ERRORMESSAGE 4
146 #define GREET_STATE_LANG 5
147 #define GREET_STATE_BAD_HOSTNAME 6
148 #define GREET_STATE_ENTER 7
149 #define GREET_STATE_TERMINATEGREET 8
150 #define GREET_STATE_USERNAME 9
151 #define GREET_STATE_CHALLENGE 10
152 #define GREET_STATE_FORM 11
155 #define DEF_SESSION CDE_INSTALLATION_TOP "/bin/Xsession"
163 int waitForResponse; /* TRUE=wait for response from dtgreet */
164 RequestHeader *request; /* request buffer */
165 ResponseHeader *response; /* response buffer */
166 int authenticated; /* TRUE=user is authenticated */
167 int vf; /* last return code from Authenticate() */
168 int loginReset; /* reset flag for LOGIN state */
169 char *msg; /* message for VF_MESSAGE */
172 char *globalDisplayName;
174 /***************************************************************************
176 * Local procedure declarations
178 ***************************************************************************/
180 static int AbortClient( int pid) ;
181 static void DeleteXloginResources( struct display *d, Display *dpy) ;
182 int LoadXloginResources( struct display *d) ;
183 static int ErrorHandler( Display *dpy, XErrorEvent *event) ;
184 static int IOErrorHandler( Display *dpy) ;
185 static int ManageGreeter( struct display *d, struct greet_info *greet,
186 struct verify_info *verify, struct greet_state *state) ;
187 static void RunGreeter( struct display *d, struct greet_info *greet,
188 struct verify_info *verify) ;
189 static void SessionExit( struct display *d, int status) ;
190 static void SessionPingFailed( struct display *d) ;
191 static int StartClient(struct verify_info *verify, struct display *d,
193 static SIGVAL catchAlrm( int arg ) ;
194 static SIGVAL catchHUP( int arg ) ;
195 static SIGVAL catchTerm( int arg ) ;
196 static SIGVAL waitAbort( int arg ) ;
197 static void SetupDisplay(struct display *d);
199 static void TellGreeter(RequestHeader *phdr);
200 static int AskGreeter(RequestHeader *preqhdr, char *b, int blen);
202 static void PrintResponse(ResponseHeader *phdr, int count);
205 #if defined (_AIX) && defined (_POWER)
206 static void release_aix_lic(void);
209 #if defined (_AIX) && !defined (_POWER)
210 static int session_execve(char *path, char *argv[], char *envp[]);
212 #define session_execve(A,B,C) execve(A,B,C)
216 static void SetTicketFileName(uid_t uid);
217 # endif /* __KERBEROS */
219 static void LoadAltDtsResources( struct display *d);
220 char * _ExpandLang(char *string, char *lang);
224 /***************************************************************************
228 ***************************************************************************/
230 static int clientPid;
231 static struct greet_info greet;
232 static struct verify_info verify;
233 static char *defaultLanguage = NULL;
235 static jmp_buf abortSession;
238 static char *sensitivityLevel;
242 static char krb_ticket_string[MAXPATHLEN];
243 #endif /* __KERBEROS */
246 XrmDatabase XresourceDB;
253 longjmp (abortSession, 1);
256 static jmp_buf pingTime;
261 longjmp (pingTime, 1);
265 FileNameCompare (a, b)
266 #if defined(__STDC__)
272 return strcoll (*(char **)a, *(char **)b);
276 SessionPingFailed( struct display *d )
280 AbortClient (clientPid);
281 source (&verify, d->reset);
283 #if defined (PAM) || defined(SUNAUTH)
285 char* user = getEnv (verify.userEnviron, "USER");
286 char* ttyLine = d->gettyLine;
288 #ifdef DEF_NETWORK_DEV
290 * If location is not local (remote XDMCP dtlogin) and
291 * remote accouting is enabled (networkDev start with /dev/...)
292 * Set tty line name to match network device for accouting.
293 * Unless the resource was specifically set, default is value
294 * of DEF_NETWORK_DEV define (/dev/dtremote)
297 if ( d->displayType.location != Local &&
298 networkDev && !strncmp(networkDev,"/dev/",5)) {
299 ttyLine = networkDev+5;
304 PamAccounting( verify.argv[0], d->name, d->utmpId, user,
305 ttyLine, clientPid, ACCOUNTING, NULL);
307 solaris_accounting( verify.argv[0], d->name, d->utmpId, user,
308 ttyLine, clientPid, ACCOUNTING, NULL);
312 solaris_resetdevperm(ttyLine);
318 SessionExit (d, RESERVER_DISPLAY);
323 * We need our own error handlers because we can't be sure what exit code Xlib
324 * will use, and our Xlib does exit(1) which matches REMANAGE_DISPLAY, which
325 * can cause a race condition leaving the display wedged. We need to use
326 * RESERVER_DISPLAY for IO errors, to ensure that the manager waits for the
327 * server to terminate. For other X errors, we should give up.
331 IOErrorHandler( Display *dpy )
334 char *s = ((errno >= 0 && errno < sys_nerr) ? sys_errlist[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", sys_errlist[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);
717 if (debugLevel <= 10)
718 if (unlink (tmpname) == -1)
719 Debug ("unlink() on %s failed\n", tmpname);
722 if (resources) free (resources);
727 /***************************************************************************
729 * LoadAltDtsResources
732 * set up alternate desktop resources..
734 ***************************************************************************/
737 LoadAltDtsResources(struct display *d)
741 char dirname[2][MAXPATHLEN];
742 char res_file[MAXPATHLEN];
743 char *rmtype; /* for XrmGetResource() */
744 XrmValue rmvalue; /* for XrmGetResource() */
745 char buf[MAXPATHLEN];
746 char tempbuf[MAXPATHLEN];
749 char altdtres[MAXPATHLEN];
750 char Altdtres[MAXPATHLEN];
753 char *resources = NULL;
755 int num_allocated = 0;
756 char **file_list = NULL;
759 if ( XrmGetResource(XresourceDB,
760 "Dtlogin*altDts", "Dtlogin*AltDts",
761 &rmtype, &rmvalue ) ) {
762 strcpy(tempbuf,rmvalue.addr);
766 strcpy(dirname[0],CDE_INSTALLATION_TOP "/config/%L/Xresources.d/");
767 strcpy(dirname[1],CDE_CONFIGURATION_TOP "/config/%L/Xresources.d/");
769 for(j = 0; j < 2 ; ++j)
771 resources = _ExpandLang(dirname[j], d->language);
772 if (access (resources, R_OK) != 0)
774 Debug("LoadAltDtsResources- cant access %s.\n", resources);
775 Debug("\t %s. Falling back to C.\n", sys_errlist[errno]);
783 resources = _ExpandLang(dirname[j], "C");
784 if (access (resources, R_OK) != 0)
786 Debug("LoadAltDtsResources- cant access %s.\n", resources);
787 Debug("\t %s.\n", sys_errlist[errno]);
790 strcpy(dirname[j], resources);
793 strcpy(dirname[j],resources);
794 Debug("LoadAltDtsResources- found resource dir %s\n", dirname[j]);
806 * Create a list of the alt DT files
808 * NOTE - an assumption made here is that files in /etc/dt
809 * should take precedence over files in /usr/dt. This precedence
810 * is maintained during the sort becase /etc/dt will come before
814 for(j = 0; j < 2 ; ++j) {
816 if((dirp = opendir(dirname[j])) != NULL) {
818 while((dp = readdir(dirp)) != NULL) {
820 if ((strcmp(dp->d_name, DOT) != 0) &&
821 (strcmp(dp->d_name, DOTDOT) != 0)) {
823 sprintf (res_file, "%s%s", dirname[j],dp->d_name);
824 if ((access (res_file, R_OK)) != 0)
826 Debug("LoadAltDtsResources- cant access %s.\n",
828 Debug("\t %s.\n", sys_errlist[errno]);
832 if (file_count == 0) {
833 file_list = malloc (list_incr * sizeof(char **));
834 num_allocated += list_incr;
836 if (file_count + 1 > num_allocated) {
837 num_allocated += list_incr;
838 file_list = realloc (file_list,
839 num_allocated * sizeof(char **));
841 file_list[file_count] = strdup (res_file);
850 qsort (file_list, file_count, sizeof (char *), FileNameCompare);
852 for (j = 0; j < file_count ; j++) {
854 userDb = XrmGetFileDatabase(file_list[j]);
855 XrmMergeDatabases(userDb,&XresourceDB);
857 if ( XrmGetResource(XresourceDB, "Dtlogin*altDtsIncrement",
858 "Dtlogin*AltDtsIncrement", &rmtype, &rmvalue ) ) {
861 * remove the trailing spaces
863 if(strchr(rmvalue.addr,' '))
864 strcpy(tempbuf, strtok(rmvalue.addr," "));
866 strcpy(tempbuf, rmvalue.addr);
868 if ((strcmp(tempbuf, "True") == 0) ||
869 (strcmp(tempbuf, "TRUE") == 0)) {
871 if ( XrmGetResource(XresourceDB,
872 "Dtlogin*altDtKey", "Dtlogin*AltDtKey",
873 &rmtype, &rmvalue ) ) {
875 sprintf(altdtres,"Dtlogin*altDtKey%d",i);
876 XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
881 if ( XrmGetResource(XresourceDB,
882 "Dtlogin*altDtName", "Dtlogin*AltDtName",
883 &rmtype, &rmvalue ) ) {
884 sprintf(altdtres,"Dtlogin*altDtName%d",i);
885 XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
887 if ( XrmGetResource(XresourceDB,
888 "Dtlogin*altDtStart", "Dtlogin*AltDtStart",
889 &rmtype, &rmvalue ) ) {
890 sprintf(altdtres,"Dtlogin*altDtStart%d",i);
891 XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
893 if ( XrmGetResource(XresourceDB,
894 "Dtlogin*altDtLogo", "Dtlogin*AltDtLogo",
895 &rmtype, &rmvalue ) ) {
896 sprintf(altdtres,"Dtlogin*altDtLogo%d",i);
897 XrmPutStringResource(&XresourceDB, altdtres, rmvalue.addr);
903 sprintf(tempbuf,"%d",i);
904 XrmPutStringResource(&XresourceDB, "Dtlogin*altDts", tempbuf);
906 if (file_count > 0) {
907 for (i = 0; i < file_count; i++) {
908 Debug ("Loading resource file: %s\n", file_list[i]);
918 * Function Name: _ExpandLang
922 * This function takes the string "string", searches for occurences of
923 * "%L" in the string and if found, the "%L" is substituted with
924 * the value of the $LANG environment variable.
926 * If $LANG is not defined, the %L is replace with NULL.
930 * _ExpandLang() is based on the DtSvc _DtExpandLang() static routine.
934 * ret_string = _ExpandLang (string);
936 * char *ret_string; Returns NULL if "string" is NULL or it points
937 * to the expanded string.
939 * char *string; The first part of the pathname. Typically
940 * the directory containing the item of interest.
942 * Note: The caller is responsible for free'ing the returned string.
964 * Count the number of expansions that will occur.
968 for (n = 0, pch = string ; pch != NULL ; ) {
969 if ((pch = strchr (pch, '%')) != NULL) {
976 return (strdup(string));
979 * We should really be calling setlocale to determine the "default"
980 * locale but setlocale's return value is not standardized across
981 * the various vendor platforms nor is it consistent within differnt
982 * revs of individual OS's. (e.g. its changing between HP-UX 9.0 and
983 * HP-UX 10.0). The "right" call would be the following line:
985 * if ((lang = getenv ("LANG")) || (lang = setlocale(LC_C_TYPE,NULL)))
987 * Here we hard code the default to "C" instead of leaving it NULL.
989 if (lang || (lang = getenv ("LANG")) || (lang = "C"))
990 lang_len = strlen (lang);
993 * Create the space needed.
995 tmp_len = strlen (string) + (n * lang_len) + n + 1;
996 tmp = (char *) malloc (tmp_len);
997 for (i = 0; i < tmp_len; tmp[i] = '\0', i++);
1001 while (pch != NULL) {
1004 if ((pch = strchr (pch, '%')) != NULL) {
1009 (void) strncat (tmp, trail, ((pch - 1) - trail) + 1);
1011 else if ((pch != NULL) && *pch == 'L') {
1012 if (lang_len == 0) {
1013 if (((pch - trail) >=2) && (*(pch-2) == '/'))
1015 * Remove the "/" as well as the "%L".
1017 (void) strncat (tmp, trail, (pch - trail) - 2);
1019 (void) strncat (tmp, trail, (pch - trail) - 1);
1023 * Remove the "%L" and then append the LANG.
1025 (void) strncat (tmp, trail, (pch - trail) - 1);
1026 (void) strcat (tmp, lang);
1030 (void) strncat (tmp, trail, (pch - trail) + 1);
1037 * A '%' was not found.
1039 (void) strcat (tmp, trail);
1048 SetupDisplay (struct display *d)
1050 char **env = 0, **crt_systemEnviron;
1052 if (d->setup && d->setup[0] && (access(d->setup, R_OK ) == 0))
1054 crt_systemEnviron = verify.systemEnviron;
1055 env = systemEnv (d, (char *) 0, (char *) 0);
1056 if (d->authFile && strlen(d->authFile) > 0 )
1057 env = setEnv( env, "XAUTHORITY", d->authFile );
1058 if(d->displayType.location == Local)
1059 env = setEnv (env, LOCATION, "local");
1061 env = setEnv (env, LOCATION, "remote");
1062 verify.systemEnviron = env;
1063 source (&verify, d->setup);
1064 verify.systemEnviron = crt_systemEnviron;
1071 DeleteXloginResources( struct display *d, Display *dpy )
1073 XDeleteProperty(dpy, RootWindow (dpy, 0), XA_RESOURCE_MANAGER);
1076 #if 0 /* dead code: transferred to Dtgreet */
1078 static jmp_buf syncJump;
1083 longjmp (syncJump, 1);
1087 SecureDisplay (d, dpy)
1091 Debug ("SecureDisplay():\n");
1092 signal (SIGALRM, syncTimeout);
1093 if (setjmp (syncJump)) {
1094 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SECDPY,MC_DEF_LOG_NO_SECDPY),
1096 SessionExit (d, RESERVER_DISPLAY);
1098 alarm ((unsigned) d->grabTimeout);
1099 Debug ("Before XGrabServer()\n");
1101 if (XGrabKeyboard (dpy, DefaultRootWindow (dpy), True, GrabModeAsync,
1102 GrabModeAsync, CurrentTime) != GrabSuccess)
1105 signal (SIGALRM, SIG_DFL);
1106 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SECKEY,MC_DEF_LOG_NO_SECKEY),
1108 SessionExit (d, RESERVER_DISPLAY);
1110 Debug ("XGrabKeyboard() succeeded\n");
1112 signal (SIGALRM, SIG_DFL);
1116 XUngrabServer (dpy);
1119 Debug ("Done secure %s\n", d->name);
1122 UnsecureDisplay (d, dpy)
1126 Debug ("Unsecure display %s\n", d->name);
1128 XUngrabServer (dpy);
1137 release_aix_lic(void)
1140 * Release AIX iFOR/LS license (if any)
1148 release_me.request_type = -1;
1149 release_me.login_pid = getpid();
1150 if ((fd = open("/etc/security/monitord_pipe", O_RDWR, 0600)) >= 0)
1152 write(fd, &release_me, sizeof(release_me));
1155 Debug("release message to monitord: %s\n", (fd >= 0) ? "OK" : "failed");
1163 SessionExit( struct display *d, int status )
1172 /* make sure the server gets reset after the session is over */
1173 if (d->serverPid >= 2) {
1174 Debug("Reseting server: pid %d signal %d\n",
1175 d->serverPid, d->resetSignal);
1177 if (d->terminateServer == 0 && d->resetSignal)
1178 kill (d->serverPid, d->resetSignal);
1183 Debug("Exiting Session with status: %d\n", status);
1188 StartClient( struct verify_info *verify, struct display *d, int *pidp )
1191 char currentdir[PATH_MAX+1];
1192 char *failsafeArgv[20];
1193 char *user; /* users name */
1194 char *lang, *font; /* failsafe LANG and font */
1197 int failsafe = FALSE; /* do we run the failsafe session? */
1198 int password = FALSE; /* do we run /bin/passwd? */
1201 char lastsessfile[MAXPATHLEN];
1204 struct pr_passwd *b1_pwd;
1208 #define NOPAG 0xffffffff
1210 long ngroups, groups[NGROUPS];
1216 Debug ("StartSession %s: ", verify->argv[0]);
1217 for (f = verify->argv; *f; f++) {
1219 if ( strcmp(*f, "failsafe") == 0) failsafe = TRUE;
1220 if ( strcmp(*f, "password") == 0) failsafe = password = TRUE;
1224 if (verify->userEnviron) {
1225 for (f = verify->userEnviron; *f; f++)
1230 user = getEnv (verify->userEnviron, "USER");
1232 switch (pid = fork ()) {
1235 /* Force a failsafe session if we can't touch the home directory
1236 * SIA has already attempted to chdir to HOME, and the current dir
1237 * will be set to / if it failed. We just check to see if the HOME
1238 * path is our current directory or not.
1240 home = getEnv (verify->userEnviron, "HOME");
1241 getcwd(currentdir, PATH_MAX+1);
1242 Debug("Current directory is: %s\n", currentdir);
1246 * The following little check doesn't really work. For example,
1247 * here at the XC, NIS reports my home directory as
1248 * "/site/guests/montyb" while getcwd comes up with
1249 * "/net/nexus/site/guests/montyb".
1251 if (strcmp(home, currentdir)) {
1252 Debug("Can't access home directory, setting failsafe to TRUE\n");
1254 LogError (ReadCatalog(
1255 MC_LOG_SET,MC_LOG_NO_HMDIR,MC_DEF_LOG_NO_HMDIR),
1256 home, getEnv (verify->userEnviron, "USER"));
1257 verify->userEnviron = setEnv(verify->userEnviron, "HOME", "/");
1265 * do process accounting...
1267 #if defined(PAM) || defined(SUNAUTH)
1269 char* ttyLine = d->gettyLine;
1271 # ifdef DEF_NETWORK_DEV
1273 * If location is not local (remote XDMCP dtlogin) and
1274 * remote accouting is enabled (networkDev start with /dev/...)
1275 * Set tty line name to match network device for accouting.
1276 * Unless the resource was specifically set, default is value
1277 * of DEF_NETWORK_DEV define (/dev/dtremote)
1280 if ( d->displayType.location != Local &&
1281 networkDev && !strncmp(networkDev,"/dev/",5)) {
1282 ttyLine = networkDev+5;
1287 PamAccounting(verify->argv[0], d->name, d->utmpId, user,
1288 ttyLine, getpid(), USER_PROCESS, NULL);
1290 solaris_accounting(verify->argv[0], d->name, d->utmpId, user,
1291 ttyLine, getpid(), USER_PROCESS, NULL);
1296 #if !defined(sun) && !defined(CSRG_BASED)
1297 Account(d, user, NULL, getpid(), USER_PROCESS, status);
1302 * In _AIX _POWER, the PENV_NOEXEC flag was added. This tells
1303 * setpenv() to set up the user's process environment and return
1304 * without execing. This allows us to set up the process environment
1305 * and proceed to the execute() call as do the other platforms.
1307 * Unfortunately, for AIXV3, the PENV_NOEXEC does not exist, so
1308 * we have to pospone the setpenv() to the actual execute().
1312 * These defines are the tag locations in userEnviron.
1313 * IMPORTANT: changes to the locations of these tags in verify.c
1314 * must be reflected here by adjusting SYS_ENV_TAG or USR_ENV_TAG.
1316 #define SYS_ENV_TAG 0
1317 #define USR_ENV_TAG 3
1320 * Set the user's credentials: uid, gid, groups,
1321 * audit classes, user limits, and umask.
1324 if (setpcred(user, NULL) == -1)
1326 Debug("Can't set User's Credentials (user=%s)\n",user);
1331 char *usrTag, *sysTag;
1332 extern char **newenv;
1335 * Save pointers to tags. The setpenv() function clears the pointers
1336 * to the tags in userEnviron as a side-effect.
1338 sysTag = verify->userEnviron[SYS_ENV_TAG];
1339 usrTag = verify->userEnviron[USR_ENV_TAG];
1342 * Set the users process environment. Store protected variables and
1343 * obtain updated user environment list. This call will initialize
1346 #define SESSION_PENV (PENV_INIT | PENV_ARGV | PENV_NOEXEC)
1347 if (setpenv(user, SESSION_PENV, verify->userEnviron, NULL) != 0)
1349 Debug("Can't set process environment (user=%s)\n",user);
1354 * Restore pointers to tags.
1356 verify->userEnviron[SYS_ENV_TAG] = sysTag;
1357 verify->userEnviron[USR_ENV_TAG] = usrTag;
1360 * Free old userEnviron and replace with newenv from setpenv().
1362 freeEnv(verify->userEnviron);
1363 verify->userEnviron = newenv;
1373 if (PamSetCred( verify->argv[0],
1374 user, verify->uid, verify->gid) > 0 ) {
1375 Debug("Can't set User's Credentials (user=%s)\n",user);
1381 if ( solaris_setcred(verify->argv[0],
1382 user, verify->uid, verify->gid) > 0 ) {
1383 Debug("Can't set User's Credentials (user=%s)\n",user);
1386 #endif /* SUNAUTH */
1393 * HP BLS B1 session setup...
1395 * 1. look up user's protected account information.
1396 * 2. set the session sensitivity/clearance levels
1397 * 3. set the logical UID (LUID)
1401 Debug("BLS - Setting user's clearance, security level and luid.\n");
1402 set_auth_parameters(1, verify->argv);
1405 verify->user_name = user;
1406 strncpy(verify->terminal,d->name,15);
1407 verify->terminal[15]='\0';
1408 verify->pwd = getpwnam(user);
1410 if ( verify->pwd == NULL || strlen(user) == 0 ) {
1411 LogError(ReadCatalog(
1412 MC_LOG_SET,MC_LOG_NO_BLSACCT,MC_DEF_LOG_NO_BLSACCT));
1415 verify->prpwd= b1_pwd = getprpwnam(user);
1416 verify->uid = b1_pwd->ufld.fd_uid;
1418 if ( b1_pwd == NULL || strlen(user) == 0 ) {
1419 LogError(ReadCatalog(
1420 MC_LOG_SET,MC_LOG_NO_BLSPACCT,MC_DEF_LOG_NO_BLSPACCT));
1425 * This has already been done successfully by dtgreet
1426 * but we need to get all the information again for the
1429 if ( verify_user_seclevel(verify,sensitivityLevel) != 1 ) {
1430 Debug("BLS - Could not verify sensitivity level.\n");
1431 LogError(ReadCatalog(
1432 MC_LOG_SET,MC_LOG_NO_VFYLVL,MC_DEF_LOG_NO_VFYLVL));
1436 if ( change_to_user(verify) != 1 ) {
1437 Debug("BLS - Could not change to user: %s.\n",verify->user_name);
1438 LogError(ReadCatalog(
1439 MC_LOG_SET,MC_LOG_NO_BLSUSR,MC_DEF_LOG_NO_BLSUSR),
1444 Debug("BLS - Session setup complete.\n");
1451 * This should never fail since everything has been verified already.
1452 * If it does it must mean registry strangeness, so exit, and try
1456 if (!DoLogin (user, greet.password, d->name)) exit (1);
1459 * extract the SYSTYPE and ISP environment values and set into user's
1460 * environment. This is necessary since we do an execve below...
1463 verify->userEnviron = setEnv(verify->userEnviron, "SYSTYPE",
1466 verify->userEnviron = setEnv(verify->userEnviron, "ISP",
1469 #else /* ! __apollo */
1473 if ( IsVerifyName(VN_AFS) ) {
1474 pagval = get_pag_from_groups(verify->groups[0], verify->groups[1]);
1475 Debug("AFS - get_pag_from_groups() returned pagval = %d\n", pagval);
1477 initgroups(greet.name, verify->groups[2]);
1478 ngroups = getgroups(NGROUPS, groups);
1479 Debug("AFS - getgroups() returned ngroups = %d\n", ngroups);
1480 for (i=0; i < ngroups; i++)
1481 Debug("AFS - groups[%d] = %d\n", i, groups[i]);
1483 if ((pagval != NOPAG) &&
1484 (get_pag_from_groups(groups[0], groups[1])) == NOPAG ) {
1485 /* we will have to shift grouplist to make room for pag */
1486 if (ngroups+2 > NGROUPS)
1488 for (j=ngroups-1; j >= 0; j--) {
1489 groups[j+2] = groups[j];
1492 get_groups_from_pag(pagval, &groups[0], &groups[1]);
1493 if (setgroups(ngroups, groups) == -1) {
1496 MC_LOG_SET,MC_LOG_AFS_FAIL,MC_DEF_LOG_AFS_FAIL));
1501 # else /* ! __AFS */
1502 /* If SIA is enabled, the initgroups and setgid calls are redundant
1509 * if your system does not support "initgroups(3C)", use
1510 * the "setgroups()" call instead...
1513 # if (defined(__hpux) || defined(__osf__))
1514 initgroups(user, -1);
1516 setgroups (verify->ngroups, verify->groups);
1519 /* setpenv() will set gid for AIX */
1521 setgid (verify->groups[0]);
1524 # else /* ! NGROUPS */
1526 /* setpenv() will set gid for AIX */
1528 setgid (verify->gid);
1531 # endif /* NGROUPS */
1537 setaudid(verify->audid);
1538 setaudproc(verify->audflg);
1541 /* setpenv() will set uid for AIX */
1543 if (setuid(verify->uid) != 0) {
1544 Debug( "Setuid failed for user %s, errno = %d\n", user, errno);
1545 LogError(ReadCatalog(
1546 MC_LOG_SET,MC_LOG_FAIL_SETUID,MC_DEF_LOG_FAIL_SETUID),
1552 #endif /* __apollo */
1555 } /* ends the else clause of if ( ISSECURE ) */
1561 * check home directory again...
1565 /* Don't need to do this if SIA is enabled, already been done.
1567 home = getEnv (verify->userEnviron, "HOME");
1569 if (chdir (home) == -1) {
1570 LogError (ReadCatalog(
1571 MC_LOG_SET,MC_LOG_NO_HMDIR,MC_DEF_LOG_NO_HMDIR),
1572 home, getEnv (verify->userEnviron, "USER"));
1574 verify->userEnviron = setEnv(verify->userEnviron,
1577 else if(!failsafe) {
1578 strcpy(lastsessfile,home); /* save user's last session */
1579 strcat(lastsessfile,LAST_SESSION_FILE);
1580 if((lastsession = fopen(lastsessfile,"w")) == NULL)
1581 Debug("Unable to open file for writing: %s\n",lastsessfile);
1583 fputs(verify->argv[0],lastsession);
1584 fclose(lastsession);
1591 SetUserAuthorization (d, verify);
1597 bzero(greet.password, strlen(greet.password));
1601 * Write login information to a file
1602 * The file name should really be settable by some kind of resource
1603 * but time is short so we hard-wire it to ".dtlogininfo".
1605 if ( ! writeLoginInfo( ".dtlogininfo" , verify ) )
1606 Debug("Unable to write \".dtlogininfo\"\n");
1608 /* extra debugging */
1609 if(!dump_sec_debug_info(verify)) {
1610 Debug("Something wrong with environment\n");
1613 # endif /* ! NDEBUG */
1621 Debug ("Executing session %s\n", verify->argv[0]);
1622 execute (verify->argv, verify->userEnviron);
1623 LogError(ReadCatalog(
1624 MC_LOG_SET,MC_LOG_SES_EXEFAIL,MC_DEF_LOG_SES_EXEFAIL),
1628 LogError(ReadCatalog(
1629 MC_LOG_SET,MC_LOG_NO_CMDARG,MC_DEF_LOG_NO_CMDARG));
1636 * specify a font for the multi-byte languages...
1640 lang = getEnv (verify->userEnviron, "LANG");
1647 failsafeArgv[i++] = "/usr/bin/X11/aixterm";
1649 failsafeArgv[i++] = "/usr/openwin/bin/xterm";
1650 #elif defined (USL) || defined(__uxp__)
1651 failsafeArgv[i++] = "/usr/X/bin/xterm";
1652 #elif defined(__hpux)
1653 failsafeArgv[i++] = "/usr/bin/X11/hpterm";
1654 #elif defined(__OpenBSD__)
1655 failsafeArgv[i++] = "/usr/X11R6/bin/xterm";
1656 #elif defined(__NetBSD__)
1657 failsafeArgv[i++] = "/usr/X11R7/bin/xterm";
1658 #elif defined(__FreeBSD__)
1659 failsafeArgv[i++] = "/usr/local/bin/xterm";
1661 failsafeArgv[i++] = "/usr/bin/X11/xterm";
1663 failsafeArgv[i++] = "-geometry";
1664 failsafeArgv[i++] = "80x10";
1665 failsafeArgv[i++] = "-bg";
1666 failsafeArgv[i++] = "white";
1667 failsafeArgv[i++] = "-fg";
1668 failsafeArgv[i++] = "black";
1670 /* aixterm requires -lang option. */
1671 failsafeArgv[i++] = "-lang";
1672 failsafeArgv[i++] = lang;
1674 failsafeArgv[i++] = "-fn";
1676 if (font == NULL) font = "fixed";
1677 failsafeArgv[i++] = font;
1680 failsafeArgv[i++] = "-e";
1681 failsafeArgv[i++] = "/bin/passwd";
1682 #if defined (__apollo) || defined(__PASSWD_ETC)
1683 failsafeArgv[i++] = "-n";
1685 failsafeArgv[i++] = getEnv (verify->userEnviron, "USER");
1688 failsafeArgv[i++] = d->failsafeClient;
1690 failsafeArgv[i++] = "-C";
1692 failsafeArgv[i++] = "-ls";
1695 failsafeArgv[i++] = "-fn";
1696 failsafeArgv[i++] = font;
1700 failsafeArgv[i] = 0;
1701 Debug ("Executing failsafe session\n", failsafeArgv[0]);
1702 execute (failsafeArgv, verify->userEnviron);
1705 Debug ("StartSession(): fork failed\n");
1706 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SESFORK,MC_DEF_LOG_NO_SESFORK),
1710 Debug ("StartSession(): fork succeeded, pid = %d\n", pid);
1717 static jmp_buf tenaciousClient;
1720 waitAbort( int arg )
1722 longjmp (tenaciousClient, 1);
1725 #if defined(SYSV) || defined(SVR4)
1727 #define killpg(pgrp, sig) kill(-(pgrp), sig)
1731 AbortClient( int pid )
1740 for (i = 0; i < 4; i++) {
1741 if (killpg (pid, sig) == -1) {
1744 LogError(ReadCatalog(
1745 MC_LOG_SET,MC_LOG_NO_KILLCL,MC_DEF_LOG_NO_KILLCL));
1751 if (!setjmp (tenaciousClient)) {
1752 (void) signal (SIGALRM, waitAbort);
1753 (void) alarm ((unsigned) 10);
1754 retId = wait ((waitType *) 0);
1755 (void) alarm ((unsigned) 0);
1756 (void) signal (SIGALRM, SIG_DFL);
1760 signal (SIGALRM, SIG_DFL);
1767 source( struct verify_info *verify, char *file )
1773 if (file && file[0]) {
1774 Debug ("Source(): %s\n", file);
1775 switch (pid = fork ()) {
1780 execute (args, verify->systemEnviron);
1781 LogError(ReadCatalog(
1782 MC_LOG_SET,MC_LOG_NO_EXE,MC_DEF_LOG_NO_EXE),args[0]);
1785 Debug ("Source(): fork failed\n");
1786 LogError(ReadCatalog(
1787 MC_LOG_SET,MC_LOG_NO_FORK,MC_DEF_LOG_NO_FORK),file);
1791 while (wait (&result) != pid)
1795 return waitVal (result);
1800 /* returns 0 on failure, -1 on out of mem, and 1 on success */
1802 execute(char **argv, char **environ )
1806 * make stdout follow stderr to the log file...
1811 session_execve (argv[0], argv, environ);
1814 * In case this is a shell script which hasn't been made executable
1815 * (or this is a SYSV box), do a reasonable thing...
1819 /* errno is EACCES if not executable */
1820 if (errno == ENOEXEC || errno == EACCES) {
1822 if (errno == ENOEXEC) {
1824 char program[1024], *e, *p, *optarg;
1826 char **newargv, **av;
1830 * emulate BSD kernel behaviour -- read
1831 * the first line; check if it starts
1832 * with "#!", in which case it uses
1833 * the rest of the line as the name of
1834 * program to run. Else use "/bin/sh".
1836 f = fopen (argv[0], "r");
1839 if (fgets (program, sizeof (program) - 1, f) == NULL)
1845 e = program + strlen (program) - 1;
1848 if (!strncmp (program, "#!", 2)) {
1850 while (*p && isspace (*p))
1853 while (*optarg && !isspace (*optarg))
1859 while (*optarg && isspace (*optarg));
1866 Debug ("Shell script execution: %s (optarg %s)\n",
1867 p, optarg ? optarg : "(null)");
1868 for (av = argv, argc = 0; *av; av++, argc++)
1870 newargv = (char **) malloc ((argc + (optarg ? 3 : 2)) * sizeof (char *));
1877 while (*av++ = *argv++)
1879 session_execve (newargv[0], newargv, environ);
1888 /*****************************************************************************
1891 * Invoke the Greeter process and wait for completion. If the user was
1892 * successfully verified, return to the calling process. If the user
1893 * selected a restart or abort option, or there was an error invoking the
1894 * Greeter, exit this entire process with appropriate status.
1896 *****************************************************************************/
1900 extern int session_set;
1901 extern char *progName; /* Global argv[0]; dtlogin name and path */
1903 int response[2], request[2];
1905 /* Fixes problem with dtlogin signal handling */
1906 static int greeterPid = 0;
1907 static struct display *greeter_d = NULL;
1912 Debug("Caught SIGHUP\n");
1915 Debug("Killing greeter process: %d\n", greeterPid);
1916 kill(greeterPid, SIGHUP);
1919 SessionExit(greeter_d, REMANAGE_DISPLAY);
1921 exit(REMANAGE_DISPLAY);
1925 RunGreeter( struct display *d, struct greet_info *greet,
1926 struct verify_info *verify )
1933 static char msg[MSGSIZE];
1937 struct greet_state state;
1942 # define U_NAMELEN sizeof(rgy_$name_t)
1946 static char name_short[U_NAMELEN];
1952 char *argv[] = { "dtlogin", 0 };
1953 char *hostName = NULL;
1954 char *loginName = NULL;
1961 if (d->serverPid == -1)
1964 siaStatus = sia_ses_init(&siaHandle, argc, argv, hostName,
1965 loginName, d->name, 1, NULL);
1966 if (siaStatus != SIASUCCESS)
1968 Debug("sia_ses_init failure status %d\n", siaStatus);
1975 if (!setjmp (abortSession)) {
1976 signal(SIGTERM, catchTerm);
1979 * We've changed dtlogin to pass HUP's down to the children
1980 * so ignore any HUP's once the client has started.
1983 signal(SIGHUP, catchHUP);
1986 * set up communication pipes...
1994 switch (greeterPid = fork ()) {
1998 * pass some information in the environment...
2002 sprintf(msg,"%d", d->grabServer);
2003 env = setEnv(env, GRABSERVER, msg);
2005 sprintf(msg,"%d", d->grabTimeout);
2006 env = setEnv(env, GRABTIMEOUT, msg);
2009 if (timeZone && strlen(timeZone) > 0 )
2010 env = setEnv(env, "TZ", timeZone);
2012 if (errorLogFile && errorLogFile[0])
2013 env = setEnv(env, ERRORLOG, errorLogFile);
2016 env = setEnv(env, "XAUTHORITY", d->authFile);
2019 env = setEnv(env, DTLITE, "True");
2022 env = setEnv(env, SESSION, d->session);
2025 env = setEnv(env, SESSION_SET, "True");
2027 if (d->pmSearchPath)
2028 env = setEnv(env, "XMICONSEARCHPATH", d->pmSearchPath);
2030 if (d->bmSearchPath)
2031 env = setEnv(env, "XMICONBMSEARCHPATH", d->bmSearchPath);
2033 #if defined (__KERBEROS) || defined (__AFS)
2034 if (d->verifyName) {
2035 if ( (strcmp(d->verifyName, VN_AFS) == 0) ||
2036 (strcmp(d->verifyName, VN_KRB) == 0) ) {
2038 env = setEnv(env, VERIFYNAME, d->verifyName );
2041 LogError(ReadCatalog(
2042 MC_LOG_SET,MC_LOG_IMPROP_AUTH,MC_DEF_LOG_IMPROP_AUTH),
2044 d->verifyName = NULL;
2049 if((path = getenv("NLSPATH")) != NULL)
2050 env = setEnv(env, "NLSPATH", path);
2052 env = setEnv(env, "NLSPATH", "/usr/lib/nls/msg/%L/%N.cat");
2057 * ping remote displays...
2061 if (d->displayType.location == Local) {
2062 GettyRunning(d); /* refresh gettyState */
2063 if (d->gettyState != DM_GETTY_USER)
2064 env = setEnv(env, LOCATION, "local");
2067 sprintf(msg,"%d", d->pingInterval);
2068 env = setEnv(env, PINGINTERVAL, msg);
2070 sprintf(msg,"%d", d->pingTimeout);
2071 env = setEnv(env, PINGTIMEOUT, msg);
2075 if ( d->langList && strlen(d->langList) > 0 )
2076 env = setEnv(env, LANGLIST, d->langList);
2077 #if !defined (ENABLE_DYNAMIC_LANGLIST)
2078 else if (languageList && strlen(languageList) > 0 )
2079 env = setEnv(env, LANGLIST, languageList);
2080 #endif /* ENABLE_DYNAMIC_LANGLIST */
2083 char *language = NULL;
2085 #if defined (ENABLE_DYNAMIC_LANGLIST)
2086 language = d->language;
2087 #endif /* ENABLE_DYNAMIC_LANGLIST */
2089 if ( d->language && strlen(d->language) > 0 )
2090 env = setLang(d, env, language);
2093 if((path = getenv("XKEYSYMDB")) != NULL)
2094 env = setEnv(env, "XKEYSYMDB", path);
2097 if((path = getenv("OPENWINHOME")) != NULL)
2098 env = setEnv(env, "OPENWINHOME", path);
2103 * set environment for Domain machines...
2105 env = setEnv(env, "ENVIRONMENT", "bsd");
2106 env = setEnv(env, "SYSTYPE", "bsd4.3");
2110 Debug ("Greeter environment:\n");
2112 Debug ("End of Greeter environment:\n");
2115 * Writing to file descriptor 1 goes to response pipe instead.
2123 * Reading from file descriptor 0 reads from request pipe instead.
2133 * figure out path to dtgreet...
2136 strcpy(msg, progName);
2138 if ((p = (char *) strrchr(msg, '/')) == NULL)
2143 strcat(msg,"dtgreet");
2145 execle(msg, "dtgreet", "-display", d->name, (char *)0, env);
2146 LogError(ReadCatalog(
2147 MC_LOG_SET,MC_LOG_NO_DTGREET,MC_DEF_LOG_NO_DTGREET),
2149 exit (NOTIFY_ABORT_DISPLAY);
2152 Debug ("Fork of Greeter failed.\n");
2153 LogError(ReadCatalog(
2154 MC_LOG_SET,MC_LOG_NO_FORKCG,MC_DEF_LOG_NO_FORKCG),d->name);
2159 exit (UNMANAGE_DISPLAY);
2162 Debug ("Greeter started\n");
2164 close(response[1]); /* Close write end of response pipe */
2165 close(request[0]); /* Close read end of request pipe */
2169 * Retrieve information from greeter and authenticate.
2171 globalDisplayName = d->name;
2172 state.id = GREET_STATE_ENTER;
2173 state.waitForResponse = FALSE;
2177 * atexit() registers this function to be called if exit() is
2178 * called. This is needed because in enhanced security mode, SIA
2179 * may call exit() whn the user fails to enter or change a
2182 sia_greeter_pid = greeterPid;
2183 if (!sia_exit_proc_reg)
2185 atexit(KillGreeter);
2186 sia_exit_proc_reg = TRUE;
2189 siaGreeterInfo.d = d;
2190 siaGreeterInfo.greet = greet;
2191 siaGreeterInfo.verify = verify;
2192 siaGreeterInfo.state = &state;
2193 siaGreeterInfo.status = TRUE;
2196 while(siaStatus != SIASUCCESS)
2198 while(siaStatus != SIASUCCESS && siaGreeterInfo.status)
2200 Debug ("RunGreeter: before sia_ses_authent\n");
2201 dt_in_sia_ses_authent = True;
2202 siaStatus = sia_ses_authent(SiaManageGreeter, NULL,
2204 dt_in_sia_ses_authent = False;
2205 Debug ("RunGreeter: after sia_ses_authent status = %d\n",
2207 if (siaStatus == SIAFAIL && siaGreeterInfo.status)
2209 state.id = GREET_STATE_ERRORMESSAGE;
2210 state.vf = VF_INVALID;
2211 ManageGreeter(d, greet, verify, &state);
2213 if (!siaGreeterInfo.status || siaStatus == SIASTOP)
2216 if (!siaGreeterInfo.status || siaStatus == SIASTOP)
2218 sia_ses_release(&siaHandle);
2222 Debug("RunGreeter: before sia_ses_estab\n");
2223 siaStatus = sia_ses_estab(SiaManageGreeter, siaHandle);
2224 Debug ("RunGreeter: after sia_ses_estab status = %d\n",
2227 if (!siaGreeterInfo.status)
2230 if (siaStatus == SIASUCCESS)
2232 Debug("RunGreeter: before sia_ses_launch\n");
2233 siaStatus = sia_ses_launch(SiaManageGreeter, siaHandle);
2234 Debug("RunGreeter: after sia_ses_launch status = %d\n",
2237 if (!siaGreeterInfo.status)
2240 if (siaStatus != SIASUCCESS)
2242 Debug("RunGreeter: sia_ses_launch failure\n");
2243 /* establish & launch failures do a release */
2245 siaStatus = sia_ses_init(&siaHandle, argc, argv, hostName,
2246 loginName, d->name, 1, NULL);
2247 if (siaStatus != SIASUCCESS)
2249 Debug("sia_ses_init failure status %d\n", siaStatus);
2250 exit(RESERVER_DISPLAY);
2255 * sia_ses_launch() wil probably seteuid to that of the
2256 * user, but we don't want that now.
2260 * extract necessary info from SIA context struct
2264 if (siaStatus == SIASUCCESS)
2265 CopySiaInfo(siaHandle, greet);
2266 sia_ses_release(&siaHandle);
2268 state.id = GREET_STATE_TERMINATEGREET;
2269 if (siaGreeterInfo.status)
2271 while (ManageGreeter(d, greet, verify, &state))
2274 sia_greeter_pid = 0;
2276 while (ManageGreeter(d, greet, verify, &state))
2281 * Wait for Greeter to end...
2284 pid = wait (&status);
2285 if (pid == greeterPid)
2291 * Greeter exited. Check return code...
2294 Debug("Greeter return status; exit = %d, signal = %d\n",
2295 waitCode(status), waitSig(status));
2299 * remove authorization file if used...
2302 if (d->authorizations && d->authFile &&
2303 waitVal(status) != NOTIFY_LANG_CHANGE
2305 && waitVal(status) != NOTIFY_BAD_SECLEVEL
2310 Debug ("Done with authorization file %s, removing\n",
2312 (void) unlink (d->authFile);
2317 if(waitVal(status) > NOTIFY_ALT_DTS)
2318 d->sessionType = waitVal(status);
2321 switch (waitVal(status)) {
2322 case NOTIFY_FAILSAFE:
2323 greet->string = "failsafe";
2325 case NOTIFY_PASSWD_EXPIRED:
2326 greet->string = "password";
2331 case NOTIFY_LAST_DT:
2332 d->sessionType = waitVal(status);
2338 Debug("waitVal - status is %d\n", waitVal(status));
2339 if(waitVal(status) > NOTIFY_ALT_DTS)
2340 notify_dt = NOTIFY_ALT_DTS; /* It is alt desktops */
2342 notify_dt = waitVal(status);
2344 switch (notify_dt) {
2345 case NOTIFY_FAILSAFE:
2346 case NOTIFY_PASSWD_EXPIRED:
2350 case NOTIFY_LAST_DT:
2351 case NOTIFY_ALT_DTS:
2353 if (NULL == greet->name) return;
2356 * greet->name, greet->password set in ManageGreeter().
2358 Debug("Greeter returned name '%s'\n", greet->name);
2361 greet->name_full = greet->name;
2362 /* get just person name out of full SID */
2364 while (i < sizeof(rgy_$name_t)
2365 && greet->name_full[i] != '.'
2366 && greet->name_full[i] != '\0') {
2367 name_short[i] = greet->name_full[i];
2370 name_short[i] = '\0';
2371 greet->name = name_short;
2376 * groups[] set in Authenticate().
2378 if ( IsVerifyName(VN_AFS) ) {
2379 verify->groups[0] = groups[0];
2380 verify->groups[1] = groups[1];
2381 Debug("Greeter returned groups[0] '%d'\n", verify->groups[0]);
2382 Debug("Greeter returned groups[1] '%d'\n", verify->groups[1]);
2388 * sensitivityLevel set in BLS_Verify()
2390 greet->b1security = sensitivityLevel;
2393 Verify(d, greet, verify);
2397 Debug ("Greeter Xlib error or SIGTERM\n");
2398 SessionExit(d, OPENFAILED_DISPLAY);
2400 case NOTIFY_RESTART:
2401 Debug ("Greeter requested RESTART_DISPLAY\n");
2402 SessionExit(d, RESERVER_DISPLAY);
2404 case NOTIFY_ABORT_DISPLAY:
2405 Debug ("Greeter requested UNMANAGE_DISPLAY\n");
2406 SessionExit(d, UNMANAGE_DISPLAY);
2408 case NOTIFY_NO_WINDOWS:
2409 Debug ("Greeter requested NO_WINDOWS mode\n");
2410 if (d->serverPid >= 2)
2412 * Don't do a SessionExit() here since that causes
2413 * the X-server to be reset. We know we are going to
2414 * terminate it anyway, so just go do that...
2416 exit(SUSPEND_DISPLAY);
2420 case NOTIFY_LANG_CHANGE:
2421 Debug ("Greeter requested LANG_CHANGE\n");
2424 * copy requested language into display struct "d". Note,
2425 * this only happens in this child's copy of "d", not in
2426 * the master struct. When the user logs out, the
2427 * resource-specified language (if any) will reactivate.
2429 Debug("Greeter returned language '%s'\n", d->language);
2431 if (strcmp(d->language, "default") == 0) {
2432 int len = strlen(defaultLanguage) + 1;
2433 d->language = (d->language == NULL ?
2434 malloc(len) : realloc (d->language, len));
2435 strcpy(d->language, defaultLanguage);
2439 case NOTIFY_BAD_SECLEVEL:
2442 case waitCompose (SIGTERM,0,0):
2443 Debug ("Greeter exited on SIGTERM\n");
2444 SessionExit(d, OPENFAILED_DISPLAY);
2447 Debug ("Greeter returned unknown status %d\n",
2449 SessionExit(d, REMANAGE_DISPLAY);
2452 signal(SIGHUP, SIG_DFL);
2455 AbortClient(greeterPid);
2456 SessionExit(d, UNMANAGE_DISPLAY);
2460 /*****************************************************************************
2466 This is the entry into greeter state processing. Allocate and initialize
2470 Display the login screen. Upon display, the login screen can be 'reset'. If
2471 reset is true, the username and password fields are cleared and the focus
2472 is set to the username field. If reset is false, the username and password
2473 field is untouched and the focus is set to the password field.
2475 LOGIN -> AUTHENTICATE:
2476 Authenticate the username entered on login screen.
2478 AUTHENTICATE -> TERMINATEGREET:
2479 User passed authentication so terminate the greeter.
2481 AUTHENTICATE -> EXPASSWORD:
2482 User passed authentication, but the their password has expired.
2483 Display old password message. This message allows the user to
2484 change their password by starting a getty and running passwd(1).
2486 AUTHENTICATE -> BAD_HOSTNAME:
2487 User passed authentication, but the their hostname is empty.
2488 Display a dialog that allows the user to run a getty to fix the
2489 problem, or start the desktop anyway.
2491 AUTHENTICATE -> ERRORMESSAGE:
2492 User failed authentication, so display error message.
2494 AUTHENTICATE -> LOGIN
2495 User failed authentication, but did not enter a password. Instead
2496 of displaying an error message, redisplay the login screen with
2497 the focus set to the password field. If the user authenticates again
2498 without the password field set, display an error. This allows a user
2499 to type the ubiquitous "username<ENTER>password<ENTER>" sequence.
2502 Free state structure and return false to stop state transitions.
2504 ERRORMESSAGE -> LOGIN
2505 Display error message base on return code from last authentication
2506 attempt. Redisplay login screen with reset set to true.
2508 (state) -> LANG -> (state)
2509 User has chosen a new language. Transition to LANG state to save off
2510 the new language, and transition back to original state.
2512 *****************************************************************************/
2514 #define SETMC(M, ID) M.id = MC_##ID; M.def = MC_DEF_##ID
2517 ManageGreeter( struct display *d, struct greet_info *greet,
2518 struct verify_info *verify, struct greet_state *state )
2525 if (state->waitForResponse)
2527 if (!AskGreeter(NULL, (char *)state->response, REQUEST_LIM_MAXLEN))
2530 * Dtgreet has terminated.
2532 state->id = GREET_STATE_EXIT;
2533 state->waitForResponse = FALSE;
2537 if (state->request->opcode != state->response->opcode)
2540 * An unrequested event arrived. See if it's one we
2543 switch(state->response->opcode)
2545 case REQUEST_OP_LANG:
2548 * User has changed language. Recursively handle this state
2549 * and return to current state.
2551 struct greet_state lang_state;
2553 lang_state = *state;
2554 lang_state.id = GREET_STATE_LANG;
2555 lang_state.waitForResponse = FALSE;
2556 ManageGreeter(d, greet, verify, &lang_state);
2557 Debug("Response opcode REQUEST_OP_LANG\n");
2562 case REQUEST_OP_CLEAR:
2565 * User has requested the screen be cleared.
2567 state->id = GREET_STATE_USERNAME;
2568 state->waitForResponse = TRUE;
2569 Debug("Response opcode REQUEST_OP_CLEAR\n");
2574 Debug("Response opcode UNEXPECTED RESPONSE!\n");
2584 * Got the response we were expecting.
2586 state->waitForResponse = FALSE;
2592 case GREET_STATE_ENTER:
2595 * Enter - initialize state
2597 Debug("GREET_STATE_ENTER\n");
2599 state->request = (RequestHeader *)malloc(REQUEST_LIM_MAXLEN);
2600 state->response= (ResponseHeader *)malloc(REQUEST_LIM_MAXLEN);
2601 state->authenticated = FALSE;
2604 state->id = GREET_STATE_USERNAME;
2608 case GREET_STATE_USERNAME:
2613 RequestChallenge *r;
2615 Debug("GREET_STATE_USERNAME\n");
2617 Authenticate(d, NULL, NULL, NULL);
2619 SETMC(msg, LOGIN_LABEL);
2621 r = (RequestChallenge *)state->request;
2622 r->hdr.opcode = REQUEST_OP_CHALLENGE;
2623 r->hdr.reserved = 0;
2626 r->hdr.length = sizeof(*r);
2628 r->offChallenge = sizeof(*r);
2629 strcpy(((char *)r) + r->offChallenge, msg.def);
2630 r->hdr.length += strlen(msg.def) + 1;
2634 r->offUserNameSeed = r->hdr.length;
2635 strcpy(((char *)r) + r->offUserNameSeed, greet->name);
2636 r->hdr.length += strlen(greet->name) + 1;
2637 Debug("Greet name: %s\n", greet->name);
2641 r->offUserNameSeed = 0;
2646 free(greet->name); greet->name = NULL;
2648 if (greet->password)
2650 free(greet->password); greet->password = NULL;
2653 TellGreeter((RequestHeader *)r);
2654 state->waitForResponse = TRUE;
2656 state->id = GREET_STATE_AUTHENTICATE;
2660 case GREET_STATE_CHALLENGE:
2665 RequestChallenge *r;
2667 Debug("GREET_STATE_CHALLENGE\n");
2669 if (greet->password)
2671 free(greet->password); greet->password = NULL;
2674 SETMC(msg, PASSWD_LABEL);
2676 r = (RequestChallenge *)state->request;
2677 r->hdr.opcode = REQUEST_OP_CHALLENGE;
2678 r->hdr.reserved = 0;
2681 r->offUserNameSeed = 0;
2682 r->offChallenge = sizeof(*r);
2683 strcpy(((char *)r) + r->offChallenge, msg.def);
2684 r->hdr.length = sizeof(*r) + strlen(msg.def) + 1;
2686 TellGreeter((RequestHeader *)r);
2687 state->waitForResponse = TRUE;
2689 state->id = GREET_STATE_AUTHENTICATE;
2693 case GREET_STATE_AUTHENTICATE:
2696 * Attempt to authenticate.
2698 ResponseChallenge *r;
2700 Debug("GREET_STATE_AUTHENTICATE\n");
2702 r = (ResponseChallenge *)state->response;
2704 if (greet->name == NULL)
2706 greet->name = strdup(((char *)r) + r->offResponse);
2707 if (strlen(greet->name) == 0)
2709 state->id = GREET_STATE_USERNAME;
2715 greet->password = strdup(((char *)r) + r->offResponse);
2725 * Attempt to authenticate user. 'username' should be a
2726 * non-empty string. 'password' may be an empty string.
2728 state->vf = Authenticate(d, greet->name, greet->password, &state->msg);
2730 if (state->vf == VF_OK ||
2731 state->vf == VF_PASSWD_AGED ||
2732 state->vf == VF_BAD_HOSTNAME)
2734 state->authenticated = TRUE;
2738 * General transitions.
2742 case VF_OK: state->id = GREET_STATE_TERMINATEGREET; break;
2743 case VF_PASSWD_AGED: state->id = GREET_STATE_EXPASSWORD; break;
2744 case VF_BAD_HOSTNAME: state->id = GREET_STATE_BAD_HOSTNAME; break;
2745 case VF_CHALLENGE: state->id = GREET_STATE_CHALLENGE; break;
2746 default: state->id = GREET_STATE_ERRORMESSAGE; break;
2751 case GREET_STATE_EXIT:
2754 * Free resources and leave.
2756 Debug("GREET_STATE_EXIT\n");
2763 if (!state->authenticated)
2767 free(greet->name); greet->name = NULL;
2769 if (greet->password)
2771 free(greet->password); greet->password = NULL;
2775 free(state->request);
2776 free(state->response);
2781 case GREET_STATE_ERRORMESSAGE:
2784 * Display error message.
2788 Debug("GREET_STATE_ERRORMESSAGE\n");
2790 r = (RequestMessage *)state->request;
2794 case VF_INVALID: SETMC(msg, LOGIN); break;
2795 case VF_HOME: SETMC(msg, HOME); break;
2796 case VF_MAX_USERS: SETMC(msg, MAX_USERS); break;
2797 case VF_BAD_UID: SETMC(msg, BAD_UID); break;
2798 case VF_BAD_GID: SETMC(msg, BAD_GID); break;
2799 case VF_BAD_AID: SETMC(msg, BAD_AID); break;
2800 case VF_BAD_AFLAG: SETMC(msg, BAD_AFLAG); break;
2801 case VF_NO_LOGIN: SETMC(msg, NO_LOGIN); break;
2803 case VF_BAD_SEN_LEVEL: SETMC(msg, BAD_SEN_LEVEL); break;
2805 case VF_MESSAGE: msg.id=0; msg.def=state->msg; break;
2806 default: msg.id=0; msg.def=""; break;
2809 r->hdr.opcode = REQUEST_OP_MESSAGE;
2810 r->hdr.reserved = 0;
2812 r->offMessage = sizeof(*r);
2813 strcpy(((char *)r) + r->offMessage, msg.def);
2814 r->hdr.length = sizeof(*r) + strlen(msg.def) + 1;
2816 TellGreeter((RequestHeader *)r);
2817 state->waitForResponse = TRUE;
2819 state->id = GREET_STATE_USERNAME;
2823 case GREET_STATE_LANG:
2826 * User selected new language.
2832 Debug("GREET_STATE_LANG\n");
2834 r = (ResponseLang *)state->response;
2835 lang = ((char *)r) + r->offLang;
2836 len = strlen(lang) + 1;
2838 d->language = (d->language == NULL ?
2839 malloc(len) : realloc(d->language, len));
2840 strcpy(d->language, lang);
2841 Debug("Language returned: %s\n", d->language);
2845 case GREET_STATE_TERMINATEGREET:
2848 * Terminate dtgreet.
2852 Debug("GREET_STATE_TERMINATEGREET\n");
2854 r = (RequestExit *)state->request;
2856 r->hdr.opcode = REQUEST_OP_EXIT;
2857 r->hdr.reserved = 0;
2858 r->hdr.length = sizeof(*r);
2860 TellGreeter((RequestHeader *)r);
2861 state->waitForResponse = TRUE;
2863 state->id = GREET_STATE_EXIT;
2867 case GREET_STATE_EXPASSWORD:
2870 * Display password expired message.
2872 RequestExpassword *r;
2874 Debug("GREET_STATE_EXPASSWORD\n");
2876 r = (RequestExpassword *)state->request;
2878 r->hdr.opcode = REQUEST_OP_EXPASSWORD;
2879 r->hdr.reserved = 0;
2880 r->hdr.length = sizeof(*r);
2882 TellGreeter((RequestHeader *)r);
2883 state->waitForResponse = TRUE;
2885 state->id = GREET_STATE_USERNAME;
2889 case GREET_STATE_BAD_HOSTNAME:
2892 * Display password expired message.
2896 Debug("GREET_STATE_BAD_HOSTNAME\n");
2898 r = (RequestHostname *)state->request;
2900 r->hdr.opcode = REQUEST_OP_HOSTNAME;
2901 r->hdr.reserved = 0;
2902 r->hdr.length = sizeof(*r);
2904 TellGreeter((RequestHeader *)r);
2905 state->waitForResponse = TRUE;
2907 state->id = GREET_STATE_USERNAME;
2912 case GREET_STATE_FORM:
2915 * Get arbitrary number of answers.
2918 Debug("GREET_STATE_FORM\n");
2920 AskGreeter(state->request, (char *)state->response, REQUEST_LIM_MAXLEN);
2922 state->waitForResponse = FALSE;
2923 state->id = GREET_STATE_USERNAME;
2935 RequestHeader *phdr)
2937 write(request[1], phdr, phdr->length);
2942 RequestHeader *preqhdr,
2948 ResponseHeader *phdr = (ResponseHeader *)buf;
2950 if (preqhdr) TellGreeter(preqhdr);
2952 phdr->opcode = REQUEST_OP_NONE;
2954 count = read(response[0], buf, sizeof(*phdr));
2956 if (count == sizeof(*phdr))
2959 * Calculate amount of data after header.
2961 remainder = phdr->length - sizeof(*phdr);
2965 * Read remainder of response.
2967 count += read(response[0], buf+sizeof(*phdr), remainder);
2972 if (debugLevel) PrintResponse(phdr, count);
2981 ResponseHeader *phdr,
2984 char *opstr = "UNKNOWN";
2988 Debug("opcode = (EOF)\n");
2992 switch(phdr->opcode)
2994 case REQUEST_OP_EXIT: opstr = "EXIT"; break;
2995 case REQUEST_OP_MESSAGE: opstr = "MESSAGE"; break;
2996 case REQUEST_OP_CHPASS: opstr = "CHPASS"; break;
2997 case REQUEST_OP_CHALLENGE: opstr = "CHALLENGE"; break;
2998 case REQUEST_OP_LANG: opstr = "LANG"; break;
2999 case REQUEST_OP_DEBUG: opstr = "DEBUG"; break;
3002 Debug("opcode = %d (%s)\n", phdr->opcode, opstr);
3003 Debug(" reserved = %d\n", phdr->reserved);
3004 Debug(" length = %d\n", phdr->length);
3006 switch(phdr->opcode)
3008 case REQUEST_OP_EXIT: break;
3009 case REQUEST_OP_LANG:
3010 Debug(" offLang=%d\n", ((ResponseLang *)phdr)->offLang);
3011 Debug(" lang='%s'\n",
3012 ((char *)phdr)+((ResponseLang *)phdr)->offLang);
3014 case REQUEST_OP_MESSAGE: break;
3015 case REQUEST_OP_CHPASS: break;
3016 case REQUEST_OP_CHALLENGE:
3017 Debug(" offResponse=%d\n", ((ResponseChallenge *)phdr)->offResponse);
3018 Debug(" response='%s'\n",
3019 ((char *)phdr)+((ResponseChallenge *)phdr)->offResponse);
3021 case REQUEST_OP_DEBUG:
3022 Debug(" offString=%d\n", ((ResponseDebug *)phdr)->offString);
3023 Debug(" string='%s'\n",
3024 ((char *)phdr)+((ResponseDebug *)phdr)->offString);
3032 /***************************************************************************
3036 * generate kerberos ticket file name. Name is returned in the static
3037 * global variable "krb_ticket_string".
3039 ***************************************************************************/
3042 SetTicketFileName(uid_t uid)
3051 * generate ticket file pathname (/tmp/tkt<uid>.<host>) ...
3054 if (env = (char *)getenv("KRBTKFILE")) {
3055 (void) strncpy(krb_ticket_string, env, sizeof(krb_ticket_string)-1);
3056 krb_ticket_string[sizeof(krb_ticket_string)-1] = '\0';
3059 if (gethostname(lhost, sizeof(lhost)) != -1) {
3060 if (p = index(lhost, '.')) *p = '\0';
3061 (void)sprintf(krb_ticket_string, "%s%ld.%s", TKT_ROOT, (long)uid, lhost);
3063 /* 32 bits of signed integer will always fit in 11 characters
3064 (including the sign), so no need to worry about overflow */
3065 (void) sprintf(krb_ticket_string, "%s%ld", TKT_ROOT, (long)uid);
3070 #endif /* __KERBEROS */
3072 #if defined (_AIX) && !defined (_POWER)
3074 /***************************************************************************
3078 * If this is an authenticated process (LOGNAME set), set user's
3079 * process environment by calling setpenv().
3081 * If this is not an authenticated process, just call execve()
3083 ***************************************************************************/
3092 char *user = getEnv (envp, "LOGNAME");
3096 rc = execve(path, argv, envp);
3100 char *usrTag, *sysTag;
3103 * Save pointers to tags. The setpenv() function clears the pointers
3104 * to the tags in userEnviron as a side-effect.
3106 sysTag = envp[SYS_ENV_TAG];
3107 usrTag = envp[USR_ENV_TAG];
3110 * Set the users process environment. This call execs arvg so it
3111 * should not return. It it should return, restore the envp tags.
3113 rc = setpenv(user, PENV_INIT | PENV_ARGV, envp, argv);
3116 * Restore pointers to tags.
3118 envp[SYS_ENV_TAG] = sysTag;
3119 envp[USR_ENV_TAG] = usrTag;
3124 #endif /* _AIX && !_POWER */
3128 /* collect the SIA parameters from a window system. */
3130 static int SiaManageGreeter(
3133 unsigned char *title,
3139 RequestMessage greeter_message;
3140 char msg_buffer[256];
3141 } greeter_msg_and_buffer;
3142 RequestForm *request_form;
3150 if (rendition == SIAFORM && dt_in_sia_ses_authent
3151 && (num_prompts == 2))
3153 /* Normal login, Password case */
3154 Debug ("SIAFORM Normal login, Password case\n");
3155 while (siaGreeterInfo.state->id != GREET_STATE_TERMINATEGREET
3156 && siaGreeterInfo.state->id != GREET_STATE_EXIT
3157 && (siaGreeterInfo.status = ManageGreeter(
3158 siaGreeterInfo.d, siaGreeterInfo.greet,
3159 siaGreeterInfo.verify, siaGreeterInfo.state)))
3162 if (!siaGreeterInfo.status
3163 || siaGreeterInfo.state->id == GREET_STATE_EXIT)
3164 return(SIACOLABORT);
3166 strncpy((char *)prompt[0].result, siaGreeterInfo.greet->name,
3167 prompt[0].max_result_length);
3168 strncpy((char *)prompt[1].result,siaGreeterInfo.greet->password,
3169 prompt[1].max_result_length);
3176 ResponseForm *response_form;
3181 Debug("SIAMENUONE num_prompts = %d\n", num_prompts);
3184 Debug("SIAMENUANY num_prompts = %d\n", num_prompts);
3187 Debug("SIAONELINER num_prompts = %d\n", num_prompts);
3190 Debug("SIAFORM num_prompts = %d\n", num_prompts);
3194 /* need to display form */
3196 req_form_size = sizeof(RequestForm)
3197 + strlen((const char *)title) + 1;
3198 for (i=0; i<num_prompts; i++)
3199 req_form_size += strlen((const char *)prompt[i].prompt) + 1;
3200 request_form = (RequestForm *) alloca(req_form_size);
3202 siaGreeterInfo.state->id = GREET_STATE_FORM;
3203 siaGreeterInfo.state->request = (RequestHeader *)request_form;
3204 /* siaGreeterInfo.state->vf = VF_MESSAGE; */
3206 request_form->hdr.opcode = REQUEST_OP_FORM;
3207 request_form->hdr.reserved = 0;
3208 request_form->hdr.length = req_form_size;
3209 request_form->num_prompts = num_prompts;
3210 request_form->rendition = rendition;
3211 request_form->offTitle = sizeof(RequestForm);
3212 request_form->offPrompts = sizeof(RequestForm) +
3213 strlen((const char *)title) + 1;
3214 strcpy((char *)request_form + request_form->offTitle,
3215 (const char *)title);
3217 pmpt_ptr = (char *)request_form + request_form->offPrompts;
3218 for (i=0; i<num_prompts; i++)
3220 if (!prompt[i].prompt || prompt[i].prompt[0] == '\0')
3224 Debug(" prompt[%d]: %s\n", i, prompt[i].prompt);
3225 strcpy(pmpt_ptr, (const char *)prompt[i].prompt);
3226 pmpt_ptr += strlen((const char *)prompt[i].prompt);
3228 request_form->visible[i] =
3229 (prompt[i].control_flags & SIARESINVIS) ? False : True;
3232 siaGreeterInfo.status = ManageGreeter(siaGreeterInfo.d,
3233 siaGreeterInfo.greet,
3234 siaGreeterInfo.verify,
3235 siaGreeterInfo.state);
3237 response_form = (ResponseForm *)siaGreeterInfo.state->response;
3238 res_ptr = (char *)response_form + response_form->offAnswers;
3239 for (i = 0; i < response_form->num_answers; i++)
3241 if (rendition == SIAMENUONE || rendition == SIAMENUANY)
3244 prompt[i].result = (unsigned char *)1;
3246 prompt[i].result = NULL;
3250 strcpy((char *)prompt[0].result, res_ptr);
3252 res_ptr += strlen(res_ptr) + 1;
3254 if (!response_form->collect_status)
3255 siaGreeterInfo.status = FALSE;
3261 Debug("SIAINFO or SIAWARNING %s\n", prompt[0].prompt);
3263 siaGreeterInfo.state->id = GREET_STATE_ERRORMESSAGE;
3264 siaGreeterInfo.state->request = (RequestHeader *)
3265 &greeter_msg_and_buffer.greeter_message;
3266 siaGreeterInfo.state->vf = VF_MESSAGE;
3267 siaGreeterInfo.state->msg = (char *)prompt[0].prompt;
3269 siaGreeterInfo.status = ManageGreeter(siaGreeterInfo.d,
3270 siaGreeterInfo.greet,
3271 siaGreeterInfo.verify,
3272 siaGreeterInfo.state);
3275 return(SIACOLABORT);
3278 if (!siaGreeterInfo.status)
3279 return(SIACOLABORT);
3280 return(SIACOLSUCCESS);
3283 static CopySiaInfo(SIAENTITY *siaHandle, struct greet_info *greet)
3286 greet->name = malloc(strlen(siaHandle->name) + 1);
3287 strcpy (greet->name, siaHandle->name);
3289 greet->password = malloc(strlen(siaHandle->password) + 1);
3290 strcpy (greet->password, siaHandle->password);
3295 static void KillGreeter( void )
3297 if (sia_greeter_pid)
3298 AbortClient(sia_greeter_pid);
3299 sia_greeter_pid = 0;