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>
95 #include "SmGlobals.h"
102 * Variables global to this module only
108 static XtIntervalId timerId, lockTimeId, lockDelayId, cycleId, flash_id;
113 static Widget grabWidget;
116 * Lock dialog visibility
118 static Boolean lockDlgVisible;
120 #ifdef LOCK_SERVER_ACCESS
122 * Server Access Control Information
124 static Boolean RestrictingAccess = False;
125 static XHostAddress *hostList;
126 static Bool hostListActive;
127 static int hostListLen;
134 static void FinishLocking(Widget, XtPointer, XEvent *, Boolean *);
135 static void RecolorCursor( void ) ;
136 static void EventDetected( Widget, XtPointer, XEvent *, Boolean *) ;
137 static void CheckString( char *, int ) ;
138 static Boolean CheckPassword( char * ) ;
139 #if defined (_AIX) && defined (_POWER)
140 static Boolean Authenticate( char *, uid_t, char * ) ;
142 #define Authenticate(A,B,C) localAuthenticate(A,B,C)
144 static Boolean localAuthenticate( char *, uid_t, char * ) ;
145 static void UnlockDisplay( Boolean, Boolean ) ;
146 static void TakeDownLogin( XtPointer, XtIntervalId * ) ;
147 static void PutUpLogin( Boolean, Boolean ) ;
148 static void LockAttemptFailed( XtPointer, XtIntervalId *) ;
149 static void RequirePassword( XtPointer, XtIntervalId *) ;
150 static void CycleSaver( XtPointer, XtIntervalId *) ;
151 static void BlinkCaret( XtPointer, XtIntervalId *) ;
154 /* #define JET_AUTHDEBUG */
156 /* Test for re-auth ability - see if we can re-authenticate via pwd,
159 static Boolean CanReAuthenticate(char *name, uid_t uid, char *passwd,
160 struct passwd **pwent, struct spwd **spent)
162 Boolean fail = False;
164 *pwent = (name == NULL) ? getpwuid(uid) : getpwnam(name);
166 *spent = getspnam((*pwent)->pw_name);
169 fprintf(stderr, "CanReAuthenticate(): %s %s %s\n",
170 (*pwent) ? "PWENT" : "NULL",
171 (*spent) ? "SPENT" : "NULL",
172 (name) ? name : "NULL");
175 /* some checking for aging stuff on RedPhat */
177 if (*pwent && (*pwent)->pw_passwd)
181 if ((loc = strchr((*pwent)->pw_passwd, ',')) != NULL)
184 fprintf(stderr, "CanReAuthenticate(): pw: '%s'\n",
185 (*pwent)->pw_passwd);
190 if (*spent && (*spent)->sp_pwdp)
194 if ((loc = strchr((*spent)->sp_pwdp, ',')) != NULL)
199 { /* if we can't get this, we're screwed. */
201 fprintf(stderr, "CanReAuthenticate(): PWENT == NULL - FALSE\n");
206 if ((*pwent)->pw_passwd == NULL)
209 fprintf(stderr, "CanReAuthenticate(): (*pwent)->pw_passwd == NULL - FALSE\n");
215 /* ok, now we have the prequisite data, look first to see if the
216 * passwd field is larger than 1 char - implying NIS, or a shadowed
217 * system. if not look for *spent being non-NULL
220 { /* if it's null, lets check for the NIS case */
221 if (strlen((*pwent)->pw_passwd) <= 1)
224 fprintf(stderr, "strlen((*pwent)->pw_passwd) <= 1\n");
227 return False; /* not NIS */
231 /* supposedly we have valid data */
233 fprintf(stderr, "CanReAuthenticate(): TRUE\n");
244 /*************************************<->*************************************
251 * Calls the routines that are in charge of locking the display.
256 * lockNow - request to lock the display immediately
264 *************************************<->***********************************/
266 * Place holders for the lock position
268 static Position visibleY;
269 static Position hiddenY;
277 Widget parent = NULL, lockDlg;
284 timerId = lockTimeId = lockDelayId = cycleId = flash_id = (XtIntervalId)0;
288 * 0 - screen will not be covered, nor will external screen saver run
289 * 1 - screen will be covered, external screen saver may be run
292 * -1 = no password required to unlock display
293 * 0 = password always required to unlock display
294 * N = password required to unlock display after N seconds
296 if (smSaverRes.saverTimeout == 0)
298 smGD.coverScreen = 0;
301 else if (lockNow || smSaverRes.lockTimeout > 0)
303 smGD.coverScreen = 1;
306 else if (smSaverRes.lockTimeout == 0)
308 else if (smSaverRes.lockTimeout <= smSaverRes.saverTimeout)
311 lockDelay = smSaverRes.lockTimeout - smSaverRes.saverTimeout;
315 smGD.coverScreen = 1;
320 * Before anything is done make sure we can unlock if we lock.
322 if (localAuthenticate(NULL, getuid(), NULL) == False)
325 PrintError(DtError, smNLS.trustedSystemErrorString);
327 XBell(smGD.display, 100);
330 * Tell the Workspace Manager to quit blinking
332 msg = tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
333 "DtActivity_Began", 0 );
334 tt_message_send( msg );
335 tt_message_destroy( msg );
341 if(((smDD.lockCoverDialog == NULL) && (smGD.coverScreen == True)) ||
342 ((smDD.lockDialog == NULL) && (smGD.coverScreen == False)))
345 * Set up the grab widget in here
350 * If the user has specified cover - create the cover dialog
352 screenNum = DefaultScreen(smGD.display);
353 if(smGD.coverScreen == True)
355 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
359 smDD.coverDialog[i] = CreateCoverDialog(i, True);
360 parent = smDD.coverDrawing[i];
364 smDD.coverDialog[i] = CreateCoverDialog(i, False);
367 smDD.lockCoverDialog = CreateLockDialogWithCover(parent);
371 * Create the lock dialog if the user has specified that
373 if((smDD.lockDialog == NULL) && (smGD.coverScreen == False))
375 smDD.lockDialog = CreateLockDialog();
378 * Get colors for the password cursor
381 XtSetArg(uiArgs[i], XmNtopShadowColor, &(xcolors[0]));i++;
382 XtSetArg(uiArgs[i], XmNbottomShadowColor, &(xcolors[1]));i++;
383 XtGetValues(smDD.lockDialog, uiArgs, i);
385 smGD.backgroundPix = xcolors[0].pixel;
386 smGD.foregroundPix = xcolors[1].pixel;
387 if (smGD.backgroundPix == smGD.foregroundPix)
389 smGD.backgroundPix = smGD.whitePixel;
390 smGD.foregroundPix = smGD.blackPixel;
396 * Wait for a visibility event to occur on the window so that
399 if(smGD.coverScreen == True)
401 smGD.lockCursor = smGD.blankCursor;
402 grabWidget = smDD.coverDialog[0];
403 lockDlg = smDD.lockCoverDialog;
404 lockDlgVisible = False; /* mappedWhenManaged False */
408 smGD.lockCursor = smGD.padlockCursor;
409 grabWidget = smDD.lockDialog;
410 lockDlg = smDD.lockDialog;
411 visibleY = hiddenY = -1;
415 * Note: grabWidget must be mapped in order to grab it. This means
416 * that if coverScreen is True, smDD.coverDialog[0] must be mapped
417 * immediately and if coverScreen is False, smDD.lockDialog must be
418 * mapped immediately. Also, if a grabWidget is unmapped, the grab
421 XtAddEventHandler(grabWidget, VisibilityChangeMask,
422 False, FinishLocking, NULL);
424 XtManageChild(lockDlg);
426 if(smGD.coverScreen == True) {
427 flash_id = XtAppAddTimeOut(smGD.appCon,
428 1000, BlinkCaret,smDD.indLabel[1]);
431 flash_id = XtAppAddTimeOut(smGD.appCon,
432 1000, BlinkCaret,smDD.indLabel[0]);
438 * Wait for 'lockDelay' seconds before requiring a password.
440 lockDelayId = XtAppAddTimeOut(smGD.appCon,
441 lockDelay*1000, RequirePassword, NULL);
444 else if (lockDelay == 0)
447 * Immediately require a password to unlock the display.
449 smGD.lockedState = LOCKED;
450 PutUpLogin(True, False); /* map, but don't set timeout */
453 if (smGD.coverScreen == True && smSaverRes.cycleTimeout > 0)
456 * Cycle to next saver in 'cycleTimeout' seconds.
458 cycleId = XtAppAddTimeOut(smGD.appCon,
459 smSaverRes.cycleTimeout*1000, CycleSaver, NULL);
462 if(smGD.coverScreen == True)
464 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
466 XtPopup(smDD.coverDialog[i], XtGrabNone);
471 * Add an event handler for when the keyboard and pointer are grabbed
473 XtAddEventHandler(grabWidget,
474 (KeyPressMask | ButtonPressMask | PointerMotionMask),
475 False, EventDetected, NULL);
477 /** wait 90 seconds for lock dialog to come up **/
478 lockTimeId = XtAppAddTimeOut(smGD.appCon,
479 90000, LockAttemptFailed, lockDlg);
485 /*************************************<->*************************************
492 * After the lock dialog is up - do the grab and lock the display
504 *************************************<->***********************************/
506 FinishLocking(Widget wid,
512 Boolean kbdGrabbed, pointerGrabbed;
515 if (lockTimeId == (XtIntervalId)0)
518 XtRemoveTimeOut(lockTimeId);
519 lockTimeId = (XtIntervalId)0;
520 XtRemoveEventHandler(wid, VisibilityChangeMask,
521 False, FinishLocking, NULL);
522 XSync(smGD.display, 0);
525 XtSetArg(uiArgs[i], XmNy, &visibleY);i++;
526 XtGetValues(wid, uiArgs, i);
528 hiddenY = (Position) DisplayHeight(smGD.display, smGD.screen) + 15;
531 * Color the cursor for this color scheme
535 XSync(smGD.display, 0);
538 * grab control of the keyboard for the entire display
540 rc = XtGrabKeyboard(grabWidget, False,
541 GrabModeAsync, GrabModeAsync,
543 kbdGrabbed = (rc == GrabSuccess);
545 #ifdef USE_HP_SPECIFIC_XLIB
546 XHPDisableReset(smGD.display);
547 #endif /* USE_HP_SPECIFIC_XLIB */
549 #if defined (AIXV3) && !defined(_POWER)
550 if(smGD.secureSystem)
552 SM_SETEUID(smGD.unLockUID);
554 SM_SETEUID(smGD.runningUID);
558 pointerGrabbed = (XtGrabPointer(grabWidget, False,
559 ButtonPressMask|PointerMotionMask,
560 GrabModeAsync, GrabModeAsync,
561 None, smGD.lockCursor, CurrentTime)
565 pointerGrabbed = (XtGrabPointer(grabWidget, False,
566 ButtonPressMask|PointerMotionMask,
567 GrabModeAsync, GrabModeAsync,
568 None, smGD.lockCursor, CurrentTime)
574 * If the grab failed - try 3 more times and give up
576 if((kbdGrabbed == False) || (pointerGrabbed == False))
578 for(j = 0;(j < 3) && ((pointerGrabbed == False) ||
579 (kbdGrabbed == False));j++)
582 * If a grab fails try one more time and then give up
584 if(kbdGrabbed == False)
587 kbdGrabbed = (XtGrabKeyboard(grabWidget, False,
588 GrabModeAsync, GrabModeAsync,
589 CurrentTime) == GrabSuccess);
592 if(pointerGrabbed == False)
595 pointerGrabbed = (XtGrabPointer(grabWidget, False,
600 None, smGD.lockCursor,
609 * Set status variable to lock if the lock has succeeded
611 if((pointerGrabbed != True) || (kbdGrabbed != True))
613 PrintError(DtError, smNLS.cantLockErrorString);
614 smGD.lockedState = UNLOCKED;
615 UnlockDisplay(pointerGrabbed, kbdGrabbed);
620 #ifdef LOCK_SERVER_ACCESS
622 * Wipe & enable X server access control list
624 hostList = XListHosts(smGD.display,
625 &hostListLen, (Bool *) &hostListActive);
626 XRemoveHosts(smGD.display, hostList, hostListLen);
627 XEnableAccessControl(smGD.display);
628 RestrictingAccess = True;
631 PutUpLogin(False, True); /* already mapped, but set timeout */
634 * Start external screen saver.
636 if (smGD.coverScreen)
646 /*************************************<->*************************************
648 * CreateLockCursor ()
653 * Creates a padlock cursor if the user has specified lock. Creates a
654 * blank cursor if the user has specified cover. Both are specified in the
655 * users resource file.
661 * buttonForm = widget from which cursor gets its color
662 * smGD.coverScreen = (global) cover screen or put up a padlock
668 * smGD.lockCursor = (global) cursor when lock is active (blank or padlock)
673 *************************************<->***********************************/
674 #define lock_m_hot_x 16
675 #define lock_m_hot_y 16
676 #define lock_m_bm_width 32
677 #define lock_m_bm_height 32
678 static unsigned char lock_m_bm_bits[] = {
679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00,
680 0x00, 0xfc, 0x9f, 0x00, 0x00, 0x0e, 0x90, 0x01, 0x00, 0x06, 0x80, 0x01,
681 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01,
682 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01,
683 0x00, 0x06, 0x80, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c,
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 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f,
688 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
689 0xc0, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0x0f};
691 #define lock_m_m_bm_width 32
692 #define lock_m_m_bm_height 32
693 static unsigned char lock_m_m_bm_bits[] = {
694 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00,
695 0x00, 0xff, 0xff, 0x00, 0x80, 0x0f, 0xf0, 0x01, 0x80, 0x07, 0xe0, 0x01,
696 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01,
697 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01,
698 0x80, 0x07, 0xe0, 0x01, 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, 0xf0, 0xff, 0xff, 0x0f,
703 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
704 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f};
706 #define lock_s_hot_x 7
707 #define lock_s_hot_y 8
708 #define lock_s_bm_width 13
709 #define lock_s_bm_height 16
710 static unsigned char lock_s_bm_bits[] = {
711 0x00, 0x02, 0x00, 0x04, 0xf0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
712 0x00, 0x00, 0xa8, 0x1a, 0x54, 0x1d, 0xa8, 0x1a, 0x54, 0x1d, 0xa8, 0x1a,
713 0x54, 0x1d, 0xa8, 0x1a, 0x54, 0x1d, 0xfe, 0x1f};
715 #define lock_s_m_bm_width 13
716 #define lock_s_m_bm_height 16
717 static unsigned char lock_s_m_bm_bits[] = {
718 0xf8, 0x03, 0xfc, 0x07, 0xfe, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
719 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f,
720 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f};
723 CreateLockCursor( void )
726 Colormap cmap = XDefaultColormap(smGD.display, smGD.screen);
728 char noCursorBits = 0x1;
730 if(InitCursorInfo() == False)
733 * Create the SMALL padlock cursor
735 source = XCreateBitmapFromData(smGD.display,
736 XRootWindow(smGD.display,
738 (char *) lock_s_bm_bits,
741 mask = XCreateBitmapFromData(smGD.display,
742 XRootWindow(smGD.display,
744 (char *) lock_s_m_bm_bits,
748 /* translate the Pixels into XColors */
749 xcolors[0].pixel = smGD.blackPixel;
750 xcolors[1].pixel = smGD.whitePixel;
751 XQueryColors(smGD.display, cmap, xcolors, 2);
753 /* create the padlock cursor */
754 smGD.padlockCursor = XCreatePixmapCursor(smGD.display, source, mask,
755 &(xcolors[0]), &(xcolors[1]),
758 XFreePixmap(smGD.display, source);
759 XFreePixmap(smGD.display, mask);
764 * Create the LARGE padlock cursor
766 source = XCreateBitmapFromData(smGD.display,
767 XRootWindow(smGD.display,
769 (char *) lock_m_bm_bits,
772 mask = XCreateBitmapFromData(smGD.display,
773 XRootWindow(smGD.display,
775 (char *) lock_m_m_bm_bits,
779 /* translate the Pixels into XColors */
780 xcolors[0].pixel = smGD.blackPixel;
781 xcolors[1].pixel = smGD.whitePixel;
782 XQueryColors(smGD.display, cmap, xcolors, 2);
784 /* create the padlock cursor */
785 smGD.padlockCursor = XCreatePixmapCursor(smGD.display, source, mask,
786 &(xcolors[0]), &(xcolors[1]),
789 XFreePixmap(smGD.display, source);
790 XFreePixmap(smGD.display, mask);
795 * create the blank cursor
797 source = XCreateBitmapFromData(smGD.display,
798 XRootWindow(smGD.display, smGD.screen),
799 &noCursorBits, 1, 1);
801 xcolors[0].pixel = smGD.blackPixel;
802 XQueryColor(smGD.display, cmap, &(xcolors[0]));
803 smGD.blankCursor = XCreatePixmapCursor(smGD.display, source, source,
804 &(xcolors[0]), &(xcolors[0]),
806 XFreePixmap(smGD.display, source);
811 /*************************************<->*************************************
818 * Recolors the padlock cursor to be the current color scheme. This has
819 * to be done because XCreatePixmapCursor allocates colors instead of jusst
820 * using a pixel value.
826 * smGD.backgroundPix = Pixel value to use for background color
827 * smGD.foregroundPix = Pixel value to use for foreground color
832 * smGD.lockCursor = (global) cursor when lock is active (padlock)
837 *************************************<->***********************************/
839 RecolorCursor( void )
841 Colormap cmap = XDefaultColormap(smGD.display, smGD.screen);
845 * translate the Pixels into XColors
847 xcolors[0].pixel = smGD.foregroundPix;
848 xcolors[1].pixel = smGD.backgroundPix;
849 XQueryColors(smGD.display, cmap, xcolors, 2);
852 * recolor the padlock cursor
854 XRecolorCursor(smGD.display, smGD.lockCursor, &(xcolors[0]),
860 /*************************************<->*************************************
862 * EventDetected (w, client_data, event)
867 * Callback routine that detects an event when the display is locked.
868 * If it's a correct password, it unlocks the display. Otherwise, it
869 * just displays status. The event is detected by the popup login dialog.
874 * w = widget where event occured
875 * client_data = client specific data sent to callback
876 * event = event that triggered callback
885 *************************************<->***********************************/
889 XtPointer client_data,
895 XKeyEvent *event = (XKeyEvent *) ev;
897 if (smGD.lockedState == LOCKED)
899 if (lockDlgVisible == False)
902 * Anytime input is received - show the passwd dialog and
903 * discard event. This is so a keypress event that causes
904 * the passwd dialog to appear will not be used in the password.
907 PutUpLogin(True, True); /* map, and reset timeout */
910 PutUpLogin(False, True); /* already mapped, but reset timeout */
914 UnlockDisplay(True, True);
919 * If the detected event is anything but a keypress, processing is
920 * complete after refreshing the status string.
922 if (event->type != KeyPress)
926 * If XLookupString() returns anything (which it won't in the case of, say,
927 * pressing the shift key or an arrow key), process it.
929 #ifdef USE_HP_SPECIFIC_XLIB
930 if (len = XHPConvertLookup(event, str, sizeof(str), NULL, NULL,
931 XHPGetEurasianCvt(smGD.display)))
932 #else /* USE_HP_SPECIFIC_XLIB */
933 if (len = XLookupString (event, str, sizeof(str), NULL, NULL))
934 #endif /* USE_HP_SPECIFIC_XLIB */
936 if (smGD.lockedState == LOCKED)
937 CheckString(str, len);
943 /*************************************<->*************************************
950 * Check string entered by user. If it is a valid password, call routine to
951 * unlock the display. Otherwise, just keep track of what we have until
952 * the password is valid
957 * s = string passed in for checking
958 * i = length of string
967 *************************************<->***********************************/
973 /* maximum supported length of password */
975 #define MAX_PASSWORD_LENGTH SIAMXPASSWORD
977 /* seems to be reasonable maximal length */
978 #define MAX_PASSWORD_LENGTH 65535
981 /* step when allocating/extending buffer */
982 #define BUF_ALLOC_LEN 64
986 * - If pw_length > MAX_PASSWORD_LENGTH, we've gone over the limit and won't
988 * - An ESC kills the line.
990 static char *passwd = NULL; /* password space */
991 static int pw_buf_length = 0; /* length of allocated password buffer */
992 static int pw_length = 0; /* password length */
1003 for (; i>0; s++,i--)
1005 /* extend buffer by BUF_ALLOC_LEN bytes if needed*/
1006 #ifdef JET_AUTHDEBUG
1007 fprintf(stderr, "CheckString: pw_length=%d\n",pw_length);
1010 if (pw_length == pw_buf_length)
1012 tmpptr = SM_REALLOC(passwd, pw_buf_length + BUF_ALLOC_LEN);
1014 PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1017 pw_buf_length += BUF_ALLOC_LEN;
1024 pw_length--; /* back up one character */
1028 pw_length = 0; /* kill the character string */
1033 if (pw_length > MAX_PASSWORD_LENGTH)
1035 pw_length = MAX_PASSWORD_LENGTH;
1037 passwd[pw_length] = '\0'; /* terminate string */
1038 pw_length = 0; /* reset length */
1039 if (CheckPassword(passwd))
1041 UpdatePasswdField(0);
1042 UnlockDisplay(True, True);
1045 XBell(smGD.display, 100); /* wrong, laserbreath */
1049 if (pw_length < MAX_PASSWORD_LENGTH)
1051 passwd[pw_length++] = *s; /* store character */
1056 UpdatePasswdField(pw_length > MAX_PASSWORD_LENGTH ? MAX_PASSWORD_LENGTH : pw_length);
1061 /*************************************<->*************************************
1063 * CheckPassword (passwd)
1068 * Check the password to see if it is the user's, roots, or one of the
1069 * users specified in the host string
1074 * passwd = password passed in
1079 * True if it is a valid password, false otherwise.
1084 *************************************<->***********************************/
1092 if (Authenticate(NULL, getuid(), passwd) == True)
1094 return(True); /* user password ok */
1097 if (Authenticate(NULL, 0, passwd) == True)
1099 return(True); /* root password ok */
1102 /* check passwords of users specified as keyholders */
1103 if (smGD.keyholders == NULL)
1105 return(False); /* no keyholders */
1108 /* since strtok() is destructive, copy the keyholders string */
1109 keyholderbuf = (char *) SM_MALLOC(strlen(smGD.keyholders)+1);
1110 if(keyholderbuf == NULL)
1112 PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1113 return(False); /* no memory */
1116 strcpy(keyholderbuf, smGD.keyholders);
1117 for (p = keyholderbuf; (q = strtok(p, ", \t")) != NULL; p = NULL)
1119 if (Authenticate(q, -1, passwd) == True)
1121 SM_FREE(keyholderbuf);
1122 return(True); /* keyholder password ok */
1125 SM_FREE(keyholderbuf);
1127 return(False); /* no matches */
1132 /*************************************<->*************************************
1139 * If the user has entered a correct password, unlock the display and
1140 * uncover the root window.
1145 * pointerGrabbed - Boolean tells if pointer is currently grabbed
1146 * kbdGrabbed - Boolean tells if keyboard is currently grabbed
1156 *************************************<->***********************************/
1159 Boolean pointerGrabbed,
1165 #ifdef LOCK_SERVER_ACCESS
1167 * Restore X server access state
1169 if (RestrictingAccess) {
1170 XAddHosts(smGD.display, hostList, hostListLen);
1171 if (!hostListActive) XDisableAccessControl(smGD.display);
1172 RestrictingAccess = False;
1173 XFree((void *) hostList);
1178 * Stop external screen saver.
1183 * Remove the event handler to grab the events
1185 XtRemoveEventHandler(grabWidget,
1186 (KeyPressMask | ButtonPressMask | PointerMotionMask),
1187 False, EventDetected, NULL);
1192 if(lockDelayId != (XtIntervalId)0)
1194 XtRemoveTimeOut(lockDelayId);
1197 if(cycleId != (XtIntervalId)0)
1199 XtRemoveTimeOut(cycleId);
1202 if(timerId != (XtIntervalId)0)
1204 XtRemoveTimeOut(timerId);
1207 if(flash_id != (XtIntervalId)0)
1209 XtRemoveTimeOut(flash_id);
1212 if(pointerGrabbed == True)
1214 XtUngrabPointer(grabWidget, CurrentTime);
1217 if(kbdGrabbed == True)
1219 XtUngrabKeyboard(grabWidget, CurrentTime);
1222 #ifdef USE_HP_SPECIFIC_XLIB
1223 XHPEnableReset(smGD.display);
1224 #endif /* USE_HP_SPECIFIC_XLIB */
1226 #if defined (AIXV3) && !defined(_POWER)
1227 if(smGD.secureSystem)
1229 SM_SETEUID(smGD.unLockUID);
1230 AixEnableHftRing(1);
1231 SM_SETEUID(smGD.runningUID);
1235 XSync(smGD.display, 0);
1238 * Unmanage session lock dialogs. If LOCKDLG_PERSIST is undefined,
1239 * destroy them. This is so the passwd dialog icon colors get freed
1240 * since currently it uses a lot of colors.
1242 if(smGD.coverScreen == False)
1244 #if defined (LOCKDLG_PERSIST)
1245 if (XtIsManaged(smDD.lockDialog))
1247 XtUnmanageChild(smDD.lockDialog);
1250 XtDestroyWidget(smDD.lockDialog);
1251 smDD.lockDialog = NULL;
1256 #if defined (LOCKDLG_PERSIST)
1257 if(!XtIsManaged(smDD.lockCoverDialog))
1259 XtManageChild(smDD.lockCoverDialog);
1262 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1264 XtPopdown(smDD.coverDialog[i]);
1267 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1269 XtDestroyWidget(smDD.coverDialog[i]);
1270 smDD.coverDialog[i] = NULL;
1272 smDD.lockCoverDialog = NULL;
1276 smGD.lockedState = UNLOCKED;
1278 XSync(smGD.display, 0);
1281 * Tell the Workspace Manager to unlock the display (depress the lock
1283 if(smGD.bmsDead == False)
1285 msg = tttk_message_create(0, TT_REQUEST, TT_SESSION, 0,
1286 "Display_Unlock", 0);
1287 tt_message_send(msg);
1288 tt_message_destroy(msg);
1296 static Position visibleY = -1;
1297 static Position hiddenY = -1;
1300 /*************************************<->*************************************
1307 * When a timeout occurs - take down the login screen by unmanaging it.
1321 *************************************<->***********************************/
1324 XtPointer client_data,
1327 if (lockDlgVisible == True)
1329 if (smGD.coverScreen == True)
1331 XtUnmapWidget(smDD.lockCoverDialog);
1338 XtSetArg(uiArgs[i], XmNy, hiddenY);i++;
1339 XtSetValues(smDD.lockDialog, uiArgs, i);
1343 timerId = (XtIntervalId)0;
1346 * Clear partially entered password if any.
1348 CheckString(NULL, 0);
1349 lockDlgVisible = False;
1351 XSync(smGD.display, 0);
1356 /*************************************<->*************************************
1363 * Redisplays the cover and the login when neccessary.
1377 *************************************<->***********************************/
1383 if (map == True && lockDlgVisible == False)
1385 if (smGD.coverScreen == True)
1387 XtMapWidget(smDD.lockCoverDialog);
1394 XtSetArg(uiArgs[i], XmNy, visibleY);i++;
1395 XtSetValues(smDD.lockDialog, uiArgs, i);
1398 lockDlgVisible = True;
1401 if (timeout == True)
1403 if(timerId != (XtIntervalId)0)
1405 XtRemoveTimeOut(timerId);
1408 if(smRes.alarmTime > 0)
1410 timerId = XtAppAddTimeOut(smGD.appCon,
1411 (smRes.alarmTime * 1000),
1412 TakeDownLogin,NULL);
1415 XSync(smGD.display, 0);
1419 /*************************************<->*************************************
1421 * LockAttemptFailed ()
1426 * Timed out trying to get a visibilitynotify on the lock
1440 *************************************<->***********************************/
1442 LockAttemptFailed(XtPointer ptr,
1443 XtIntervalId *invId)
1445 Widget lockWid = (Widget) ptr;
1447 PrintError(DtError, smNLS.cantLockErrorString);
1448 smGD.lockedState = UNLOCKED;
1449 XtRemoveEventHandler(lockWid, VisibilityChangeMask,
1450 False, FinishLocking, NULL);
1451 UnlockDisplay(False, False);
1452 XSync(smGD.display, 0);
1458 /*************************************<->*************************************
1460 * RequirePassword ()
1465 * Callback indicating a password is now required to unlock display.
1479 *************************************<->***********************************/
1481 RequirePassword(XtPointer ptr,
1482 XtIntervalId *invId)
1484 smGD.lockedState = LOCKED;
1488 /*************************************<->*************************************
1495 * blinks the caret in the password field
1509 *************************************<->***********************************/
1511 BlinkCaret(XtPointer ptr,
1512 XtIntervalId *invId)
1514 static int flag = 1;
1519 * Blink cursor to show the focus ..
1522 tmpString = XmStringCreateLocalized (" " );
1524 XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1525 XtSetValues(ptr, uiArgs, i);
1529 tmpString = XmStringCreateLocalized ("|");
1531 XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1532 XtSetValues(ptr, uiArgs, i);
1536 XmStringFree(tmpString);
1537 flash_id = XtAppAddTimeOut(smGD.appCon, 1000,
1543 /*************************************<->*************************************
1550 * Callback indicating we should cycle to next screen saver
1564 *************************************<->***********************************/
1566 CycleSaver(XtPointer ptr,
1567 XtIntervalId *invId)
1570 * Stop running screen saver, start a new one and reset timer.
1574 cycleId = XtAppAddTimeOut(smGD.appCon, smSaverRes.cycleTimeout*1000,
1580 /*************************************<->*************************************
1582 * localAuthenticate (name, uid, passwd)
1599 *************************************<->***********************************/
1610 char *Argv[2] = { "dtsession", NULL };
1612 SIAENTITY *se = NULL;
1618 real_uid = getuid();
1620 if (-1 == seteuid(0))
1627 * Caller just checking if it is possible to access
1628 * password file (ie is dtsession suid bit set properly).
1633 if (name && name[0])
1638 pw_name = getlogin();
1641 if ( sia_ses_init(&se, 1, Argv, (char *)NULL,
1642 pw_name, NULL, 0 /* don't collect info */,
1643 NULL) != SIASUCCESS)
1649 se->password = (char *)malloc(strlen(passwd) + 1);
1650 if ( se->password == (char *)NULL )
1652 sia_ses_release(&se);
1657 strcpy(se->password, passwd);
1659 code = sia_ses_reauthent (NULL, se);
1660 sia_ses_release(&se);
1664 if ( code == SIASUCCESS )
1670 #elif defined(linux)
1673 struct passwd *pwent = NULL;
1677 Boolean done = False;
1678 struct spwd *sp = NULL;
1680 if(smGD.secureSystem)
1682 SM_SETEUID(smGD.unLockUID);
1686 * Get password entry for 'name' or 'uid'.
1688 if (CanReAuthenticate(name, uid, passwd, &pwent, &sp) == False)
1697 if(smGD.secureSystem)
1699 SM_SETEUID(smGD.runningUID);
1705 if (pwent->pw_passwd == NULL || pwent->pw_passwd[0] == '*')
1708 if (sp == NULL || sp->sp_pwdp == NULL)
1711 * Could not read password.
1724 * Caller just checking if it is possible to access
1725 * password file (ie is dtsession suid bit set properly).
1738 if (sp != NULL && !strcmp(sp->sp_pwdp, crypt(passwd,sp->sp_pwdp)))
1739 { /* a shadow match */
1743 else if (pwent != NULL &&
1744 !strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)))
1745 { /* passwd match */
1750 { /* failure dude! */
1765 register struct passwd *pwent;
1769 Boolean done = False;
1775 char *upasswd, *newname = NULL;
1777 struct spwd *sp=NULL;
1781 if(smGD.secureSystem)
1783 SM_SETEUID(smGD.unLockUID);
1788 * Get shadow password entry for 'name' or 'uid'.
1792 pwent = getpwuid(uid);
1796 name = newname = strdup(pwent->pw_name);
1798 name = pwent->pw_name;
1805 ia_openinfo(name, &uinfo)
1807 (sp = getspnam(name)) == NULL
1819 * Get password entry for 'name' or 'uid'.
1821 if ((pwent = (name == NULL ? getpwuid(uid) : getpwnam(name))) == NULL)
1831 if(smGD.secureSystem)
1833 SM_SETEUID(smGD.runningUID);
1839 ia_get_logpwd(uinfo, &upasswd);
1842 pwent->pw_passwd == NULL
1843 || pwent->pw_passwd[0] == '*'
1854 * Could not read password.
1866 * Caller just checking if it is possible to access
1867 * password file (ie is dtsession suid bit set properly).
1881 if (strcmp(crypt(passwd, upasswd), upasswd) != 0)
1883 if (strcmp(crypt(passwd,sp->sp_pwdp),sp->sp_pwdp) != 0)
1886 if (strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)) != 0)
1890 * Password incorrect.
1900 ia_closeinfo(uinfo);
1901 if (newname) free(newname);
1912 /*************************************<->*************************************
1914 * Authenticate (name, uid, passwd)
1931 *************************************<->***********************************/
1933 #if defined (_AIX) && defined(_POWER)
1941 register struct passwd *pwent;
1945 Boolean done = False;
1949 char *newname = NULL;
1952 if(smGD.secureSystem)
1954 SM_SETEUID(smGD.unLockUID);
1962 pwent = getpwuid(uid);
1965 name = newname = strdup(pwent->pw_name);
1971 * Authenticate user. Note: normally, we should check 'reenter' to
1972 * see if the user has another challenge. Since the dtsession screen
1973 * lock i/f does not yet have the support, our policy is to let the
1974 * user back in if they pass the first (password) challenge.
1976 arc = authenticate(name, passwd, &reenter, &msg);
1978 if(smGD.secureSystem)
1980 SM_SETEUID(smGD.runningUID);
1984 if (newname) free(newname);
1986 return(arc == 0 ? True : False);
1988 #endif /* _AIX && _POWER */