1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Authorization checking: 29 * 30 * These functions check 'vntsd' authorization to access guest consoles. 31 * The mechanism used is Solaris authorizations. The local client (telnet) 32 * process requesting the connection to a console is verified to have the 33 * required authorization. 34 * 35 * Authorizations available are to access the console of any/all guests or to 36 * access the consoles of a specific console group. A client connecting to the 37 * console through telnet must have the appropriate authorization from file 38 * /etc/security/auth_attr. 39 * 40 * The all-consoles authorization is added during vntsd installation: 41 * solaris.vntsd.consoles:::Access All LDoms Guest Consoles:: 42 * 43 * Example of a specific console group authorization based on the name of the 44 * console group (added manually by a user with 'vntsd.grant' authorization, 45 * such as 'root'); the group name in this example is "ldg1" : 46 * solaris.vntsd.console-ldg1:::Access Specific LDoms Guest Console:: 47 * 48 * Specific users are authorized with usermod(8). To add an authorization 49 * (to /etc/user_attr) type a command similar to this (when user NOT 50 * logged in): 51 * 52 * To authorize a user 'user1' to access all guest consoles: 53 * # usermod -A solaris.vntsd.consoles user1 54 * 55 */ 56 57 #include <sys/types.h> /* uid_t */ 58 #include <sys/param.h> /* MAXNAMELEN */ 59 #include <pwd.h> /* getpw*() */ 60 #include <auth_attr.h> /* chkauthattr() */ 61 #include <secdb.h> /* chkauthattr() */ 62 #include <ucred.h> /* getpeerucred() */ 63 #include <errno.h> /* errno */ 64 65 #define VNTSD_AUTH_ALLCONS "solaris.vntsd.consoles" /* all-consoles auth */ 66 #define VNTSD_AUTH_GRPCONS "solaris.vntsd.console-" /* cons-group auth */ 67 #define VNTSD_AUTH_PREFIXLEN 32 /* max len of prefix */ 68 69 /* 70 * socket_peer_euid() 71 * 72 * Return the effective UID (EUID) of the socket peer. 73 * If none, return -1. 74 * 75 * Parameters: 76 * sock_fd The socket fd of a locally-connected socket (mapped to a pid) 77 * 78 * Returns: 79 * EUID if OK 80 * -1 on failure or unknown EUID (passed on from ucred_geteuid()). 81 */ 82 static uid_t 83 socket_peer_euid(int sock_fd) 84 { 85 int rc; 86 uid_t peer_euid; 87 ucred_t *ucredp = NULL; 88 89 /* Get info on the peer on the other side of the socket */ 90 rc = getpeerucred(sock_fd, &ucredp); 91 if (rc == -1) { 92 /* If errno is EINVAL, it's probably a non-local socket peer */ 93 return ((uid_t)-1); 94 } 95 96 /* Extract effective UID (EUID) info for the socket peer process */ 97 peer_euid = ucred_geteuid(ucredp); 98 ucred_free(ucredp); 99 100 /* Return EUID */ 101 return (peer_euid); 102 } 103 104 /* 105 * auth_check_username() 106 * 107 * Check vntsd console authorization, given a user account. 108 * 109 * Parameters: 110 * username The name of a user account to check authorization 111 * group_name The name of the console group to check authorization. The max 112 * length of group name is MAXPATHLEN. 113 * 114 * Returns: 115 * 0 if OK (authorized), 1 on authorization failure. 116 */ 117 static int 118 auth_check_username(char *username, char *group_name) 119 { 120 int auth_granted = 0; 121 char authname[VNTSD_AUTH_PREFIXLEN + MAXPATHLEN]; 122 size_t len = VNTSD_AUTH_PREFIXLEN + MAXPATHLEN; 123 124 /* Sanity check: */ 125 if ((username == NULL) || (username[0] == '\0') || 126 (group_name == NULL) || (group_name[0] == '\0')) { 127 return (1); /* error (bad parameter) */ 128 } 129 130 (void) snprintf(authname, len, VNTSD_AUTH_GRPCONS"%s", group_name); 131 132 /* 133 * Do authorization checking. 134 * First, check if the user is authorized access to all consoles. If it 135 * fails, check authorization to the specific console group. 136 */ 137 auth_granted = chkauthattr(VNTSD_AUTH_ALLCONS, username); 138 if (auth_granted) 139 return (0); 140 141 auth_granted = chkauthattr(authname, username); 142 if (auth_granted) 143 return (0); 144 145 return (1); 146 } 147 148 /* 149 * auth_check_euid() 150 * 151 * Check vntsd console authorization, given a EUID. 152 * 153 * Parameters: 154 * euid The effective UID of a user account to check authorization 155 * group_name The name of the console group to check authorization 156 * 157 * Returns: 158 * 0 if OK (authorized), 1 on authorization failure. 159 */ 160 static int 161 auth_check_euid(uid_t euid, char *group_name) 162 { 163 struct passwd *passwdp = NULL; 164 char *username = NULL; 165 166 /* If EUID is -1, then it's unknown, so fail */ 167 if (euid == (uid_t)-1) { 168 return (1); 169 } 170 171 /* Map EUID to user name */ 172 passwdp = getpwuid(euid); 173 if (passwdp == NULL) { /* lookup failed */ 174 return (1); 175 } 176 username = passwdp->pw_name; 177 178 /* Do authorization check: */ 179 return (auth_check_username(username, group_name)); 180 } 181 182 /* 183 * auth_check_fd() 184 * 185 * Check vntsd authorization, given a fd of a socket. The socket fd is mapped 186 * to a pid (and should not be used for remote connections). 187 * 188 * Parameters: 189 * sock_fd The socket fd of a locally-connected socket (mapped to a pid) 190 * group_name The name of the console group to check authorization 191 * 192 * Returns: 193 * B_TRUE if OK (authorized), B_FALSE on authorization failure. 194 */ 195 boolean_t 196 auth_check_fd(int sock_fd, char *group_name) 197 { 198 uid_t peer_euid; 199 int rv; 200 201 peer_euid = socket_peer_euid(sock_fd); 202 if (peer_euid == (uid_t)-1) { /* unknown EUID */ 203 return (B_FALSE); 204 } 205 206 /* Do authorization check: */ 207 rv = auth_check_euid(peer_euid, group_name); 208 if (rv != 0) { 209 return (B_FALSE); 210 } 211 return (B_TRUE); 212 } 213