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