1145b7b3cSmrg/*
2145b7b3cSmrg
3145b7b3cSmrgCopyright 1988, 1998  The Open Group
4145b7b3cSmrg
5145b7b3cSmrgPermission to use, copy, modify, distribute, and sell this software and its
6145b7b3cSmrgdocumentation for any purpose is hereby granted without fee, provided that
7145b7b3cSmrgthe above copyright notice appear in all copies and that both that
8145b7b3cSmrgcopyright notice and this permission notice appear in supporting
9145b7b3cSmrgdocumentation.
10145b7b3cSmrg
11145b7b3cSmrgThe above copyright notice and this permission notice shall be included
12145b7b3cSmrgin all copies or substantial portions of the Software.
13145b7b3cSmrg
14145b7b3cSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15145b7b3cSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16145b7b3cSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17145b7b3cSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18145b7b3cSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19145b7b3cSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20145b7b3cSmrgOTHER DEALINGS IN THE SOFTWARE.
21145b7b3cSmrg
22145b7b3cSmrgExcept as contained in this notice, the name of The Open Group shall
23145b7b3cSmrgnot be used in advertising or otherwise to promote the sale, use or
24145b7b3cSmrgother dealings in this Software without prior written authorization
25145b7b3cSmrgfrom The Open Group.
26145b7b3cSmrg
27145b7b3cSmrg*/
28145b7b3cSmrg
29145b7b3cSmrg/*
30145b7b3cSmrg * xdm - display manager daemon
31145b7b3cSmrg * Author:  Keith Packard, MIT X Consortium
32145b7b3cSmrg *
33145b7b3cSmrg * verify.c
34145b7b3cSmrg *
35145b7b3cSmrg * typical unix verification routine.
36145b7b3cSmrg */
37145b7b3cSmrg
38145b7b3cSmrg#include	"dm.h"
39145b7b3cSmrg#include	"dm_error.h"
40145b7b3cSmrg
41145b7b3cSmrg#include	<pwd.h>
42145b7b3cSmrg
43145b7b3cSmrg#if defined(USE_PAM)
44145b7b3cSmrg# include	<stdlib.h>
45629baa8cSmrg#elif defined(HAVE_GETSPNAM)
46145b7b3cSmrg# include	<shadow.h>
47145b7b3cSmrg# include	<errno.h>
48145b7b3cSmrg#elif defined(USE_BSDAUTH)
49145b7b3cSmrg# include	<login_cap.h>
50b7d26471Smrg# include	<stdarg.h>
51145b7b3cSmrg# include	<bsd_auth.h>
52145b7b3cSmrg#endif
53145b7b3cSmrg
54578741aaSmrg#include	"greet.h"
55145b7b3cSmrg
56145b7b3cSmrg
57b7d26471Smrgstatic const char *envvars[] = {
584901b09eSmrg    "TZ",
59145b7b3cSmrg    NULL
60145b7b3cSmrg};
61145b7b3cSmrg
62145b7b3cSmrg#ifdef KERBEROS
63578741aaSmrg# include <sys/param.h>
64578741aaSmrg# include <kerberosIV/krb.h>
65145b7b3cSmrg/* OpenBSD 2.8 needs this. */
66578741aaSmrg# if defined(OpenBSD) && (OpenBSD <= 200012)
67578741aaSmrg#  include <kerberosIV/kafs.h>
68578741aaSmrg# endif
69145b7b3cSmrgstatic char krbtkfile[MAXPATHLEN];
70145b7b3cSmrg#endif
71145b7b3cSmrg
72145b7b3cSmrgstatic char **
73145b7b3cSmrguserEnv (struct display *d, int useSystemPath, char *user, char *home, char *shell)
74145b7b3cSmrg{
75145b7b3cSmrg    char	**env;
76b7d26471Smrg    const char	**envvar;
77b7d26471Smrg    const char	*str;
78145b7b3cSmrg
79145b7b3cSmrg    env = defaultEnv ();
80145b7b3cSmrg    env = setEnv (env, "DISPLAY", d->name);
81145b7b3cSmrg    env = setEnv (env, "HOME", home);
82145b7b3cSmrg    env = setEnv (env, "LOGNAME", user); /* POSIX, System V */
83145b7b3cSmrg    env = setEnv (env, "USER", user);    /* BSD */
84145b7b3cSmrg    env = setEnv (env, "PATH", useSystemPath ? d->systemPath : d->userPath);
85145b7b3cSmrg    env = setEnv (env, "SHELL", shell);
86145b7b3cSmrg#ifdef KERBEROS
87145b7b3cSmrg    if (krbtkfile[0] != '\0')
88145b7b3cSmrg        env = setEnv (env, "KRBTKFILE", krbtkfile);
89145b7b3cSmrg#endif
90145b7b3cSmrg    for (envvar = envvars; *envvar; envvar++)
91145b7b3cSmrg    {
92145b7b3cSmrg	str = getenv(*envvar);
93145b7b3cSmrg	if (str)
94145b7b3cSmrg	    env = setEnv (env, *envvar, str);
95145b7b3cSmrg    }
96145b7b3cSmrg    return env;
97145b7b3cSmrg}
98145b7b3cSmrg
99145b7b3cSmrg#ifdef USE_BSDAUTH
100145b7b3cSmrg_X_INTERNAL
101145b7b3cSmrgint
102145b7b3cSmrgVerify (struct display *d, struct greet_info *greet, struct verify_info *verify)
103145b7b3cSmrg{
104145b7b3cSmrg	struct passwd	*p;
105145b7b3cSmrg	login_cap_t	*lc;
106145b7b3cSmrg	auth_session_t	*as;
107145b7b3cSmrg	char		*style, *shell, *home, *s, **argv;
108145b7b3cSmrg	char		path[MAXPATHLEN];
109145b7b3cSmrg	int		authok;
110145b7b3cSmrg
111145b7b3cSmrg	/* User may have specified an authentication style. */
112145b7b3cSmrg	if ((style = strchr(greet->name, ':')) != NULL)
113145b7b3cSmrg		*style++ = '\0';
114145b7b3cSmrg
115145b7b3cSmrg	Debug ("Verify %s, style %s ...\n", greet->name,
116145b7b3cSmrg	    style ? style : "default");
117145b7b3cSmrg
118145b7b3cSmrg	p = getpwnam (greet->name);
119145b7b3cSmrg	endpwent();
120145b7b3cSmrg
121145b7b3cSmrg	if (!p || strlen (greet->name) == 0) {
122145b7b3cSmrg		Debug("getpwnam() failed.\n");
123145b7b3cSmrg		bzero(greet->password, strlen(greet->password));
124145b7b3cSmrg		return 0;
125145b7b3cSmrg	}
126145b7b3cSmrg
127145b7b3cSmrg	if ((lc = login_getclass(p->pw_class)) == NULL) {
128145b7b3cSmrg		Debug("login_getclass() failed.\n");
129145b7b3cSmrg		bzero(greet->password, strlen(greet->password));
130145b7b3cSmrg		return 0;
131145b7b3cSmrg	}
132145b7b3cSmrg	if ((style = login_getstyle(lc, style, "xdm")) == NULL) {
133145b7b3cSmrg		Debug("login_getstyle() failed.\n");
134145b7b3cSmrg		bzero(greet->password, strlen(greet->password));
135145b7b3cSmrg		return 0;
136145b7b3cSmrg	}
137145b7b3cSmrg	if ((as = auth_open()) == NULL) {
138145b7b3cSmrg		Debug("auth_open() failed.\n");
139145b7b3cSmrg		login_close(lc);
140145b7b3cSmrg		bzero(greet->password, strlen(greet->password));
141145b7b3cSmrg		return 0;
142145b7b3cSmrg	}
143145b7b3cSmrg	if (auth_setoption(as, "login", "yes") == -1) {
144145b7b3cSmrg		Debug("auth_setoption() failed.\n");
145145b7b3cSmrg		login_close(lc);
146145b7b3cSmrg		bzero(greet->password, strlen(greet->password));
147145b7b3cSmrg		return 0;
148145b7b3cSmrg	}
149145b7b3cSmrg
150145b7b3cSmrg	/* Set up state for no challenge, just check a response. */
151145b7b3cSmrg	auth_setstate(as, 0);
152145b7b3cSmrg	auth_setdata(as, "", 1);
153145b7b3cSmrg	auth_setdata(as, greet->password, strlen(greet->password) + 1);
154145b7b3cSmrg
155145b7b3cSmrg	/* Build path of the auth script and call it */
156145b7b3cSmrg	snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style);
157578741aaSmrg	auth_call(as, path, style, "-s", "response", greet->name,
158145b7b3cSmrg		  lc->lc_class, (void *)NULL);
159145b7b3cSmrg	authok = auth_getstate(as);
160145b7b3cSmrg
161145b7b3cSmrg	if ((authok & AUTH_ALLOW) == 0) {
162145b7b3cSmrg		Debug("password verify failed\n");
163145b7b3cSmrg		bzero(greet->password, strlen(greet->password));
164145b7b3cSmrg		auth_close(as);
165145b7b3cSmrg		login_close(lc);
166145b7b3cSmrg		return 0;
167145b7b3cSmrg	}
168145b7b3cSmrg	/* Run the approval script */
169145b7b3cSmrg	if (!auth_approval(as, lc, greet->name, "auth-xdm")) {
170145b7b3cSmrg		Debug("login not approved\n");
171145b7b3cSmrg		bzero(greet->password, strlen(greet->password));
172145b7b3cSmrg		auth_close(as);
173145b7b3cSmrg		login_close(lc);
174145b7b3cSmrg		return 0;
175145b7b3cSmrg	}
176145b7b3cSmrg	auth_close(as);
177145b7b3cSmrg	login_close(lc);
178145b7b3cSmrg	/* Check empty passwords against allowNullPasswd */
179145b7b3cSmrg	if (!greet->allow_null_passwd && strlen(greet->password) == 0) {
180145b7b3cSmrg		Debug("empty password not allowed\n");
181145b7b3cSmrg		return 0;
182145b7b3cSmrg	}
183145b7b3cSmrg	/* Only accept root logins if allowRootLogin resource is set */
184145b7b3cSmrg	if (p->pw_uid == 0 && !greet->allow_root_login) {
185145b7b3cSmrg		Debug("root logins not allowed\n");
186145b7b3cSmrg		bzero(greet->password, strlen(greet->password));
187145b7b3cSmrg		return 0;
188145b7b3cSmrg	}
189145b7b3cSmrg
190145b7b3cSmrg	/*
191578741aaSmrg	 * Shell must be in /etc/shells
192145b7b3cSmrg	 */
193145b7b3cSmrg	for (;;) {
194145b7b3cSmrg		s = getusershell();
195145b7b3cSmrg		if (s == NULL) {
196578741aaSmrg			/* did not found the shell in /etc/shells
197145b7b3cSmrg			   -> failure */
198145b7b3cSmrg			Debug("shell not in /etc/shells\n");
199145b7b3cSmrg			bzero(greet->password, strlen(greet->password));
200145b7b3cSmrg			endusershell();
201145b7b3cSmrg			return 0;
202145b7b3cSmrg		}
203145b7b3cSmrg		if (strcmp(s, p->pw_shell) == 0) {
204145b7b3cSmrg			/* found the shell in /etc/shells */
205145b7b3cSmrg			endusershell();
206145b7b3cSmrg			break;
207145b7b3cSmrg		}
208578741aaSmrg	}
209b7d26471Smrg#else /* !USE_BSDAUTH */
210145b7b3cSmrg_X_INTERNAL
211145b7b3cSmrgint
212145b7b3cSmrgVerify (struct display *d, struct greet_info *greet, struct verify_info *verify)
213145b7b3cSmrg{
214145b7b3cSmrg	struct passwd	*p;
215578741aaSmrg# ifndef USE_PAM
216629baa8cSmrg#  ifdef HAVE_GETSPNAM
217145b7b3cSmrg	struct spwd	*sp;
218578741aaSmrg#  endif
219145b7b3cSmrg	char		*user_pass = NULL;
220b7d26471Smrg	char		*crypted_pass = NULL;
221578741aaSmrg# endif
222578741aaSmrg# ifdef __OpenBSD__
223145b7b3cSmrg	char            *s;
224145b7b3cSmrg	struct timeval  tp;
225578741aaSmrg# endif
226145b7b3cSmrg	char		*shell, *home;
227145b7b3cSmrg	char		**argv;
228145b7b3cSmrg
229145b7b3cSmrg	Debug ("Verify %s ...\n", greet->name);
230145b7b3cSmrg
231145b7b3cSmrg	p = getpwnam (greet->name);
232145b7b3cSmrg	endpwent();
233145b7b3cSmrg
234145b7b3cSmrg	if (!p || strlen (greet->name) == 0) {
235145b7b3cSmrg		Debug ("getpwnam() failed.\n");
236145b7b3cSmrg		if (greet->password != NULL)
237145b7b3cSmrg		    bzero(greet->password, strlen(greet->password));
238145b7b3cSmrg		return 0;
239145b7b3cSmrg	}
240145b7b3cSmrg
241629baa8cSmrg	/*
242629baa8cSmrg	 * Only accept root logins if allowRootLogin resource is not false
243629baa8cSmrg	 */
244629baa8cSmrg	if ((p->pw_uid == 0) && !greet->allow_root_login) {
245629baa8cSmrg		Debug("root logins not allowed\n");
246629baa8cSmrg		if (greet->password != NULL)
247629baa8cSmrg		    bzero(greet->password, strlen(greet->password));
248629baa8cSmrg		return 0;
249629baa8cSmrg	}
250629baa8cSmrg
251578741aaSmrg# if defined(sun) && defined(SVR4)
252578741aaSmrg	/* Solaris: If CONSOLE is set to /dev/console in /etc/default/login,
253145b7b3cSmrg	   then root can only login on system console */
254145b7b3cSmrg
255578741aaSmrg#  define SOLARIS_LOGIN_DEFAULTS "/etc/default/login"
256145b7b3cSmrg
257145b7b3cSmrg	if (p->pw_uid == 0) {
258145b7b3cSmrg	    char *console = NULL, *tmp = NULL;
259145b7b3cSmrg	    FILE *fs;
260145b7b3cSmrg
261145b7b3cSmrg	    if ((fs= fopen(SOLARIS_LOGIN_DEFAULTS, "r")) != NULL)
262578741aaSmrg	    {
263145b7b3cSmrg		char str[120];
264145b7b3cSmrg		while (!feof(fs))
265145b7b3cSmrg		{
266145b7b3cSmrg		    fgets(str, 120, fs);
267145b7b3cSmrg		    if(str[0] == '#' || strlen(str) < 8)
268145b7b3cSmrg			continue;
269145b7b3cSmrg		    if((tmp = strstr(str, "CONSOLE=")) != NULL)
270145b7b3cSmrg			console = strdup((tmp+8));
271145b7b3cSmrg		}
272145b7b3cSmrg		fclose(fs);
273578741aaSmrg                if ( console != NULL &&
274578741aaSmrg		  (strncmp(console, "/dev/console", 12) == 0) &&
275145b7b3cSmrg		  (strncmp(d->name,":0",2) != 0) )
276145b7b3cSmrg		{
277145b7b3cSmrg                        Debug("Not on system console\n");
278145b7b3cSmrg			if (greet->password != NULL)
279145b7b3cSmrg			    bzero(greet->password, strlen(greet->password));
280629baa8cSmrg			free(console);
281145b7b3cSmrg	                return 0;
282145b7b3cSmrg                }
283145b7b3cSmrg		free(console);
284145b7b3cSmrg	    }
285145b7b3cSmrg	    else
286145b7b3cSmrg	    {
287145b7b3cSmrg		Debug("Could not open %s\n", SOLARIS_LOGIN_DEFAULTS);
288578741aaSmrg	    }
289145b7b3cSmrg	}
290578741aaSmrg# endif
291145b7b3cSmrg
292578741aaSmrg# ifndef USE_PAM /* PAM authentication happened in GreetUser already */
293578741aaSmrg#  ifdef linux
294145b7b3cSmrg	if (!strcmp(p->pw_passwd, "!") || !strcmp(p->pw_passwd, "*")) {
295145b7b3cSmrg	    Debug ("The account is locked, no login allowed.\n");
296145b7b3cSmrg	    bzero(greet->password, strlen(greet->password));
297145b7b3cSmrg	    return 0;
298145b7b3cSmrg	}
299578741aaSmrg#  endif
300145b7b3cSmrg	user_pass = p->pw_passwd;
301578741aaSmrg#  ifdef KERBEROS
302145b7b3cSmrg	if(strcmp(greet->name, "root") != 0){
303145b7b3cSmrg		char name[ANAME_SZ];
304145b7b3cSmrg		char realm[REALM_SZ];
305145b7b3cSmrg		char *q;
306145b7b3cSmrg		int ret;
307578741aaSmrg
308145b7b3cSmrg		if(krb_get_lrealm(realm, 1)){
309145b7b3cSmrg			Debug ("Can't get Kerberos realm.\n");
310145b7b3cSmrg		} else {
311145b7b3cSmrg
312578741aaSmrg		    snprintf(krbtkfile, sizeof(krbktfile), "%s.%s",
313578741aaSmrg			     TKT_ROOT, d->name);
314145b7b3cSmrg		    krb_set_tkt_string(krbtkfile);
315145b7b3cSmrg		    unlink(krbtkfile);
316578741aaSmrg
317578741aaSmrg		    ret = krb_verify_user(greet->name, "", realm,
318145b7b3cSmrg				      greet->password, 1, "rcmd");
319578741aaSmrg
320145b7b3cSmrg		    if(ret == KSUCCESS){
321145b7b3cSmrg			    chown(krbtkfile, p->pw_uid, p->pw_gid);
322145b7b3cSmrg			    Debug("kerberos verify succeeded\n");
323145b7b3cSmrg			    if (k_hasafs()) {
324145b7b3cSmrg				    if (k_setpag() == -1)
325145b7b3cSmrg					    LogError ("setpag() failed for %s\n",
326145b7b3cSmrg						      greet->name);
327578741aaSmrg
328145b7b3cSmrg				    if((ret = k_afsklog(NULL, NULL)) != KSUCCESS)
329578741aaSmrg					    LogError("Warning %s\n",
330145b7b3cSmrg						     krb_get_err_text(ret));
331145b7b3cSmrg			    }
332145b7b3cSmrg			    goto done;
333145b7b3cSmrg		    } else if(ret != KDC_PR_UNKNOWN && ret != SKDC_CANT){
334145b7b3cSmrg			    /* failure */
335145b7b3cSmrg			    Debug("kerberos verify failure %d\n", ret);
336145b7b3cSmrg			    krbtkfile[0] = '\0';
337145b7b3cSmrg		    }
338145b7b3cSmrg		}
339145b7b3cSmrg	}
340578741aaSmrg#  endif
341629baa8cSmrg#  ifdef HAVE_GETSPNAM
342145b7b3cSmrg	errno = 0;
343145b7b3cSmrg	sp = getspnam(greet->name);
344145b7b3cSmrg	if (sp == NULL) {
345578741aaSmrg	    Debug ("getspnam() failed: %s\n", _SysErrorMsg (errno));
346145b7b3cSmrg	} else {
347145b7b3cSmrg	    user_pass = sp->sp_pwdp;
348145b7b3cSmrg	}
349145b7b3cSmrg	endspent();
350629baa8cSmrg#  endif /* HAVE_GETSPNAM */
351b7d26471Smrg	crypted_pass = crypt (greet->password, user_pass);
352b7d26471Smrg	if ((crypted_pass == NULL)
353b7d26471Smrg	    || (strcmp (crypted_pass, user_pass)))
354145b7b3cSmrg	{
355145b7b3cSmrg		if(!greet->allow_null_passwd || strlen(p->pw_passwd) > 0) {
356145b7b3cSmrg			Debug ("password verify failed\n");
357145b7b3cSmrg			bzero(greet->password, strlen(greet->password));
358145b7b3cSmrg			return 0;
359145b7b3cSmrg		} /* else: null passwd okay */
360145b7b3cSmrg	}
361578741aaSmrg#  ifdef KERBEROS
362145b7b3cSmrgdone:
363578741aaSmrg#  endif
364145b7b3cSmrg	/*
365145b7b3cSmrg	 * Only accept root logins if allowRootLogin resource is set
366145b7b3cSmrg	 */
367145b7b3cSmrg	if ((p->pw_uid == 0) && !greet->allow_root_login) {
368145b7b3cSmrg		Debug("root logins not allowed\n");
369145b7b3cSmrg		bzero(greet->password, strlen(greet->password));
370145b7b3cSmrg		return 0;
371145b7b3cSmrg	}
372629baa8cSmrg#  ifdef __OpenBSD__
373145b7b3cSmrg	/*
374578741aaSmrg	 * Shell must be in /etc/shells
375145b7b3cSmrg	 */
376145b7b3cSmrg	for (;;) {
377145b7b3cSmrg		s = getusershell();
378145b7b3cSmrg		if (s == NULL) {
379578741aaSmrg			/* did not found the shell in /etc/shells
380145b7b3cSmrg			   -> failure */
381145b7b3cSmrg			Debug("shell not in /etc/shells\n");
382145b7b3cSmrg			bzero(greet->password, strlen(greet->password));
383145b7b3cSmrg			endusershell();
384145b7b3cSmrg			return 0;
385145b7b3cSmrg		}
386145b7b3cSmrg		if (strcmp(s, p->pw_shell) == 0) {
387145b7b3cSmrg			/* found the shell in /etc/shells */
388145b7b3cSmrg			endusershell();
389145b7b3cSmrg			break;
390145b7b3cSmrg		}
391578741aaSmrg	}
392145b7b3cSmrg	/*
393145b7b3cSmrg	 * Test for expired password
394145b7b3cSmrg	 */
395145b7b3cSmrg	if (p->pw_change || p->pw_expire)
396145b7b3cSmrg		(void)gettimeofday(&tp, (struct timezone *)NULL);
397145b7b3cSmrg	if (p->pw_change) {
398145b7b3cSmrg		if (tp.tv_sec >= p->pw_change) {
399145b7b3cSmrg			Debug("Password has expired.\n");
400145b7b3cSmrg			bzero(greet->password, strlen(greet->password));
401145b7b3cSmrg			return 0;
402145b7b3cSmrg		}
403145b7b3cSmrg	}
404145b7b3cSmrg	if (p->pw_expire) {
405145b7b3cSmrg		if (tp.tv_sec >= p->pw_expire) {
406145b7b3cSmrg			Debug("account has expired.\n");
407145b7b3cSmrg			bzero(greet->password, strlen(greet->password));
408145b7b3cSmrg			return 0;
409578741aaSmrg		}
410145b7b3cSmrg	}
411578741aaSmrg#  endif /* __OpenBSD__ */
412145b7b3cSmrg	bzero(user_pass, strlen(user_pass)); /* in case shadow password */
413145b7b3cSmrg
414578741aaSmrg# endif /* USE_PAM */
415145b7b3cSmrg#endif /* USE_BSDAUTH */
416145b7b3cSmrg
417145b7b3cSmrg	Debug ("verify succeeded\n");
418145b7b3cSmrg	/* The password is passed to StartClient() for use by user-based
419145b7b3cSmrg	   authorization schemes.  It is zeroed there. */
420145b7b3cSmrg	verify->uid = p->pw_uid;
421145b7b3cSmrg	verify->gid = p->pw_gid;
422145b7b3cSmrg	home = p->pw_dir;
423145b7b3cSmrg	shell = p->pw_shell;
424145b7b3cSmrg	argv = NULL;
425145b7b3cSmrg	if (d->session)
426145b7b3cSmrg		argv = parseArgs (argv, d->session);
427145b7b3cSmrg	if (greet->string)
428145b7b3cSmrg		argv = parseArgs (argv, greet->string);
429145b7b3cSmrg	if (!argv)
430145b7b3cSmrg		argv = parseArgs (argv, "xsession");
431145b7b3cSmrg	verify->argv = argv;
432145b7b3cSmrg	verify->userEnviron = userEnv (d, p->pw_uid == 0,
433145b7b3cSmrg				       greet->name, home, shell);
434145b7b3cSmrg	Debug ("user environment:\n");
435145b7b3cSmrg	printEnv (verify->userEnviron);
436145b7b3cSmrg	verify->systemEnviron = systemEnv (d, greet->name, home);
437145b7b3cSmrg	Debug ("system environment:\n");
438145b7b3cSmrg	printEnv (verify->systemEnviron);
439145b7b3cSmrg	Debug ("end of environments\n");
440145b7b3cSmrg	return 1;
441145b7b3cSmrg}
442