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 /* $XConsortium: SmLock.c /main/8 1996/10/30 11:13:55 drk $ */
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. *
30 /*************************************<+>*************************************
31 *****************************************************************************
35 ** Project: HP DT Session Manager (dtsession)
39 ** In charge of locking and unlocking the display in response from
40 ** the front panel to so.
44 *******************************************************************
45 ** (c) Copyright Hewlett-Packard Company, 1990. All rights are
46 ** reserved. Copying or other reproduction of this program
47 ** except for archival purposes is prohibited without prior
48 ** written consent of Hewlett-Packard Company.
49 ********************************************************************
53 *****************************************************************************
54 *************************************<+>*************************************/
67 #ifdef USE_HP_SPECIFIC_XLIB
68 #include <X11/XHPlib.h>
69 #endif /* USE_HP_SPECIFIC_XLIB */
71 #include <X11/Intrinsic.h>
73 #include <Dt/UserMsg.h>
74 #include <Dt/Indicator.h>
79 # include <sys/types.h>
89 #if defined(CSRG_BASED)
90 #include <sys/types.h>
101 * Variables global to this module only
107 static XtIntervalId timerId, lockTimeId, lockDelayId, cycleId, flash_id;
112 static Widget grabWidget;
115 * Lock dialog visibility
117 static Boolean lockDlgVisible;
119 #ifdef LOCK_SERVER_ACCESS
121 * Server Access Control Information
123 static Boolean RestrictingAccess = False;
124 static XHostAddress *hostList;
125 static Bool hostListActive;
126 static int hostListLen;
133 static void FinishLocking(Widget, XtPointer, XEvent *, Boolean *);
134 static void RecolorCursor( void ) ;
135 static void EventDetected( Widget, XtPointer, XEvent *, Boolean *) ;
136 static void CheckString( char *, int ) ;
137 static Boolean CheckPassword( char * ) ;
138 #if defined (_AIX) && defined (_POWER)
139 static Boolean Authenticate( char *, uid_t, char * ) ;
141 #define Authenticate(A,B,C) localAuthenticate(A,B,C)
143 static Boolean localAuthenticate( char *, uid_t, char * ) ;
144 static void UnlockDisplay( Boolean, Boolean ) ;
145 static void TakeDownLogin( XtPointer, XtIntervalId * ) ;
146 static void PutUpLogin( Boolean, Boolean ) ;
147 static void LockAttemptFailed( XtPointer, XtIntervalId *) ;
148 static void RequirePassword( XtPointer, XtIntervalId *) ;
149 static void CycleSaver( XtPointer, XtIntervalId *) ;
150 static void BlinkCaret( XtPointer, XtIntervalId *) ;
153 /* #define JET_AUTHDEBUG */
155 /* Test for re-auth ability - see if we can re-authenticate via pwd,
158 static Boolean CanReAuthenticate(char *name, uid_t uid, char *passwd,
159 struct passwd **pwent, struct spwd **spent)
161 Boolean fail = False;
163 *pwent = (name == NULL) ? getpwuid(uid) : getpwnam(name);
164 *spent = getspnam((*pwent)->pw_name);
167 fprintf(stderr, "CanReAuthenticate(): %s %s %s\n",
168 (*pwent) ? "PWENT" : "NULL",
169 (*spent) ? "SPENT" : "NULL",
170 (name) ? name : "NULL");
173 /* some checking for aging stuff on RedPhat */
175 if (*pwent && (*pwent)->pw_passwd)
179 if ((loc = strchr((*pwent)->pw_passwd, ',')) != NULL)
182 fprintf(stderr, "CanReAuthenticate(): pw: '%s'\n",
183 (*pwent)->pw_passwd);
188 if (*spent && (*spent)->sp_pwdp)
192 if ((loc = strchr((*spent)->sp_pwdp, ',')) != NULL)
197 { /* if we can't get this, we're screwed. */
199 fprintf(stderr, "CanReAuthenticate(): PWENT == NULL - FALSE\n");
204 if ((*pwent)->pw_passwd == NULL)
207 fprintf(stderr, "CanReAuthenticate(): (*pwent)->pw_passwd == NULL - FALSE\n");
213 /* ok, now we have the prequisite data, look first to see if the
214 * passwd field is larger than 1 char - implying NIS, or a shadowed
215 * system. if not look for *spent being non-NULL
218 { /* if it's null, lets check for the NIS case */
219 if (strlen((*pwent)->pw_passwd) <= 1)
222 fprintf(stderr, "strlen((*pwent)->pw_passwd) <= 1\n");
225 return False; /* not NIS */
229 /* supposedly we have valid data */
231 fprintf(stderr, "CanReAuthenticate(): TRUE\n");
242 /*************************************<->*************************************
249 * Calls the routines that are in charge of locking the display.
254 * lockNow - request to lock the display immediately
262 *************************************<->***********************************/
264 * Place holders for the lock position
266 static Position visibleY;
267 static Position hiddenY;
275 Widget parent = NULL, lockDlg;
282 timerId = lockTimeId = lockDelayId = cycleId = flash_id = (XtIntervalId)0;
286 * 0 - screen will not be covered, nor will external screen saver run
287 * 1 - screen will be covered, external screen saver may be run
290 * -1 = no password required to unlock display
291 * 0 = password always required to unlock display
292 * N = password required to unlock display after N seconds
294 if (smSaverRes.saverTimeout == 0)
296 smGD.coverScreen = 0;
299 else if (lockNow || smSaverRes.lockTimeout > 0)
301 smGD.coverScreen = 1;
304 else if (smSaverRes.lockTimeout == 0)
306 else if (smSaverRes.lockTimeout <= smSaverRes.saverTimeout)
309 lockDelay = smSaverRes.lockTimeout - smSaverRes.saverTimeout;
313 smGD.coverScreen = 1;
318 * Before anything is done make sure we can unlock if we lock.
320 if (localAuthenticate(NULL, getuid(), NULL) == False)
323 PrintError(DtError, smNLS.trustedSystemErrorString);
325 XBell(smGD.display, 100);
328 * Tell the Workspace Manager to quit blinking
330 msg = tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
331 "DtActivity_Began", 0 );
332 tt_message_send( msg );
333 tt_message_destroy( msg );
339 if(((smDD.lockCoverDialog == NULL) && (smGD.coverScreen == True)) ||
340 ((smDD.lockDialog == NULL) && (smGD.coverScreen == False)))
343 * Set up the grab widget in here
348 * If the user has specified cover - create the cover dialog
350 screenNum = DefaultScreen(smGD.display);
351 if(smGD.coverScreen == True)
353 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
357 smDD.coverDialog[i] = CreateCoverDialog(i, True);
358 parent = smDD.coverDrawing[i];
362 smDD.coverDialog[i] = CreateCoverDialog(i, False);
365 smDD.lockCoverDialog = CreateLockDialogWithCover(parent);
369 * Create the lock dialog if the user has specified that
371 if((smDD.lockDialog == NULL) && (smGD.coverScreen == False))
373 smDD.lockDialog = CreateLockDialog();
376 * Get colors for the password cursor
379 XtSetArg(uiArgs[i], XmNtopShadowColor, &(xcolors[0]));i++;
380 XtSetArg(uiArgs[i], XmNbottomShadowColor, &(xcolors[1]));i++;
381 XtGetValues(smDD.lockDialog, uiArgs, i);
383 smGD.backgroundPix = xcolors[0].pixel;
384 smGD.foregroundPix = xcolors[1].pixel;
385 if (smGD.backgroundPix == smGD.foregroundPix)
387 smGD.backgroundPix = smGD.whitePixel;
388 smGD.foregroundPix = smGD.blackPixel;
394 * Wait for a visibility event to occur on the window so that
397 if(smGD.coverScreen == True)
399 smGD.lockCursor = smGD.blankCursor;
400 grabWidget = smDD.coverDialog[0];
401 lockDlg = smDD.lockCoverDialog;
402 lockDlgVisible = False; /* mappedWhenManaged False */
406 smGD.lockCursor = smGD.padlockCursor;
407 grabWidget = smDD.lockDialog;
408 lockDlg = smDD.lockDialog;
409 visibleY = hiddenY = -1;
413 * Note: grabWidget must be mapped in order to grab it. This means
414 * that if coverScreen is True, smDD.coverDialog[0] must be mapped
415 * immediately and if coverScreen is False, smDD.lockDialog must be
416 * mapped immediately. Also, if a grabWidget is unmapped, the grab
419 XtAddEventHandler(grabWidget, VisibilityChangeMask,
420 False, FinishLocking, NULL);
422 XtManageChild(lockDlg);
424 if(smGD.coverScreen == True) {
425 flash_id = XtAppAddTimeOut(smGD.appCon,
426 1000, BlinkCaret,smDD.indLabel[1]);
429 flash_id = XtAppAddTimeOut(smGD.appCon,
430 1000, BlinkCaret,smDD.indLabel[0]);
436 * Wait for 'lockDelay' seconds before requiring a password.
438 lockDelayId = XtAppAddTimeOut(smGD.appCon,
439 lockDelay*1000, RequirePassword, NULL);
442 else if (lockDelay == 0)
445 * Immediately require a password to unlock the display.
447 smGD.lockedState = LOCKED;
448 PutUpLogin(True, False); /* map, but don't set timeout */
451 if (smGD.coverScreen == True && smSaverRes.cycleTimeout > 0)
454 * Cycle to next saver in 'cycleTimeout' seconds.
456 cycleId = XtAppAddTimeOut(smGD.appCon,
457 smSaverRes.cycleTimeout*1000, CycleSaver, NULL);
460 if(smGD.coverScreen == True)
462 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
464 XtPopup(smDD.coverDialog[i], XtGrabNone);
469 * Add an event handler for when the keyboard and pointer are grabbed
471 XtAddEventHandler(grabWidget,
472 (KeyPressMask | ButtonPressMask | PointerMotionMask),
473 False, EventDetected, NULL);
475 /** wait 90 seconds for lock dialog to come up **/
476 lockTimeId = XtAppAddTimeOut(smGD.appCon,
477 90000, LockAttemptFailed, lockDlg);
483 /*************************************<->*************************************
490 * After the lock dialog is up - do the grab and lock the display
502 *************************************<->***********************************/
504 FinishLocking(Widget wid,
510 Boolean kbdGrabbed, pointerGrabbed;
513 if (lockTimeId == (XtIntervalId)0)
516 XtRemoveTimeOut(lockTimeId);
517 lockTimeId = (XtIntervalId)0;
518 XtRemoveEventHandler(wid, VisibilityChangeMask,
519 False, FinishLocking, NULL);
520 XSync(smGD.display, 0);
523 XtSetArg(uiArgs[i], XmNy, &visibleY);i++;
524 XtGetValues(wid, uiArgs, i);
526 hiddenY = (Position) DisplayHeight(smGD.display, smGD.screen) + 15;
529 * Color the cursor for this color scheme
533 XSync(smGD.display, 0);
536 * grab control of the keyboard for the entire display
538 rc = XtGrabKeyboard(grabWidget, False,
539 GrabModeAsync, GrabModeAsync,
541 kbdGrabbed = (rc == GrabSuccess);
543 #ifdef USE_HP_SPECIFIC_XLIB
544 XHPDisableReset(smGD.display);
545 #endif /* USE_HP_SPECIFIC_XLIB */
547 #if defined (AIXV3) && !defined(_POWER)
548 if(smGD.secureSystem)
550 SM_SETEUID(smGD.unLockUID);
552 SM_SETEUID(smGD.runningUID);
556 pointerGrabbed = (XtGrabPointer(grabWidget, False,
557 ButtonPressMask|PointerMotionMask,
558 GrabModeAsync, GrabModeAsync,
559 None, smGD.lockCursor, CurrentTime)
563 pointerGrabbed = (XtGrabPointer(grabWidget, False,
564 ButtonPressMask|PointerMotionMask,
565 GrabModeAsync, GrabModeAsync,
566 None, smGD.lockCursor, CurrentTime)
572 * If the grab failed - try 3 more times and give up
574 if((kbdGrabbed == False) || (pointerGrabbed == False))
576 for(j = 0;(j < 3) && ((pointerGrabbed == False) ||
577 (kbdGrabbed == False));j++)
580 * If a grab fails try one more time and then give up
582 if(kbdGrabbed == False)
585 kbdGrabbed = (XtGrabKeyboard(grabWidget, False,
586 GrabModeAsync, GrabModeAsync,
587 CurrentTime) == GrabSuccess);
590 if(pointerGrabbed == False)
593 pointerGrabbed = (XtGrabPointer(grabWidget, False,
598 None, smGD.lockCursor,
607 * Set status variable to lock if the lock has succeeded
609 if((pointerGrabbed != True) || (kbdGrabbed != True))
611 PrintError(DtError, smNLS.cantLockErrorString);
612 smGD.lockedState = UNLOCKED;
613 UnlockDisplay(pointerGrabbed, kbdGrabbed);
618 #ifdef LOCK_SERVER_ACCESS
620 * Wipe & enable X server access control list
622 hostList = XListHosts(smGD.display,
623 &hostListLen, (Bool *) &hostListActive);
624 XRemoveHosts(smGD.display, hostList, hostListLen);
625 XEnableAccessControl(smGD.display);
626 RestrictingAccess = True;
629 PutUpLogin(False, True); /* already mapped, but set timeout */
632 * Start external screen saver.
634 if (smGD.coverScreen)
644 /*************************************<->*************************************
646 * CreateLockCursor ()
651 * Creates a padlock cursor if the user has specified lock. Creates a
652 * blank cursor if the user has specified cover. Both are specified in the
653 * users resource file.
659 * buttonForm = widget from which cursor gets its color
660 * smGD.coverScreen = (global) cover screen or put up a padlock
666 * smGD.lockCursor = (global) cursor when lock is active (blank or padlock)
671 *************************************<->***********************************/
672 #define lock_m_hot_x 16
673 #define lock_m_hot_y 16
674 #define lock_m_bm_width 32
675 #define lock_m_bm_height 32
676 static unsigned char lock_m_bm_bits[] = {
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00,
678 0x00, 0xfc, 0x9f, 0x00, 0x00, 0x0e, 0x90, 0x01, 0x00, 0x06, 0x80, 0x01,
679 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01,
680 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01,
681 0x00, 0x06, 0x80, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c,
682 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
683 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f,
684 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
685 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f,
686 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
687 0xc0, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0x0f};
689 #define lock_m_m_bm_width 32
690 #define lock_m_m_bm_height 32
691 static unsigned char lock_m_m_bm_bits[] = {
692 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00,
693 0x00, 0xff, 0xff, 0x00, 0x80, 0x0f, 0xf0, 0x01, 0x80, 0x07, 0xe0, 0x01,
694 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01,
695 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01,
696 0x80, 0x07, 0xe0, 0x01, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
697 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
698 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
699 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
700 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
701 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
702 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f};
704 #define lock_s_hot_x 7
705 #define lock_s_hot_y 8
706 #define lock_s_bm_width 13
707 #define lock_s_bm_height 16
708 static unsigned char lock_s_bm_bits[] = {
709 0x00, 0x02, 0x00, 0x04, 0xf0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
710 0x00, 0x00, 0xa8, 0x1a, 0x54, 0x1d, 0xa8, 0x1a, 0x54, 0x1d, 0xa8, 0x1a,
711 0x54, 0x1d, 0xa8, 0x1a, 0x54, 0x1d, 0xfe, 0x1f};
713 #define lock_s_m_bm_width 13
714 #define lock_s_m_bm_height 16
715 static unsigned char lock_s_m_bm_bits[] = {
716 0xf8, 0x03, 0xfc, 0x07, 0xfe, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
717 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f,
718 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f};
721 CreateLockCursor( void )
724 Colormap cmap = XDefaultColormap(smGD.display, smGD.screen);
726 char noCursorBits = 0x1;
728 if(InitCursorInfo() == False)
731 * Create the SMALL padlock cursor
733 source = XCreateBitmapFromData(smGD.display,
734 XRootWindow(smGD.display,
736 (char *) lock_s_bm_bits,
739 mask = XCreateBitmapFromData(smGD.display,
740 XRootWindow(smGD.display,
742 (char *) lock_s_m_bm_bits,
746 /* translate the Pixels into XColors */
747 xcolors[0].pixel = smGD.blackPixel;
748 xcolors[1].pixel = smGD.whitePixel;
749 XQueryColors(smGD.display, cmap, xcolors, 2);
751 /* create the padlock cursor */
752 smGD.padlockCursor = XCreatePixmapCursor(smGD.display, source, mask,
753 &(xcolors[0]), &(xcolors[1]),
756 XFreePixmap(smGD.display, source);
757 XFreePixmap(smGD.display, mask);
762 * Create the LARGE padlock cursor
764 source = XCreateBitmapFromData(smGD.display,
765 XRootWindow(smGD.display,
767 (char *) lock_m_bm_bits,
770 mask = XCreateBitmapFromData(smGD.display,
771 XRootWindow(smGD.display,
773 (char *) lock_m_m_bm_bits,
777 /* translate the Pixels into XColors */
778 xcolors[0].pixel = smGD.blackPixel;
779 xcolors[1].pixel = smGD.whitePixel;
780 XQueryColors(smGD.display, cmap, xcolors, 2);
782 /* create the padlock cursor */
783 smGD.padlockCursor = XCreatePixmapCursor(smGD.display, source, mask,
784 &(xcolors[0]), &(xcolors[1]),
787 XFreePixmap(smGD.display, source);
788 XFreePixmap(smGD.display, mask);
793 * create the blank cursor
795 source = XCreateBitmapFromData(smGD.display,
796 XRootWindow(smGD.display, smGD.screen),
797 &noCursorBits, 1, 1);
799 xcolors[0].pixel = smGD.blackPixel;
800 XQueryColor(smGD.display, cmap, &(xcolors[0]));
801 smGD.blankCursor = XCreatePixmapCursor(smGD.display, source, source,
802 &(xcolors[0]), &(xcolors[0]),
804 XFreePixmap(smGD.display, source);
809 /*************************************<->*************************************
816 * Recolors the padlock cursor to be the current color scheme. This has
817 * to be done because XCreatePixmapCursor allocates colors instead of jusst
818 * using a pixel value.
824 * smGD.backgroundPix = Pixel value to use for background color
825 * smGD.foregroundPix = Pixel value to use for foreground color
830 * smGD.lockCursor = (global) cursor when lock is active (padlock)
835 *************************************<->***********************************/
837 RecolorCursor( void )
839 Colormap cmap = XDefaultColormap(smGD.display, smGD.screen);
843 * translate the Pixels into XColors
845 xcolors[0].pixel = smGD.foregroundPix;
846 xcolors[1].pixel = smGD.backgroundPix;
847 XQueryColors(smGD.display, cmap, xcolors, 2);
850 * recolor the padlock cursor
852 XRecolorCursor(smGD.display, smGD.lockCursor, &(xcolors[0]),
858 /*************************************<->*************************************
860 * EventDetected (w, client_data, event)
865 * Callback routine that detects an event when the display is locked.
866 * If it's a correct password, it unlocks the display. Otherwise, it
867 * just displays status. The event is detected by the popup login dialog.
872 * w = widget where event occured
873 * client_data = client specific data sent to callback
874 * event = event that triggered callback
883 *************************************<->***********************************/
887 XtPointer client_data,
893 XKeyEvent *event = (XKeyEvent *) ev;
895 if (smGD.lockedState == LOCKED)
897 if (lockDlgVisible == False)
900 * Anytime input is received - show the passwd dialog and
901 * discard event. This is so a keypress event that causes
902 * the passwd dialog to appear will not be used in the password.
905 PutUpLogin(True, True); /* map, and reset timeout */
908 PutUpLogin(False, True); /* already mapped, but reset timeout */
912 UnlockDisplay(True, True);
917 * If the detected event is anything but a keypress, processing is
918 * complete after refreshing the status string.
920 if (event->type != KeyPress)
924 * If XLookupString() returns anything (which it won't in the case of, say,
925 * pressing the shift key or an arrow key), process it.
927 #ifdef USE_HP_SPECIFIC_XLIB
928 if (len = XHPConvertLookup(event, str, sizeof(str), NULL, NULL,
929 XHPGetEurasianCvt(smGD.display)))
930 #else /* USE_HP_SPECIFIC_XLIB */
931 if (len = XLookupString (event, str, sizeof(str), NULL, NULL))
932 #endif /* USE_HP_SPECIFIC_XLIB */
934 if (smGD.lockedState == LOCKED)
935 CheckString(str, len);
941 /*************************************<->*************************************
948 * Check string entered by user. If it is a valid password, call routine to
949 * unlock the display. Otherwise, just keep track of what we have until
950 * the password is valid
955 * s = string passed in for checking
956 * i = length of string
965 *************************************<->***********************************/
973 * - Only the first eight characters are used.
974 * - If pw_length > 8, we've gone over eight characters and won't
976 * - An ESC kills the line.
979 static char passwd[82]; /* password space */
981 static char passwd[10]; /* password space */
983 static int pw_length = 0; /* password length */
1000 pw_length--; /* back up one character */
1004 pw_length = 0; /* kill the character string */
1020 passwd[pw_length] = '\0'; /* terminate string */
1021 pw_length = 0; /* reset length */
1022 if (CheckPassword(passwd))
1024 UpdatePasswdField(0);
1025 UnlockDisplay(True, True);
1028 XBell(smGD.display, 100); /* wrong, laserbreath */
1037 passwd[pw_length] = *s; /* store character */
1039 * The length is incremented no matter what, so the user can
1040 * think the program handles multi-thousand-character
1041 * passwords. If the user types twenty characters and eighteen
1042 * erases (#), the result will be the first two characters
1043 * entered, as expected. Up to a point -- 65536 is long
1046 if (pw_length < 65535)
1054 UpdatePasswdField(8);
1058 UpdatePasswdField(pw_length);
1064 /*************************************<->*************************************
1066 * CheckPassword (passwd)
1071 * Check the password to see if it is the user's, roots, or one of the
1072 * users specified in the host string
1077 * passwd = password passed in
1082 * True if it is a valid password, false otherwise.
1087 *************************************<->***********************************/
1095 if (Authenticate(NULL, getuid(), passwd) == True)
1097 return(True); /* user password ok */
1100 if (Authenticate(NULL, 0, passwd) == True)
1102 return(True); /* root password ok */
1105 /* check passwords of users specified as keyholders */
1106 if (smGD.keyholders == NULL)
1108 return(False); /* no keyholders */
1111 /* since strtok() is destructive, copy the keyholders string */
1112 keyholderbuf = (char *) SM_MALLOC(strlen(smGD.keyholders)+1);
1113 if(keyholderbuf == NULL)
1115 PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1116 return(False); /* no memory */
1119 strcpy(keyholderbuf, smGD.keyholders);
1120 for (p = keyholderbuf; (q = strtok(p, ", \t")) != NULL; p = NULL)
1122 if (Authenticate(q, -1, passwd) == True)
1124 SM_FREE(keyholderbuf);
1125 return(True); /* keyholder password ok */
1128 SM_FREE(keyholderbuf);
1130 return(False); /* no matches */
1135 /*************************************<->*************************************
1142 * If the user has entered a correct password, unlock the display and
1143 * uncover the root window.
1148 * pointerGrabbed - Boolean tells if pointer is currently grabbed
1149 * kbdGrabbed - Boolean tells if keyboard is currently grabbed
1159 *************************************<->***********************************/
1162 Boolean pointerGrabbed,
1168 #ifdef LOCK_SERVER_ACCESS
1170 * Restore X server access state
1172 if (RestrictingAccess) {
1173 XAddHosts(smGD.display, hostList, hostListLen);
1174 if (!hostListActive) XDisableAccessControl(smGD.display);
1175 RestrictingAccess = False;
1176 XFree((void *) hostList);
1181 * Stop external screen saver.
1186 * Remove the event handler to grab the events
1188 XtRemoveEventHandler(grabWidget,
1189 (KeyPressMask | ButtonPressMask | PointerMotionMask),
1190 False, EventDetected, NULL);
1195 if(lockDelayId != (XtIntervalId)0)
1197 XtRemoveTimeOut(lockDelayId);
1200 if(cycleId != (XtIntervalId)0)
1202 XtRemoveTimeOut(cycleId);
1205 if(timerId != (XtIntervalId)0)
1207 XtRemoveTimeOut(timerId);
1210 if(flash_id != (XtIntervalId)0)
1212 XtRemoveTimeOut(flash_id);
1215 if(pointerGrabbed == True)
1217 XtUngrabPointer(grabWidget, CurrentTime);
1220 if(kbdGrabbed == True)
1222 XtUngrabKeyboard(grabWidget, CurrentTime);
1225 #ifdef USE_HP_SPECIFIC_XLIB
1226 XHPEnableReset(smGD.display);
1227 #endif /* USE_HP_SPECIFIC_XLIB */
1229 #if defined (AIXV3) && !defined(_POWER)
1230 if(smGD.secureSystem)
1232 SM_SETEUID(smGD.unLockUID);
1233 AixEnableHftRing(1);
1234 SM_SETEUID(smGD.runningUID);
1238 XSync(smGD.display, 0);
1241 * Unmanage session lock dialogs. If LOCKDLG_PERSIST is undefined,
1242 * destroy them. This is so the passwd dialog icon colors get freed
1243 * since currently it uses a lot of colors.
1245 if(smGD.coverScreen == False)
1247 #if defined (LOCKDLG_PERSIST)
1248 if (XtIsManaged(smDD.lockDialog))
1250 XtUnmanageChild(smDD.lockDialog);
1253 XtDestroyWidget(smDD.lockDialog);
1254 smDD.lockDialog = NULL;
1259 #if defined (LOCKDLG_PERSIST)
1260 if(!XtIsManaged(smDD.lockCoverDialog))
1262 XtManageChild(smDD.lockCoverDialog);
1265 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1267 XtPopdown(smDD.coverDialog[i]);
1270 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1272 XtDestroyWidget(smDD.coverDialog[i]);
1273 smDD.coverDialog[i] = NULL;
1275 smDD.lockCoverDialog = NULL;
1279 smGD.lockedState = UNLOCKED;
1281 XSync(smGD.display, 0);
1284 * Tell the Workspace Manager to unlock the display (depress the lock
1286 if(smGD.bmsDead == False)
1288 msg = tttk_message_create(0, TT_REQUEST, TT_SESSION, 0,
1289 "Display_Unlock", 0);
1290 tt_message_send(msg);
1291 tt_message_destroy(msg);
1299 static Position visibleY = -1;
1300 static Position hiddenY = -1;
1303 /*************************************<->*************************************
1310 * When a timeout occurs - take down the login screen by unmanaging it.
1324 *************************************<->***********************************/
1327 XtPointer client_data,
1330 if (lockDlgVisible == True)
1332 if (smGD.coverScreen == True)
1334 XtUnmapWidget(smDD.lockCoverDialog);
1341 XtSetArg(uiArgs[i], XmNy, hiddenY);i++;
1342 XtSetValues(smDD.lockDialog, uiArgs, i);
1346 timerId = (XtIntervalId)0;
1349 * Clear partially entered password if any.
1351 CheckString(NULL, 0);
1352 lockDlgVisible = False;
1354 XSync(smGD.display, 0);
1359 /*************************************<->*************************************
1366 * Redisplays the cover and the login when neccessary.
1380 *************************************<->***********************************/
1386 if (map == True && lockDlgVisible == False)
1388 if (smGD.coverScreen == True)
1390 XtMapWidget(smDD.lockCoverDialog);
1397 XtSetArg(uiArgs[i], XmNy, visibleY);i++;
1398 XtSetValues(smDD.lockDialog, uiArgs, i);
1401 lockDlgVisible = True;
1404 if (timeout == True)
1406 if(timerId != (XtIntervalId)0)
1408 XtRemoveTimeOut(timerId);
1411 if(smRes.alarmTime > 0)
1413 timerId = XtAppAddTimeOut(smGD.appCon,
1414 (smRes.alarmTime * 1000),
1415 TakeDownLogin,NULL);
1418 XSync(smGD.display, 0);
1422 /*************************************<->*************************************
1424 * LockAttemptFailed ()
1429 * Timed out trying to get a visibilitynotify on the lock
1443 *************************************<->***********************************/
1445 LockAttemptFailed(XtPointer ptr,
1446 XtIntervalId *invId)
1448 Widget lockWid = (Widget) ptr;
1450 PrintError(DtError, smNLS.cantLockErrorString);
1451 smGD.lockedState = UNLOCKED;
1452 XtRemoveEventHandler(lockWid, VisibilityChangeMask,
1453 False, FinishLocking, NULL);
1454 UnlockDisplay(False, False);
1455 XSync(smGD.display, 0);
1461 /*************************************<->*************************************
1463 * RequirePassword ()
1468 * Callback indicating a password is now required to unlock display.
1482 *************************************<->***********************************/
1484 RequirePassword(XtPointer ptr,
1485 XtIntervalId *invId)
1487 smGD.lockedState = LOCKED;
1491 /*************************************<->*************************************
1498 * blinks the caret in the password field
1512 *************************************<->***********************************/
1514 BlinkCaret(XtPointer ptr,
1515 XtIntervalId *invId)
1517 static int flag = 1;
1522 * Blink cursor to show the focus ..
1525 tmpString = XmStringCreateLocalized (" " );
1527 XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1528 XtSetValues(ptr, uiArgs, i);
1532 tmpString = XmStringCreateLocalized ("|");
1534 XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1535 XtSetValues(ptr, uiArgs, i);
1539 XmStringFree(tmpString);
1540 flash_id = XtAppAddTimeOut(smGD.appCon, 1000,
1546 /*************************************<->*************************************
1553 * Callback indicating we should cycle to next screen saver
1567 *************************************<->***********************************/
1569 CycleSaver(XtPointer ptr,
1570 XtIntervalId *invId)
1573 * Stop running screen saver, start a new one and reset timer.
1577 cycleId = XtAppAddTimeOut(smGD.appCon, smSaverRes.cycleTimeout*1000,
1583 /*************************************<->*************************************
1585 * localAuthenticate (name, uid, passwd)
1602 *************************************<->***********************************/
1613 char *Argv[2] = { "dtsession", NULL };
1615 SIAENTITY *se = NULL;
1621 real_uid = getuid();
1623 if (-1 == seteuid(0))
1630 * Caller just checking if it is possible to access
1631 * password file (ie is dtsession suid bit set properly).
1636 if (name && name[0])
1641 pw_name = getlogin();
1644 if ( sia_ses_init(&se, 1, Argv, (char *)NULL,
1645 pw_name, NULL, 0 /* don't collect info */,
1646 NULL) != SIASUCCESS)
1652 se->password = (char *)malloc(strlen(passwd) + 1);
1653 if ( se->password == (char *)NULL )
1655 sia_ses_release(&se);
1660 strcpy(se->password, passwd);
1662 code = sia_ses_reauthent (NULL, se);
1663 sia_ses_release(&se);
1667 if ( code == SIASUCCESS )
1673 #elif defined(linux)
1676 struct passwd *pwent = NULL;
1680 Boolean done = False;
1681 struct spwd *sp = NULL;
1683 if(smGD.secureSystem)
1685 SM_SETEUID(smGD.unLockUID);
1689 * Get password entry for 'name' or 'uid'.
1691 if (CanReAuthenticate(name, uid, passwd, &pwent, &sp) == False)
1700 if(smGD.secureSystem)
1702 SM_SETEUID(smGD.runningUID);
1708 if (pwent->pw_passwd == NULL || pwent->pw_passwd[0] == '*')
1711 if (sp == NULL || sp->sp_pwdp == NULL)
1714 * Could not read password.
1727 * Caller just checking if it is possible to access
1728 * password file (ie is dtsession suid bit set properly).
1741 if (sp != NULL && !strcmp(sp->sp_pwdp, crypt(passwd,sp->sp_pwdp)))
1742 { /* a shadow match */
1746 else if (pwent != NULL &&
1747 !strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)))
1748 { /* passwd match */
1753 { /* failure dude! */
1768 register struct passwd *pwent;
1772 Boolean done = False;
1778 char *upasswd, *newname = NULL;
1780 struct spwd *sp=NULL;
1784 if(smGD.secureSystem)
1786 SM_SETEUID(smGD.unLockUID);
1791 * Get shadow password entry for 'name' or 'uid'.
1795 pwent = getpwuid(uid);
1799 name = newname = strdup(pwent->pw_name);
1801 name = pwent->pw_name;
1808 ia_openinfo(name, &uinfo)
1810 (sp = getspnam(name)) == NULL
1822 * Get password entry for 'name' or 'uid'.
1824 if ((pwent = (name == NULL ? getpwuid(uid) : getpwnam(name))) == NULL)
1834 if(smGD.secureSystem)
1836 SM_SETEUID(smGD.runningUID);
1842 ia_get_logpwd(uinfo, &upasswd);
1845 pwent->pw_passwd == NULL
1846 || pwent->pw_passwd[0] == '*'
1857 * Could not read password.
1869 * Caller just checking if it is possible to access
1870 * password file (ie is dtsession suid bit set properly).
1884 if (strcmp(crypt(passwd, upasswd), upasswd) != 0)
1886 if (strcmp(crypt(passwd,sp->sp_pwdp),sp->sp_pwdp) != 0)
1889 if (strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)) != 0)
1893 * Password incorrect.
1903 ia_closeinfo(uinfo);
1904 if (newname) free(newname);
1915 /*************************************<->*************************************
1917 * Authenticate (name, uid, passwd)
1934 *************************************<->***********************************/
1936 #if defined (_AIX) && defined(_POWER)
1944 register struct passwd *pwent;
1948 Boolean done = False;
1952 char *newname = NULL;
1955 if(smGD.secureSystem)
1957 SM_SETEUID(smGD.unLockUID);
1965 pwent = getpwuid(uid);
1968 name = newname = strdup(pwent->pw_name);
1974 * Authenticate user. Note: normally, we should check 'reenter' to
1975 * see if the user has another challenge. Since the dtsession screen
1976 * lock i/f does not yet have the support, our policy is to let the
1977 * user back in if they pass the first (password) challenge.
1979 arc = authenticate(name, passwd, &reenter, &msg);
1981 if(smGD.secureSystem)
1983 SM_SETEUID(smGD.runningUID);
1987 if (newname) free(newname);
1989 return(arc == 0 ? True : False);
1991 #endif /* _AIX && _POWER */