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