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 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * nfs log - read buffer file and print structs in user-readable form 30 */ 31 32 #define _REENTRANT 33 34 #include <ctype.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <stddef.h> 38 #include <string.h> 39 #include <strings.h> 40 #include <time.h> 41 #include <fcntl.h> 42 #include <unistd.h> 43 #include <signal.h> 44 #include <sys/types.h> 45 #include <sys/stat.h> 46 #include <sys/param.h> 47 #include <sys/utsname.h> 48 #include <errno.h> 49 #include <time.h> 50 #include <limits.h> 51 #include <libintl.h> 52 #include <pwd.h> 53 #include <netdb.h> 54 #include <syslog.h> 55 #include <rpc/rpc.h> 56 #include <netconfig.h> 57 #include <netdir.h> 58 #include <nfs/nfs_sec.h> 59 #include <nfs/export.h> 60 #include <rpc/auth.h> 61 #include <rpc/svc.h> 62 #include <rpc/xdr.h> 63 #include <rpc/clnt.h> 64 #include <nfs/nfs.h> 65 #include <nfs/nfs_log.h> 66 #include "fhtab.h" 67 #include "nfslogd.h" 68 69 static char empty_name[4] = "-"; 70 71 static char ftype3_names[NF3FIFO + 1][20] = { 72 "\"none\"", "\"file\"", "\"dir\"", "\"blk device\"", 73 "\"chr device\"", "\"link\"", "\"socket\"", "\"fifo\"" 74 }; 75 76 #define NFSL_FTYPE3(ftype) \ 77 ((((ftype) >= 0) && ((ftype) <= NF3FIFO)) ? \ 78 ftype3_names[ftype] : empty_name) 79 80 static char createmode3_names[EXCLUSIVE + 1][20] = { 81 "\"unchecked", "\"guarded\"", "\"exclusive\"" 82 }; 83 84 #define NFSL_CREATEMODE3(createmode) \ 85 ((((createmode) >= 0) && ((createmode) <= EXCLUSIVE)) ? \ 86 createmode3_names[createmode] : empty_name) 87 88 static char auth_flavor_name[RPCSEC_GSS + 1][20] = { 89 "\"auth_null\"", "\"auth_unix\"", "\"auth_short\"", "\"auth_des\"", 90 "\"auth_kerb\"", "\"none\"", "\"rpcsec_gss\"" 91 }; 92 93 #define NFSL_AUTH_FLAVOR_PRINT(auth_flavor) \ 94 (((auth_flavor) <= RPCSEC_GSS) ? \ 95 auth_flavor_name[auth_flavor] : empty_name) 96 97 #define NFSL_ERR_CNT 31 /* Actual err numbers */ 98 99 /* 100 * Two arrays - one short ints containing err codes, the other the strings 101 * (merged codes for both v2 and v3 102 */ 103 static char nfsl_status_name[NFSL_ERR_CNT][30] = { 104 "\"ok\"", "\"perm\"", "\"noent\"", "\"io\"", 105 "\"nxio\"", "\"access\"", "\"exist\"", "\"xdev\"", 106 "\"nodev\"", "\"notdir\"", "\"isdir\"", "\"inval\"", 107 "\"fbig\"", "\"nospc\"", "\"rofs\"", "\"mlink\"", 108 "\"notsupp\"", "\"nametoolong\"", "\"notempty\"", "\"dquot\"", 109 "\"stale\"", "\"remote\"", "\"wflush\"", "\"badhandle\"", 110 "\"not_sync\"", "\"bad_cookie\"", "\"notsupp\"", "\"toosmall\"", 111 "\"serverfault\"", "\"badtype\"", "\"jukebox\"", 112 }; 113 114 static short nfsl_status[NFSL_ERR_CNT] = { 115 0, 1, 2, 5, 6, 13, 17, 18, 116 19, 20, 21, 22, 27, 28, 30, 31, 117 45, 63, 66, 69, 70, 71, 99, 10001, 118 10002, 10003, 10004, 10005, 10006, 10007, 10008 119 }; 120 121 /* list of open elf files */ 122 static struct nfsl_log_file *elf_file_list = NULL; 123 124 /* Imported functions */ 125 extern void bcopy(const void *s1, void *s2, size_t n); 126 127 /* Static functions */ 128 static void nfsl_log_file_free(struct nfsl_log_file *elfrec); 129 static void nfsl_log_file_add(struct nfsl_log_file *elfrec, 130 struct nfsl_log_file **elf_listp); 131 static struct nfsl_log_file *nfsl_log_file_find(struct nfsl_log_file *elfrec, 132 struct nfsl_log_file *elf_list); 133 static struct nfsl_log_file *nfsl_log_file_del(struct nfsl_log_file *elfrec, 134 struct nfsl_log_file **elf_listp); 135 136 static char *nfsl_get_time(time_t tt); 137 static char *nfsl_get_date(time_t tt); 138 static char *nfsl_get_date_nq(time_t tt); 139 static int nfsl_write_elfbuf(struct nfsl_log_file *elfrec); 140 static void nfsl_ipaddr_print(struct nfsl_log_file *, struct netbuf *); 141 static void nfsl_elf_record_header_print(struct nfsl_log_file *, 142 nfslog_record_header *, char *, char *, 143 struct nfsl_proc_disp *, char *); 144 static void nfsl_elf_buffer_header_print(struct nfsl_log_file *, 145 nfslog_buffer_header *); 146 static struct nfsl_proc_disp *nfsl_find_elf_dispatch( 147 nfslog_request_record *, char **); 148 static void nfsl_elf_rpc_print(struct nfsl_log_file *, 149 nfslog_request_record *, struct nfsl_proc_disp *, 150 char *, char *, char *); 151 static void nfslog_size3_print(struct nfsl_log_file *, set_size3 *); 152 153 static void nfslog_null_args(struct nfsl_log_file *, caddr_t *); 154 static void nfslog_null_res(struct nfsl_log_file *, caddr_t *); 155 156 157 /* 158 * NFS VERSION 2 159 */ 160 161 /* Functions for elf print of the arguments */ 162 static void nfslog_fhandle_print(struct nfsl_log_file *, fhandle_t *); 163 static void nfslog_diropargs_print(struct nfsl_log_file *, nfslog_diropargs *); 164 static void nfslog_setattrargs_print(struct nfsl_log_file *, 165 nfslog_setattrargs *); 166 static void nfslog_sattr_print(struct nfsl_log_file *, 167 nfslog_sattr *); 168 static void nfslog_nfsreadargs_print(struct nfsl_log_file *, 169 nfslog_nfsreadargs *); 170 static void nfslog_writeargs_print(struct nfsl_log_file *, 171 nfslog_writeargs *); 172 static void nfslog_writeresult_print(struct nfsl_log_file *, 173 nfslog_writeresult *, bool_t); 174 static void nfslog_creatargs_print(struct nfsl_log_file *, 175 nfslog_createargs *); 176 static void nfslog_rddirargs_print(struct nfsl_log_file *, nfslog_rddirargs *); 177 static void nfslog_linkargs_print(struct nfsl_log_file *, nfslog_linkargs *); 178 static void nfslog_rnmargs_print(struct nfsl_log_file *, nfslog_rnmargs *); 179 static void nfslog_symlinkargs_print(struct nfsl_log_file *, 180 nfslog_symlinkargs *); 181 182 static void nfslog_sharefsargs_print(struct nfsl_log_file *, 183 nfslog_sharefsargs *); 184 static void nfslog_getfhargs_print(struct nfsl_log_file *, 185 nfslog_getfhargs *); 186 187 /* Functions for elf print of the response */ 188 static void nfslog_nfsstat_print(struct nfsl_log_file *, enum nfsstat *, 189 bool_t); 190 static void nfslog_diropres_print(struct nfsl_log_file *, nfslog_diropres *, 191 bool_t); 192 static void nfslog_rdlnres_print(struct nfsl_log_file *, nfslog_rdlnres *, 193 bool_t); 194 static void nfslog_rdresult_print(struct nfsl_log_file *, 195 nfslog_rdresult *, bool_t); 196 static void nfslog_rddirres_print(struct nfsl_log_file *, nfslog_rddirres *, 197 bool_t); 198 199 /* 200 * NFS VERSION 3 201 */ 202 203 /* Functions for elf print of the arguments */ 204 static void nfslog_fh3_print(struct nfsl_log_file *, nfs_fh3 *); 205 static void nfslog_diropargs3_print(struct nfsl_log_file *, 206 nfslog_diropargs3 *); 207 static void nfslog_SETATTR3args_print(struct nfsl_log_file *, 208 nfslog_SETATTR3args *); 209 static void nfslog_READ3args_print(struct nfsl_log_file *, nfslog_READ3args *); 210 static void nfslog_WRITE3args_print(struct nfsl_log_file *, 211 nfslog_WRITE3args *); 212 static void nfslog_CREATE3args_print(struct nfsl_log_file *, 213 nfslog_CREATE3args *); 214 static void nfslog_MKDIR3args_print(struct nfsl_log_file *, 215 nfslog_MKDIR3args *); 216 static void nfslog_SYMLINK3args_print(struct nfsl_log_file *, 217 nfslog_SYMLINK3args *); 218 static void nfslog_MKNOD3args_print(struct nfsl_log_file *, 219 nfslog_MKNOD3args *); 220 static void nfslog_REMOVE3args_print(struct nfsl_log_file *, 221 nfslog_REMOVE3args *); 222 static void nfslog_RMDIR3args_print(struct nfsl_log_file *, 223 nfslog_RMDIR3args *); 224 static void nfslog_RENAME3args_print(struct nfsl_log_file *, 225 nfslog_RENAME3args *); 226 static void nfslog_LINK3args_print(struct nfsl_log_file *, 227 nfslog_LINK3args *); 228 static void nfslog_COMMIT3args_print(struct nfsl_log_file *, 229 nfslog_COMMIT3args *); 230 static void nfslog_READDIRPLUS3args_print(struct nfsl_log_file *, 231 nfslog_READDIRPLUS3args *); 232 233 /* Functions for elf print of the response */ 234 static void nfslog_nfsstat3_print(struct nfsl_log_file *, 235 nfsstat3 *, bool_t); 236 static void nfslog_LOOKUP3res_print(struct nfsl_log_file *, 237 nfslog_LOOKUP3res *, bool_t); 238 static void nfslog_READLINK3res_print(struct nfsl_log_file *, 239 nfslog_READLINK3res *, bool_t); 240 static void nfslog_READ3res_print(struct nfsl_log_file *, 241 nfslog_READ3res *, bool_t); 242 static void nfslog_WRITE3res_print(struct nfsl_log_file *, 243 nfslog_WRITE3res *, bool_t); 244 static void nfslog_CREATE3res_print(struct nfsl_log_file *, 245 nfslog_CREATE3res *, bool_t); 246 static void nfslog_MKDIR3res_print(struct nfsl_log_file *, 247 nfslog_MKDIR3res *, bool_t); 248 static void nfslog_SYMLINK3res_print(struct nfsl_log_file *, 249 nfslog_SYMLINK3res *, bool_t); 250 static void nfslog_MKNOD3res_print(struct nfsl_log_file *, 251 nfslog_MKNOD3res *, bool_t); 252 static void nfslog_READDIRPLUS3res_print(struct nfsl_log_file *, 253 nfslog_READDIRPLUS3res *, bool_t); 254 255 extern int debug; 256 static bool_t nfsl_print_fh = FALSE; /* print file handles? */ 257 258 #define DFLT_BUFFERSIZE 8192 259 #define DFLT_OVFSIZE 3072 /* Maximum logged or buffered size */ 260 261 static char hostname[MAXHOSTNAMELEN]; /* name of host */ 262 263 264 /* 265 * Define the actions taken per prog/vers/proc: 266 * 267 * In some cases, the nl types are the same as the nfs types and a simple 268 * bcopy should suffice. Rather that define tens of identical procedures, 269 * simply define these to bcopy. Similarly this takes care of different 270 * procs that use same parameter struct. 271 */ 272 273 static struct nfsl_proc_disp nfsl_elf_proc_v2[] = { 274 /* 275 * NFS VERSION 2 276 */ 277 278 /* RFS_NULL = 0 */ 279 {nfslog_null_args, nfslog_null_res, "\"null\""}, 280 281 /* RFS_GETATTR = 1 */ 282 {nfslog_fhandle_print, nfslog_nfsstat_print, "\"getattr\""}, 283 284 /* RFS_SETATTR = 2 */ 285 {nfslog_setattrargs_print, nfslog_nfsstat_print, "\"setattr\""}, 286 287 /* RFS_ROOT = 3 *** NO LONGER SUPPORTED *** */ 288 {nfslog_null_args, nfslog_null_res, "\"root\""}, 289 290 /* RFS_LOOKUP = 4 */ 291 {nfslog_diropargs_print, nfslog_diropres_print, "\"lookup\""}, 292 293 /* RFS_READLINK = 5 */ 294 {nfslog_fhandle_print, nfslog_rdlnres_print, "\"readlink\""}, 295 296 /* RFS_READ = 6 */ 297 {nfslog_nfsreadargs_print, nfslog_rdresult_print, "\"read\""}, 298 299 /* RFS_WRITECACHE = 7 *** NO LONGER SUPPORTED *** */ 300 {nfslog_null_args, nfslog_null_res, "\"writecache\""}, 301 302 /* RFS_WRITE = 8 */ 303 {nfslog_writeargs_print, nfslog_writeresult_print, "\"write\""}, 304 305 /* RFS_CREATE = 9 */ 306 {nfslog_creatargs_print, nfslog_diropres_print, "\"create\""}, 307 308 /* RFS_REMOVE = 10 */ 309 {nfslog_diropargs_print, nfslog_nfsstat_print, "\"remove\""}, 310 311 /* RFS_RENAME = 11 */ 312 {nfslog_rnmargs_print, nfslog_nfsstat_print, "\"rename\""}, 313 314 /* RFS_LINK = 12 */ 315 {nfslog_linkargs_print, nfslog_nfsstat_print, "\"link\""}, 316 317 /* RFS_SYMLINK = 13 */ 318 {nfslog_symlinkargs_print, nfslog_nfsstat_print, "\"symlink\""}, 319 320 /* RFS_MKDIR = 14 */ 321 {nfslog_creatargs_print, nfslog_diropres_print, "\"mkdir\""}, 322 323 /* RFS_RMDIR = 15 */ 324 {nfslog_diropargs_print, nfslog_nfsstat_print, "\"rmdir\""}, 325 326 /* RFS_READDIR = 16 */ 327 {nfslog_rddirargs_print, nfslog_rddirres_print, "\"readdir\""}, 328 329 /* RFS_STATFS = 17 */ 330 {nfslog_fhandle_print, nfslog_nfsstat_print, "\"statfs\""}, 331 }; 332 333 334 /* 335 * NFS VERSION 3 336 */ 337 338 static struct nfsl_proc_disp nfsl_elf_proc_v3[] = { 339 340 /* NFSPROC3_NULL = 0 */ 341 {nfslog_null_args, nfslog_null_res, "\"null\""}, 342 343 /* NFSPROC3_GETATTR = 1 */ 344 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"getattr\""}, 345 346 /* NFSPROC3_SETATTR = 2 */ 347 {nfslog_SETATTR3args_print, nfslog_nfsstat3_print, "\"setattr\""}, 348 349 /* NFSPROC3_LOOKUP = 3 */ 350 {nfslog_diropargs3_print, nfslog_LOOKUP3res_print, "\"lookup\""}, 351 352 /* NFSPROC3_ACCESS = 4 */ 353 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"access\""}, 354 355 /* NFSPROC3_READLINK = 5 */ 356 {nfslog_fh3_print, nfslog_READLINK3res_print, "\"readlink\""}, 357 358 /* NFSPROC3_READ = 6 */ 359 {nfslog_READ3args_print, nfslog_READ3res_print, "\"read\""}, 360 361 /* NFSPROC3_WRITE = 7 */ 362 {nfslog_WRITE3args_print, nfslog_WRITE3res_print, "\"write\""}, 363 364 /* NFSPROC3_CREATE = 8 */ 365 {nfslog_CREATE3args_print, nfslog_CREATE3res_print, "\"create\""}, 366 367 /* NFSPROC3_MKDIR = 9 */ 368 {nfslog_MKDIR3args_print, nfslog_MKDIR3res_print, "\"mkdir\""}, 369 370 /* NFSPROC3_SYMLINK = 10 */ 371 {nfslog_SYMLINK3args_print, nfslog_SYMLINK3res_print, "\"symlink\""}, 372 373 /* NFSPROC3_MKNOD = 11 */ 374 {nfslog_MKNOD3args_print, nfslog_MKNOD3res_print, "\"mknod\""}, 375 376 /* NFSPROC3_REMOVE = 12 */ 377 {nfslog_REMOVE3args_print, nfslog_nfsstat3_print, "\"remove\""}, 378 379 /* NFSPROC3_RMDIR = 13 */ 380 {nfslog_RMDIR3args_print, nfslog_nfsstat3_print, "\"rmdir\""}, 381 382 /* NFSPROC3_RENAME = 14 */ 383 {nfslog_RENAME3args_print, nfslog_nfsstat3_print, "\"rename\""}, 384 385 /* NFSPROC3_LINK = 15 */ 386 {nfslog_LINK3args_print, nfslog_nfsstat3_print, "\"link\""}, 387 388 /* NFSPROC3_READDIR = 16 */ 389 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"readdir\""}, 390 391 /* NFSPROC3_READDIRPLUS = 17 */ 392 {nfslog_READDIRPLUS3args_print, nfslog_READDIRPLUS3res_print, 393 "\"readdirplus\""}, 394 395 /* NFSPROC3_FSSTAT = 18 */ 396 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"fsstat\""}, 397 398 /* NFSPROC3_FSINFO = 19 */ 399 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"fsinfo\""}, 400 401 /* NFSPROC3_PATHCONF = 20 */ 402 {nfslog_fh3_print, nfslog_nfsstat3_print, "\"pathconf\""}, 403 404 /* NFSPROC3_COMMIT = 21 */ 405 {nfslog_COMMIT3args_print, nfslog_nfsstat3_print, "\"commit\""}, 406 }; 407 408 /* 409 * NFSLOG VERSION 1 410 */ 411 412 static struct nfsl_proc_disp nfsl_log_elf_proc_v1[] = { 413 414 /* NFSLOG_NULL = 0 */ 415 {nfslog_null_args, nfslog_null_res, "\"null\""}, 416 417 /* NFSLOG_SHARE = 1 */ 418 {nfslog_sharefsargs_print, nfslog_nfsstat_print, "\"log_share\""}, 419 420 /* NFSLOG_UNSHARE = 2 */ 421 {nfslog_sharefsargs_print, nfslog_nfsstat_print, "\"log_unshare\""}, 422 423 /* NFSLOG_LOOKUP = 3 */ 424 {nfslog_diropargs3_print, nfslog_LOOKUP3res_print, "\"lookup\""}, 425 426 /* NFSLOG_GETFH = 4 */ 427 {nfslog_getfhargs_print, nfslog_nfsstat_print, "\"log_getfh\""}, 428 }; 429 430 static struct nfsl_vers_disp nfsl_elf_vers_disptable[] = { 431 {sizeof (nfsl_elf_proc_v2) / sizeof (nfsl_elf_proc_v2[0]), 432 nfsl_elf_proc_v2}, 433 {sizeof (nfsl_elf_proc_v3) / sizeof (nfsl_elf_proc_v3[0]), 434 nfsl_elf_proc_v3}, 435 }; 436 437 static struct nfsl_vers_disp nfsl_log_elf_vers_disptable[] = { 438 {sizeof (nfsl_log_elf_proc_v1) / sizeof (nfsl_log_elf_proc_v1[0]), 439 nfsl_log_elf_proc_v1}, 440 }; 441 442 static struct nfsl_prog_disp nfsl_elf_dispatch_table[] = { 443 {NFS_PROGRAM, 444 NFS_VERSMIN, 445 sizeof (nfsl_elf_vers_disptable) / 446 sizeof (nfsl_elf_vers_disptable[0]), 447 nfsl_elf_vers_disptable, "nfs"}, 448 {NFSLOG_PROGRAM, 449 NFSLOG_VERSMIN, 450 sizeof (nfsl_log_elf_vers_disptable) / 451 sizeof (nfsl_log_elf_vers_disptable[0]), 452 nfsl_log_elf_vers_disptable, "nfslog"}, 453 }; 454 455 static int nfsl_elf_dispatch_table_arglen = 456 sizeof (nfsl_elf_dispatch_table) / 457 sizeof (nfsl_elf_dispatch_table[0]); 458 459 static char * 460 nfslog_get_status(short status) 461 { 462 int low, mid, high; 463 short errstat; 464 465 /* Usually status is 0... */ 466 if (status == 0) 467 return (nfsl_status_name[0]); 468 469 low = 0; 470 high = NFSL_ERR_CNT; 471 mid = NFSL_ERR_CNT / 2; 472 /* binary search for status string */ 473 while (((errstat = nfsl_status[mid]) != status) && (low < mid) && 474 (mid < high)) { 475 if (errstat > status) { /* search bottom half */ 476 high = mid; 477 } else { /* search upper half */ 478 low = mid; 479 } 480 mid = low + ((high - low) / 2); 481 } 482 if (errstat == status) { /* found it */ 483 return (nfsl_status_name[mid]); 484 } 485 return (NULL); 486 } 487 488 /* nfsl_get_time - return string with time formatted as hh:mm:ss */ 489 static char * 490 nfsl_get_time(time_t tt) 491 { 492 static char timestr[20]; 493 static time_t lasttime; 494 struct tm tmst; 495 496 if (tt == lasttime) 497 return (timestr); 498 if (localtime_r(&tt, &tmst) == NULL) { 499 return (empty_name); 500 } 501 (void) sprintf(timestr, "%02d:%02d:%02d", 502 tmst.tm_hour, tmst.tm_min, tmst.tm_sec); 503 lasttime = tt; 504 return (timestr); 505 } 506 507 /* nfsl_get_date - return date string formatted as "yyyy-mm-dd hh:mm:ss" */ 508 static char * 509 nfsl_get_date(time_t tt) 510 { 511 static char timestr[30]; 512 static time_t lasttime; 513 struct tm tmst; 514 515 if (tt == lasttime) 516 return (timestr); 517 if (localtime_r(&tt, &tmst) == NULL) { 518 return (empty_name); 519 } 520 (void) sprintf(timestr, "\"%04d-%02d-%02d %02d:%02d:%02d\"", 521 tmst.tm_year + 1900, tmst.tm_mon + 1, tmst.tm_mday, 522 tmst.tm_hour, tmst.tm_min, tmst.tm_sec); 523 lasttime = tt; 524 return (timestr); 525 } 526 527 /* 528 * nfsl_get_date_nq - return date string formatted as yyyy-mm-dd hh:mm:ss 529 * (no quotes) 530 */ 531 static char * 532 nfsl_get_date_nq(time_t tt) 533 { 534 static char timestr[30]; 535 static time_t lasttime; 536 struct tm tmst; 537 538 if (tt == lasttime) 539 return (timestr); 540 if (localtime_r(&tt, &tmst) == NULL) { 541 return (empty_name); 542 } 543 (void) sprintf(timestr, "%04d-%02d-%02d %02d:%02d:%02d", 544 tmst.tm_year + 1900, tmst.tm_mon + 1, tmst.tm_mday, 545 tmst.tm_hour, tmst.tm_min, tmst.tm_sec); 546 return (timestr); 547 } 548 549 /* write log buffer out to file */ 550 static int 551 nfsl_write_elfbuf(struct nfsl_log_file *elfrec) 552 { 553 int rc; 554 char *elfbuf = elfrec->buf; 555 int elfbufoffset = elfrec->bufoffset; 556 557 if (debug > 1) 558 (void) printf("nfsl_write_elfbuf: bufoffset %d\n", 559 elfbufoffset); 560 if (elfbufoffset <= 0) 561 return (0); 562 elfbuf[elfbufoffset] = '\0'; 563 if ((rc = fputs(elfbuf, elfrec->fp)) < 0) { 564 syslog(LOG_ERR, gettext("Write to %s failed: %s\n"), 565 elfrec->path, strerror(errno)); 566 return (-1); 567 } 568 if (rc != elfbufoffset) { 569 syslog(LOG_ERR, gettext("Write %d bytes to %s returned %d\n"), 570 elfbufoffset, elfrec->path, rc); 571 return (-1); 572 } 573 elfrec->bufoffset = 0; 574 return (0); 575 } 576 577 /*ARGSUSED*/ 578 static void 579 nfslog_null_args(struct nfsl_log_file *elfrec, caddr_t *nfsl_args) 580 { 581 } 582 583 /*ARGSUSED*/ 584 static void 585 nfslog_null_res(struct nfsl_log_file *elfrec, caddr_t *nfsl_res) 586 { 587 } 588 589 static void 590 nfslog_fh3_print(struct nfsl_log_file *elfrec, nfs_fh3 *fh3) 591 { 592 if (!nfsl_print_fh) 593 return; 594 if (fh3->fh3_length == sizeof (fhandle_t)) { 595 nfslog_fhandle_print(elfrec, (fhandle_t *)&fh3->fh3_u.data); 596 } else { 597 nfslog_opaque_print_buf(fh3->fh3_u.data, fh3->fh3_length, 598 elfrec->buf, &elfrec->bufoffset, 599 DFLT_BUFFERSIZE + DFLT_OVFSIZE); 600 } 601 } 602 603 /* 604 * NFS VERSION 2 605 */ 606 607 608 /* Functions that elf print the arguments */ 609 610 static void 611 nfslog_fhandle_print(struct nfsl_log_file *elfrec, fhandle_t *args) 612 { 613 if (!nfsl_print_fh) 614 return; 615 nfslog_opaque_print_buf(args, sizeof (*args), 616 elfrec->buf, &elfrec->bufoffset, 617 DFLT_BUFFERSIZE + DFLT_OVFSIZE); 618 } 619 620 static void 621 nfslog_diropargs_print(struct nfsl_log_file *elfrec, nfslog_diropargs *args) 622 { 623 char *elfbuf = elfrec->buf; 624 int elfbufoffset = elfrec->bufoffset; 625 626 if (nfsl_print_fh) { 627 nfslog_fhandle_print(elfrec, &args->da_fhandle); 628 elfbufoffset = elfrec->bufoffset; 629 if (args->da_name != NULL) { 630 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 631 " \"%s\"", args->da_name); 632 } else { 633 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 634 empty_name); 635 } 636 } 637 elfrec->bufoffset = elfbufoffset; 638 } 639 640 static void 641 nfslog_sattr_print(struct nfsl_log_file *elfrec, nfslog_sattr *args) 642 { 643 char *elfbuf = elfrec->buf; 644 int elfbufoffset = elfrec->bufoffset; 645 646 /* BEGIN CSTYLED */ 647 if (args->sa_mode != (uint32_t)-1) { 648 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 649 " \"mode=0%o\"", args->sa_mode); 650 } 651 if (args->sa_uid != (uint32_t)-1) { 652 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 653 " \"uid=0x%x\"", args->sa_uid); 654 } 655 if (args->sa_gid != (uint32_t)-1) { 656 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 657 " \"gid=0x%x\"", args->sa_gid); 658 } 659 if (args->sa_size != (uint32_t)-1) { 660 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 661 " \"size=0x%x\"", args->sa_size); 662 } 663 if (args->sa_atime.tv_sec != (uint32_t)-1) { 664 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 665 " \"atime=%s\"", 666 nfsl_get_date_nq((time_t)args->sa_atime.tv_sec)); 667 } 668 if (args->sa_mtime.tv_sec != (uint32_t)-1) { 669 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 670 " \"mtime=%s\"", 671 nfsl_get_date_nq((time_t)args->sa_mtime.tv_sec)); 672 } 673 /* END CSTYLED */ 674 elfrec->bufoffset = elfbufoffset; 675 } 676 677 static void 678 nfslog_setattrargs_print(struct nfsl_log_file *elfrec, nfslog_setattrargs *args) 679 { 680 nfslog_fhandle_print(elfrec, &args->saa_fh); 681 nfslog_sattr_print(elfrec, &args->saa_sa); 682 } 683 684 static void 685 nfslog_nfsreadargs_print(struct nfsl_log_file *elfrec, 686 nfslog_nfsreadargs *args) 687 { 688 char *elfbuf = elfrec->buf; 689 int elfbufoffset; 690 691 nfslog_fhandle_print(elfrec, &args->ra_fhandle); 692 elfbufoffset = elfrec->bufoffset; 693 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 694 args->ra_offset); 695 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 696 args->ra_count); 697 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 698 args->ra_totcount); 699 elfrec->bufoffset = elfbufoffset; 700 } 701 702 static void 703 nfslog_writeargs_print(struct nfsl_log_file *elfrec, nfslog_writeargs *args) 704 { 705 char *elfbuf = elfrec->buf; 706 int elfbufoffset = elfrec->bufoffset; 707 708 nfslog_fhandle_print(elfrec, &args->waargs_fhandle); 709 elfbufoffset = elfrec->bufoffset; 710 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 711 args->waargs_begoff); 712 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 713 args->waargs_offset); 714 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 715 args->waargs_totcount); 716 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%x", 717 args->waargs_count); 718 } 719 720 static void 721 nfslog_writeresult_print(struct nfsl_log_file *elfrec, nfslog_writeresult *res, 722 bool_t print_status) 723 { 724 char *elfbuf = elfrec->buf; 725 int elfbufoffset = elfrec->bufoffset; 726 727 if (print_status) { 728 nfslog_nfsstat_print(elfrec, &res->wr_status, print_status); 729 } else if (res->wr_status == NFS_OK) { 730 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 731 res->nfslog_writeresult_u.wr_size); 732 elfrec->bufoffset = elfbufoffset; 733 } 734 } 735 736 static void 737 nfslog_creatargs_print(struct nfsl_log_file *elfrec, nfslog_createargs *args) 738 { 739 nfslog_diropargs_print(elfrec, &args->ca_da); 740 nfslog_sattr_print(elfrec, &args->ca_sa); 741 } 742 743 744 static void 745 nfslog_rddirargs_print(struct nfsl_log_file *elfrec, nfslog_rddirargs *args) 746 { 747 char *elfbuf = elfrec->buf; 748 int elfbufoffset; 749 750 nfslog_fhandle_print(elfrec, &args->rda_fh); 751 elfbufoffset = elfrec->bufoffset; 752 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 753 args->rda_offset); 754 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 755 args->rda_count); 756 elfrec->bufoffset = elfbufoffset; 757 } 758 759 static void 760 nfslog_rnmargs_print(struct nfsl_log_file *elfrec, nfslog_rnmargs *args) 761 { 762 nfslog_diropargs_print(elfrec, &args->rna_from); 763 nfslog_diropargs_print(elfrec, &args->rna_to); 764 } 765 766 static void 767 nfslog_linkargs_print(struct nfsl_log_file *elfrec, nfslog_linkargs *args) 768 { 769 nfslog_fhandle_print(elfrec, &args->la_from); 770 nfslog_diropargs_print(elfrec, &args->la_to); 771 } 772 773 static void 774 nfslog_symlinkargs_print(struct nfsl_log_file *elfrec, nfslog_symlinkargs *args) 775 { 776 char *elfbuf = elfrec->buf; 777 int elfbufoffset; 778 779 nfslog_diropargs_print(elfrec, &args->sla_from); 780 elfbufoffset = elfrec->bufoffset; 781 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " \"%s\"", 782 args->sla_tnm); 783 elfrec->bufoffset = elfbufoffset; 784 nfslog_sattr_print(elfrec, &args->sla_sa); 785 } 786 787 /* 788 * SHARE/UNSHARE fs log args copy 789 */ 790 static void 791 nfslog_sharefsargs_print(struct nfsl_log_file *elfrec, 792 nfslog_sharefsargs *args) 793 { 794 unsigned int elfbufoffset; 795 char *elfbuf = elfrec->buf; 796 797 nfslog_fhandle_print(elfrec, &args->sh_fh_buf); 798 799 elfbufoffset = elfrec->bufoffset; 800 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 801 args->sh_flags); 802 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 803 args->sh_anon); 804 if (nfsl_print_fh) { 805 if (args->sh_path != NULL) { 806 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 807 " \"%s\"", args->sh_path); 808 } else { 809 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 810 empty_name); 811 } 812 } 813 elfrec->bufoffset = elfbufoffset; 814 } 815 816 static void 817 nfslog_getfhargs_print(struct nfsl_log_file *elfrec, 818 nfslog_getfhargs *args) 819 { 820 unsigned int elfbufoffset; 821 char *elfbuf = elfrec->buf; 822 823 nfslog_fhandle_print(elfrec, &args->gfh_fh_buf); 824 825 elfbufoffset = elfrec->bufoffset; 826 if (nfsl_print_fh) { 827 if (args->gfh_path != NULL) { 828 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 829 " \"%s\"", args->gfh_path); 830 } else { 831 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 832 empty_name); 833 } 834 } 835 elfrec->bufoffset = elfbufoffset; 836 } 837 838 static void 839 nfslog_nfsstat_print(struct nfsl_log_file *elfrec, enum nfsstat *res, 840 bool_t print_status) 841 { 842 if (print_status) { 843 char *statp = nfslog_get_status((short)(*res)); 844 845 if (statp != NULL) 846 elfrec->bufoffset += 847 sprintf(&elfrec->buf[elfrec->bufoffset], " %s", 848 statp); 849 else 850 elfrec->bufoffset += 851 sprintf(&elfrec->buf[elfrec->bufoffset], " %5d", 852 *res); 853 } 854 } 855 856 static void 857 nfslog_diropres_print(struct nfsl_log_file *elfrec, nfslog_diropres *res, 858 bool_t print_status) 859 { 860 if (print_status) { 861 nfslog_nfsstat_print(elfrec, &res->dr_status, print_status); 862 } else if (res->dr_status == NFS_OK) { 863 nfslog_fhandle_print(elfrec, 864 &res->nfslog_diropres_u.dr_ok.drok_fhandle); 865 } 866 } 867 868 static void 869 nfslog_rdlnres_print(struct nfsl_log_file *elfrec, nfslog_rdlnres *res, 870 bool_t print_status) 871 { 872 if (print_status) { 873 nfslog_nfsstat_print(elfrec, &res->rl_status, print_status); 874 } else if (res->rl_status == NFS_OK) { 875 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 876 " \"%s\"", res->nfslog_rdlnres_u.rl_ok); 877 } 878 } 879 880 static void 881 nfslog_rdresult_print(struct nfsl_log_file *elfrec, nfslog_rdresult *res, 882 bool_t print_status) 883 { 884 if (print_status) { 885 nfslog_nfsstat_print(elfrec, &res->r_status, print_status); 886 } else if (res->r_status == NFS_OK) { 887 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 888 " 0x%x", res->nfslog_rdresult_u.r_ok.filesize); 889 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 890 " 0x%x", res->nfslog_rdresult_u.r_ok.rrok_count); 891 } 892 } 893 894 static void 895 nfslog_rddirres_print(struct nfsl_log_file *elfrec, nfslog_rddirres *res, 896 bool_t print_status) 897 { 898 if (print_status) { 899 nfslog_nfsstat_print(elfrec, &res->rd_status, print_status); 900 } else if (res->rd_status == NFS_OK) { 901 char *elfbuf = elfrec->buf; 902 int elfbufoffset = elfrec->bufoffset; 903 904 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 905 res->nfslog_rddirres_u.rd_ok.rdok_offset); 906 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 907 res->nfslog_rddirres_u.rd_ok.rdok_size); 908 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 909 res->nfslog_rddirres_u.rd_ok.rdok_eof); 910 elfrec->bufoffset = elfbufoffset; 911 } 912 } 913 914 /* 915 * NFS VERSION 3 916 */ 917 918 static void 919 nfslog_diropargs3_print(struct nfsl_log_file *elfrec, 920 nfslog_diropargs3 *args) 921 { 922 if (nfsl_print_fh) { 923 nfslog_fh3_print(elfrec, &args->dir); 924 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 925 " \"%s\"", args->name); 926 } 927 } 928 929 static void 930 nfslog_size3_print(struct nfsl_log_file *elfrec, set_size3 *args) 931 { 932 char *elfbuf = elfrec->buf; 933 int elfbufoffset = elfrec->bufoffset; 934 935 if (args->set_it) { 936 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 937 /* CSTYLED */ 938 " \"size=0x%llx\"", args->size); 939 } 940 elfrec->bufoffset = elfbufoffset; 941 } 942 943 static void 944 nfslog_SETATTR3args_print(struct nfsl_log_file *elfrec, 945 nfslog_SETATTR3args *args) 946 { 947 nfslog_fh3_print(elfrec, &args->object); 948 nfslog_size3_print(elfrec, &args->size); 949 } 950 951 static void 952 nfslog_READ3args_print(struct nfsl_log_file *elfrec, nfslog_READ3args *args) 953 { 954 nfslog_fh3_print(elfrec, &args->file); 955 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%llx", 956 args->offset); 957 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%x", 958 args->count); 959 } 960 961 static void 962 nfslog_WRITE3args_print(struct nfsl_log_file *elfrec, 963 nfslog_WRITE3args *args) 964 { 965 char *elfbuf = elfrec->buf; 966 int elfbufoffset; 967 968 nfslog_fh3_print(elfrec, &args->file); 969 elfbufoffset = elfrec->bufoffset; 970 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%llx", 971 args->offset); 972 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 973 args->count); 974 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 975 args->stable); 976 elfrec->bufoffset = elfbufoffset; 977 } 978 979 static void 980 nfslog_CREATE3args_print(struct nfsl_log_file *elfrec, 981 nfslog_CREATE3args *args) 982 { 983 nfslog_diropargs3_print(elfrec, &args->where); 984 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " %s", 985 NFSL_CREATEMODE3(args->how.mode)); 986 if (args->how.mode != EXCLUSIVE) { 987 nfslog_size3_print(elfrec, 988 &args->how.nfslog_createhow3_u.size); 989 } 990 } 991 992 static void 993 nfslog_MKDIR3args_print(struct nfsl_log_file *elfrec, 994 nfslog_MKDIR3args *args) 995 { 996 nfslog_diropargs3_print(elfrec, &args->where); 997 } 998 999 static void 1000 nfslog_SYMLINK3args_print(struct nfsl_log_file *elfrec, 1001 nfslog_SYMLINK3args *args) 1002 { 1003 nfslog_diropargs3_print(elfrec, &args->where); 1004 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 1005 " \"%s\"", args->symlink_data); 1006 } 1007 1008 static void 1009 nfslog_MKNOD3args_print(struct nfsl_log_file *elfrec, 1010 nfslog_MKNOD3args *args) 1011 { 1012 nfslog_diropargs3_print(elfrec, &args->where); 1013 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " %s", 1014 NFSL_FTYPE3(args->type)); 1015 } 1016 1017 static void 1018 nfslog_REMOVE3args_print(struct nfsl_log_file *elfrec, 1019 nfslog_REMOVE3args *args) 1020 { 1021 nfslog_diropargs3_print(elfrec, &args->object); 1022 } 1023 1024 static void 1025 nfslog_RMDIR3args_print(struct nfsl_log_file *elfrec, 1026 nfslog_RMDIR3args *args) 1027 { 1028 nfslog_diropargs3_print(elfrec, &args->object); 1029 } 1030 1031 static void 1032 nfslog_RENAME3args_print(struct nfsl_log_file *elfrec, 1033 nfslog_RENAME3args *args) 1034 { 1035 nfslog_diropargs3_print(elfrec, &args->from); 1036 nfslog_diropargs3_print(elfrec, &args->to); 1037 } 1038 1039 static void 1040 nfslog_LINK3args_print(struct nfsl_log_file *elfrec, nfslog_LINK3args *args) 1041 { 1042 nfslog_fh3_print(elfrec, &args->file); 1043 nfslog_diropargs3_print(elfrec, &args->link); 1044 } 1045 1046 static void 1047 nfslog_READDIRPLUS3args_print(struct nfsl_log_file *elfrec, 1048 nfslog_READDIRPLUS3args *args) 1049 { 1050 nfslog_fh3_print(elfrec, &args->dir); 1051 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%x", 1052 args->dircount); 1053 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%x", 1054 args->maxcount); 1055 } 1056 1057 static void 1058 nfslog_COMMIT3args_print(struct nfsl_log_file *elfrec, 1059 nfslog_COMMIT3args *args) 1060 { 1061 nfslog_fh3_print(elfrec, &args->file); 1062 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%llx", 1063 args->offset); 1064 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], " 0x%x", 1065 args->count); 1066 } 1067 1068 static void 1069 nfslog_nfsstat3_print(struct nfsl_log_file *elfrec, enum nfsstat3 *res, 1070 bool_t print_status) 1071 { 1072 if (print_status) { 1073 char *statp = nfslog_get_status((short)(*res)); 1074 1075 if (statp != NULL) 1076 elfrec->bufoffset += 1077 sprintf(&elfrec->buf[elfrec->bufoffset], " %s", 1078 statp); 1079 else 1080 elfrec->bufoffset += 1081 sprintf(&elfrec->buf[elfrec->bufoffset], " %5d", 1082 *res); 1083 } 1084 } 1085 1086 static void 1087 nfslog_LOOKUP3res_print(struct nfsl_log_file *elfrec, 1088 nfslog_LOOKUP3res *res, bool_t print_status) 1089 { 1090 if (print_status) { 1091 nfslog_nfsstat3_print(elfrec, &res->status, print_status); 1092 } else if (res->status == NFS3_OK) { 1093 nfslog_fh3_print(elfrec, &res->nfslog_LOOKUP3res_u.object); 1094 } 1095 } 1096 1097 static void 1098 nfslog_READLINK3res_print(struct nfsl_log_file *elfrec, 1099 nfslog_READLINK3res *res, bool_t print_status) 1100 { 1101 if (print_status) { 1102 nfslog_nfsstat3_print(elfrec, &res->status, print_status); 1103 } else if (res->status == NFS3_OK) { 1104 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 1105 " %s", res->nfslog_READLINK3res_u.data); 1106 } 1107 } 1108 1109 static void 1110 nfslog_READ3res_print(struct nfsl_log_file *elfrec, nfslog_READ3res *res, 1111 bool_t print_status) 1112 { 1113 if (print_status) { 1114 nfslog_nfsstat3_print(elfrec, &res->status, print_status); 1115 } else if (res->status == NFS3_OK) { 1116 char *elfbuf = elfrec->buf; 1117 int elfbufoffset = elfrec->bufoffset; 1118 1119 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%llx", 1120 res->nfslog_READ3res_u.ok.filesize); 1121 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 1122 res->nfslog_READ3res_u.ok.count); 1123 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 1124 res->nfslog_READ3res_u.ok.eof); 1125 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 1126 res->nfslog_READ3res_u.ok.size); 1127 elfrec->bufoffset = elfbufoffset; 1128 } 1129 } 1130 1131 static void 1132 nfslog_WRITE3res_print(struct nfsl_log_file *elfrec, nfslog_WRITE3res *res, 1133 bool_t print_status) 1134 { 1135 if (print_status) { 1136 nfslog_nfsstat3_print(elfrec, &res->status, print_status); 1137 } else if (res->status == NFS3_OK) { 1138 char *elfbuf = elfrec->buf; 1139 int elfbufoffset = elfrec->bufoffset; 1140 1141 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%llx", 1142 res->nfslog_WRITE3res_u.ok.filesize); 1143 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 1144 " 0x%x", res->nfslog_WRITE3res_u.ok.count); 1145 elfbufoffset += sprintf(&elfrec->buf[elfbufoffset], 1146 " 0x%x", res->nfslog_WRITE3res_u.ok.committed); 1147 elfrec->bufoffset = elfbufoffset; 1148 } 1149 } 1150 1151 static void 1152 nfslog_CREATE3res_print(struct nfsl_log_file *elfrec, nfslog_CREATE3res *res, 1153 bool_t print_status) 1154 { 1155 if (print_status) { 1156 nfslog_nfsstat3_print(elfrec, &res->status, print_status); 1157 } else if (res->status == NFS3_OK) { 1158 if (res->nfslog_CREATE3res_u.ok.obj.handle_follows) { 1159 nfslog_fh3_print(elfrec, 1160 &res->nfslog_CREATE3res_u.ok.obj.handle); 1161 } 1162 } 1163 } 1164 1165 static void 1166 nfslog_MKDIR3res_print(struct nfsl_log_file *elfrec, nfslog_MKDIR3res *res, 1167 bool_t print_status) 1168 { 1169 if (print_status) { 1170 nfslog_nfsstat3_print(elfrec, &res->status, print_status); 1171 } else if (res->status == NFS3_OK) { 1172 if (res->nfslog_MKDIR3res_u.obj.handle_follows) { 1173 nfslog_fh3_print(elfrec, 1174 &res->nfslog_MKDIR3res_u.obj.handle); 1175 } 1176 } 1177 } 1178 1179 static void 1180 nfslog_SYMLINK3res_print(struct nfsl_log_file *elfrec, nfslog_SYMLINK3res *res, 1181 bool_t print_status) 1182 { 1183 if (print_status) { 1184 nfslog_nfsstat3_print(elfrec, &res->status, print_status); 1185 } else if (res->status == NFS3_OK) { 1186 if (res->nfslog_SYMLINK3res_u.obj.handle_follows) { 1187 nfslog_fh3_print(elfrec, 1188 &res->nfslog_SYMLINK3res_u.obj.handle); 1189 } 1190 } 1191 } 1192 1193 static void 1194 nfslog_MKNOD3res_print(struct nfsl_log_file *elfrec, nfslog_MKNOD3res *res, 1195 bool_t print_status) 1196 { 1197 if (print_status) { 1198 nfslog_nfsstat3_print(elfrec, &res->status, print_status); 1199 } else if (res->status == NFS3_OK) { 1200 if (res->nfslog_MKNOD3res_u.obj.handle_follows) { 1201 nfslog_fh3_print(elfrec, 1202 &res->nfslog_MKNOD3res_u.obj.handle); 1203 } 1204 } 1205 } 1206 1207 static void 1208 nfslog_READDIRPLUS3res_print(struct nfsl_log_file *elfrec, 1209 nfslog_READDIRPLUS3res *res, bool_t print_status) 1210 { 1211 if (print_status) { 1212 nfslog_nfsstat3_print(elfrec, &res->status, print_status); 1213 } 1214 } 1215 1216 /* 1217 * **** End of table functions for logging specific procs **** 1218 * 1219 * Hereafter are the general logging management and dispatcher. 1220 */ 1221 1222 1223 /* 1224 * nfsl_ipaddr_print - extracts sender ip address from transport struct 1225 * and prints it in legible form. 1226 */ 1227 static void 1228 nfsl_ipaddr_print(struct nfsl_log_file *elfrec, struct netbuf *ptr) 1229 { 1230 struct hostent *hp; 1231 extern char *inet_ntop(); 1232 int size, sin_family, error; 1233 char *elfbuf = elfrec->buf; 1234 char *addrp; 1235 int elfbufoffset = elfrec->bufoffset; 1236 1237 if (ptr->len == 0) { 1238 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 1239 empty_name); 1240 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 1241 empty_name); 1242 elfrec->bufoffset = elfbufoffset; 1243 return; 1244 } 1245 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " "); 1246 /* LINTED */ 1247 sin_family = ((struct sockaddr_in *)ptr->buf)->sin_family; 1248 switch (sin_family) { 1249 case (AF_INET): 1250 /* LINTED */ 1251 addrp = (char *)&((struct sockaddr_in *)ptr->buf)->sin_addr; 1252 size = sizeof (struct in_addr); 1253 break; 1254 case (AF_INET6): 1255 /* LINTED */ 1256 addrp = (char *)&((struct sockaddr_in6 *)ptr->buf)->sin6_addr; 1257 size = sizeof (struct in6_addr); 1258 break; 1259 default: 1260 /* unknown protocol: print address in hex form */ 1261 for (size = ptr->len, addrp = ptr->buf; size > 0; size--) { 1262 elfbufoffset += sprintf(&elfbuf[elfbufoffset], "%02x", 1263 *addrp); 1264 } 1265 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 1266 empty_name); 1267 elfrec->bufoffset = elfbufoffset; 1268 return; 1269 } 1270 if (inet_ntop(sin_family, addrp, &elfbuf[elfbufoffset], 1271 (size_t)(DFLT_BUFFERSIZE + DFLT_OVFSIZE - elfbufoffset)) 1272 == NULL) { 1273 /* Not enough space to print - should never happen */ 1274 elfbuf[elfrec->bufoffset] = '\0'; /* just in case */ 1275 return; 1276 } 1277 /* inet_ntop copied address into elfbuf, so update offset */ 1278 elfbufoffset += strlen(&elfbuf[elfbufoffset]); 1279 /* get host name and log it as well */ 1280 hp = getipnodebyaddr(addrp, size, sin_family, &error); 1281 if (hp != NULL) { 1282 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " \"%s\"", 1283 hp->h_name); 1284 } else { 1285 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 1286 empty_name); 1287 } 1288 elfrec->bufoffset = elfbufoffset; 1289 } 1290 1291 static void 1292 nfsl_elf_record_header_print(struct nfsl_log_file *elfrec, 1293 nfslog_record_header *lhp, char *principal_name, char *tag, 1294 struct nfsl_proc_disp *disp, char *progname) 1295 { 1296 struct passwd *pwp = NULL; 1297 char *elfbuf = elfrec->buf; 1298 int elfbufoffset = elfrec->bufoffset; 1299 1300 /* 1301 * Fields: time bytes tag rpc-program rpc-version rpc-procedure 1302 * auth-flavor s-user-name s-uid uid u-name gid net-id 1303 * c-ip c-dns s-dns status rpcarg-path <arguments> <response> 1304 */ 1305 elfbufoffset += sprintf(&elfbuf[elfbufoffset], "%s", 1306 nfsl_get_time((time_t)lhp->rh_timestamp.tv_sec)); 1307 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%x", 1308 lhp->rh_reclen); 1309 if ((tag != NULL) && (tag[0] != '\0')) { 1310 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " \"%s\"", tag); 1311 } else { 1312 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 1313 empty_name); 1314 } 1315 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s 0x%x %s", 1316 progname, lhp->rh_version, disp->procname); 1317 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 1318 NFSL_AUTH_FLAVOR_PRINT(lhp->rh_auth_flavor)); 1319 if ((principal_name != NULL) && (principal_name[0] != '\0')) { 1320 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " \"%s\"", 1321 principal_name); 1322 if ((pwp = getpwnam(principal_name)) != NULL) { 1323 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 1324 " 0x%lx", pwp->pw_uid); 1325 } else { 1326 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 1327 " %s", empty_name); 1328 } 1329 } else { 1330 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 1331 empty_name); 1332 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 1333 empty_name); 1334 } 1335 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%lx", lhp->rh_uid); 1336 if (((pwp = getpwuid(lhp->rh_uid)) != NULL) && (pwp->pw_name != NULL)) { 1337 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " \"%s\"", 1338 pwp->pw_name); 1339 } else { 1340 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " %s", 1341 empty_name); 1342 } 1343 elfbufoffset += sprintf(&elfbuf[elfbufoffset], " 0x%lx", lhp->rh_gid); 1344 elfrec->bufoffset = elfbufoffset; 1345 } 1346 1347 static void 1348 nfsl_elf_buffer_header_print(struct nfsl_log_file *elfrec, 1349 nfslog_buffer_header *bufhdr) 1350 { 1351 int rc; 1352 struct utsname name; 1353 char *elfbuf = elfrec->buf; 1354 int elfbufoffset = elfrec->bufoffset; 1355 1356 rc = uname(&name); 1357 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 1358 "#Version %d.0\n#Software \"%s\"\n", 1359 bufhdr->bh_version, ((rc >= 0) ? name.sysname : empty_name)); 1360 elfbufoffset += sprintf(&elfbuf[elfbufoffset], "#Date %s\n", 1361 nfsl_get_date((time_t)bufhdr->bh_timestamp.tv_sec)); 1362 elfbufoffset += sprintf(&elfbuf[elfbufoffset], "#Remark %s\n", 1363 empty_name); 1364 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 1365 "#Fields: time bytes tag"); 1366 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 1367 " rpc-program rpc-version rpc-procedure"); 1368 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 1369 " auth-flavor s-user-name s-uid uid u-name gid net-id c-ip"); 1370 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 1371 " c-dns s-dns status rpcarg-path"); 1372 elfbufoffset += sprintf(&elfbuf[elfbufoffset], 1373 " rpc-arguments... rpc-response...\n"); 1374 elfrec->bufoffset = elfbufoffset; 1375 } 1376 1377 /* 1378 * nfsl_find_elf_dispatch - get the dispatch struct for this request 1379 */ 1380 static struct nfsl_proc_disp * 1381 nfsl_find_elf_dispatch(nfslog_request_record *logrec, char **prognamep) 1382 { 1383 nfslog_record_header *logrechdr = &logrec->re_header; 1384 struct nfsl_prog_disp *progtable; /* prog struct */ 1385 struct nfsl_vers_disp *verstable; /* version struct */ 1386 int i, vers; 1387 1388 /* Find prog element - search because can't use prog as array index */ 1389 for (i = 0; (i < nfsl_elf_dispatch_table_arglen) && 1390 (logrechdr->rh_prognum != nfsl_elf_dispatch_table[i].nfsl_dis_prog); 1391 i++); 1392 if (i >= nfsl_elf_dispatch_table_arglen) { /* program not logged */ 1393 /* not an error */ 1394 return (NULL); 1395 } 1396 progtable = &nfsl_elf_dispatch_table[i]; 1397 /* Find vers element - no validity check - if here it's valid vers */ 1398 vers = logrechdr->rh_version - progtable->nfsl_dis_versmin; 1399 verstable = &progtable->nfsl_dis_vers_table[vers]; 1400 /* Find proc element - no validity check - if here it's valid proc */ 1401 *prognamep = progtable->progname; 1402 return (&verstable->nfsl_dis_proc_table[logrechdr->rh_procnum]); 1403 } 1404 1405 /* 1406 * nfsl_elf_rpc_print - Print the record buffer. 1407 */ 1408 static void 1409 nfsl_elf_rpc_print(struct nfsl_log_file *elfrec, 1410 nfslog_request_record *logrec, struct nfsl_proc_disp *disp, 1411 char *progname, char *path1, char *path2) 1412 { 1413 if (debug > 1) { 1414 (void) printf("%s %d %s", progname, 1415 logrec->re_header.rh_version, disp->procname); 1416 (void) printf(": '%s', '%s'\n", 1417 ((path1 != NULL) ? path1 : empty_name), 1418 ((path2 != NULL) ? path2 : empty_name)); 1419 } 1420 /* 1421 * XXXX programs using this file to get a usable record should 1422 * take "record" struct. 1423 */ 1424 /* 1425 * Print the variable fields: 1426 * principal name 1427 * netid 1428 * ip address 1429 * rpc args 1430 * rpc res 1431 * Use the displacements calculated earlier... 1432 */ 1433 1434 /* 1435 * Fields: time bytes tag rpc-program rpc-version rpc-procedure 1436 * auth-flavor s-user-name s-uid uid u-name gid net-id c-ip 1437 * c-dns s-dns status rpcarg-path <arguments> <response> 1438 */ 1439 nfsl_elf_record_header_print(elfrec, &logrec->re_header, 1440 logrec->re_principal_name, logrec->re_tag, 1441 disp, progname); 1442 if ((logrec->re_netid != NULL) && (logrec->re_netid[0] != '\0')) { 1443 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 1444 " \"%s\"", logrec->re_netid); 1445 } else { 1446 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 1447 " %s", empty_name); 1448 } 1449 nfsl_ipaddr_print(elfrec, &logrec->re_ipaddr); 1450 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 1451 " \"%s\"", hostname); 1452 /* Next is return status */ 1453 (*disp->nfsl_dis_res)(elfrec, logrec->re_rpc_res, TRUE); 1454 /* Next is argpath */ 1455 if (path1 != NULL) { 1456 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 1457 " \"%s\"", path1); 1458 } else { 1459 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 1460 " %s", empty_name); 1461 } 1462 /* 1463 * path2 is non-empty for rename/link type operations. If it is non- 1464 * empty print it here as it's a part of the args 1465 */ 1466 if (path2 != NULL) { 1467 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], 1468 " \"%s\"", path2); 1469 } 1470 /* Next print formatted rpc args */ 1471 (*disp->nfsl_dis_args)(elfrec, logrec->re_rpc_arg); 1472 /* Next print formatted rpc res (minus status) */ 1473 (*disp->nfsl_dis_res)(elfrec, logrec->re_rpc_res, FALSE); 1474 elfrec->bufoffset += sprintf(&elfrec->buf[elfrec->bufoffset], "\n"); 1475 } 1476 1477 /* 1478 * nfsl_log_file_add - add a new record to the list 1479 */ 1480 static void 1481 nfsl_log_file_add(struct nfsl_log_file *elfrec, 1482 struct nfsl_log_file **elf_listp) 1483 { 1484 elfrec->next = *elf_listp; 1485 elfrec->prev = NULL; 1486 if (*elf_listp != NULL) { 1487 (*elf_listp)->prev = elfrec; 1488 } 1489 *elf_listp = elfrec; 1490 } 1491 1492 /* 1493 * nfsl_log_file_find - finds a record in the list, given a cookie (== elfrec) 1494 * Returns the record. 1495 */ 1496 static struct nfsl_log_file * 1497 nfsl_log_file_find(struct nfsl_log_file *elfrec, 1498 struct nfsl_log_file *elf_list) 1499 { 1500 struct nfsl_log_file *rec; 1501 1502 for (rec = elf_list; (rec != NULL) && (rec != elfrec); 1503 rec = rec->next); 1504 return (rec); 1505 } 1506 1507 /* 1508 * nfsl_log_file_del - delete a record from the list, does not free rec. 1509 * Returns the deleted record. 1510 */ 1511 static struct nfsl_log_file * 1512 nfsl_log_file_del(struct nfsl_log_file *elfrec, 1513 struct nfsl_log_file **elf_listp) 1514 { 1515 struct nfsl_log_file *rec; 1516 1517 if ((rec = nfsl_log_file_find(elfrec, *elf_listp)) == NULL) { 1518 return (NULL); 1519 } 1520 if (rec->prev != NULL) { 1521 rec->prev->next = rec->next; 1522 } else { 1523 *elf_listp = rec->next; 1524 } 1525 if (rec->next != NULL) { 1526 rec->next->prev = rec->prev; 1527 } 1528 return (rec); 1529 } 1530 1531 /* 1532 * nfsl_log_file_free - frees a record 1533 */ 1534 static void 1535 nfsl_log_file_free(struct nfsl_log_file *elfrec) 1536 { 1537 if (elfrec == NULL) 1538 return; 1539 if (elfrec->path != NULL) 1540 free(elfrec->path); 1541 if (elfrec->buf != NULL) 1542 free(elfrec->buf); 1543 free(elfrec); 1544 } 1545 1546 /* 1547 * Exported Functions 1548 */ 1549 1550 /* 1551 * nfslog_open_elf_file - open the output elf file and mallocs needed buffers 1552 * Returns a pointer to the nfsl_log_file on success, NULL on error. 1553 * 1554 * *error contains the last error encountered on this object, It can 1555 * be used to avoid reporting the same error endlessly, by comparing 1556 * the current error to the last error. It is reset to the current error 1557 * code on return. 1558 */ 1559 void * 1560 nfslog_open_elf_file(char *elfpath, nfslog_buffer_header *bufhdr, int *error) 1561 { 1562 struct nfsl_log_file *elfrec; 1563 struct stat stat_buf; 1564 int preverror = *error; 1565 1566 if ((elfrec = malloc(sizeof (*elfrec))) == NULL) { 1567 *error = errno; 1568 if (*error != preverror) { 1569 syslog(LOG_ERR, gettext("nfslog_open_elf_file: %s"), 1570 strerror(*error)); 1571 } 1572 return (NULL); 1573 } 1574 bzero(elfrec, sizeof (*elfrec)); 1575 1576 elfrec->buf = (char *)malloc(DFLT_BUFFERSIZE + DFLT_OVFSIZE); 1577 if (elfrec->buf == NULL) { 1578 *error = errno; 1579 if (*error != preverror) { 1580 syslog(LOG_ERR, gettext("nfslog_open_elf_file: %s"), 1581 strerror(*error)); 1582 } 1583 nfsl_log_file_free(elfrec); 1584 return (NULL); 1585 } 1586 1587 if ((elfrec->path = strdup(elfpath)) == NULL) { 1588 *error = errno; 1589 if (*error != preverror) { 1590 syslog(LOG_ERR, gettext("nfslog_open_elf_file: %s"), 1591 strerror(*error)); 1592 } 1593 nfsl_log_file_free(elfrec); 1594 return (NULL); 1595 } 1596 1597 if ((elfrec->fp = fopen(elfpath, "a")) == NULL) { 1598 *error = errno; 1599 if (*error != preverror) { 1600 syslog(LOG_ERR, gettext("Cannot open '%s': %s"), 1601 elfpath, strerror(*error)); 1602 } 1603 nfsl_log_file_free(elfrec); 1604 return (NULL); 1605 } 1606 1607 if (stat(elfpath, &stat_buf) == -1) { 1608 *error = errno; 1609 if (*error != preverror) { 1610 syslog(LOG_ERR, gettext("Cannot stat '%s': %s"), 1611 elfpath, strerror(*error)); 1612 } 1613 (void) fclose(elfrec->fp); 1614 nfsl_log_file_free(elfrec); 1615 return (NULL); 1616 } 1617 1618 nfsl_log_file_add(elfrec, &elf_file_list); 1619 1620 if (stat_buf.st_size == 0) { 1621 /* 1622 * Print header unto logfile 1623 */ 1624 nfsl_elf_buffer_header_print(elfrec, bufhdr); 1625 } 1626 1627 if (hostname[0] == '\0') { 1628 (void) gethostname(hostname, MAXHOSTNAMELEN); 1629 } 1630 1631 return (elfrec); 1632 } 1633 1634 /* 1635 * nfslog_close_elf_file - close elffile and write out last buffer 1636 */ 1637 void 1638 nfslog_close_elf_file(void **elfcookie) 1639 { 1640 struct nfsl_log_file *elfrec; 1641 1642 if ((*elfcookie == NULL) || ((elfrec = nfsl_log_file_del( 1643 *elfcookie, &elf_file_list)) == NULL)) { 1644 *elfcookie = NULL; 1645 return; 1646 } 1647 if (elfrec->fp != NULL) { 1648 /* Write the last output buffer to disk */ 1649 (void) nfsl_write_elfbuf(elfrec); 1650 (void) fclose(elfrec->fp); 1651 } 1652 nfsl_log_file_free(elfrec); 1653 *elfcookie = NULL; 1654 } 1655 1656 /* 1657 * nfslog_process_elf_rec - processes the record in the buffer and outputs 1658 * to the elf log. 1659 * Return 0 for success, errno else. 1660 */ 1661 int 1662 nfslog_process_elf_rec(void *elfcookie, nfslog_request_record *logrec, 1663 char *path1, char *path2) 1664 { 1665 struct nfsl_log_file *elfrec; 1666 struct nfsl_proc_disp *disp; 1667 char *progname; 1668 1669 if ((elfrec = nfsl_log_file_find(elfcookie, elf_file_list)) == NULL) { 1670 return (EINVAL); 1671 } 1672 /* Make sure there is room */ 1673 if (elfrec->bufoffset > DFLT_BUFFERSIZE) { 1674 if (nfsl_write_elfbuf(elfrec) < 0) { 1675 return (errno); 1676 } 1677 } 1678 if ((disp = nfsl_find_elf_dispatch(logrec, &progname)) != NULL) { 1679 nfsl_elf_rpc_print(elfrec, logrec, disp, progname, 1680 path1, path2); 1681 } 1682 return (0); 1683 } 1684