0e7307c737152f3b117efcbccfa585cc820fe040
[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     /*
973      * password rules:
974      *  - Only the first eight characters are used.
975      *  - If pw_length > 8, we've gone over eight characters and won't
976      *    accept any more.
977      *  - An ESC kills the line.
978      */
979 #ifdef SIA
980     static char passwd[82];           /* password space */
981 #else
982     static char passwd[10];             /* password space */
983 #endif
984     static int pw_length = 0;           /* password length */
985
986     if (s == NULL)
987     {
988      /*
989       * Clear password.
990       */
991       pw_length = 0;
992       return;
993     }
994     
995     for (; i>0; s++,i--)
996     {
997         switch(*s)
998         {
999             case '\010':
1000                 if (pw_length)
1001                     pw_length--;                /* back up one character */
1002                 break;
1003                 
1004             case '\e':
1005                 pw_length = 0;                  /* kill the character string */
1006                 break;
1007
1008             case '\n':
1009             case '\r':
1010 #ifdef SIA
1011                 if (pw_length > 80)
1012                 {
1013                     pw_length = 80;
1014                 }
1015 #else
1016                 if (pw_length > 8)
1017                 {
1018                     pw_length = 8;
1019                 }
1020 #endif
1021                 passwd[pw_length] = '\0';       /* terminate string */
1022                 pw_length = 0;                  /* reset length */
1023                 if (CheckPassword(passwd))
1024                 {
1025                     UpdatePasswdField(0);
1026                     UnlockDisplay(True, True);
1027                     return;
1028                 }
1029                 XBell(smGD.display, 100);       /* wrong, laserbreath */
1030                 break;
1031
1032             default:
1033 #ifdef SIA
1034                 if (pw_length < 80)
1035 #else
1036                 if (pw_length < 8)
1037 #endif
1038                     passwd[pw_length] = *s;     /* store character */
1039                 /*
1040                  * The length is incremented no matter what, so the user can
1041                  * think the program handles multi-thousand-character
1042                  * passwords.  If the user types twenty characters and eighteen
1043                  * erases (#), the result will be the first two characters
1044                  * entered, as expected.  Up to a point -- 65536 is long
1045                  * enough!
1046                  */
1047                 if (pw_length < 65535)
1048                     pw_length++;
1049                 break;
1050         }
1051     }
1052
1053     if(pw_length > 8)
1054     {
1055         UpdatePasswdField(8);
1056     }
1057     else
1058     {
1059         UpdatePasswdField(pw_length);
1060     }
1061 }
1062
1063
1064 \f
1065 /*************************************<->*************************************
1066  *
1067  *  CheckPassword (passwd)
1068  *
1069  *
1070  *  Description:
1071  *  -----------
1072  *  Check the password to see if it is the user's, roots, or one of the
1073  *  users specified in the host string
1074  *
1075  *
1076  *  Inputs:
1077  *  ------
1078  *  passwd = password passed in
1079  *
1080  * 
1081  *  Outputs:
1082  *  -------
1083  *  True if it is a valid password, false otherwise.
1084  *
1085  *  Comments:
1086  *  --------
1087  * 
1088  *************************************<->***********************************/
1089 static Boolean 
1090 CheckPassword(
1091         char *passwd )
1092 {
1093     char *p, *q;
1094     char *keyholderbuf;
1095
1096     if (Authenticate(NULL, getuid(), passwd) == True)
1097     {   
1098       return(True);  /* user password ok */
1099     }
1100
1101     if (Authenticate(NULL, 0, passwd) == True)
1102     {
1103       return(True);  /* root password ok */
1104     }
1105
1106     /* check passwords of users specified as keyholders */
1107     if (smGD.keyholders == NULL)
1108     {
1109         return(False);                  /* no keyholders */
1110     }
1111
1112     /* since strtok() is destructive, copy the keyholders string */
1113     keyholderbuf = (char *) SM_MALLOC(strlen(smGD.keyholders)+1);
1114     if(keyholderbuf == NULL)
1115     {
1116         PrintErrnoError(DtError, smNLS.cantMallocErrorString);
1117         return(False); /* no memory */
1118     }
1119     
1120     strcpy(keyholderbuf, smGD.keyholders);
1121     for (p = keyholderbuf; (q = strtok(p, ", \t")) != NULL; p = NULL)
1122     {
1123         if (Authenticate(q, -1, passwd) == True)
1124         {
1125           SM_FREE(keyholderbuf);
1126           return(True); /* keyholder password ok */
1127         }
1128     }
1129     SM_FREE(keyholderbuf);
1130
1131     return(False); /* no matches */
1132 }
1133
1134
1135 \f
1136 /*************************************<->*************************************
1137  *
1138  *  UnlockDisplay ()
1139  *
1140  *
1141  *  Description:
1142  *  -----------
1143  *  If the user has entered a correct password, unlock the display and
1144  *  uncover the root window.
1145  *
1146  *
1147  *  Inputs:
1148  *  ------
1149  *  pointerGrabbed - Boolean tells if pointer is currently grabbed
1150  *  kbdGrabbed - Boolean tells if keyboard is currently grabbed
1151  *
1152  * 
1153  *  Outputs:
1154  *  -------
1155  *
1156  *
1157  *  Comments:
1158  *  --------
1159  * 
1160  *************************************<->***********************************/
1161 static void 
1162 UnlockDisplay(
1163         Boolean pointerGrabbed,
1164         Boolean kbdGrabbed)
1165 {
1166     int i;
1167     Tt_message msg;
1168
1169 #ifdef LOCK_SERVER_ACCESS
1170     /*
1171      * Restore X server access state
1172      */
1173     if (RestrictingAccess) {
1174         XAddHosts(smGD.display, hostList, hostListLen);
1175         if (!hostListActive) XDisableAccessControl(smGD.display);
1176         RestrictingAccess = False;
1177         XFree((void *) hostList);
1178     }
1179 #endif
1180
1181     /*
1182      * Stop external screen saver.
1183      */
1184     StopScreenSaver();
1185
1186     /*
1187      * Remove the event handler to grab the events
1188      */
1189     XtRemoveEventHandler(grabWidget,
1190                          (KeyPressMask | ButtonPressMask | PointerMotionMask),
1191                          False, EventDetected, NULL);
1192
1193     /*
1194      * Turn off alarms
1195      */
1196     if(lockDelayId != (XtIntervalId)0)
1197     {
1198         XtRemoveTimeOut(lockDelayId);
1199     }
1200
1201     if(cycleId != (XtIntervalId)0)
1202     {
1203         XtRemoveTimeOut(cycleId);
1204     }
1205
1206     if(timerId != (XtIntervalId)0)
1207     {
1208         XtRemoveTimeOut(timerId);
1209     }
1210
1211     if(flash_id != (XtIntervalId)0)
1212     {
1213         XtRemoveTimeOut(flash_id);
1214     }
1215
1216     if(pointerGrabbed == True)
1217     {
1218         XtUngrabPointer(grabWidget, CurrentTime);
1219     }
1220
1221     if(kbdGrabbed == True)
1222     {
1223         XtUngrabKeyboard(grabWidget, CurrentTime);
1224     }
1225     
1226 #ifdef USE_HP_SPECIFIC_XLIB
1227     XHPEnableReset(smGD.display);
1228 #endif /* USE_HP_SPECIFIC_XLIB */
1229
1230 #if defined (AIXV3) && !defined(_POWER)
1231     if(smGD.secureSystem)
1232     {
1233       SM_SETEUID(smGD.unLockUID);
1234       AixEnableHftRing(1);
1235       SM_SETEUID(smGD.runningUID);
1236     }
1237 #endif
1238
1239     XSync(smGD.display, 0);
1240
1241    /*
1242     * Unmanage session lock dialogs. If LOCKDLG_PERSIST is undefined,
1243     * destroy them. This is so the passwd dialog icon colors get freed
1244     * since currently it uses a lot of colors. 
1245     */
1246     if(smGD.coverScreen == False) 
1247     {
1248 #if defined (LOCKDLG_PERSIST)
1249         if (XtIsManaged(smDD.lockDialog))
1250         {
1251           XtUnmanageChild(smDD.lockDialog);
1252         }
1253 #else
1254         XtDestroyWidget(smDD.lockDialog);
1255         smDD.lockDialog = NULL;
1256 #endif
1257     }
1258     else
1259     {
1260 #if defined (LOCKDLG_PERSIST)
1261         if(!XtIsManaged(smDD.lockCoverDialog))
1262         {
1263             XtManageChild(smDD.lockCoverDialog);
1264         }
1265         
1266         for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1267         {
1268             XtPopdown(smDD.coverDialog[i]);
1269         }
1270 #else
1271         for(i = (smGD.numSavedScreens - 1);i >= 0;i--)
1272         {
1273             XtDestroyWidget(smDD.coverDialog[i]);
1274             smDD.coverDialog[i] = NULL;
1275         }
1276         smDD.lockCoverDialog = NULL;
1277 #endif
1278     }
1279
1280     smGD.lockedState = UNLOCKED;
1281
1282     XSync(smGD.display, 0);
1283
1284     /*
1285      * Tell the Workspace Manager to unlock the display (depress the lock
1286      * button)
1287     if(smGD.bmsDead == False)
1288     {
1289         msg = tttk_message_create(0, TT_REQUEST, TT_SESSION, 0,
1290                                   "Display_Unlock", 0);
1291         tt_message_send(msg);
1292         tt_message_destroy(msg);
1293     }
1294      */
1295
1296     SetSystemReady();
1297     
1298 }
1299
1300 static Position visibleY = -1;
1301 static Position hiddenY = -1;
1302
1303 \f
1304 /*************************************<->*************************************
1305  *
1306  *  TakeDownLogin ()
1307  *
1308  *
1309  *  Description:
1310  *  -----------
1311  *  When a timeout occurs - take down the login screen by unmanaging it.
1312  *
1313  *
1314  *  Inputs:
1315  *  ------
1316  *
1317  * 
1318  *  Outputs:
1319  *  -------
1320  *
1321  *
1322  *  Comments:
1323  *  --------
1324  * 
1325  *************************************<->***********************************/
1326 static void 
1327 TakeDownLogin(
1328         XtPointer client_data,
1329         XtIntervalId *id )
1330 {
1331   if (lockDlgVisible == True)
1332   {
1333     if (smGD.coverScreen == True)
1334     {
1335       XtUnmapWidget(smDD.lockCoverDialog);
1336     }
1337     else
1338     {
1339       if (hiddenY > -1)
1340       {
1341         int i = 0;
1342         XtSetArg(uiArgs[i], XmNy, hiddenY);i++;
1343         XtSetValues(smDD.lockDialog, uiArgs, i);
1344       }
1345     }
1346     
1347     timerId = (XtIntervalId)0; 
1348
1349    /*
1350     * Clear partially entered password if any.
1351     */
1352     CheckString(NULL, 0);
1353     lockDlgVisible = False;
1354
1355     XSync(smGD.display, 0);
1356   }
1357 }
1358
1359 \f
1360 /*************************************<->*************************************
1361  *
1362  *  PutUpLogin ()
1363  *
1364  *
1365  *  Description:
1366  *  -----------
1367  *  Redisplays the cover and the login when neccessary.
1368  *
1369  *
1370  *  Inputs:
1371  *  ------
1372  *
1373  * 
1374  *  Outputs:
1375  *  -------
1376  *
1377  *
1378  *  Comments:
1379  *  --------
1380  * 
1381  *************************************<->***********************************/
1382 static void 
1383 PutUpLogin(
1384   Boolean map,
1385   Boolean timeout )
1386 {
1387   if (map == True && lockDlgVisible == False)
1388   {
1389     if (smGD.coverScreen == True)
1390     {
1391       XtMapWidget(smDD.lockCoverDialog);
1392     }
1393     else
1394     {
1395       if (visibleY > -1)
1396       {
1397         int i = 0;
1398         XtSetArg(uiArgs[i], XmNy, visibleY);i++;
1399         XtSetValues(smDD.lockDialog, uiArgs, i);
1400       }
1401     }
1402     lockDlgVisible = True;
1403   }
1404
1405   if (timeout == True)
1406   {
1407     if(timerId != (XtIntervalId)0)
1408     {
1409         XtRemoveTimeOut(timerId);
1410     }
1411  
1412     if(smRes.alarmTime > 0)
1413     {
1414         timerId = XtAppAddTimeOut(smGD.appCon,
1415                                   (smRes.alarmTime * 1000),
1416                                   TakeDownLogin,NULL);
1417     }
1418   }
1419   XSync(smGD.display, 0);
1420 }
1421
1422 \f
1423 /*************************************<->*************************************
1424  *
1425  *  LockAttemptFailed ()
1426  *
1427  *
1428  *  Description:
1429  *  -----------
1430  *  Timed out trying to get a visibilitynotify on the lock
1431  *
1432  *
1433  *  Inputs:
1434  *  ------
1435  *
1436  * 
1437  *  Outputs:
1438  *  -------
1439  *
1440  *
1441  *  Comments:
1442  *  --------
1443  * 
1444  *************************************<->***********************************/
1445 static void 
1446 LockAttemptFailed(XtPointer     ptr,
1447                   XtIntervalId  *invId)
1448 {
1449     Widget lockWid = (Widget) ptr;
1450     
1451     PrintError(DtError, smNLS.cantLockErrorString);
1452     smGD.lockedState = UNLOCKED;
1453     XtRemoveEventHandler(lockWid, VisibilityChangeMask,
1454                          False, FinishLocking, NULL);
1455     UnlockDisplay(False, False);
1456     XSync(smGD.display, 0);
1457 }
1458
1459
1460
1461 \f
1462 /*************************************<->*************************************
1463  *
1464  *  RequirePassword ()
1465  *
1466  *
1467  *  Description:
1468  *  -----------
1469  *  Callback indicating a password is now required to unlock display.
1470  *
1471  *
1472  *  Inputs:
1473  *  ------
1474  *
1475  * 
1476  *  Outputs:
1477  *  -------
1478  *
1479  *
1480  *  Comments:
1481  *  --------
1482  * 
1483  *************************************<->***********************************/
1484 static void 
1485 RequirePassword(XtPointer       ptr,
1486                   XtIntervalId  *invId)
1487 {
1488   smGD.lockedState = LOCKED;
1489 }
1490
1491
1492 /*************************************<->*************************************
1493  *
1494  *  BlinkCaret ()
1495  *
1496  *
1497  *  Description:
1498  *  -----------
1499  *  blinks the caret in the password field
1500  *
1501  *
1502  *  Inputs:
1503  *  ------
1504  *
1505  *
1506  *  Outputs:
1507  *  -------
1508  *
1509  *
1510  *  Comments:
1511  *  --------
1512  *
1513  *************************************<->***********************************/
1514 static void
1515 BlinkCaret(XtPointer    ptr,
1516                   XtIntervalId  *invId)
1517 {
1518 static int flag = 1;
1519 XmString tmpString;
1520 int i;
1521  
1522  /*
1523   * Blink cursor to show the focus ..
1524   */
1525   if(flag){
1526      tmpString = XmStringCreateLocalized (" " );
1527      i = 0;
1528      XtSetArg(uiArgs[i], XmNlabelString,     tmpString); i++;
1529      XtSetValues(ptr, uiArgs, i);
1530      flag = 0;
1531   }
1532   else{
1533      tmpString = XmStringCreateLocalized ("|");
1534      i = 0;
1535      XtSetArg(uiArgs[i], XmNlabelString,     tmpString); i++;
1536      XtSetValues(ptr, uiArgs, i);
1537      flag = 1;
1538   }
1539  
1540   XmStringFree(tmpString);
1541   flash_id = XtAppAddTimeOut(smGD.appCon, 1000,
1542                             BlinkCaret, ptr);
1543 }
1544
1545
1546 \f
1547 /*************************************<->*************************************
1548  *
1549  *  CycleSaver ()
1550  *
1551  *
1552  *  Description:
1553  *  -----------
1554  *  Callback indicating we should cycle to next screen saver
1555  *
1556  *
1557  *  Inputs:
1558  *  ------
1559  *
1560  * 
1561  *  Outputs:
1562  *  -------
1563  *
1564  *
1565  *  Comments:
1566  *  --------
1567  * 
1568  *************************************<->***********************************/
1569 static void 
1570 CycleSaver(XtPointer    ptr,
1571                   XtIntervalId  *invId)
1572 {
1573  /*
1574   * Stop running screen saver, start a new one and reset timer.
1575   */
1576   StopScreenSaver();
1577   StartScreenSaver();  
1578   cycleId = XtAppAddTimeOut(smGD.appCon, smSaverRes.cycleTimeout*1000,
1579                             CycleSaver, NULL);
1580 }
1581
1582
1583 \f
1584 /*************************************<->*************************************
1585  *
1586  *  localAuthenticate (name, uid, passwd)
1587  *
1588  *
1589  *  Description:
1590  *  -----------
1591  *
1592  *
1593  *  Inputs:
1594  *  ------
1595  *
1596  * 
1597  *  Outputs:
1598  *  -------
1599  *
1600  *  Comments:
1601  *  --------
1602  * 
1603  *************************************<->***********************************/
1604 static Boolean 
1605 localAuthenticate(
1606         char *name,
1607         uid_t uid,
1608         char *passwd )
1609 #ifdef SIA
1610
1611
1612
1613   {
1614     char *Argv[2] = { "dtsession", NULL };
1615
1616     SIAENTITY *se = NULL;
1617     int code;
1618     char *  pw_name;
1619     uid_t real_uid;
1620
1621
1622     real_uid = getuid();
1623
1624     if (-1 == seteuid(0))
1625       return FALSE;
1626
1627
1628     if (passwd == NULL)
1629     {
1630       /*
1631       * Caller just checking if it is possible to access 
1632       * password file (ie is dtsession suid bit set properly).
1633       */
1634       seteuid(real_uid);
1635       return TRUE;
1636     }
1637     if (name && name[0])
1638       pw_name = name;
1639     else if (uid == 0)
1640       pw_name = "root";
1641     else
1642       pw_name = getlogin();
1643
1644
1645     if ( sia_ses_init(&se, 1, Argv, (char *)NULL,
1646                       pw_name, NULL, 0 /* don't collect info */, 
1647                       NULL) != SIASUCCESS)
1648       {
1649       seteuid(real_uid);
1650       return FALSE;
1651       }
1652     
1653     se->password = (char *)malloc(strlen(passwd) + 1);
1654     if ( se->password == (char *)NULL ) 
1655     {
1656         sia_ses_release(&se);
1657       seteuid(real_uid);
1658       return FALSE;
1659     }
1660
1661     strcpy(se->password, passwd);
1662
1663     code = sia_ses_reauthent (NULL, se);
1664     sia_ses_release(&se);
1665
1666     seteuid(real_uid);
1667
1668     if ( code == SIASUCCESS )
1669       return TRUE;
1670     else
1671       return FALSE;
1672 }
1673     
1674 #elif defined(linux)
1675
1676 {
1677     struct passwd *pwent = NULL;
1678     char *p, *q;
1679     char *crypt();
1680     Boolean rc = True;
1681     Boolean done = False;
1682     struct spwd *sp = NULL;
1683
1684     if(smGD.secureSystem)
1685     {   
1686       SM_SETEUID(smGD.unLockUID);
1687     }
1688
1689    /*
1690     * Get password entry for 'name' or 'uid'.
1691     */
1692     if (CanReAuthenticate(name, uid, passwd, &pwent, &sp) == False)
1693     {
1694      /*
1695       * Can't get entry.
1696       */
1697       rc = False;
1698       done = True;
1699     }
1700
1701     if(smGD.secureSystem)
1702     {
1703         SM_SETEUID(smGD.runningUID);
1704     }
1705
1706     if (done == False)
1707     {
1708
1709       if (pwent->pw_passwd == NULL || pwent->pw_passwd[0] == '*')
1710       {
1711                                 /* check sp */
1712         if (sp == NULL || sp->sp_pwdp == NULL)
1713           {
1714             /*
1715              * Could not read password.
1716              */
1717             rc = False;
1718             done = True;
1719           }
1720       }
1721     }
1722
1723     if (done == False)
1724     {
1725       if (passwd == NULL)
1726       {
1727        /*
1728         * Caller just checking if it is possible to access 
1729         * password file (ie is dtsession suid bit set properly).
1730         */
1731         rc = True; 
1732         done = True;
1733       }
1734     }
1735
1736     if (done == False)
1737     {
1738      /*
1739       * Check password.
1740       */
1741
1742       if (sp != NULL && !strcmp(sp->sp_pwdp, crypt(passwd,sp->sp_pwdp)))
1743         {                       /* a shadow match */
1744           rc = True;
1745           done = True;
1746         }
1747       else if (pwent != NULL && 
1748                !strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)))
1749         {                       /* passwd match */
1750           rc = True;
1751           done = True;
1752         }
1753       else
1754         {                       /* failure dude! */
1755           rc = False;
1756           done = True;
1757         }
1758     }
1759
1760     endpwent();
1761     endspent();
1762
1763     return(rc);
1764 }
1765
1766 #else
1767
1768 {
1769     register struct passwd *pwent;
1770     char *p, *q;
1771     char *crypt();
1772     Boolean rc = True;
1773     Boolean done = False;
1774
1775
1776 #ifdef SVR4
1777 # ifdef USL
1778     uinfo_t uinfo;
1779     char *upasswd, *newname = NULL;
1780 # else
1781     struct spwd *sp=NULL;
1782 # endif
1783 #endif
1784
1785     if(smGD.secureSystem)
1786     {   
1787         SM_SETEUID(smGD.unLockUID);
1788     }
1789
1790 #ifdef SVR4
1791    /*
1792     * Get shadow password entry for 'name' or 'uid'.
1793     */
1794     if (name == NULL)
1795     {
1796       pwent = getpwuid(uid);
1797       if (pwent != NULL) 
1798       {
1799 # ifdef USL
1800         name = newname = strdup(pwent->pw_name);
1801 # else
1802         name = pwent->pw_name;
1803 #endif
1804       }
1805     }
1806
1807     if (name == NULL ||
1808 # ifdef USL
1809         ia_openinfo(name, &uinfo)
1810 # else
1811         (sp = getspnam(name)) == NULL
1812 # endif
1813         )
1814     {
1815      /*
1816       * Can't get entry.
1817       */
1818       rc = False;
1819       done = True;
1820     }
1821 #else  /* SVR4 */
1822    /*
1823     * Get password entry for 'name' or 'uid'.
1824     */
1825     if ((pwent = (name == NULL ? getpwuid(uid) : getpwnam(name))) == NULL)
1826     {
1827      /*
1828       * Can't get entry.
1829       */
1830       rc = False;
1831       done = True;
1832     }
1833 #endif /* SVR4 */
1834
1835     if(smGD.secureSystem)
1836     {
1837         SM_SETEUID(smGD.runningUID);
1838     }
1839
1840     if (done == False)
1841     {
1842 #ifdef USL
1843         ia_get_logpwd(uinfo, &upasswd);
1844 #endif
1845       if (
1846           pwent->pw_passwd == NULL 
1847           || pwent->pw_passwd[0] == '*'
1848 #ifdef SVR4
1849 # ifdef USL
1850           || upasswd == NULL
1851 # else
1852           || sp == NULL
1853 # endif
1854 #endif
1855           )
1856       {
1857        /*
1858         * Could not read password.
1859         */
1860         rc = False;
1861         done = True;
1862       }
1863     }
1864
1865     if (done == False)
1866     {
1867       if (passwd == NULL)
1868       {
1869        /*
1870         * Caller just checking if it is possible to access 
1871         * password file (ie is dtsession suid bit set properly).
1872         */
1873         rc = True; 
1874         done = True;
1875       }
1876     }
1877
1878     if (done == False)
1879     {
1880      /*
1881       * Check password.
1882       */
1883 #ifdef SVR4
1884 # ifdef USL
1885       if (strcmp(crypt(passwd, upasswd), upasswd) != 0)
1886 # else
1887       if (strcmp(crypt(passwd,sp->sp_pwdp),sp->sp_pwdp) != 0)
1888 # endif
1889 #else
1890       if (strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd)) != 0)
1891 #endif
1892       {
1893        /*
1894         * Password incorrect.
1895         */
1896         rc = False;
1897         done = True;
1898       }
1899     }
1900
1901     endpwent();
1902 #ifdef SVR4
1903 # ifdef USL
1904     ia_closeinfo(uinfo);
1905     if (newname) free(newname);
1906 # else
1907     endspent();
1908 # endif
1909 #endif
1910
1911     return(rc);
1912 }
1913 #endif /* SIA */
1914
1915 \f
1916 /*************************************<->*************************************
1917  *
1918  *  Authenticate (name, uid, passwd)
1919  *
1920  *
1921  *  Description:
1922  *  -----------
1923  *
1924  *
1925  *  Inputs:
1926  *  ------
1927  *
1928  * 
1929  *  Outputs:
1930  *  -------
1931  *
1932  *  Comments:
1933  *  --------
1934  * 
1935  *************************************<->***********************************/
1936
1937 #if defined (_AIX) && defined(_POWER)
1938
1939 static Boolean 
1940 Authenticate(
1941         char *name,
1942         uid_t uid,
1943         char *passwd )
1944 {
1945     register struct passwd *pwent;
1946     char *p, *q;
1947     char *crypt();
1948     Boolean rc = True;
1949     Boolean done = False;
1950
1951     int arc;
1952     int reenter;
1953     char *newname = NULL;
1954     char *msg;
1955
1956     if(smGD.secureSystem)
1957     {
1958         SM_SETEUID(smGD.unLockUID);
1959     }
1960
1961    /*
1962     * Map uid to name.
1963     */
1964     if (name == NULL)
1965     {
1966       pwent = getpwuid(uid);
1967       if (pwent != NULL)
1968       {
1969         name = newname = strdup(pwent->pw_name);
1970       }
1971       endpwent();
1972     }
1973  
1974    /* 
1975     * Authenticate user. Note: normally, we should check 'reenter' to
1976     * see if the user has another challenge. Since the dtsession screen
1977     * lock i/f does not yet have the support, our policy is to let the
1978     * user back in if they pass the first (password) challenge.
1979     */ 
1980     arc = authenticate(name, passwd, &reenter, &msg);
1981
1982     if(smGD.secureSystem)
1983     {
1984         SM_SETEUID(smGD.runningUID);
1985     }
1986
1987     if (msg) free(msg);
1988     if (newname) free(newname);
1989
1990     return(arc == 0 ? True : False);
1991 }
1992 #endif /* _AIX && _POWER */
1993