auth.c revision 69591
1/* 2 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * All rights reserved 4 * 5 * As far as I am concerned, the code I have written for this software 6 * can be used freely for any purpose. Any derived versions of this 7 * software must be clearly marked as such, and if the derived work is 8 * incompatible with the protocol description in the RFC file, it must be 9 * called by a name other than "ssh" or "Secure Shell". 10 * 11 * 12 * Copyright (c) 2000 Markus Friedl. All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35#include "includes.h" 36RCSID("$OpenBSD: auth.c,v 1.11 2000/10/11 20:27:23 markus Exp $"); 37RCSID("$FreeBSD: head/crypto/openssh/auth.c 69591 2000-12-05 02:55:12Z green $"); 38 39#include "xmalloc.h" 40#include "rsa.h" 41#include "ssh.h" 42#include "pty.h" 43#include "packet.h" 44#include "buffer.h" 45#include "mpaux.h" 46#include "servconf.h" 47#include "compat.h" 48#include "channels.h" 49#include "match.h" 50 51#include "bufaux.h" 52#include "ssh2.h" 53#include "auth.h" 54#include "session.h" 55 56/* import */ 57extern ServerOptions options; 58 59/* 60 * Check if the user is allowed to log in via ssh. If user is listed in 61 * DenyUsers or user's primary group is listed in DenyGroups, false will 62 * be returned. If AllowUsers isn't empty and user isn't listed there, or 63 * if AllowGroups isn't empty and user isn't listed there, false will be 64 * returned. 65 * If the user's shell is not executable, false will be returned. 66 * Otherwise true is returned. 67 */ 68int 69allowed_user(struct passwd * pw) 70{ 71 struct stat st; 72 struct group *grp; 73 char *shell; 74 int i; 75 76 /* Shouldn't be called if pw is NULL, but better safe than sorry... */ 77 if (!pw) 78 return 0; 79 80 /* 81 * Get the shell from the password data. An empty shell field is 82 * legal, and means /bin/sh. 83 */ 84 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; 85 86 /* deny if shell does not exists or is not executable */ 87 if (stat(shell, &st) != 0) 88 return 0; 89 if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)))) 90 return 0; 91 92 /* Return false if user is listed in DenyUsers */ 93 if (options.num_deny_users > 0) { 94 if (!pw->pw_name) 95 return 0; 96 for (i = 0; i < options.num_deny_users; i++) 97 if (match_pattern(pw->pw_name, options.deny_users[i])) 98 return 0; 99 } 100 /* Return false if AllowUsers isn't empty and user isn't listed there */ 101 if (options.num_allow_users > 0) { 102 if (!pw->pw_name) 103 return 0; 104 for (i = 0; i < options.num_allow_users; i++) 105 if (match_pattern(pw->pw_name, options.allow_users[i])) 106 break; 107 /* i < options.num_allow_users iff we break for loop */ 108 if (i >= options.num_allow_users) 109 return 0; 110 } 111 /* Get the primary group name if we need it. Return false if it fails */ 112 if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { 113 grp = getgrgid(pw->pw_gid); 114 if (!grp) 115 return 0; 116 117 /* Return false if user's group is listed in DenyGroups */ 118 if (options.num_deny_groups > 0) { 119 if (!grp->gr_name) 120 return 0; 121 for (i = 0; i < options.num_deny_groups; i++) 122 if (match_pattern(grp->gr_name, options.deny_groups[i])) 123 return 0; 124 } 125 /* 126 * Return false if AllowGroups isn't empty and user's group 127 * isn't listed there 128 */ 129 if (options.num_allow_groups > 0) { 130 if (!grp->gr_name) 131 return 0; 132 for (i = 0; i < options.num_allow_groups; i++) 133 if (match_pattern(grp->gr_name, options.allow_groups[i])) 134 break; 135 /* i < options.num_allow_groups iff we break for 136 loop */ 137 if (i >= options.num_allow_groups) 138 return 0; 139 } 140 } 141 /* We found no reason not to let this user try to log on... */ 142 return 1; 143} 144