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);
165 *spent = getspnam((*pwent)->pw_name);
168 fprintf(stderr, "CanReAuthenticate(): %s %s %s\n",
169 (*pwent) ? "PWENT" : "NULL",
170 (*spent) ? "SPENT" : "NULL",
171 (name) ? name : "NULL");
174 /* some checking for aging stuff on RedPhat */
176 if (*pwent && (*pwent)->pw_passwd)
180 if ((loc = strchr((*pwent)->pw_passwd, ',')) != NULL)
183 fprintf(stderr, "CanReAuthenticate(): pw: '%s'\n",
184 (*pwent)->pw_passwd);
189 if (*spent && (*spent)->sp_pwdp)
193 if ((loc = strchr((*spent)->sp_pwdp, ',')) != NULL)
198 { /* if we can't get this, we're screwed. */
200 fprintf(stderr, "CanReAuthenticate(): PWENT == NULL - FALSE\n");
205 if ((*pwent)->pw_passwd == NULL)
208 fprintf(stderr, "CanReAuthenticate(): (*pwent)->pw_passwd == NULL - FALSE\n");
214 /* ok, now we have the prequisite data, look first to see if the
215 * passwd field is larger than 1 char - implying NIS, or a shadowed
216 * system. if not look for *spent being non-NULL
219 { /* if it's null, lets check for the NIS case */
220 if (strlen((*pwent)->pw_passwd) <= 1)
223 fprintf(stderr, "strlen((*pwent)->pw_passwd) <= 1\n");
226 return False; /* not NIS */
230 /* supposedly we have valid data */
232 fprintf(stderr, "CanReAuthenticate(): TRUE\n");
243 /*************************************<->*************************************
250 * Calls the routines that are in charge of locking the display.
255 * lockNow - request to lock the display immediately
263 *************************************<->***********************************/
265 * Place holders for the lock position
267 static Position visibleY;
268 static Position hiddenY;
276 Widget parent = NULL, lockDlg;
283 timerId = lockTimeId = lockDelayId = cycleId = flash_id = (XtIntervalId)0;
287 * 0 - screen will not be covered, nor will external screen saver run
288 * 1 - screen will be covered, external screen saver may be run
291 * -1 = no password required to unlock display
292 * 0 = password always required to unlock display
293 * N = password required to unlock display after N seconds
295 if (smSaverRes.saverTimeout == 0)
297 smGD.coverScreen = 0;
300 else if (lockNow || smSaverRes.lockTimeout > 0)
302 smGD.coverScreen = 1;
305 else if (smSaverRes.lockTimeout == 0)
307 else if (smSaverRes.lockTimeout <= smSaverRes.saverTimeout)
310 lockDelay = smSaverRes.lockTimeout - smSaverRes.saverTimeout;
314 smGD.coverScreen = 1;
319 * Before anything is done make sure we can unlock if we lock.
321 if (localAuthenticate(NULL, getuid(), NULL) == False)
324 PrintError(DtError, smNLS.trustedSystemErrorString);
326 XBell(smGD.display, 100);
329 * Tell the Workspace Manager to quit blinking
331 msg = tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
332 "DtActivity_Began", 0 );
333 tt_message_send( msg );
334 tt_message_destroy( msg );
340 if(((smDD.lockCoverDialog == NULL) && (smGD.coverScreen == True)) ||
341 ((smDD.lockDialog == NULL) && (smGD.coverScreen == False)))
344 * Set up the grab widget in here
349 * If the user has specified cover - create the cover dialog
351 screenNum = DefaultScreen(smGD.display);
352 if(smGD.coverScreen == True)
354 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
358 smDD.coverDialog[i] = CreateCoverDialog(i, True);
359 parent = smDD.coverDrawing[i];
363 smDD.coverDialog[i] = CreateCoverDialog(i, False);
366 smDD.lockCoverDialog = CreateLockDialogWithCover(parent);
370 * Create the lock dialog if the user has specified that
372 if((smDD.lockDialog == NULL) && (smGD.coverScreen == False))
374 smDD.lockDialog = CreateLockDialog();
377 * Get colors for the password cursor
380 XtSetArg(uiArgs[i], XmNtopShadowColor, &(xcolors[0]));i++;
381 XtSetArg(uiArgs[i], XmNbottomShadowColor, &(xcolors[1]));i++;
382 XtGetValues(smDD.lockDialog, uiArgs, i);
384 smGD.backgroundPix = xcolors[0].pixel;
385 smGD.foregroundPix = xcolors[1].pixel;
386 if (smGD.backgroundPix == smGD.foregroundPix)
388 smGD.backgroundPix = smGD.whitePixel;
389 smGD.foregroundPix = smGD.blackPixel;
395 * Wait for a visibility event to occur on the window so that
398 if(smGD.coverScreen == True)
400 smGD.lockCursor = smGD.blankCursor;
401 grabWidget = smDD.coverDialog[0];
402 lockDlg = smDD.lockCoverDialog;
403 lockDlgVisible = False; /* mappedWhenManaged False */
407 smGD.lockCursor = smGD.padlockCursor;
408 grabWidget = smDD.lockDialog;
409 lockDlg = smDD.lockDialog;
410 visibleY = hiddenY = -1;
414 * Note: grabWidget must be mapped in order to grab it. This means
415 * that if coverScreen is True, smDD.coverDialog[0] must be mapped
416 * immediately and if coverScreen is False, smDD.lockDialog must be
417 * mapped immediately. Also, if a grabWidget is unmapped, the grab
420 XtAddEventHandler(grabWidget, VisibilityChangeMask,
421 False, FinishLocking, NULL);
423 XtManageChild(lockDlg);
425 if(smGD.coverScreen == True) {
426 flash_id = XtAppAddTimeOut(smGD.appCon,
427 1000, BlinkCaret,smDD.indLabel[1]);
430 flash_id = XtAppAddTimeOut(smGD.appCon,
431 1000, BlinkCaret,smDD.indLabel[0]);
437 * Wait for 'lockDelay' seconds before requiring a password.
439 lockDelayId = XtAppAddTimeOut(smGD.appCon,
440 lockDelay*1000, RequirePassword, NULL);
443 else if (lockDelay == 0)
446 * Immediately require a password to unlock the display.
448 smGD.lockedState = LOCKED;
449 PutUpLogin(True, False); /* map, but don't set timeout */
452 if (smGD.coverScreen == True && smSaverRes.cycleTimeout > 0)
455 * Cycle to next saver in 'cycleTimeout' seconds.
457 cycleId = XtAppAddTimeOut(smGD.appCon,
458 smSaverRes.cycleTimeout*1000, CycleSaver, NULL);
461 if(smGD.coverScreen == True)
463 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
465 XtPopup(smDD.coverDialog[i], XtGrabNone);
470 * Add an event handler for when the keyboard and pointer are grabbed
472 XtAddEventHandler(grabWidget,
473 (KeyPressMask | ButtonPressMask | PointerMotionMask),
474 False, EventDetected, NULL);
476 /** wait 90 seconds for lock dialog to come up **/
477 lockTimeId = XtAppAddTimeOut(smGD.appCon,
478 90000, LockAttemptFailed, lockDlg);
484 /*************************************<->*************************************
491 * After the lock dialog is up - do the grab and lock the display
503 *************************************<->***********************************/
505 FinishLocking(Widget wid,
511 Boolean kbdGrabbed, pointerGrabbed;
514 if (lockTimeId == (XtIntervalId)0)
517 XtRemoveTimeOut(lockTimeId);
518 lockTimeId = (XtIntervalId)0;
519 XtRemoveEventHandler(wid, VisibilityChangeMask,
520 False, FinishLocking, NULL);
521 XSync(smGD.display, 0);
524 XtSetArg(uiArgs[i], XmNy, &visibleY);i++;
525 XtGetValues(wid, uiArgs, i);
527 hiddenY = (Position) DisplayHeight(smGD.display, smGD.screen) + 15;
530 * Color the cursor for this color scheme
534 XSync(smGD.display, 0);
537 * grab control of the keyboard for the entire display
539 rc = XtGrabKeyboard(grabWidget, False,
540 GrabModeAsync, GrabModeAsync,
542 kbdGrabbed = (rc == GrabSuccess);
544 #ifdef USE_HP_SPECIFIC_XLIB
545 XHPDisableReset(smGD.display);
546 #endif /* USE_HP_SPECIFIC_XLIB */
548 #if defined (AIXV3) && !defined(_POWER)
549 if(smGD.secureSystem)
551 SM_SETEUID(smGD.unLockUID);
553 SM_SETEUID(smGD.runningUID);
557 pointerGrabbed = (XtGrabPointer(grabWidget, False,
558 ButtonPressMask|PointerMotionMask,
559 GrabModeAsync, GrabModeAsync,
560 None, smGD.lockCursor, CurrentTime)
564 pointerGrabbed = (XtGrabPointer(grabWidget, False,
565 ButtonPressMask|PointerMotionMask,
566 GrabModeAsync, GrabModeAsync,
567 None, smGD.lockCursor, CurrentTime)
573 * If the grab failed - try 3 more times and give up
575 if((kbdGrabbed == False) || (pointerGrabbed == False))
577 for(j = 0;(j < 3) && ((pointerGrabbed == False) ||
578 (kbdGrabbed == False));j++)
581 * If a grab fails try one more time and then give up
583 if(kbdGrabbed == False)
586 kbdGrabbed = (XtGrabKeyboard(grabWidget, False,
587 GrabModeAsync, GrabModeAsync,
588 CurrentTime) == GrabSuccess);
591 if(pointerGrabbed == False)
594 pointerGrabbed = (XtGrabPointer(grabWidget, False,
599 None, smGD.lockCursor,
608 * Set status variable to lock if the lock has succeeded
610 if((pointerGrabbed != True) || (kbdGrabbed != True))
612 PrintError(DtError, smNLS.cantLockErrorString);
613 smGD.lockedState = UNLOCKED;
614 UnlockDisplay(pointerGrabbed, kbdGrabbed);
619 #ifdef LOCK_SERVER_ACCESS
621 * Wipe & enable X server access control list
623 hostList = XListHosts(smGD.display,
624 &hostListLen, (Bool *) &hostListActive);
625 XRemoveHosts(smGD.display, hostList, hostListLen);
626 XEnableAccessControl(smGD.display);
627 RestrictingAccess = True;
630 PutUpLogin(False, True); /* already mapped, but set timeout */
633 * Start external screen saver.
635 if (smGD.coverScreen)
645 /*************************************<->*************************************
647 * CreateLockCursor ()
652 * Creates a padlock cursor if the user has specified lock. Creates a
653 * blank cursor if the user has specified cover. Both are specified in the
654 * users resource file.
660 * buttonForm = widget from which cursor gets its color
661 * smGD.coverScreen = (global) cover screen or put up a padlock
667 * smGD.lockCursor = (global) cursor when lock is active (blank or padlock)
672 *************************************<->***********************************/
673 #define lock_m_hot_x 16
674 #define lock_m_hot_y 16
675 #define lock_m_bm_width 32
676 #define lock_m_bm_height 32
677 static unsigned char lock_m_bm_bits[] = {
678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00,
679 0x00, 0xfc, 0x9f, 0x00, 0x00, 0x0e, 0x90, 0x01, 0x00, 0x06, 0x80, 0x01,
680 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01,
681 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01,
682 0x00, 0x06, 0x80, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c,
683 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
684 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f,
685 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
686 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f,
687 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
688 0xc0, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0x0f};
690 #define lock_m_m_bm_width 32
691 #define lock_m_m_bm_height 32
692 static unsigned char lock_m_m_bm_bits[] = {
693 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00,
694 0x00, 0xff, 0xff, 0x00, 0x80, 0x0f, 0xf0, 0x01, 0x80, 0x07, 0xe0, 0x01,
695 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01,
696 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01,
697 0x80, 0x07, 0xe0, 0x01, 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, 0xf0, 0xff, 0xff, 0x0f,
703 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f};
705 #define lock_s_hot_x 7
706 #define lock_s_hot_y 8
707 #define lock_s_bm_width 13
708 #define lock_s_bm_height 16
709 static unsigned char lock_s_bm_bits[] = {
710 0x00, 0x02, 0x00, 0x04, 0xf0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
711 0x00, 0x00, 0xa8, 0x1a, 0x54, 0x1d, 0xa8, 0x1a, 0x54, 0x1d, 0xa8, 0x1a,
712 0x54, 0x1d, 0xa8, 0x1a, 0x54, 0x1d, 0xfe, 0x1f};
714 #define lock_s_m_bm_width 13
715 #define lock_s_m_bm_height 16
716 static unsigned char lock_s_m_bm_bits[] = {
717 0xf8, 0x03, 0xfc, 0x07, 0xfe, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
718 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f,
719 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f};
722 CreateLockCursor( void )
725 Colormap cmap = XDefaultColormap(smGD.display, smGD.screen);
727 char noCursorBits = 0x1;
729 if(InitCursorInfo() == False)
732 * Create the SMALL padlock cursor
734 source = XCreateBitmapFromData(smGD.display,
735 XRootWindow(smGD.display,
737 (char *) lock_s_bm_bits,
740 mask = XCreateBitmapFromData(smGD.display,
741 XRootWindow(smGD.display,
743 (char *) lock_s_m_bm_bits,
747 /* translate the Pixels into XColors */
748 xcolors[0].pixel = smGD.blackPixel;
749 xcolors[1].pixel = smGD.whitePixel;
750 XQueryColors(smGD.display, cmap, xcolors, 2);
752 /* create the padlock cursor */
753 smGD.padlockCursor = XCreatePixmapCursor(smGD.display, source, mask,
754 &(xcolors[0]), &(xcolors[1]),
757 XFreePixmap(smGD.display, source);
758 XFreePixmap(smGD.display, mask);
763 * Create the LARGE padlock cursor
765 source = XCreateBitmapFromData(smGD.display,
766 XRootWindow(smGD.display,
768 (char *) lock_m_bm_bits,
771 mask = XCreateBitmapFromData(smGD.display,
772 XRootWindow(smGD.display,
774 (char *) lock_m_m_bm_bits,
778 /* translate the Pixels into XColors */
779 xcolors[0].pixel = smGD.blackPixel;
780 xcolors[1].pixel = smGD.whitePixel;
781 XQueryColors(smGD.display, cmap, xcolors, 2);
783 /* create the padlock cursor */
784 smGD.padlockCursor = XCreatePixmapCursor(smGD.display, source, mask,
785 &(xcolors[0]), &(xcolors[1]),
788 XFreePixmap(smGD.display, source);
789 XFreePixmap(smGD.display, mask);
794 * create the blank cursor
796 source = XCreateBitmapFromData(smGD.display,
797 XRootWindow(smGD.display, smGD.screen),
798 &noCursorBits, 1, 1);
800 xcolors[0].pixel = smGD.blackPixel;
801 XQueryColor(smGD.display, cmap, &(xcolors[0]));
802 smGD.blankCursor = XCreatePixmapCursor(smGD.display, source, source,
803 &(xcolors[0]), &(xcolors[0]),
805 XFreePixmap(smGD.display, source);
810 /*************************************<->*************************************
817 * Recolors the padlock cursor to be the current color scheme. This has
818 * to be done because XCreatePixmapCursor allocates colors instead of jusst
819 * using a pixel value.
825 * smGD.backgroundPix = Pixel value to use for background color
826 * smGD.foregroundPix = Pixel value to use for foreground color
831 * smGD.lockCursor = (global) cursor when lock is active (padlock)
836 *************************************<->***********************************/
838 RecolorCursor( void )
840 Colormap cmap = XDefaultColormap(smGD.display, smGD.screen);
844 * translate the Pixels into XColors
846 xcolors[0].pixel = smGD.foregroundPix;
847 xcolors[1].pixel = smGD.backgroundPix;
848 XQueryColors(smGD.display, cmap, xcolors, 2);
851 * recolor the padlock cursor
853 XRecolorCursor(smGD.display, smGD.lockCursor, &(xcolors[0]),
859 /*************************************<->*************************************
861 * EventDetected (w, client_data, event)
866 * Callback routine that detects an event when the display is locked.
867 * If it's a correct password, it unlocks the display. Otherwise, it
868 * just displays status. The event is detected by the popup login dialog.
873 * w = widget where event occured
874 * client_data = client specific data sent to callback
875 * event = event that triggered callback
884 *************************************<->***********************************/
888 XtPointer client_data,
894 XKeyEvent *event = (XKeyEvent *) ev;
896 if (smGD.lockedState == LOCKED)
898 if (lockDlgVisible == False)
901 * Anytime input is received - show the passwd dialog and
902 * discard event. This is so a keypress event that causes
903 * the passwd dialog to appear will not be used in the password.
906 PutUpLogin(True, True); /* map, and reset timeout */
909 PutUpLogin(False, True); /* already mapped, but reset timeout */
913 UnlockDisplay(True, True);
918 * If the detected event is anything but a keypress, processing is
919 * complete after refreshing the status string.
921 if (event->type != KeyPress)
925 * If XLookupString() returns anything (which it won't in the case of, say,
926 * pressing the shift key or an arrow key), process it.
928 #ifdef USE_HP_SPECIFIC_XLIB
929 if (len = XHPConvertLookup(event, str, sizeof(str), NULL, NULL,
930 XHPGetEurasianCvt(smGD.display)))
931 #else /* USE_HP_SPECIFIC_XLIB */
932 if (len = XLookupString (event, str, sizeof(str), NULL, NULL))
933 #endif /* USE_HP_SPECIFIC_XLIB */
935 if (smGD.lockedState == LOCKED)
936 CheckString(str, len);
942 /*************************************<->*************************************
949 * Check string entered by user. If it is a valid password, call routine to
950 * unlock the display. Otherwise, just keep track of what we have until
951 * the password is valid
956 * s = string passed in for checking
957 * i = length of string
966 *************************************<->***********************************/
974 * - Only the first eight characters are used.
975 * - If pw_length > 8, we've gone over eight characters and won't
977 * - An ESC kills the line.
980 static char passwd[82]; /* password space */
982 static char passwd[10]; /* password space */
984 static int pw_length = 0; /* password length */
1001 pw_length--; /* back up one character */
1005 pw_length = 0; /* kill the character string */
1021 passwd[pw_length] = '\0'; /* terminate string */
1022 pw_length = 0; /* reset length */
1023 if (CheckPassword(passwd))
1025 UpdatePasswdField(0);
1026 UnlockDisplay(True, True);
1029 XBell(smGD.display, 100); /* wrong, laserbreath */
1038 passwd[pw_length] = *s; /* store character */
1040 * The length is incremented no matter what, so the user can
1041 * think the program handles multi-thousand-character
1042 * passwords. If the user types twenty characters and eighteen
1043 * erases (#), the result will be the first two characters
1044 * entered, as expected. Up to a point -- 65536 is long
1047 if (pw_length < 65535)
1055 UpdatePasswdField(8);
1059 UpdatePasswdField(pw_length);
1065 /*************************************<->*************************************
1067 * CheckPassword (passwd)
1072 * Check the password to see if it is the user's, roots, or one of the
1073 * users specified in the host string
1078 * passwd = password passed in
1083 * True if it is a valid password, false otherwise.
1088 *************************************<->***********************************/
1096 if (Authenticate(NULL, getuid(), passwd) == True)
1098 return(True); /* user password ok */
1101 if (Authenticate(NULL, 0, passwd) == True)
1103 return(True); /* root password ok */
1106 /* check passwords of users specified as keyholders */
1107 if (smGD.keyholders == NULL)
1109 return(False); /* no keyholders */
1112 /* since strtok() is destructive, copy the keyholders string */
1113 keyholderbuf = (char *) SM_MALLOC(strlen(smGD.keyholders)+1);
1114 if(keyholderbuf == NULL)
1116 PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1117 return(False); /* no memory */
1120 strcpy(keyholderbuf, smGD.keyholders);
1121 for (p = keyholderbuf; (q = strtok(p, ", \t")) != NULL; p = NULL)
1123 if (Authenticate(q, -1, passwd) == True)
1125 SM_FREE(keyholderbuf);
1126 return(True); /* keyholder password ok */
1129 SM_FREE(keyholderbuf);
1131 return(False); /* no matches */
1136 /*************************************<->*************************************
1143 * If the user has entered a correct password, unlock the display and
1144 * uncover the root window.
1149 * pointerGrabbed - Boolean tells if pointer is currently grabbed
1150 * kbdGrabbed - Boolean tells if keyboard is currently grabbed
1160 *************************************<->***********************************/
1163 Boolean pointerGrabbed,
1169 #ifdef LOCK_SERVER_ACCESS
1171 * Restore X server access state
1173 if (RestrictingAccess) {
1174 XAddHosts(smGD.display, hostList, hostListLen);
1175 if (!hostListActive) XDisableAccessControl(smGD.display);
1176 RestrictingAccess = False;
1177 XFree((void *) hostList);
1182 * Stop external screen saver.
1187 * Remove the event handler to grab the events
1189 XtRemoveEventHandler(grabWidget,
1190 (KeyPressMask | ButtonPressMask | PointerMotionMask),
1191 False, EventDetected, NULL);
1196 if(lockDelayId != (XtIntervalId)0)
1198 XtRemoveTimeOut(lockDelayId);
1201 if(cycleId != (XtIntervalId)0)
1203 XtRemoveTimeOut(cycleId);
1206 if(timerId != (XtIntervalId)0)
1208 XtRemoveTimeOut(timerId);
1211 if(flash_id != (XtIntervalId)0)
1213 XtRemoveTimeOut(flash_id);
1216 if(pointerGrabbed == True)
1218 XtUngrabPointer(grabWidget, CurrentTime);
1221 if(kbdGrabbed == True)
1223 XtUngrabKeyboard(grabWidget, CurrentTime);
1226 #ifdef USE_HP_SPECIFIC_XLIB
1227 XHPEnableReset(smGD.display);
1228 #endif /* USE_HP_SPECIFIC_XLIB */
1230 #if defined (AIXV3) && !defined(_POWER)
1231 if(smGD.secureSystem)
1233 SM_SETEUID(smGD.unLockUID);
1234 AixEnableHftRing(1);
1235 SM_SETEUID(smGD.runningUID);
1239 XSync(smGD.display, 0);
1242 * Unmanage session lock dialogs. If LOCKDLG_PERSIST is undefined,
1243 * destroy them. This is so the passwd dialog icon colors get freed
1244 * since currently it uses a lot of colors.
1246 if(smGD.coverScreen == False)
1248 #if defined (LOCKDLG_PERSIST)
1249 if (XtIsManaged(smDD.lockDialog))
1251 XtUnmanageChild(smDD.lockDialog);
1254 XtDestroyWidget(smDD.lockDialog);
1255 smDD.lockDialog = NULL;
1260 #if defined (LOCKDLG_PERSIST)
1261 if(!XtIsManaged(smDD.lockCoverDialog))
1263 XtManageChild(smDD.lockCoverDialog);
1266 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1268 XtPopdown(smDD.coverDialog[i]);
1271 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1273 XtDestroyWidget(smDD.coverDialog[i]);
1274 smDD.coverDialog[i] = NULL;
1276 smDD.lockCoverDialog = NULL;
1280 smGD.lockedState = UNLOCKED;
1282 XSync(smGD.display, 0);
1285 * Tell the Workspace Manager to unlock the display (depress the lock
1287 if(smGD.bmsDead == False)
1289 msg = tttk_message_create(0, TT_REQUEST, TT_SESSION, 0,
1290 "Display_Unlock", 0);
1291 tt_message_send(msg);
1292 tt_message_destroy(msg);
1300 static Position visibleY = -1;
1301 static Position hiddenY = -1;
1304 /*************************************<->*************************************
1311 * When a timeout occurs - take down the login screen by unmanaging it.
1325 *************************************<->***********************************/
1328 XtPointer client_data,
1331 if (lockDlgVisible == True)
1333 if (smGD.coverScreen == True)
1335 XtUnmapWidget(smDD.lockCoverDialog);
1342 XtSetArg(uiArgs[i], XmNy, hiddenY);i++;
1343 XtSetValues(smDD.lockDialog, uiArgs, i);
1347 timerId = (XtIntervalId)0;
1350 * Clear partially entered password if any.
1352 CheckString(NULL, 0);
1353 lockDlgVisible = False;
1355 XSync(smGD.display, 0);
1360 /*************************************<->*************************************
1367 * Redisplays the cover and the login when neccessary.
1381 *************************************<->***********************************/
1387 if (map == True && lockDlgVisible == False)
1389 if (smGD.coverScreen == True)
1391 XtMapWidget(smDD.lockCoverDialog);
1398 XtSetArg(uiArgs[i], XmNy, visibleY);i++;
1399 XtSetValues(smDD.lockDialog, uiArgs, i);
1402 lockDlgVisible = True;
1405 if (timeout == True)
1407 if(timerId != (XtIntervalId)0)
1409 XtRemoveTimeOut(timerId);
1412 if(smRes.alarmTime > 0)
1414 timerId = XtAppAddTimeOut(smGD.appCon,
1415 (smRes.alarmTime * 1000),
1416 TakeDownLogin,NULL);
1419 XSync(smGD.display, 0);
1423 /*************************************<->*************************************
1425 * LockAttemptFailed ()
1430 * Timed out trying to get a visibilitynotify on the lock
1444 *************************************<->***********************************/
1446 LockAttemptFailed(XtPointer ptr,
1447 XtIntervalId *invId)
1449 Widget lockWid = (Widget) ptr;
1451 PrintError(DtError, smNLS.cantLockErrorString);
1452 smGD.lockedState = UNLOCKED;
1453 XtRemoveEventHandler(lockWid, VisibilityChangeMask,
1454 False, FinishLocking, NULL);
1455 UnlockDisplay(False, False);
1456 XSync(smGD.display, 0);
1462 /*************************************<->*************************************
1464 * RequirePassword ()
1469 * Callback indicating a password is now required to unlock display.
1483 *************************************<->***********************************/
1485 RequirePassword(XtPointer ptr,
1486 XtIntervalId *invId)
1488 smGD.lockedState = LOCKED;
1492 /*************************************<->*************************************
1499 * blinks the caret in the password field
1513 *************************************<->***********************************/
1515 BlinkCaret(XtPointer ptr,
1516 XtIntervalId *invId)
1518 static int flag = 1;
1523 * Blink cursor to show the focus ..
1526 tmpString = XmStringCreateLocalized (" " );
1528 XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1529 XtSetValues(ptr, uiArgs, i);
1533 tmpString = XmStringCreateLocalized ("|");
1535 XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1536 XtSetValues(ptr, uiArgs, i);
1540 XmStringFree(tmpString);
1541 flash_id = XtAppAddTimeOut(smGD.appCon, 1000,
1547 /*************************************<->*************************************
1554 * Callback indicating we should cycle to next screen saver
1568 *************************************<->***********************************/
1570 CycleSaver(XtPointer ptr,
1571 XtIntervalId *invId)
1574 * Stop running screen saver, start a new one and reset timer.
1578 cycleId = XtAppAddTimeOut(smGD.appCon, smSaverRes.cycleTimeout*1000,
1584 /*************************************<->*************************************
1586 * localAuthenticate (name, uid, passwd)
1603 *************************************<->***********************************/
1614 char *Argv[2] = { "dtsession", NULL };
1616 SIAENTITY *se = NULL;
1622 real_uid = getuid();
1624 if (-1 == seteuid(0))
1631 * Caller just checking if it is possible to access
1632 * password file (ie is dtsession suid bit set properly).
1637 if (name && name[0])
1642 pw_name = getlogin();
1645 if ( sia_ses_init(&se, 1, Argv, (char *)NULL,
1646 pw_name, NULL, 0 /* don't collect info */,
1647 NULL) != SIASUCCESS)
1653 se->password = (char *)malloc(strlen(passwd) + 1);
1654 if ( se->password == (char *)NULL )
1656 sia_ses_release(&se);
1661 strcpy(se->password, passwd);
1663 code = sia_ses_reauthent (NULL, se);
1664 sia_ses_release(&se);
1668 if ( code == SIASUCCESS )
1674 #elif defined(linux)
1677 struct passwd *pwent = NULL;
1681 Boolean done = False;
1682 struct spwd *sp = NULL;
1684 if(smGD.secureSystem)
1686 SM_SETEUID(smGD.unLockUID);
1690 * Get password entry for 'name' or 'uid'.
1692 if (CanReAuthenticate(name, uid, passwd, &pwent, &sp) == False)
1701 if(smGD.secureSystem)
1703 SM_SETEUID(smGD.runningUID);
1709 if (pwent->pw_passwd == NULL || pwent->pw_passwd[0] == '*')
1712 if (sp == NULL || sp->sp_pwdp == NULL)
1715 * Could not read password.
1728 * Caller just checking if it is possible to access
1729 * password file (ie is dtsession suid bit set properly).
1742 if (sp != NULL && !strcmp(sp->sp_pwdp, crypt(passwd,sp->sp_pwdp)))
1743 { /* a shadow match */
1747 else if (pwent != NULL &&
1748 !strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)))
1749 { /* passwd match */
1754 { /* failure dude! */
1769 register struct passwd *pwent;
1773 Boolean done = False;
1779 char *upasswd, *newname = NULL;
1781 struct spwd *sp=NULL;
1785 if(smGD.secureSystem)
1787 SM_SETEUID(smGD.unLockUID);
1792 * Get shadow password entry for 'name' or 'uid'.
1796 pwent = getpwuid(uid);
1800 name = newname = strdup(pwent->pw_name);
1802 name = pwent->pw_name;
1809 ia_openinfo(name, &uinfo)
1811 (sp = getspnam(name)) == NULL
1823 * Get password entry for 'name' or 'uid'.
1825 if ((pwent = (name == NULL ? getpwuid(uid) : getpwnam(name))) == NULL)
1835 if(smGD.secureSystem)
1837 SM_SETEUID(smGD.runningUID);
1843 ia_get_logpwd(uinfo, &upasswd);
1846 pwent->pw_passwd == NULL
1847 || pwent->pw_passwd[0] == '*'
1858 * Could not read password.
1870 * Caller just checking if it is possible to access
1871 * password file (ie is dtsession suid bit set properly).
1885 if (strcmp(crypt(passwd, upasswd), upasswd) != 0)
1887 if (strcmp(crypt(passwd,sp->sp_pwdp),sp->sp_pwdp) != 0)
1890 if (strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)) != 0)
1894 * Password incorrect.
1904 ia_closeinfo(uinfo);
1905 if (newname) free(newname);
1916 /*************************************<->*************************************
1918 * Authenticate (name, uid, passwd)
1935 *************************************<->***********************************/
1937 #if defined (_AIX) && defined(_POWER)
1945 register struct passwd *pwent;
1949 Boolean done = False;
1953 char *newname = NULL;
1956 if(smGD.secureSystem)
1958 SM_SETEUID(smGD.unLockUID);
1966 pwent = getpwuid(uid);
1969 name = newname = strdup(pwent->pw_name);
1975 * Authenticate user. Note: normally, we should check 'reenter' to
1976 * see if the user has another challenge. Since the dtsession screen
1977 * lock i/f does not yet have the support, our policy is to let the
1978 * user back in if they pass the first (password) challenge.
1980 arc = authenticate(name, passwd, &reenter, &msg);
1982 if(smGD.secureSystem)
1984 SM_SETEUID(smGD.runningUID);
1988 if (newname) free(newname);
1990 return(arc == 0 ? True : False);
1992 #endif /* _AIX && _POWER */