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 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/systm.h> 31 #include <sys/errno.h> 32 #include <sys/zone.h> 33 #include <sys/lx_types.h> 34 #include <sys/lx_syscall.h> 35 #include <sys/cred_impl.h> 36 #include <sys/policy.h> 37 #include <sys/ucred.h> 38 #include <sys/syscall.h> 39 #include <alloca.h> 40 #include <errno.h> 41 #include <ucred.h> 42 #include <unistd.h> 43 #include <errno.h> 44 #include <string.h> 45 #include <sys/lx_misc.h> 46 47 int 48 lx_setuid16(uintptr_t uid) 49 { 50 return ((setuid(LX_UID16_TO_UID32((lx_uid16_t)uid))) ? -errno : 0); 51 } 52 53 int 54 lx_getuid16(void) 55 { 56 return ((int)LX_UID32_TO_UID16(getuid())); 57 } 58 59 int 60 lx_setgid16(uintptr_t gid) 61 { 62 return ((setgid(LX_GID16_TO_GID32((lx_gid16_t)gid))) ? -errno : 0); 63 } 64 65 int 66 lx_getgid16(void) 67 { 68 return ((int)LX_GID32_TO_GID16(getgid())); 69 } 70 71 int 72 lx_geteuid16(void) 73 { 74 return ((int)LX_UID32_TO_UID16(geteuid())); 75 } 76 77 int 78 lx_getegid16(void) 79 { 80 return ((int)LX_GID32_TO_GID16(getegid())); 81 } 82 83 int 84 lx_geteuid(void) 85 { 86 return ((int)geteuid()); 87 } 88 89 int 90 lx_getegid(void) 91 { 92 return ((int)getegid()); 93 } 94 95 int 96 lx_getresuid(uintptr_t ruid, uintptr_t euid, uintptr_t suid) 97 { 98 lx_uid_t lx_ruid, lx_euid, lx_suid; 99 ucred_t *cr; 100 size_t sz; 101 102 /* 103 * We allocate a ucred_t ourselves rather than call ucred_get(3C) 104 * because ucred_get() calls malloc(3C), which the brand library cannot 105 * use. Because we allocate the space with SAFE_ALLOCA(), there's 106 * no need to free it when we're done. 107 */ 108 sz = ucred_size(); 109 cr = (ucred_t *)SAFE_ALLOCA(sz); 110 if (cr == NULL) 111 return (-ENOMEM); 112 113 if (syscall(SYS_ucredsys, UCREDSYS_UCREDGET, P_MYID, cr) != 0) 114 return (-errno); 115 116 if (((lx_ruid = (lx_uid_t)ucred_getruid(cr)) == (lx_uid_t)-1) || 117 ((lx_euid = (lx_uid_t)ucred_geteuid(cr)) == (lx_uid_t)-1) || 118 ((lx_suid = (lx_uid_t)ucred_getsuid(cr)) == (lx_uid_t)-1)) { 119 return (-errno); 120 } 121 122 if (uucopy(&lx_ruid, (void *)ruid, sizeof (lx_uid_t)) != 0) 123 return (-errno); 124 125 if (uucopy(&lx_euid, (void *)euid, sizeof (lx_uid_t)) != 0) 126 return (-errno); 127 128 return ((uucopy(&lx_suid, (void *)suid, sizeof (lx_uid_t)) != 0) 129 ? -errno : 0); 130 } 131 132 int 133 lx_getresuid16(uintptr_t ruid16, uintptr_t euid16, uintptr_t suid16) 134 { 135 lx_uid_t lx_ruid, lx_euid, lx_suid; 136 lx_uid16_t lx_ruid16, lx_euid16, lx_suid16; 137 int rv; 138 139 if ((rv = lx_getresuid((uintptr_t)&lx_ruid, (uintptr_t)&lx_euid, 140 (uintptr_t)&lx_suid)) != 0) 141 return (rv); 142 143 lx_ruid16 = LX_UID32_TO_UID16(lx_ruid); 144 lx_euid16 = LX_UID32_TO_UID16(lx_euid); 145 lx_suid16 = LX_UID32_TO_UID16(lx_suid); 146 147 if (uucopy(&lx_ruid16, (void *)ruid16, sizeof (lx_uid16_t)) != 0) 148 return (-errno); 149 150 if (uucopy(&lx_euid16, (void *)euid16, sizeof (lx_uid16_t)) != 0) 151 return (-errno); 152 153 return ((uucopy(&lx_suid16, (void *)suid16, sizeof (lx_uid16_t)) != 0) 154 ? -errno : 0); 155 } 156 157 int 158 lx_getresgid(uintptr_t rgid, uintptr_t egid, uintptr_t sgid) 159 { 160 ucred_t *cr; 161 lx_gid_t lx_rgid, lx_egid, lx_sgid; 162 size_t sz; 163 164 /* 165 * We allocate a ucred_t ourselves rather than call ucred_get(3C) 166 * because ucred_get() calls malloc(3C), which the brand library cannot 167 * use. Because we allocate the space with SAFE_ALLOCA(), there's 168 * no need to free it when we're done. 169 */ 170 sz = ucred_size(); 171 cr = (ucred_t *)SAFE_ALLOCA(sz); 172 if (cr == NULL) 173 return (-ENOMEM); 174 175 if (syscall(SYS_ucredsys, UCREDSYS_UCREDGET, P_MYID, cr) != 0) 176 return (-errno); 177 178 if (((lx_rgid = (lx_gid_t)ucred_getrgid(cr)) == (lx_gid_t)-1) || 179 ((lx_egid = (lx_gid_t)ucred_getegid(cr)) == (lx_gid_t)-1) || 180 ((lx_sgid = (lx_gid_t)ucred_getsgid(cr)) == (lx_gid_t)-1)) { 181 return (-errno); 182 } 183 184 if (uucopy(&lx_rgid, (void *)rgid, sizeof (lx_gid_t)) != 0) 185 return (-errno); 186 187 if (uucopy(&lx_egid, (void *)egid, sizeof (lx_gid_t)) != 0) 188 return (-errno); 189 190 return ((uucopy(&lx_sgid, (void *)sgid, sizeof (lx_gid_t)) != 0) 191 ? -errno : 0); 192 } 193 194 int 195 lx_getresgid16(uintptr_t rgid16, uintptr_t egid16, uintptr_t sgid16) 196 { 197 lx_gid_t lx_rgid, lx_egid, lx_sgid; 198 lx_gid16_t lx_rgid16, lx_egid16, lx_sgid16; 199 int rv; 200 201 if ((rv = lx_getresgid((uintptr_t)&lx_rgid, (uintptr_t)&lx_egid, 202 (uintptr_t)&lx_sgid)) != 0) 203 return (rv); 204 205 lx_rgid16 = LX_UID32_TO_UID16(lx_rgid); 206 lx_egid16 = LX_UID32_TO_UID16(lx_egid); 207 lx_sgid16 = LX_UID32_TO_UID16(lx_sgid); 208 209 if (uucopy(&lx_rgid16, (void *)rgid16, sizeof (lx_gid16_t)) != 0) 210 return (-errno); 211 212 if (uucopy(&lx_egid16, (void *)egid16, sizeof (lx_gid16_t)) != 0) 213 return (-errno); 214 215 return ((uucopy(&lx_sgid16, (void *)sgid16, sizeof (lx_gid16_t)) != 0) 216 ? -errno : 0); 217 } 218 219 int 220 lx_setreuid16(uintptr_t ruid, uintptr_t euid) 221 { 222 return ((setreuid(LX_UID16_TO_UID32((lx_uid16_t)ruid), 223 LX_UID16_TO_UID32((lx_uid16_t)euid))) ? -errno : 0); 224 } 225 226 int 227 lx_setregid16(uintptr_t rgid, uintptr_t egid) 228 { 229 return ((setregid(LX_UID16_TO_UID32((lx_gid16_t)rgid), 230 LX_UID16_TO_UID32((lx_gid16_t)egid))) ? -errno : 0); 231 } 232 233 /* 234 * The lx brand cannot support the setfs[ug]id16/setfs[ug]id calls as that 235 * would require significant rework of Solaris' privilege mechanisms, so 236 * instead return the current effective [ug]id. 237 * 238 * In Linux, fsids track effective IDs, so returning the effective IDs works 239 * as a substitute; returning the current value also denotes failure of the 240 * call if the caller had specified something different. We don't need to 241 * worry about setting error codes because the Linux calls don't set any. 242 */ 243 /*ARGSUSED*/ 244 int 245 lx_setfsuid16(uintptr_t fsuid16) 246 { 247 return (lx_geteuid16()); 248 } 249 250 /*ARGSUSED*/ 251 int 252 lx_setfsgid16(uintptr_t fsgid16) 253 { 254 return (lx_getegid16()); 255 } 256 257 /*ARGSUSED*/ 258 int 259 lx_setfsuid(uintptr_t fsuid) 260 { 261 return (geteuid()); 262 } 263 264 /*ARGSUSED*/ 265 int 266 lx_setfsgid(uintptr_t fsgid) 267 { 268 return (getegid()); 269 }