1 /* 2 * Copyright (c) 2009, Sun Microsystems, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * - Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * - Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * - Neither the name of Sun Microsystems, Inc. nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 //#include <sys/cdefs.h> 30 31 /* 32 * auth_unix.c, Implements UNIX style authentication parameters. 33 * 34 * Copyright (C) 1984, Sun Microsystems, Inc. 35 * 36 * The system is very weak. The client uses no encryption for it's 37 * credentials and only sends null verifiers. The server sends backs 38 * null verifiers or optionally a verifier that suggests a new short hand 39 * for the credentials. 40 * 41 */ 42 43 /* NFSv4.1 client for Windows 44 * Copyright � 2012 The Regents of the University of Michigan 45 * 46 * Olga Kornievskaia <aglo@umich.edu> 47 * Casey Bodley <cbodley@umich.edu> 48 * 49 * This library is free software; you can redistribute it and/or modify it 50 * under the terms of the GNU Lesser General Public License as published by 51 * the Free Software Foundation; either version 2.1 of the License, or (at 52 * your option) any later version. 53 * 54 * This library is distributed in the hope that it will be useful, but 55 * without any warranty; without even the implied warranty of merchantability 56 * or fitness for a particular purpose. See the GNU Lesser General Public 57 * License for more details. 58 * 59 * You should have received a copy of the GNU Lesser General Public License 60 * along with this library; if not, write to the Free Software Foundation, 61 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 62 */ 63 64 #include <wintirpc.h> 65 //#include <pthread.h> 66 #include <reentrant.h> 67 //#include <sys/param.h> 68 69 #include <assert.h> 70 //#include <err.h> 71 #include <stdio.h> 72 #include <stdlib.h> 73 //#include <unistd.h> 74 #include <string.h> 75 76 #include <rpc/types.h> 77 #include <rpc/xdr.h> 78 #include <rpc/auth.h> 79 #include <rpc/auth_unix.h> 80 81 /* auth_unix.c */ 82 static void authunix_nextverf (AUTH *); 83 static bool_t authunix_marshal (AUTH *, XDR *, u_int *seq); 84 static bool_t authunix_validate (AUTH *, struct opaque_auth *, u_int); 85 static bool_t authunix_refresh (AUTH *, void *); 86 static void authunix_destroy (AUTH *); 87 static void marshal_new_auth (AUTH *); 88 static struct auth_ops *authunix_ops (void); 89 90 /* 91 * This struct is pointed to by the ah_private field of an auth_handle. 92 */ 93 struct audata { 94 struct opaque_auth au_origcred; /* original credentials */ 95 struct opaque_auth au_shcred; /* short hand cred */ 96 u_long au_shfaults; /* short hand cache faults */ 97 char au_marshed[MAX_AUTH_BYTES]; 98 u_int au_mpos; /* xdr pos at end of marshed */ 99 }; 100 #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) 101 102 /* 103 * Create a unix style authenticator. 104 * Returns an auth handle with the given stuff in it. 105 */ 106 AUTH * 107 authunix_create(machname, uid, gid, len, aup_gids) 108 char *machname; 109 uid_t uid; 110 gid_t gid; 111 int len; 112 gid_t *aup_gids; 113 { 114 struct authunix_parms aup; 115 char mymem[MAX_AUTH_BYTES]; 116 struct timeval now; 117 XDR xdrs; 118 AUTH *auth; 119 struct audata *au; 120 121 /* 122 * Allocate and set up auth handle 123 */ 124 au = NULL; 125 auth = mem_alloc(sizeof(*auth)); 126 #ifndef _KERNEL 127 if (auth == NULL) { 128 // XXX warnx("authunix_create: out of memory"); 129 goto cleanup_authunix_create; 130 } 131 #endif 132 au = mem_alloc(sizeof(*au)); 133 #ifndef _KERNEL 134 if (au == NULL) { 135 // XXX warnx("authunix_create: out of memory"); 136 goto cleanup_authunix_create; 137 } 138 #endif 139 auth->ah_ops = authunix_ops(); 140 auth->ah_private = (caddr_t)au; 141 auth->ah_verf = au->au_shcred = _null_auth; 142 au->au_shfaults = 0; 143 au->au_origcred.oa_base = NULL; 144 145 /* 146 * fill in param struct from the given params 147 */ 148 (void)gettimeofday(&now, NULL); 149 aup.aup_time = now.tv_sec; 150 aup.aup_machname = machname; 151 aup.aup_uid = uid; 152 aup.aup_gid = gid; 153 aup.aup_len = (u_int)len; 154 aup.aup_gids = aup_gids; 155 156 /* 157 * Serialize the parameters into origcred 158 */ 159 xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); 160 if (! xdr_authunix_parms(&xdrs, &aup)) 161 abort(); 162 au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); 163 au->au_origcred.oa_flavor = AUTH_UNIX; 164 #ifdef _KERNEL 165 au->au_origcred.oa_base = mem_alloc((u_int) len); 166 #else 167 if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { 168 // XXX warnx("authunix_create: out of memory"); 169 goto cleanup_authunix_create; 170 } 171 #endif 172 memmove(au->au_origcred.oa_base, mymem, (size_t)len); 173 174 /* 175 * set auth handle to reflect new cred. 176 */ 177 auth->ah_cred = au->au_origcred; 178 marshal_new_auth(auth); 179 return (auth); 180 #ifndef _KERNEL 181 cleanup_authunix_create: 182 if (auth) 183 mem_free(auth, sizeof(*auth)); 184 if (au) { 185 if (au->au_origcred.oa_base) 186 mem_free(au->au_origcred.oa_base, (u_int)len); 187 mem_free(au, sizeof(*au)); 188 } 189 return (NULL); 190 #endif 191 } 192 193 /* 194 * Returns an auth handle with parameters determined by doing lots of 195 * syscalls. 196 */ 197 AUTH * 198 authunix_create_default() 199 { 200 int len; 201 char machname[MAXHOSTNAMELEN + 1]; 202 uid_t uid; 203 gid_t gid; 204 gid_t gids[NGRPS]; 205 206 if (gethostname(machname, sizeof machname) == -1) 207 abort(); 208 machname[sizeof(machname) - 1] = 0; 209 #if 0 210 uid = geteuid(); 211 gid = getegid(); 212 if ((len = getgroups(NGRPS, gids)) < 0) 213 abort(); 214 #else 215 // XXX Need to figure out what to do here! 216 uid = 666; 217 gid = 777; 218 gids[0] = 0; 219 len = 0; 220 #endif 221 /* XXX: interface problem; those should all have been unsigned */ 222 return (authunix_create(machname, uid, gid, len, gids)); 223 } 224 225 /* 226 * authunix operations 227 */ 228 229 /* ARGSUSED */ 230 static void 231 authunix_nextverf(auth) 232 AUTH *auth; 233 { 234 /* no action necessary */ 235 } 236 237 static bool_t 238 authunix_marshal(auth, xdrs, seq) 239 AUTH *auth; 240 XDR *xdrs; 241 u_int *seq; 242 { 243 struct audata *au; 244 245 assert(auth != NULL); 246 assert(xdrs != NULL); 247 248 au = AUTH_PRIVATE(auth); 249 return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); 250 } 251 252 static bool_t 253 authunix_validate(auth, verf, seq) 254 AUTH *auth; 255 struct opaque_auth *verf; 256 u_int seq; 257 { 258 struct audata *au; 259 XDR xdrs; 260 261 assert(auth != NULL); 262 assert(verf != NULL); 263 264 if (verf->oa_flavor == AUTH_SHORT) { 265 au = AUTH_PRIVATE(auth); 266 xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, 267 XDR_DECODE); 268 269 if (au->au_shcred.oa_base != NULL) { 270 mem_free(au->au_shcred.oa_base, 271 au->au_shcred.oa_length); 272 au->au_shcred.oa_base = NULL; 273 } 274 if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { 275 auth->ah_cred = au->au_shcred; 276 } else { 277 xdrs.x_op = XDR_FREE; 278 (void)xdr_opaque_auth(&xdrs, &au->au_shcred); 279 au->au_shcred.oa_base = NULL; 280 auth->ah_cred = au->au_origcred; 281 } 282 marshal_new_auth(auth); 283 } 284 return (TRUE); 285 } 286 287 static bool_t 288 authunix_refresh(AUTH *auth, void *dummy) 289 { 290 struct audata *au = AUTH_PRIVATE(auth); 291 struct authunix_parms aup; 292 struct timeval now; 293 XDR xdrs; 294 int stat; 295 296 assert(auth != NULL); 297 298 if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { 299 /* there is no hope. Punt */ 300 return (FALSE); 301 } 302 au->au_shfaults ++; 303 304 /* first deserialize the creds back into a struct authunix_parms */ 305 aup.aup_machname = NULL; 306 aup.aup_gids = NULL; 307 xdrmem_create(&xdrs, au->au_origcred.oa_base, 308 au->au_origcred.oa_length, XDR_DECODE); 309 stat = xdr_authunix_parms(&xdrs, &aup); 310 if (! stat) 311 goto done; 312 313 /* update the time and serialize in place */ 314 (void)gettimeofday(&now, NULL); 315 aup.aup_time = now.tv_sec; 316 xdrs.x_op = XDR_ENCODE; 317 XDR_SETPOS(&xdrs, 0); 318 stat = xdr_authunix_parms(&xdrs, &aup); 319 if (! stat) 320 goto done; 321 auth->ah_cred = au->au_origcred; 322 marshal_new_auth(auth); 323 done: 324 /* free the struct authunix_parms created by deserializing */ 325 xdrs.x_op = XDR_FREE; 326 (void)xdr_authunix_parms(&xdrs, &aup); 327 XDR_DESTROY(&xdrs); 328 return (stat); 329 } 330 331 static void 332 authunix_destroy(auth) 333 AUTH *auth; 334 { 335 struct audata *au; 336 337 assert(auth != NULL); 338 339 au = AUTH_PRIVATE(auth); 340 mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); 341 342 if (au->au_shcred.oa_base != NULL) 343 mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); 344 345 mem_free(auth->ah_private, sizeof(struct audata)); 346 347 if (auth->ah_verf.oa_base != NULL) 348 mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); 349 350 mem_free(auth, sizeof(*auth)); 351 } 352 353 /* 354 * Marshals (pre-serializes) an auth struct. 355 * sets private data, au_marshed and au_mpos 356 */ 357 static void 358 marshal_new_auth(auth) 359 AUTH *auth; 360 { 361 XDR xdr_stream; 362 XDR *xdrs = &xdr_stream; 363 struct audata *au; 364 365 assert(auth != NULL); 366 367 au = AUTH_PRIVATE(auth); 368 xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); 369 if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || 370 (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) 371 assert(0); // XXX 372 // XXX warnx("auth_none.c - Fatal marshalling problem"); 373 else 374 au->au_mpos = XDR_GETPOS(xdrs); 375 XDR_DESTROY(xdrs); 376 } 377 378 static bool_t 379 #ifndef __REACTOS__ 380 authunix_wrap(AUTH *auth, XDR *xdrs, xdrproc_t func, caddr_t args, u_int seq) 381 #else 382 authunix_wrap(AUTH *auth, XDR *xdrs, xdrproc_t func, caddr_t args) 383 #endif 384 { 385 return ((*func)(xdrs, args)); 386 } 387 #ifdef __REACTOS__ 388 static bool_t 389 authunix_unwrap(AUTH *auth, XDR *xdrs, xdrproc_t func, caddr_t args, u_int seq) 390 { 391 return ((*func)(xdrs, args)); 392 } 393 #endif 394 395 static struct auth_ops * 396 authunix_ops() 397 { 398 static struct auth_ops ops; 399 extern mutex_t ops_lock; 400 401 /* VARIABLES PROTECTED BY ops_lock: ops */ 402 403 mutex_lock(&ops_lock); 404 if (ops.ah_nextverf == NULL) { 405 ops.ah_nextverf = authunix_nextverf; 406 ops.ah_marshal = authunix_marshal; 407 ops.ah_validate = authunix_validate; 408 ops.ah_refresh = authunix_refresh; 409 ops.ah_destroy = authunix_destroy; 410 ops.ah_wrap = authunix_wrap; 411 #ifndef __REACTOS__ 412 ops.ah_unwrap = authunix_wrap; 413 #else 414 ops.ah_unwrap = authunix_unwrap; 415 #endif 416 } 417 mutex_unlock(&ops_lock); 418 return (&ops); 419 } 420