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