Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtlogin / vgapollo.c
1 /* $XConsortium: vgapollo.c /main/4 1995/10/27 16:17:06 rswiston $ */
2 /*                                                                      *
3  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
4  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
5  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
6  * (c) Copyright 1993, 1994 Novell, Inc.                                *
7  */
8 /************************************<+>*************************************
9  ****************************************************************************
10  **
11  **   File:        vgapollo.c
12  **
13  **   Project:     HP Visual User Environment (DT)
14  **
15  **   Description: Dtgreet user authentication routines for Domain/OS 10.4
16  **
17  **                These routines validate the user; checking name, password,
18  **                home directory, password aging, etc.
19  **
20  **
21  **   (c) Copyright 1987, 1988, 1989 by Hewlett-Packard Company
22  **
23  **
24  **     Conditional compiles:
25  **
26  **     __apollo    Domain OS only
27  **
28  ****************************************************************************
29  ************************************<+>*************************************/
30
31
32 #include        <stdio.h>               /* placed here so file isn't empty  */
33 #include        "vgmsg.h"
34
35 #ifdef __apollo
36
37 /***************************************************************************
38  *
39  *  Includes & Defines
40  *
41  ***************************************************************************/
42
43 #include        <pwd.h>
44
45 #include        <apollo/base.h>
46 #include        <apollo/error.h>
47
48 #include        "apollo/passwd.h"       /* copy of <apollo/sys/passwd.h>   */
49 #include        "apollo/login.h"        /* copy of <apollo/sys/login.h>    */
50 #include        "apollo/rgy_base.h"
51
52 #include        "vg.h"
53
54       
55 #define SCMPN(a, b)     strncmp(a, b, sizeof(a))
56 #define SCPYN(a, b)     strncpy(a, b, sizeof(a))
57 #define eq(a,b)         !strcmp(a,b)
58
59 #define NMAX    strlen(name)
60 #define HMAX    strlen(host)
61
62 #define STRING(str)     (str), (short) strlen(str)
63 #define STRNULL(s, l)   ((s)[(l)] = '\0')
64 #define ISTRING(str)    (str), (int) strlen(str)
65
66
67
68 /***************************************************************************
69  *
70  *  External declarations
71  *
72  ***************************************************************************/
73
74
75 /***************************************************************************
76  *
77  *  Procedure declarations
78  *
79  ***************************************************************************/
80
81
82 static boolean  CheckLogin( char *user, char *passwd, char *host, 
83                             status_$t *status)
84 static boolean  CheckPassword( char *user, char *passwd) ;
85 static int      PasswordAged( register struct passwd *pw) ;
86
87
88
89
90 /***************************************************************************
91  *
92  *  Global variables
93  *
94  ***************************************************************************/
95
96 rgy_$policy_t       policy;
97 rgy_$acct_user_t user_part;
98 rgy_$acct_admin_t admin_part;     
99 extern struct passwd * getpwnam_full();
100
101
102
103 /***************************************************************************
104  *
105  *  Stub routines
106  *
107  ***************************************************************************/
108
109
110
111
112 /***************************************************************************
113  *
114  *  CheckLogin
115  *
116  *  check validity of user name, password and other login parameters
117  *
118  ***************************************************************************/
119
120 static boolean
121 CheckLogin( char *user, char *passwd, char *host, status_$t *status)
122 {
123     ios_$id_t           logid;
124     login_$opt_set_t    opts;
125       
126     login_$set_host(host, strlen(host));
127
128     opts = login_$no_setsid_sm |
129            login_$no_setwd_sm  |
130            login_$no_prompt_pass;
131
132     if ( !login_$chk_login(opts,
133                         STRING(user),
134                         STRING(passwd), 
135                         (login_$open_log_p) NULL,
136                         STRING(""),
137                         &logid,
138                         status)) {
139
140         return(false);
141
142     } else
143         return(true);
144 }     
145
146
147
148
149 /***************************************************************************
150  *
151  *  CheckPassword
152  *
153  *  check validity of just user name and password
154  ***************************************************************************/
155
156 static boolean 
157 CheckPassword( char *user, char *passwd )
158 {
159     login_$ptr  lptr;
160     status_$t   status;
161              
162     login_$open((login_$mode_t) 0, &lptr, &status);
163     if (status.all == status_$ok)
164         login_$set_ppo(lptr, STRING(user), &status);
165     if (status.all == status_$ok)
166         login_$ckpass(lptr, STRING(passwd), &status);
167
168     return (status.all == status_$ok);
169 }     
170
171
172
173
174 /***************************************************************************
175  *
176  *  PasswordAged
177  *
178  *  see if password has aged
179  ***************************************************************************/
180
181 static int 
182 PasswordAged( register struct passwd *pw )
183 {
184
185     boolean lrgy;
186
187     /* Account validity checks:  If we were able to connect to the network
188      * registry, then we've acquired account and policy data and can perform
189      * account/password checking
190      */
191
192     lrgy = rgy_$using_local_registry();
193     if ( !lrgy ) { 
194
195         /* Check for password expiration or invalidity */
196         if (rgy_$is_passwd_expired(&user_part, &policy ) == true  ||
197             rgy_$is_passwd_invalid(&user_part) == true)  {
198
199             return TRUE;
200         }
201     }
202    return FALSE;
203 }
204
205
206     
207
208 /***************************************************************************
209  *
210  *  Verify
211  *
212  *  verify the user
213  *
214  *  return codes indicate authentication results.
215  ***************************************************************************/
216
217 #define MAXATTEMPTS     5
218
219 extern Widget focusWidget;              /* login or password text field    */
220 struct  passwd nouser = {"", "nope"};   /* invalid user password struct    */
221
222 int 
223 Verify( char *name, char *passwd )
224 {
225
226     static int          login_attempts = 0; /* # failed authentications    */
227     
228     struct passwd       *p;     /* password structure                      */
229     char                *host;  /* host that login is coming in from       */
230     status_$t           status; /* status code returned by CheckLogin      */
231
232     int                 n;
233
234     host = dpyinfo.name;
235     
236
237     /*
238      *  look up entry from registry...
239      *
240      *  need getpwnam_full to get policy data for passwd expiration 
241      *  or invalidity...
242      */
243     p = getpwnam_full(name, &user_part, &admin_part, &policy);
244 /*    p = getpwnam(name);*/
245     
246     if (!p || strlen(name) == 0 || p->pw_name == NULL )
247         p = &nouser;
248
249
250     /*
251      *  validate user/password...
252      */
253
254     if (!CheckLogin(name, passwd, host, &status)) {
255
256         /*
257          *  if verification failed, but was just a name check, prompt for
258          *  password...
259          */
260
261         if ( focusWidget != passwd_text ) 
262             return (VF_INVALID);
263
264
265         /*
266          *  if maximum number of attempts exceeded, log failure...
267          */
268
269         if ((++login_attempts % MAXATTEMPTS) == 0 ) {
270
271 #ifdef peter
272                 syslog(LOG_CRIT,
273                     "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s",
274                     "??", HMAX, host, NMAX, name);
275 #endif
276         }
277         
278
279         /*
280          *  check status codes from verification...
281          */
282      
283         switch (status.all) {
284
285         case login_$logins_disabled:    /* logins are disabled             */
286             if (p->pw_uid != 0)
287                 return(VF_NO_LOGIN);
288             else
289                 if (!CheckPassword(name,passwd))
290                     return(VF_INVALID);
291                     
292             break;
293
294         case login_$inv_acct:           /* invalid account                 */
295             if ( PasswordAged(p) ) 
296                 return(VF_PASSWD_AGED);
297             else
298                 return(VF_INVALID);
299             break;
300
301         default:                        /* other failed verification       */
302             return(VF_INVALID);
303             break;
304
305         }
306     }
307
308          
309
310     /*
311      *  verify home directory exists...
312      */
313
314     if (chdir(p->pw_dir) < 0) {
315         if (chdir("/") < 0)
316             return(VF_HOME);
317         else 
318             LogError(ReadCatalog(
319                 MC_LOG_SET,MC_LOG_NO_HMDIR,MC_DEF_LOG_NO_HMDIR),
320                 p->pw_dir, name);
321     }
322
323
324     /*
325      *  validate uid and gid...
326      */
327
328     if ((p->pw_gid < 0)      || 
329         (setgid(p->pw_gid) == -1)) {
330         return(VF_BAD_GID);
331     }
332
333     if ((p->pw_uid < 0)      || 
334         (seteuid(p->pw_uid) == -1)) {
335         return(VF_BAD_UID);
336     }
337
338
339     /*
340      * verify ok...
341      */
342
343     return(VF_OK);
344 }
345
346 #endif