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