]> andersk Git - openssh.git/blob - auth.c
Please grep through the source and look for 'ISSUE' comments and verify
[openssh.git] / auth.c
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.13 2001/01/18 16:59:59 markus Exp $");
27
28 #include "xmalloc.h"
29 #include "ssh.h"
30 #include "match.h"
31 #include "servconf.h"
32 #include "groupaccess.h"
33 #ifdef HAVE_LOGIN_H
34 #include <login.h>
35 #endif
36 #if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
37 #include <shadow.h>
38 #endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
39
40 #include "auth.h"
41 #include "auth-options.h"
42
43 /* import */
44 extern ServerOptions options;
45
46 /*
47  * Check if the user is allowed to log in via ssh. If user is listed
48  * in DenyUsers or one of user's groups is listed in DenyGroups, false
49  * will be returned. If AllowUsers isn't empty and user isn't listed
50  * there, or if AllowGroups isn't empty and one of user's groups isn't
51  * listed there, false will be returned.
52  * If the user's shell is not executable, false will be returned.
53  * Otherwise true is returned.
54  */
55 int
56 allowed_user(struct passwd * pw)
57 {
58         struct stat st;
59         char *shell;
60         int i;
61 #ifdef WITH_AIXAUTHENTICATE
62         char *loginmsg;
63 #endif /* WITH_AIXAUTHENTICATE */
64 #if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \
65         !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
66         struct spwd *spw;
67
68         /* Shouldn't be called if pw is NULL, but better safe than sorry... */
69         if (!pw || !pw->pw_name)
70                 return 0;
71
72         spw = getspnam(pw->pw_name);
73         if (spw != NULL) {
74                 int days = time(NULL) / 86400;
75
76                 /* Check account expiry */
77                 if ((spw->sp_expire >= 0) && (days > spw->sp_expire))
78                         return 0;
79
80                 /* Check password expiry */
81                 if ((spw->sp_lstchg >= 0) && (spw->sp_max >= 0) && 
82                     (days > (spw->sp_lstchg + spw->sp_max)))
83                         return 0;
84         }
85 #else
86         /* Shouldn't be called if pw is NULL, but better safe than sorry... */
87         if (!pw || !pw->pw_name)
88                 return 0;
89 #endif
90
91         /*
92          * Get the shell from the password data.  An empty shell field is
93          * legal, and means /bin/sh.
94          */
95         shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
96
97         /* deny if shell does not exists or is not executable */
98         if (stat(shell, &st) != 0)
99                 return 0;
100         if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP))))
101                 return 0;
102
103         /* Return false if user is listed in DenyUsers */
104         if (options.num_deny_users > 0) {
105                 for (i = 0; i < options.num_deny_users; i++)
106                         if (match_pattern(pw->pw_name, options.deny_users[i]))
107                                 return 0;
108         }
109         /* Return false if AllowUsers isn't empty and user isn't listed there */
110         if (options.num_allow_users > 0) {
111                 for (i = 0; i < options.num_allow_users; i++)
112                         if (match_pattern(pw->pw_name, options.allow_users[i]))
113                                 break;
114                 /* i < options.num_allow_users iff we break for loop */
115                 if (i >= options.num_allow_users)
116                         return 0;
117         }
118         if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
119                 /* Get the user's group access list (primary and supplementary) */
120                 if (ga_init(pw->pw_name, pw->pw_gid) == 0)
121                         return 0;
122
123                 /* Return false if one of user's groups is listed in DenyGroups */
124                 if (options.num_deny_groups > 0)
125                         if (ga_match(options.deny_groups,
126                             options.num_deny_groups)) {
127                                 ga_free();
128                                 return 0;
129                         }
130                 /*
131                  * Return false if AllowGroups isn't empty and one of user's groups
132                  * isn't listed there
133                  */
134                 if (options.num_allow_groups > 0)
135                         if (!ga_match(options.allow_groups,
136                             options.num_allow_groups)) {
137                                 ga_free();
138                                 return 0;
139                         }
140                 ga_free();
141         }
142
143 #ifdef WITH_AIXAUTHENTICATE
144         if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) {
145                 if (loginmsg && *loginmsg) {
146                         /* Remove embedded newlines (if any) */
147                         char *p;
148                         for (p = loginmsg; *p; p++) {
149                                 if (*p == '\n')
150                                         *p = ' ';
151                         }
152                         /* Remove trailing newline */
153                         *--p = '\0';
154                         log("Login restricted for %s: %.100s", pw->pw_name, loginmsg);
155                 }
156                 return 0;
157         }
158 #endif /* WITH_AIXAUTHENTICATE */
159
160         /* We found no reason not to let this user try to log on... */
161         return 1;
162 }
163
164 Authctxt *
165 authctxt_new(void)
166 {
167         Authctxt *authctxt = xmalloc(sizeof(*authctxt));
168         memset(authctxt, 0, sizeof(*authctxt));
169         return authctxt;
170 }
171
172 struct passwd *
173 pwcopy(struct passwd *pw)
174 {
175         struct passwd *copy = xmalloc(sizeof(*copy));
176         memset(copy, 0, sizeof(*copy));
177         copy->pw_name = xstrdup(pw->pw_name);
178         copy->pw_passwd = xstrdup(pw->pw_passwd);
179         copy->pw_uid = pw->pw_uid;
180         copy->pw_gid = pw->pw_gid;
181 #ifdef HAVE_PW_CLASS_IN_PASSWD
182         copy->pw_class = xstrdup(pw->pw_class);
183 #endif
184         copy->pw_dir = xstrdup(pw->pw_dir);
185         copy->pw_shell = xstrdup(pw->pw_shell);
186         return copy;
187 }
188
189 void
190 auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
191 {
192         void (*authlog) (const char *fmt,...) = verbose;
193         char *authmsg;
194
195         /* Raise logging level */
196         if (authenticated == 1 ||
197             !authctxt->valid ||
198             authctxt->failures >= AUTH_FAIL_LOG ||
199             strcmp(method, "password") == 0)
200                 authlog = log;
201
202         if (authctxt->postponed)
203                 authmsg = "Postponed";
204         else
205                 authmsg = authenticated ? "Accepted" : "Failed";
206
207         authlog("%s %s for %s%.100s from %.200s port %d%s",
208             authmsg,
209             method,
210             authctxt->valid ? "" : "illegal user ",
211             authctxt->valid && authctxt->pw->pw_uid == 0 ? "ROOT" : authctxt->user,
212             get_remote_ipaddr(),
213             get_remote_port(),
214             info);
215 }
216
217 /*
218  * Check if the user is logging in as root and root logins are disallowed.
219  * Note that root login is _allways_ allowed for forced commands.
220  */
221 int
222 auth_root_allowed(void)
223 {
224         if (options.permit_root_login)
225                 return 1;
226         if (forced_command) {
227                 log("Root login accepted for forced command.");
228                 return 1;
229         } else {
230                 log("ROOT LOGIN REFUSED FROM %.200s", get_canonical_hostname());
231                 return 0;
232         }
233 }
This page took 0.630606 seconds and 5 git commands to generate.