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 *************************************<->***********************************/
972 /* maximum supported length of password */
974 #define MAX_PASSWORD_LENGTH SIAMXPASSWORD
976 /* seems to be reasonable maximal length */
977 #define MAX_PASSWORD_LENGTH 65535
980 /* step when allocating/extending buffer */
981 #define BUF_ALLOC_LEN 64
985 * - If pw_length > MAX_PASSWORD_LENGTH, we've gone over the limit and won't
987 * - An ESC kills the line.
989 static char *passwd = NULL; /* password space */
990 static int pw_buf_length = 0; /* length of allocated password buffer */
991 static int pw_length = 0; /* password length */
1002 for (; i>0; s++,i--)
1004 /* extend buffer by BUF_ALLOC_LEN bytes if needed*/
1005 #ifdef JET_AUTHDEBUG
1006 fprintf(stderr, "CheckString: pw_length=%d\n",pw_length);
1009 if (pw_length == pw_buf_length)
1011 tmpptr = SM_REALLOC(passwd, pw_buf_length + BUF_ALLOC_LEN);
1013 PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1016 pw_buf_length += BUF_ALLOC_LEN;
1023 pw_length--; /* back up one character */
1027 pw_length = 0; /* kill the character string */
1032 if (pw_length > MAX_PASSWORD_LENGTH)
1034 pw_length = MAX_PASSWORD_LENGTH;
1036 passwd[pw_length] = '\0'; /* terminate string */
1037 pw_length = 0; /* reset length */
1038 if (CheckPassword(passwd))
1040 UpdatePasswdField(0);
1041 UnlockDisplay(True, True);
1044 XBell(smGD.display, 100); /* wrong, laserbreath */
1048 if (pw_length < MAX_PASSWORD_LENGTH)
1050 passwd[pw_length++] = *s; /* store character */
1055 UpdatePasswdField(pw_length > MAX_PASSWORD_LENGTH ? MAX_PASSWORD_LENGTH : pw_length);
1060 /*************************************<->*************************************
1062 * CheckPassword (passwd)
1067 * Check the password to see if it is the user's, roots, or one of the
1068 * users specified in the host string
1073 * passwd = password passed in
1078 * True if it is a valid password, false otherwise.
1083 *************************************<->***********************************/
1091 if (Authenticate(NULL, getuid(), passwd) == True)
1093 return(True); /* user password ok */
1096 if (Authenticate(NULL, 0, passwd) == True)
1098 return(True); /* root password ok */
1101 /* check passwords of users specified as keyholders */
1102 if (smGD.keyholders == NULL)
1104 return(False); /* no keyholders */
1107 /* since strtok() is destructive, copy the keyholders string */
1108 keyholderbuf = (char *) SM_MALLOC(strlen(smGD.keyholders)+1);
1109 if(keyholderbuf == NULL)
1111 PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1112 return(False); /* no memory */
1115 strcpy(keyholderbuf, smGD.keyholders);
1116 for (p = keyholderbuf; (q = strtok(p, ", \t")) != NULL; p = NULL)
1118 if (Authenticate(q, -1, passwd) == True)
1120 SM_FREE(keyholderbuf);
1121 return(True); /* keyholder password ok */
1124 SM_FREE(keyholderbuf);
1126 return(False); /* no matches */
1131 /*************************************<->*************************************
1138 * If the user has entered a correct password, unlock the display and
1139 * uncover the root window.
1144 * pointerGrabbed - Boolean tells if pointer is currently grabbed
1145 * kbdGrabbed - Boolean tells if keyboard is currently grabbed
1155 *************************************<->***********************************/
1158 Boolean pointerGrabbed,
1164 #ifdef LOCK_SERVER_ACCESS
1166 * Restore X server access state
1168 if (RestrictingAccess) {
1169 XAddHosts(smGD.display, hostList, hostListLen);
1170 if (!hostListActive) XDisableAccessControl(smGD.display);
1171 RestrictingAccess = False;
1172 XFree((void *) hostList);
1177 * Stop external screen saver.
1182 * Remove the event handler to grab the events
1184 XtRemoveEventHandler(grabWidget,
1185 (KeyPressMask | ButtonPressMask | PointerMotionMask),
1186 False, EventDetected, NULL);
1191 if(lockDelayId != (XtIntervalId)0)
1193 XtRemoveTimeOut(lockDelayId);
1196 if(cycleId != (XtIntervalId)0)
1198 XtRemoveTimeOut(cycleId);
1201 if(timerId != (XtIntervalId)0)
1203 XtRemoveTimeOut(timerId);
1206 if(flash_id != (XtIntervalId)0)
1208 XtRemoveTimeOut(flash_id);
1211 if(pointerGrabbed == True)
1213 XtUngrabPointer(grabWidget, CurrentTime);
1216 if(kbdGrabbed == True)
1218 XtUngrabKeyboard(grabWidget, CurrentTime);
1221 #ifdef USE_HP_SPECIFIC_XLIB
1222 XHPEnableReset(smGD.display);
1223 #endif /* USE_HP_SPECIFIC_XLIB */
1225 #if defined (AIXV3) && !defined(_POWER)
1226 if(smGD.secureSystem)
1228 SM_SETEUID(smGD.unLockUID);
1229 AixEnableHftRing(1);
1230 SM_SETEUID(smGD.runningUID);
1234 XSync(smGD.display, 0);
1237 * Unmanage session lock dialogs. If LOCKDLG_PERSIST is undefined,
1238 * destroy them. This is so the passwd dialog icon colors get freed
1239 * since currently it uses a lot of colors.
1241 if(smGD.coverScreen == False)
1243 #if defined (LOCKDLG_PERSIST)
1244 if (XtIsManaged(smDD.lockDialog))
1246 XtUnmanageChild(smDD.lockDialog);
1249 XtDestroyWidget(smDD.lockDialog);
1250 smDD.lockDialog = NULL;
1255 #if defined (LOCKDLG_PERSIST)
1256 if(!XtIsManaged(smDD.lockCoverDialog))
1258 XtManageChild(smDD.lockCoverDialog);
1261 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1263 XtPopdown(smDD.coverDialog[i]);
1266 for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1268 XtDestroyWidget(smDD.coverDialog[i]);
1269 smDD.coverDialog[i] = NULL;
1271 smDD.lockCoverDialog = NULL;
1275 smGD.lockedState = UNLOCKED;
1277 XSync(smGD.display, 0);
1280 * Tell the Workspace Manager to unlock the display (depress the lock
1282 if(smGD.bmsDead == False)
1284 msg = tttk_message_create(0, TT_REQUEST, TT_SESSION, 0,
1285 "Display_Unlock", 0);
1286 tt_message_send(msg);
1287 tt_message_destroy(msg);
1295 static Position visibleY = -1;
1296 static Position hiddenY = -1;
1299 /*************************************<->*************************************
1306 * When a timeout occurs - take down the login screen by unmanaging it.
1320 *************************************<->***********************************/
1323 XtPointer client_data,
1326 if (lockDlgVisible == True)
1328 if (smGD.coverScreen == True)
1330 XtUnmapWidget(smDD.lockCoverDialog);
1337 XtSetArg(uiArgs[i], XmNy, hiddenY);i++;
1338 XtSetValues(smDD.lockDialog, uiArgs, i);
1342 timerId = (XtIntervalId)0;
1345 * Clear partially entered password if any.
1347 CheckString(NULL, 0);
1348 lockDlgVisible = False;
1350 XSync(smGD.display, 0);
1355 /*************************************<->*************************************
1362 * Redisplays the cover and the login when neccessary.
1376 *************************************<->***********************************/
1382 if (map == True && lockDlgVisible == False)
1384 if (smGD.coverScreen == True)
1386 XtMapWidget(smDD.lockCoverDialog);
1393 XtSetArg(uiArgs[i], XmNy, visibleY);i++;
1394 XtSetValues(smDD.lockDialog, uiArgs, i);
1397 lockDlgVisible = True;
1400 if (timeout == True)
1402 if(timerId != (XtIntervalId)0)
1404 XtRemoveTimeOut(timerId);
1407 if(smRes.alarmTime > 0)
1409 timerId = XtAppAddTimeOut(smGD.appCon,
1410 (smRes.alarmTime * 1000),
1411 TakeDownLogin,NULL);
1414 XSync(smGD.display, 0);
1418 /*************************************<->*************************************
1420 * LockAttemptFailed ()
1425 * Timed out trying to get a visibilitynotify on the lock
1439 *************************************<->***********************************/
1441 LockAttemptFailed(XtPointer ptr,
1442 XtIntervalId *invId)
1444 Widget lockWid = (Widget) ptr;
1446 PrintError(DtError, smNLS.cantLockErrorString);
1447 smGD.lockedState = UNLOCKED;
1448 XtRemoveEventHandler(lockWid, VisibilityChangeMask,
1449 False, FinishLocking, NULL);
1450 UnlockDisplay(False, False);
1451 XSync(smGD.display, 0);
1457 /*************************************<->*************************************
1459 * RequirePassword ()
1464 * Callback indicating a password is now required to unlock display.
1478 *************************************<->***********************************/
1480 RequirePassword(XtPointer ptr,
1481 XtIntervalId *invId)
1483 smGD.lockedState = LOCKED;
1487 /*************************************<->*************************************
1494 * blinks the caret in the password field
1508 *************************************<->***********************************/
1510 BlinkCaret(XtPointer ptr,
1511 XtIntervalId *invId)
1513 static int flag = 1;
1518 * Blink cursor to show the focus ..
1521 tmpString = XmStringCreateLocalized (" " );
1523 XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1524 XtSetValues(ptr, uiArgs, i);
1528 tmpString = XmStringCreateLocalized ("|");
1530 XtSetArg(uiArgs[i], XmNlabelString, tmpString); i++;
1531 XtSetValues(ptr, uiArgs, i);
1535 XmStringFree(tmpString);
1536 flash_id = XtAppAddTimeOut(smGD.appCon, 1000,
1542 /*************************************<->*************************************
1549 * Callback indicating we should cycle to next screen saver
1563 *************************************<->***********************************/
1565 CycleSaver(XtPointer ptr,
1566 XtIntervalId *invId)
1569 * Stop running screen saver, start a new one and reset timer.
1573 cycleId = XtAppAddTimeOut(smGD.appCon, smSaverRes.cycleTimeout*1000,
1579 /*************************************<->*************************************
1581 * localAuthenticate (name, uid, passwd)
1598 *************************************<->***********************************/
1609 char *Argv[2] = { "dtsession", NULL };
1611 SIAENTITY *se = NULL;
1617 real_uid = getuid();
1619 if (-1 == seteuid(0))
1626 * Caller just checking if it is possible to access
1627 * password file (ie is dtsession suid bit set properly).
1632 if (name && name[0])
1637 pw_name = getlogin();
1640 if ( sia_ses_init(&se, 1, Argv, (char *)NULL,
1641 pw_name, NULL, 0 /* don't collect info */,
1642 NULL) != SIASUCCESS)
1648 se->password = (char *)malloc(strlen(passwd) + 1);
1649 if ( se->password == (char *)NULL )
1651 sia_ses_release(&se);
1656 strcpy(se->password, passwd);
1658 code = sia_ses_reauthent (NULL, se);
1659 sia_ses_release(&se);
1663 if ( code == SIASUCCESS )
1669 #elif defined(linux)
1672 struct passwd *pwent = NULL;
1676 Boolean done = False;
1677 struct spwd *sp = NULL;
1679 if(smGD.secureSystem)
1681 SM_SETEUID(smGD.unLockUID);
1685 * Get password entry for 'name' or 'uid'.
1687 if (CanReAuthenticate(name, uid, passwd, &pwent, &sp) == False)
1696 if(smGD.secureSystem)
1698 SM_SETEUID(smGD.runningUID);
1704 if (pwent->pw_passwd == NULL || pwent->pw_passwd[0] == '*')
1707 if (sp == NULL || sp->sp_pwdp == NULL)
1710 * Could not read password.
1723 * Caller just checking if it is possible to access
1724 * password file (ie is dtsession suid bit set properly).
1737 if (sp != NULL && !strcmp(sp->sp_pwdp, crypt(passwd,sp->sp_pwdp)))
1738 { /* a shadow match */
1742 else if (pwent != NULL &&
1743 !strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)))
1744 { /* passwd match */
1749 { /* failure dude! */
1764 register struct passwd *pwent;
1768 Boolean done = False;
1774 char *upasswd, *newname = NULL;
1776 struct spwd *sp=NULL;
1780 if(smGD.secureSystem)
1782 SM_SETEUID(smGD.unLockUID);
1787 * Get shadow password entry for 'name' or 'uid'.
1791 pwent = getpwuid(uid);
1795 name = newname = strdup(pwent->pw_name);
1797 name = pwent->pw_name;
1804 ia_openinfo(name, &uinfo)
1806 (sp = getspnam(name)) == NULL
1818 * Get password entry for 'name' or 'uid'.
1820 if ((pwent = (name == NULL ? getpwuid(uid) : getpwnam(name))) == NULL)
1830 if(smGD.secureSystem)
1832 SM_SETEUID(smGD.runningUID);
1838 ia_get_logpwd(uinfo, &upasswd);
1841 pwent->pw_passwd == NULL
1842 || pwent->pw_passwd[0] == '*'
1853 * Could not read password.
1865 * Caller just checking if it is possible to access
1866 * password file (ie is dtsession suid bit set properly).
1880 if (strcmp(crypt(passwd, upasswd), upasswd) != 0)
1882 if (strcmp(crypt(passwd,sp->sp_pwdp),sp->sp_pwdp) != 0)
1885 if (strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)) != 0)
1889 * Password incorrect.
1899 ia_closeinfo(uinfo);
1900 if (newname) free(newname);
1911 /*************************************<->*************************************
1913 * Authenticate (name, uid, passwd)
1930 *************************************<->***********************************/
1932 #if defined (_AIX) && defined(_POWER)
1940 register struct passwd *pwent;
1944 Boolean done = False;
1948 char *newname = NULL;
1951 if(smGD.secureSystem)
1953 SM_SETEUID(smGD.unLockUID);
1961 pwent = getpwuid(uid);
1964 name = newname = strdup(pwent->pw_name);
1970 * Authenticate user. Note: normally, we should check 'reenter' to
1971 * see if the user has another challenge. Since the dtsession screen
1972 * lock i/f does not yet have the support, our policy is to let the
1973 * user back in if they pass the first (password) challenge.
1975 arc = authenticate(name, passwd, &reenter, &msg);
1977 if(smGD.secureSystem)
1979 SM_SETEUID(smGD.runningUID);
1983 if (newname) free(newname);
1985 return(arc == 0 ? True : False);
1987 #endif /* _AIX && _POWER */