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