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 libraries 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>
80 #if defined(__linux__)
83 #if defined(CSRG_BASED)
84 #include <sys/types.h>
89 #include "SmGlobals.h"
96 * Variables global to this module only
102 static XtIntervalId timerId, lockTimeId, lockDelayId, cycleId, flash_id;
107 static Widget grabWidget;
110 * Lock dialog visibility
112 static Boolean lockDlgVisible;
114 #ifdef LOCK_SERVER_ACCESS
116 * Server Access Control Information
118 static Boolean RestrictingAccess = False;
119 static XHostAddress *hostList;
120 static Bool hostListActive;
121 static int hostListLen;
128 static void FinishLocking(Widget, XtPointer, XEvent *, Boolean *);
129 static void RecolorCursor( void ) ;
130 static void EventDetected( Widget, XtPointer, XEvent *, Boolean *) ;
131 static void CheckString( char *, int ) ;
132 static Boolean CheckPassword( char * ) ;
133 #if defined (_AIX) && defined (_POWER)
134 static Boolean Authenticate( char *, uid_t, char * ) ;
136 #define Authenticate(A,B,C) localAuthenticate(A,B,C)
138 static Boolean localAuthenticate( char *, uid_t, char * ) ;
139 static void UnlockDisplay( Boolean, Boolean ) ;
140 static void TakeDownLogin( XtPointer, XtIntervalId * ) ;
141 static void PutUpLogin( Boolean, Boolean ) ;
142 static void LockAttemptFailed( XtPointer, XtIntervalId *) ;
143 static void RequirePassword( XtPointer, XtIntervalId *) ;
144 static void CycleSaver( XtPointer, XtIntervalId *) ;
145 static void BlinkCaret( XtPointer, XtIntervalId *) ;
147 #if defined(__linux__)
148 /* #define JET_AUTHDEBUG */
150 /* Test for re-auth ability - see if we can re-authenticate via pwd,
153 static Boolean CanReAuthenticate(char *name, uid_t uid, char *passwd,
154 struct passwd **pwent, struct spwd **spent)
156 Boolean fail = False;
159 *pwent = (name == NULL) ? getpwuid(uid) : getpwnam(name);
160 *spent = getspnam((*pwent)->pw_name);
163 fprintf(stderr, "CanReAuthenticate(): %s %s %s\n",
164 (*pwent) ? "PWENT" : "NULL",
165 (*spent) ? "SPENT" : "NULL",
166 (name) ? name : "NULL");
169 /* some checking for aging stuff on RedPhat */
171 if (*pwent && (*pwent)->pw_passwd)
175 if ((loc = strchr((*pwent)->pw_passwd, ',')) != NULL)
178 fprintf(stderr, "CanReAuthenticate(): pw: '%s'\n",
179 (*pwent)->pw_passwd);
184 if (*spent && (*spent)->sp_pwdp)
188 if ((loc = strchr((*spent)->sp_pwdp, ',')) != NULL)
193 { /* if we can't get this, we're screwed. */
195 fprintf(stderr, "CanReAuthenticate(): PWENT == NULL - FALSE\n");
200 if ((*pwent)->pw_passwd == NULL)
203 fprintf(stderr, "CanReAuthenticate(): (*pwent)->pw_passwd == NULL - FALSE\n");
209 /* ok, now we have the prequisite data, look first to see if the
210 * passwd field is larger than 1 char - implying NIS, or a shadowed
211 * system. if not look for *spent being non-NULL
214 { /* if it's null, lets check for the NIS case */
215 if (strlen((*pwent)->pw_passwd) <= 1)
218 fprintf(stderr, "strlen((*pwent)->pw_passwd) <= 1\n");
221 return False; /* not NIS */
225 /* supposedly we have valid data */
227 fprintf(stderr, "CanReAuthenticate(): TRUE\n");
238 /*************************************<->*************************************
245 * Calls the routines that are in charge of locking the display.
250 * lockNow - request to lock the display immediately
258 *************************************<->***********************************/
260 * Place holders for the lock position
262 static Position visibleY;
263 static Position hiddenY;
271 Widget parent = NULL, lockDlg;
278 timerId = lockTimeId = lockDelayId = cycleId = flash_id = (XtIntervalId)0;
282 * 0 - screen will not be covered, nor will external screen saver run
283 * 1 - screen will be covered, external screen saver may be run
286 * -1 = no password required to unlock display
287 * 0 = password always required to unlock display
288 * N = password required to unlock display after N seconds
290 if (smSaverRes.saverTimeout == 0)
292 smGD.coverScreen = 0;
295 else if (lockNow || smSaverRes.lockTimeout > 0)
297 smGD.coverScreen = 1;
300 else if (smSaverRes.lockTimeout == 0)
302 else if (smSaverRes.lockTimeout <= smSaverRes.saverTimeout)
305 lockDelay = smSaverRes.lockTimeout - smSaverRes.saverTimeout;
309 smGD.coverScreen = 1;
314 * Before anything is done make sure we can unlock if we lock.
316 if (localAuthenticate(NULL, getuid(), NULL) == False)
319 PrintError(DtError, smNLS.trustedSystemErrorString);
321 XBell(smGD.display, 100);
324 * Tell the Workspace Manager to quit blinking
326 msg = tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
327 "DtActivity_Began", 0 );
328 tt_message_send( msg );
329 tt_message_destroy( msg );
335 if(((smDD.lockCoverDialog == NULL) && (smGD.coverScreen == True)) ||
336 ((smDD.lockDialog == NULL) && (smGD.coverScreen == False)))
339 * Set up the grab widget in here
344 * If the user has specified cover - create the cover dialog
346 screenNum = DefaultScreen(smGD.display);
347 if(smGD.coverScreen == True)
349 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
353 smDD.coverDialog[i] = CreateCoverDialog(i, True);
354 parent = smDD.coverDrawing[i];
358 smDD.coverDialog[i] = CreateCoverDialog(i, False);
361 smDD.lockCoverDialog = CreateLockDialogWithCover(parent);
365 * Create the lock dialog if the user has specified that
367 if((smDD.lockDialog == NULL) && (smGD.coverScreen == False))
369 smDD.lockDialog = CreateLockDialog();
372 * Get colors for the password cursor
375 XtSetArg(uiArgs[i], XmNtopShadowColor, &(xcolors[0]));i++;
376 XtSetArg(uiArgs[i], XmNbottomShadowColor, &(xcolors[1]));i++;
377 XtGetValues(smDD.lockDialog, uiArgs, i);
379 smGD.backgroundPix = xcolors[0].pixel;
380 smGD.foregroundPix = xcolors[1].pixel;
381 if (smGD.backgroundPix == smGD.foregroundPix)
383 smGD.backgroundPix = smGD.whitePixel;
384 smGD.foregroundPix = smGD.blackPixel;
390 * Wait for a visibility event to occur on the window so that
393 if(smGD.coverScreen == True)
395 smGD.lockCursor = smGD.blankCursor;
396 grabWidget = smDD.coverDialog[0];
397 lockDlg = smDD.lockCoverDialog;
398 lockDlgVisible = False; /* mappedWhenManaged False */
402 smGD.lockCursor = smGD.padlockCursor;
403 grabWidget = smDD.lockDialog;
404 lockDlg = smDD.lockDialog;
405 visibleY = hiddenY = -1;
409 * Note: grabWidget must be mapped in order to grab it. This means
410 * that if coverScreen is True, smDD.coverDialog[0] must be mapped
411 * immediately and if coverScreen is False, smDD.lockDialog must be
412 * mapped immediately. Also, if a grabWidget is unmapped, the grab
415 XtAddEventHandler(grabWidget, VisibilityChangeMask,
416 False, FinishLocking, NULL);
418 XtManageChild(lockDlg);
420 if(smGD.coverScreen == True) {
421 flash_id = XtAppAddTimeOut(smGD.appCon,
422 1000, BlinkCaret,smDD.indLabel[1]);
425 flash_id = XtAppAddTimeOut(smGD.appCon,
426 1000, BlinkCaret,smDD.indLabel[0]);
432 * Wait for 'lockDelay' seconds before requiring a password.
434 lockDelayId = XtAppAddTimeOut(smGD.appCon,
435 lockDelay*1000, RequirePassword, NULL);
438 else if (lockDelay == 0)
441 * Immediately require a password to unlock the display.
443 smGD.lockedState = LOCKED;
444 PutUpLogin(True, False); /* map, but don't set timeout */
447 if (smGD.coverScreen == True && smSaverRes.cycleTimeout > 0)
450 * Cycle to next saver in 'cycleTimeout' seconds.
452 cycleId = XtAppAddTimeOut(smGD.appCon,
453 smSaverRes.cycleTimeout*1000, CycleSaver, NULL);
456 if(smGD.coverScreen == True)
458 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
460 XtPopup(smDD.coverDialog[i], XtGrabNone);
465 * Add an event handler for when the keyboard and pointer are grabbed
467 XtAddEventHandler(grabWidget,
468 (KeyPressMask | ButtonPressMask | PointerMotionMask),
469 False, EventDetected, NULL);
471 /** wait 90 seconds for lock dialog to come up **/
472 lockTimeId = XtAppAddTimeOut(smGD.appCon,
473 90000, LockAttemptFailed, lockDlg);
479 /*************************************<->*************************************
486 * After the lock dialog is up - do the grab and lock the display
498 *************************************<->***********************************/
500 FinishLocking(Widget wid,
506 Boolean kbdGrabbed, pointerGrabbed;
509 if (lockTimeId == (XtIntervalId)0)
512 XtRemoveTimeOut(lockTimeId);
513 lockTimeId = (XtIntervalId)0;
514 XtRemoveEventHandler(wid, VisibilityChangeMask,
515 False, FinishLocking, NULL);
516 XSync(smGD.display, 0);
519 XtSetArg(uiArgs[i], XmNy, &visibleY);i++;
520 XtGetValues(wid, uiArgs, i);
522 hiddenY = (Position) DisplayHeight(smGD.display, smGD.screen) + 15;
525 * Color the cursor for this color scheme
529 XSync(smGD.display, 0);
532 * grab control of the keyboard for the entire display
534 rc = XtGrabKeyboard(grabWidget, False,
535 GrabModeAsync, GrabModeAsync,
537 kbdGrabbed = (rc == GrabSuccess);
539 #ifdef USE_HP_SPECIFIC_XLIB
540 XHPDisableReset(smGD.display);
541 #endif /* USE_HP_SPECIFIC_XLIB */
543 #if defined (AIXV3) && !defined(_POWER)
544 if(smGD.secureSystem)
546 SM_SETEUID(smGD.unLockUID);
548 SM_SETEUID(smGD.runningUID);
552 pointerGrabbed = (XtGrabPointer(grabWidget, False,
553 ButtonPressMask|PointerMotionMask,
554 GrabModeAsync, GrabModeAsync,
555 None, smGD.lockCursor, CurrentTime)
559 pointerGrabbed = (XtGrabPointer(grabWidget, False,
560 ButtonPressMask|PointerMotionMask,
561 GrabModeAsync, GrabModeAsync,
562 None, smGD.lockCursor, CurrentTime)
568 * If the grab failed - try 3 more times and give up
570 if((kbdGrabbed == False) || (pointerGrabbed == False))
572 for(j = 0;(j < 3) && ((pointerGrabbed == False) ||
573 (kbdGrabbed == False));j++)
576 * If a grab fails try one more time and then give up
578 if(kbdGrabbed == False)
581 kbdGrabbed = (XtGrabKeyboard(grabWidget, False,
582 GrabModeAsync, GrabModeAsync,
583 CurrentTime) == GrabSuccess);
586 if(pointerGrabbed == False)
589 pointerGrabbed = (XtGrabPointer(grabWidget, False,
594 None, smGD.lockCursor,
603 * Set status variable to lock if the lock has succeeded
605 if((pointerGrabbed != True) || (kbdGrabbed != True))
607 PrintError(DtError, smNLS.cantLockErrorString);
608 smGD.lockedState = UNLOCKED;
609 UnlockDisplay(pointerGrabbed, kbdGrabbed);
614 #ifdef LOCK_SERVER_ACCESS
616 * Wipe & enable X server access control list
618 hostList = XListHosts(smGD.display,
619 &hostListLen, (Bool *) &hostListActive);
620 XRemoveHosts(smGD.display, hostList, hostListLen);
621 XEnableAccessControl(smGD.display);
622 RestrictingAccess = True;
625 PutUpLogin(False, True); /* already mapped, but set timeout */
628 * Start external screen saver.
630 if (smGD.coverScreen)
640 /*************************************<->*************************************
642 * CreateLockCursor ()
647 * Creates a padlock cursor if the user has specified lock. Creates a
648 * blank cursor if the user has specified cover. Both are specified in the
649 * users resource file.
655 * buttonForm = widget from which cursor gets its color
656 * smGD.coverScreen = (global) cover screen or put up a padlock
662 * smGD.lockCursor = (global) cursor when lock is active (blank or padlock)
667 *************************************<->***********************************/
668 #define lock_m_hot_x 16
669 #define lock_m_hot_y 16
670 #define lock_m_bm_width 32
671 #define lock_m_bm_height 32
672 static unsigned char lock_m_bm_bits[] = {
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00,
674 0x00, 0xfc, 0x9f, 0x00, 0x00, 0x0e, 0x90, 0x01, 0x00, 0x06, 0x80, 0x01,
675 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01,
676 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01,
677 0x00, 0x06, 0x80, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c,
678 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
679 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f,
680 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
681 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f,
682 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
683 0xc0, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0x0f};
685 #define lock_m_m_bm_width 32
686 #define lock_m_m_bm_height 32
687 static unsigned char lock_m_m_bm_bits[] = {
688 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00,
689 0x00, 0xff, 0xff, 0x00, 0x80, 0x0f, 0xf0, 0x01, 0x80, 0x07, 0xe0, 0x01,
690 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01,
691 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01,
692 0x80, 0x07, 0xe0, 0x01, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
693 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
694 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
695 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
696 0xf0, 0xff, 0xff, 0x0f, 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};
700 #define lock_s_hot_x 7
701 #define lock_s_hot_y 8
702 #define lock_s_bm_width 13
703 #define lock_s_bm_height 16
704 static unsigned char lock_s_bm_bits[] = {
705 0x00, 0x02, 0x00, 0x04, 0xf0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
706 0x00, 0x00, 0xa8, 0x1a, 0x54, 0x1d, 0xa8, 0x1a, 0x54, 0x1d, 0xa8, 0x1a,
707 0x54, 0x1d, 0xa8, 0x1a, 0x54, 0x1d, 0xfe, 0x1f};
709 #define lock_s_m_bm_width 13
710 #define lock_s_m_bm_height 16
711 static unsigned char lock_s_m_bm_bits[] = {
712 0xf8, 0x03, 0xfc, 0x07, 0xfe, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
713 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f,
714 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f};
717 CreateLockCursor( void )
720 Colormap cmap = XDefaultColormap(smGD.display, smGD.screen);
722 char noCursorBits = 0x1;
724 if(InitCursorInfo() == False)
727 * Create the SMALL padlock cursor
729 source = XCreateBitmapFromData(smGD.display,
730 XRootWindow(smGD.display,
732 (char *) lock_s_bm_bits,
735 mask = XCreateBitmapFromData(smGD.display,
736 XRootWindow(smGD.display,
738 (char *) lock_s_m_bm_bits,
742 /* translate the Pixels into XColors */
743 xcolors[0].pixel = smGD.blackPixel;
744 xcolors[1].pixel = smGD.whitePixel;
745 XQueryColors(smGD.display, cmap, xcolors, 2);
747 /* create the padlock cursor */
748 smGD.padlockCursor = XCreatePixmapCursor(smGD.display, source, mask,
749 &(xcolors[0]), &(xcolors[1]),
752 XFreePixmap(smGD.display, source);
753 XFreePixmap(smGD.display, mask);
758 * Create the LARGE padlock cursor
760 source = XCreateBitmapFromData(smGD.display,
761 XRootWindow(smGD.display,
763 (char *) lock_m_bm_bits,
766 mask = XCreateBitmapFromData(smGD.display,
767 XRootWindow(smGD.display,
769 (char *) lock_m_m_bm_bits,
773 /* translate the Pixels into XColors */
774 xcolors[0].pixel = smGD.blackPixel;
775 xcolors[1].pixel = smGD.whitePixel;
776 XQueryColors(smGD.display, cmap, xcolors, 2);
778 /* create the padlock cursor */
779 smGD.padlockCursor = XCreatePixmapCursor(smGD.display, source, mask,
780 &(xcolors[0]), &(xcolors[1]),
783 XFreePixmap(smGD.display, source);
784 XFreePixmap(smGD.display, mask);
789 * create the blank cursor
791 source = XCreateBitmapFromData(smGD.display,
792 XRootWindow(smGD.display, smGD.screen),
793 &noCursorBits, 1, 1);
795 xcolors[0].pixel = smGD.blackPixel;
796 XQueryColor(smGD.display, cmap, &(xcolors[0]));
797 smGD.blankCursor = XCreatePixmapCursor(smGD.display, source, source,
798 &(xcolors[0]), &(xcolors[0]),
800 XFreePixmap(smGD.display, source);
805 /*************************************<->*************************************
812 * Recolors the padlock cursor to be the current color scheme. This has
813 * to be done because XCreatePixmapCursor allocates colors instead of jusst
814 * using a pixel value.
820 * smGD.backgroundPix = Pixel value to use for background color
821 * smGD.foregroundPix = Pixel value to use for foreground color
826 * smGD.lockCursor = (global) cursor when lock is active (padlock)
831 *************************************<->***********************************/
833 RecolorCursor( void )
835 Colormap cmap = XDefaultColormap(smGD.display, smGD.screen);
839 * translate the Pixels into XColors
841 xcolors[0].pixel = smGD.foregroundPix;
842 xcolors[1].pixel = smGD.backgroundPix;
843 XQueryColors(smGD.display, cmap, xcolors, 2);
846 * recolor the padlock cursor
848 XRecolorCursor(smGD.display, smGD.lockCursor, &(xcolors[0]),
854 /*************************************<->*************************************
856 * EventDetected (w, client_data, event)
861 * Callback routine that detects an event when the display is locked.
862 * If it's a correct password, it unlocks the display. Otherwise, it
863 * just displays status. The event is detected by the popup login dialog.
868 * w = widget where event occurred
869 * client_data = client specific data sent to callback
870 * event = event that triggered callback
879 *************************************<->***********************************/
883 XtPointer client_data,
889 XKeyEvent *event = (XKeyEvent *) ev;
891 if (smGD.lockedState == LOCKED)
893 if (lockDlgVisible == False)
896 * Anytime input is received - show the passwd dialog and
897 * discard event. This is so a keypress event that causes
898 * the passwd dialog to appear will not be used in the password.
901 PutUpLogin(True, True); /* map, and reset timeout */
904 PutUpLogin(False, True); /* already mapped, but reset timeout */
908 UnlockDisplay(True, True);
913 * If the detected event is anything but a keypress, processing is
914 * complete after refreshing the status string.
916 if (event->type != KeyPress)
920 * If XLookupString() returns anything (which it won't in the case of, say,
921 * pressing the shift key or an arrow key), process it.
923 #ifdef USE_HP_SPECIFIC_XLIB
924 if (len = XHPConvertLookup(event, str, sizeof(str), NULL, NULL,
925 XHPGetEurasianCvt(smGD.display)))
926 #else /* USE_HP_SPECIFIC_XLIB */
927 if (len = XLookupString (event, str, sizeof(str), NULL, NULL))
928 #endif /* USE_HP_SPECIFIC_XLIB */
930 if (smGD.lockedState == LOCKED)
931 CheckString(str, len);
937 /*************************************<->*************************************
944 * Check string entered by user. If it is a valid password, call routine to
945 * unlock the display. Otherwise, just keep track of what we have until
946 * the password is valid
951 * s = string passed in for checking
952 * i = length of string
961 *************************************<->***********************************/
967 /* maximum supported length of password */
969 #define MAX_PASSWORD_LENGTH SIAMXPASSWORD
971 /* seems to be reasonable maximal length */
972 #define MAX_PASSWORD_LENGTH 65535
975 /* step when allocating/extending buffer */
976 #define BUF_ALLOC_LEN 64
980 * - If pw_length > MAX_PASSWORD_LENGTH, we've gone over the limit and won't
982 * - An ESC kills the line.
984 static char *passwd = NULL; /* password space */
985 static int pw_buf_length = 0; /* length of allocated password buffer */
986 static int pw_length = 0; /* password length */
999 /* extend buffer by BUF_ALLOC_LEN bytes if needed*/
1000 #ifdef JET_AUTHDEBUG
1001 fprintf(stderr, "CheckString: pw_length=%d\n",pw_length);
1004 if (pw_length == pw_buf_length)
1006 tmpptr = SM_REALLOC(passwd, pw_buf_length + BUF_ALLOC_LEN);
1008 PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1011 pw_buf_length += BUF_ALLOC_LEN;
1018 pw_length--; /* back up one character */
1022 pw_length = 0; /* kill the character string */
1027 if (pw_length > MAX_PASSWORD_LENGTH)
1029 pw_length = MAX_PASSWORD_LENGTH;
1031 passwd[pw_length] = '\0'; /* terminate string */
1032 pw_length = 0; /* reset length */
1033 if (CheckPassword(passwd))
1035 UpdatePasswdField(0);
1036 UnlockDisplay(True, True);
1039 XBell(smGD.display, 100); /* wrong, laserbreath */
1043 if (pw_length < MAX_PASSWORD_LENGTH)
1045 passwd[pw_length++] = *s; /* store character */
1050 UpdatePasswdField(pw_length > MAX_PASSWORD_LENGTH ? MAX_PASSWORD_LENGTH : pw_length);
1055 /*************************************<->*************************************
1057 * CheckPassword (passwd)
1062 * Check the password to see if it is the user's, roots, or one of the
1063 * users specified in the host string
1068 * passwd = password passed in
1073 * True if it is a valid password, false otherwise.
1078 *************************************<->***********************************/
1086 if (Authenticate(NULL, getuid(), passwd) == True)
1088 return(True); /* user password ok */
1091 if (Authenticate(NULL, 0, passwd) == True)
1093 return(True); /* root password ok */
1096 /* check passwords of users specified as keyholders */
1097 if (smGD.keyholders == NULL)
1099 return(False); /* no keyholders */
1102 /* since strtok() is destructive, copy the keyholders string */
1103 keyholderbuf = (char *) SM_MALLOC(strlen(smGD.keyholders)+1);
1104 if(keyholderbuf == NULL)
1106 PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1107 return(False); /* no memory */
1110 strcpy(keyholderbuf, smGD.keyholders);
1111 for (p = keyholderbuf; (q = strtok(p, ", \t")) != NULL; p = NULL)
1113 if (Authenticate(q, -1, passwd) == True)
1115 SM_FREE(keyholderbuf);
1116 return(True); /* keyholder password ok */
1119 SM_FREE(keyholderbuf);
1121 return(False); /* no matches */
1126 /*************************************<->*************************************
1133 * If the user has entered a correct password, unlock the display and
1134 * uncover the root window.
1139 * pointerGrabbed - Boolean tells if pointer is currently grabbed
1140 * kbdGrabbed - Boolean tells if keyboard is currently grabbed
1150 *************************************<->***********************************/
1153 Boolean pointerGrabbed,
1159 #ifdef LOCK_SERVER_ACCESS
1161 * Restore X server access state
1163 if (RestrictingAccess) {
1164 XAddHosts(smGD.display, hostList, hostListLen);
1165 if (!hostListActive) XDisableAccessControl(smGD.display);
1166 RestrictingAccess = False;
1167 XFree((void *) hostList);
1172 * Stop external screen saver.
1177 * Remove the event handler to grab the events
1179 XtRemoveEventHandler(grabWidget,
1180 (KeyPressMask | ButtonPressMask | PointerMotionMask),
1181 False, EventDetected, NULL);
1186 if(lockDelayId != (XtIntervalId)0)
1188 XtRemoveTimeOut(lockDelayId);
1191 if(cycleId != (XtIntervalId)0)
1193 XtRemoveTimeOut(cycleId);
1196 if(timerId != (XtIntervalId)0)
1198 XtRemoveTimeOut(timerId);
1201 if(flash_id != (XtIntervalId)0)
1203 XtRemoveTimeOut(flash_id);
1206 if(pointerGrabbed == True)
1208 XtUngrabPointer(grabWidget, CurrentTime);
1211 if(kbdGrabbed == True)
1213 XtUngrabKeyboard(grabWidget, CurrentTime);
1216 #ifdef USE_HP_SPECIFIC_XLIB
1217 XHPEnableReset(smGD.display);
1218 #endif /* USE_HP_SPECIFIC_XLIB */
1220 #if defined (AIXV3) && !defined(_POWER)
1221 if(smGD.secureSystem)
1223 SM_SETEUID(smGD.unLockUID);
1224 AixEnableHftRing(1);
1225 SM_SETEUID(smGD.runningUID);
1229 XSync(smGD.display, 0);
1232 * Unmanage session lock dialogs. If LOCKDLG_PERSIST is undefined,
1233 * destroy them. This is so the passwd dialog icon colors get freed
1234 * since currently it uses a lot of colors.
1236 if(smGD.coverScreen == False)
1238 #if defined (LOCKDLG_PERSIST)
1239 if (XtIsManaged(smDD.lockDialog))
1241 XtUnmanageChild(smDD.lockDialog);
1244 XtDestroyWidget(smDD.lockDialog);
1245 smDD.lockDialog = NULL;
1250 #if defined (LOCKDLG_PERSIST)
1251 if(!XtIsManaged(smDD.lockCoverDialog))
1253 XtManageChild(smDD.lockCoverDialog);
1256 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1258 XtPopdown(smDD.coverDialog[i]);
1261 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1263 XtDestroyWidget(smDD.coverDialog[i]);
1264 smDD.coverDialog[i] = NULL;
1266 smDD.lockCoverDialog = NULL;
1270 smGD.lockedState = UNLOCKED;
1272 XSync(smGD.display, 0);
1275 * Tell the Workspace Manager to unlock the display (depress the lock
1277 if(smGD.bmsDead == False)
1279 msg = tttk_message_create(0, TT_REQUEST, TT_SESSION, 0,
1280 "Display_Unlock", 0);
1281 tt_message_send(msg);
1282 tt_message_destroy(msg);
1290 static Position visibleY = -1;
1291 static Position hiddenY = -1;
1294 /*************************************<->*************************************
1301 * When a timeout occurs - take down the login screen by unmanaging it.
1315 *************************************<->***********************************/
1318 XtPointer client_data,
1321 if (lockDlgVisible == True)
1323 if (smGD.coverScreen == True)
1325 XtUnmapWidget(smDD.lockCoverDialog);
1332 XtSetArg(uiArgs[i], XmNy, hiddenY);i++;
1333 XtSetValues(smDD.lockDialog, uiArgs, i);
1337 timerId = (XtIntervalId)0;
1340 * Clear partially entered password if any.
1342 CheckString(NULL, 0);
1343 lockDlgVisible = False;
1345 XSync(smGD.display, 0);
1350 /*************************************<->*************************************
1357 * Redisplays the cover and the login when necessary.
1371 *************************************<->***********************************/
1377 if (map == True && lockDlgVisible == False)
1379 if (smGD.coverScreen == True)
1381 XtMapWidget(smDD.lockCoverDialog);
1388 XtSetArg(uiArgs[i], XmNy, visibleY);i++;
1389 XtSetValues(smDD.lockDialog, uiArgs, i);
1392 lockDlgVisible = True;
1395 if (timeout == True)
1397 if(timerId != (XtIntervalId)0)
1399 XtRemoveTimeOut(timerId);
1402 if(smRes.alarmTime > 0)
1404 timerId = XtAppAddTimeOut(smGD.appCon,
1405 (smRes.alarmTime * 1000),
1406 TakeDownLogin,NULL);
1409 XSync(smGD.display, 0);
1413 /*************************************<->*************************************
1415 * LockAttemptFailed ()
1420 * Timed out trying to get a visibilitynotify on the lock
1434 *************************************<->***********************************/
1436 LockAttemptFailed(XtPointer ptr,
1437 XtIntervalId *invId)
1439 Widget lockWid = (Widget) ptr;
1441 PrintError(DtError, smNLS.cantLockErrorString);
1442 smGD.lockedState = UNLOCKED;
1443 XtRemoveEventHandler(lockWid, VisibilityChangeMask,
1444 False, FinishLocking, NULL);
1445 UnlockDisplay(False, False);
1446 XSync(smGD.display, 0);
1452 /*************************************<->*************************************
1454 * RequirePassword ()
1459 * Callback indicating a password is now required to unlock display.
1473 *************************************<->***********************************/
1475 RequirePassword(XtPointer ptr,
1476 XtIntervalId *invId)
1478 smGD.lockedState = LOCKED;
1482 /*************************************<->*************************************
1489 * blinks the caret in the password field
1503 *************************************<->***********************************/
1505 BlinkCaret(XtPointer ptr,
1506 XtIntervalId *invId)
1508 static int flag = 1;
1513 * Blink cursor to show the focus ..
1516 tmpString = XmStringCreateLocalized (" " );
1518 XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1519 XtSetValues(ptr, uiArgs, i);
1523 tmpString = XmStringCreateLocalized ("|");
1525 XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1526 XtSetValues(ptr, uiArgs, i);
1530 XmStringFree(tmpString);
1531 flash_id = XtAppAddTimeOut(smGD.appCon, 1000,
1537 /*************************************<->*************************************
1544 * Callback indicating we should cycle to next screen saver
1558 *************************************<->***********************************/
1560 CycleSaver(XtPointer ptr,
1561 XtIntervalId *invId)
1564 * Stop running screen saver, start a new one and reset timer.
1568 cycleId = XtAppAddTimeOut(smGD.appCon, smSaverRes.cycleTimeout*1000,
1574 /*************************************<->*************************************
1576 * localAuthenticate (name, uid, passwd)
1593 *************************************<->***********************************/
1604 char *Argv[2] = { "dtsession", NULL };
1606 SIAENTITY *se = NULL;
1612 real_uid = getuid();
1614 if (-1 == seteuid(0))
1621 * Caller just checking if it is possible to access
1622 * password file (ie is dtsession suid bit set properly).
1627 if (name && name[0])
1632 pw_name = getlogin();
1635 if ( sia_ses_init(&se, 1, Argv, (char *)NULL,
1636 pw_name, NULL, 0 /* don't collect info */,
1637 NULL) != SIASUCCESS)
1643 se->password = (char *)malloc(strlen(passwd) + 1);
1644 if ( se->password == (char *)NULL )
1646 sia_ses_release(&se);
1651 strcpy(se->password, passwd);
1653 code = sia_ses_reauthent (NULL, se);
1654 sia_ses_release(&se);
1658 if ( code == SIASUCCESS )
1664 #elif defined(__linux__)
1667 struct passwd *pwent = NULL;
1671 Boolean done = False;
1672 struct spwd *sp = NULL;
1674 if(smGD.secureSystem)
1676 SM_SETEUID(smGD.unLockUID);
1680 * Get password entry for 'name' or 'uid'.
1682 if (CanReAuthenticate(name, uid, passwd, &pwent, &sp) == False)
1691 if(smGD.secureSystem)
1693 SM_SETEUID(smGD.runningUID);
1699 if (pwent->pw_passwd == NULL || pwent->pw_passwd[0] == '*')
1702 if (sp == NULL || sp->sp_pwdp == NULL)
1705 * Could not read password.
1718 * Caller just checking if it is possible to access
1719 * password file (ie is dtsession suid bit set properly).
1732 if (sp != NULL && !strcmp(sp->sp_pwdp, crypt(passwd,sp->sp_pwdp)))
1733 { /* a shadow match */
1737 else if (pwent != NULL &&
1738 !strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)))
1739 { /* passwd match */
1744 { /* failure dude! */
1759 register struct passwd *pwent;
1763 Boolean done = False;
1767 struct spwd *sp=NULL;
1770 if(smGD.secureSystem)
1772 SM_SETEUID(smGD.unLockUID);
1777 * Get shadow password entry for 'name' or 'uid'.
1781 pwent = getpwuid(uid);
1784 name = pwent->pw_name;
1789 (sp = getspnam(name)) == NULL
1800 * Get password entry for 'name' or 'uid'.
1802 if ((pwent = (name == NULL ? getpwuid(uid) : getpwnam(name))) == NULL)
1812 if(smGD.secureSystem)
1814 SM_SETEUID(smGD.runningUID);
1820 pwent->pw_passwd == NULL
1821 || pwent->pw_passwd[0] == '*'
1828 * Could not read password.
1840 * Caller just checking if it is possible to access
1841 * password file (ie is dtsession suid bit set properly).
1854 if (strcmp(crypt(passwd,sp->sp_pwdp),sp->sp_pwdp) != 0)
1856 if (strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)) != 0)
1860 * Password incorrect.
1877 /*************************************<->*************************************
1879 * Authenticate (name, uid, passwd)
1896 *************************************<->***********************************/
1898 #if defined (_AIX) && defined(_POWER)
1906 register struct passwd *pwent;
1910 Boolean done = False;
1914 char *newname = NULL;
1917 if(smGD.secureSystem)
1919 SM_SETEUID(smGD.unLockUID);
1927 pwent = getpwuid(uid);
1930 name = newname = strdup(pwent->pw_name);
1936 * Authenticate user. Note: normally, we should check 'reenter' to
1937 * see if the user has another challenge. Since the dtsession screen
1938 * lock i/f does not yet have the support, our policy is to let the
1939 * user back in if they pass the first (password) challenge.
1941 arc = authenticate(name, passwd, &reenter, &msg);
1943 if(smGD.secureSystem)
1945 SM_SETEUID(smGD.runningUID);
1949 if (newname) free(newname);
1951 return(arc == 0 ? True : False);
1953 #endif /* _AIX && _POWER */