auth.c revision 60573
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
7#include "includes.h"
8RCSID("$OpenBSD: auth.c,v 1.6 2000/04/26 21:28:31 markus Exp $");
9
10#include "xmalloc.h"
11#include "rsa.h"
12#include "ssh.h"
13#include "pty.h"
14#include "packet.h"
15#include "buffer.h"
16#include "cipher.h"
17#include "mpaux.h"
18#include "servconf.h"
19#include "compat.h"
20#include "channels.h"
21#include "match.h"
22
23#include "bufaux.h"
24#include "ssh2.h"
25#include "auth.h"
26#include "session.h"
27#include "dispatch.h"
28
29
30/* import */
31extern ServerOptions options;
32extern char *forced_command;
33
34/*
35 * Check if the user is allowed to log in via ssh. If user is listed in
36 * DenyUsers or user's primary group is listed in DenyGroups, false will
37 * be returned. If AllowUsers isn't empty and user isn't listed there, or
38 * if AllowGroups isn't empty and user isn't listed there, false will be
39 * returned.
40 * If the user's shell is not executable, false will be returned.
41 * Otherwise true is returned.
42 */
43int
44allowed_user(struct passwd * pw)
45{
46	struct stat st;
47	struct group *grp;
48	int i;
49
50	/* Shouldn't be called if pw is NULL, but better safe than sorry... */
51	if (!pw)
52		return 0;
53
54	/* deny if shell does not exists or is not executable */
55	if (stat(pw->pw_shell, &st) != 0)
56		return 0;
57	if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP))))
58		return 0;
59
60	/* Return false if user is listed in DenyUsers */
61	if (options.num_deny_users > 0) {
62		if (!pw->pw_name)
63			return 0;
64		for (i = 0; i < options.num_deny_users; i++)
65			if (match_pattern(pw->pw_name, options.deny_users[i]))
66				return 0;
67	}
68	/* Return false if AllowUsers isn't empty and user isn't listed there */
69	if (options.num_allow_users > 0) {
70		if (!pw->pw_name)
71			return 0;
72		for (i = 0; i < options.num_allow_users; i++)
73			if (match_pattern(pw->pw_name, options.allow_users[i]))
74				break;
75		/* i < options.num_allow_users iff we break for loop */
76		if (i >= options.num_allow_users)
77			return 0;
78	}
79	/* Get the primary group name if we need it. Return false if it fails */
80	if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
81		grp = getgrgid(pw->pw_gid);
82		if (!grp)
83			return 0;
84
85		/* Return false if user's group is listed in DenyGroups */
86		if (options.num_deny_groups > 0) {
87			if (!grp->gr_name)
88				return 0;
89			for (i = 0; i < options.num_deny_groups; i++)
90				if (match_pattern(grp->gr_name, options.deny_groups[i]))
91					return 0;
92		}
93		/*
94		 * Return false if AllowGroups isn't empty and user's group
95		 * isn't listed there
96		 */
97		if (options.num_allow_groups > 0) {
98			if (!grp->gr_name)
99				return 0;
100			for (i = 0; i < options.num_allow_groups; i++)
101				if (match_pattern(grp->gr_name, options.allow_groups[i]))
102					break;
103			/* i < options.num_allow_groups iff we break for
104			   loop */
105			if (i >= options.num_allow_groups)
106				return 0;
107		}
108	}
109	/* We found no reason not to let this user try to log on... */
110	return 1;
111}
112