dtsession: fix screen saver/locking on linux
[oweals/cde.git] / cde / programs / dtsession / SmLock.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
23 /* $XConsortium: SmLock.c /main/8 1996/10/30 11:13:55 drk $ */
24 /*                                                                      *
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.                                *
29  */
30 /*************************************<+>*************************************
31  *****************************************************************************
32  **
33  **  File:        SmLock.c
34  **
35  **  Project:     HP DT Session Manager (dtsession)
36  **
37  **  Description:
38  **  -----------
39  **  In charge of locking and unlocking the display in response from
40  **  the front panel to so.
41  **
42  **
43  **
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  ********************************************************************
50  **
51  **
52  **
53  *****************************************************************************
54  *************************************<+>*************************************/
55
56
57 #include <stdio.h>
58 #include <errno.h>
59 #include <pwd.h>
60 #include <string.h>
61 #include <fcntl.h>
62
63 #ifdef SIA
64 #include <sia.h>
65 #endif
66  
67 #ifdef USE_HP_SPECIFIC_XLIB
68 #include <X11/XHPlib.h>
69 #endif /* USE_HP_SPECIFIC_XLIB */
70
71 #include <X11/Intrinsic.h>
72 #include <Xm/Xm.h>
73 #include <Dt/UserMsg.h>
74 #include <Dt/Indicator.h>
75 #include <Tt/tttk.h>
76 #ifdef SVR4
77 #  include <shadow.h>
78 #endif
79
80 #if defined(__linux__)
81 # include <shadow.h>
82 #endif
83 #if defined(CSRG_BASED)
84 #include <sys/types.h>
85 #include <pwd.h>
86 #endif
87
88 #include "Sm.h"
89 #include "SmGlobals.h"
90 #include "SmUI.h"
91 #include "SmError.h"
92 #include "SmLock.h"
93 #include "SmScreen.h"
94
95 /*
96  * Variables global to this module only
97  */
98
99 /*
100  * Global timer value
101  */
102 static XtIntervalId             timerId, lockTimeId, lockDelayId, cycleId, flash_id;
103
104 /*
105  * Global grab widget
106  */
107 static Widget                   grabWidget;
108
109 /*
110  * Lock dialog visibility
111  */
112 static Boolean                  lockDlgVisible;
113
114 #ifdef LOCK_SERVER_ACCESS
115 /* 
116  * Server Access Control Information
117  */
118 static Boolean                  RestrictingAccess = False;
119 static XHostAddress             *hostList;
120 static Bool                     hostListActive;
121 static int                      hostListLen;
122 #endif
123
124 /*
125  * Local Functions
126  */
127
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 * ) ;
135 #else
136 #define Authenticate(A,B,C) localAuthenticate(A,B,C)
137 #endif
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 *) ;
146
147 #if defined(__linux__)
148 /* #define JET_AUTHDEBUG */
149
150 /* Test for re-auth ability - see if we can re-authenticate via pwd,
151  * shadow, or NIS
152  */
153 static Boolean CanReAuthenticate(char *name, uid_t uid, char *passwd,
154                                  struct passwd **pwent, struct spwd **spent)
155 {
156   if (!pwent)
157       return False;
158
159   *pwent = (name == NULL) ? getpwuid(uid) : getpwnam(name);
160   if (!*pwent)
161       return False;
162
163   *spent = getspnam((*pwent)->pw_name);
164
165 #ifdef JET_AUTHDEBUG
166   fprintf(stderr, "CanReAuthenticate(): uid: %d name: '%s' errno %d %s %s %s\n",
167           uid,
168           (name) ? name : "NULL",
169           errno,
170           (*pwent) ? "PWENT" : "NULL",
171           (*spent) ? "SPENT" : "NULL",
172           (name) ? name : "NULL");
173 #endif
174
175   /* some checking for aging stuff on RedPhat */
176
177   if (*pwent && (*pwent)->pw_passwd)
178     {
179       char *loc;
180
181       if ((loc = strchr((*pwent)->pw_passwd, ',')) != NULL)
182         *loc = '\0';
183 #ifdef JET_AUTHDEBUG
184       fprintf(stderr, "CanReAuthenticate(): pw: '%s'\n",
185               (*pwent)->pw_passwd);
186 #endif
187
188     }
189
190   if (*spent && (*spent)->sp_pwdp)
191     {
192       char *loc;
193
194       if ((loc = strchr((*spent)->sp_pwdp, ',')) != NULL)
195         *loc = '\0';
196     }
197
198   if (*pwent == NULL)
199     {                           /* if we can't get this, we're screwed. */
200 #ifdef JET_AUTHDEBUG
201       fprintf(stderr, "CanReAuthenticate(): PWENT == NULL - FALSE\n");
202 #endif
203       return False;
204     }
205
206   if ((*pwent)->pw_passwd == NULL)
207     {
208 #ifdef JET_AUTHDEBUG
209       fprintf(stderr, "CanReAuthenticate(): (*pwent)->pw_passwd == NULL - FALSE\n");
210 #endif
211
212       return False;
213     }
214
215   /* ok, now we have the prequisite data, look first to see if the
216    * passwd field is larger than 1 char - implying NIS, or a shadowed
217    * system.  if not look for *spent being non-NULL
218    */
219   if (*spent == NULL)
220     {                           /* if it's null, lets check for the NIS case */
221       if (strlen((*pwent)->pw_passwd) <= 1)
222         {
223 #ifdef JET_AUTHDEBUG
224           fprintf(stderr, "strlen((*pwent)->pw_passwd) <= 1\n");
225 #endif
226
227           return False;         /* not NIS */
228         }
229     }
230
231                                 /* supposedly we have valid data */
232 #ifdef JET_AUTHDEBUG
233       fprintf(stderr, "CanReAuthenticate(): TRUE\n");
234 #endif
235
236   return True;
237 }
238
239 #endif /* linux */
240
241
242
243 \f
244 /*************************************<->*************************************
245  *
246  *  LockDisplay ()
247  *
248  *
249  *  Description:
250  *  -----------
251  *  Calls the routines that are in charge of locking the display.
252  *
253  *
254  *  Inputs:
255  *  ------
256  *  lockNow - request to lock the display immediately
257  * 
258  *  Outputs:
259  *  -------
260  *
261  *  Comments:
262  *  --------
263  * 
264  *************************************<->***********************************/
265 /*
266  * Place holders for the lock position
267  */
268 static Position visibleY;
269 static Position hiddenY;
270
271 void 
272 LockDisplay( 
273   Boolean lockNow) 
274 {
275     register int i;
276     int      screenNum;
277     Widget   parent = NULL, lockDlg;
278     XColor   xcolors[2];
279     struct passwd *pw;
280     Boolean  secure;
281     int lockDelay;
282     int rc;
283
284     timerId = lockTimeId = lockDelayId = cycleId = flash_id = (XtIntervalId)0;
285
286    /*
287     * coverScreen 
288     *  0 - screen will not be covered, nor will external screen saver run
289     *  1 - screen will be covered, external screen saver may be run
290     *
291     * lockDelay
292     * -1 = no password required to unlock display
293     *  0 = password always required to unlock display
294     *  N = password required to unlock display after N seconds
295     */ 
296     if (smSaverRes.saverTimeout == 0)
297     {
298       smGD.coverScreen = 0; 
299       lockDelay = 0;        
300     }
301     else if (lockNow || smSaverRes.lockTimeout > 0)
302     {
303       smGD.coverScreen = 1; 
304       if (lockNow)
305         lockDelay = 0; 
306       else if (smSaverRes.lockTimeout == 0)
307         lockDelay = -1; 
308       else if (smSaverRes.lockTimeout <= smSaverRes.saverTimeout)
309         lockDelay = 0; 
310       else
311         lockDelay = smSaverRes.lockTimeout - smSaverRes.saverTimeout;
312     }
313     else
314     {
315       smGD.coverScreen = 1;
316       lockDelay = -1;
317     }
318
319     /*
320      * Before anything is done make sure we can unlock if we lock. 
321      */
322     if (localAuthenticate(NULL, getuid(), NULL) == False)
323        {
324         Tt_message msg;
325         PrintError(DtError, smNLS.trustedSystemErrorString);
326
327         XBell(smGD.display, 100);
328         
329         /*
330          * Tell the Workspace Manager to quit blinking
331          */
332         msg = tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
333                                    "DtActivity_Began", 0 );
334         tt_message_send( msg );
335         tt_message_destroy( msg );
336         SetSystemReady();
337
338         return;
339     }
340      
341     if(((smDD.lockCoverDialog == NULL) && (smGD.coverScreen == True)) ||
342        ((smDD.lockDialog == NULL) && (smGD.coverScreen == False)))
343     {
344         /*
345          * Set up the grab widget in here
346          */
347         grabWidget = NULL;
348
349         /*
350          * If the user has specified cover - create the cover dialog
351          */
352         screenNum = DefaultScreen(smGD.display);
353         if(smGD.coverScreen == True)
354         {
355             for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
356             {
357                 if(i == screenNum)
358                 {
359                     smDD.coverDialog[i] = CreateCoverDialog(i, True);
360                     parent = smDD.coverDrawing[i];
361                 }
362                 else
363                 {
364                     smDD.coverDialog[i] = CreateCoverDialog(i, False);
365                 }
366             }
367             smDD.lockCoverDialog = CreateLockDialogWithCover(parent);
368         }
369         
370         /*
371          * Create the lock dialog if the user has specified that
372          */
373         if((smDD.lockDialog == NULL) && (smGD.coverScreen == False))
374         {
375             smDD.lockDialog = CreateLockDialog();
376
377             /*
378              * Get colors for the password cursor
379              */
380             i = 0;
381             XtSetArg(uiArgs[i], XmNtopShadowColor, &(xcolors[0]));i++;
382             XtSetArg(uiArgs[i], XmNbottomShadowColor, &(xcolors[1]));i++;
383             XtGetValues(smDD.lockDialog, uiArgs, i);
384
385             smGD.backgroundPix = xcolors[0].pixel;
386             smGD.foregroundPix = xcolors[1].pixel;
387             if (smGD.backgroundPix == smGD.foregroundPix)
388             {
389                 smGD.backgroundPix = smGD.whitePixel;
390                 smGD.foregroundPix = smGD.blackPixel;
391             }           
392         }
393     }
394
395    /*
396     * Wait for a visibility event to occur on the window so that
397     * we can grab it
398     */
399     if(smGD.coverScreen == True)
400     {
401        smGD.lockCursor = smGD.blankCursor;
402        grabWidget = smDD.coverDialog[0];
403        lockDlg = smDD.lockCoverDialog;
404        lockDlgVisible = False; /* mappedWhenManaged False */
405     }
406     else
407     {
408        smGD.lockCursor = smGD.padlockCursor;
409        grabWidget = smDD.lockDialog;
410        lockDlg = smDD.lockDialog;
411        visibleY = hiddenY = -1;
412     }
413
414    /*
415     * Note: grabWidget must be mapped in order to grab it. This means
416     * that if coverScreen is True, smDD.coverDialog[0] must be mapped
417     * immediately and if coverScreen is False, smDD.lockDialog must be
418     * mapped immediately. Also, if a grabWidget is unmapped, the grab
419     * is lost. Ah X.
420     */
421     XtAddEventHandler(grabWidget, VisibilityChangeMask,
422                       False, FinishLocking, NULL);
423
424     XtManageChild(lockDlg);
425
426     if(smGD.coverScreen == True) {
427         flash_id = XtAppAddTimeOut(smGD.appCon,
428                                1000, BlinkCaret,smDD.indLabel[1]);
429     }
430     else{
431         flash_id = XtAppAddTimeOut(smGD.appCon,
432                                1000, BlinkCaret,smDD.indLabel[0]);
433     }
434
435     if (lockDelay > 0)
436     {
437      /*
438       * Wait for 'lockDelay' seconds before requiring a password. 
439       */
440       lockDelayId = XtAppAddTimeOut(smGD.appCon,
441                                lockDelay*1000, RequirePassword, NULL);
442   
443     }
444     else if (lockDelay == 0)
445     { 
446      /* 
447       * Immediately require a password to unlock the display.
448       */
449       smGD.lockedState = LOCKED;
450       PutUpLogin(True, False); /* map, but don't set timeout */
451     }
452
453     if (smGD.coverScreen == True && smSaverRes.cycleTimeout > 0)
454     { 
455      /*
456       * Cycle to next saver in 'cycleTimeout' seconds.
457       */
458       cycleId = XtAppAddTimeOut(smGD.appCon,
459                                smSaverRes.cycleTimeout*1000, CycleSaver, NULL);
460     }
461     
462     if(smGD.coverScreen == True)
463     {
464        for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
465        {
466           XtPopup(smDD.coverDialog[i], XtGrabNone);
467        }
468     }
469
470    /*
471     * Add an event handler for when the keyboard and pointer are grabbed
472     */
473     XtAddEventHandler(grabWidget,
474                       (KeyPressMask | ButtonPressMask | PointerMotionMask),
475                       False, EventDetected, NULL);
476
477     /** wait 90 seconds for lock dialog to come up **/
478     lockTimeId = XtAppAddTimeOut(smGD.appCon,
479                                  90000, LockAttemptFailed, lockDlg);
480     return;
481 }
482
483
484 \f
485 /*************************************<->*************************************
486  *
487  *  FinishLocking ()
488  *
489  *
490  *  Description:
491  *  -----------
492  *  After the lock dialog is up - do the grab and lock the display
493  *
494  *
495  *  Inputs:
496  *  ------
497  * 
498  *  Outputs:
499  *  -------
500  *
501  *  Comments:
502  *  --------
503  * 
504  *************************************<->***********************************/
505 static void 
506 FinishLocking(Widget            wid,
507               XtPointer         ptr,
508               XEvent            *ev,
509               Boolean           *bl)
510 {
511     int i,j;
512     Boolean kbdGrabbed, pointerGrabbed;
513     int rc;
514
515         if (lockTimeId == (XtIntervalId)0)
516           return;
517
518         XtRemoveTimeOut(lockTimeId); 
519         lockTimeId = (XtIntervalId)0;
520         XtRemoveEventHandler(wid, VisibilityChangeMask,
521                              False, FinishLocking, NULL);
522         XSync(smGD.display, 0);
523
524         i = 0;
525         XtSetArg(uiArgs[i], XmNy, &visibleY);i++;
526         XtGetValues(wid, uiArgs, i);
527
528         hiddenY = (Position) DisplayHeight(smGD.display, smGD.screen) + 15;
529
530         /*
531          * Color the cursor for this color scheme
532          */
533         RecolorCursor();
534
535         XSync(smGD.display, 0);
536
537         /*
538          * grab control of the keyboard for the entire display
539          */
540         rc = XtGrabKeyboard(grabWidget, False,
541                                      GrabModeAsync, GrabModeAsync,
542                                      CurrentTime);
543         kbdGrabbed = (rc == GrabSuccess);
544
545 #ifdef USE_HP_SPECIFIC_XLIB
546        XHPDisableReset(smGD.display);
547 #endif /* USE_HP_SPECIFIC_XLIB */
548
549 #if defined (AIXV3) && !defined(_POWER)
550        if(smGD.secureSystem)
551        {
552          SM_SETEUID(smGD.unLockUID);
553          AixEnableHftRing(0);
554          SM_SETEUID(smGD.runningUID);
555        }
556 #endif
557
558         pointerGrabbed = (XtGrabPointer(grabWidget, False,
559                                         ButtonPressMask|PointerMotionMask,
560                                         GrabModeAsync, GrabModeAsync,
561                                         None, smGD.lockCursor, CurrentTime)
562                           == GrabSuccess);
563
564         {
565           pointerGrabbed = (XtGrabPointer(grabWidget, False,
566                                         ButtonPressMask|PointerMotionMask,
567                                         GrabModeAsync, GrabModeAsync,
568                                         None, smGD.lockCursor, CurrentTime)
569                             == GrabSuccess);
570         }
571
572
573         /*
574          * If the grab failed - try 3 more times and give up
575          */
576         if((kbdGrabbed == False) || (pointerGrabbed == False))
577         {
578             for(j = 0;(j < 3) && ((pointerGrabbed == False) ||
579                                   (kbdGrabbed == False));j++)
580             {
581                 /*
582                  * If a grab fails try one more time and then give up
583                  */
584                 if(kbdGrabbed == False)
585                 {
586                     sleep(1);
587                     kbdGrabbed = (XtGrabKeyboard(grabWidget, False,
588                                                  GrabModeAsync, GrabModeAsync,
589                                                  CurrentTime) == GrabSuccess);
590                 }
591
592                 if(pointerGrabbed == False)
593                 {
594                     sleep(1);
595                     pointerGrabbed = (XtGrabPointer(grabWidget, False,
596                                                     ButtonPressMask |
597                                                     PointerMotionMask,
598                                                     GrabModeAsync,
599                                                     GrabModeAsync,
600                                                     None, smGD.lockCursor,
601                                                     CurrentTime)
602                                       == GrabSuccess);
603                 }
604             }
605         }
606
607
608         /*
609          * Set status variable to lock if the lock has succeeded
610          */
611         if((pointerGrabbed != True) || (kbdGrabbed != True))
612         {
613             PrintError(DtError, smNLS.cantLockErrorString);
614             smGD.lockedState = UNLOCKED;
615             UnlockDisplay(pointerGrabbed, kbdGrabbed);
616         }
617         else
618         {
619
620 #ifdef LOCK_SERVER_ACCESS
621             /*
622              *  Wipe & enable X server access control list
623              */
624             hostList = XListHosts(smGD.display,
625                 &hostListLen, (Bool *) &hostListActive);
626             XRemoveHosts(smGD.display, hostList, hostListLen);
627             XEnableAccessControl(smGD.display);
628             RestrictingAccess = True;
629 #endif
630  
631             PutUpLogin(False, True); /* already mapped, but set timeout */
632
633            /*
634             * Start external screen saver.
635             */
636             if (smGD.coverScreen)
637             {
638               StartScreenSaver();
639             }
640         }
641
642     return;
643 }
644
645 \f
646 /*************************************<->*************************************
647  *
648  *  CreateLockCursor ()
649  *
650  *
651  *  Description:
652  *  -----------
653  *  Creates a padlock cursor if the user has specified lock.  Creates a
654  *  blank cursor if the user has specified cover.  Both are specified in the
655  *  users resource file.
656  * 
657  *
658  *
659  *  Inputs:
660  *  ------
661  *  buttonForm = widget from which cursor gets its color
662  *  smGD.coverScreen = (global) cover screen or put up a padlock
663  
664  *
665  * 
666  *  Outputs:
667  *  -------
668  *  smGD.lockCursor = (global) cursor when lock is active (blank or padlock)
669  *
670  *  Comments:
671  *  --------
672  * 
673  *************************************<->***********************************/
674 #define lock_m_hot_x    16
675 #define lock_m_hot_y    16
676 #define lock_m_bm_width 32
677 #define lock_m_bm_height 32
678 static unsigned char lock_m_bm_bits[] = {
679    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00,
680    0x00, 0xfc, 0x9f, 0x00, 0x00, 0x0e, 0x90, 0x01, 0x00, 0x06, 0x80, 0x01,
681    0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01,
682    0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01, 0x00, 0x06, 0x80, 0x01,
683    0x00, 0x06, 0x80, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c,
684    0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
685    0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f,
686    0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
687    0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f,
688    0x80, 0xaa, 0xaa, 0x0e, 0x00, 0x55, 0x55, 0x0f, 0x80, 0xaa, 0xaa, 0x0e,
689    0xc0, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0x0f};
690
691 #define lock_m_m_bm_width 32
692 #define lock_m_m_bm_height 32
693 static unsigned char lock_m_m_bm_bits[] = {
694    0x00, 0xf8, 0x1f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00,
695    0x00, 0xff, 0xff, 0x00, 0x80, 0x0f, 0xf0, 0x01, 0x80, 0x07, 0xe0, 0x01,
696    0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01,
697    0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0x01,
698    0x80, 0x07, 0xe0, 0x01, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
699    0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
700    0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
701    0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
702    0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
703    0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
704    0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f};
705
706 #define lock_s_hot_x    7
707 #define lock_s_hot_y    8
708 #define lock_s_bm_width 13
709 #define lock_s_bm_height 16
710 static unsigned char lock_s_bm_bits[] = {
711    0x00, 0x02, 0x00, 0x04, 0xf0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
712    0x00, 0x00, 0xa8, 0x1a, 0x54, 0x1d, 0xa8, 0x1a, 0x54, 0x1d, 0xa8, 0x1a,
713    0x54, 0x1d, 0xa8, 0x1a, 0x54, 0x1d, 0xfe, 0x1f};
714
715 #define lock_s_m_bm_width 13
716 #define lock_s_m_bm_height 16
717 static unsigned char lock_s_m_bm_bits[] = {
718    0xf8, 0x03, 0xfc, 0x07, 0xfe, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
719    0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f,
720    0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f};
721
722 void 
723 CreateLockCursor( void )
724 {
725     Pixmap source, mask;
726     Colormap cmap = XDefaultColormap(smGD.display, smGD.screen);
727     XColor xcolors[2];
728     char noCursorBits = 0x1;
729
730     if(InitCursorInfo() == False)
731     {
732         /*
733          * Create the SMALL padlock cursor
734          */
735         source = XCreateBitmapFromData(smGD.display,
736                                        XRootWindow(smGD.display,
737                                                    smGD.screen),
738                                        (char *) lock_s_bm_bits,
739                                        lock_s_bm_width,
740                                        lock_s_bm_height);
741         mask = XCreateBitmapFromData(smGD.display,
742                                      XRootWindow(smGD.display,
743                                                  smGD.screen),
744                                      (char *) lock_s_m_bm_bits,
745                                      lock_s_m_bm_width,
746                                      lock_s_m_bm_height);
747
748         /* translate the Pixels into XColors */
749         xcolors[0].pixel = smGD.blackPixel;
750         xcolors[1].pixel = smGD.whitePixel;
751         XQueryColors(smGD.display, cmap, xcolors, 2);
752
753         /* create the padlock cursor */
754         smGD.padlockCursor = XCreatePixmapCursor(smGD.display, source, mask,
755                                               &(xcolors[0]), &(xcolors[1]),
756                                               lock_s_hot_x,
757                                               lock_s_hot_y);
758         XFreePixmap(smGD.display, source);
759         XFreePixmap(smGD.display, mask);
760     }
761     else
762     {
763         /*
764          * Create the LARGE padlock cursor
765          */
766         source = XCreateBitmapFromData(smGD.display,
767                                        XRootWindow(smGD.display,
768                                                    smGD.screen),
769                                        (char *) lock_m_bm_bits,
770                                        lock_m_bm_width,
771                                        lock_m_bm_height);
772         mask = XCreateBitmapFromData(smGD.display,
773                                      XRootWindow(smGD.display,
774                                                  smGD.screen),
775                                      (char *) lock_m_m_bm_bits,
776                                      lock_m_m_bm_width,
777                                      lock_m_m_bm_height);
778
779         /* translate the Pixels into XColors */
780         xcolors[0].pixel = smGD.blackPixel;
781         xcolors[1].pixel = smGD.whitePixel;
782         XQueryColors(smGD.display, cmap, xcolors, 2);
783
784         /* create the padlock cursor */
785         smGD.padlockCursor = XCreatePixmapCursor(smGD.display, source, mask,
786                                                  &(xcolors[0]), &(xcolors[1]),
787                                                  lock_m_hot_x,
788                                                  lock_m_hot_y);
789         XFreePixmap(smGD.display, source);
790         XFreePixmap(smGD.display, mask);
791     }
792
793     /*
794      *
795      * create the blank cursor
796      */
797     source = XCreateBitmapFromData(smGD.display,
798                                    XRootWindow(smGD.display, smGD.screen),
799                                    &noCursorBits, 1, 1);
800
801     xcolors[0].pixel = smGD.blackPixel;
802     XQueryColor(smGD.display, cmap, &(xcolors[0]));
803     smGD.blankCursor = XCreatePixmapCursor(smGD.display, source, source,
804                                           &(xcolors[0]), &(xcolors[0]),
805                                           0, 0);
806     XFreePixmap(smGD.display, source);
807 }
808
809
810 \f
811 /*************************************<->*************************************
812  *
813  *  RecolorCursor ()
814  *
815  *
816  *  Description:
817  *  -----------
818  *  Recolors the padlock cursor to be the current color scheme.  This has
819  *  to be done because XCreatePixmapCursor allocates colors instead of jusst
820  *  using a pixel value.
821  * 
822  *
823  *
824  *  Inputs:
825  *  ------
826  *  smGD.backgroundPix = Pixel value to use for background color
827  *  smGD.foregroundPix = Pixel value to use for foreground color
828  *
829  * 
830  *  Outputs:
831  *  -------
832  *  smGD.lockCursor = (global) cursor when lock is active (padlock)
833  *
834  *  Comments:
835  *  --------
836  * 
837  *************************************<->***********************************/
838 static void 
839 RecolorCursor( void )
840 {
841     Colormap cmap = XDefaultColormap(smGD.display, smGD.screen);
842     XColor xcolors[2];
843
844     /*
845      * translate the Pixels into XColors
846      */
847     xcolors[0].pixel = smGD.foregroundPix;
848     xcolors[1].pixel = smGD.backgroundPix;
849     XQueryColors(smGD.display, cmap, xcolors, 2);
850
851     /*
852      * recolor the padlock cursor
853      */
854     XRecolorCursor(smGD.display, smGD.lockCursor, &(xcolors[0]),
855                    &(xcolors[1]));
856 }
857
858
859 \f
860 /*************************************<->*************************************
861  *
862  *  EventDetected (w, client_data, event)
863  *
864  *
865  *  Description:
866  *  -----------
867  *  Callback routine that detects an event when the display is locked.
868  *  If it's a correct password, it unlocks the display.  Otherwise, it
869  *  just displays status.  The event is detected by the popup login dialog.
870  *
871  *
872  *  Inputs:
873  *  ------
874  *  w = widget where event occurred
875  *  client_data = client specific data sent to callback
876  *  event = event that triggered callback
877  *
878  * 
879  *  Outputs:
880  *  -------
881  *
882  *  Comments:
883  *  --------
884  * 
885  *************************************<->***********************************/
886 static void 
887 EventDetected(
888               Widget w,
889               XtPointer client_data,
890               XEvent *ev,
891               Boolean *bl)
892 {
893     char str[256];
894     int len;
895     XKeyEvent   *event = (XKeyEvent *) ev;
896    
897     if (smGD.lockedState == LOCKED)
898     {
899       if (lockDlgVisible == False)
900       {
901        /*
902         * Anytime input is received - show the passwd dialog and
903         * discard event. This is so a keypress event that causes
904         * the passwd dialog to appear will not be used in the password.
905         * CMVC 612.
906         */
907         PutUpLogin(True, True); /* map, and reset timeout */
908         return;
909       }
910       PutUpLogin(False, True); /* already mapped, but reset timeout */
911     }
912     else 
913     {
914       UnlockDisplay(True, True);
915       return;
916     }
917
918     /*
919      * If the detected event is anything but a keypress, processing is
920      * complete after refreshing the status string.
921      */
922     if (event->type != KeyPress)
923         return;
924
925     /*
926      * If XLookupString() returns anything (which it won't in the case of, say,
927      * pressing the shift key or an arrow key), process it.
928      */
929 #ifdef USE_HP_SPECIFIC_XLIB
930     if (len = XHPConvertLookup(event, str, sizeof(str), NULL, NULL,
931                                XHPGetEurasianCvt(smGD.display)))
932 #else /* USE_HP_SPECIFIC_XLIB */
933     if (len = XLookupString (event, str, sizeof(str), NULL, NULL))
934 #endif /* USE_HP_SPECIFIC_XLIB */
935     {
936         if (smGD.lockedState == LOCKED)
937             CheckString(str, len);
938     }
939 }
940
941
942 \f
943 /*************************************<->*************************************
944  *
945  *  CheckString (s, i)
946  *
947  *
948  *  Description:
949  *  -----------
950  *  Check string entered by user.  If it is a valid password, call routine to
951  *  unlock the display.  Otherwise, just keep track of what we have until
952  *  the password is valid
953  *
954  *
955  *  Inputs:
956  *  ------
957  *  s = string passed in for checking
958  *  i = length of string
959  *
960  * 
961  *  Outputs:
962  *  -------
963  *
964  *  Comments:
965  *  --------
966  * 
967  *************************************<->***********************************/
968 static void 
969 CheckString(
970         register char *s,
971         register int i )
972 {
973   /* maximum supported length of password */
974 #if defined(SIA)
975 #define MAX_PASSWORD_LENGTH SIAMXPASSWORD
976 #else
977   /* seems to be reasonable maximal length */
978 #define MAX_PASSWORD_LENGTH 65535
979 #endif
980
981   /* step when allocating/extending buffer */
982 #define BUF_ALLOC_LEN 64
983
984     /*
985      * password rules:
986      *  - If pw_length >  MAX_PASSWORD_LENGTH, we've gone over the limit and won't
987      *    accept any more.
988      *  - An ESC kills the line.
989      */
990     static char *passwd = NULL;                            /* password space */
991     static int pw_buf_length = 0;                          /* length of allocated password buffer */
992     static int pw_length = 0;                              /* password length */
993     char * tmpptr;
994
995     if (s == NULL)
996     {
997      /*
998       * Clear password.
999       */
1000       pw_length = 0;
1001       return;
1002     }
1003     for (; i>0; s++,i--)
1004     {
1005         /* extend buffer by BUF_ALLOC_LEN bytes if needed*/
1006 #ifdef  JET_AUTHDEBUG
1007         fprintf(stderr, "CheckString: pw_length=%d\n",pw_length);
1008 #endif
1009
1010         if (pw_length == pw_buf_length)
1011         {
1012             tmpptr = SM_REALLOC(passwd,  pw_buf_length + BUF_ALLOC_LEN);
1013             if (!tmpptr) {
1014                 PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1015                 return;
1016             }
1017             pw_buf_length += BUF_ALLOC_LEN;
1018             passwd = tmpptr;
1019         }
1020         switch(*s)
1021         {
1022             case '\010':
1023                 if (pw_length)
1024                     pw_length--;                /* back up one character */
1025                 break;
1026                 
1027             case '\e':
1028                 pw_length = 0;                  /* kill the character string */
1029                 break;
1030
1031             case '\n':
1032             case '\r':
1033                 if (pw_length > MAX_PASSWORD_LENGTH)
1034                 {
1035                     pw_length = MAX_PASSWORD_LENGTH;
1036                 }
1037                 passwd[pw_length] = '\0';       /* terminate string */
1038                 pw_length = 0;                  /* reset length */
1039                 if (CheckPassword(passwd))
1040                 {
1041                     UpdatePasswdField(0);
1042                     UnlockDisplay(True, True);
1043                     return;
1044                 }
1045                 XBell(smGD.display, 100);       /* wrong, laserbreath */
1046                 break;
1047
1048             default:
1049                 if (pw_length < MAX_PASSWORD_LENGTH)
1050                 {
1051                     passwd[pw_length++] = *s;   /* store character */
1052                 }
1053                 break;
1054         }
1055     }
1056     UpdatePasswdField(pw_length > MAX_PASSWORD_LENGTH ? MAX_PASSWORD_LENGTH : pw_length);
1057 }
1058
1059
1060 \f
1061 /*************************************<->*************************************
1062  *
1063  *  CheckPassword (passwd)
1064  *
1065  *
1066  *  Description:
1067  *  -----------
1068  *  Check the password to see if it is the user's, roots, or one of the
1069  *  users specified in the host string
1070  *
1071  *
1072  *  Inputs:
1073  *  ------
1074  *  passwd = password passed in
1075  *
1076  * 
1077  *  Outputs:
1078  *  -------
1079  *  True if it is a valid password, false otherwise.
1080  *
1081  *  Comments:
1082  *  --------
1083  * 
1084  *************************************<->***********************************/
1085 static Boolean 
1086 CheckPassword(
1087         char *passwd )
1088 {
1089     char *p, *q;
1090     char *keyholderbuf;
1091
1092     if (Authenticate(NULL, getuid(), passwd) == True)
1093     {   
1094       return(True);  /* user password ok */
1095     }
1096
1097     if (Authenticate(NULL, 0, passwd) == True)
1098     {
1099       return(True);  /* root password ok */
1100     }
1101
1102     /* check passwords of users specified as keyholders */
1103     if (smGD.keyholders == NULL)
1104     {
1105         return(False);                  /* no keyholders */
1106     }
1107
1108     /* since strtok() is destructive, copy the keyholders string */
1109     keyholderbuf = (char *) SM_MALLOC(strlen(smGD.keyholders)+1);
1110     if(keyholderbuf == NULL)
1111     {
1112         PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1113         return(False); /* no memory */
1114     }
1115     
1116     strcpy(keyholderbuf, smGD.keyholders);
1117     for (p = keyholderbuf; (q = strtok(p, ", \t")) != NULL; p = NULL)
1118     {
1119         if (Authenticate(q, -1, passwd) == True)
1120         {
1121           SM_FREE(keyholderbuf);
1122           return(True); /* keyholder password ok */
1123         }
1124     }
1125     SM_FREE(keyholderbuf);
1126
1127     return(False); /* no matches */
1128 }
1129
1130
1131 \f
1132 /*************************************<->*************************************
1133  *
1134  *  UnlockDisplay ()
1135  *
1136  *
1137  *  Description:
1138  *  -----------
1139  *  If the user has entered a correct password, unlock the display and
1140  *  uncover the root window.
1141  *
1142  *
1143  *  Inputs:
1144  *  ------
1145  *  pointerGrabbed - Boolean tells if pointer is currently grabbed
1146  *  kbdGrabbed - Boolean tells if keyboard is currently grabbed
1147  *
1148  * 
1149  *  Outputs:
1150  *  -------
1151  *
1152  *
1153  *  Comments:
1154  *  --------
1155  * 
1156  *************************************<->***********************************/
1157 static void 
1158 UnlockDisplay(
1159         Boolean pointerGrabbed,
1160         Boolean kbdGrabbed)
1161 {
1162     int i;
1163     Tt_message msg;
1164
1165 #ifdef LOCK_SERVER_ACCESS
1166     /*
1167      * Restore X server access state
1168      */
1169     if (RestrictingAccess) {
1170         XAddHosts(smGD.display, hostList, hostListLen);
1171         if (!hostListActive) XDisableAccessControl(smGD.display);
1172         RestrictingAccess = False;
1173         XFree((void *) hostList);
1174     }
1175 #endif
1176
1177     /*
1178      * Stop external screen saver.
1179      */
1180     StopScreenSaver();
1181
1182     /*
1183      * Remove the event handler to grab the events
1184      */
1185     XtRemoveEventHandler(grabWidget,
1186                          (KeyPressMask | ButtonPressMask | PointerMotionMask),
1187                          False, EventDetected, NULL);
1188
1189     /*
1190      * Turn off alarms
1191      */
1192     if(lockDelayId != (XtIntervalId)0)
1193     {
1194         XtRemoveTimeOut(lockDelayId);
1195     }
1196
1197     if(cycleId != (XtIntervalId)0)
1198     {
1199         XtRemoveTimeOut(cycleId);
1200     }
1201
1202     if(timerId != (XtIntervalId)0)
1203     {
1204         XtRemoveTimeOut(timerId);
1205     }
1206
1207     if(flash_id != (XtIntervalId)0)
1208     {
1209         XtRemoveTimeOut(flash_id);
1210     }
1211
1212     if(pointerGrabbed == True)
1213     {
1214         XtUngrabPointer(grabWidget, CurrentTime);
1215     }
1216
1217     if(kbdGrabbed == True)
1218     {
1219         XtUngrabKeyboard(grabWidget, CurrentTime);
1220     }
1221     
1222 #ifdef USE_HP_SPECIFIC_XLIB
1223     XHPEnableReset(smGD.display);
1224 #endif /* USE_HP_SPECIFIC_XLIB */
1225
1226 #if defined (AIXV3) && !defined(_POWER)
1227     if(smGD.secureSystem)
1228     {
1229       SM_SETEUID(smGD.unLockUID);
1230       AixEnableHftRing(1);
1231       SM_SETEUID(smGD.runningUID);
1232     }
1233 #endif
1234
1235     XSync(smGD.display, 0);
1236
1237    /*
1238     * Unmanage session lock dialogs. If LOCKDLG_PERSIST is undefined,
1239     * destroy them. This is so the passwd dialog icon colors get freed
1240     * since currently it uses a lot of colors. 
1241     */
1242     if(smGD.coverScreen == False) 
1243     {
1244 #if defined (LOCKDLG_PERSIST)
1245         if (XtIsManaged(smDD.lockDialog))
1246         {
1247           XtUnmanageChild(smDD.lockDialog);
1248         }
1249 #else
1250         XtDestroyWidget(smDD.lockDialog);
1251         smDD.lockDialog = NULL;
1252 #endif
1253     }
1254     else
1255     {
1256 #if defined (LOCKDLG_PERSIST)
1257         if(!XtIsManaged(smDD.lockCoverDialog))
1258         {
1259             XtManageChild(smDD.lockCoverDialog);
1260         }
1261         
1262         for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1263         {
1264             XtPopdown(smDD.coverDialog[i]);
1265         }
1266 #else
1267         for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1268         {
1269             XtDestroyWidget(smDD.coverDialog[i]);
1270             smDD.coverDialog[i] = NULL;
1271         }
1272         smDD.lockCoverDialog = NULL;
1273 #endif
1274     }
1275
1276     smGD.lockedState = UNLOCKED;
1277
1278     XSync(smGD.display, 0);
1279
1280     /*
1281      * Tell the Workspace Manager to unlock the display (depress the lock
1282      * button)
1283     if(smGD.bmsDead == False)
1284     {
1285         msg = tttk_message_create(0, TT_REQUEST, TT_SESSION, 0,
1286                                   "Display_Unlock", 0);
1287         tt_message_send(msg);
1288         tt_message_destroy(msg);
1289     }
1290      */
1291
1292     SetSystemReady();
1293     
1294 }
1295
1296 static Position visibleY = -1;
1297 static Position hiddenY = -1;
1298
1299 \f
1300 /*************************************<->*************************************
1301  *
1302  *  TakeDownLogin ()
1303  *
1304  *
1305  *  Description:
1306  *  -----------
1307  *  When a timeout occurs - take down the login screen by unmanaging it.
1308  *
1309  *
1310  *  Inputs:
1311  *  ------
1312  *
1313  * 
1314  *  Outputs:
1315  *  -------
1316  *
1317  *
1318  *  Comments:
1319  *  --------
1320  * 
1321  *************************************<->***********************************/
1322 static void 
1323 TakeDownLogin(
1324         XtPointer client_data,
1325         XtIntervalId *id )
1326 {
1327   if (lockDlgVisible == True)
1328   {
1329     if (smGD.coverScreen == True)
1330     {
1331       XtUnmapWidget(smDD.lockCoverDialog);
1332     }
1333     else
1334     {
1335       if (hiddenY > -1)
1336       {
1337         int i = 0;
1338         XtSetArg(uiArgs[i], XmNy, hiddenY);i++;
1339         XtSetValues(smDD.lockDialog, uiArgs, i);
1340       }
1341     }
1342     
1343     timerId = (XtIntervalId)0; 
1344
1345    /*
1346     * Clear partially entered password if any.
1347     */
1348     CheckString(NULL, 0);
1349     lockDlgVisible = False;
1350
1351     XSync(smGD.display, 0);
1352   }
1353 }
1354
1355 \f
1356 /*************************************<->*************************************
1357  *
1358  *  PutUpLogin ()
1359  *
1360  *
1361  *  Description:
1362  *  -----------
1363  *  Redisplays the cover and the login when necessary.
1364  *
1365  *
1366  *  Inputs:
1367  *  ------
1368  *
1369  * 
1370  *  Outputs:
1371  *  -------
1372  *
1373  *
1374  *  Comments:
1375  *  --------
1376  * 
1377  *************************************<->***********************************/
1378 static void 
1379 PutUpLogin(
1380   Boolean map,
1381   Boolean timeout )
1382 {
1383   if (map == True && lockDlgVisible == False)
1384   {
1385     if (smGD.coverScreen == True)
1386     {
1387       XtMapWidget(smDD.lockCoverDialog);
1388     }
1389     else
1390     {
1391       if (visibleY > -1)
1392       {
1393         int i = 0;
1394         XtSetArg(uiArgs[i], XmNy, visibleY);i++;
1395         XtSetValues(smDD.lockDialog, uiArgs, i);
1396       }
1397     }
1398     lockDlgVisible = True;
1399   }
1400
1401   if (timeout == True)
1402   {
1403     if(timerId != (XtIntervalId)0)
1404     {
1405         XtRemoveTimeOut(timerId);
1406     }
1407  
1408     if(smRes.alarmTime > 0)
1409     {
1410         timerId = XtAppAddTimeOut(smGD.appCon,
1411                                   (smRes.alarmTime * 1000),
1412                                   TakeDownLogin,NULL);
1413     }
1414   }
1415   XSync(smGD.display, 0);
1416 }
1417
1418 \f
1419 /*************************************<->*************************************
1420  *
1421  *  LockAttemptFailed ()
1422  *
1423  *
1424  *  Description:
1425  *  -----------
1426  *  Timed out trying to get a visibilitynotify on the lock
1427  *
1428  *
1429  *  Inputs:
1430  *  ------
1431  *
1432  * 
1433  *  Outputs:
1434  *  -------
1435  *
1436  *
1437  *  Comments:
1438  *  --------
1439  * 
1440  *************************************<->***********************************/
1441 static void 
1442 LockAttemptFailed(XtPointer     ptr,
1443                   XtIntervalId  *invId)
1444 {
1445     Widget lockWid = (Widget) ptr;
1446     
1447     PrintError(DtError, smNLS.cantLockErrorString);
1448     smGD.lockedState = UNLOCKED;
1449     XtRemoveEventHandler(lockWid, VisibilityChangeMask,
1450                          False, FinishLocking, NULL);
1451     UnlockDisplay(False, False);
1452     XSync(smGD.display, 0);
1453 }
1454
1455
1456
1457 \f
1458 /*************************************<->*************************************
1459  *
1460  *  RequirePassword ()
1461  *
1462  *
1463  *  Description:
1464  *  -----------
1465  *  Callback indicating a password is now required to unlock display.
1466  *
1467  *
1468  *  Inputs:
1469  *  ------
1470  *
1471  * 
1472  *  Outputs:
1473  *  -------
1474  *
1475  *
1476  *  Comments:
1477  *  --------
1478  * 
1479  *************************************<->***********************************/
1480 static void 
1481 RequirePassword(XtPointer       ptr,
1482                   XtIntervalId  *invId)
1483 {
1484   smGD.lockedState = LOCKED;
1485 }
1486
1487
1488 /*************************************<->*************************************
1489  *
1490  *  BlinkCaret ()
1491  *
1492  *
1493  *  Description:
1494  *  -----------
1495  *  blinks the caret in the password field
1496  *
1497  *
1498  *  Inputs:
1499  *  ------
1500  *
1501  *
1502  *  Outputs:
1503  *  -------
1504  *
1505  *
1506  *  Comments:
1507  *  --------
1508  *
1509  *************************************<->***********************************/
1510 static void
1511 BlinkCaret(XtPointer    ptr,
1512                   XtIntervalId  *invId)
1513 {
1514 static int flag = 1;
1515 XmString tmpString;
1516 int i;
1517  
1518  /*
1519   * Blink cursor to show the focus ..
1520   */
1521   if(flag){
1522      tmpString = XmStringCreateLocalized (" " );
1523      i = 0;
1524      XtSetArg(uiArgs[i], XmNlabelString,     tmpString); i++;
1525      XtSetValues(ptr, uiArgs, i);
1526      flag = 0;
1527   }
1528   else{
1529      tmpString = XmStringCreateLocalized ("|");
1530      i = 0;
1531      XtSetArg(uiArgs[i], XmNlabelString,     tmpString); i++;
1532      XtSetValues(ptr, uiArgs, i);
1533      flag = 1;
1534   }
1535  
1536   XmStringFree(tmpString);
1537   flash_id = XtAppAddTimeOut(smGD.appCon, 1000,
1538                             BlinkCaret, ptr);
1539 }
1540
1541
1542 \f
1543 /*************************************<->*************************************
1544  *
1545  *  CycleSaver ()
1546  *
1547  *
1548  *  Description:
1549  *  -----------
1550  *  Callback indicating we should cycle to next screen saver
1551  *
1552  *
1553  *  Inputs:
1554  *  ------
1555  *
1556  * 
1557  *  Outputs:
1558  *  -------
1559  *
1560  *
1561  *  Comments:
1562  *  --------
1563  * 
1564  *************************************<->***********************************/
1565 static void 
1566 CycleSaver(XtPointer    ptr,
1567                   XtIntervalId  *invId)
1568 {
1569  /*
1570   * Stop running screen saver, start a new one and reset timer.
1571   */
1572   StopScreenSaver();
1573   StartScreenSaver();  
1574   cycleId = XtAppAddTimeOut(smGD.appCon, smSaverRes.cycleTimeout*1000,
1575                             CycleSaver, NULL);
1576 }
1577
1578
1579 \f
1580 /*************************************<->*************************************
1581  *
1582  *  localAuthenticate (name, uid, passwd)
1583  *
1584  *
1585  *  Description:
1586  *  -----------
1587  *
1588  *
1589  *  Inputs:
1590  *  ------
1591  *
1592  * 
1593  *  Outputs:
1594  *  -------
1595  *
1596  *  Comments:
1597  *  --------
1598  * 
1599  *************************************<->***********************************/
1600 static Boolean 
1601 localAuthenticate(
1602         char *name,
1603         uid_t uid,
1604         char *passwd )
1605 #ifdef SIA
1606
1607
1608
1609   {
1610     char *Argv[2] = { "dtsession", NULL };
1611
1612     SIAENTITY *se = NULL;
1613     int code;
1614     char *  pw_name;
1615     uid_t real_uid;
1616
1617
1618     real_uid = getuid();
1619
1620     if (-1 == seteuid(0))
1621       return FALSE;
1622
1623
1624     if (passwd == NULL)
1625     {
1626       /*
1627       * Caller just checking if it is possible to access 
1628       * password file (ie is dtsession suid bit set properly).
1629       */
1630       seteuid(real_uid);
1631       return TRUE;
1632     }
1633     if (name && name[0])
1634       pw_name = name;
1635     else if (uid == 0)
1636       pw_name = "root";
1637     else
1638       pw_name = getlogin();
1639
1640
1641     if ( sia_ses_init(&se, 1, Argv, (char *)NULL,
1642                       pw_name, NULL, 0 /* don't collect info */, 
1643                       NULL) != SIASUCCESS)
1644       {
1645       seteuid(real_uid);
1646       return FALSE;
1647       }
1648     
1649     se->password = (char *)malloc(strlen(passwd) + 1);
1650     if ( se->password == (char *)NULL ) 
1651     {
1652         sia_ses_release(&se);
1653       seteuid(real_uid);
1654       return FALSE;
1655     }
1656
1657     strcpy(se->password, passwd);
1658
1659     code = sia_ses_reauthent (NULL, se);
1660     sia_ses_release(&se);
1661
1662     seteuid(real_uid);
1663
1664     if ( code == SIASUCCESS )
1665       return TRUE;
1666     else
1667       return FALSE;
1668 }
1669     
1670 #elif defined(__linux__)
1671
1672 {
1673     struct passwd *pwent = NULL;
1674     char *p, *q;
1675     char *crypt();
1676     Boolean rc = True;
1677     Boolean done = False;
1678     struct spwd *sp = NULL;
1679
1680     if(smGD.secureSystem)
1681     {   
1682       SM_SETEUID(smGD.unLockUID);
1683     }
1684
1685    /*
1686     * Get password entry for 'name' or 'uid'.
1687     */
1688     if (CanReAuthenticate(name, uid, passwd, &pwent, &sp) == False)
1689     {
1690      /*
1691       * Can't get entry.
1692       */
1693       rc = False;
1694       done = True;
1695     }
1696
1697     if(smGD.secureSystem)
1698     {
1699         SM_SETEUID(smGD.runningUID);
1700     }
1701
1702     if (done == False)
1703     {
1704
1705       if (pwent->pw_passwd == NULL || pwent->pw_passwd[0] == '*')
1706       {
1707                                 /* check sp */
1708         if (sp == NULL || sp->sp_pwdp == NULL)
1709           {
1710             /*
1711              * Could not read password.
1712              */
1713             rc = False;
1714             done = True;
1715           }
1716       }
1717     }
1718
1719     if (done == False)
1720     {
1721       if (passwd == NULL)
1722       {
1723        /*
1724         * Caller just checking if it is possible to access 
1725         * password file (ie is dtsession suid bit set properly).
1726         */
1727         rc = True; 
1728         done = True;
1729       }
1730     }
1731
1732     if (done == False)
1733     {
1734      /*
1735       * Check password.
1736       */
1737
1738       if (sp != NULL && !strcmp(sp->sp_pwdp, crypt(passwd,sp->sp_pwdp)))
1739         {                       /* a shadow match */
1740           rc = True;
1741           done = True;
1742         }
1743       else if (pwent != NULL && 
1744                !strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)))
1745         {                       /* passwd match */
1746           rc = True;
1747           done = True;
1748         }
1749       else
1750         {                       /* failure dude! */
1751           rc = False;
1752           done = True;
1753         }
1754     }
1755
1756     endpwent();
1757     endspent();
1758
1759     return(rc);
1760 }
1761
1762 #else
1763
1764 {
1765     register struct passwd *pwent;
1766     char *p, *q;
1767     char *crypt();
1768     Boolean rc = True;
1769     Boolean done = False;
1770
1771
1772 #ifdef SVR4
1773     struct spwd *sp=NULL;
1774 #endif
1775
1776     if(smGD.secureSystem)
1777     {   
1778         SM_SETEUID(smGD.unLockUID);
1779     }
1780
1781 #ifdef SVR4
1782    /*
1783     * Get shadow password entry for 'name' or 'uid'.
1784     */
1785     if (name == NULL)
1786     {
1787       pwent = getpwuid(uid);
1788       if (pwent != NULL) 
1789       {
1790         name = pwent->pw_name;
1791       }
1792     }
1793
1794     if (name == NULL ||
1795         (sp = getspnam(name)) == NULL
1796         )
1797     {
1798      /*
1799       * Can't get entry.
1800       */
1801       rc = False;
1802       done = True;
1803     }
1804 #else  /* SVR4 */
1805    /*
1806     * Get password entry for 'name' or 'uid'.
1807     */
1808 #if defined(__OpenBSD__) && OSMAJORVERSION > 5
1809     if ((pwent = (name == NULL ?
1810             getpwuid_shadow(uid) : getpwnam_shadow(name))) == NULL)
1811 #else
1812     if ((pwent = (name == NULL ? getpwuid(uid) : getpwnam(name))) == NULL)
1813 #endif
1814     {
1815      /*
1816       * Can't get entry.
1817       */
1818       rc = False;
1819       done = True;
1820     }
1821 #endif /* SVR4 */
1822
1823     if(smGD.secureSystem)
1824     {
1825         SM_SETEUID(smGD.runningUID);
1826     }
1827
1828     if (done == False)
1829     {
1830       if (
1831           pwent->pw_passwd == NULL 
1832           || pwent->pw_passwd[0] == '*'
1833 #ifdef SVR4
1834           || sp == NULL
1835 #endif
1836           )
1837       {
1838        /*
1839         * Could not read password.
1840         */
1841         rc = False;
1842         done = True;
1843       }
1844     }
1845
1846     if (done == False)
1847     {
1848       if (passwd == NULL)
1849       {
1850        /*
1851         * Caller just checking if it is possible to access 
1852         * password file (ie is dtsession suid bit set properly).
1853         */
1854         rc = True; 
1855         done = True;
1856       }
1857     }
1858
1859     if (done == False)
1860     {
1861      /*
1862       * Check password.
1863       */
1864 #ifdef SVR4
1865       if (strcmp(crypt(passwd,sp->sp_pwdp),sp->sp_pwdp) != 0)
1866 #else
1867       if (strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)) != 0)
1868 #endif
1869       {
1870        /*
1871         * Password incorrect.
1872         */
1873         rc = False;
1874         done = True;
1875       }
1876     }
1877
1878     endpwent();
1879 #ifdef SVR4
1880     endspent();
1881 #endif
1882
1883     return(rc);
1884 }
1885 #endif /* SIA */
1886
1887 \f
1888 /*************************************<->*************************************
1889  *
1890  *  Authenticate (name, uid, passwd)
1891  *
1892  *
1893  *  Description:
1894  *  -----------
1895  *
1896  *
1897  *  Inputs:
1898  *  ------
1899  *
1900  * 
1901  *  Outputs:
1902  *  -------
1903  *
1904  *  Comments:
1905  *  --------
1906  * 
1907  *************************************<->***********************************/
1908
1909 #if defined (_AIX) && defined(_POWER)
1910
1911 static Boolean 
1912 Authenticate(
1913         char *name,
1914         uid_t uid,
1915         char *passwd )
1916 {
1917     register struct passwd *pwent;
1918     char *p, *q;
1919     char *crypt();
1920     Boolean rc = True;
1921     Boolean done = False;
1922
1923     int arc;
1924     int reenter;
1925     char *newname = NULL;
1926     char *msg;
1927
1928     if(smGD.secureSystem)
1929     {
1930         SM_SETEUID(smGD.unLockUID);
1931     }
1932
1933    /*
1934     * Map uid to name.
1935     */
1936     if (name == NULL)
1937     {
1938       pwent = getpwuid(uid);
1939       if (pwent != NULL)
1940       {
1941         name = newname = strdup(pwent->pw_name);
1942       }
1943       endpwent();
1944     }
1945  
1946    /* 
1947     * Authenticate user. Note: normally, we should check 'reenter' to
1948     * see if the user has another challenge. Since the dtsession screen
1949     * lock i/f does not yet have the support, our policy is to let the
1950     * user back in if they pass the first (password) challenge.
1951     */ 
1952     arc = authenticate(name, passwd, &reenter, &msg);
1953
1954     if(smGD.secureSystem)
1955     {
1956         SM_SETEUID(smGD.runningUID);
1957     }
1958
1959     if (msg) free(msg);
1960     if (newname) free(newname);
1961
1962     return(arc == 0 ? True : False);
1963 }
1964 #endif /* _AIX && _POWER */
1965