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