xref: /freebsd/crypto/openssh/auth.c (revision 1b6c2589164a3a7b2f62d4c28c2ffa1be860959e)
1 /*
2  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24 
25 #include "includes.h"
26 RCSID("$OpenBSD: auth.c,v 1.21 2001/03/19 17:07:23 markus Exp $");
27 RCSID("$FreeBSD$");
28 
29 #include "xmalloc.h"
30 #include "match.h"
31 #include "groupaccess.h"
32 #include "log.h"
33 #include "servconf.h"
34 #include "auth.h"
35 #include "auth-options.h"
36 #include "canohost.h"
37 
38 /* import */
39 extern ServerOptions options;
40 
41 /*
42  * Check if the user is allowed to log in via ssh. If user is listed
43  * in DenyUsers or one of user's groups is listed in DenyGroups, false
44  * will be returned. If AllowUsers isn't empty and user isn't listed
45  * there, or if AllowGroups isn't empty and one of user's groups isn't
46  * listed there, false will be returned.
47  * If the user's shell is not executable, false will be returned.
48  * Otherwise true is returned.
49  */
50 int
51 allowed_user(struct passwd * pw)
52 {
53 	struct stat st;
54 	char *shell;
55 	int i;
56 
57 	/* Shouldn't be called if pw is NULL, but better safe than sorry... */
58 	if (!pw || !pw->pw_name)
59 		return 0;
60 
61 	/*
62 	 * Get the shell from the password data.  An empty shell field is
63 	 * legal, and means /bin/sh.
64 	 */
65 	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
66 
67 	/* deny if shell does not exists or is not executable */
68 	if (stat(shell, &st) != 0)
69 		return 0;
70 	if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP))))
71 		return 0;
72 
73 	/* Return false if user is listed in DenyUsers */
74 	if (options.num_deny_users > 0) {
75 		for (i = 0; i < options.num_deny_users; i++)
76 			if (match_pattern(pw->pw_name, options.deny_users[i]))
77 				return 0;
78 	}
79 	/* Return false if AllowUsers isn't empty and user isn't listed there */
80 	if (options.num_allow_users > 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 	if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
89 		/* Get the user's group access list (primary and supplementary) */
90 		if (ga_init(pw->pw_name, pw->pw_gid) == 0)
91 			return 0;
92 
93 		/* Return false if one of user's groups is listed in DenyGroups */
94 		if (options.num_deny_groups > 0)
95 			if (ga_match(options.deny_groups,
96 			    options.num_deny_groups)) {
97 				ga_free();
98 				return 0;
99 			}
100 		/*
101 		 * Return false if AllowGroups isn't empty and one of user's groups
102 		 * isn't listed there
103 		 */
104 		if (options.num_allow_groups > 0)
105 			if (!ga_match(options.allow_groups,
106 			    options.num_allow_groups)) {
107 				ga_free();
108 				return 0;
109 			}
110 		ga_free();
111 	}
112 	/* We found no reason not to let this user try to log on... */
113 	return 1;
114 }
115 
116 Authctxt *
117 authctxt_new(void)
118 {
119 	Authctxt *authctxt = xmalloc(sizeof(*authctxt));
120 	memset(authctxt, 0, sizeof(*authctxt));
121 	return authctxt;
122 }
123 
124 void
125 auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
126 {
127 	void (*authlog) (const char *fmt,...) = verbose;
128 	char *authmsg;
129 
130 	/* Raise logging level */
131 	if (authenticated == 1 ||
132 	    !authctxt->valid ||
133 	    authctxt->failures >= AUTH_FAIL_LOG ||
134 	    strcmp(method, "password") == 0)
135 		authlog = log;
136 
137 	if (authctxt->postponed)
138 		authmsg = "Postponed";
139 	else
140 		authmsg = authenticated ? "Accepted" : "Failed";
141 
142 	authlog("%s %s for %s%.100s from %.200s port %d%s",
143 	    authmsg,
144 	    method,
145 	    authctxt->valid ? "" : "illegal user ",
146 	    authctxt->valid && authctxt->pw->pw_uid == 0 ? "ROOT" : authctxt->user,
147 	    get_remote_ipaddr(),
148 	    get_remote_port(),
149 	    info);
150 }
151 
152 /*
153  * Check whether root logins are disallowed.
154  */
155 int
156 auth_root_allowed(char *method)
157 {
158 	switch (options.permit_root_login) {
159 	case PERMIT_YES:
160 		return 1;
161 		break;
162 	case PERMIT_NO_PASSWD:
163 		if (strcmp(method, "password") != 0)
164 			return 1;
165 		break;
166 	case PERMIT_FORCED_ONLY:
167 		if (forced_command) {
168 			log("Root login accepted for forced command.");
169 			return 1;
170 		}
171 		break;
172 	}
173 	log("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr());
174 	return 0;
175 }
176