auth.c revision 63249
1/*
2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3 *                    All rights reserved
4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
5 *
6 * $FreeBSD: head/crypto/openssh/auth.c 61212 2000-06-03 09:58:15Z kris $
7 */
8
9#include "includes.h"
10RCSID("$OpenBSD: auth.c,v 1.7 2000/05/17 21:37:24 deraadt Exp $");
11
12#include "xmalloc.h"
13#include "rsa.h"
14#include "ssh.h"
15#include "pty.h"
16#include "packet.h"
17#include "buffer.h"
18#include "cipher.h"
19#include "mpaux.h"
20#include "servconf.h"
21#include "compat.h"
22#include "channels.h"
23#include "match.h"
24
25#include "bufaux.h"
26#include "ssh2.h"
27#include "auth.h"
28#include "session.h"
29#include "dispatch.h"
30
31
32/* import */
33extern ServerOptions options;
34extern char *forced_command;
35
36/*
37 * Check if the user is allowed to log in via ssh. If user is listed in
38 * DenyUsers or user's primary group is listed in DenyGroups, false will
39 * be returned. If AllowUsers isn't empty and user isn't listed there, or
40 * if AllowGroups isn't empty and user isn't listed there, false will be
41 * returned.
42 * If the user's shell is not executable, false will be returned.
43 * Otherwise true is returned.
44 */
45int
46allowed_user(struct passwd * pw)
47{
48	struct stat st;
49	struct group *grp;
50	char *shell;
51	int i;
52
53	/* Shouldn't be called if pw is NULL, but better safe than sorry... */
54	if (!pw)
55		return 0;
56
57	/*
58	 * Get the shell from the password data.  An empty shell field is
59	 * legal, and means /bin/sh.
60	 */
61	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
62
63	/* deny if shell does not exists or is not executable */
64	if (stat(shell, &st) != 0)
65		return 0;
66	if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP))))
67		return 0;
68
69	/* Return false if user is listed in DenyUsers */
70	if (options.num_deny_users > 0) {
71		if (!pw->pw_name)
72			return 0;
73		for (i = 0; i < options.num_deny_users; i++)
74			if (match_pattern(pw->pw_name, options.deny_users[i]))
75				return 0;
76	}
77	/* Return false if AllowUsers isn't empty and user isn't listed there */
78	if (options.num_allow_users > 0) {
79		if (!pw->pw_name)
80			return 0;
81		for (i = 0; i < options.num_allow_users; i++)
82			if (match_pattern(pw->pw_name, options.allow_users[i]))
83				break;
84		/* i < options.num_allow_users iff we break for loop */
85		if (i >= options.num_allow_users)
86			return 0;
87	}
88	/* Get the primary group name if we need it. Return false if it fails */
89	if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
90		grp = getgrgid(pw->pw_gid);
91		if (!grp)
92			return 0;
93
94		/* Return false if user's group is listed in DenyGroups */
95		if (options.num_deny_groups > 0) {
96			if (!grp->gr_name)
97				return 0;
98			for (i = 0; i < options.num_deny_groups; i++)
99				if (match_pattern(grp->gr_name, options.deny_groups[i]))
100					return 0;
101		}
102		/*
103		 * Return false if AllowGroups isn't empty and user's group
104		 * isn't listed there
105		 */
106		if (options.num_allow_groups > 0) {
107			if (!grp->gr_name)
108				return 0;
109			for (i = 0; i < options.num_allow_groups; i++)
110				if (match_pattern(grp->gr_name, options.allow_groups[i]))
111					break;
112			/* i < options.num_allow_groups iff we break for
113			   loop */
114			if (i >= options.num_allow_groups)
115				return 0;
116		}
117	}
118#ifndef __FreeBSD__     /* FreeBSD handle it later */
119	/* Fail if the account's expiration time has passed. */
120	if (pw->pw_expire != 0) {
121		struct timeval tv;
122
123		(void)gettimeofday(&tv, NULL);
124		if (tv.tv_sec >= pw->pw_expire)
125			return 0;
126	}
127#endif /* !__FreeBSD__ */
128	/* We found no reason not to let this user try to log on... */
129	return 1;
130}
131