--- //depot/vendor/freebsd/src/contrib/openbsm/bin/praudit/praudit.1 2008-12-02 23:35:38.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/bin/praudit/praudit.1 2010-08-06 18:10:43.000000000 0000 @@ -77,6 +77,9 @@ record and event type are displayed. This option is exclusive from .Fl r . +.It Fl c +Don't map user credentials to the local base system and print them in raw, +numeric form instead. This option is useful when auditing NFS RPCs. .It Fl x Print audit records in the XML output format. .El --- //depot/vendor/freebsd/src/contrib/openbsm/bin/praudit/praudit.c 2008-12-02 23:35:38.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/bin/praudit/praudit.c 2010-08-06 18:10:43.000000000 0000 @@ -50,6 +50,7 @@ static char *del = ","; /* Default delimiter. */ static int oneline = 0; static int raw = 0; +static int rawcred = 0; static int shortfrm = 0; static int partial = 0; static int xml = 0; @@ -58,7 +59,7 @@ usage(void) { - fprintf(stderr, "usage: praudit [-lpx] [-r | -s] [-d del] " + fprintf(stderr, "usage: praudit [-lpxc] [-r | -s] [-d del] " "[file ...]\n"); exit(1); } @@ -93,10 +94,10 @@ break; if (xml) au_print_tok_xml(stdout, &tok, del, raw, - shortfrm); + shortfrm, rawcred); else au_print_tok(stdout, &tok, del, raw, - shortfrm); + shortfrm, rawcred); bytesread += tok.len; if (oneline) { if (!xml) @@ -119,8 +120,12 @@ int i; FILE *fp; - while ((ch = getopt(argc, argv, "d:lprsx")) != -1) { + while ((ch = getopt(argc, argv, "d:lprcsx")) != -1) { switch(ch) { + case 'c': + rawcred = 1; + break; + case 'd': del = optarg; break; --- //depot/vendor/freebsd/src/contrib/openbsm/bsm/libbsm.h 2009-04-19 16:37:15.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/bsm/libbsm.h 2010-08-07 16:49:25.000000000 0000 @@ -502,17 +502,21 @@ au_tidaddr64_t tid; } au_proc64ex_t; +typedef struct { + u_int32_t protocol; +} au_protocol_t; + /* - * error status 1 byte + * error status 4 byte * return value 4 bytes/8 bytes (32-bit/64-bit value) */ typedef struct { - u_char status; + u_int32_t status; u_int32_t ret; } au_ret32_t; typedef struct { - u_char err; + u_int32_t err; u_int64_t val; } au_ret64_t; @@ -661,6 +665,10 @@ char *text; } au_text_t; +typedef struct { + u_int32_t vtype; +} au_vtype_t; + /* * zonename length 2 bytes * zonename text N bytes + 1 NULL terminator @@ -723,6 +731,7 @@ au_proc32ex_t proc32_ex; au_proc64_t proc64; au_proc64ex_t proc64_ex; + au_protocol_t prot; au_ret32_t ret32; au_ret64_t ret64; au_seq_t seq; @@ -735,6 +744,7 @@ au_subject64_t subj64; au_subject64ex_t subj64_ex; au_text_t text; + au_vtype_t vtype; au_kevent_t kevent; au_invalid_t invalid; au_trailer_t trail; @@ -820,9 +830,9 @@ int au_fetch_tok(tokenstr_t *tok, u_char *buf, int len); //XXX The following interface has different prototype from BSM void au_print_tok(FILE *outfp, tokenstr_t *tok, - char *del, char raw, char sfrm); + char *del, char raw, char sfrm, char rawcred); void au_print_tok_xml(FILE *outfp, tokenstr_t *tok, - char *del, char raw, char sfrm); + char *del, char raw, char sfrm, char rawcred); /* * Functions relating to XML output. @@ -836,16 +846,16 @@ * the FreeBSD and Mac OS X kernels) */ int au_bsm_to_domain(u_short bsm_domain, int *local_domainp); -int au_bsm_to_errno(u_char bsm_error, int *errorp); +int au_bsm_to_errno(int bsm_error, int *errorp); int au_bsm_to_fcntl_cmd(u_short bsm_fcntl_cmd, int *local_fcntl_cmdp); int au_bsm_to_socket_type(u_short bsm_socket_type, int *local_socket_typep); u_short au_domain_to_bsm(int local_domain); -u_char au_errno_to_bsm(int local_errno); +int au_errno_to_bsm(int local_errno); u_short au_fcntl_cmd_to_bsm(int local_fcntl_command); u_short au_socket_type_to_bsm(int local_socket_type); -const char *au_strerror(u_char bsm_error); +const char *au_strerror(int bsm_error); __END_DECLS /* --- //depot/vendor/freebsd/src/contrib/openbsm/etc/audit_event 2009-08-02 10:35:25.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/etc/audit_event 2010-07-08 19:00:38.000000000 0000 @@ -360,6 +360,71 @@ 360:AUE_DARWIN_SYSCTL_NONADMIN:sysctl() - non-admin:ot 361:AUE_DARWIN_COPYFILE:copyfile():fr,fw # +# NFS-specific kernel events +# +2000:AUE_NFS_NULL:nfsrv_null():ot +2001:AUE_NFS_GETATTR:nfsrv_getattr():fa +2002:AUE_NFS_SETATTR:nfsrv_setattr():fm +2003:AUE_NFS_LOOKUP:nfsrv_lookup():fa,ad +2004:AUE_NFS_ACCESS:nfsrv_access():fa +2005:AUE_NFS_READLINK:nfsrv_readlink():fr +2006:AUE_NFS_READ:nfsrv_read():fr +2007:AUE_NFS_WRITE:nfsrv_write():fw +2008:AUE_NFS_CREATE:nfsrv_create():fc,ad +2009:AUE_NFS_MKDIR:nfsrv_mkdir():fc,ad +2010:AUE_NFS_SYMLINK:nfsrv_symlink():fc,ad +2011:AUE_NFS_MKNOD:nfsrv_mknod():fc,ad +2012:AUE_NFS_REMOVE:nfsrv_remove():fd +2013:AUE_NFS_RMDIR:nfsrv_rmdir():fd +2014:AUE_NFS_RENAME:nfsrv_rename():fc,fd +2015:AUE_NFS_LINK:nfsrv_link():fc +2016:AUE_NFS_READDIR:nfsrv_readdir():fr +2017:AUE_NFS_READDIR_PLUS:nfsrv_readdirplus():fr,ad +2018:AUE_NFS_STATFS:nfsrv_statfs():fa +2019:AUE_NFS_FSINFO:nfsrv_fsinfo():ot +2020:AUE_NFS_PATHCONF:nfsrv_pathconf():fa +2021:AUE_NFS_COMMIT:nfsrv_commit():fw +2022:AUE_NFS_NOOP:nfsrv_noop():no +# +# NFSv4 specific RPC events +# +2023:AUE_NFS_CLOSE:nfsrv_close():cl +2024:AUE_NFS_DELEGPURGE:nfsrv_delegpurge():ad +2025:AUE_NFS_DELEGRETURN:nfsrv_delegreturn():ad +2026:AUE_NFSv4_GETFH:nfsrv4_getfh():ad +2027:AUE_NFS_LOCK:nfsrv_lock():fm +2028:AUE_NFS_LOCKT:nfsrv_lockt():fm +2029:AUE_NFS_LOCKU:nfsrv_locku():fm +2030:AUE_NFS_LOOKUPP:nfsrv_lookupp():fa,ad +2031:AUE_NFS_NVERIFY:nfsrv_nverify():fa +2032:AUE_NFS_OPEN:nfsrv_open():fa +2033:AUE_NFS_OPENATTR:nfsrv_openattr():fa +2034:AUE_NFS_OPENCONFIRM:nfsrv_openconfirm():fa +2035:AUE_NFS_OPENDOWNGRADE:nfsrv_opendowngrade():fm +2036:AUE_NFS_PUTFH:nfsrv_putfh():ad +2037:AUE_NFS_PUTPUBFH:nfsrv_putpubfh():ad +2038:AUE_NFS_PUTROOTFH:nfsrv_putrootfh():ad +2039:AUE_NFS_RENEW:nfsrv_renew():ad +2040:AUE_NFS_RESTOREFH:nfsrv_restorefh():ad +2041:AUE_NFS_SAVEFH:nfsrv_savefh():ad +2042:AUE_NFS_SECINFO:nfsrv_secinfo():ot +2043:AUE_NFS_SETCLIENTID:nfsrv_setclientid():aa +2044:AUE_NFS_SETCLIENTIDCFRM:nfsrv_setclientidcfrm():aa +2045:AUE_NFS_VERIFY:nfsrv_verify():fa +2046:AUE_NFS_RELEASELCKOWN:nfsrv_releaselckown():ad +2047:AUE_NFS_OPEN_R:nfsrv_open() - read:fr +2048:AUE_NFS_OPEN_RC:nfsrv_open() - read, creat:fr,fc,fa,fm +2049:AUE_NFS_OPEN_RTC:nfsrv_open() - read, trunc, creat:fr,fd,fc,fa,fm +2050:AUE_NFS_OPEN_RT:nfsrv_open() - read, trunc:fr,fd,fa,fm +2051:AUE_NFS_OPEN_RW:nfsrv_open() - read, write:fr,fw +2052:AUE_NFS_OPEN_RWC:nfsrv_open() - read, write, creat:fr,fw,fc,fa,fm +2053:AUE_NFS_OPEN_RWTC:nfsrv_open() - read, write, trunc, creat:fr,fw,fd,fc,fa,fm +2054:AUE_NFS_OPEN_RWT:nfsrv_open() - read, write, trunc:fr,fw,fd,fa,fm +2055:AUE_NFS_OPEN_W:nfsrv_open() - write:fw +2056:AUE_NFS_OPEN_WC:nfsrv_open() - write, creat:fw,fc,fa,fm +2057:AUE_NFS_OPEN_WTC:nfsrv_open() - write, trunc, creat:fw,fd,fc,fa,fm +2058:AUE_NFS_OPEN_WT:nfsrv_open() - write, trunc:fw,fd,fa,fm +# # OpenBSM-specific kernel events. # 43001:AUE_GETFSSTAT:getfsstat(2):fa --- //depot/vendor/freebsd/src/contrib/openbsm/libbsm/au_errno.3 2009-03-03 17:37:22.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/libbsm/au_errno.3 2010-08-06 18:10:43.000000000 0000 @@ -77,7 +77,11 @@ function converts a BSM error value to a string, generally by converting first to a local error number and using the local .Xr strerror 3 -function, but will also work for errors that are not locally defined. +function, but will also work for errors that are not locally defined. It will also +work for BSM errors limited to specific kernel modules that cannot be serviced +by +.Xr strerror 3 , +such as NFSv4 error values. .Sh RETURN VALULES On success, .Fn au_bsm_to_errno --- //depot/vendor/freebsd/src/contrib/openbsm/libbsm/bsm_errno.c 2009-07-17 14:37:30.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/libbsm/bsm_errno.c 2010-08-16 13:30:34.000000000 0000 @@ -31,6 +31,8 @@ #include +#include + #include #include @@ -43,17 +45,17 @@ * Different operating systems use different numeric constants for different * error numbers, and sometimes error numbers don't exist in more than one * operating system. These routines convert between BSM and local error - * number spaces, subject to the above realities. BSM error numbers are - * stored in a single 8-bit character, so don't have a byte order. + * number spaces, subject to the above realities. * * Don't include string definitions when this code is compiled into a kernel. */ struct bsm_errno { int be_bsm_errno; int be_local_errno; + char be_use_strerror; #if !defined(KERNEL) && !defined(_KERNEL) const char *be_strerror; -#endif +#endif }; #define ERRNO_NO_LOCAL_MAPPING -600 @@ -80,610 +82,953 @@ * string using strerror(3). */ static const struct bsm_errno bsm_errnos[] = { - { BSM_ERRNO_ESUCCESS, 0, ES("Success") }, - { BSM_ERRNO_EPERM, EPERM, ES("Operation not permitted") }, - { BSM_ERRNO_ENOENT, ENOENT, ES("No such file or directory") }, - { BSM_ERRNO_ESRCH, ESRCH, ES("No such process") }, - { BSM_ERRNO_EINTR, EINTR, ES("Interrupted system call") }, - { BSM_ERRNO_EIO, EIO, ES("Input/output error") }, - { BSM_ERRNO_ENXIO, ENXIO, ES("Device not configured") }, - { BSM_ERRNO_E2BIG, E2BIG, ES("Argument list too long") }, - { BSM_ERRNO_ENOEXEC, ENOEXEC, ES("Exec format error") }, - { BSM_ERRNO_EBADF, EBADF, ES("Bad file descriptor") }, - { BSM_ERRNO_ECHILD, ECHILD, ES("No child processes") }, - { BSM_ERRNO_EAGAIN, EAGAIN, ES("Resource temporarily unavailable") }, - { BSM_ERRNO_ENOMEM, ENOMEM, ES("Cannot allocate memory") }, - { BSM_ERRNO_EACCES, EACCES, ES("Permission denied") }, - { BSM_ERRNO_EFAULT, EFAULT, ES("Bad address") }, - { BSM_ERRNO_ENOTBLK, ENOTBLK, ES("Block device required") }, - { BSM_ERRNO_EBUSY, EBUSY, ES("Device busy") }, - { BSM_ERRNO_EEXIST, EEXIST, ES("File exists") }, - { BSM_ERRNO_EXDEV, EXDEV, ES("Cross-device link") }, - { BSM_ERRNO_ENODEV, ENODEV, ES("Operation not supported by device") }, - { BSM_ERRNO_ENOTDIR, ENOTDIR, ES("Not a directory") }, - { BSM_ERRNO_EISDIR, EISDIR, ES("Is a directory") }, - { BSM_ERRNO_EINVAL, EINVAL, ES("Invalid argument") }, - { BSM_ERRNO_ENFILE, ENFILE, ES("Too many open files in system") }, - { BSM_ERRNO_EMFILE, EMFILE, ES("Too many open files") }, - { BSM_ERRNO_ENOTTY, ENOTTY, ES("Inappropriate ioctl for device") }, - { BSM_ERRNO_ETXTBSY, ETXTBSY, ES("Text file busy") }, - { BSM_ERRNO_EFBIG, EFBIG, ES("File too large") }, - { BSM_ERRNO_ENOSPC, ENOSPC, ES("No space left on device") }, - { BSM_ERRNO_ESPIPE, ESPIPE, ES("Illegal seek") }, - { BSM_ERRNO_EROFS, EROFS, ES("Read-only file system") }, - { BSM_ERRNO_EMLINK, EMLINK, ES("Too many links") }, - { BSM_ERRNO_EPIPE, EPIPE, ES("Broken pipe") }, - { BSM_ERRNO_EDOM, EDOM, ES("Numerical argument out of domain") }, - { BSM_ERRNO_ERANGE, ERANGE, ES("Result too large") }, - { BSM_ERRNO_ENOMSG, ENOMSG, ES("No message of desired type") }, - { BSM_ERRNO_EIDRM, EIDRM, ES("Identifier removed") }, + { BSM_ERRNO_ESUCCESS, 0, 1, ES("Success") }, + { BSM_ERRNO_EPERM, EPERM, 1, ES("Operation not permitted") }, + { BSM_ERRNO_ENOENT, ENOENT, 1, ES("No such file or directory") }, + { BSM_ERRNO_ESRCH, ESRCH, 1, ES("No such process") }, + { BSM_ERRNO_EINTR, EINTR, 1, ES("Interrupted system call") }, + { BSM_ERRNO_EIO, EIO, 1, ES("Input/output error") }, + { BSM_ERRNO_ENXIO, ENXIO, 1, ES("Device not configured") }, + { BSM_ERRNO_E2BIG, E2BIG, 1, ES("Argument list too long") }, + { BSM_ERRNO_ENOEXEC, ENOEXEC, 1, ES("Exec format error") }, + { BSM_ERRNO_EBADF, EBADF, 1, ES("Bad file descriptor") }, + { BSM_ERRNO_ECHILD, ECHILD, 1, ES("No child processes") }, + { BSM_ERRNO_EAGAIN, EAGAIN, 1, ES("Resource temporarily unavailable") }, + { BSM_ERRNO_ENOMEM, ENOMEM, 1, ES("Cannot allocate memory") }, + { BSM_ERRNO_EACCES, EACCES, 1, ES("Permission denied") }, + { BSM_ERRNO_EFAULT, EFAULT, 1, ES("Bad address") }, + { BSM_ERRNO_ENOTBLK, ENOTBLK, 1, ES("Block device required") }, + { BSM_ERRNO_EBUSY, EBUSY, 1, ES("Device busy") }, + { BSM_ERRNO_EEXIST, EEXIST, 1, ES("File exists") }, + { BSM_ERRNO_EXDEV, EXDEV, 1, ES("Cross-device link") }, + { BSM_ERRNO_ENODEV, ENODEV, 1, ES("Operation not supported by device") }, + { BSM_ERRNO_ENOTDIR, ENOTDIR, 1, ES("Not a directory") }, + { BSM_ERRNO_EISDIR, EISDIR, 1, ES("Is a directory") }, + { BSM_ERRNO_EINVAL, EINVAL, 1, ES("Invalid argument") }, + { BSM_ERRNO_ENFILE, ENFILE, 1, ES("Too many open files in system") }, + { BSM_ERRNO_EMFILE, EMFILE, 1, ES("Too many open files") }, + { BSM_ERRNO_ENOTTY, ENOTTY, 1, ES("Inappropriate ioctl for device") }, + { BSM_ERRNO_ETXTBSY, ETXTBSY, 1, ES("Text file busy") }, + { BSM_ERRNO_EFBIG, EFBIG, 1, ES("File too large") }, + { BSM_ERRNO_ENOSPC, ENOSPC, 1, ES("No space left on device") }, + { BSM_ERRNO_ESPIPE, ESPIPE, 1, ES("Illegal seek") }, + { BSM_ERRNO_EROFS, EROFS, 1, ES("Read-only file system") }, + { BSM_ERRNO_EMLINK, EMLINK, 1, ES("Too many links") }, + { BSM_ERRNO_EPIPE, EPIPE, 1, ES("Broken pipe") }, + { BSM_ERRNO_EDOM, EDOM, 1, ES("Numerical argument out of domain") }, + { BSM_ERRNO_ERANGE, ERANGE, 1, ES("Result too large") }, + { BSM_ERRNO_ENOMSG, ENOMSG, 1, ES("No message of desired type") }, + { BSM_ERRNO_EIDRM, EIDRM, 1, ES("Identifier removed") }, { BSM_ERRNO_ECHRNG, #ifdef ECHRNG ECHRNG, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Channel number out of range") }, + 1, ES("Channel number out of range") }, { BSM_ERRNO_EL2NSYNC, #ifdef EL2NSYNC EL2NSYNC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Level 2 not synchronized") }, + 1, ES("Level 2 not synchronized") }, { BSM_ERRNO_EL3HLT, #ifdef EL3HLT EL3HLT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Level 3 halted") }, + 1, ES("Level 3 halted") }, { BSM_ERRNO_EL3RST, #ifdef EL3RST EL3RST, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Level 3 reset") }, + 1, ES("Level 3 reset") }, { BSM_ERRNO_ELNRNG, #ifdef ELNRNG ELNRNG, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Link number out of range") }, + 1, ES("Link number out of range") }, { BSM_ERRNO_EUNATCH, #ifdef EUNATCH EUNATCH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Protocol driver not attached") }, + 1, ES("Protocol driver not attached") }, { BSM_ERRNO_ENOCSI, #ifdef ENOCSI ENOCSI, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("No CSI structure available") }, + 1, ES("No CSI structure available") }, { BSM_ERRNO_EL2HLT, #ifdef EL2HLT EL2HLT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Level 2 halted") }, - { BSM_ERRNO_EDEADLK, EDEADLK, ES("Resource deadlock avoided") }, - { BSM_ERRNO_ENOLCK, ENOLCK, ES("No locks available") }, - { BSM_ERRNO_ECANCELED, ECANCELED, ES("Operation canceled") }, - { BSM_ERRNO_ENOTSUP, ENOTSUP, ES("Operation not supported") }, - { BSM_ERRNO_EDQUOT, EDQUOT, ES("Disc quota exceeded") }, + 1, ES("Level 2 halted") }, + { BSM_ERRNO_EDEADLK, EDEADLK, 1, ES("Resource deadlock avoided") }, + { BSM_ERRNO_ENOLCK, ENOLCK, 1, ES("No locks available") }, + { BSM_ERRNO_ECANCELED, ECANCELED, 1, ES("Operation canceled") }, + { BSM_ERRNO_ENOTSUP, ENOTSUP, 1, ES("Operation not supported") }, + { BSM_ERRNO_EDQUOT, EDQUOT, 1, ES("Disc quota exceeded") }, { BSM_ERRNO_EBADE, #ifdef EBADE EBADE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Invalid exchange") }, + 1, ES("Invalid exchange") }, { BSM_ERRNO_EBADR, #ifdef EBADR EBADR, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Invalid request descriptor") }, + 1, ES("Invalid request descriptor") }, { BSM_ERRNO_EXFULL, #ifdef EXFULL EXFULL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Exchange full") }, + 1, ES("Exchange full") }, { BSM_ERRNO_ENOANO, #ifdef ENOANO ENOANO, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("No anode") }, + 1, ES("No anode") }, { BSM_ERRNO_EBADRQC, #ifdef EBADRQC EBADRQC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Invalid request descriptor") }, + 1, ES("Invalid request descriptor") }, { BSM_ERRNO_EBADSLT, #ifdef EBADSLT EBADSLT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Invalid slot") }, + 1, ES("Invalid slot") }, { BSM_ERRNO_EDEADLOCK, #ifdef EDEADLOCK EDEADLOCK, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Resource deadlock avoided") }, + 1, ES("Resource deadlock avoided") }, { BSM_ERRNO_EBFONT, #ifdef EBFONT EBFONT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Bad font file format") }, + 1, ES("Bad font file format") }, { BSM_ERRNO_EOWNERDEAD, #ifdef EOWNERDEAD EOWNERDEAD, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Process died with the lock") }, + 1, ES("Process died with the lock") }, { BSM_ERRNO_ENOTRECOVERABLE, #ifdef ENOTRECOVERABLE ENOTRECOVERABLE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Lock is not recoverable") }, + 1, ES("Lock is not recoverable") }, { BSM_ERRNO_ENOSTR, #ifdef ENOSTR ENOSTR, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Device not a stream") }, + 1, ES("Device not a stream") }, { BSM_ERRNO_ENONET, #ifdef ENONET ENONET, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Machine is not on the network") }, + 1, ES("Machine is not on the network") }, { BSM_ERRNO_ENOPKG, #ifdef ENOPKG ENOPKG, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Package not installed") }, + 1, ES("Package not installed") }, { BSM_ERRNO_EREMOTE, EREMOTE, - ES("Too many levels of remote in path") }, + 1, ES("Too many levels of remote in path") }, { BSM_ERRNO_ENOLINK, #ifdef ENOLINK ENOLINK, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Link has been severed") }, + 1, ES("Link has been severed") }, { BSM_ERRNO_EADV, #ifdef EADV EADV, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Advertise error") }, + 1, ES("Advertise error") }, { BSM_ERRNO_ESRMNT, #ifdef ESRMNT ESRMNT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("srmount error") }, + 1, ES("srmount error") }, { BSM_ERRNO_ECOMM, #ifdef ECOMM ECOMM, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Communication error on send") }, + 1, ES("Communication error on send") }, { BSM_ERRNO_EPROTO, #ifdef EPROTO EPROTO, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Protocol error") }, + 1, ES("Protocol error") }, { BSM_ERRNO_ELOCKUNMAPPED, #ifdef ELOCKUNMAPPED ELOCKUNMAPPED, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Locked lock was unmapped") }, + 1, ES("Locked lock was unmapped") }, { BSM_ERRNO_ENOTACTIVE, #ifdef ENOTACTIVE ENOTACTIVE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Facility is not active") }, + 1, ES("Facility is not active") }, { BSM_ERRNO_EMULTIHOP, #ifdef EMULTIHOP EMULTIHOP, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Multihop attempted") }, + 1, ES("Multihop attempted") }, { BSM_ERRNO_EBADMSG, #ifdef EBADMSG EBADMSG, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Bad message") }, - { BSM_ERRNO_ENAMETOOLONG, ENAMETOOLONG, ES("File name too long") }, + 1, ES("Bad message") }, + { BSM_ERRNO_ENAMETOOLONG, ENAMETOOLONG, 1, ES("File name too long") }, { BSM_ERRNO_EOVERFLOW, EOVERFLOW, - ES("Value too large to be stored in data type") }, + 1, ES("Value too large to be stored in data type") }, { BSM_ERRNO_ENOTUNIQ, #ifdef ENOTUNIQ ENOTUNIQ, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Given log name not unique") }, + 1, ES("Given log name not unique") }, { BSM_ERRNO_EBADFD, #ifdef EBADFD EBADFD, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Given f.d. invalid for this operation") }, + 1, ES("Given f.d. invalid for this operation") }, { BSM_ERRNO_EREMCHG, #ifdef EREMCHG EREMCHG, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Remote address changed") }, + 1, ES("Remote address changed") }, { BSM_ERRNO_ELIBACC, #ifdef ELIBACC ELIBACC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Can't access a needed shared lib") }, + 1, ES("Can't access a needed shared lib") }, { BSM_ERRNO_ELIBBAD, #ifdef ELIBBAD ELIBBAD, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Accessing a corrupted shared lib") }, + 1, ES("Accessing a corrupted shared lib") }, { BSM_ERRNO_ELIBSCN, #ifdef ELIBSCN ELIBSCN, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES(".lib section in a.out corrupted") }, + 1, ES(".lib section in a.out corrupted") }, { BSM_ERRNO_ELIBMAX, #ifdef ELIBMAX ELIBMAX, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Attempting to link in too many libs") }, + 1, ES("Attempting to link in too many libs") }, { BSM_ERRNO_ELIBEXEC, #ifdef ELIBEXEC ELIBEXEC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Attempting to exec a shared library") }, - { BSM_ERRNO_EILSEQ, EILSEQ, ES("Illegal byte sequence") }, - { BSM_ERRNO_ENOSYS, ENOSYS, ES("Function not implemented") }, - { BSM_ERRNO_ELOOP, ELOOP, ES("Too many levels of symbolic links") }, + 1, ES("Attempting to exec a shared library") }, + { BSM_ERRNO_EILSEQ, EILSEQ, 1, ES("Illegal byte sequence") }, + { BSM_ERRNO_ENOSYS, ENOSYS, 1, ES("Function not implemented") }, + { BSM_ERRNO_ELOOP, ELOOP, 1, ES("Too many levels of symbolic links") }, { BSM_ERRNO_ERESTART, #ifdef ERESTART ERESTART, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Restart syscall") }, + 1, ES("Restart syscall") }, { BSM_ERRNO_ESTRPIPE, #ifdef ESTRPIPE ESTRPIPE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("If pipe/FIFO, don't sleep in stream head") }, - { BSM_ERRNO_ENOTEMPTY, ENOTEMPTY, ES("Directory not empty") }, - { BSM_ERRNO_EUSERS, EUSERS, ES("Too many users") }, + 1, ES("If pipe/FIFO, don't sleep in stream head") }, + { BSM_ERRNO_ENOTEMPTY, ENOTEMPTY, 1, ES("Directory not empty") }, + { BSM_ERRNO_EUSERS, EUSERS, 1, ES("Too many users") }, { BSM_ERRNO_ENOTSOCK, ENOTSOCK, - ES("Socket operation on non-socket") }, + 1, ES("Socket operation on non-socket") }, { BSM_ERRNO_EDESTADDRREQ, EDESTADDRREQ, - ES("Destination address required") }, - { BSM_ERRNO_EMSGSIZE, EMSGSIZE, ES("Message too long") }, + 1, ES("Destination address required") }, + { BSM_ERRNO_EMSGSIZE, EMSGSIZE, 1, ES("Message too long") }, { BSM_ERRNO_EPROTOTYPE, EPROTOTYPE, - ES("Protocol wrong type for socket") }, - { BSM_ERRNO_ENOPROTOOPT, ENOPROTOOPT, ES("Protocol not available") }, + 1, ES("Protocol wrong type for socket") }, + { BSM_ERRNO_ENOPROTOOPT, ENOPROTOOPT, 1, ES("Protocol not available") }, { BSM_ERRNO_EPROTONOSUPPORT, EPROTONOSUPPORT, - ES("Protocol not supported") }, + 1, ES("Protocol not supported") }, { BSM_ERRNO_ESOCKTNOSUPPORT, ESOCKTNOSUPPORT, - ES("Socket type not supported") }, - { BSM_ERRNO_EOPNOTSUPP, EOPNOTSUPP, ES("Operation not supported") }, + 1, ES("Socket type not supported") }, + { BSM_ERRNO_EOPNOTSUPP, EOPNOTSUPP, 1, ES("Operation not supported") }, { BSM_ERRNO_EPFNOSUPPORT, EPFNOSUPPORT, - ES("Protocol family not supported") }, + 1, ES("Protocol family not supported") }, { BSM_ERRNO_EAFNOSUPPORT, EAFNOSUPPORT, - ES("Address family not supported by protocol family") }, - { BSM_ERRNO_EADDRINUSE, EADDRINUSE, ES("Address already in use") }, + 1, ES("Address family not supported by protocol family") }, + { BSM_ERRNO_EADDRINUSE, EADDRINUSE, 1, ES("Address already in use") }, { BSM_ERRNO_EADDRNOTAVAIL, EADDRNOTAVAIL, - ES("Can't assign requested address") }, - { BSM_ERRNO_ENETDOWN, ENETDOWN, ES("Network is down") }, + 1, ES("Can't assign requested address") }, + { BSM_ERRNO_ENETDOWN, ENETDOWN, 1, ES("Network is down") }, { BSM_ERRNO_ENETRESET, ENETRESET, - ES("Network dropped connection on reset") }, + 1, ES("Network dropped connection on reset") }, { BSM_ERRNO_ECONNABORTED, ECONNABORTED, - ES("Software caused connection abort") }, - { BSM_ERRNO_ECONNRESET, ECONNRESET, ES("Connection reset by peer") }, - { BSM_ERRNO_ENOBUFS, ENOBUFS, ES("No buffer space available") }, - { BSM_ERRNO_EISCONN, EISCONN, ES("Socket is already connected") }, - { BSM_ERRNO_ENOTCONN, ENOTCONN, ES("Socket is not connected") }, + 1, ES("Software caused connection abort") }, + { BSM_ERRNO_ECONNRESET, ECONNRESET, 1, ES("Connection reset by peer") }, + { BSM_ERRNO_ENOBUFS, ENOBUFS, 1, ES("No buffer space available") }, + { BSM_ERRNO_EISCONN, EISCONN, 1, ES("Socket is already connected") }, + { BSM_ERRNO_ENOTCONN, ENOTCONN, 1, ES("Socket is not connected") }, { BSM_ERRNO_ESHUTDOWN, ESHUTDOWN, - ES("Can't send after socket shutdown") }, + 1, ES("Can't send after socket shutdown") }, { BSM_ERRNO_ETOOMANYREFS, ETOOMANYREFS, - ES("Too many references: can't splice") }, - { BSM_ERRNO_ETIMEDOUT, ETIMEDOUT, ES("Operation timed out") }, - { BSM_ERRNO_ECONNREFUSED, ECONNREFUSED, ES("Connection refused") }, - { BSM_ERRNO_EHOSTDOWN, EHOSTDOWN, ES("Host is down") }, - { BSM_ERRNO_EHOSTUNREACH, EHOSTUNREACH, ES("No route to host") }, - { BSM_ERRNO_EALREADY, EALREADY, ES("Operation already in progress") }, + 1, ES("Too many references: can't splice") }, + { BSM_ERRNO_ETIMEDOUT, ETIMEDOUT, 1, ES("Operation timed out") }, + { BSM_ERRNO_ECONNREFUSED, ECONNREFUSED, 1, ES("Connection refused") }, + { BSM_ERRNO_EHOSTDOWN, EHOSTDOWN, 1, ES("Host is down") }, + { BSM_ERRNO_EHOSTUNREACH, EHOSTUNREACH, 1, ES("No route to host") }, + { BSM_ERRNO_EALREADY, EALREADY, 1, ES("Operation already in progress") }, { BSM_ERRNO_EINPROGRESS, EINPROGRESS, - ES("Operation now in progress") }, - { BSM_ERRNO_ESTALE, ESTALE, ES("Stale NFS file handle") }, + 1, ES("Operation now in progress") }, + { BSM_ERRNO_ESTALE, ESTALE, 1, ES("Stale NFS file handle") }, { BSM_ERRNO_EPROCLIM, #ifdef EPROCLIM EPROCLIM, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Too many processes") }, + 1, ES("Too many processes") }, { BSM_ERRNO_EBADRPC, #ifdef EBADRPC EBADRPC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("RPC struct is bad") }, + 1, ES("RPC struct is bad") }, { BSM_ERRNO_ERPCMISMATCH, #ifdef ERPCMISMATCH ERPCMISMATCH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("RPC version wrong") }, + 1, ES("RPC version wrong") }, { BSM_ERRNO_EPROGUNAVAIL, #ifdef EPROGUNAVAIL EPROGUNAVAIL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("RPC prog. not avail") }, + 1, ES("RPC prog. not avail") }, { BSM_ERRNO_EPROGMISMATCH, #ifdef EPROGMISMATCH EPROGMISMATCH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("RPC version wrong") }, + 1, ES("RPC version wrong") }, { BSM_ERRNO_EPROCUNAVAIL, #ifdef EPROCUNAVAIL EPROCUNAVAIL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Bad procedure for program") }, + 1, ES("Bad procedure for program") }, { BSM_ERRNO_EFTYPE, #ifdef EFTYPE EFTYPE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Inappropriate file type or format") }, + 1, ES("Inappropriate file type or format") }, { BSM_ERRNO_EAUTH, #ifdef EAUTH EAUTH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Authenticateion error") }, + 1, ES("Authenticateion error") }, { BSM_ERRNO_ENEEDAUTH, #ifdef ENEEDAUTH ENEEDAUTH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Need authenticator") }, + 1, ES("Need authenticator") }, { BSM_ERRNO_ENOATTR, #ifdef ENOATTR ENOATTR, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Attribute not found") }, + 1, ES("Attribute not found") }, { BSM_ERRNO_EDOOFUS, #ifdef EDOOFUS EDOOFUS, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Programming error") }, + 1, ES("Programming error") }, { BSM_ERRNO_EJUSTRETURN, #ifdef EJUSTRETURN EJUSTRETURN, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Just return") }, + 1, ES("Just return") }, { BSM_ERRNO_ENOIOCTL, #ifdef ENOIOCTL ENOIOCTL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("ioctl not handled by this layer") }, + 1, ES("ioctl not handled by this layer") }, { BSM_ERRNO_EDIRIOCTL, #ifdef EDIRIOCTL EDIRIOCTL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("do direct ioctl in GEOM") }, + 1, ES("do direct ioctl in GEOM") }, { BSM_ERRNO_EPWROFF, #ifdef EPWROFF EPWROFF, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Device power is off") }, + 1, ES("Device power is off") }, { BSM_ERRNO_EDEVERR, #ifdef EDEVERR EDEVERR, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Device error") }, + 1, ES("Device error") }, { BSM_ERRNO_EBADEXEC, #ifdef EBADEXEC EBADEXEC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Bad executable") }, + 1, ES("Bad executable") }, { BSM_ERRNO_EBADARCH, #ifdef EBADARCH EBADARCH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Bad CPU type in executable") }, + 1, ES("Bad CPU type in executable") }, { BSM_ERRNO_ESHLIBVERS, #ifdef ESHLIBVERS ESHLIBVERS, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Shared library version mismatch") }, + 1, ES("Shared library version mismatch") }, { BSM_ERRNO_EBADMACHO, #ifdef EBADMACHO EBADMACHO, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Malformed Macho file") }, + 1, ES("Malformed Macho file") }, { BSM_ERRNO_EPOLICY, #ifdef EPOLICY EPOLICY, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Operation failed by policy") }, + 1, ES("Operation failed by policy") }, { BSM_ERRNO_EDOTDOT, #ifdef EDOTDOT EDOTDOT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("RFS specific error") }, + 1, ES("RFS specific error") }, { BSM_ERRNO_EUCLEAN, #ifdef EUCLEAN EUCLEAN, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Structure needs cleaning") }, + 1, ES("Structure needs cleaning") }, { BSM_ERRNO_ENOTNAM, #ifdef ENOTNAM ENOTNAM, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Not a XENIX named type file") }, + 1, ES("Not a XENIX named type file") }, { BSM_ERRNO_ENAVAIL, #ifdef ENAVAIL ENAVAIL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("No XENIX semaphores available") }, + 1, ES("No XENIX semaphores available") }, { BSM_ERRNO_EISNAM, #ifdef EISNAM EISNAM, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Is a named type file") }, + 1, ES("Is a named type file") }, { BSM_ERRNO_EREMOTEIO, #ifdef EREMOTEIO EREMOTEIO, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Remote I/O error") }, + 1, ES("Remote I/O error") }, { BSM_ERRNO_ENOMEDIUM, #ifdef ENOMEDIUM ENOMEDIUM, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("No medium found") }, + 1, ES("No medium found") }, { BSM_ERRNO_EMEDIUMTYPE, #ifdef EMEDIUMTYPE EMEDIUMTYPE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Wrong medium type") }, + 1, ES("Wrong medium type") }, { BSM_ERRNO_ENOKEY, #ifdef ENOKEY ENOKEY, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Required key not available") }, + 1, ES("Required key not available") }, { BSM_ERRNO_EKEYEXPIRED, #ifdef EKEEXPIRED EKEYEXPIRED, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Key has expired") }, + 1, ES("Key has expired") }, { BSM_ERRNO_EKEYREVOKED, #ifdef EKEYREVOKED EKEYREVOKED, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Key has been revoked") }, + 1, ES("Key has been revoked") }, { BSM_ERRNO_EKEYREJECTED, -#ifdef EKEREJECTED +#ifdef EKEYREJECTED EKEYREJECTED, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Key was rejected by service") }, + 1, ES("Key was rejected by service") }, + { BSM_NFS_ERRNO_WFLUSH, +#ifdef NFSERR_WFLUSH + NFSERR_WFLUSH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("The server's write cache used in the WRITECACHE call got flushed to disk") }, + { BSM_NFS_ERRNO_BADHANDLE, +#ifdef NFSERR_BADHANDLE + NFSERR_BADHANDLE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("Illegal NFS filehandle") }, + { BSM_NFS_ERRNO_NOT_SYNC, +#ifdef NFSERR_NOT_SYNC + NFSERR_NOT_SYNC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("Update synchronization mismatch detected during a SETATTR operation") }, + { BSM_NFS_ERRNO_BAD_COOKIE, +#ifdef NFSERR_BAD_COOKIE + NFSERR_BAD_COOKIE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("READDIR cookie is stale") }, + { BSM_NFS_ERRNO_NOTSUPP, +#ifdef NFSERR_NOTSUPP + NFSERR_NOTSUPP, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("operation not supported") }, + { BSM_NFS_ERRNO_TOOSMALL, +#ifdef NFSERR_TOOSMALL + NFSERR_TOOSMALL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("response limit exceeded") }, + { BSM_NFS_ERRNO_SERVERFAULT, +#ifdef NFSERR_SERVERFAULT + NFSERR_SERVERFAULT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("undefined server error") }, + { BSM_NFS_ERRNO_BADTYPE, +#ifdef NFSERR_BADTYPE + NFSERR_BADTYPE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("type invalid for CREATE") }, + { BSM_NFS_ERRNO_DELAY, +#ifdef NFSERR_DELAY + NFSERR_DELAY, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("file \"busy\" - retry") }, + { BSM_NFS_ERRNO_SAME, +#ifdef NFSERR_SAME + NFSERR_SAME, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("nverify says attrs same") }, + { BSM_NFS_ERRNO_DENIED, +#ifdef NFSERR_DENIED + NFSERR_DENIED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("lock unavailable") }, + { BSM_NFS_ERRNO_EXPIRED, +#ifdef NFSERR_EXPIRED + NFSERR_EXPIRED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("lock lease expired") }, + { BSM_NFS_ERRNO_LOCKED, +#ifdef NFSERR_LOCKED + NFSERR_LOCKED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("I/O failed due to lock") }, + { BSM_NFS_ERRNO_GRACE, +#ifdef NFSERR_GRACE + NFSERR_GRACE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("in grace period") }, + { BSM_NFS_ERRNO_FHEXPIRED, +#ifdef NFSERR_FHEXPIRED + NFSERR_FHEXPIRED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("filehandle expired") }, + { BSM_NFS_ERRNO_SHAREDENIED, +#ifdef NFSERR_SHAREDENIED + NFSERR_SHAREDENIED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("share reserve denied") }, + { BSM_NFS_ERRNO_WRONGSEC, +#ifdef NFSERR_WRONGSEC + NFSERR_WRONGSEC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("wrong security flavor") }, + { BSM_NFS_ERRNO_CLIDINUSE, +#ifdef NFSERR_CLIDINUSE + NFSERR_CLIDINUSE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("clientid in use") }, + { BSM_NFS_ERRNO_RESOURCE, +#ifdef NFSERR_RESOURCE + NFSERR_RESOURCE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("resource exhaustion") }, + { BSM_NFS_ERRNO_MOVED, +#ifdef NFSERR_MOVED + NFSERR_MOVED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("filesystem relocated") }, + { BSM_NFS_ERRNO_NOFILEHANDLE, +#ifdef NFSERR_NOFILEHANDLE + NFSERR_NOFILEHANDLE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("current FH is not set") }, + { BSM_NFS_ERRNO_MINORVERMISMATCH, +#ifdef NFSERR_MINORVERMISMATCH + NFSERR_MINORVERMISMATCH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("minor vers not supp") }, + { BSM_NFS_ERRNO_STALECLIENTID, +#ifdef NFSERR_STALECLIENTID + NFSERR_STALECLIENTID, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("server has rebooted") }, + { BSM_NFS_ERRNO_STALESTATEID, +#ifdef NFSERR_STALESTATEID + NFSERR_STALESTATEID, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("server has rebooted") }, + { BSM_NFS_ERRNO_OLDSTATEID, +#ifdef NFSERR_OLDSTATEID + NFSERR_OLDSTATEID, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("state is out of sync") }, + { BSM_NFS_ERRNO_BADSTATEID, +#ifdef NFSERR_BADSTATEID + NFSERR_BADSTATEID, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("incorrect stateid") }, + { BSM_NFS_ERRNO_BADSEQID, +#ifdef NFSERR_BADSEQID + NFSERR_BADSEQID, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("request is out of seq") }, + { BSM_NFS_ERRNO_NOTSAME, +#ifdef NFSERR_NOTSAME + NFSERR_NOTSAME, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("verify - attrs not same") }, + { BSM_NFS_ERRNO_LOCKRANGE, +#ifdef NFSERR_LOCKRANGE + NFSERR_LOCKRANGE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("lock range not supported") }, + { BSM_NFS_ERRNO_SYMLINK, +#ifdef NFSERR_SYMLINK + NFSERR_SYMLINK, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("should be file/directory") }, + { BSM_NFS_ERRNO_RESTOREFH, +#ifdef NFSERR_RESTOREFH + NFSERR_RESTOREFH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("no saved filehandle") }, + { BSM_NFS_ERRNO_LEASEMOVED, +#ifdef NFSERR_LEASEMOVED + NFSERR_LEASEMOVED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("some filesystem moved") }, + { BSM_NFS_ERRNO_ATTRNOTSUPP, +#ifdef NFSERR_ATTRNOTSUPP + NFSERR_ATTRNOTSUPP, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("recommended attr not sup") }, + { BSM_NFS_ERRNO_NOGRACE, +#ifdef NFSERR_NOGRACE + NFSERR_NOGRACE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("reclaim outside of grace") }, + { BSM_NFS_ERRNO_RECLAIMBAD, +#ifdef NFSERR_RECLAIMBAD + NFSERR_RECLAIMBAD, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("reclaim error at server") }, + { BSM_NFS_ERRNO_RECLAIMCONFLICT, +#ifdef NFSERR_RECLAIMCONFLICT + NFSERR_RECLAIMCONFLICT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("conflict on reclaim") }, + { BSM_NFS_ERRNO_BADXDR, +#ifdef NFSERR_BADXDR + NFSERR_BADXDR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("XDR decode failed") }, + { BSM_NFS_ERRNO_LOCKSHELD, +#ifdef NFSERR_LOCKSHELD + NFSERR_LOCKSHELD, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("file locks held at CLOSE") }, + { BSM_NFS_ERRNO_OPENMODE, +#ifdef NFSERR_OPENMODE + NFSERR_OPENMODE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("conflict in OPEN and I/O") }, + { BSM_NFS_ERRNO_BADOWNER, +#ifdef NFSERR_BADOWNER + NFSERR_BADOWNER, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("owner translation bad") }, + { BSM_NFS_ERRNO_BADCHAR, +#ifdef NFSERR_BADCHAR + NFSERR_BADCHAR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("utf-8 char not supported") }, + { BSM_NFS_ERRNO_BADNAME, +#ifdef NFSERR_BADNAME + NFSERR_BADNAME, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("name not supported") }, + { BSM_NFS_ERRNO_BADRANGE, +#ifdef NFSERR_BADRANGE + NFSERR_BADRANGE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("lock range not supported") }, + { BSM_NFS_ERRNO_LOCKNOTSUPP, +#ifdef NFSERR_LOCKNOTSUPP + NFSERR_LOCKNOTSUPP, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("no atomic up/downgrade") }, + { BSM_NFS_ERRNO_OPILLEGAL, +#ifdef NFSERR_OPILLEGAL + NFSERR_OPILLEGAL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("undefined operation") }, + { BSM_NFS_ERRNO_DEADLOCK, +#ifdef NFSERR_DEADLOCK + NFSERR_DEADLOCK, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("file locking deadlock") }, + { BSM_NFS_ERRNO_FILEOPEN, +#ifdef NFSERR_FILEOPEN + NFSERR_FILEOPEN, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("open file blocks op") }, + { BSM_NFS_ERRNO_ADMINREVOKED, +#ifdef NFSERR_ADMINREVOKED + NFSERR_ADMINREVOKED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("lockowner state revoked") }, + { BSM_NFS_ERRNO_CBPATHDOWN, +#ifdef NFSERR_CBPATHDOWN + NFSERR_CBPATHDOWN, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("callback path down") }, }; static const int bsm_errnos_count = sizeof(bsm_errnos) / sizeof(bsm_errnos[0]); @@ -703,7 +1048,7 @@ * Conversion to the BSM errno space isn't allowed to fail; we simply map to * BSM_ERRNO_UNKNOWN and let the remote endpoint deal with it. */ -u_char +int au_errno_to_bsm(int local_errno) { const struct bsm_errno *bsme; @@ -715,7 +1060,7 @@ } static const struct bsm_errno * -bsm_lookup_errno_bsm(u_char bsm_errno) +bsm_lookup_errno_bsm(int bsm_errno) { int i; @@ -732,7 +1077,7 @@ * appropriate local mapping. */ int -au_bsm_to_errno(u_char bsm_errno, int *errorp) +au_bsm_to_errno(int bsm_errno, int *errorp) { const struct bsm_errno *bsme; @@ -745,14 +1090,14 @@ #if !defined(KERNEL) && !defined(_KERNEL) const char * -au_strerror(u_char bsm_errno) +au_strerror(int bsm_errno) { const struct bsm_errno *bsme; bsme = bsm_lookup_errno_bsm(bsm_errno); if (bsme == NULL) return ("Unrecognized BSM error"); - if (bsme->be_local_errno != ERRNO_NO_LOCAL_MAPPING) + if (bsme->be_local_errno != ERRNO_NO_LOCAL_MAPPING && bsme->be_use_strerror != 0) return (strerror(bsme->be_local_errno)); return (bsme->be_strerror); } --- //depot/vendor/freebsd/src/contrib/openbsm/libbsm/bsm_io.c 2009-07-17 14:37:30.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/libbsm/bsm_io.c 2010-08-07 16:49:25.000000000 0000 @@ -60,6 +60,7 @@ #include #include +#include #include @@ -587,12 +588,14 @@ * Prints a user value. */ static void -print_user(FILE *fp, u_int32_t usr, char raw) +print_user(FILE *fp, u_int32_t usr, char raw, char rawcred) { struct passwd *pwent; if (raw) fprintf(fp, "%d", usr); + else if (rawcred) + fprintf(fp, "%d", usr); else { pwent = getpwuid(usr); if (pwent != NULL) @@ -606,12 +609,14 @@ * Prints a group value. */ static void -print_group(FILE *fp, u_int32_t grp, char raw) +print_group(FILE *fp, u_int32_t grp, char raw, char rawcred) { struct group *grpent; if (raw) fprintf(fp, "%d", grp); + else if (rawcred) + fprintf(fp, "%d", grp); else { grpent = getgrgid(grp); if (grpent != NULL) @@ -773,10 +778,48 @@ } /* + * prints a string value for the protocol used + */ +static void +print_protocol(FILE *fp, int protocol, char raw) +{ + char *protocols[] = { + "NFSv2", + "NFSv3", + "NFSv4", + "Unknown Protocol" + }; + char *prot; + + if (raw) + fprintf(fp, "%u", protocol); + else { + switch (protocol) { + case ND_NFSV2: + prot = protocols[0]; + break; + + case ND_NFSV3: + prot = protocols[1]; + break; + + case ND_NFSV4: + prot = protocols[2]; + break; + + default: + prot = protocols[3]; + break; + } + fprintf(fp, "%s", prot); + } +} + +/* * Prints return value as success or failure. */ static void -print_retval(FILE *fp, u_char status, char raw) +print_retval(FILE *fp, int status, char raw) { int error; @@ -785,21 +828,55 @@ else { /* * Convert to a local error number and print the OS's version - * of the error string if possible. We may want to provide - * an au_strerror(3) in the future so that we can print - * strings for non-local errors. + * of the error string if possible. + * We are now using au_strerror(3) because strerror(3) may fail + * to map error codes to error messages for some security events + * such as NFS RPCs. */ if (au_bsm_to_errno(status, &error) == 0) { if (error == 0) fprintf(fp, "success"); else - fprintf(fp, "failure : %s", strerror(error)); + fprintf(fp, "failure : %s", au_strerror(status)); } else fprintf(fp, "failure: Unknown error: %d", status); } } /* + * prints a string value for a vnode type + */ +static void +print_vtype(FILE *fp, int vtype, char raw) +{ + char *vtypes[] = { + "VNON", + "VREG", + "VDIR", + "VBLK", + "VCHR", + "VLNK", + "VSOCK", + "VFIFO", + "VBAD", + "VMARKER" + }; + char *vt; + + if (raw) + fprintf(fp, "%u", vtype); + else { + if (vtype != VCHR && vtype != VBLK && vtype != VSOCK && vtype != VFIFO + && vtype != VNON && vtype != VREG && vtype != VDIR && vtype != VLNK + && vtype != VBAD && vtype != VMARKER) + vt = vtypes[VBAD]; + else + vt = vtypes[vtype]; + fprintf(fp, "%s", vt); + } +} + +/* * Prints the exit value. */ static void @@ -1645,7 +1722,7 @@ static void print_attr32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "attribute", raw, xml); @@ -1654,10 +1731,10 @@ print_4_bytes(fp, tok->tt.attr32.mode, "%o"); close_attr(fp); open_attr(fp, "uid"); - print_user(fp, tok->tt.attr32.uid, raw); + print_user(fp, tok->tt.attr32.uid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.attr32.gid, raw); + print_group(fp, tok->tt.attr32.gid, raw, rawcred); close_attr(fp); open_attr(fp, "fsid"); print_4_bytes(fp, tok->tt.attr32.fsid, "%u"); @@ -1673,9 +1750,9 @@ print_delim(fp, del); print_4_bytes(fp, tok->tt.attr32.mode, "%o"); print_delim(fp, del); - print_user(fp, tok->tt.attr32.uid, raw); + print_user(fp, tok->tt.attr32.uid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.attr32.gid, raw); + print_group(fp, tok->tt.attr32.gid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.attr32.fsid, "%u"); print_delim(fp, del); @@ -1727,7 +1804,7 @@ static void print_attr64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "attribute", raw, xml); @@ -1736,10 +1813,10 @@ print_4_bytes(fp, tok->tt.attr64.mode, "%o"); close_attr(fp); open_attr(fp, "uid"); - print_user(fp, tok->tt.attr64.uid, raw); + print_user(fp, tok->tt.attr64.uid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.attr64.gid, raw); + print_group(fp, tok->tt.attr64.gid, raw, rawcred); close_attr(fp); open_attr(fp, "fsid"); print_4_bytes(fp, tok->tt.attr64.fsid, "%u"); @@ -1755,9 +1832,9 @@ print_delim(fp, del); print_4_bytes(fp, tok->tt.attr64.mode, "%o"); print_delim(fp, del); - print_user(fp, tok->tt.attr64.uid, raw); + print_user(fp, tok->tt.attr64.uid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.attr64.gid, raw); + print_group(fp, tok->tt.attr64.gid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.attr64.fsid, "%u"); print_delim(fp, del); @@ -2010,7 +2087,7 @@ static void print_newgroups_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { int i; @@ -2018,12 +2095,12 @@ for (i = 0; i < tok->tt.grps.no; i++) { if (xml) { fprintf(fp, ""); - print_group(fp, tok->tt.grps.list[i], raw); + print_group(fp, tok->tt.grps.list[i], raw, rawcred); fprintf(fp, ""); close_tag(fp, tok->id); } else { print_delim(fp, del); - print_group(fp, tok->tt.grps.list[i], raw); + print_group(fp, tok->tt.grps.list[i], raw, rawcred); } } } @@ -2316,22 +2393,22 @@ static void print_ipcperm_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "IPC perm", raw, xml); if (xml) { open_attr(fp, "uid"); - print_user(fp, tok->tt.ipcperm.uid, raw); + print_user(fp, tok->tt.ipcperm.uid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.ipcperm.gid, raw); + print_group(fp, tok->tt.ipcperm.gid, raw, rawcred); close_attr(fp); open_attr(fp, "creator-uid"); - print_user(fp, tok->tt.ipcperm.puid, raw); + print_user(fp, tok->tt.ipcperm.puid, raw, rawcred); close_attr(fp); open_attr(fp, "creator-gid"); - print_group(fp, tok->tt.ipcperm.pgid, raw); + print_group(fp, tok->tt.ipcperm.pgid, raw, rawcred); close_attr(fp); open_attr(fp, "mode"); print_4_bytes(fp, tok->tt.ipcperm.mode, "%o"); @@ -2345,13 +2422,13 @@ close_tag(fp, tok->id); } else { print_delim(fp, del); - print_user(fp, tok->tt.ipcperm.uid, raw); + print_user(fp, tok->tt.ipcperm.uid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.ipcperm.gid, raw); + print_group(fp, tok->tt.ipcperm.gid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.ipcperm.puid, raw); + print_user(fp, tok->tt.ipcperm.puid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.ipcperm.pgid, raw); + print_group(fp, tok->tt.ipcperm.pgid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.ipcperm.mode, "%o"); print_delim(fp, del); @@ -2528,25 +2605,25 @@ static void print_process32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "process", raw, xml); if (xml) { open_attr(fp, "audit-uid"); - print_user(fp, tok->tt.proc32.auid, raw); + print_user(fp, tok->tt.proc32.auid, raw, rawcred); close_attr(fp); open_attr(fp, "uid"); - print_user(fp, tok->tt.proc32.euid, raw); + print_user(fp, tok->tt.proc32.euid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.proc32.egid, raw); + print_group(fp, tok->tt.proc32.egid, raw, rawcred); close_attr(fp); open_attr(fp, "ruid"); - print_user(fp, tok->tt.proc32.ruid, raw); + print_user(fp, tok->tt.proc32.ruid, raw, rawcred); close_attr(fp); open_attr(fp, "rgid"); - print_group(fp, tok->tt.proc32.rgid, raw); + print_group(fp, tok->tt.proc32.rgid, raw, rawcred); close_attr(fp); open_attr(fp, "pid"); print_4_bytes(fp, tok->tt.proc32.pid, "%u"); @@ -2561,15 +2638,15 @@ close_tag(fp, tok->id); } else { print_delim(fp, del); - print_user(fp, tok->tt.proc32.auid, raw); + print_user(fp, tok->tt.proc32.auid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.proc32.euid, raw); + print_user(fp, tok->tt.proc32.euid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.proc32.egid, raw); + print_group(fp, tok->tt.proc32.egid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.proc32.ruid, raw); + print_user(fp, tok->tt.proc32.ruid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.proc32.rgid, raw); + print_group(fp, tok->tt.proc32.rgid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.proc32.pid, "%u"); print_delim(fp, del); @@ -2641,24 +2718,24 @@ static void print_process64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "process", raw, xml); if (xml) { open_attr(fp, "audit-uid"); - print_user(fp, tok->tt.proc64.auid, raw); + print_user(fp, tok->tt.proc64.auid, raw, rawcred); close_attr(fp); open_attr(fp, "uid"); - print_user(fp, tok->tt.proc64.euid, raw); + print_user(fp, tok->tt.proc64.euid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.proc64.egid, raw); + print_group(fp, tok->tt.proc64.egid, raw, rawcred); close_attr(fp); open_attr(fp, "ruid"); - print_user(fp, tok->tt.proc64.ruid, raw); + print_user(fp, tok->tt.proc64.ruid, raw, rawcred); close_attr(fp); open_attr(fp, "rgid"); - print_group(fp, tok->tt.proc64.rgid, raw); + print_group(fp, tok->tt.proc64.rgid, raw, rawcred); close_attr(fp); open_attr(fp, "pid"); print_4_bytes(fp, tok->tt.proc64.pid, "%u"); @@ -2673,15 +2750,15 @@ close_tag(fp, tok->id); } else { print_delim(fp, del); - print_user(fp, tok->tt.proc64.auid, raw); + print_user(fp, tok->tt.proc64.auid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.proc64.euid, raw); + print_user(fp, tok->tt.proc64.euid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.proc64.egid, raw); + print_group(fp, tok->tt.proc64.egid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.proc64.ruid, raw); + print_user(fp, tok->tt.proc64.ruid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.proc64.rgid, raw); + print_group(fp, tok->tt.proc64.rgid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.proc64.pid, "%u"); print_delim(fp, del); @@ -2768,25 +2845,25 @@ static void print_process32ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "process_ex", raw, xml); if (xml) { open_attr(fp, "audit-uid"); - print_user(fp, tok->tt.proc32_ex.auid, raw); + print_user(fp, tok->tt.proc32_ex.auid, raw, rawcred); close_attr(fp); open_attr(fp, "uid"); - print_user(fp, tok->tt.proc32_ex.euid, raw); + print_user(fp, tok->tt.proc32_ex.euid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.proc32_ex.egid, raw); + print_group(fp, tok->tt.proc32_ex.egid, raw, rawcred); close_attr(fp); open_attr(fp, "ruid"); - print_user(fp, tok->tt.proc32_ex.ruid, raw); + print_user(fp, tok->tt.proc32_ex.ruid, raw, rawcred); close_attr(fp); open_attr(fp, "rgid"); - print_group(fp, tok->tt.proc32_ex.rgid, raw); + print_group(fp, tok->tt.proc32_ex.rgid, raw, rawcred); close_attr(fp); open_attr(fp, "pid"); print_4_bytes(fp, tok->tt.proc32_ex.pid, "%u"); @@ -2802,15 +2879,15 @@ close_tag(fp, tok->id); } else { print_delim(fp, del); - print_user(fp, tok->tt.proc32_ex.auid, raw); + print_user(fp, tok->tt.proc32_ex.auid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.proc32_ex.euid, raw); + print_user(fp, tok->tt.proc32_ex.euid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.proc32_ex.egid, raw); + print_group(fp, tok->tt.proc32_ex.egid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.proc32_ex.ruid, raw); + print_user(fp, tok->tt.proc32_ex.ruid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.proc32_ex.rgid, raw); + print_group(fp, tok->tt.proc32_ex.rgid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.proc32_ex.pid, "%u"); print_delim(fp, del); @@ -2898,24 +2975,24 @@ static void print_process64ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "process_ex", raw, xml); if (xml) { open_attr(fp, "audit-uid"); - print_user(fp, tok->tt.proc64_ex.auid, raw); + print_user(fp, tok->tt.proc64_ex.auid, raw, rawcred); close_attr(fp); open_attr(fp, "uid"); - print_user(fp, tok->tt.proc64_ex.euid, raw); + print_user(fp, tok->tt.proc64_ex.euid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.proc64_ex.egid, raw); + print_group(fp, tok->tt.proc64_ex.egid, raw, rawcred); close_attr(fp); open_attr(fp, "ruid"); - print_user(fp, tok->tt.proc64_ex.ruid, raw); + print_user(fp, tok->tt.proc64_ex.ruid, raw, rawcred); close_attr(fp); open_attr(fp, "rgid"); - print_group(fp, tok->tt.proc64_ex.rgid, raw); + print_group(fp, tok->tt.proc64_ex.rgid, raw, rawcred); close_attr(fp); open_attr(fp, "pid"); print_4_bytes(fp, tok->tt.proc64_ex.pid, "%u"); @@ -2931,15 +3008,15 @@ close_tag(fp, tok->id); } else { print_delim(fp, del); - print_user(fp, tok->tt.proc64_ex.auid, raw); + print_user(fp, tok->tt.proc64_ex.auid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.proc64_ex.euid, raw); + print_user(fp, tok->tt.proc64_ex.euid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.proc64_ex.egid, raw); + print_group(fp, tok->tt.proc64_ex.egid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.proc64_ex.ruid, raw); + print_user(fp, tok->tt.proc64_ex.ruid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.proc64_ex.rgid, raw); + print_group(fp, tok->tt.proc64_ex.rgid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.proc64_ex.pid, "%u"); print_delim(fp, del); @@ -2953,7 +3030,39 @@ } /* - * errno 1 byte + * protocol 4 bytes + */ +static int +fetch_protocol_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.prot.protocol, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_protocol_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "protocol", raw, xml); + if (xml) { + open_attr(fp, "protocol"); + print_protocol(fp, tok->tt.prot.protocol, raw); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_protocol(fp, tok->tt.prot.protocol, raw); + } +} + +/* + * errno 4 bytes * return value 4 bytes */ static int @@ -2961,7 +3070,7 @@ { int err = 0; - READ_TOKEN_U_CHAR(buf, len, tok->tt.ret32.status, tok->len, err); + READ_TOKEN_U_INT32(buf, len, tok->tt.ret32.status, tok->len, err); if (err) return (-1); @@ -2999,7 +3108,7 @@ { int err = 0; - READ_TOKEN_U_CHAR(buf, len, tok->tt.ret64.err, tok->len, err); + READ_TOKEN_U_INT32(buf, len, tok->tt.ret64.err, tok->len, err); if (err) return (-1); @@ -3362,25 +3471,25 @@ static void print_subject32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "subject", raw, xml); if (xml) { open_attr(fp, "audit-uid"); - print_user(fp, tok->tt.subj32.auid, raw); + print_user(fp, tok->tt.subj32.auid, raw, rawcred); close_attr(fp); open_attr(fp, "uid"); - print_user(fp, tok->tt.subj32.euid, raw); + print_user(fp, tok->tt.subj32.euid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.subj32.egid, raw); + print_group(fp, tok->tt.subj32.egid, raw, rawcred); close_attr(fp); open_attr(fp, "ruid"); - print_user(fp, tok->tt.subj32.ruid, raw); + print_user(fp, tok->tt.subj32.ruid, raw, rawcred); close_attr(fp); open_attr(fp, "rgid"); - print_group(fp, tok->tt.subj32.rgid, raw); + print_group(fp, tok->tt.subj32.rgid, raw, rawcred); close_attr(fp); open_attr(fp,"pid"); print_4_bytes(fp, tok->tt.subj32.pid, "%u"); @@ -3395,15 +3504,15 @@ close_tag(fp, tok->id); } else { print_delim(fp, del); - print_user(fp, tok->tt.subj32.auid, raw); + print_user(fp, tok->tt.subj32.auid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.subj32.euid, raw); + print_user(fp, tok->tt.subj32.euid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.subj32.egid, raw); + print_group(fp, tok->tt.subj32.egid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.subj32.ruid, raw); + print_user(fp, tok->tt.subj32.ruid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.subj32.rgid, raw); + print_group(fp, tok->tt.subj32.rgid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.subj32.pid, "%u"); print_delim(fp, del); @@ -3474,25 +3583,25 @@ static void print_subject64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "subject", raw, xml); if (xml) { open_attr(fp, "audit-uid"); - print_user(fp, tok->tt.subj64.auid, raw); + print_user(fp, tok->tt.subj64.auid, raw, rawcred); close_attr(fp); open_attr(fp, "uid"); - print_user(fp, tok->tt.subj64.euid, raw); + print_user(fp, tok->tt.subj64.euid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.subj64.egid, raw); + print_group(fp, tok->tt.subj64.egid, raw, rawcred); close_attr(fp); open_attr(fp, "ruid"); - print_user(fp, tok->tt.subj64.ruid, raw); + print_user(fp, tok->tt.subj64.ruid, raw, rawcred); close_attr(fp); open_attr(fp, "rgid"); - print_group(fp, tok->tt.subj64.rgid, raw); + print_group(fp, tok->tt.subj64.rgid, raw, rawcred); close_attr(fp); open_attr(fp, "pid"); print_4_bytes(fp, tok->tt.subj64.pid, "%u"); @@ -3507,15 +3616,15 @@ close_tag(fp, tok->id); } else { print_delim(fp, del); - print_user(fp, tok->tt.subj64.auid, raw); + print_user(fp, tok->tt.subj64.auid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.subj64.euid, raw); + print_user(fp, tok->tt.subj64.euid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.subj64.egid, raw); + print_group(fp, tok->tt.subj64.egid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.subj64.ruid, raw); + print_user(fp, tok->tt.subj64.ruid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.subj64.rgid, raw); + print_group(fp, tok->tt.subj64.rgid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.subj64.pid, "%u"); print_delim(fp, del); @@ -3601,25 +3710,25 @@ static void print_subject32ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "subject_ex", raw, xml); if (xml) { open_attr(fp, "audit-uid"); - print_user(fp, tok->tt.subj32_ex.auid, raw); + print_user(fp, tok->tt.subj32_ex.auid, raw, rawcred); close_attr(fp); open_attr(fp, "uid"); - print_user(fp, tok->tt.subj32_ex.euid, raw); + print_user(fp, tok->tt.subj32_ex.euid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.subj32_ex.egid, raw); + print_group(fp, tok->tt.subj32_ex.egid, raw, rawcred); close_attr(fp); open_attr(fp, "ruid"); - print_user(fp, tok->tt.subj32_ex.ruid, raw); + print_user(fp, tok->tt.subj32_ex.ruid, raw, rawcred); close_attr(fp); open_attr(fp, "rgid"); - print_group(fp, tok->tt.subj32_ex.rgid, raw); + print_group(fp, tok->tt.subj32_ex.rgid, raw, rawcred); close_attr(fp); open_attr(fp, "pid"); print_4_bytes(fp, tok->tt.subj32_ex.pid, "%u"); @@ -3635,15 +3744,15 @@ close_tag(fp, tok->id); } else { print_delim(fp, del); - print_user(fp, tok->tt.subj32_ex.auid, raw); + print_user(fp, tok->tt.subj32_ex.auid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.subj32_ex.euid, raw); + print_user(fp, tok->tt.subj32_ex.euid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.subj32_ex.egid, raw); + print_group(fp, tok->tt.subj32_ex.egid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.subj32_ex.ruid, raw); + print_user(fp, tok->tt.subj32_ex.ruid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.subj32_ex.rgid, raw); + print_group(fp, tok->tt.subj32_ex.rgid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.subj32_ex.pid, "%u"); print_delim(fp, del); @@ -3730,24 +3839,24 @@ static void print_subject64ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, - __unused char sfrm, int xml) + __unused char sfrm, int xml, char rawcred) { print_tok_type(fp, tok->id, "subject_ex", raw, xml); if (xml) { open_attr(fp, "audit-uid"); - print_user(fp, tok->tt.subj64_ex.auid, raw); + print_user(fp, tok->tt.subj64_ex.auid, raw, rawcred); close_attr(fp); open_attr(fp, "uid"); - print_user(fp, tok->tt.subj64_ex.euid, raw); + print_user(fp, tok->tt.subj64_ex.euid, raw, rawcred); close_attr(fp); open_attr(fp, "gid"); - print_group(fp, tok->tt.subj64_ex.egid, raw); + print_group(fp, tok->tt.subj64_ex.egid, raw, rawcred); close_attr(fp); open_attr(fp, "ruid"); - print_user(fp, tok->tt.subj64_ex.ruid, raw); + print_user(fp, tok->tt.subj64_ex.ruid, raw, rawcred); close_attr(fp); open_attr(fp, "rgid"); - print_group(fp, tok->tt.subj64_ex.rgid, raw); + print_group(fp, tok->tt.subj64_ex.rgid, raw, rawcred); close_attr(fp); open_attr(fp, "pid"); print_4_bytes(fp, tok->tt.subj64_ex.pid, "%u"); @@ -3763,15 +3872,15 @@ close_tag(fp, tok->id); } else { print_delim(fp, del); - print_user(fp, tok->tt.subj64_ex.auid, raw); + print_user(fp, tok->tt.subj64_ex.auid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.subj64_ex.euid, raw); + print_user(fp, tok->tt.subj64_ex.euid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.subj64_ex.egid, raw); + print_group(fp, tok->tt.subj64_ex.egid, raw, rawcred); print_delim(fp, del); - print_user(fp, tok->tt.subj64_ex.ruid, raw); + print_user(fp, tok->tt.subj64_ex.ruid, raw, rawcred); print_delim(fp, del); - print_group(fp, tok->tt.subj64_ex.rgid, raw); + print_group(fp, tok->tt.subj64_ex.rgid, raw, rawcred); print_delim(fp, del); print_4_bytes(fp, tok->tt.subj64_ex.pid, "%u"); print_delim(fp, del); @@ -3821,6 +3930,39 @@ } /* + * vtype 4 bytes + */ +static int +fetch_vtype_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.vtype.vtype, tok->len, err); + if (err) + return (-1); + + return (0); +} + + +static void +print_vtype_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "vnode type", raw, xml); + if (xml) { + open_attr(fp, "vtype"); + print_vtype(fp, tok->tt.vtype.vtype, raw); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_vtype(fp, tok->tt.vtype.vtype, raw); + } +} + +/* * socket domain 2 bytes * socket type 2 bytes * address type 2 bytes @@ -4107,6 +4249,9 @@ case AUT_PROCESS64_EX: return (fetch_process64ex_tok(tok, buf, len)); + case AUT_PROTOCOL: + return (fetch_protocol_tok(tok, buf, len)); + case AUT_RETURN32: return (fetch_return32_tok(tok, buf, len)); @@ -4143,6 +4288,9 @@ case AUT_TEXT: return (fetch_text_tok(tok, buf, len)); + case AUT_VTYPE: + return (fetch_vtype_tok(tok, buf, len)); + case AUT_SOCKET_EX: return (fetch_socketex32_tok(tok, buf, len)); @@ -4161,7 +4309,7 @@ * 'prints' the token out to outfp. */ void -au_print_tok(FILE *outfp, tokenstr_t *tok, char *del, char raw, char sfrm) +au_print_tok(FILE *outfp, tokenstr_t *tok, char *del, char raw, char sfrm, char rawcred) { switch(tok->id) { @@ -4198,11 +4346,11 @@ return; case AUT_ATTR32: - print_attr32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_attr32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_ATTR64: - print_attr64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_attr64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_EXIT: @@ -4222,7 +4370,7 @@ return; case AUT_NEWGROUPS: - print_newgroups_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_newgroups_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_IN_ADDR: @@ -4242,7 +4390,7 @@ return; case AUT_IPC_PERM: - print_ipcperm_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_ipcperm_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_IPORT: @@ -4258,19 +4406,23 @@ return; case AUT_PROCESS32: - print_process32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_process32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_PROCESS32_EX: - print_process32ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_process32ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_PROCESS64: - print_process64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_process64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_PROCESS64_EX: - print_process64ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_process64ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); + return; + + case AUT_PROTOCOL: + print_protocol_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); return; case AUT_RETURN32: @@ -4302,25 +4454,29 @@ return; case AUT_SUBJECT32: - print_subject32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_subject32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_SUBJECT64: - print_subject64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_subject64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_SUBJECT32_EX: - print_subject32ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_subject32ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_SUBJECT64_EX: - print_subject64ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + print_subject64ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN, rawcred); return; case AUT_TEXT: print_text_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); return; + case AUT_VTYPE: + print_vtype_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + case AUT_SOCKET_EX: print_socketex32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); return; @@ -4339,7 +4495,7 @@ */ void au_print_tok_xml(FILE *outfp, tokenstr_t *tok, char *del, char raw, - char sfrm) + char sfrm, char rawcred) { switch(tok->id) { @@ -4376,11 +4532,11 @@ return; case AUT_ATTR32: - print_attr32_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_attr32_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_ATTR64: - print_attr64_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_attr64_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_EXIT: @@ -4400,7 +4556,7 @@ return; case AUT_NEWGROUPS: - print_newgroups_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_newgroups_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_IN_ADDR: @@ -4420,7 +4576,7 @@ return; case AUT_IPC_PERM: - print_ipcperm_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_ipcperm_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_IPORT: @@ -4436,19 +4592,23 @@ return; case AUT_PROCESS32: - print_process32_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_process32_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_PROCESS32_EX: - print_process32ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_process32ex_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_PROCESS64: - print_process64_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_process64_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_PROCESS64_EX: - print_process64ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_process64ex_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); + return; + + case AUT_PROTOCOL: + print_protocol_tok(outfp, tok, del, raw, sfrm, AU_XML); return; case AUT_RETURN32: @@ -4476,25 +4636,29 @@ return; case AUT_SUBJECT32: - print_subject32_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_subject32_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_SUBJECT64: - print_subject64_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_subject64_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_SUBJECT32_EX: - print_subject32ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_subject32ex_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_SUBJECT64_EX: - print_subject64ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + print_subject64ex_tok(outfp, tok, del, raw, sfrm, AU_XML, rawcred); return; case AUT_TEXT: print_text_tok(outfp, tok, del, raw, sfrm, AU_XML); return; + case AUT_VTYPE: + print_vtype_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + case AUT_SOCKET_EX: print_socketex32_tok(outfp, tok, del, raw, sfrm, AU_XML); return; --- //depot/vendor/freebsd/src/contrib/openbsm/sys/bsm/audit_errno.h 2009-01-14 11:35:39.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/sys/bsm/audit_errno.h 2010-08-06 18:10:43.000000000 0000 @@ -206,9 +206,62 @@ #define BSM_ERRNO_EKEYREJECTED 222 /* Linux-specific. */ /* + * NFS specific error numbers + */ +#define BSM_NFS_ERRNO_WFLUSH 300 +#define BSM_NFS_ERRNO_BADHANDLE 301 +#define BSM_NFS_ERRNO_NOT_SYNC 302 +#define BSM_NFS_ERRNO_BAD_COOKIE 303 +#define BSM_NFS_ERRNO_NOTSUPP 304 +#define BSM_NFS_ERRNO_TOOSMALL 305 +#define BSM_NFS_ERRNO_SERVERFAULT 306 +#define BSM_NFS_ERRNO_BADTYPE 307 +#define BSM_NFS_ERRNO_DELAY 308 +#define BSM_NFS_ERRNO_SAME 309 +#define BSM_NFS_ERRNO_DENIED 310 +#define BSM_NFS_ERRNO_EXPIRED 311 +#define BSM_NFS_ERRNO_LOCKED 312 +#define BSM_NFS_ERRNO_GRACE 313 +#define BSM_NFS_ERRNO_FHEXPIRED 314 +#define BSM_NFS_ERRNO_SHAREDENIED 315 +#define BSM_NFS_ERRNO_WRONGSEC 316 +#define BSM_NFS_ERRNO_CLIDINUSE 317 +#define BSM_NFS_ERRNO_RESOURCE 318 +#define BSM_NFS_ERRNO_MOVED 319 +#define BSM_NFS_ERRNO_NOFILEHANDLE 320 +#define BSM_NFS_ERRNO_MINORVERMISMATCH 321 +#define BSM_NFS_ERRNO_STALECLIENTID 322 +#define BSM_NFS_ERRNO_STALESTATEID 323 +#define BSM_NFS_ERRNO_OLDSTATEID 324 +#define BSM_NFS_ERRNO_BADSTATEID 325 +#define BSM_NFS_ERRNO_BADSEQID 326 +#define BSM_NFS_ERRNO_NOTSAME 327 +#define BSM_NFS_ERRNO_LOCKRANGE 328 +#define BSM_NFS_ERRNO_SYMLINK 329 +#define BSM_NFS_ERRNO_RESTOREFH 330 +#define BSM_NFS_ERRNO_LEASEMOVED 331 +#define BSM_NFS_ERRNO_ATTRNOTSUPP 332 +#define BSM_NFS_ERRNO_NOGRACE 333 +#define BSM_NFS_ERRNO_RECLAIMBAD 334 +#define BSM_NFS_ERRNO_RECLAIMCONFLICT 335 +#define BSM_NFS_ERRNO_BADXDR 336 +#define BSM_NFS_ERRNO_LOCKSHELD 337 +#define BSM_NFS_ERRNO_OPENMODE 338 +#define BSM_NFS_ERRNO_BADOWNER 339 +#define BSM_NFS_ERRNO_BADCHAR 340 +#define BSM_NFS_ERRNO_BADNAME 341 +#define BSM_NFS_ERRNO_BADRANGE 342 +#define BSM_NFS_ERRNO_LOCKNOTSUPP 343 +#define BSM_NFS_ERRNO_OPILLEGAL 344 +#define BSM_NFS_ERRNO_DEADLOCK 345 +#define BSM_NFS_ERRNO_FILEOPEN 346 +#define BSM_NFS_ERRNO_ADMINREVOKED 347 +#define BSM_NFS_ERRNO_CBPATHDOWN 348 + +/* * In the event that OpenBSM doesn't have a file representation of a local * error number, use this. */ -#define BSM_ERRNO_UNKNOWN 250 /* OpenBSM-specific. */ +#define BSM_ERRNO_UNKNOWN 1000 /* OpenBSM-specific. */ #endif /* !_BSM_AUDIT_ERRNO_H_ */ --- //depot/vendor/freebsd/src/contrib/openbsm/sys/bsm/audit_record.h 2009-04-19 16:37:15.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/sys/bsm/audit_record.h 2010-08-07 16:49:25.000000000 0000 @@ -125,6 +125,10 @@ #define AUT_SOCKINET128 0x81 /* XXX */ #define AUT_SOCKUNIX 0x82 /* XXX */ +/* Yet more token identifiers */ +#define AUT_PROTOCOL 0x83 +#define AUT_VTYPE 0x84 + /* print values for the arbitrary token */ #define AUP_BINARY 0 #define AUP_OCTAL 1 @@ -170,6 +174,11 @@ #define AUT_TRAILER_MAGIC 0xb105 +/* NFS specific stuff */ +#define ND_NFSV2 0x00000004 +#define ND_NFSV3 0x00000008 +#define ND_NFSV4 0x00000010 + /* BSM library calls */ __BEGIN_DECLS @@ -284,12 +293,12 @@ * BSM library routines for converting between local and BSM constant spaces. */ int au_bsm_to_domain(u_short bsm_domain, int *local_domainp); -int au_bsm_to_errno(u_char bsm_error, int *errorp); +int au_bsm_to_errno(int bsm_error, int *errorp); int au_bsm_to_fcntl_cmd(u_short bsm_fcntl_cmd, int *local_fcntl_cmdp); int au_bsm_to_socket_type(u_short bsm_socket_type, int *local_socket_typep); u_short au_domain_to_bsm(int local_domain); -u_char au_errno_to_bsm(int local_errno); +int au_errno_to_bsm(int local_errno); u_short au_fcntl_cmd_to_bsm(int local_fcntl_command); u_short au_socket_type_to_bsm(int local_socket_type); --- //depot/vendor/freebsd/src/share/man/man9/VOP_VPTOFH.9 2010-04-14 19:35:30.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/share/man/man9/VOP_VPTOFH.9 2010-08-02 17:57:28.000000000 0000 @@ -38,7 +38,7 @@ .In sys/param.h .In sys/vnode.h .Ft int -.Fn VOP_VPTOFH "struct vnode *vp" "struct fid *fhp" +.Fn VOP_VPTOFH "struct vnode *vp" "struct fid *fhp" "struct vnode *dvp" .Sh DESCRIPTION This is used by the NFS server to create an opaque filehandle which uniquely identifies the file and which can be used by an NFS client @@ -50,10 +50,15 @@ The vnode to make a filehandle for. .It Fa fhp Return parameter for the filehandle. +.It Fa dvp +The directory vnode that contains a dirent for vp, NULL otherwise. +This is used to store a hint that will facilitate the work of +.Xr vn_fullpath_nocache 9 . .El .Sh SEE ALSO .Xr VFS 9 , .Xr VFS_FHTOVP 9 , +.Xr vn_fullpath_nocache 9 , .Xr vnode 9 .Sh AUTHORS This manual page was written by --- //depot/vendor/freebsd/src/sys/bsm/audit_errno.h 2009-01-14 10:50:16.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/bsm/audit_errno.h 2010-08-06 18:10:43.000000000 0000 @@ -207,9 +207,62 @@ #define BSM_ERRNO_EKEYREJECTED 222 /* Linux-specific. */ /* + * NFS specific error numbers + */ +#define BSM_NFS_ERRNO_WFLUSH 300 +#define BSM_NFS_ERRNO_BADHANDLE 301 +#define BSM_NFS_ERRNO_NOT_SYNC 302 +#define BSM_NFS_ERRNO_BAD_COOKIE 303 +#define BSM_NFS_ERRNO_NOTSUPP 304 +#define BSM_NFS_ERRNO_TOOSMALL 305 +#define BSM_NFS_ERRNO_SERVERFAULT 306 +#define BSM_NFS_ERRNO_BADTYPE 307 +#define BSM_NFS_ERRNO_DELAY 308 +#define BSM_NFS_ERRNO_SAME 309 +#define BSM_NFS_ERRNO_DENIED 310 +#define BSM_NFS_ERRNO_EXPIRED 311 +#define BSM_NFS_ERRNO_LOCKED 312 +#define BSM_NFS_ERRNO_GRACE 313 +#define BSM_NFS_ERRNO_FHEXPIRED 314 +#define BSM_NFS_ERRNO_SHAREDENIED 315 +#define BSM_NFS_ERRNO_WRONGSEC 316 +#define BSM_NFS_ERRNO_CLIDINUSE 317 +#define BSM_NFS_ERRNO_RESOURCE 318 +#define BSM_NFS_ERRNO_MOVED 319 +#define BSM_NFS_ERRNO_NOFILEHANDLE 320 +#define BSM_NFS_ERRNO_MINORVERMISMATCH 321 +#define BSM_NFS_ERRNO_STALECLIENTID 322 +#define BSM_NFS_ERRNO_STALESTATEID 323 +#define BSM_NFS_ERRNO_OLDSTATEID 324 +#define BSM_NFS_ERRNO_BADSTATEID 325 +#define BSM_NFS_ERRNO_BADSEQID 326 +#define BSM_NFS_ERRNO_NOTSAME 327 +#define BSM_NFS_ERRNO_LOCKRANGE 328 +#define BSM_NFS_ERRNO_SYMLINK 329 +#define BSM_NFS_ERRNO_RESTOREFH 330 +#define BSM_NFS_ERRNO_LEASEMOVED 331 +#define BSM_NFS_ERRNO_ATTRNOTSUPP 332 +#define BSM_NFS_ERRNO_NOGRACE 333 +#define BSM_NFS_ERRNO_RECLAIMBAD 334 +#define BSM_NFS_ERRNO_RECLAIMCONFLICT 335 +#define BSM_NFS_ERRNO_BADXDR 336 +#define BSM_NFS_ERRNO_LOCKSHELD 337 +#define BSM_NFS_ERRNO_OPENMODE 338 +#define BSM_NFS_ERRNO_BADOWNER 339 +#define BSM_NFS_ERRNO_BADCHAR 340 +#define BSM_NFS_ERRNO_BADNAME 341 +#define BSM_NFS_ERRNO_BADRANGE 342 +#define BSM_NFS_ERRNO_LOCKNOTSUPP 343 +#define BSM_NFS_ERRNO_OPILLEGAL 344 +#define BSM_NFS_ERRNO_DEADLOCK 345 +#define BSM_NFS_ERRNO_FILEOPEN 346 +#define BSM_NFS_ERRNO_ADMINREVOKED 347 +#define BSM_NFS_ERRNO_CBPATHDOWN 348 + +/* * In the event that OpenBSM doesn't have a file representation of a local * error number, use this. */ -#define BSM_ERRNO_UNKNOWN 250 /* OpenBSM-specific. */ +#define BSM_ERRNO_UNKNOWN 1000 /* OpenBSM-specific. */ #endif /* !_BSM_AUDIT_ERRNO_H_ */ --- //depot/vendor/freebsd/src/sys/bsm/audit_kevents.h 2009-09-29 21:30:13.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/bsm/audit_kevents.h 2010-07-08 19:00:38.000000000 0000 @@ -385,6 +385,70 @@ #define AUE_DARWIN_COPYFILE 361 /* Darwin-specific. */ /* + * NFS RPC events + */ +#define AUE_NFS_NULL 2000 +#define AUE_NFS_GETATTR 2001 +#define AUE_NFS_SETATTR 2002 +#define AUE_NFS_LOOKUP 2003 +#define AUE_NFS_ACCESS 2004 +#define AUE_NFS_READLINK 2005 +#define AUE_NFS_READ 2006 +#define AUE_NFS_WRITE 2007 +#define AUE_NFS_CREATE 2008 +#define AUE_NFS_MKDIR 2009 +#define AUE_NFS_SYMLINK 2010 +#define AUE_NFS_MKNOD 2011 +#define AUE_NFS_REMOVE 2012 +#define AUE_NFS_RMDIR 2013 +#define AUE_NFS_RENAME 2014 +#define AUE_NFS_LINK 2015 +#define AUE_NFS_READDIR 2016 +#define AUE_NFS_READDIR_PLUS 2017 +#define AUE_NFS_STATFS 2018 +#define AUE_NFS_FSINFO 2019 +#define AUE_NFS_PATHCONF 2020 +#define AUE_NFS_COMMIT 2021 +#define AUE_NFS_NOOP 2022 +/* NFSv4 specific RPC events */ +#define AUE_NFS_CLOSE 2023 +#define AUE_NFS_DELEGPURGE 2024 +#define AUE_NFS_DELEGRETURN 2025 +#define AUE_NFSv4_GETFH 2026 +#define AUE_NFS_LOCK 2027 +#define AUE_NFS_LOCKT 2028 +#define AUE_NFS_LOCKU 2029 +#define AUE_NFS_LOOKUPP 2030 +#define AUE_NFS_NVERIFY 2031 +#define AUE_NFS_OPEN 2032 +#define AUE_NFS_OPENATTR 2033 +#define AUE_NFS_OPENCONFIRM 2034 +#define AUE_NFS_OPENDOWNGRADE 2035 +#define AUE_NFS_PUTFH 2036 +#define AUE_NFS_PUTPUBFH 2037 +#define AUE_NFS_PUTROOTFH 2038 +#define AUE_NFS_RENEW 2039 +#define AUE_NFS_RESTOREFH 2040 +#define AUE_NFS_SAVEFH 2041 +#define AUE_NFS_SECINFO 2042 +#define AUE_NFS_SETCLIENTID 2043 +#define AUE_NFS_SETCLIENTIDCFRM 2044 +#define AUE_NFS_VERIFY 2045 +#define AUE_NFS_RELEASELCKOWN 2046 +#define AUE_NFS_OPEN_R 2047 +#define AUE_NFS_OPEN_RC 2048 +#define AUE_NFS_OPEN_RTC 2049 +#define AUE_NFS_OPEN_RT 2050 +#define AUE_NFS_OPEN_RW 2051 +#define AUE_NFS_OPEN_RWC 2052 +#define AUE_NFS_OPEN_RWTC 2053 +#define AUE_NFS_OPEN_RWT 2054 +#define AUE_NFS_OPEN_W 2055 +#define AUE_NFS_OPEN_WC 2056 +#define AUE_NFS_OPEN_WTC 2057 +#define AUE_NFS_OPEN_WT 2058 + +/* * Audit event identifiers added as part of OpenBSM, generally corresponding * to events in FreeBSD, Darwin, and Linux that were not present in Solaris. * These often duplicate events added to the Solaris set by Darwin, but use --- //depot/vendor/freebsd/src/sys/bsm/audit_record.h 2009-04-19 14:55:18.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/bsm/audit_record.h 2010-08-16 13:30:34.000000000 0000 @@ -126,6 +126,10 @@ #define AUT_SOCKINET128 0x81 /* XXX */ #define AUT_SOCKUNIX 0x82 /* XXX */ +/* Yet more token identifiers */ +#define AUT_PROTOCOL 0x83 +#define AUT_VTYPE 0x84 + /* print values for the arbitrary token */ #define AUP_BINARY 0 #define AUP_OCTAL 1 @@ -171,6 +175,11 @@ #define AUT_TRAILER_MAGIC 0xb105 +/* NFS specific stuff */ +#define ND_NFSV2 0x00000004 +#define ND_NFSV3 0x00000008 +#define ND_NFSV4 0x00000010 + /* BSM library calls */ __BEGIN_DECLS @@ -247,9 +256,10 @@ au_tid_addr_t *tid); token_t *au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid); -token_t *au_to_return(char status, uint32_t ret); -token_t *au_to_return32(char status, uint32_t ret); -token_t *au_to_return64(char status, uint64_t ret); +token_t *au_to_protocol(u_int32_t protocol); +token_t *au_to_return(u_int32_t status, uint32_t ret); +token_t *au_to_return32(u_int32_t status, uint32_t ret); +token_t *au_to_return64(u_int32_t status, uint64_t ret); token_t *au_to_seq(long audit_count); token_t *au_to_socket_ex(u_short so_domain, u_short so_type, struct sockaddr *sa_local, struct sockaddr *sa_remote); @@ -277,6 +287,7 @@ token_t *au_to_exec_env(char **envp); #endif token_t *au_to_text(const char *text); +token_t *au_to_vtype(u_int32_t vtype); token_t *au_to_kevent(struct kevent *kev); token_t *au_to_trailer(int rec_size); token_t *au_to_zonename(const char *zonename); @@ -285,12 +296,12 @@ * BSM library routines for converting between local and BSM constant spaces. */ int au_bsm_to_domain(u_short bsm_domain, int *local_domainp); -int au_bsm_to_errno(u_char bsm_error, int *errorp); +int au_bsm_to_errno(int bsm_error, int *errorp); int au_bsm_to_fcntl_cmd(u_short bsm_fcntl_cmd, int *local_fcntl_cmdp); int au_bsm_to_socket_type(u_short bsm_socket_type, int *local_socket_typep); u_short au_domain_to_bsm(int local_domain); -u_char au_errno_to_bsm(int local_errno); +int au_errno_to_bsm(int local_errno); u_short au_fcntl_cmd_to_bsm(int local_fcntl_command); u_short au_socket_type_to_bsm(int local_socket_type); --- //depot/vendor/freebsd/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c 2009-09-26 00:15:13.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c 2010-05-24 11:27:15.000000000 0000 @@ -1176,7 +1176,7 @@ err = zfsctl_traverse_begin(&vp, LK_SHARED | LK_RETRY); if (err == 0) - err = VOP_VPTOFH(vp, (void *)ap->a_fid); + err = VOP_VPTOFH(vp, (void *)ap->a_fid, NULL); zfsctl_traverse_end(vp, err); return (err); } --- //depot/vendor/freebsd/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c 2010-04-15 16:45:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -112,6 +112,7 @@ .vfs_sync = zfs_sync, .vfs_checkexp = zfs_checkexp, .vfs_fhtovp = zfs_fhtovp, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(zfs_vfsops, zfs, VFCF_JAIL | VFCF_DELEGADMIN); --- //depot/vendor/freebsd/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c 2010-04-15 16:45:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c 2010-08-02 17:57:28.000000000 0000 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -3771,7 +3772,7 @@ ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(zp); - gen = (uint32_t)zp->z_gen; + gen = (uint32_t)zp->z_gen; size = (zfsvfs->z_parent != zfsvfs) ? LONG_FID_LEN : SHORT_FID_LEN; fidp->fid_len = size; @@ -4454,6 +4455,7 @@ struct vop_fid_args /* { struct vnode *a_vp; struct fid *a_fid; + struct vnode *a_dvp; } */ *ap; { @@ -4963,6 +4965,169 @@ return (EOPNOTSUPP); } +/* + * XXXgpf: should relocate them someplace else + * I just dont know where:S + */ +#define PARENTHINT 0x0001 +#define EXHAUSTSEARCH 0x0002 +#define WANTNAME 0x0004 + +/* + * VOP_GETPARENT + * + * int VOP_GETPARENT(struct vnode *vp, struct vnode **dvp, uint64_t hint, + * int flags, char *buf, int *buflen); + * + * Find a parent directory -dvp- with vp as a child. The parent hint is used to + * facilitate the search. + * + * Flags should be set to: + * - PARENTHINT: if a hint ino_t of a directory is supplied to facilitate the search + * - EXHAUSTSEARCH: if we are willing to search the whole filesystem to find the directory + * - WANTNAME: if we want to copy the name used to reference the file inside the dir, to buf + * + * ZFS note: only WANTNAME & PARENTHINT are actually used in ZFS code + * + * Locks: vp should be locked on entry and will still be locked on exit. + * On success, dvp will be locked and have its reference count incremented. + * + */ +int +zfs_freebsd_getparent(struct vop_getparent_args *ap) +/* +vop_getparent { + IN struct vnode *a_vp; + OUT struct vnode **a_vpp; + IN uint64_t a_hint; + IN int a_flags; + INOUT char *a_buf; + INOUT int *a_buflen; +}; +*/ +{ + znode_t *zp; + struct mount *mp; + struct vnode *dvp; + char *dirbuf; + int error; + ino_t parent; + + KASSERT(ap->a_vp != NULL, ("VOP_GEPARENT: null vp")); + if (ap->a_flags & WANTPARENT) + KASSERT(ap->a_buf != NULL, ("VOP_GEPARENT: null buffer")); + + zp = VTOZ(ap->a_vp); + mp = ap->a_vp->v_mount; + dvp = NULL; + dirbuf = NULL; + + if (zp->z_phys == NULL) { + error = ENOENT; + goto out; + } + parent = zp->z_phys->zp_parent; +tryparent: + /* grab directory vnode that should contain this znode */ + error = VFS_VGET(mp, parent, LK_SHARED, &dvp); + if (error) { + error = ENOENT; + goto out; + } + /* scan the directory for a matching dirent */ + else { + struct uio io; + struct iovec iov; + struct dirent *dp, *edp; + struct thread *td; + u_int64_t dirbuflen; + int error, eofflag; + char foundit; + + foundit = 0; + dirbuflen = ((struct znode *)dvp->v_data)->z_blksz; + dirbuf = malloc(dirbuflen, M_TEMP, M_WAITOK); + td = curthread; + + /* prep the call to VOP_READDIR() */ + iov.iov_base = dirbuf; + iov.iov_len = dirbuflen; + io.uio_iov = &iov; + io.uio_iovcnt = 1; + io.uio_offset = 0; + io.uio_resid = dirbuflen; + io.uio_segflg = UIO_SYSSPACE; + io.uio_rw = UIO_READ; + io.uio_td = td; + eofflag = 0; + + error = VOP_READDIR(dvp, &io, td->td_ucred, &eofflag, NULL, NULL); + if (error) { + error = EIO; + goto out; + } + + /* search for the correct znode number inside the directory */ + edp = (struct dirent *)&dirbuf[dirbuflen - io.uio_resid]; + for (dp = (struct dirent *)dirbuf; dp < edp; ) { + if (dp->d_reclen > 0) { + /* found it */ + if (zp->z_id == ((struct dirent *)dp)->d_fileno) { + if (ap->a_flags & WANTNAME) { + char *pch; + int len; + + pch = ((struct dirent *)dp)->d_name; + len = strlen(pch); + + if (len >= *(ap->a_buflen)) { + error = ENOMEM; + goto out; + } + + strlcpy(ap->a_buf, ((struct dirent *)dp)->d_name, *(ap->a_buflen)); + *(ap->a_buflen) -= len + 1; + } + foundit = 1; + break; + } + dp = (struct dirent *)((char *)dp + dp->d_reclen); + } + else { + error = EIO; + break; + } + } + + if (foundit == 0 && error == 0) + error = ENOENT; + } + +out: + if (dirbuf != NULL) { + free(dirbuf, M_TEMP); + dirbuf = NULL; + } + + if (error && dvp != NULL) { + vput(dvp); + dvp = NULL; + } + + /* if an error occured and we have been supplied with a parenthint, try it out */ + if (error && (ap->a_flags & PARENTHINT) && parent != ap->a_hint) { + parent = ap->a_hint; + goto tryparent; + } + + if (error == 0 && dvp != NULL) + *(ap->a_vpp) = dvp; + else + *(ap->a_vpp) = NULL; + + return (error); +} + struct vop_vector zfs_vnodeops; struct vop_vector zfs_fifoops; @@ -5005,6 +5170,7 @@ .vop_getacl = zfs_freebsd_getacl, .vop_setacl = zfs_freebsd_setacl, .vop_aclcheck = zfs_freebsd_aclcheck, + .vop_getparent = zfs_freebsd_getparent, }; struct vop_vector zfs_fifoops = { --- //depot/vendor/freebsd/src/sys/fs/cd9660/cd9660_vfsops.c 2010-01-23 22:40:07.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/cd9660/cd9660_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -84,6 +84,7 @@ .vfs_statfs = cd9660_statfs, .vfs_unmount = cd9660_unmount, .vfs_vget = cd9660_vget, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(cd9660_vfsops, cd9660, VFCF_READONLY); MODULE_VERSION(cd9660, 1); --- //depot/vendor/freebsd/src/sys/fs/ext2fs/ext2_vfsops.c 2010-01-14 14:35:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/ext2fs/ext2_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -86,6 +86,7 @@ .vfs_sync = ext2_sync, .vfs_unmount = ext2_unmount, .vfs_vget = ext2_vget, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(ext2fs_vfsops, ext2fs, 0); --- //depot/vendor/freebsd/src/sys/fs/hpfs/hpfs_vfsops.c 2009-05-11 15:35:16.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/hpfs/hpfs_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -538,5 +538,6 @@ .vfs_statfs = hpfs_statfs, .vfs_unmount = hpfs_unmount, .vfs_vget = hpfs_vget, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(hpfs_vfsops, hpfs, 0); --- //depot/vendor/freebsd/src/sys/fs/msdosfs/msdosfs_vfsops.c 2010-04-02 15:25:18.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/msdosfs/msdosfs_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -986,6 +986,7 @@ .vfs_statfs = msdosfs_statfs, .vfs_sync = msdosfs_sync, .vfs_unmount = msdosfs_unmount, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(msdosfs_vfsops, msdosfs, 0); --- //depot/vendor/freebsd/src/sys/fs/nfs/nfs.h 2009-06-20 17:15:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfs/nfs.h 2010-07-08 19:00:38.000000000 0000 @@ -273,6 +273,10 @@ #define LCL_GSS LCL_KERBV /* Or of all mechs */ +/* flags for auditing the open RPC */ +#define NFS_CREATE 0x00000010 +#define NFS_TRUNC 0x00000020 + /* * Bits for flags in nfslock and nfsstate. * The access, deny, NFSLCK_READ and NFSLCK_WRITE bits must be defined as --- //depot/vendor/freebsd/src/sys/fs/nfs/nfs_var.h 2010-04-24 22:55:19.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfs/nfs_var.h 2010-06-25 00:45:44.000000000 0000 @@ -308,6 +308,7 @@ NFSPATHLEN_T *); void nfsd_init(void); int nfsd_checkrootexp(struct nfsrv_descript *); +void nfsrv_auditpath(vnode_t vp, vnode_t dvp, char *fname, fhandle_t *fhp, int n); /* nfs_clvfsops.c */ @@ -512,7 +513,7 @@ NFSPROC_T *); int nfsvno_setattr(vnode_t, struct nfsvattr *, struct ucred *, NFSPROC_T *, struct nfsexstuff *); -int nfsvno_getfh(vnode_t, fhandle_t *, NFSPROC_T *); +int nfsvno_getfh(vnode_t, fhandle_t *, NFSPROC_T *, vnode_t); int nfsvno_accchk(vnode_t, accmode_t, struct ucred *, struct nfsexstuff *, NFSPROC_T *, int, int, u_int32_t *); int nfsvno_namei(struct nfsrv_descript *, struct nameidata *, --- //depot/vendor/freebsd/src/sys/fs/nfsserver/nfs_nfsdkrpc.c 2009-06-17 23:00:24.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdkrpc.c 2010-07-06 21:25:27.000000000 0000 @@ -42,6 +42,7 @@ #include #include +#include #include NFSDLOCKMUTEX; @@ -108,6 +109,7 @@ struct nfsrv_descript nd; struct nfsrvcache *rp = NULL; int cacherep, credflavor; + int nfsprot; memset(&nd, 0, sizeof(nd)); if (rqst->rq_vers == NFS_VER2) { @@ -233,6 +235,12 @@ cacherep = nfs_proc(&nd, rqst->rq_xid, xprt->xp_socket, xprt->xp_sockref, &rp); } else { + nfsprot = nd.nd_flag & (ND_NFSV2 | ND_NFSV3 | ND_NFSV4); + AUDIT_NFS_ENTER(NFSPROC_NULL, nd.nd_cred, curthread, nfsprot); + AUDIT_ARG_PROTOCOL(nfsprot); + if (nd.nd_nam != NULL) + AUDIT_ARG_SOCKADDR_IN((struct sockaddr_in *)nd.nd_nam); + AUDIT_NFS_EXIT(0, curthread); NFSMGET(nd.nd_mreq); nd.nd_mreq->m_len = 0; cacherep = RC_REPLY; --- //depot/vendor/freebsd/src/sys/fs/nfsserver/nfs_nfsdport.c 2010-04-04 23:22:57.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdport.c 2010-07-08 13:04:03.000000000 0000 @@ -44,6 +44,7 @@ #include #include #include +#include extern u_int32_t newnfs_true, newnfs_false, newnfs_xdrneg1; extern int nfsv4root_set; @@ -118,13 +119,13 @@ * Get a file handle for a vnode. */ int -nfsvno_getfh(struct vnode *vp, fhandle_t *fhp, struct thread *p) +nfsvno_getfh(struct vnode *vp, fhandle_t *fhp, struct thread *p, struct vnode *dvp) { int error; NFSBZERO((caddr_t)fhp, sizeof(fhandle_t)); fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(vp, &fhp->fh_fid); + error = VOP_VPTOFH(vp, &fhp->fh_fid, dvp); return (error); } @@ -636,6 +637,7 @@ uiop->uio_resid = len; uiop->uio_rw = UIO_READ; uiop->uio_segflg = UIO_SYSSPACE; + AUDIT_ARG_FFLAGS(IO_NODELOCKED | ioflag); error = VOP_READ(vp, uiop, IO_NODELOCKED | ioflag, cred); FREE((caddr_t)iv2, M_TEMP); if (error) { @@ -701,6 +703,7 @@ uiop->uio_segflg = UIO_SYSSPACE; NFSUIOPROC(uiop, p); uiop->uio_offset = off; + AUDIT_ARG_FFLAGS(ioflags); error = VOP_WRITE(vp, uiop, ioflags, cred); FREE((caddr_t)iv, M_TEMP); return (error); @@ -721,6 +724,7 @@ if (!error && ndp->ni_vp == NULL) { if (nvap->na_type == VREG || nvap->na_type == VSOCK) { vrele(ndp->ni_startdir); + AUDIT_ARG_MODE(nvap->na_vattr.va_mode); error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); vput(ndp->ni_dvp); @@ -752,6 +756,7 @@ return (error); } nvap->na_rdev = rdev; + AUDIT_ARG_MODE(nvap->na_vattr.va_mode); error = VOP_MKNOD(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); vput(ndp->ni_dvp); @@ -767,6 +772,8 @@ return (ENXIO); } *vpp = ndp->ni_vp; + if (!error) + AUDIT_ARG_VNODE1(ndp->ni_vp); } else { /* * Handle cases where error is already set and/or @@ -826,11 +833,13 @@ vput(ndp->ni_dvp); return (NFSERR_BADTYPE); } + AUDIT_ARG_MODE(nvap->na_vattr.va_mode); if (vtyp == VSOCK) { - vrele(ndp->ni_startdir); + vrele(ndp->ni_startdir); error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); vput(ndp->ni_dvp); + nfsrv_auditpath(NULL, ndp->ni_dvp, ndp->ni_cnd.cn_pnbuf, NULL, 1); nfsvno_relpathbuf(ndp); } else { if (nvap->na_type != VFIFO && @@ -843,6 +852,7 @@ error = VOP_MKNOD(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); vput(ndp->ni_dvp); + nfsrv_auditpath(NULL, ndp->ni_dvp, ndp->ni_cnd.cn_pnbuf, NULL, 1); nfsvno_relpathbuf(ndp); if (error) vrele(ndp->ni_startdir); @@ -851,6 +861,9 @@ * see any reason to do the lookup. */ } + if (!error) + AUDIT_ARG_VNODE1(ndp->ni_vp); + return (error); } @@ -872,10 +885,13 @@ nfsvno_relpathbuf(ndp); return (EEXIST); } + AUDIT_ARG_MODE(nvap->na_vattr.va_mode); error = VOP_MKDIR(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); vput(ndp->ni_dvp); nfsvno_relpathbuf(ndp); + if (!error) + AUDIT_ARG_VNODE1(ndp->ni_vp); return (error); } @@ -888,7 +904,9 @@ struct nfsexstuff *exp) { int error = 0; - + + AUDIT_ARG_UPATH2(curthread, pathcp); + AUDIT_ARG_MODE(nvap->na_vattr.va_mode); if (ndp->ni_vp) { vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); @@ -899,19 +917,21 @@ vrele(ndp->ni_vp); return (EEXIST); } - + error = VOP_SYMLINK(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr, pathcp); vput(ndp->ni_dvp); vrele(ndp->ni_startdir); nfsvno_relpathbuf(ndp); + if (!error) + AUDIT_ARG_VNODE1(ndp->ni_vp); /* * Although FreeBSD still had the lookup code in * it for 7/current, there doesn't seem to be any * point, since VOP_SYMLINK() returns the ni_vp. * Just vput it for v2. */ - if (!not_v2 && !error) + if (!not_v2 && !error) vput(ndp->ni_vp); return (error); } @@ -1107,9 +1127,16 @@ } out: if (!error) { + /* extra verfs to make the audit code less racy */ + vref(fromndp->ni_dvp); + vref(tondp->ni_dvp); error = VOP_RENAME(fromndp->ni_dvp, fromndp->ni_vp, &fromndp->ni_cnd, tondp->ni_dvp, tondp->ni_vp, &tondp->ni_cnd); + nfsrv_auditpath(NULL, fromndp->ni_dvp, fromndp->ni_cnd.cn_pnbuf, NULL, 1); + nfsrv_auditpath(NULL, tondp->ni_dvp, tondp->ni_cnd.cn_pnbuf, NULL, 2); + vrele(fromndp->ni_dvp); + vrele(tondp->ni_dvp); } else { if (tdvp == tvp) vrele(tdvp); @@ -1154,8 +1181,9 @@ if (ndp->ni_dvp == vp) vrele(ndp->ni_dvp); else - vput(ndp->ni_dvp); + vput(ndp->ni_dvp); NFSVOPUNLOCK(vp, 0, p); + nfsrv_auditpath(NULL, ndp->ni_dvp, ndp->ni_cnd.cn_pnbuf, NULL, 1); } else { if (ndp->ni_dvp == ndp->ni_vp) vrele(ndp->ni_dvp); @@ -1292,6 +1320,7 @@ if (!nd->nd_repstat) { if (ndp->ni_vp == NULL) { vrele(ndp->ni_startdir); + AUDIT_ARG_MODE(nvap->na_vattr.va_mode); nd->nd_repstat = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr); vput(ndp->ni_dvp); @@ -1432,6 +1461,9 @@ struct uio io; struct iovec iv; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); + if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &at); return (0); @@ -1678,6 +1710,9 @@ struct iovec iv; struct componentname cn; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); + if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &at); return (0); @@ -1940,7 +1975,7 @@ if (refp == NULL && ((nd->nd_flag & ND_NFSV3) || NFSNONZERO_ATTRBIT(&attrbits))) { - r = nfsvno_getfh(nvp, &nfh, p); + r = nfsvno_getfh(nvp, &nfh, p, vp); if (!r) r = nfsvno_getattr(nvp, nvap, nd->nd_cred, p); @@ -2652,7 +2687,7 @@ nfsexargp->fspec, p); if ((error = namei(&nd)) != 0) return (error); - error = nfsvno_getfh(nd.ni_vp, &fh, p); + error = nfsvno_getfh(nd.ni_vp, &fh, p, NULL); vrele(nd.ni_vp); if (!error) { nfs_rootfh.nfsrvfh_len = NFSX_MYFH; --- //depot/vendor/freebsd/src/sys/fs/nfsserver/nfs_nfsdserv.c 2010-04-06 01:15:13.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdserv.c 2010-07-11 23:22:14.000000000 0000 @@ -53,6 +53,7 @@ extern struct timeval nfsboottime; extern int nfs_rootfhset, nfsv4root_set; #endif /* !APPLEKEXT */ +#include /* * This list defines the GSS mechanisms supported. @@ -90,12 +91,15 @@ u_int32_t testmode, nfsmode, supported = 0; accmode_t deletebit; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); if (nd->nd_repstat) { nfsrv_postopattr(nd, 1, &nva); return (0); } NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); nfsmode = fxdr_unsigned(u_int32_t, *tl); + AUDIT_ARG_FFLAGS(nfsmode); if ((nd->nd_flag & ND_NFSV4) && (nfsmode & ~(NFSACCESS_READ | NFSACCESS_LOOKUP | NFSACCESS_MODIFY | NFSACCESS_EXTEND | NFSACCESS_DELETE | @@ -173,6 +177,8 @@ struct nfsreferral *refp; nfsattrbit_t attrbits; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); if (nd->nd_repstat) return (0); if (nd->nd_flag & ND_NFSV4) { @@ -203,7 +209,7 @@ if (!nd->nd_repstat) { if (nd->nd_flag & ND_NFSV4) { if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_FILEHANDLE)) - nd->nd_repstat = nfsvno_getfh(vp, &fh, p); + nd->nd_repstat = nfsvno_getfh(vp, &fh, p, NULL); if (!nd->nd_repstat) nd->nd_repstat = nfsrv_checkgetattr(nd, vp, &nva, &attrbits, nd->nd_cred, p); @@ -236,7 +242,10 @@ nfsattrbit_t attrbits, retbits; nfsv4stateid_t stateid; NFSACL_T *aclp = NULL; - + + if (vp) + AUDIT_ARG_VNODE1(vp); + if (nd->nd_repstat) { nfsrv_wcc(nd, preat_ret, &nva2, postat_ret, &nva); return (0); @@ -379,6 +388,7 @@ if (!nd->nd_repstat) nd->nd_repstat = postat_ret; } + AUDIT_ARG_VNODE2(vp); vput(vp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); @@ -391,6 +401,7 @@ nfsrv_fillattr(nd, &nva); return (0); nfsmout: + AUDIT_ARG_VNODE1(vp); vput(vp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); @@ -438,7 +449,7 @@ } NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, LOOKUP, - LOCKLEAF | SAVESTART); + LOCKLEAF | SAVESTART | WANTPARENT); nfsvno_setpathbuf(&named, &bufp, &hashp); error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); if (error) { @@ -467,7 +478,11 @@ vrele(named.ni_startdir); nfsvno_relpathbuf(&named); vp = named.ni_vp; - nd->nd_repstat = nfsvno_getfh(vp, fhp, p); + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); + nd->nd_repstat = nfsvno_getfh(vp, fhp, p, named.ni_dvp); + if (named.ni_dvp) + vrele(named.ni_dvp); if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat) nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p); if (vpp) { @@ -510,6 +525,8 @@ int getret = 1, len; struct nfsvattr nva; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &nva); return (0); @@ -555,6 +572,8 @@ nfsv4stateid_t stateid; nfsquad_t clientid; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &nva); return (0); @@ -594,6 +613,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); stp->ls_stateid.other[2] = *tl++; off = fxdr_hyper(tl); lop->lo_first = off; @@ -710,6 +730,8 @@ nfsv4stateid_t stateid; nfsquad_t clientid; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); if (nd->nd_repstat) { nfsrv_wcc(nd, forat_ret, &forat, aftat_ret, &nva); return (0); @@ -742,6 +764,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); stp->ls_stateid.other[2] = *tl++; off = fxdr_hyper(tl); lop->lo_first = off; @@ -990,11 +1013,12 @@ &exclusive_flag, cverf, rdev, p, exp); if (!nd->nd_repstat) { - nd->nd_repstat = nfsvno_getfh(vp, &fh, p); + nd->nd_repstat = nfsvno_getfh(vp, &fh, p, named.ni_dvp); if (!nd->nd_repstat) nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p); vput(vp); + nfsrv_auditpath(vp, NULL, NULL, &fh, 1); if (!nd->nd_repstat) { tverf[0] = nva.na_atime.tv_sec; tverf[1] = nva.na_atime.tv_nsec; @@ -1062,6 +1086,7 @@ if (nd->nd_flag & ND_NFSV4) { NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); vtyp = nfsv34tov_type(*tl); + AUDIT_ARG_VTYPE(vtyp); nfs4type = fxdr_unsigned(nfstype, *tl); switch (nfs4type) { case NFLNK: @@ -1114,6 +1139,7 @@ if (nd->nd_flag & ND_NFSV3) { NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); vtyp = nfsv34tov_type(*tl); + AUDIT_ARG_VTYPE(vtyp); } error = nfsrv_sattr(nd, &nva, &attrbits, aclp, p); if (error) { @@ -1211,10 +1237,10 @@ } nd->nd_repstat = nfsvno_mknod(&named, &nva, nd->nd_cred, p); - if (!nd->nd_repstat) { + if (!nd->nd_repstat) { vp = named.ni_vp; nfsrv_fixattr(nd, vp, &nva, aclp, p, &attrbits, exp); - nd->nd_repstat = nfsvno_getfh(vp, fhp, p); + nd->nd_repstat = nfsvno_getfh(vp, fhp, p, named.ni_dvp); if ((nd->nd_flag & ND_NFSV3) && !nd->nd_repstat) nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p); @@ -1317,6 +1343,7 @@ nd->nd_repstat = nfsvno_removesub(&named, 0, nd->nd_cred, p, exp); } + nfsrv_auditpath(NULL, named.ni_dvp, named.ni_cnd.cn_pnbuf, NULL, 1); } if (!(nd->nd_flag & ND_NFSV2)) { if (dirp) { @@ -1437,7 +1464,7 @@ /* * Done parsing, now down to business. - */ + */ nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 1, exp, p, &fdirp); if (nd->nd_repstat) { if (nd->nd_flag & ND_NFSV3) { @@ -1457,6 +1484,8 @@ nfsvno_relpathbuf(&tond); return (0); } + if (fromnd.ni_vp != NULL) + AUDIT_ARG_VNODE1(fromnd.ni_vp); if (vnode_vtype(fromnd.ni_vp) == VDIR) tond.ni_cnd.cn_flags |= WILLBEDIR; nd->nd_repstat = nfsvno_namei(nd, &tond, tdp, 0, &tnes, p, &tdirp); @@ -1510,6 +1539,8 @@ char *bufp; u_long *hashp; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &at); nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft); @@ -1698,11 +1729,13 @@ if (!nd->nd_repstat && !(nd->nd_flag & ND_NFSV2)) { nfsrv_fixattr(nd, ndp->ni_vp, nvap, aclp, p, attrbitp, exp); if (nd->nd_flag & ND_NFSV3) { - nd->nd_repstat = nfsvno_getfh(ndp->ni_vp, fhp, p); + nd->nd_repstat = nfsvno_getfh(ndp->ni_vp, fhp, p, ndp->ni_dvp); if (!nd->nd_repstat) nd->nd_repstat = nfsvno_getattr(ndp->ni_vp, nvap, nd->nd_cred, p); } + else if (nd->nd_flag & ND_NFSV4) + nfsvno_getfh(ndp->ni_vp, fhp, p, ndp->ni_dvp); if (vpp) { NFSVOPUNLOCK(ndp->ni_vp, 0, p); *vpp = ndp->ni_vp; @@ -1796,7 +1829,6 @@ */ nfsrvd_mkdirsub(nd, &named, &nva, fhp, vpp, dirp, &dirfor, &diraft, &diraft_ret, NULL, NULL, p, exp); - if (nd->nd_flag & ND_NFSV3) { if (!nd->nd_repstat) { (void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 1); @@ -1833,7 +1865,7 @@ if (!nd->nd_repstat) { vp = ndp->ni_vp; nfsrv_fixattr(nd, vp, nvap, aclp, p, attrbitp, exp); - nd->nd_repstat = nfsvno_getfh(vp, fhp, p); + nd->nd_repstat = nfsvno_getfh(vp, fhp, p, ndp->ni_dvp); if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat) nd->nd_repstat = nfsvno_getattr(vp, nvap, nd->nd_cred, p); @@ -1870,6 +1902,8 @@ int error = 0, for_ret = 1, aft_ret = 1, cnt; u_int64_t off; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); if (nd->nd_repstat) { nfsrv_wcc(nd, for_ret, &bfor, aft_ret, &aft); return (0); @@ -1915,6 +1949,8 @@ struct statfs sfs; u_quad_t tval; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &at); return (0); @@ -1968,6 +2004,8 @@ int getret = 1; struct nfsvattr at; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &at); return (0); @@ -2004,6 +2042,8 @@ register_t linkmax, namemax, chownres, notrunc; struct nfsvattr at; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &at); return (0); @@ -2058,8 +2098,11 @@ nfsv4stateid_t stateid; nfsquad_t clientid; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); NFSM_DISSECT(tl, u_int32_t *, 7 * NFSX_UNSIGNED); i = fxdr_unsigned(int, *tl++); + AUDIT_ARG_LOCKTYPE(i); switch (i) { case NFSV4LOCKT_READW: flags |= NFSLCK_BLOCKING; @@ -2109,9 +2152,12 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); error = nfsrv_mtostr(nd, stp->ls_owner, stp->ls_ownerlen); if (error) goto nfsmout; + else + AUDIT_ARG_LOCKOWNER(stp->ls_owner, stp->ls_ownerlen); } else { NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID + NFSX_UNSIGNED); MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate), @@ -2132,6 +2178,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); } MALLOC(lop, struct nfslock *, sizeof (struct nfslock), M_NFSDLOCK, M_WAITOK); @@ -2231,6 +2278,8 @@ nfsquad_t clientid; u_int64_t len; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); NFSM_DISSECT(tl, u_int32_t *, 8 * NFSX_UNSIGNED); i = fxdr_unsigned(int, *(tl + 7)); if (i <= 0 || i > NFSV4_OPAQUELIMIT) { @@ -2244,6 +2293,7 @@ stp->ls_flags = NFSLCK_TEST; stp->ls_uid = nd->nd_cred->cr_uid; i = fxdr_unsigned(int, *tl++); + AUDIT_ARG_LOCKTYPE(i); switch (i) { case NFSV4LOCKT_READW: stp->ls_flags |= NFSLCK_BLOCKING; @@ -2279,9 +2329,12 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); error = nfsrv_mtostr(nd, stp->ls_owner, stp->ls_ownerlen); if (error) goto nfsmout; + else + AUDIT_ARG_LOCKOWNER(stp->ls_owner, stp->ls_ownerlen); if (!nd->nd_repstat && vnode_vtype(vp) != VREG) { if (vnode_vtype(vp) == VDIR) nd->nd_repstat = NFSERR_ISDIR; @@ -2338,6 +2391,8 @@ nfsquad_t clientid; u_int64_t len; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); NFSM_DISSECT(tl, u_int32_t *, 6 * NFSX_UNSIGNED + NFSX_STATEID); MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate), M_NFSDSTATE, M_WAITOK); @@ -2347,6 +2402,7 @@ lop->lo_flags = NFSLCK_UNLOCK; stp->ls_op = nd->nd_rp; i = fxdr_unsigned(int, *tl++); + AUDIT_ARG_LOCKTYPE(i); switch (i) { case NFSV4LOCKT_READW: stp->ls_flags |= NFSLCK_BLOCKING; @@ -2388,6 +2444,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); if (!nd->nd_repstat && vnode_vtype(vp) != VREG) { if (vnode_vtype(vp) == VDIR) nd->nd_repstat = NFSERR_ISDIR; @@ -2420,7 +2477,7 @@ */ APPLESTATIC int nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, - vnode_t dp, vnode_t *vpp, __unused fhandle_t *fhp, NFSPROC_T *p, + vnode_t dp, vnode_t *vpp, fhandle_t *fhp, NFSPROC_T *p, struct nfsexstuff *exp) { u_int32_t *tl; @@ -2439,6 +2496,7 @@ char *bufp = NULL; u_long *hashp; NFSACL_T *aclp = NULL; + int AUDIT_flags = 0; #ifdef NFS4_ACL_EXTATTR_NAME aclp = acl_alloc(M_WAITOK); @@ -2494,6 +2552,8 @@ default: nd->nd_repstat = NFSERR_INVAL; }; + AUDIT_flags = stp->ls_flags & ( NFSLCK_READACCESS | NFSLCK_WRITEACCESS + | NFSLCK_READDENY | NFSLCK_WRITEDENY); clientid.lval[0] = *tl++; clientid.lval[1] = *tl; if (nd->nd_flag & ND_IMPLIEDCLID) { @@ -2503,6 +2563,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); error = nfsrv_mtostr(nd, stp->ls_owner, stp->ls_ownerlen); if (error) { vrele(dp); @@ -2515,6 +2576,8 @@ NFSVNO_ATTRINIT(&nva); NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); create = fxdr_unsigned(int, *tl); + if (create) + AUDIT_flags |= NFS_CREATE; if (!nd->nd_repstat) nd->nd_repstat = nfsvno_getattr(dp, &dirfor, nd->nd_cred, p); if (create == NFSV4OPEN_CREATE) { @@ -2525,7 +2588,7 @@ switch (how) { case NFSCREATE_UNCHECKED: case NFSCREATE_GUARDED: - error = nfsv4_sattr(nd, &nva, &attrbits, aclp, p); + error = nfsv4_sattr(nd, &nva, &attrbits, aclp, p); if (error) { vrele(dp); #ifdef NFS4_ACL_EXTATTR_NAME @@ -2648,6 +2711,9 @@ nva.na_mode = 0; }; } + /* XXXgpf: not sure this means that we are to truncate the file */ + if (NFSVNO_ISSETSIZE(&nva) && nva.na_size == 0) + AUDIT_flags |= NFS_TRUNC; nfsvno_open(nd, &named, clientid, &stateid, stp, &exclusive_flag, &nva, cverf, create, aclp, &attrbits, nd->nd_cred, p, exp, &vp); @@ -2685,6 +2751,7 @@ FREE((caddr_t)stp, M_NFSDSTATE); return (0); } + AUDIT_ARG_FFLAGS(AUDIT_flags); /* * Do basic access checking. @@ -2731,8 +2798,10 @@ * below, to avoid a deadlock with the lookup in nfsvno_namei() above. * (ie: Leave the NFSVOPUNLOCK() about here.) */ - if (vp) + if (vp) { + AUDIT_ARG_VNODE1(vp); NFSVOPUNLOCK(vp, 0, p); + } if (stp) FREE((caddr_t)stp, M_NFSDSTATE); if (!nd->nd_repstat && dirp) @@ -2793,6 +2862,7 @@ (void) nfsm_strtom(nd, "OWNER@", 6); } *vpp = vp; + nfsvno_getfh(vp, fhp, p, dp); } else if (vp) { vrele(vp); } @@ -2824,7 +2894,9 @@ int error = 0; nfsv4stateid_t stateid; nfsquad_t clientid; - + + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_STATEID); stp->ls_seq = fxdr_unsigned(u_int32_t, *tl++); stp->ls_ownerlen = 0; @@ -2843,6 +2915,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); nd->nd_repstat = nfsrv_openupdate(vp, stp, clientid, &stateid, nd, p); vput(vp); if (!nd->nd_repstat) { @@ -2882,6 +2955,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); nd->nd_repstat = nfsrv_delegupdate(clientid, NULL, NULL, NFSV4OP_DELEGPURGE, nd->nd_cred, p); nfsmout: @@ -2900,6 +2974,8 @@ nfsv4stateid_t stateid; nfsquad_t clientid; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID); stateid.seqid = fxdr_unsigned(u_int32_t, *tl++); NFSBCOPY((caddr_t)tl, (caddr_t)stateid.other, NFSX_STATEIDOTHER); @@ -2912,6 +2988,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); nd->nd_repstat = nfsrv_delegupdate(clientid, &stateid, vp, NFSV4OP_DELEGRETURN, nd->nd_cred, p); nfsmout: @@ -2928,7 +3005,7 @@ { fhandle_t fh; - nd->nd_repstat = nfsvno_getfh(vp, &fh, p); + nd->nd_repstat = nfsvno_getfh(vp, &fh, p, NULL); vput(vp); if (!nd->nd_repstat) (void) nfsm_fhtom(nd, (u_int8_t *)&fh, 0, 0); @@ -2948,6 +3025,8 @@ nfsv4stateid_t stateid; nfsquad_t clientid; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID + NFSX_UNSIGNED); stp->ls_ownerlen = 0; stp->ls_op = nd->nd_rp; @@ -2967,6 +3046,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); nd->nd_repstat = nfsrv_openupdate(vp, stp, clientid, &stateid, nd, p); if (!nd->nd_repstat) { NFSM_BUILD(tl, u_int32_t *, NFSX_STATEID); @@ -2992,6 +3072,8 @@ nfsv4stateid_t stateid; nfsquad_t clientid; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID + 3 * NFSX_UNSIGNED); stp->ls_ownerlen = 0; stp->ls_op = nd->nd_rp; @@ -3042,6 +3124,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); if (!nd->nd_repstat) nd->nd_repstat = nfsrv_openupdate(vp, stp, clientid, &stateid, nd, p); @@ -3081,6 +3164,7 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); nd->nd_repstat = nfsrv_getclient(clientid, (CLOPS_RENEWOP|CLOPS_RENEW), NULL, (nfsquad_t)((u_quad_t)0), nd, p); nfsmout: @@ -3132,7 +3216,7 @@ nfsvno_relpathbuf(&named); fh.nfsrvfh_len = NFSX_MYFH; vp = named.ni_vp; - nd->nd_repstat = nfsvno_getfh(vp, (fhandle_t *)fh.nfsrvfh_data, p); + nd->nd_repstat = nfsvno_getfh(vp, (fhandle_t *)fh.nfsrvfh_data, p, NULL); mp = vnode_mount(vp); /* so it won't try to re-lock filesys */ retnes.nes_vfslocked = exp->nes_vfslocked; vput(vp); @@ -3247,6 +3331,7 @@ clp->lc_namelen = nd->nd_princlen; clp->lc_name = &clp->lc_id[idlen]; NFSBCOPY(nd->nd_principal, clp->lc_name, clp->lc_namelen); + AUDIT_ARG_CLIENTNAME(clp->lc_name, clp->lc_namelen); } else { clp->lc_uid = nd->nd_cred->cr_uid; clp->lc_gid = nd->nd_cred->cr_gid; @@ -3267,6 +3352,7 @@ * so it should be free'd. */ nd->nd_repstat = nfsrv_setclient(nd, &clp, &clientid, &confirm, p); + AUDIT_ARG_CLIENTID(clientid.qval); if (nd->nd_repstat == NFSERR_CLIDINUSE) { if (clp->lc_flags & LCL_TCPCALLBACK) (void) nfsm_strtom(nd, "tcp", 3); @@ -3324,7 +3410,7 @@ clientid.lval[1] = *tl++; confirm.lval[0] = *tl++; confirm.lval[1] = *tl; - + AUDIT_ARG_CLIENTID(clientid.qval); /* * nfsrv_getclient() searches the client list for a match and * returns the appropriate NFSERR status. @@ -3348,11 +3434,13 @@ struct nfsfsinfo fs; fhandle_t fh; + if (vp != NULL) + AUDIT_ARG_VNODE1(vp); nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p); if (!nd->nd_repstat) nd->nd_repstat = nfsvno_statfs(vp, &sf); if (!nd->nd_repstat) - nd->nd_repstat = nfsvno_getfh(vp, &fh, p); + nd->nd_repstat = nfsvno_getfh(vp, &fh, p, NULL); if (!nd->nd_repstat) { nfsvno_getfs(&fs, isdgram); error = nfsv4_loadattr(nd, vp, &nva, NULL, &fh, fhsize, NULL, @@ -3428,9 +3516,12 @@ nd->nd_flag |= ND_IMPLIEDCLID; nd->nd_clientid.qval = clientid.qval; } + AUDIT_ARG_CLIENTID(clientid.qval); error = nfsrv_mtostr(nd, stp->ls_owner, len); if (error) goto nfsmout; + else + AUDIT_ARG_LOCKOWNER(stp->ls_owner, len); nd->nd_repstat = nfsrv_releaselckown(stp, clientid, p); FREE((caddr_t)stp, M_NFSDSTATE); return (0); --- //depot/vendor/freebsd/src/sys/fs/nfsserver/nfs_nfsdsocket.c 2009-05-26 01:20:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdsocket.c 2010-07-11 16:53:25.000000000 0000 @@ -268,6 +268,8 @@ }; #endif /* !APPLEKEXT */ +#include + /* * Static array that defines which nfs rpc's are nonidempotent */ @@ -356,9 +358,11 @@ { int error = 0; vnode_t vp; + vnode_t AUDIT_vp; mount_t mp = NULL; struct nfsrvfh fh; struct nfsexstuff nes; + int nfsprot; /* * Get a locked vnode for the first file handle @@ -427,21 +431,52 @@ * The procedures are in three groups with different arguments. * The group is indicated by the value in nfs_retfh[]. */ - if (nd->nd_flag & ND_NFSV4) { + if (nd->nd_flag & ND_NFSV4) nfsrvd_compound(nd, isdgram, p); - } else { + else { + nfsprot = nd->nd_flag & (ND_NFSV2 | ND_NFSV3); + AUDIT_NFS_ENTER(nd->nd_procnum, nd->nd_cred, curthread, nfsprot); + if (nd->nd_nam != NULL) + AUDIT_ARG_SOCKADDR_IN((struct sockaddr_in *)nd->nd_nam); + AUDIT_ARG_PROTOCOL(nfsprot); if (nfs_retfh[nd->nd_procnum] == 1) { if (vp) NFSVOPUNLOCK(vp, 0, p); + AUDIT_vp = NULL; error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram, - vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes); + vp, &AUDIT_vp, (fhandle_t *)fh.nfsrvfh_data, p, &nes); + if (AUDIT_vp != NULL) { + if (nd->nd_procnum != NFSPROC_MKNOD) + nfsrv_auditpath(AUDIT_vp, NULL, NULL, + (fhandle_t *)fh.nfsrvfh_data, 1); + vrele(AUDIT_vp); + } } else if (nfs_retfh[nd->nd_procnum] == 2) { + if (vp != NULL) + vref(vp); error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram, vp, NULL, p, &nes, NULL); + if (vp != NULL) { + if (nd->nd_procnum == NFSPROC_LINK) + nfsrv_auditpath(vp, NULL, NULL, + (fhandle_t *)fh.nfsrvfh_data, 2); + vrele(vp); + } } else { + if (vp != NULL) + vref(vp); error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram, vp, p, &nes); + if (vp != NULL) { + if (nd->nd_procnum != NFSPROC_CREATE && + nd->nd_procnum != NFSPROC_RMDIR && + nd->nd_procnum != NFSPROC_REMOVE) + nfsrv_auditpath(vp, NULL, NULL, + (fhandle_t *)fh.nfsrvfh_data, 1); + vrele(vp); + } } + AUDIT_NFS_EXIT(nd->nd_repstat, curthread); if (mp) { if (nfs_writerpc[nd->nd_procnum]) NFS_ENDWRITE(mp); @@ -494,7 +529,7 @@ u_int32_t minorvers, retops = 0, *retopsp = NULL, *repp; u_char tag[NFSV4_SMALLSTR + 1], *tagstr; vnode_t vp, nvp, savevp; - struct nfsrvfh fh; + struct nfsrvfh fh, savefh; mount_t mp, savemp; struct ucred *credanon; struct nfsexstuff nes, vpnes, savevpnes; @@ -697,12 +732,18 @@ } if (nfsv4_opflag[op].savereply) nd->nd_flag |= ND_SAVEREPLY; - NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]); + NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]); + AUDIT_NFS_ENTER(op, nd->nd_cred, curthread, ND_NFSV4); + if (nd->nd_nam != NULL) + AUDIT_ARG_SOCKADDR_IN((struct sockaddr_in *)nd->nd_nam); + AUDIT_ARG_PROTOCOL(ND_NFSV4); switch (op) { case NFSV4OP_PUTFH: error = nfsrv_mtofh(nd, &fh); - if (error) + if (error) { + printf("error! %p\n", curthread); goto nfsmout; + } if (!nd->nd_repstat) { nes.nes_vfslocked = vpnes.nes_vfslocked; nfsd_fhtovp(nd, &fh, &nvp, &nes, &mp, @@ -713,7 +754,12 @@ if (vp) vrele(vp); vp = nvp; + vref(vp); + AUDIT_ARG_VNODE1(vp); NFSVOPUNLOCK(vp, 0, p); + nfsrv_auditpath(vp, NULL, NULL, + (fhandle_t *)fh.nfsrvfh_data, 1); + vrele(vp); vpnes = nes; } break; @@ -729,8 +775,14 @@ if (vp) vrele(vp); vp = nvp; + vref(vp); + AUDIT_ARG_VNODE1(vp); NFSVOPUNLOCK(vp, 0, p); + nfsrv_auditpath(vp, NULL, NULL, + (fhandle_t *)nfs_pubfh.nfsrvfh_data, 1); + vrele(vp); vpnes = nes; + NFSBCOPY(&nfs_pubfh, &fh, sizeof(fh)); } break; case NFSV4OP_PUTROOTFH: @@ -742,8 +794,14 @@ if (vp) vrele(vp); vp = nvp; + vref(vp); + AUDIT_ARG_VNODE1(vp); NFSVOPUNLOCK(vp, 0, p); + nfsrv_auditpath(vp, NULL, NULL, + (fhandle_t *)nfs_rootfh.nfsrvfh_data, 1); + vrele(vp); vpnes = nes; + NFSBCOPY(&nfs_rootfh, &fh, sizeof(fh)); } } else if (nfsv4root_vp && nfsv4root_set) { if (vp) { @@ -756,6 +814,7 @@ NFSVNO_SETEXRDONLY(&vpnes); vpnes.nes_vfslocked = 0; mp = vnode_mount(vp); + NFSBCOPY(&nfs_rootfh, &fh, sizeof(fh)); } else { nd->nd_repstat = NFSERR_NOFILEHANDLE; } @@ -771,7 +830,15 @@ savevp = vp; savevpnes = vpnes; savemp = mp; + NFSBCOPY(&fh, &savefh, sizeof(fh)); } + if (savevp) { + nfsrv_auditpath(savevp, NULL, NULL, + (fhandle_t *)fh.nfsrvfh_data, 1); + vn_lock(savevp, LK_EXCLUSIVE); + AUDIT_ARG_VNODE1(savevp); + VOP_UNLOCK(savevp, 0); + } } else { nd->nd_repstat = NFSERR_NOFILEHANDLE; } @@ -779,6 +846,13 @@ case NFSV4OP_RESTOREFH: if (savevp) { nd->nd_repstat = 0; + vref(savevp); + nfsrv_auditpath(savevp, NULL, NULL, + (fhandle_t *)savefh.nfsrvfh_data, 1); + vn_lock(savevp, LK_EXCLUSIVE); + AUDIT_ARG_VNODE1(savevp); + VOP_UNLOCK(savevp, 0); + vrele(savevp); /* If vp == savevp, a no-op */ if (vp != savevp) { VREF(savevp); @@ -799,11 +873,28 @@ vp = savevp; vpnes = savevpnes; mp = savemp; + NFSBCOPY(&savefh, &fh, sizeof(fh)); } } else { nd->nd_repstat = NFSERR_RESTOREFH; } break; + /* + * XXXgpf: + * NFSV4OP_GETFH hack so that current filehandle, with the hint stored inside, + * is returned instead of recomputing the filehandle and losing the hint. + * All NFS v4 OPs that are supposed to replace the current filehandle, now do so: + * putroofh, putpubfh, open, mknod, lookup, lookupp, putfh + */ + case NFSV4OP_GETFH: + if (vp == NULL) + error = nd->nd_repstat = NFSERR_NOFILEHANDLE; + else { + (void) nfsm_fhtom(nd, (u_int8_t *)fh.nfsrvfh_data, 0, 0); + error = nd->nd_repstat = 0; + nfsrv_auditpath(vp, NULL, NULL, (fhandle_t *)fh.nfsrvfh_data, 1); + } + break; default: /* * Allow a Lookup, Getattr, GetFH, Secinfo on an @@ -851,6 +942,8 @@ NFS_STARTWRITE(NULL, &mp); error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp, &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes); + nfsrv_auditpath(nvp, NULL, NULL, + (fhandle_t *)fh.nfsrvfh_data, 1); if (!error && !nd->nd_repstat) { if (vfs_statfs(mp)->f_fsid.val[0] != vfs_statfs(vnode_mount(nvp))->f_fsid.val[0] || @@ -904,8 +997,16 @@ if (nfsv4_opflag[op].modifyfs) NFS_STARTWRITE(NULL, &mp); NFSVOPLOCK(savevp, LK_EXCLUSIVE | LK_RETRY, p); + if (savevp) + vref(savevp); error = (*(nfsrv4_ops2[op]))(nd, isdgram, savevp, vp, p, &savevpnes, &vpnes); + if (savevp) { + if (nd->nd_procnum == NFSV4OP_LINK) + nfsrv_auditpath(savevp, NULL, NULL, + (fhandle_t *)savefh.nfsrvfh_data, 2); + vrele(savevp); + } if (nfsv4_opflag[op].modifyfs) NFS_ENDWRITE(mp); } else { @@ -930,8 +1031,16 @@ } break; } + if (vp != NULL) + vref(vp); error = (*(nfsrv4_ops0[op]))(nd, isdgram, vp, - p, &vpnes); + p, &vpnes); + if (vp != NULL) { + if (nd->nd_procnum != NFSV4OP_REMOVE) + nfsrv_auditpath(vp, NULL, NULL, + (fhandle_t *)fh.nfsrvfh_data, 1); + vrele(vp); + } if (nfsv4_opflag[op].modifyfs) NFS_ENDWRITE(mp); } else { @@ -939,7 +1048,7 @@ NULL, p, &vpnes); } } - }; + }; if (error) { if (error == EBADRPC || error == NFSERR_BADXDR) { nd->nd_repstat = NFSERR_BADXDR; @@ -949,6 +1058,7 @@ } error = 0; } + AUDIT_NFS_EXIT(nd->nd_repstat, curthread); retops++; if (nd->nd_repstat) { *repp = nfsd_errmap(nd); @@ -958,6 +1068,8 @@ } } nfsmout: + /* XXXgpf: when error occurs, we may jump here */ + AUDIT_NFS_EXIT(nd->nd_repstat, curthread); if (error) { if (error == EBADRPC || error == NFSERR_BADXDR) nd->nd_repstat = NFSERR_BADXDR; --- //depot/vendor/freebsd/src/sys/fs/nfsserver/nfs_nfsdstate.c 2010-04-24 22:55:19.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdstate.c 2010-06-04 22:15:06.000000000 0000 @@ -2974,7 +2974,7 @@ * Do a sanity check against the file handle for DelegReturn. */ if (vp) { - error = nfsvno_getfh(vp, &fh, p); + error = nfsvno_getfh(vp, &fh, p, NULL); if (error) return (error); } @@ -3112,7 +3112,7 @@ } else { panic("nfsrv_getlockfh"); } - error = nfsvno_getfh(vp, fhp, p); + error = nfsvno_getfh(vp, fhp, p, NULL); return (error); } --- //depot/vendor/freebsd/src/sys/fs/nfsserver/nfs_nfsdsubs.c 2009-05-14 21:40:15.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nfsserver/nfs_nfsdsubs.c 2010-07-18 17:26:56.000000000 0000 @@ -41,6 +41,7 @@ * copy data between mbuf chains and uio lists. */ #include +#include extern u_int32_t newnfs_true, newnfs_false; extern int nfs_pubfhset; @@ -2041,3 +2042,116 @@ return (1); } + +/* + * XXXgpf: should relocate them someplace else + * I just dont know where:S + */ +#define PARENTHINT 0x0001 +#define EXHAUSTSEARCH 0x0002 +#define WANTNAME 0x0004 + +/* + * XXXgpf: dont know if this is the right location for the function + * + * Do our best to acquire 'a' working path for vp + * + * vp - vnode in question + * dvp - directory with vp as a child + * fname - name used to reference vp inside dvp + * fhp - file handle for vp + * n - AUDIT_ARG_UPATH1 or AUDIT_ARG_UPATH2 + * + * Note: vp and dvp may be vref'd but not locks should be held on them as the + * two vn_fullpath_* KPIs may try to lock them themselves. + */ +void +nfsrv_auditpath(vnode_t vp, vnode_t dvp, char *fname, fhandle_t *fhp, int n) +{ + char path[PATH_MAX]; + struct thread *td; + char *fullpath, *freepath; + int flag; + char success; + + if (!AUDITING_TD(curthread)) + return; + + td = curthread; + freepath = NULL; + flag = WANTNAME; + success = 0; + + /* try to find the path through vp */ + if (vp != NULL) { + /* try the cache */ + vn_fullpath_global(td, vp, &fullpath, &freepath); + if (freepath != NULL) { + success = 1; + goto out; + } + + /* if our cache fails us */ + if (vp->v_mount != NULL) { + uint64_t parent_hint; + /* get the hint stored inside the file handle */ + if (fhp != NULL) + if (VFS_FHHINT(vp->v_mount, &fhp->fh_fid, &parent_hint) == 0) + flag = PARENTHINT | WANTNAME; + vn_fullpath_nocache(vp, &fullpath, &freepath, + parent_hint, flag); + if (freepath != NULL) { + success = 1; + goto out; + } + } + } + + /* try to find the path through dvp and the component name used to reference vp */ + if (dvp != NULL && fname != NULL) { + /* try the cache */ + vn_fullpath_global(td, dvp, &fullpath, &freepath); + if (freepath != NULL) { + snprintf(path, sizeof(path), "%s/%s", fullpath, fname); + fullpath = path; + success = 1; + goto out; + } + + /* if our cache fails us */ + vn_fullpath_nocache(dvp, &fullpath, &freepath, + 0, WANTNAME); + if (freepath != NULL) { + snprintf(path, sizeof(path), "%s/%s", fullpath, fname); + fullpath = path; + success = 1; + goto out; + } + } + + /* last resort, just save the name used to reference the file in question */ + if (fname != NULL) { + strlcpy(path, fname, sizeof(path)); + fullpath = path; + success = 1; + } + +out: + if (success) { + switch (n) { + case 1: + AUDIT_ARG_UPATH1(td, fullpath); + break; + case 2: + AUDIT_ARG_UPATH2(td, fullpath); + break; + default: + AUDIT_ARG_UPATH1(td, fullpath); + break; + } + } + + if (freepath != NULL) { + free(freepath, M_TEMP); + } +} --- //depot/vendor/freebsd/src/sys/fs/ntfs/ntfs_vfsops.c 2009-12-07 15:20:16.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/ntfs/ntfs_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -787,6 +787,7 @@ .vfs_uninit = ntfs_uninit, .vfs_unmount = ntfs_unmount, .vfs_vget = ntfs_vget, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(ntfs_vfsops, ntfs, 0); MODULE_VERSION(ntfs, 1); --- //depot/vendor/freebsd/src/sys/fs/nullfs/null_vfsops.c 2009-05-11 15:35:16.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nullfs/null_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -359,6 +359,7 @@ .vfs_uninit = nullfs_uninit, .vfs_unmount = nullfs_unmount, .vfs_vget = nullfs_vget, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(null_vfsops, nullfs, VFCF_LOOPBACK); --- //depot/vendor/freebsd/src/sys/fs/nullfs/null_vnops.c 2009-06-21 19:25:13.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/nullfs/null_vnops.c 2010-05-24 11:27:15.000000000 0000 @@ -738,7 +738,7 @@ struct vnode *lvp; lvp = NULLVPTOLOWERVP(ap->a_vp); - return VOP_VPTOFH(lvp, ap->a_fhp); + return VOP_VPTOFH(lvp, ap->a_fhp, NULL); } static int --- //depot/vendor/freebsd/src/sys/fs/tmpfs/tmpfs_vfsops.c 2010-01-29 12:15:19.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/tmpfs/tmpfs_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -414,5 +414,6 @@ .vfs_root = tmpfs_root, .vfs_statfs = tmpfs_statfs, .vfs_fhtovp = tmpfs_fhtovp, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(tmpfs_vfsops, tmpfs, 0); --- //depot/vendor/freebsd/src/sys/fs/udf/udf_vfsops.c 2009-05-11 15:35:16.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/udf/udf_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -129,6 +129,7 @@ .vfs_uninit = udf_uninit, .vfs_unmount = udf_unmount, .vfs_vget = udf_vget, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(udf_vfsops, udf, VFCF_READONLY); --- //depot/vendor/freebsd/src/sys/fs/unionfs/union_vfsops.c 2009-05-11 15:35:16.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/fs/unionfs/union_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -519,6 +519,7 @@ .vfs_uninit = unionfs_uninit, .vfs_unmount = unionfs_unmount, .vfs_vget = unionfs_vget, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(unionfs_vfsops, unionfs, VFCF_LOOPBACK); --- //depot/vendor/freebsd/src/sys/gnu/fs/reiserfs/reiserfs_vfsops.c 2009-12-03 18:20:15.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/gnu/fs/reiserfs/reiserfs_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -1114,6 +1114,7 @@ //.vfs_checkexp = reiserfs_checkexp, //.vfs_extattrctl = reiserfs_extattrctl, .vfs_fhtovp = reiserfs_fhtovp, + .vfs_fhhint = vfs_stdfhhint, //.vfs_quotactl = reiserfs_quotactl, .vfs_root = reiserfs_root, //.vfs_start = reiserfs_start, --- //depot/vendor/freebsd/src/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c 2009-05-11 15:35:16.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c 2010-05-27 14:41:11.000000000 0000 @@ -419,6 +419,7 @@ .vfs_init = _xfs_init, .vfs_uninit = _xfs_uninit, .vfs_extattrctl = _xfs_extattrctl, + .vfs_fhhint = vfs_stdfhhint, }; VFS_SET(xfs_fsops, xfs, 0); --- //depot/vendor/freebsd/src/sys/kern/vfs_cache.c 2010-04-20 10:30:25.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/kern/vfs_cache.c 2010-07-18 17:26:56.000000000 0000 @@ -1226,3 +1226,179 @@ buf[l] = '\0'; return (0); } + +/* + * XXXgpf: should relocate them someplace else + * I just dont know where:S + */ +#define PARENTHINT 0x0001 +#define EXHAUSTSEARCH 0x0002 +#define WANTNAME 0x0004 + +/* + * vn_fullpath_nocache(9) + * + * Retrieve the full filesystem path that corresponds to a vnode without use of the + * name cache. + * - A directory hint (UFS file_id of the directory that contains the vnode) may be + * supplied to facilitate the search if our target is not a directory itself. + * - flags should be set to PARENT_HINT, if the directory hint is supplied + * and to EXHAUSTIVE_SEARCH, if we are willing to search the entire filesystem to acquire a path. + * + * Locks: no locks required. + * + * Authors Note: freepath should be set to NULL before calling this KPI. Upon returning from the KPI, + * the caller should check if freepath is non-NULL, and if so, invoke free(9) with a pool type of M_TEMP. + */ +int +vn_fullpath_nocache(struct vnode *vp, char **fullpath, char **freepath, uint64_t directory_hint, char flags) +{ + char fname[MNAMELEN]; + struct vnode *dvp, *upper_dvp; + struct mount *mp; + struct thread * td; + char *buf, *pch; + int error, buflen, vfslocked, fnamelen; + + KASSERT(vp != NULL, ("vn_fullpath_nocache: null vp")); + + dvp = NULL; + buf = NULL; + *freepath = NULL; + VREF(vp); + /* doesn't really make sense to continue without this flag set */ + flags |= WANTNAME; + + /* XXXgpf: do we really need this? */ + if (vp->v_type == VBAD) { + error = ENOENT; + goto out; + } + error = 0; + td = curthread; + mp = vp->v_mount; + fnamelen = sizeof(fname); + buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); + buflen = MAXPATHLEN - 1; + buf[MAXPATHLEN-1] = '\0'; + + /* + * - If our target is a directory, move on to the part where we traverse the '..' entries. + * - If not, try to find its' parent through VOP_GETPARENT + */ + if (vp->v_type != VDIR) { + /* + * XXXgpf: perhaps locking vp is redundant. + * On the other hand, if we really want to lock vp shouldn't we at least + * have a flag, e.g. 'ALREADYLOCKED', so that if the caller already has a + * lock on vp, we won't try to re-lock it and perhaps risk a + * "panic panic: EXCLUSIVE->SHARED locked" situation ? + */ + vn_lock(vp, LK_SHARED); + error = VOP_GETPARENT(vp, &dvp, directory_hint, flags, fname, &fnamelen); + VOP_UNLOCK(vp, 0); + if (error) { + dvp = NULL; + goto out; + } + + /* + * we have found a parent directory and a name for our vnode, + * save the name at the end of buf + */ + pch = buf + buflen - strlen(fname); + if (pch < buf) { + error = EOVERFLOW; + if (dvp != NULL) { + vfslocked = VFS_LOCK_GIANT(dvp->v_mount); + vput(dvp); + VFS_UNLOCK_GIANT(vfslocked); + } + goto out; + } + strcpy(pch, fname); + buflen -= strlen(fname); + buf[--buflen] = '/'; + } + /* if our target is a dir, do the initial preparation */ + else { + dvp = vp; + VREF(dvp); + vn_lock(dvp, LK_SHARED); + } + + /* + * We have found 'a' directory that contains our target or our target is a directory. + * In any case, just traverse the '..' nodes and construct a path via VOP_VPTOCNP(9) + */ + while (dvp != rootvnode) { + /* + * If we've found a vnode that is the root of a filesystem + * Use the path that the filesystem was mounted on to complete our fullpath + */ + if ((dvp->v_vflag & VV_ROOT) != 0) { + char *pch, *fs_path; + int fs_path_len; + + MNT_REF(dvp->v_mount); + *fullpath = buf + buflen; + fs_path = dvp->v_mount->mnt_stat.f_mntonname; + fs_path_len = strlen(fs_path); + + if (buflen - fs_path_len - 1 < 0) { + vfslocked = VFS_LOCK_GIANT(dvp->v_mount); + vput(dvp); + VFS_UNLOCK_GIANT(vfslocked); + error = EOVERFLOW; + MNT_REL(dvp->v_mount); + goto out; + } + + pch = buf + buflen - fs_path_len; + memcpy(pch, fs_path, fs_path_len); + buflen -= fs_path_len; + + MNT_REL(dvp->v_mount); + break; + } + + vfslocked = VFS_LOCK_GIANT(dvp->v_mount); + error = VOP_VPTOCNP(dvp, &upper_dvp, td->td_ucred, buf, &buflen); + VFS_UNLOCK_GIANT(vfslocked); + if (error) + break; + if (buflen <= 0) { + error = EOVERFLOW; + break; + } + + buf[--buflen] = '/'; + if (dvp != NULL) { + vfslocked = VFS_LOCK_GIANT(dvp->v_mount); + vput(dvp); + VFS_UNLOCK_GIANT(vfslocked); + } + vdrop(upper_dvp); + dvp = upper_dvp; + vn_lock(dvp, LK_SHARED); + VREF(dvp); + } /* while */ + + vfslocked = VFS_LOCK_GIANT(dvp->v_mount); + vput(dvp); + VFS_UNLOCK_GIANT(vfslocked); + *fullpath = buf + buflen; + *freepath = buf; + +out: + if (error != 0) { + *freepath = NULL; + if (buf != NULL) + free(buf, M_TEMP); + } + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); + VFS_UNLOCK_GIANT(vfslocked); + + return (error); +} --- //depot/vendor/freebsd/src/sys/kern/vfs_default.c 2010-04-02 14:05:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/kern/vfs_default.c 2010-05-27 14:41:11.000000000 0000 @@ -120,6 +120,7 @@ .vop_unlock = vop_stdunlock, .vop_vptocnp = vop_stdvptocnp, .vop_vptofh = vop_stdvptofh, + .vop_getparent = vop_stdgetparent, }; /* @@ -841,6 +842,12 @@ return (error); } +int +vop_stdgetparent(struct vop_getparent_args *ap) +{ + return (EOPNOTSUPP); +} + /* * vfs default ops * used to fill the vfs function table to get reasonable default return values. @@ -948,6 +955,12 @@ } int +vfs_stdfhhint (struct mount *mp, struct fid *fhp, uint64_t *hint) +{ + return (EOPNOTSUPP); +} + +int vfs_stdinit (vfsp) struct vfsconf *vfsp; { --- //depot/vendor/freebsd/src/sys/kern/vfs_export.c 2009-09-28 18:10:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/kern/vfs_export.c 2010-05-24 11:27:15.000000000 0000 @@ -377,7 +377,7 @@ if ((error = VFS_ROOT(mp, LK_EXCLUSIVE, &rvp))) return (error); - if ((error = VOP_VPTOFH(rvp, &nfs_pub.np_handle.fh_fid))) + if ((error = VOP_VPTOFH(rvp, &nfs_pub.np_handle.fh_fid, NULL))) return (error); vput(rvp); --- //depot/vendor/freebsd/src/sys/kern/vfs_syscalls.c 2010-04-13 08:55:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/kern/vfs_syscalls.c 2010-05-24 11:27:15.000000000 0000 @@ -4298,7 +4298,7 @@ vp = nd.ni_vp; bzero(&fh, sizeof(fh)); fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(vp, &fh.fh_fid); + error = VOP_VPTOFH(vp, &fh.fh_fid, NULL); vput(vp); VFS_UNLOCK_GIANT(vfslocked); if (error) @@ -4337,7 +4337,7 @@ vp = nd.ni_vp; bzero(&fh, sizeof(fh)); fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(vp, &fh.fh_fid); + error = VOP_VPTOFH(vp, &fh.fh_fid, NULL); vput(vp); VFS_UNLOCK_GIANT(vfslocked); if (error) --- //depot/vendor/freebsd/src/sys/kern/vnode_if.src 2009-06-21 19:25:13.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/kern/vnode_if.src 2010-05-26 21:05:34.000000000 0000 @@ -599,6 +599,7 @@ vop_vptofh { IN struct vnode *vp; IN struct fid *fhp; + IN struct vnode *dvp; }; %% vptocnp vp L L L @@ -611,3 +612,15 @@ INOUT char *buf; INOUT int *buflen; }; + +%% getparent vp L L L +%% getparent vpp - L - + +vop_getparent { + IN struct vnode *vp; + OUT struct vnode **vpp; + IN uint64_t hint; + IN int flags; + INOUT char *buf; + INOUT int *buflen; +}; --- //depot/vendor/freebsd/src/sys/nfs/nfs_nfssvc.c 2009-06-27 14:00:18.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/nfs/nfs_nfssvc.c 2010-06-29 21:25:59.000000000 0000 @@ -79,7 +79,18 @@ KASSERT(!mtx_owned(&Giant), ("nfssvc(): called with Giant")); - AUDIT_ARG_CMD(uap->flag); + AUDIT_ARG_CMD(uap->flag); + /* + * XXX:gpf quick fix until I figure out something better. + * Even if Audit supports multiple simultaneous td_ars per + * kernel thread, we still want to end the audit record for + * nfs_svc so that Audit records for NFS RPCs that are serviced + * by this thread are recorded without any trouble such as waiting + * for nfssvc() to return before commiting them to the audit daemon. + * Problem is that we are now *not* recording the return value from + * the nfs server. + */ + AUDIT_SYSCALL_EXIT(0, td); error = priv_check(td, PRIV_NFS_DAEMON); if (error) --- //depot/vendor/freebsd/src/sys/nfsserver/nfs.h 2010-02-09 23:50:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/nfsserver/nfs.h 2010-07-06 21:25:27.000000000 0000 @@ -195,6 +195,7 @@ }; /* Bits for "nd_flag" */ +#define ND_NFSV2 0x04 #define ND_NFSV3 0x08 /* --- //depot/vendor/freebsd/src/sys/nfsserver/nfs_serv.c 2009-12-03 21:00:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/nfsserver/nfs_serv.c 2010-07-18 17:26:56.000000000 0000 @@ -88,6 +88,8 @@ #include #include +#include + #include #include #include @@ -97,6 +99,14 @@ #include #include +/* + * XXXgpf: should relocate them someplace else + * I just dont know where:S + */ +#define PARENTHINT 0x0001 +#define EXHAUSTSEARCH 0x0002 +#define WANTNAME 0x0004 + #ifdef NFSRV_DEBUG #define nfsdbprintf(info) printf info #else @@ -184,6 +194,106 @@ } /* + * Do our best to acquire 'a' working path for vp + * + * vp - vnode in question + * dvp - directory with vp as a child + * fname - name used to reference vp inside dvp + * fhp - file handle for vp + * n - AUDIT_ARG_UPATH1 or AUDIT_ARG_UPATH2 + * + * Note: vp and dvp may be vref'd but not locks should be held on them as the + * two vn_fullpath_* KPIs may try to lock them themselves. + */ +static void +nfsrv_auditpath(struct vnode *vp, struct vnode *dvp, char *fname, fhandle_t *fhp, int n) +{ + char path[PATH_MAX]; + struct thread *td; + char *fullpath, *freepath; + int flag; + char success; + + td = curthread; + freepath = NULL; + flag = WANTNAME; + success = 0; + + /* try to find the path through vp */ + if (vp != NULL) { + /* try the cache */ + vn_fullpath_global(td, vp, &fullpath, &freepath); + if (freepath != NULL) { + success = 1; + goto out; + } + + /* if our cache fails us */ + if (vp->v_mount != NULL) { + uint64_t parent_hint; + /* get the hint stored inside the file handle */ + if (fhp != NULL) + if (VFS_FHHINT(vp->v_mount, &fhp->fh_fid, &parent_hint) == 0) + flag = PARENTHINT | WANTNAME; + vn_fullpath_nocache(vp, &fullpath, &freepath, + parent_hint, flag); + if (freepath != NULL) { + success = 1; + goto out; + } + } + } + + /* try to find the path through dvp and the component name used to reference vp */ + if (dvp != NULL && fname != NULL) { + /* try the cache */ + vn_fullpath_global(td, dvp, &fullpath, &freepath); + if (freepath != NULL) { + snprintf(path, sizeof(path), "%s/%s", fullpath, fname); + fullpath = path; + success = 1; + goto out; + } + + /* if our cache fails us */ + vn_fullpath_nocache(dvp, &fullpath, &freepath, + 0, WANTNAME); + if (freepath != NULL) { + snprintf(path, sizeof(path), "%s/%s", fullpath, fname); + fullpath = path; + success = 1; + goto out; + } + } + + /* last resort, just save the name used to reference the file in question */ + if (fname != NULL) { + strlcpy(path, fname, sizeof(path)); + fullpath = path; + success = 1; + } + +out: + if (success) { + switch (n) { + case 1: + AUDIT_ARG_UPATH1(td, fullpath); + break; + case 2: + AUDIT_ARG_UPATH2(td, fullpath); + break; + default: + AUDIT_ARG_UPATH1(td, fullpath); + break; + } + } + + if (freepath != NULL) { + free(freepath, M_TEMP); + } +} + +/* * nfs v3 access service */ int @@ -195,6 +305,7 @@ caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = nfsd->nd_cr; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; @@ -214,14 +325,21 @@ nfsm_srvmtofh(fhp); tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED); error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp, - nam, &rdonly, TRUE); + nam, &rdonly, TRUE); if (error) { nfsm_reply(NFSX_UNSIGNED); nfsm_srvpostop_attr(1, NULL); error = 0; goto nfsmout; } + + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } nfsmode = fxdr_unsigned(u_int32_t, *tl); + AUDIT_ARG_FFLAGS(nfsmode); if ((nfsmode & NFSV3ACCESS_READ) && nfsrv_access(vp, VREAD, cred, rdonly, 0)) nfsmode &= ~NFSV3ACCESS_READ; @@ -250,6 +368,11 @@ nfsmout: if (vp) vput(vp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); return(error); } @@ -269,6 +392,7 @@ struct vattr va; struct vattr *vap = &va; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; nfsfh_t nfh; fhandle_t *fhp; caddr_t bpos; @@ -287,6 +411,12 @@ error = 0; goto nfsmout; } + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + error = VOP_GETATTR(vp, vap, cred); vput(vp); vp = NULL; @@ -303,7 +433,13 @@ nfsmout: if (vp) vput(vp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -323,6 +459,7 @@ struct nfsv2_sattr *sp; struct nfs_fattr *fp; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; @@ -400,6 +537,12 @@ goto nfsmout; } + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + /* * vp now an active resource, pay careful attention to cleanup */ @@ -438,6 +581,8 @@ goto out; } error = VOP_SETATTR(vp, vap, cred); + if (AUDIT_vp != NULL) + AUDIT_ARG_VNODE2(AUDIT_vp); postat_ret = VOP_GETATTR(vp, vap, cred); if (!error) error = postat_ret; @@ -461,7 +606,13 @@ if (vp) vput(vp); vn_finished_write(mp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -479,6 +630,7 @@ struct nfs_fattr *fp; struct nameidata nd, ind, *ndp = &nd; struct vnode *vp, *dirp = NULL; + struct vnode *AUDIT_vp = NULL; nfsfh_t nfh; fhandle_t *fhp; caddr_t bpos; @@ -498,10 +650,9 @@ nfsm_srvnamesiz(len); pubflag = nfs_ispublicfh(fhp); - nd.ni_cnd.cn_cred = cred; nd.ni_cnd.cn_nameiop = LOOKUP; - nd.ni_cnd.cn_flags = LOCKLEAF | SAVESTART | MPSAFE; + nd.ni_cnd.cn_flags = LOCKLEAF | SAVESTART | MPSAFE | WANTPARENT; error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, &dirp, v3, &dirattr, &dirattr_ret, pubflag); vfslocked = NDHASGIANT(&nd); @@ -510,7 +661,6 @@ * namei failure, only dirp to cleanup. Clear out garbarge from * structure in case macros jump to nfsmout. */ - if (error) { if (dirp) { vrele(dirp); @@ -523,6 +673,12 @@ goto nfsmout; } + AUDIT_vp = nd.ni_vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + /* * Locate index file for public filehandle * @@ -606,13 +762,12 @@ * Get underlying attribute, then release remaining resources ( for * the same potential blocking reason ) and reply. */ - vp = ndp->ni_vp; + vp = ndp->ni_vp; bzero((caddr_t)fhp, sizeof(nfh)); fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(vp, &fhp->fh_fid); + error = VOP_VPTOFH(vp, &fhp->fh_fid, ndp->ni_dvp); if (!error) error = VOP_GETATTR(vp, vap, cred); - vput(vp); vrele(ndp->ni_startdir); vrele(dirp); @@ -644,8 +799,16 @@ if (ndp->ni_startdir) vrele(ndp->ni_startdir); } + if (ndp->ni_dvp) + vrele(ndp->ni_dvp); NDFREE(&nd, NDF_ONLY_PNBUF); - VFS_UNLOCK_GIANT(vfslocked); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } + VFS_UNLOCK_GIANT(vfslocked); + return (error); } @@ -669,6 +832,7 @@ int v3 = (nfsd->nd_flag & ND_NFSV3); struct mbuf *mb, *mp3, *nmp, *mreq; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; struct vattr attr; nfsfh_t nfh; fhandle_t *fhp; @@ -713,7 +877,7 @@ uiop->uio_segflg = UIO_SYSSPACE; uiop->uio_td = NULL; error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp, - nam, &rdonly, TRUE); + nam, &rdonly, TRUE); if (error) { nfsm_reply(2 * NFSX_UNSIGNED); if (v3) @@ -721,6 +885,12 @@ error = 0; goto nfsmout; } + + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } if (vp->v_type != VLNK) { if (v3) error = EINVAL; @@ -752,7 +922,13 @@ m_freem(mp3); if (vp) vput(vp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -779,6 +955,7 @@ struct mbuf *mb, *mreq; struct mbuf *m2; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; nfsfh_t nfh; fhandle_t *fhp; struct uio io, *uiop = &io; @@ -809,7 +986,7 @@ */ error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp, - nam, &rdonly, TRUE); + nam, &rdonly, TRUE); if (error) { vp = NULL; nfsm_reply(2 * NFSX_UNSIGNED); @@ -819,6 +996,12 @@ goto nfsmout; } + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + if (vp->v_type != VREG) { if (v3) error = EINVAL; @@ -965,6 +1148,7 @@ uiop->uio_resid = len; uiop->uio_rw = UIO_READ; uiop->uio_segflg = UIO_SYSSPACE; + AUDIT_ARG_FFLAGS(IO_NODELOCKED | ioflag); error = VOP_READ(vp, uiop, IO_NODELOCKED | ioflag, cred); off = uiop->uio_offset; nh->nh_nextr = off; @@ -1002,7 +1186,13 @@ nfsmout: if (vp) vput(vp); - VFS_UNLOCK_GIANT(vfslocked); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } + VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -1032,6 +1222,7 @@ int v3 = (nfsd->nd_flag & ND_NFSV3); struct mbuf *mb, *mreq; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; nfsfh_t nfh; fhandle_t *fhp; struct uio io, *uiop = &io; @@ -1120,6 +1311,13 @@ error = 0; goto nfsmout; } + + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + if (v3) forat_ret = VOP_GETATTR(vp, &forat, cred); if (vp->v_type != VREG) { @@ -1173,6 +1371,7 @@ uiop->uio_segflg = UIO_SYSSPACE; uiop->uio_td = NULL; uiop->uio_offset = off; + AUDIT_ARG_FFLAGS(ioflags); error = VOP_WRITE(vp, uiop, ioflags, cred); /* Unlocked write. */ nfsrvstats.srvvop_writes++; @@ -1220,7 +1419,13 @@ if (vp) vput(vp); vn_finished_write(mntp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -1247,6 +1452,7 @@ int v3 = (nfsd->nd_flag & ND_NFSV3), how, exclusive_flag = 0; struct mbuf *mb, *mreq; struct vnode *dirp = NULL; + struct vnode *AUDIT_vp = NULL, *AUDIT_dvp = NULL; nfsfh_t nfh; fhandle_t *fhp; u_quad_t tempsize; @@ -1301,6 +1507,10 @@ goto nfsmout; } + AUDIT_dvp = nd.ni_dvp; + if (AUDIT_dvp != NULL && AUDITING_TD(curthread)) + vref(AUDIT_dvp); + /* * No error. Continue. State: * @@ -1371,6 +1581,7 @@ if (nd.ni_vp == NULL) { if (vap->va_mode == (mode_t)VNOVAL) vap->va_mode = 0; + AUDIT_ARG_MODE(vap->va_mode); if (vap->va_type == VREG || vap->va_type == VSOCK) { error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); if (error) @@ -1442,6 +1653,7 @@ error = ENXIO; } } else { + AUDIT_ARG_MODE(vap->va_mode); if (vap->va_size != -1) { error = nfsrv_access(nd.ni_vp, VWRITE, cred, (nd.ni_cnd.cn_flags & RDONLY), 0); @@ -1453,11 +1665,16 @@ } } } + AUDIT_vp = nd.ni_vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } if (!error) { bzero((caddr_t)fhp, sizeof(nfh)); fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid); + error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid, nd.ni_dvp); if (!error) error = VOP_GETATTR(nd.ni_vp, vap, cred); } @@ -1518,7 +1735,20 @@ vrele(dirp); NDFREE(&nd, NDF_ONLY_PNBUF); vn_finished_write(mp); + /* + * XXXgpf: + * There's a chance that nd.ni_cnd.cn_pnbuf contains junk, + * if an error occured; do we mind? + */ + if (AUDITING_TD(curthread)) { + nfsrv_auditpath(AUDIT_vp, AUDIT_dvp, nd.ni_cnd.cn_pnbuf, fhp, 1); + if (AUDIT_dvp != NULL) + vrele(AUDIT_dvp); + if (AUDIT_vp != NULL) + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return (error); } @@ -1544,6 +1774,7 @@ enum vtype vtyp; struct mbuf *mb, *mreq; struct vnode *vp, *dirp = NULL; + struct vnode *AUDIT_vp = NULL, *AUDIT_dvp = NULL; nfsfh_t nfh; fhandle_t *fhp; struct mount *mp = NULL; @@ -1587,8 +1818,14 @@ error = 0; goto nfsmout; } + + AUDIT_dvp = nd.ni_dvp; + if (AUDIT_dvp != NULL && AUDITING_TD(curthread)) + vref(AUDIT_dvp); + tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED); vtyp = nfsv3tov_type(*tl); + AUDIT_ARG_VTYPE(vtyp); if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) { error = NFSERR_BADTYPE; goto out; @@ -1600,8 +1837,8 @@ major = fxdr_unsigned(u_int32_t, *tl++); minor = fxdr_unsigned(u_int32_t, *tl); vap->va_rdev = makedev(major, minor); - } - + } + /* * Iff doesn't exist, create it. */ @@ -1612,21 +1849,37 @@ vap->va_type = vtyp; if (vap->va_mode == (mode_t)VNOVAL) vap->va_mode = 0; + AUDIT_ARG_MODE(vap->va_mode); if (vtyp == VSOCK) { vrele(nd.ni_startdir); - nd.ni_startdir = NULL; + nd.ni_startdir = NULL; error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); + if (error) NDFREE(&nd, NDF_ONLY_PNBUF); + else { + AUDIT_vp = nd.ni_vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + } } else { if (vtyp != VFIFO && (error = priv_check_cred(cred, PRIV_VFS_MKNOD_DEV, 0))) goto out; error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); + if (error) { NDFREE(&nd, NDF_ONLY_PNBUF); goto out; } + AUDIT_vp = nd.ni_vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + vput(nd.ni_vp); nd.ni_vp = NULL; @@ -1658,11 +1911,12 @@ * send response, cleanup, return. */ out: - vp = nd.ni_vp; + vp = nd.ni_vp; + if (!error) { bzero((caddr_t)fhp, sizeof(nfh)); fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(vp, &fhp->fh_fid); + error = VOP_VPTOFH(vp, &fhp->fh_fid, AUDIT_dvp); if (!error) error = VOP_GETATTR(vp, vap, cred); } @@ -1698,7 +1952,20 @@ nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); } vn_finished_write(mp); + /* + * XXXgpf: + * There's a chance that nd.ni_cnd.cn_pnbuf contains junk, + * if an error occured; do we mind? + */ + if (AUDITING_TD(curthread)) { + nfsrv_auditpath(AUDIT_vp, AUDIT_dvp, nd.ni_cnd.cn_pnbuf, fhp, 1); + if (AUDIT_dvp != NULL) + vrele(AUDIT_dvp); + if (AUDIT_vp != NULL) + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return (0); nfsmout: if (nd.ni_dvp) { @@ -1715,7 +1982,20 @@ vrele(nd.ni_startdir); NDFREE(&nd, NDF_ONLY_PNBUF); vn_finished_write(mp); + /* + * XXXgpf: + * There's a chance that nd.ni_cnd.cn_pnbuf contains junk, + * if an error occured; do we mind? + */ + if (AUDITING_TD(curthread)) { + nfsrv_auditpath(AUDIT_vp, AUDIT_dvp, nd.ni_cnd.cn_pnbuf, fhp, 1); + if (AUDIT_dvp != NULL) + vrele(AUDIT_dvp); + if (AUDIT_vp != NULL) + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return (error); } @@ -1736,6 +2016,7 @@ int v3 = (nfsd->nd_flag & ND_NFSV3); struct mbuf *mb, *mreq; struct vnode *dirp; + struct vnode *AUDIT_dvp = NULL; struct vattr dirfor, diraft; nfsfh_t nfh; fhandle_t *fhp; @@ -1768,6 +2049,12 @@ dirp = NULL; } if (error == 0) { + AUDIT_dvp = nd.ni_dvp; + if (AUDIT_dvp != NULL && AUDITING_TD(curthread)) + vref(AUDIT_dvp); + if (nd.ni_vp != NULL) + AUDIT_ARG_VNODE1(nd.ni_vp); + if (nd.ni_vp->v_type == VDIR) { error = EPERM; /* POSIX */ goto out; @@ -1824,7 +2111,17 @@ if (nd.ni_vp) vput(nd.ni_vp); vn_finished_write(mp); + /* + * XXXgpf: + * There's a chance that nd.ni_cnd.cn_pnbuf contains junk, + * if an error occured; do we mind? + */ + if (AUDITING_TD(curthread) && AUDIT_dvp != NULL) { + nfsrv_auditpath(NULL, AUDIT_dvp, nd.ni_cnd.cn_pnbuf, NULL, 1); + vrele(AUDIT_dvp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -1846,6 +2143,7 @@ struct mbuf *mb, *mreq; struct nameidata fromnd, tond; struct vnode *fvp, *tvp, *tdvp, *fdirp = NULL; + struct vnode *AUDIT_fromdvp = NULL, *AUDIT_todvp = NULL, *AUDIT_vp = NULL; struct vnode *tdirp = NULL; struct vattr fdirfor, fdiraft, tdirfor, tdiraft; nfsfh_t fnfh, tnfh; @@ -1902,6 +2200,17 @@ error = 0; goto nfsmout; } + + AUDIT_vp = fromnd.ni_vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vn_lock(AUDIT_vp, LK_SHARED); + AUDIT_ARG_VNODE1(AUDIT_vp); + VOP_UNLOCK(AUDIT_vp, 0); + } + AUDIT_fromdvp = fromnd.ni_dvp; + if (AUDIT_fromdvp != NULL && AUDITING_TD(curthread)) + vref(AUDIT_fromdvp); + fvp = fromnd.ni_vp; nfsm_srvmtofh(tfhp); nfsm_srvnamesiz(len2); @@ -1911,7 +2220,7 @@ tond.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | MPSAFE; error = nfs_namei(&tond, nfsd, tfhp, len2, slp, nam, &md, &dpos, &tdirp, v3, &tdirfor, &tdirfor_ret, FALSE); - vfslocked = nfsrv_lockedpair_nd(vfslocked, &tond); + vfslocked = nfsrv_lockedpair_nd(vfslocked, &tond); if (tdirp && !v3) { vrele(tdirp); tdirp = NULL; @@ -1919,6 +2228,10 @@ if (error) goto out1; + AUDIT_todvp = tond.ni_dvp; + if (AUDIT_todvp != NULL && AUDITING_TD(curthread)) + vref(AUDIT_todvp); + tdvp = tond.ni_dvp; tvp = tond.ni_vp; if (tvp != NULL) { @@ -2057,7 +2370,21 @@ vrele(fromnd.ni_vp); vn_finished_write(mp); + /* + * XXXgpf: + * There's a chance that nd.ni_cnd.cn_pnbuf contains junk, + * if an error occured; do we mind? + */ + if (AUDITING_TD(curthread)) { + nfsrv_auditpath(NULL, AUDIT_fromdvp, fromnd.ni_cnd.cn_pnbuf, NULL, 1); + nfsrv_auditpath(NULL, AUDIT_todvp, tond.ni_cnd.cn_pnbuf, NULL, 2); + if (AUDIT_fromdvp != NULL) + vrele(AUDIT_fromdvp); + if (AUDIT_todvp != NULL) + vrele(AUDIT_todvp); + } VFS_UNLOCK_GIANT(vfslocked); + return (error); } @@ -2078,6 +2405,7 @@ int getret = 1, v3 = (nfsd->nd_flag & ND_NFSV3); struct mbuf *mb, *mreq; struct vnode *vp = NULL, *xp, *dirp = NULL; + struct vnode *AUDIT_vp = NULL, *AUDIT_dvp = NULL; struct vattr dirfor, diraft, at; nfsfh_t nfh, dnfh; fhandle_t *fhp, *dfhp; @@ -2115,6 +2443,12 @@ error = 0; goto nfsmout; } + + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } if (v3) getret = VOP_GETATTR(vp, &at, cred); if (vp->v_type == VDIR) { @@ -2137,6 +2471,11 @@ vp = NULL; goto out2; } + + AUDIT_dvp = nd.ni_dvp; + if (AUDIT_dvp != NULL && AUDITING_TD(curthread)) + vref(AUDIT_dvp); + xp = nd.ni_vp; if (xp != NULL) { error = EEXIST; @@ -2152,7 +2491,7 @@ goto out2; } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); + error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); NDFREE(&nd, NDF_ONLY_PNBUF); /* fall through */ @@ -2205,7 +2544,21 @@ if (nd.ni_vp) vrele(nd.ni_vp); vn_finished_write(mp); + /* + * XXXgpf: + * There's a chance that nd.ni_cnd.cn_pnbuf contains junk, + * if an error occured; do we mind? + */ + if (AUDITING_TD(curthread)) { + nfsrv_auditpath(NULL, AUDIT_dvp, nd.ni_cnd.cn_pnbuf, NULL, 1); + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 2); + if (AUDIT_dvp != NULL) + vrele(AUDIT_dvp); + if (AUDIT_vp != NULL) + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -2231,6 +2584,7 @@ int v3 = (nfsd->nd_flag & ND_NFSV3); struct mbuf *mb, *mreq; struct vnode *dirp = NULL; + struct vnode *AUDIT_vp = NULL, *AUDIT_dvp = NULL; nfsfh_t nfh; fhandle_t *fhp; struct mount *mp = NULL; @@ -2263,6 +2617,11 @@ nfsm_srvsattr(vap); nfsm_srvpathsiz(len2); } + + AUDIT_dvp = nd.ni_dvp; + if (AUDIT_dvp != NULL && AUDITING_TD(curthread)) + vref(AUDIT_dvp); + if (dirp && !v3) { vrele(dirp); dirp = NULL; @@ -2289,18 +2648,28 @@ error = EEXIST; goto out; } - + + if (pathcp != NULL) + AUDIT_ARG_UPATH2(curthread, pathcp); /* * issue symlink op. SAVESTART is set so the underlying path component * is only freed by the VOP if an error occurs. */ if (vap->va_mode == (mode_t)VNOVAL) vap->va_mode = 0; + AUDIT_ARG_MODE(vap->va_mode); error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap, pathcp); if (error) NDFREE(&nd, NDF_ONLY_PNBUF); - else - vput(nd.ni_vp); + else { + AUDIT_vp = nd.ni_vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + vput(nd.ni_vp); + } + nd.ni_vp = NULL; /* * releases directory prior to potential lookup op. @@ -2333,7 +2702,7 @@ if (error == 0) { bzero((caddr_t)fhp, sizeof(nfh)); fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid); + error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid, AUDIT_dvp); if (!error) error = VOP_GETATTR(nd.ni_vp, vap, cred); vput(nd.ni_vp); @@ -2388,7 +2757,20 @@ free(pathcp, M_TEMP); vn_finished_write(mp); + /* + * XXXgpf: + * There's a chance that nd.ni_cnd.cn_pnbuf contains junk, + * if an error occured; do we mind? + */ + if (AUDITING_TD(curthread)) { + nfsrv_auditpath(AUDIT_vp, AUDIT_dvp, nd.ni_cnd.cn_pnbuf, fhp, 1); + if (AUDIT_dvp != NULL) + vrele(AUDIT_dvp); + if (AUDIT_vp != NULL) + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return (error); } @@ -2413,6 +2795,7 @@ int v3 = (nfsd->nd_flag & ND_NFSV3); struct mbuf *mb, *mreq; struct vnode *dirp = NULL; + struct vnode *AUDIT_vp = NULL, *AUDIT_dvp = NULL; int vpexcl = 0; nfsfh_t nfh; fhandle_t *fhp; @@ -2451,6 +2834,10 @@ error = 0; goto nfsmout; } + AUDIT_dvp = nd.ni_dvp; + if (AUDIT_dvp != NULL && AUDITING_TD(curthread)) + vref(AUDIT_dvp); + VATTR_NULL(vap); if (v3) { nfsm_srvsattr(vap); @@ -2469,7 +2856,7 @@ NDFREE(&nd, NDF_ONLY_PNBUF); error = EEXIST; goto out; - } + } /* * Issue mkdir op. Since SAVESTART is not set, the pathname @@ -2478,7 +2865,8 @@ */ if (vap->va_mode == (mode_t)VNOVAL) vap->va_mode = 0; - error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); + AUDIT_ARG_MODE(vap->va_mode); + error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); NDFREE(&nd, NDF_ONLY_PNBUF); vpexcl = 1; @@ -2486,9 +2874,15 @@ nd.ni_dvp = NULL; if (!error) { + AUDIT_vp = nd.ni_vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + bzero((caddr_t)fhp, sizeof(nfh)); fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid); + error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid, AUDIT_dvp); if (!error) error = VOP_GETATTR(nd.ni_vp, vap, cred); } @@ -2533,7 +2927,6 @@ } error = 0; /* fall through */ - nfsmout: if (nd.ni_dvp) { NDFREE(&nd, NDF_ONLY_PNBUF); @@ -2551,7 +2944,20 @@ if (dirp) vrele(dirp); vn_finished_write(mp); + /* + * XXXgpf: + * There's a chance that nd.ni_cnd.cn_pnbuf contains junk, + * if an error occured; do we mind? + */ + if (AUDITING_TD(curthread)) { + nfsrv_auditpath(AUDIT_vp, AUDIT_dvp, nd.ni_cnd.cn_pnbuf, fhp, 1); + if (AUDIT_dvp != NULL) + vrele(AUDIT_dvp); + if (AUDIT_vp != NULL) + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return (error); } @@ -2571,6 +2977,7 @@ int v3 = (nfsd->nd_flag & ND_NFSV3); struct mbuf *mb, *mreq; struct vnode *vp, *dirp = NULL; + struct vnode *AUDIT_dvp = NULL; struct vattr dirfor, diraft; nfsfh_t nfh; fhandle_t *fhp; @@ -2597,6 +3004,7 @@ nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | MPSAFE; error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, &dirp, v3, &dirfor, &dirfor_ret, FALSE); + vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd); if (dirp && !v3) { vrele(dirp); @@ -2609,6 +3017,12 @@ error = 0; goto nfsmout; } + AUDIT_dvp = nd.ni_dvp; + if (AUDIT_dvp != NULL && AUDITING_TD(curthread)) + vref(AUDIT_dvp); + if (nd.ni_vp != NULL) + AUDIT_ARG_VNODE1(nd.ni_vp); + vp = nd.ni_vp; if (vp->v_type != VDIR) { error = ENOTDIR; @@ -2675,7 +3089,17 @@ vrele(dirp); vn_finished_write(mp); + /* + * XXXgpf: + * There's a chance that nd.ni_cnd.cn_pnbuf contains junk, + * if an error occured; do we mind? + */ + if (AUDITING_TD(curthread) && AUDIT_dvp != NULL) { + nfsrv_auditpath(NULL, AUDIT_dvp, nd.ni_cnd.cn_pnbuf, NULL, 1); + vrele(AUDIT_dvp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -2734,6 +3158,7 @@ struct mbuf *mb, *mreq; char *cpos, *cend, *rbuf; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; struct vattr at; nfsfh_t nfh; fhandle_t *fhp; @@ -2772,11 +3197,18 @@ fullsiz = siz; error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp, nam, &rdonly, TRUE); + if (!error) { + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + } if (!error && vp->v_type != VDIR) { error = ENOTDIR; vput(vp); vp = NULL; - } + } if (error) { nfsm_reply(NFSX_UNSIGNED); if (v3) @@ -2784,7 +3216,6 @@ error = 0; goto nfsmout; } - /* * Obtain lock on vnode for this section of the code */ @@ -3008,7 +3439,13 @@ nfsmout: if (vp) vrele(vp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -3029,6 +3466,7 @@ struct mbuf *mb, *mreq; char *cpos, *cend, *rbuf; struct vnode *vp = NULL, *nvp; + struct vnode *AUDIT_vp = NULL; struct flrep fl; nfsfh_t nfh; fhandle_t *fhp, *nfhp = (fhandle_t *)fl.fl_nfh; @@ -3066,6 +3504,13 @@ fullsiz = siz; error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp, nam, &rdonly, TRUE); + if (!error) { + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } + } if (!error && vp->v_type != VDIR) { error = ENOTDIR; vput(vp); @@ -3241,11 +3686,11 @@ */ KASSERT(nvp->v_mount == vp->v_mount, ("nfsrv_readdirplus: nvp mount != vp mount")); - if (VOP_VPTOFH(nvp, &nfhp->fh_fid)) { + if (VOP_VPTOFH(nvp, &nfhp->fh_fid, vp)) { vput(nvp); nvp = NULL; goto invalid; - } + } if (VOP_GETATTR(nvp, vap, cred)) { vput(nvp); nvp = NULL; @@ -3357,7 +3802,13 @@ nfsmout: if (vp) vrele(vp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -3374,6 +3825,7 @@ struct ucred *cred = nfsd->nd_cr; struct vattr bfor, aft; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; @@ -3417,6 +3869,11 @@ error = 0; goto nfsmout; } + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } for_ret = VOP_GETATTR(vp, &bfor, cred); if (cnt > MAX_COMMIT_COUNT) { @@ -3520,7 +3977,13 @@ if (vp) vput(vp); vn_finished_write(mp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -3542,6 +4005,7 @@ int v3 = (nfsd->nd_flag & ND_NFSV3); struct mbuf *mb, *mreq; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; struct vattr at; nfsfh_t nfh; fhandle_t *fhp; @@ -3554,7 +4018,7 @@ fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp, - nam, &rdonly, TRUE); + nam, &rdonly, TRUE); if (error) { nfsm_reply(NFSX_UNSIGNED); if (v3) @@ -3562,6 +4026,11 @@ error = 0; goto nfsmout; } + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } sf = &statfs; error = VFS_STATFS(vp->v_mount, sf); getret = VOP_GETATTR(vp, &at, cred); @@ -3614,7 +4083,13 @@ nfsmout: if (vp) vput(vp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -3634,6 +4109,7 @@ int error = 0, rdonly, getret = 1, pref; struct mbuf *mb, *mreq; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; struct vattr at; nfsfh_t nfh; fhandle_t *fhp; @@ -3656,6 +4132,11 @@ error = 0; goto nfsmout; } + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } /* XXX Try to make a guess on the max file size. */ VFS_STATFS(vp->v_mount, &sb); @@ -3690,7 +4171,13 @@ nfsmout: if (vp) vput(vp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } @@ -3711,6 +4198,7 @@ register_t linkmax, namemax, chownres, notrunc; struct mbuf *mb, *mreq; struct vnode *vp = NULL; + struct vnode *AUDIT_vp = NULL; struct vattr at; nfsfh_t nfh; fhandle_t *fhp; @@ -3731,6 +4219,11 @@ error = 0; goto nfsmout; } + AUDIT_vp = vp; + if (AUDIT_vp != NULL && AUDITING_TD(curthread)) { + vref(AUDIT_vp); + AUDIT_ARG_VNODE1(AUDIT_vp); + } error = VOP_PATHCONF(vp, _PC_LINK_MAX, &linkmax); if (!error) error = VOP_PATHCONF(vp, _PC_NAME_MAX, &namemax); @@ -3764,7 +4257,13 @@ nfsmout: if (vp) vput(vp); + /* XXX AUDIT */ + if (AUDITING_TD(curthread) && AUDIT_vp != NULL) { + nfsrv_auditpath(AUDIT_vp, NULL, NULL, fhp, 1); + vrele(AUDIT_vp); + } VFS_UNLOCK_GIANT(vfslocked); + return(error); } --- //depot/vendor/freebsd/src/sys/nfsserver/nfs_srvkrpc.c 2010-02-09 23:50:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/nfsserver/nfs_srvkrpc.c 2010-07-08 13:04:03.000000000 0000 @@ -63,6 +63,8 @@ #include #include +#include + #include #include #ifdef INET6 @@ -254,6 +256,8 @@ struct nfsrv_descript nd; struct mbuf *mreq, *mrep; int error; + int protocol; + struct thread *td = curthread; if (rqst->rq_vers == NFS_VER2) { if (rqst->rq_proc > NFSV2PROC_STATFS) { @@ -291,7 +295,7 @@ nd.nd_nam2 = rqst->rq_addr; nd.nd_procnum = procnum; nd.nd_cr = NULL; - nd.nd_flag = flag; + nd.nd_flag = flag; if (nfs_privport) { /* Check if source port is privileged */ @@ -349,7 +353,15 @@ } nfsrvstats.srvrpccnt[nd.nd_procnum]++; + if (flag) + protocol = ND_NFSV3; + else + protocol = ND_NFSV2; + AUDIT_NFS_ENTER(procnum, nd.nd_cr, td, protocol); + AUDIT_ARG_SOCKADDR_IN((struct sockaddr_in *)nd.nd_nam); + AUDIT_ARG_PROTOCOL(protocol); error = proc(&nd, NULL, &mrep); + AUDIT_NFS_EXIT(nd.nd_repstat, td); if (nd.nd_cr) crfree(nd.nd_cr); --- //depot/vendor/freebsd/src/sys/security/audit/audit.c 2009-07-28 21:45:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/security/audit/audit.c 2010-08-16 13:30:34.000000000 0000 @@ -63,6 +63,7 @@ #include #include #include +#include #include #include @@ -78,6 +79,9 @@ MALLOC_DEFINE(M_AUDITPATH, "audit_path", "Audit path storage"); MALLOC_DEFINE(M_AUDITTEXT, "audit_text", "Audit text storage"); MALLOC_DEFINE(M_AUDITGIDSET, "audit_gidset", "Audit GID set storage"); +MALLOC_DEFINE(M_AUDITLOCKOWNER, "audit_lockowner", "Audit lockowner storage"); +MALLOC_DEFINE(M_AUDITCLIENTNAME, "audit_clientname", "Audit client name storage"); +MALLOC_DEFINE(M_AUDITRECORD, "audit_record", "Audit Record storage"); SYSCTL_NODE(_security, OID_AUTO, audit, CTLFLAG_RW, 0, "TrustedBSD audit controls"); @@ -215,22 +219,28 @@ td = arg; ar = mem; bzero(ar, sizeof(*ar)); - ar->k_ar.ar_magic = AUDIT_RECORD_MAGIC; - nanotime(&ar->k_ar.ar_starttime); + /* We should allocate a k_ar iff we are auditing this event */ + if (td->td_pflags & TDP_AUDITREC) { + ar->k_ar = malloc(sizeof(struct audit_record), M_AUDITRECORD, M_WAITOK); + bzero(ar->k_ar, sizeof(struct audit_record)); + ar->k_ar->ar_magic = AUDIT_RECORD_MAGIC; + nanotime(&ar->k_ar->ar_starttime); + + /* + * Export the subject credential. + */ + cred = td->td_ucred; + cru2x(cred, &ar->k_ar->ar_subj_cred); + ar->k_ar->ar_subj_ruid = cred->cr_ruid; + ar->k_ar->ar_subj_rgid = cred->cr_rgid; + ar->k_ar->ar_subj_egid = cred->cr_groups[0]; + ar->k_ar->ar_subj_auid = cred->cr_audit.ai_auid; + ar->k_ar->ar_subj_asid = cred->cr_audit.ai_asid; + ar->k_ar->ar_subj_pid = td->td_proc->p_pid; + ar->k_ar->ar_subj_amask = cred->cr_audit.ai_mask; + ar->k_ar->ar_subj_term_addr = cred->cr_audit.ai_termid; + } - /* - * Export the subject credential. - */ - cred = td->td_ucred; - cru2x(cred, &ar->k_ar.ar_subj_cred); - ar->k_ar.ar_subj_ruid = cred->cr_ruid; - ar->k_ar.ar_subj_rgid = cred->cr_rgid; - ar->k_ar.ar_subj_egid = cred->cr_groups[0]; - ar->k_ar.ar_subj_auid = cred->cr_audit.ai_auid; - ar->k_ar.ar_subj_asid = cred->cr_audit.ai_asid; - ar->k_ar.ar_subj_pid = td->td_proc->p_pid; - ar->k_ar.ar_subj_amask = cred->cr_audit.ai_mask; - ar->k_ar.ar_subj_term_addr = cred->cr_audit.ai_termid; return (0); } @@ -242,20 +252,27 @@ KASSERT(sizeof(*ar) == size, ("audit_record_dtor: wrong size")); ar = mem; - if (ar->k_ar.ar_arg_upath1 != NULL) - free(ar->k_ar.ar_arg_upath1, M_AUDITPATH); - if (ar->k_ar.ar_arg_upath2 != NULL) - free(ar->k_ar.ar_arg_upath2, M_AUDITPATH); - if (ar->k_ar.ar_arg_text != NULL) - free(ar->k_ar.ar_arg_text, M_AUDITTEXT); - if (ar->k_udata != NULL) - free(ar->k_udata, M_AUDITDATA); - if (ar->k_ar.ar_arg_argv != NULL) - free(ar->k_ar.ar_arg_argv, M_AUDITTEXT); - if (ar->k_ar.ar_arg_envv != NULL) - free(ar->k_ar.ar_arg_envv, M_AUDITTEXT); - if (ar->k_ar.ar_arg_groups.gidset != NULL) - free(ar->k_ar.ar_arg_groups.gidset, M_AUDITGIDSET); + if (ar->k_ar != NULL) { + if (ar->k_ar->ar_arg_upath1 != NULL) + free(ar->k_ar->ar_arg_upath1, M_AUDITPATH); + if (ar->k_ar->ar_arg_upath2 != NULL) + free(ar->k_ar->ar_arg_upath2, M_AUDITPATH); + if (ar->k_ar->ar_arg_text != NULL) + free(ar->k_ar->ar_arg_text, M_AUDITTEXT); + if (ar->k_udata != NULL) + free(ar->k_udata, M_AUDITDATA); + if (ar->k_ar->ar_arg_argv != NULL) + free(ar->k_ar->ar_arg_argv, M_AUDITTEXT); + if (ar->k_ar->ar_arg_envv != NULL) + free(ar->k_ar->ar_arg_envv, M_AUDITTEXT); + if (ar->k_ar->ar_arg_groups.gidset != NULL) + free(ar->k_ar->ar_arg_groups.gidset, M_AUDITGIDSET); + if (ar->k_ar->ar_arg_lockowner != NULL) + free(ar->k_ar->ar_arg_lockowner, M_AUDITLOCKOWNER); + if (ar->k_ar->ar_arg_clientname != NULL) + free(ar->k_ar->ar_arg_clientname, M_AUDITCLIENTNAME); + free(ar->k_ar, M_AUDITRECORD); + } } /* @@ -367,7 +384,8 @@ * in the kernel. */ ar = uma_zalloc_arg(audit_record_zone, td, M_WAITOK); - ar->k_ar.ar_event = event; + if (ar->k_ar != NULL) + ar->k_ar->ar_event = event; mtx_lock(&audit_mtx); audit_pre_q_len++; @@ -383,105 +401,168 @@ uma_zfree(audit_record_zone, ar); } +/* + * Insert the new audit record in the per thread tree structure & + * make td_ar point to it + */ void -audit_commit(struct kaudit_record *ar, int error, int retval) +audit_tree_insert(struct thread *td, struct kaudit_record *ar) +{ + if (ar == NULL) + return; + + ar->k_parent = td->td_ar; + STAILQ_INIT(&ar->kaudit_children_q); + if (td->td_ar != NULL) + STAILQ_INSERT_TAIL(&td->td_ar->kaudit_children_q, ar, k_record_q); + td->td_ar = ar; +} + + +/* + * Go up on level on the tree hierarchy, restore the audit flag + * to its previous value and make td_ar point to the parent event + */ +void +audit_tree_go_up(struct thread *td) { + td->td_ar = td->td_ar->k_parent; + if (td->td_ar->k_ar == NULL) + td->td_pflags &= ~TDP_AUDITREC; + else + td->td_pflags |= TDP_AUDITREC; +} + +/* + * commit the audit events of the tree in preorder & destroy the + * ones we don't commit + * + * XXXgpf: The caller needs to hold a lock on audit_mtx. If we don't + * like hogging on the mutex, we can split this function in two. + * One will decide which records should be commited and the other, + * which will require the lock, will just commit or destroy each record. + */ +void +audit_tree_commit(struct kaudit_record *ar, int *signal_worker) +{ au_event_t event; au_class_t class; au_id_t auid; - int sorf; + int commit, error, retval, sorf; struct au_mask *aumask; + struct kaudit_record *child, *tchild; + + commit = 0; + + if (ar->k_ar != NULL) { + error = ar->k_ar->ar_errno; + retval = ar->k_ar->ar_retval; + + /* + * Decide whether to commit the audit record by checking the error + * value from the system call and using the appropriate audit mask. + */ + if (ar->k_ar->ar_subj_auid == AU_DEFAUDITID) + aumask = &audit_nae_mask; + else + aumask = &ar->k_ar->ar_subj_amask; + + if (error) + sorf = AU_PRS_FAILURE; + else + sorf = AU_PRS_SUCCESS; - if (ar == NULL) - return; + /* + * syscalls.master sometimes contains a prototype event number, which + * we will transform into a more specific event number now that we + * have more complete information gathered during the system call. + */ + switch(ar->k_ar->ar_event) { + case AUE_OPEN_RWTC: + ar->k_ar->ar_event = audit_flags_and_error_to_openevent( + ar->k_ar->ar_arg_fflags, error); + break; - /* - * Decide whether to commit the audit record by checking the error - * value from the system call and using the appropriate audit mask. - */ - if (ar->k_ar.ar_subj_auid == AU_DEFAUDITID) - aumask = &audit_nae_mask; - else - aumask = &ar->k_ar.ar_subj_amask; + case AUE_OPENAT_RWTC: + ar->k_ar->ar_event = audit_flags_and_error_to_openatevent( + ar->k_ar->ar_arg_fflags, error); + break; - if (error) - sorf = AU_PRS_FAILURE; - else - sorf = AU_PRS_SUCCESS; + case AUE_SYSCTL: + ar->k_ar->ar_event = audit_ctlname_to_sysctlevent( + ar->k_ar->ar_arg_ctlname, ar->k_ar->ar_valid_arg); + break; - /* - * syscalls.master sometimes contains a prototype event number, which - * we will transform into a more specific event number now that we - * have more complete information gathered during the system call. - */ - switch(ar->k_ar.ar_event) { - case AUE_OPEN_RWTC: - ar->k_ar.ar_event = audit_flags_and_error_to_openevent( - ar->k_ar.ar_arg_fflags, error); - break; + case AUE_AUDITON: + /* Convert the auditon() command to an event. */ + ar->k_ar->ar_event = auditon_command_event(ar->k_ar->ar_arg_cmd); + break; + + case AUE_NFS_OPEN: + ar->k_ar->ar_event = audit_flags_to_nfs_openevent(ar->k_ar->ar_arg_fflags); + break; + } - case AUE_OPENAT_RWTC: - ar->k_ar.ar_event = audit_flags_and_error_to_openatevent( - ar->k_ar.ar_arg_fflags, error); - break; + auid = ar->k_ar->ar_subj_auid; + event = ar->k_ar->ar_event; + class = au_event_class(event); - case AUE_SYSCTL: - ar->k_ar.ar_event = audit_ctlname_to_sysctlevent( - ar->k_ar.ar_arg_ctlname, ar->k_ar.ar_valid_arg); - break; + ar->k_ar_commit |= AR_COMMIT_KERNEL; + if (au_preselect(event, class, aumask, sorf) != 0) + ar->k_ar_commit |= AR_PRESELECT_TRAIL; + if (audit_pipe_preselect(auid, event, class, sorf, + ar->k_ar_commit & AR_PRESELECT_TRAIL) != 0) + ar->k_ar_commit |= AR_PRESELECT_PIPE; + if ((ar->k_ar_commit & (AR_PRESELECT_TRAIL | AR_PRESELECT_PIPE | + AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE)) == 0) + goto out; - case AUE_AUDITON: - /* Convert the auditon() command to an event. */ - ar->k_ar.ar_event = auditon_command_event(ar->k_ar.ar_arg_cmd); - break; - } + /* + * Note: it could be that some records initiated while audit was + * enabled should still be committed? + */ + if (audit_suspended || !audit_enabled) + goto out; - auid = ar->k_ar.ar_subj_auid; - event = ar->k_ar.ar_event; - class = au_event_class(event); + commit = 1; + *signal_worker = 1; + /* + * Constrain the number of committed audit records based on the + * configurable parameter. + */ + while (audit_q_len >= audit_qctrl.aq_hiwater) + cv_wait(&audit_watermark_cv, &audit_mtx); - ar->k_ar_commit |= AR_COMMIT_KERNEL; - if (au_preselect(event, class, aumask, sorf) != 0) - ar->k_ar_commit |= AR_PRESELECT_TRAIL; - if (audit_pipe_preselect(auid, event, class, sorf, - ar->k_ar_commit & AR_PRESELECT_TRAIL) != 0) - ar->k_ar_commit |= AR_PRESELECT_PIPE; - if ((ar->k_ar_commit & (AR_PRESELECT_TRAIL | AR_PRESELECT_PIPE | - AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE)) == 0) { - mtx_lock(&audit_mtx); + TAILQ_INSERT_TAIL(&audit_q, ar, k_q); + audit_q_len++; audit_pre_q_len--; - mtx_unlock(&audit_mtx); - audit_free(ar); - return; } - ar->k_ar.ar_errno = error; - ar->k_ar.ar_retval = retval; - nanotime(&ar->k_ar.ar_endtime); - - /* - * Note: it could be that some records initiated while audit was - * enabled should still be committed? - */ - mtx_lock(&audit_mtx); - if (audit_suspended || !audit_enabled) { +out: + STAILQ_FOREACH_SAFE(child, &ar->kaudit_children_q, k_record_q, tchild) { + audit_tree_commit(child, signal_worker); + } + + /* if we are not commiting this ar, free it */ + if (commit == 0) { audit_pre_q_len--; - mtx_unlock(&audit_mtx); audit_free(ar); - return; } +} - /* - * Constrain the number of committed audit records based on the - * configurable parameter. - */ - while (audit_q_len >= audit_qctrl.aq_hiwater) - cv_wait(&audit_watermark_cv, &audit_mtx); +void +audit_commit(struct kaudit_record *ar) +{ + int signal_worker; + + if (ar == NULL) + return; - TAILQ_INSERT_TAIL(&audit_q, ar, k_q); - audit_q_len++; - audit_pre_q_len--; - cv_signal(&audit_worker_cv); + signal_worker = 0; + mtx_lock(&audit_mtx); + audit_tree_commit(ar, &signal_worker); + if (signal_worker != 0) + cv_signal(&audit_worker_cv); mtx_unlock(&audit_mtx); } @@ -498,10 +579,7 @@ au_class_t class; au_event_t event; au_id_t auid; - - KASSERT(td->td_ar == NULL, ("audit_syscall_enter: td->td_ar != NULL")); - KASSERT((td->td_pflags & TDP_AUDITREC) == 0, - ("audit_syscall_enter: TDP_AUDITREC set")); + struct kaudit_record *ar; /* * In FreeBSD, each ABI has its own system call table, and hence @@ -510,6 +588,9 @@ * reference. In Darwin, there's only one, so we use the global * symbol for the system call table. No audit record is generated * for bad system calls, as no operation has been performed. + * + * gpf: This doesn't seem ok now that we are keeping state for + * every event, whether we are auditing it or not. */ if (code >= td->td_proc->p_sysent->sv_size) return; @@ -551,42 +632,316 @@ cv_wait(&audit_fail_cv, &audit_mtx); panic("audit_failing_stop: thread continued"); } - td->td_ar = audit_new(event, td); - if (td->td_ar != NULL) - td->td_pflags |= TDP_AUDITREC; - } else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0)) { - td->td_ar = audit_new(event, td); - if (td->td_ar != NULL) - td->td_pflags |= TDP_AUDITREC; - } else + td->td_pflags |= TDP_AUDITREC; + } + else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0)) + td->td_pflags |= TDP_AUDITREC; + else + td->td_pflags &= ~TDP_AUDITREC; + + /* + * We need to keep state, even if we are not auditing this event. + * The reason is that that we may encounter another security event, + * before this one is over. When we exit from the second event, we + * need a way to remember if we were auditing the first event or not. + */ + ar = audit_new(event, td); + if (ar != NULL) + audit_tree_insert(td, ar); + else { + audit_commit(td->td_ar); + td->td_pflags &= ~TDP_AUDITREC; td->td_ar = NULL; + } } /* * audit_syscall_exit() is called from the return of every system call, or in - * the event of exit1(), during the execution of exit1(). It is responsible - * for committing the audit record, if any, along with return condition. + * the event of exit1(), during the execution of exit1(). If the current + * event is the root of the audit record tree structure, this function + * is responsible for commiting the whole audit record tree. Otherwise, + * it stores the return status & endtime; also it restores the auditing flag + * and td_ar to reflect the parent audit record. + * + * In the event of nfssvc(), we are forced to call audit_syscall_exit() + * before the syscall actually exits because in some cases, it may hang around + * in the kernel as a NFS daemon thread; this can cause problems with the + * auditing of NFS RPCs. */ void audit_syscall_exit(int error, struct thread *td) { int retval; + if (td->td_ar == NULL) + return; + /* - * Commit the audit record as desired; once we pass the record into - * audit_commit(), the memory is owned by the audit subsystem. The - * return value from the system call is stored on the user thread. + * The return value from the system call is stored on the user thread. * If there was an error, the return value is set to -1, imitating * the behavior of the cerror routine. + */ + if (error) + retval = -1; + else + retval = td->td_retval[0]; + + AUDIT_ENDTIME(); + AUDIT_ERROR(error); + AUDIT_RETVAL(retval); + + /* + * Commit the audit record tree; once we pass the records into + * audit_commit(), the memory is owned by the audit subsystem. */ + if (td->td_ar->k_parent == NULL) { + audit_commit(td->td_ar); + td->td_ar = NULL; + td->td_pflags &= ~TDP_AUDITREC; + } + else + audit_tree_go_up(td); +} + +/* + * Convert an NFS RPC procedure number to an audit event + */ +int +audit_nfs_proc_to_event(unsigned int proc, au_event_t *event, int nfsprot) +{ + au_event_t nfsv3toevent[] = { + AUE_NFS_NULL, + AUE_NFS_GETATTR, + AUE_NFS_SETATTR, + AUE_NFS_LOOKUP, + AUE_NFS_ACCESS, + AUE_NFS_READLINK, + AUE_NFS_READ, + AUE_NFS_WRITE, + AUE_NFS_CREATE, + AUE_NFS_MKDIR, + AUE_NFS_SYMLINK, + AUE_NFS_MKNOD, + AUE_NFS_REMOVE, + AUE_NFS_RMDIR, + AUE_NFS_RENAME, + AUE_NFS_LINK, + AUE_NFS_READDIR, + AUE_NFS_READDIR_PLUS, + AUE_NFS_STATFS, + AUE_NFS_FSINFO, + AUE_NFS_PATHCONF, + AUE_NFS_COMMIT, + AUE_NFS_NOOP, + }; + au_event_t nfsv4toevent[] = { + AUE_NFS_NULL, + AUE_NFS_NOOP, + AUE_NFS_NOOP, + AUE_NFS_ACCESS, + AUE_NFS_CLOSE, + AUE_NFS_COMMIT, + AUE_NFS_CREATE, + AUE_NFS_DELEGPURGE, + AUE_NFS_DELEGRETURN, + AUE_NFS_GETATTR, + AUE_NFSv4_GETFH, + AUE_NFS_LINK, + AUE_NFS_LOCK, + AUE_NFS_LOCKT, + AUE_NFS_LOCKU, + AUE_NFS_LOOKUP, + AUE_NFS_LOOKUPP, + AUE_NFS_NVERIFY, + AUE_NFS_OPEN, + AUE_NFS_OPENATTR, + AUE_NFS_OPENCONFIRM, + AUE_NFS_OPENDOWNGRADE, + AUE_NFS_PUTFH, + AUE_NFS_PUTPUBFH, + AUE_NFS_PUTROOTFH, + AUE_NFS_READ, + AUE_NFS_READDIR, + AUE_NFS_READLINK, + AUE_NFS_REMOVE, + AUE_NFS_RENAME, + AUE_NFS_RENEW, + AUE_NFS_RESTOREFH, + AUE_NFS_SAVEFH, + AUE_NFS_SECINFO, + AUE_NFS_SETATTR, + AUE_NFS_SETCLIENTID, + AUE_NFS_SETCLIENTIDCFRM, + AUE_NFS_VERIFY, + AUE_NFS_WRITE, + AUE_NFS_RELEASELCKOWN, + }; + static int nfs_v3nprocs = sizeof(nfsv3toevent) / sizeof(au_event_t); + static int nfs_v4nprocs = sizeof(nfsv4toevent) / sizeof(au_event_t); + int error = 0; + + switch (nfsprot) { + case ND_NFSV4: + if (proc < nfs_v4nprocs) + *event = nfsv4toevent[proc]; + else + error = EINVAL; + break; + /* FALLTHROUGH */ + default: + case ND_NFSV2: + case ND_NFSV3: + if (proc < nfs_v3nprocs) + *event = nfsv3toevent[proc]; + else + error = EINVAL; + break; + } + + return (error); +} + +/* + * audit_nfs_enter() is called on entry to each rpc request that *will* + * be serviced by the nfs server. It is responsible for deciding + * whether or not to audit the remote procedure call (preselection), + * and if so, allocating a per-thread audit record. + * audit_new() will fill in basic thread/credential properties. + */ +void +audit_nfs_enter(unsigned int proc, struct ucred *user_cr, struct thread *td, int nfsprot) +{ + struct au_mask *aumask; + au_class_t class; + au_event_t event; + au_id_t auid; + int error; + struct kaudit_record *ar; + + error = audit_nfs_proc_to_event(proc, &event, nfsprot); + if (error) + return; + + /* + * Check which audit mask to use; either the kernel non-attributable + * event mask or the process audit mask. + */ + auid = td->td_ucred->cr_audit.ai_auid; + if (auid == AU_DEFAUDITID) + aumask = &audit_nae_mask; + else + aumask = &td->td_ucred->cr_audit.ai_mask; + + /* + * Allocate an audit record, if preselection allows it, and store in + * the thread for later use. + */ + class = au_event_class(event); + if (au_preselect(event, class, aumask, AU_PRS_BOTH)) { + /* + * If we're out of space and need to suspend unprivileged + * processes, do that here rather than trying to allocate + * another audit record. + * + * Note: we might wish to be able to continue here in the + * future, if the system recovers. That should be possible + * by means of checking the condition in a loop around + * cv_wait(). It might be desirable to reevaluate whether an + * audit record is still required for this event by + * re-calling au_preselect(). + */ + if (audit_in_failure && + priv_check(td, PRIV_AUDIT_FAILSTOP) != 0) { + cv_wait(&audit_fail_cv, &audit_mtx); + panic("audit_failing_stop: thread continued"); + } + td->td_pflags |= TDP_AUDITREC; + } + else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0)) + td->td_pflags |= TDP_AUDITREC; + else + td->td_pflags &= ~TDP_AUDITREC; + + /* + * We need to keep state, even if we are not auditing this event. + * The reason is that that we may encounter another security event, + * before this one is over. When we exit from the second event, we + * need a way to remember if we were auditing the first event or not. + */ + ar = audit_new(event, td); + if (ar != NULL) + audit_tree_insert(td, ar); + else { + audit_commit(td->td_ar); + td->td_pflags &= ~TDP_AUDITREC; + td->td_ar = NULL; + return; + } + + /* + * Write over the credentials that audit_record_ctor() exported. + * These are the credentials of the user that initiated the NFS RPC. + */ + /* XXXgpf: seems better than having to use another uma_zone_t with a + * different contructor. + * + * I also tried temporarily replacing td's ucred with + * user_cr just before the call to audit_new() like this, but it + * results in bogus behaviour (no nfs events in my log): + * orig_cr = td->td_ucred; + * td->td_ucred = user_cr; + * td->ar = audit_new(...); + * td->td_ucred = orig_cr; + */ + if (AUDITING_TD(td) && user_cr != NULL) { + cru2x(user_cr, &td->td_ar->k_ar->ar_subj_cred); + td->td_ar->k_ar->ar_subj_ruid = user_cr->cr_ruid; + td->td_ar->k_ar->ar_subj_rgid = user_cr->cr_rgid; + td->td_ar->k_ar->ar_subj_egid = user_cr->cr_groups[0]; + } +} + + +/* + * audit_nfs_exit() is called from the return of every NFS pseudo-sys/call + * that services an RPC by performing the various vnode operations. If the + * current event is the root of the audit record tree structure, this function + * is responsible for commiting the whole audit record tree. Otherwise, + * it stores the return status & endtime; also it restores the auditing flag + * and td_ar to reflect the parent audit record. + */ +void +audit_nfs_exit(int error, struct thread *td) +{ + int retval; + + if (td->td_ar == NULL) + return; + + /* + * XXXgpf: In the case of NFS RPCs, I don't think we need to worry + * about retval. + */ if (error) retval = -1; else retval = td->td_retval[0]; - audit_commit(td->td_ar, error, retval); - td->td_ar = NULL; - td->td_pflags &= ~TDP_AUDITREC; + AUDIT_ENDTIME(); + AUDIT_ERROR(error); + AUDIT_RETVAL(retval); + + /* + * Commit the audit record tree; once we pass the records into + * audit_commit(), the memory is owned by the audit subsystem. + */ + if (td->td_ar->k_parent == NULL) { + audit_commit(td->td_ar); + td->td_ar = NULL; + td->td_pflags &= ~TDP_AUDITREC; + } + else + audit_tree_go_up(td); } void @@ -685,16 +1040,21 @@ * Where possible coredump records should contain a pathname and arg32 * (signal) tokens. */ + td->td_pflags |= TDP_AUDITREC; ar = audit_new(AUE_CORE, td); if (path != NULL) { - pathp = &ar->k_ar.ar_arg_upath1; + pathp = &ar->k_ar->ar_arg_upath1; *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); audit_canon_path(td, path, *pathp); ARG_SET_VALID(ar, ARG_UPATH1); } - ar->k_ar.ar_arg_signum = td->td_proc->p_sig; + ar->k_ar->ar_arg_signum = td->td_proc->p_sig; ARG_SET_VALID(ar, ARG_SIGNUM); if (errcode != 0) ret = 1; - audit_commit(ar, errcode, ret); + AUDIT_ERROR(errcode); + AUDIT_RETVAL(ret); + AUDIT_ENDTIME(); + audit_commit(ar); + td->td_pflags &= ~TDP_AUDITREC; } --- //depot/vendor/freebsd/src/sys/security/audit/audit.h 2009-08-12 10:50:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/security/audit/audit.h 2010-07-21 18:35:00.000000000 0000 @@ -59,6 +59,9 @@ void audit_syscall_enter(unsigned short code, struct thread *td); void audit_syscall_exit(int error, struct thread *td); +void audit_nfs_enter(unsigned int proc, struct ucred *user_cr, struct thread *td, int nfsprot); +void audit_nfs_exit(int error, struct thread *td); + /* * The remaining kernel functions are conditionally compiled in as they are * wrapped by a macro, and the macro should be the only place in the source @@ -67,6 +70,7 @@ #ifdef AUDIT struct ipc_perm; struct sockaddr; +struct sockaddr_in; union auditon_udata; void audit_arg_addr(void * addr); void audit_arg_exit(int status, int retval); @@ -96,6 +100,7 @@ void audit_arg_signum(u_int signum); void audit_arg_socket(int sodomain, int sotype, int soprotocol); void audit_arg_sockaddr(struct thread *td, struct sockaddr *sa); +void audit_arg_sockaddr_in(struct sockaddr_in *sin); void audit_arg_auid(uid_t auid); void audit_arg_auditinfo(struct auditinfo *au_info); void audit_arg_auditinfo_addr(struct auditinfo_addr *au_info); @@ -123,6 +128,15 @@ void audit_proc_coredump(struct thread *td, char *path, int errcode); void audit_thread_alloc(struct thread *td); void audit_thread_free(struct thread *td); +void audit_arg_protocol(int protocol); +void audit_arg_vtype(int vtype); +void audit_arg_clientid(uint64_t clientid); +void audit_arg_lockowner(char *lockowner, u_short len); +void audit_arg_locktype(int locktype); +void audit_arg_clientname(char *clientname, u_short len); +void audit_error(int error); +void audit_retval(int retval); +void audit_endtime(void); /* * Define macros to wrap the audit_arg_* calls by checking the global @@ -155,6 +169,16 @@ audit_arg_auditon((udata)); \ } while (0) +#define AUDIT_ARG_CLIENTID(clientid) do { \ + if (AUDITING_TD(curthread)) \ + audit_arg_clientid((clientid)); \ +} while (0) + +#define AUDIT_ARG_CLIENTNAME(clientname, size) do { \ + if (AUDITING_TD(curthread)) \ + audit_arg_clientname((clientname), (size)); \ +} while (0) + #define AUDIT_ARG_CMD(cmd) do { \ if (AUDITING_TD(curthread)) \ audit_arg_cmd((cmd)); \ @@ -210,6 +234,16 @@ audit_arg_groupset((gidset), (gidset_size)); \ } while (0) +#define AUDIT_ARG_LOCKOWNER(lockowner, size) do { \ + if (AUDITING_TD(curthread)) \ + audit_arg_lockowner((lockowner), (size)); \ +} while (0) + +#define AUDIT_ARG_LOCKTYPE(locktype) do { \ + if (AUDITING_TD(curthread)) \ + audit_arg_locktype((locktype)); \ +} while (0) + #define AUDIT_ARG_MODE(mode) do { \ if (AUDITING_TD(curthread)) \ audit_arg_mode((mode)); \ @@ -230,6 +264,11 @@ audit_arg_process((p)); \ } while (0) +#define AUDIT_ARG_PROTOCOL(prot) do { \ + if (AUDITING_TD(curthread)) \ + audit_arg_protocol((prot)); \ +} while (0) + #define AUDIT_ARG_RGID(rgid) do { \ if (AUDITING_TD(curthread)) \ audit_arg_rgid((rgid)); \ @@ -255,6 +294,11 @@ audit_arg_socket((sodomain), (sotype), (soprotocol)); \ } while (0) +#define AUDIT_ARG_SOCKADDR_IN(sin) do { \ + if (AUDITING_TD(curthread)) \ + audit_arg_sockaddr_in((sin)); \ +} while (0) + #define AUDIT_ARG_SUID(suid) do { \ if (AUDITING_TD(curthread)) \ audit_arg_suid((suid)); \ @@ -295,23 +339,61 @@ audit_arg_vnode2((vp)); \ } while (0) +#define AUDIT_ARG_VTYPE(vtype) do { \ + if (AUDITING_TD(curthread)) \ + audit_arg_vtype((vtype)); \ +} while (0) + #define AUDIT_SYSCALL_ENTER(code, td) do { \ if (audit_enabled) { \ audit_syscall_enter(code, td); \ } \ } while (0) +#define AUDIT_ENDTIME() do { \ + if (AUDITING_TD(curthread)) \ + audit_endtime(); \ +} while (0) \ + +#define AUDIT_ERROR(error) do { \ + if (AUDITING_TD(curthread)) \ + audit_error((error)); \ +} while (0) \ + +#define AUDIT_RETVAL(retval) do { \ + if (AUDITING_TD(curthread)) \ + audit_retval((retval)); \ +} while (0) \ + /* - * Wrap the audit_syscall_exit() function so that it is called only when - * we have a audit record on the thread. Audit records can persist after + * audit_syscall_exit() needs to be called even if we are not auditing + * this particular event because we may have to commit a whole tree + * of audit records, make td_ar point someplace else or change the value + * of the thread's auditing flag. Audit records can persist after * auditing is disabled, so we don't just check audit_enabled here. */ #define AUDIT_SYSCALL_EXIT(error, td) do { \ - if (td->td_pflags & TDP_AUDITREC) \ audit_syscall_exit(error, td); \ } while (0) +#define AUDIT_NFS_ENTER(proc, user_cr, td, nfsprot) do { \ + if (audit_enabled) { \ + audit_nfs_enter(proc, user_cr, td, nfsprot); \ + } \ +} while (0) + /* + * audit_syscall_exit() needs to be called even if we are not auditing + * this particular event because we may have to commit a whole tree + * of audit records, make td_ar point someplace else or change the value + * of the thread's auditing flag. Audit records can persist after + * auditing is disabled, so we don't just check audit_enabled here. + */ +#define AUDIT_NFS_EXIT(error, td) do { \ + audit_nfs_exit(error, td); \ +} while (0) + +/* * A Macro to wrap the audit_sysclose() function. */ #define AUDIT_SYSCLOSE(td, fd) do { \ @@ -326,6 +408,8 @@ #define AUDIT_ARG_ATFD1(atfd) #define AUDIT_ARG_ATFD2(atfd) #define AUDIT_ARG_AUDITON(udata) +#define AUDIT_ARG_CLIENTID(clientid) +#define AUDIT_ARG_CLIENTNAME(clientname, size) #define AUDIT_ARG_CMD(cmd) #define AUDIT_ARG_DEV(dev) #define AUDIT_ARG_EGID(egid) @@ -337,14 +421,18 @@ #define AUDIT_ARG_FFLAGS(fflags) #define AUDIT_ARG_GID(gid) #define AUDIT_ARG_GROUPSET(gidset, gidset_size) +#define AUDIT_ARG_LOCKOWNER(lockowner, size) +#define AUDIT_ARG_LOCKTYPE(locktype) #define AUDIT_ARG_MODE(mode) #define AUDIT_ARG_OWNER(uid, gid) #define AUDIT_ARG_PID(pid) #define AUDIT_ARG_PROCESS(p) +#define AUDIT_ARG_PROTOCOL(prot) #define AUDIT_ARG_RGID(rgid) #define AUDIT_ARG_RUID(ruid) #define AUDIT_ARG_SIGNUM(signum) #define AUDIT_ARG_SGID(sgid) +#define AUDIT_ARG_SOCKADDR_IN(sin) #define AUDIT_ARG_SOCKET(sodomain, sotype, soprotocol) #define AUDIT_ARG_SUID(suid) #define AUDIT_ARG_TEXT(text) @@ -354,12 +442,20 @@ #define AUDIT_ARG_VALUE(value) #define AUDIT_ARG_VNODE1(vp) #define AUDIT_ARG_VNODE2(vp) +#define AUDIT_ARG_VTYPE(vtype) + +#define AUDIT_ENDTIME() +#define AUDIT_ERROR(error) +#define AUDIT_RETVAL(retval) #define AUDIT_SYSCALL_ENTER(code, td) #define AUDIT_SYSCALL_EXIT(error, td) #define AUDIT_SYSCLOSE(p, fd) +#define AUDIT_NFS_ENTER(proc, user_cr, td, prot) +#define AUDIT_NFS_EXIT(error, td) + #endif /* AUDIT */ #endif /* !_SECURITY_AUDIT_KERNEL_H_ */ --- //depot/vendor/freebsd/src/sys/security/audit/audit_arg.c 2010-01-12 07:55:13.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/security/audit/audit_arg.c 2010-07-21 18:35:00.000000000 0000 @@ -69,7 +69,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_addr = addr; + ar->k_ar->ar_arg_addr = addr; ARG_SET_VALID(ar, ARG_ADDR); } @@ -82,8 +82,8 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_exitstatus = status; - ar->k_ar.ar_arg_exitretval = retval; + ar->k_ar->ar_arg_exitstatus = status; + ar->k_ar->ar_arg_exitretval = retval; ARG_SET_VALID(ar, ARG_EXIT); } @@ -96,7 +96,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_len = len; + ar->k_ar->ar_arg_len = len; ARG_SET_VALID(ar, ARG_LEN); } @@ -109,7 +109,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_atfd1 = atfd; + ar->k_ar->ar_arg_atfd1 = atfd; ARG_SET_VALID(ar, ARG_ATFD1); } @@ -122,7 +122,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_atfd2 = atfd; + ar->k_ar->ar_arg_atfd2 = atfd; ARG_SET_VALID(ar, ARG_ATFD2); } @@ -135,7 +135,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_fd = fd; + ar->k_ar->ar_arg_fd = fd; ARG_SET_VALID(ar, ARG_FD); } @@ -148,7 +148,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_fflags = fflags; + ar->k_ar->ar_arg_fflags = fflags; ARG_SET_VALID(ar, ARG_FFLAGS); } @@ -161,7 +161,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_gid = gid; + ar->k_ar->ar_arg_gid = gid; ARG_SET_VALID(ar, ARG_GID); } @@ -174,7 +174,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_uid = uid; + ar->k_ar->ar_arg_uid = uid; ARG_SET_VALID(ar, ARG_UID); } @@ -187,7 +187,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_egid = egid; + ar->k_ar->ar_arg_egid = egid; ARG_SET_VALID(ar, ARG_EGID); } @@ -200,7 +200,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_euid = euid; + ar->k_ar->ar_arg_euid = euid; ARG_SET_VALID(ar, ARG_EUID); } @@ -213,7 +213,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_rgid = rgid; + ar->k_ar->ar_arg_rgid = rgid; ARG_SET_VALID(ar, ARG_RGID); } @@ -226,7 +226,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_ruid = ruid; + ar->k_ar->ar_arg_ruid = ruid; ARG_SET_VALID(ar, ARG_RUID); } @@ -239,7 +239,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_sgid = sgid; + ar->k_ar->ar_arg_sgid = sgid; ARG_SET_VALID(ar, ARG_SGID); } @@ -252,7 +252,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_suid = suid; + ar->k_ar->ar_arg_suid = suid; ARG_SET_VALID(ar, ARG_SUID); } @@ -269,13 +269,13 @@ if (ar == NULL) return; - if (ar->k_ar.ar_arg_groups.gidset == NULL) - ar->k_ar.ar_arg_groups.gidset = malloc( + if (ar->k_ar->ar_arg_groups.gidset == NULL) + ar->k_ar->ar_arg_groups.gidset = malloc( sizeof(gid_t) * gidset_size, M_AUDITGIDSET, M_WAITOK); for (i = 0; i < gidset_size; i++) - ar->k_ar.ar_arg_groups.gidset[i] = gidset[i]; - ar->k_ar.ar_arg_groups.gidset_size = gidset_size; + ar->k_ar->ar_arg_groups.gidset[i] = gidset[i]; + ar->k_ar->ar_arg_groups.gidset_size = gidset_size; ARG_SET_VALID(ar, ARG_GROUPSET); } @@ -288,7 +288,7 @@ if (ar == NULL) return; - strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME); + strlcpy(ar->k_ar->ar_arg_login, login, MAXLOGNAME); ARG_SET_VALID(ar, ARG_LOGIN); } @@ -301,8 +301,8 @@ if (ar == NULL) return; - bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int)); - ar->k_ar.ar_arg_len = namelen; + bcopy(name, &ar->k_ar->ar_arg_ctlname, namelen * sizeof(int)); + ar->k_ar->ar_arg_len = namelen; ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN); } @@ -315,7 +315,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_mask = mask; + ar->k_ar->ar_arg_mask = mask; ARG_SET_VALID(ar, ARG_MASK); } @@ -328,7 +328,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_mode = mode; + ar->k_ar->ar_arg_mode = mode; ARG_SET_VALID(ar, ARG_MODE); } @@ -341,7 +341,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_dev = dev; + ar->k_ar->ar_arg_dev = dev; ARG_SET_VALID(ar, ARG_DEV); } @@ -354,7 +354,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_value = value; + ar->k_ar->ar_arg_value = value; ARG_SET_VALID(ar, ARG_VALUE); } @@ -367,8 +367,8 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_uid = uid; - ar->k_ar.ar_arg_gid = gid; + ar->k_ar->ar_arg_uid = uid; + ar->k_ar->ar_arg_gid = gid; ARG_SET_VALID(ar, ARG_UID | ARG_GID); } @@ -381,7 +381,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_pid = pid; + ar->k_ar->ar_arg_pid = pid; ARG_SET_VALID(ar, ARG_PID); } @@ -400,14 +400,14 @@ return; cred = p->p_ucred; - ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid; - ar->k_ar.ar_arg_euid = cred->cr_uid; - ar->k_ar.ar_arg_egid = cred->cr_groups[0]; - ar->k_ar.ar_arg_ruid = cred->cr_ruid; - ar->k_ar.ar_arg_rgid = cred->cr_rgid; - ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid; - ar->k_ar.ar_arg_termid_addr = cred->cr_audit.ai_termid; - ar->k_ar.ar_arg_pid = p->p_pid; + ar->k_ar->ar_arg_auid = cred->cr_audit.ai_auid; + ar->k_ar->ar_arg_euid = cred->cr_uid; + ar->k_ar->ar_arg_egid = cred->cr_groups[0]; + ar->k_ar->ar_arg_ruid = cred->cr_ruid; + ar->k_ar->ar_arg_rgid = cred->cr_rgid; + ar->k_ar->ar_arg_asid = cred->cr_audit.ai_asid; + ar->k_ar->ar_arg_termid_addr = cred->cr_audit.ai_termid; + ar->k_ar->ar_arg_pid = p->p_pid; ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID | ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS); } @@ -421,7 +421,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_signum = signum; + ar->k_ar->ar_arg_signum = signum; ARG_SET_VALID(ar, ARG_SIGNUM); } @@ -434,9 +434,9 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_sockinfo.so_domain = sodomain; - ar->k_ar.ar_arg_sockinfo.so_type = sotype; - ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol; + ar->k_ar->ar_arg_sockinfo.so_domain = sodomain; + ar->k_ar->ar_arg_sockinfo.so_type = sotype; + ar->k_ar->ar_arg_sockinfo.so_protocol = soprotocol; ARG_SET_VALID(ar, ARG_SOCKINFO); } @@ -452,7 +452,7 @@ if (ar == NULL) return; - bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len); + bcopy(sa, &ar->k_ar->ar_arg_sockaddr, sa->sa_len); switch (sa->sa_family) { case AF_INET: ARG_SET_VALID(ar, ARG_SADDRINET); @@ -471,6 +471,24 @@ } void +audit_arg_sockaddr_in(struct sockaddr_in *sin) +{ + char text[MAXPATHLEN]; + struct kaudit_record *ar; + u_short port; + + KASSERT(sin != NULL, ("audit_arg_sockaddr_in: sin == NULL")); + + ar = currecord(); + if (ar == NULL) + return; + + port = ntohs(sin->sin_port); + snprintf(text, sizeof(text), "%s:%d", inet_ntoa(sin->sin_addr), port); + AUDIT_ARG_TEXT(text); +} + +void audit_arg_auid(uid_t auid) { struct kaudit_record *ar; @@ -479,7 +497,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_auid = auid; + ar->k_ar->ar_arg_auid = auid; ARG_SET_VALID(ar, ARG_AUID); } @@ -492,12 +510,12 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_auid = au_info->ai_auid; - ar->k_ar.ar_arg_asid = au_info->ai_asid; - ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; - ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; - ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port; - ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine; + ar->k_ar->ar_arg_auid = au_info->ai_auid; + ar->k_ar->ar_arg_asid = au_info->ai_asid; + ar->k_ar->ar_arg_amask.am_success = au_info->ai_mask.am_success; + ar->k_ar->ar_arg_amask.am_failure = au_info->ai_mask.am_failure; + ar->k_ar->ar_arg_termid.port = au_info->ai_termid.port; + ar->k_ar->ar_arg_termid.machine = au_info->ai_termid.machine; ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID); } @@ -510,16 +528,16 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_auid = au_info->ai_auid; - ar->k_ar.ar_arg_asid = au_info->ai_asid; - ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; - ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; - ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type; - ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port; - ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0]; - ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1]; - ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2]; - ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3]; + ar->k_ar->ar_arg_auid = au_info->ai_auid; + ar->k_ar->ar_arg_asid = au_info->ai_asid; + ar->k_ar->ar_arg_amask.am_success = au_info->ai_mask.am_success; + ar->k_ar->ar_arg_amask.am_failure = au_info->ai_mask.am_failure; + ar->k_ar->ar_arg_termid_addr.at_type = au_info->ai_termid.at_type; + ar->k_ar->ar_arg_termid_addr.at_port = au_info->ai_termid.at_port; + ar->k_ar->ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0]; + ar->k_ar->ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1]; + ar->k_ar->ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2]; + ar->k_ar->ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3]; ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR); } @@ -535,13 +553,13 @@ return; /* Invalidate the text string */ - ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); + ar->k_ar->ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); - if (ar->k_ar.ar_arg_text == NULL) - ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, + if (ar->k_ar->ar_arg_text == NULL) + ar->k_ar->ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, M_WAITOK); - strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); + strncpy(ar->k_ar->ar_arg_text, text, MAXPATHLEN); ARG_SET_VALID(ar, ARG_TEXT); } @@ -554,7 +572,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_cmd = cmd; + ar->k_ar->ar_arg_cmd = cmd; ARG_SET_VALID(ar, ARG_CMD); } @@ -567,7 +585,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_svipc_cmd = cmd; + ar->k_ar->ar_arg_svipc_cmd = cmd; ARG_SET_VALID(ar, ARG_SVIPC_CMD); } @@ -580,8 +598,8 @@ if (ar == NULL) return; - bcopy(perm, &ar->k_ar.ar_arg_svipc_perm, - sizeof(ar->k_ar.ar_arg_svipc_perm)); + bcopy(perm, &ar->k_ar->ar_arg_svipc_perm, + sizeof(ar->k_ar->ar_arg_svipc_perm)); ARG_SET_VALID(ar, ARG_SVIPC_PERM); } @@ -594,7 +612,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_svipc_id = id; + ar->k_ar->ar_arg_svipc_id = id; ARG_SET_VALID(ar, ARG_SVIPC_ID); } @@ -607,7 +625,7 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_svipc_addr = addr; + ar->k_ar->ar_arg_svipc_addr = addr; ARG_SET_VALID(ar, ARG_SVIPC_ADDR); } @@ -620,9 +638,9 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid; - ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid; - ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode; + ar->k_ar->ar_arg_pipc_perm.pipc_uid = uid; + ar->k_ar->ar_arg_pipc_perm.pipc_gid = gid; + ar->k_ar->ar_arg_pipc_perm.pipc_mode = mode; ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM); } @@ -635,8 +653,8 @@ if (ar == NULL) return; - bcopy((void *)udata, &ar->k_ar.ar_arg_auditon, - sizeof(ar->k_ar.ar_arg_auditon)); + bcopy((void *)udata, &ar->k_ar->ar_arg_auditon, + sizeof(ar->k_ar->ar_arg_auditon)); ARG_SET_VALID(ar, ARG_AUDITON); } @@ -675,22 +693,22 @@ so = (struct socket *)fp->f_data; if (INP_CHECK_SOCKAF(so, PF_INET)) { SOCK_LOCK(so); - ar->k_ar.ar_arg_sockinfo.so_type = + ar->k_ar->ar_arg_sockinfo.so_type = so->so_type; - ar->k_ar.ar_arg_sockinfo.so_domain = + ar->k_ar->ar_arg_sockinfo.so_domain = INP_SOCKAF(so); - ar->k_ar.ar_arg_sockinfo.so_protocol = + ar->k_ar->ar_arg_sockinfo.so_protocol = so->so_proto->pr_protocol; SOCK_UNLOCK(so); pcb = (struct inpcb *)so->so_pcb; INP_RLOCK(pcb); - ar->k_ar.ar_arg_sockinfo.so_raddr = + ar->k_ar->ar_arg_sockinfo.so_raddr = pcb->inp_faddr.s_addr; - ar->k_ar.ar_arg_sockinfo.so_laddr = + ar->k_ar->ar_arg_sockinfo.so_laddr = pcb->inp_laddr.s_addr; - ar->k_ar.ar_arg_sockinfo.so_rport = + ar->k_ar->ar_arg_sockinfo.so_rport = pcb->inp_fport; - ar->k_ar.ar_arg_sockinfo.so_lport = + ar->k_ar->ar_arg_sockinfo.so_lport = pcb->inp_lport; INP_RUNLOCK(pcb); ARG_SET_VALID(ar, ARG_SOCKINFO); @@ -727,7 +745,7 @@ if (ar == NULL) return; - audit_arg_upath(td, upath, &ar->k_ar.ar_arg_upath1); + audit_arg_upath(td, upath, &ar->k_ar->ar_arg_upath1); ARG_SET_VALID(ar, ARG_UPATH1); } @@ -740,7 +758,7 @@ if (ar == NULL) return; - audit_arg_upath(td, upath, &ar->k_ar.ar_arg_upath2); + audit_arg_upath(td, upath, &ar->k_ar->ar_arg_upath2); ARG_SET_VALID(ar, ARG_UPATH2); } @@ -802,7 +820,7 @@ return; ARG_CLEAR_VALID(ar, ARG_VNODE1); - error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode1); + error = audit_arg_vnode(vp, &ar->k_ar->ar_arg_vnode1); if (error == 0) ARG_SET_VALID(ar, ARG_VNODE1); } @@ -818,7 +836,7 @@ return; ARG_CLEAR_VALID(ar, ARG_VNODE2); - error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode2); + error = audit_arg_vnode(vp, &ar->k_ar->ar_arg_vnode2); if (error == 0) ARG_SET_VALID(ar, ARG_VNODE2); } @@ -838,9 +856,9 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK); - bcopy(argv, ar->k_ar.ar_arg_argv, length); - ar->k_ar.ar_arg_argc = argc; + ar->k_ar->ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK); + bcopy(argv, ar->k_ar->ar_arg_argv, length); + ar->k_ar->ar_arg_argc = argc; ARG_SET_VALID(ar, ARG_ARGV); } @@ -859,9 +877,9 @@ if (ar == NULL) return; - ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK); - bcopy(envv, ar->k_ar.ar_arg_envv, length); - ar->k_ar.ar_arg_envc = envc; + ar->k_ar->ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK); + bcopy(envv, ar->k_ar->ar_arg_envv, length); + ar->k_ar->ar_arg_envc = envc; ARG_SET_VALID(ar, ARG_ENVV); } @@ -897,3 +915,159 @@ VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); } + +/* + * Audit the NFS protocol used in NFS RPCs + */ +void +audit_arg_protocol(int protocol) +{ + struct kaudit_record *ar; + + ar = currecord(); + if (ar == NULL) + return; + + ar->k_ar->ar_arg_protocol = protocol; + ARG_SET_VALID(ar, ARG_PROTOCOL); +} + +/* + * Audit the vnode type of the file created by some NFS RPC + */ +void +audit_arg_vtype(int vtype) +{ + struct kaudit_record *ar; + + ar = currecord(); + if (ar == NULL) + return; + + ar->k_ar->ar_arg_vtype = vtype; + ARG_SET_VALID(ar, ARG_VTYPE); +} + +/* + * Audit the clientid used by some NFSv4 RPCs + */ +void +audit_arg_clientid(uint64_t clientid) +{ + struct kaudit_record *ar; + + ar = currecord(); + if (ar == NULL) + return; + + ar->k_ar->ar_arg_clientid = clientid; + ARG_SET_VALID(ar, ARG_CLIENTID); +} + +/* + * Audit the lockowner; used by NFSv4 RPCs lock,lockt & releaselckown + */ +void +audit_arg_lockowner(char *lockowner, u_short len) +{ + struct kaudit_record *ar; + + len++; + + KASSERT(lockowner != NULL, ("audit_arg_lockowner: lockowner == NULL")); + KASSERT(len != 0, ("audit_arg_lockowner: len == 0")); + + ar = currecord(); + if (ar == NULL) + return; + + /* Invalidate the lockowner string */ + ar->k_ar->ar_valid_arg &= (ARG_ALL ^ ARG_LOCKOWNER); + + if (ar->k_ar->ar_arg_lockowner == NULL) + ar->k_ar->ar_arg_lockowner = malloc(len, M_AUDITLOCKOWNER, + M_WAITOK); + + strlcpy(ar->k_ar->ar_arg_lockowner, lockowner, len); + ARG_SET_VALID(ar, ARG_LOCKOWNER); +} + +/* + * Audit the client name used by NFSv4 RPC setclientid when RPCSEC_GSS is used + */ +void +audit_arg_clientname(char *clientname, u_short len) +{ + struct kaudit_record *ar; + + len++; + + KASSERT(clientname != NULL, ("audit_arg_clientname: clientname == NULL")); + KASSERT(len != 0, ("audit_arg_clientname: len == 0")); + + ar = currecord(); + if (ar == NULL) + return; + + /* Invalidate the clientname string */ + ar->k_ar->ar_valid_arg &= (ARG_ALL ^ ARG_CLIENTNAME); + + if (ar->k_ar->ar_arg_clientname == NULL) + ar->k_ar->ar_arg_clientname = malloc(len, M_AUDITCLIENTNAME, + M_WAITOK); + + strlcpy(ar->k_ar->ar_arg_clientname, clientname, len); + ARG_SET_VALID(ar, ARG_CLIENTNAME); +} + +/* + * Audit the locktype used by the NFSv4 RPCs lock,lockt & locku + */ +void +audit_arg_locktype(int locktype) +{ + struct kaudit_record *ar; + + ar = currecord(); + if (ar == NULL) + return; + + ar->k_ar->ar_arg_locktype = locktype; + ARG_SET_VALID(ar, ARG_LOCKTYPE); +} + +void +audit_error(int error) +{ + struct kaudit_record *ar; + + ar = currecord(); + if (ar == NULL) + return; + + ar->k_ar->ar_errno = error; +} + +void +audit_retval(int retval) +{ + struct kaudit_record *ar; + + ar = currecord(); + if (ar == NULL) + return; + + ar->k_ar->ar_retval = retval; +} + +void +audit_endtime(void) +{ + struct kaudit_record *ar; + + ar = currecord(); + if (ar == NULL) + return; + + nanotime(&ar->k_ar->ar_endtime); +} --- //depot/vendor/freebsd/src/sys/security/audit/audit_bsm.c 2010-05-04 15:30:16.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/security/audit/audit_bsm.c 2010-08-07 16:49:25.000000000 0000 @@ -471,7 +471,7 @@ KASSERT(kar != NULL, ("kaudit_to_bsm: kar == NULL")); *pau = NULL; - ar = &kar->k_ar; + ar = kar->k_ar; rec = kau_open(); /* @@ -1581,6 +1581,256 @@ kau_write(rec, tok); break; + case AUE_NFS_CREATE: + case AUE_NFS_MKNOD: + if (ARG_IS_VALID(kar, ARG_VTYPE)) { + tok = au_to_vtype(ar->ar_arg_vtype); + kau_write(rec, tok); + } + + /* FALLTHROUGH */ + case AUE_NFS_MKDIR: + if (ARG_IS_VALID(kar, ARG_MODE)) { + tok = au_to_arg32(3, "mode", ar->ar_arg_mode); + kau_write(rec, tok); + } + /* FALLTHROUGH */ + + case AUE_NFS_READDIR: + case AUE_NFS_READDIR_PLUS: + case AUE_NFS_READLINK: + case AUE_NFS_REMOVE: + case AUE_NFS_RMDIR: + case AUE_NFS_GETATTR: + case AUE_NFS_LOOKUP: + case AUE_NFS_LOOKUPP: + case AUE_NFS_COMMIT: + case AUE_NFS_PATHCONF: + case AUE_NFS_STATFS: + case AUE_NFS_FSINFO: + UPATH1_VNODE1_TOKENS; + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + + break; + + case AUE_NFS_READ: + case AUE_NFS_WRITE: + if (ARG_IS_VALID(kar, ARG_CLIENTID)) { + tok = au_to_arg64(2, "client id", ar->ar_arg_clientid); + kau_write(rec, tok); + } + case AUE_NFS_ACCESS: + if (ARG_IS_VALID(kar, ARG_FFLAGS)) { + tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); + kau_write(rec, tok); + } + UPATH1_VNODE1_TOKENS; + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + break; + + case AUE_NFS_NOOP: + case AUE_NFS_NULL: + case AUE_NFS_OPENATTR: + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + break; + + case AUE_NFS_SYMLINK: + if (ARG_IS_VALID(kar, ARG_MODE)) { + tok = au_to_arg32(3, "mode", ar->ar_arg_mode); + kau_write(rec, tok); + } + UPATH1_VNODE1_TOKENS; + UPATH2_TOKENS; + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + break; + + case AUE_NFS_SETATTR: + UPATH1_VNODE1_TOKENS; + VNODE2_TOKENS; + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + break; + + case AUE_NFS_LINK: + case AUE_NFS_RENAME: + UPATH1_VNODE1_TOKENS; + UPATH2_TOKENS; + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + break; + + case AUE_NFS_LOCK: + case AUE_NFS_LOCKT: + if (ARG_IS_VALID(kar, ARG_LOCKOWNER)) { + tok = au_to_text(ar->ar_arg_lockowner); + kau_write(rec, tok); + } + + /* FALLTHROUGH */ + case AUE_NFS_LOCKU: + if (ARG_IS_VALID(kar, ARG_LOCKTYPE)) { + tok = au_to_arg32(1, "lock type", ar->ar_arg_locktype); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_CLIENTID)) { + tok = au_to_arg64(2, "client id", ar->ar_arg_clientid); + kau_write(rec, tok); + } + UPATH1_VNODE1_TOKENS; + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + break; + + case AUE_NFS_RELEASELCKOWN: + if (ARG_IS_VALID(kar, ARG_LOCKOWNER)) { + tok = au_to_text(ar->ar_arg_lockowner); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_CLIENTID)) { + tok = au_to_arg64(2, "client id", ar->ar_arg_clientid); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + break; + + case AUE_NFS_OPEN_RC: + case AUE_NFS_OPEN_RTC: + case AUE_NFS_OPEN_RWC: + case AUE_NFS_OPEN_RWTC: + case AUE_NFS_OPEN_WC: + case AUE_NFS_OPEN_WTC: + if (ARG_IS_VALID(kar, ARG_MODE)) { + tok = au_to_arg32(3, "mode", ar->ar_arg_mode); + kau_write(rec, tok); + } + + /* FALLTHROUGH */ + case AUE_NFS_CLOSE: + case AUE_NFS_DELEGRETURN: + case AUE_NFS_OPEN: + case AUE_NFS_OPEN_R: + case AUE_NFS_OPEN_RT: + case AUE_NFS_OPEN_RW: + case AUE_NFS_OPEN_RWT: + case AUE_NFS_OPEN_W: + case AUE_NFS_OPEN_WT: + case AUE_NFS_OPENCONFIRM: + case AUE_NFS_OPENDOWNGRADE: + if (ARG_IS_VALID(kar, ARG_CLIENTID)) { + tok = au_to_arg64(2, "client id", ar->ar_arg_clientid); + kau_write(rec, tok); + } + + /* FALLTHROUGH */ + case AUE_NFS_PUTFH: + case AUE_NFS_PUTPUBFH: + case AUE_NFS_PUTROOTFH: + case AUE_NFS_RESTOREFH: + case AUE_NFS_SAVEFH: + case AUE_NFSv4_GETFH: + case AUE_NFS_NVERIFY: + case AUE_NFS_VERIFY: + case AUE_NFS_SECINFO: + UPATH1_VNODE1_TOKENS; + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + break; + + case AUE_NFS_DELEGPURGE: + case AUE_NFS_RENEW: + case AUE_NFS_SETCLIENTIDCFRM: + if (ARG_IS_VALID(kar, ARG_CLIENTID)) { + tok = au_to_arg64(2, "client id", ar->ar_arg_clientid); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + break; + + case AUE_NFS_SETCLIENTID: + if (ARG_IS_VALID(kar, ARG_CLIENTNAME)) { + tok = au_to_text(ar->ar_arg_clientname); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_CLIENTID)) { + tok = au_to_arg64(2, "client id", ar->ar_arg_clientid); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_TEXT)) { + tok = au_to_text(ar->ar_arg_text); + kau_write(rec, tok); + } + if (ARG_IS_VALID(kar, ARG_PROTOCOL)) { + tok = au_to_protocol(ar->ar_arg_protocol); + kau_write(rec, tok); + } + break; + case AUE_WAIT4: PROCESS_PID_TOKENS(1); if (ARG_IS_VALID(kar, ARG_VALUE)) { --- //depot/vendor/freebsd/src/sys/security/audit/audit_bsm_errno.c 2009-07-17 14:10:13.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/security/audit/audit_bsm_errno.c 2010-08-16 13:30:34.000000000 0000 @@ -41,21 +41,23 @@ #include +#include + /* * Different operating systems use different numeric constants for different * error numbers, and sometimes error numbers don't exist in more than one * operating system. These routines convert between BSM and local error - * number spaces, subject to the above realities. BSM error numbers are - * stored in a single 8-bit character, so don't have a byte order. + * number spaces, subject to the above realities. * * Don't include string definitions when this code is compiled into a kernel. */ struct bsm_errno { int be_bsm_errno; int be_local_errno; + char be_use_strerror; #if !defined(KERNEL) && !defined(_KERNEL) const char *be_strerror; -#endif +#endif }; #define ERRNO_NO_LOCAL_MAPPING -600 @@ -82,610 +84,953 @@ * string using strerror(3). */ static const struct bsm_errno bsm_errnos[] = { - { BSM_ERRNO_ESUCCESS, 0, ES("Success") }, - { BSM_ERRNO_EPERM, EPERM, ES("Operation not permitted") }, - { BSM_ERRNO_ENOENT, ENOENT, ES("No such file or directory") }, - { BSM_ERRNO_ESRCH, ESRCH, ES("No such process") }, - { BSM_ERRNO_EINTR, EINTR, ES("Interrupted system call") }, - { BSM_ERRNO_EIO, EIO, ES("Input/output error") }, - { BSM_ERRNO_ENXIO, ENXIO, ES("Device not configured") }, - { BSM_ERRNO_E2BIG, E2BIG, ES("Argument list too long") }, - { BSM_ERRNO_ENOEXEC, ENOEXEC, ES("Exec format error") }, - { BSM_ERRNO_EBADF, EBADF, ES("Bad file descriptor") }, - { BSM_ERRNO_ECHILD, ECHILD, ES("No child processes") }, - { BSM_ERRNO_EAGAIN, EAGAIN, ES("Resource temporarily unavailable") }, - { BSM_ERRNO_ENOMEM, ENOMEM, ES("Cannot allocate memory") }, - { BSM_ERRNO_EACCES, EACCES, ES("Permission denied") }, - { BSM_ERRNO_EFAULT, EFAULT, ES("Bad address") }, - { BSM_ERRNO_ENOTBLK, ENOTBLK, ES("Block device required") }, - { BSM_ERRNO_EBUSY, EBUSY, ES("Device busy") }, - { BSM_ERRNO_EEXIST, EEXIST, ES("File exists") }, - { BSM_ERRNO_EXDEV, EXDEV, ES("Cross-device link") }, - { BSM_ERRNO_ENODEV, ENODEV, ES("Operation not supported by device") }, - { BSM_ERRNO_ENOTDIR, ENOTDIR, ES("Not a directory") }, - { BSM_ERRNO_EISDIR, EISDIR, ES("Is a directory") }, - { BSM_ERRNO_EINVAL, EINVAL, ES("Invalid argument") }, - { BSM_ERRNO_ENFILE, ENFILE, ES("Too many open files in system") }, - { BSM_ERRNO_EMFILE, EMFILE, ES("Too many open files") }, - { BSM_ERRNO_ENOTTY, ENOTTY, ES("Inappropriate ioctl for device") }, - { BSM_ERRNO_ETXTBSY, ETXTBSY, ES("Text file busy") }, - { BSM_ERRNO_EFBIG, EFBIG, ES("File too large") }, - { BSM_ERRNO_ENOSPC, ENOSPC, ES("No space left on device") }, - { BSM_ERRNO_ESPIPE, ESPIPE, ES("Illegal seek") }, - { BSM_ERRNO_EROFS, EROFS, ES("Read-only file system") }, - { BSM_ERRNO_EMLINK, EMLINK, ES("Too many links") }, - { BSM_ERRNO_EPIPE, EPIPE, ES("Broken pipe") }, - { BSM_ERRNO_EDOM, EDOM, ES("Numerical argument out of domain") }, - { BSM_ERRNO_ERANGE, ERANGE, ES("Result too large") }, - { BSM_ERRNO_ENOMSG, ENOMSG, ES("No message of desired type") }, - { BSM_ERRNO_EIDRM, EIDRM, ES("Identifier removed") }, + { BSM_ERRNO_ESUCCESS, 0, 1, ES("Success") }, + { BSM_ERRNO_EPERM, EPERM, 1, ES("Operation not permitted") }, + { BSM_ERRNO_ENOENT, ENOENT, 1, ES("No such file or directory") }, + { BSM_ERRNO_ESRCH, ESRCH, 1, ES("No such process") }, + { BSM_ERRNO_EINTR, EINTR, 1, ES("Interrupted system call") }, + { BSM_ERRNO_EIO, EIO, 1, ES("Input/output error") }, + { BSM_ERRNO_ENXIO, ENXIO, 1, ES("Device not configured") }, + { BSM_ERRNO_E2BIG, E2BIG, 1, ES("Argument list too long") }, + { BSM_ERRNO_ENOEXEC, ENOEXEC, 1, ES("Exec format error") }, + { BSM_ERRNO_EBADF, EBADF, 1, ES("Bad file descriptor") }, + { BSM_ERRNO_ECHILD, ECHILD, 1, ES("No child processes") }, + { BSM_ERRNO_EAGAIN, EAGAIN, 1, ES("Resource temporarily unavailable") }, + { BSM_ERRNO_ENOMEM, ENOMEM, 1, ES("Cannot allocate memory") }, + { BSM_ERRNO_EACCES, EACCES, 1, ES("Permission denied") }, + { BSM_ERRNO_EFAULT, EFAULT, 1, ES("Bad address") }, + { BSM_ERRNO_ENOTBLK, ENOTBLK, 1, ES("Block device required") }, + { BSM_ERRNO_EBUSY, EBUSY, 1, ES("Device busy") }, + { BSM_ERRNO_EEXIST, EEXIST, 1, ES("File exists") }, + { BSM_ERRNO_EXDEV, EXDEV, 1, ES("Cross-device link") }, + { BSM_ERRNO_ENODEV, ENODEV, 1, ES("Operation not supported by device") }, + { BSM_ERRNO_ENOTDIR, ENOTDIR, 1, ES("Not a directory") }, + { BSM_ERRNO_EISDIR, EISDIR, 1, ES("Is a directory") }, + { BSM_ERRNO_EINVAL, EINVAL, 1, ES("Invalid argument") }, + { BSM_ERRNO_ENFILE, ENFILE, 1, ES("Too many open files in system") }, + { BSM_ERRNO_EMFILE, EMFILE, 1, ES("Too many open files") }, + { BSM_ERRNO_ENOTTY, ENOTTY, 1, ES("Inappropriate ioctl for device") }, + { BSM_ERRNO_ETXTBSY, ETXTBSY, 1, ES("Text file busy") }, + { BSM_ERRNO_EFBIG, EFBIG, 1, ES("File too large") }, + { BSM_ERRNO_ENOSPC, ENOSPC, 1, ES("No space left on device") }, + { BSM_ERRNO_ESPIPE, ESPIPE, 1, ES("Illegal seek") }, + { BSM_ERRNO_EROFS, EROFS, 1, ES("Read-only file system") }, + { BSM_ERRNO_EMLINK, EMLINK, 1, ES("Too many links") }, + { BSM_ERRNO_EPIPE, EPIPE, 1, ES("Broken pipe") }, + { BSM_ERRNO_EDOM, EDOM, 1, ES("Numerical argument out of domain") }, + { BSM_ERRNO_ERANGE, ERANGE, 1, ES("Result too large") }, + { BSM_ERRNO_ENOMSG, ENOMSG, 1, ES("No message of desired type") }, + { BSM_ERRNO_EIDRM, EIDRM, 1, ES("Identifier removed") }, { BSM_ERRNO_ECHRNG, #ifdef ECHRNG ECHRNG, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Channel number out of range") }, + 1, ES("Channel number out of range") }, { BSM_ERRNO_EL2NSYNC, #ifdef EL2NSYNC EL2NSYNC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Level 2 not synchronized") }, + 1, ES("Level 2 not synchronized") }, { BSM_ERRNO_EL3HLT, #ifdef EL3HLT EL3HLT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Level 3 halted") }, + 1, ES("Level 3 halted") }, { BSM_ERRNO_EL3RST, #ifdef EL3RST EL3RST, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Level 3 reset") }, + 1, ES("Level 3 reset") }, { BSM_ERRNO_ELNRNG, #ifdef ELNRNG ELNRNG, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Link number out of range") }, + 1, ES("Link number out of range") }, { BSM_ERRNO_EUNATCH, #ifdef EUNATCH EUNATCH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Protocol driver not attached") }, + 1, ES("Protocol driver not attached") }, { BSM_ERRNO_ENOCSI, #ifdef ENOCSI ENOCSI, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("No CSI structure available") }, + 1, ES("No CSI structure available") }, { BSM_ERRNO_EL2HLT, #ifdef EL2HLT EL2HLT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Level 2 halted") }, - { BSM_ERRNO_EDEADLK, EDEADLK, ES("Resource deadlock avoided") }, - { BSM_ERRNO_ENOLCK, ENOLCK, ES("No locks available") }, - { BSM_ERRNO_ECANCELED, ECANCELED, ES("Operation canceled") }, - { BSM_ERRNO_ENOTSUP, ENOTSUP, ES("Operation not supported") }, - { BSM_ERRNO_EDQUOT, EDQUOT, ES("Disc quota exceeded") }, + 1, ES("Level 2 halted") }, + { BSM_ERRNO_EDEADLK, EDEADLK, 1, ES("Resource deadlock avoided") }, + { BSM_ERRNO_ENOLCK, ENOLCK, 1, ES("No locks available") }, + { BSM_ERRNO_ECANCELED, ECANCELED, 1, ES("Operation canceled") }, + { BSM_ERRNO_ENOTSUP, ENOTSUP, 1, ES("Operation not supported") }, + { BSM_ERRNO_EDQUOT, EDQUOT, 1, ES("Disc quota exceeded") }, { BSM_ERRNO_EBADE, #ifdef EBADE EBADE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Invalid exchange") }, + 1, ES("Invalid exchange") }, { BSM_ERRNO_EBADR, #ifdef EBADR EBADR, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Invalid request descriptor") }, + 1, ES("Invalid request descriptor") }, { BSM_ERRNO_EXFULL, #ifdef EXFULL EXFULL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Exchange full") }, + 1, ES("Exchange full") }, { BSM_ERRNO_ENOANO, #ifdef ENOANO ENOANO, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("No anode") }, + 1, ES("No anode") }, { BSM_ERRNO_EBADRQC, #ifdef EBADRQC EBADRQC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Invalid request descriptor") }, + 1, ES("Invalid request descriptor") }, { BSM_ERRNO_EBADSLT, #ifdef EBADSLT EBADSLT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Invalid slot") }, + 1, ES("Invalid slot") }, { BSM_ERRNO_EDEADLOCK, #ifdef EDEADLOCK EDEADLOCK, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Resource deadlock avoided") }, + 1, ES("Resource deadlock avoided") }, { BSM_ERRNO_EBFONT, #ifdef EBFONT EBFONT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Bad font file format") }, + 1, ES("Bad font file format") }, { BSM_ERRNO_EOWNERDEAD, #ifdef EOWNERDEAD EOWNERDEAD, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Process died with the lock") }, + 1, ES("Process died with the lock") }, { BSM_ERRNO_ENOTRECOVERABLE, #ifdef ENOTRECOVERABLE ENOTRECOVERABLE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Lock is not recoverable") }, + 1, ES("Lock is not recoverable") }, { BSM_ERRNO_ENOSTR, #ifdef ENOSTR ENOSTR, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Device not a stream") }, + 1, ES("Device not a stream") }, { BSM_ERRNO_ENONET, #ifdef ENONET ENONET, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Machine is not on the network") }, + 1, ES("Machine is not on the network") }, { BSM_ERRNO_ENOPKG, #ifdef ENOPKG ENOPKG, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Package not installed") }, + 1, ES("Package not installed") }, { BSM_ERRNO_EREMOTE, EREMOTE, - ES("Too many levels of remote in path") }, + 1, ES("Too many levels of remote in path") }, { BSM_ERRNO_ENOLINK, #ifdef ENOLINK ENOLINK, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Link has been severed") }, + 1, ES("Link has been severed") }, { BSM_ERRNO_EADV, #ifdef EADV EADV, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Advertise error") }, + 1, ES("Advertise error") }, { BSM_ERRNO_ESRMNT, #ifdef ESRMNT ESRMNT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("srmount error") }, + 1, ES("srmount error") }, { BSM_ERRNO_ECOMM, #ifdef ECOMM ECOMM, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Communication error on send") }, + 1, ES("Communication error on send") }, { BSM_ERRNO_EPROTO, #ifdef EPROTO EPROTO, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Protocol error") }, + 1, ES("Protocol error") }, { BSM_ERRNO_ELOCKUNMAPPED, #ifdef ELOCKUNMAPPED ELOCKUNMAPPED, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Locked lock was unmapped") }, + 1, ES("Locked lock was unmapped") }, { BSM_ERRNO_ENOTACTIVE, #ifdef ENOTACTIVE ENOTACTIVE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Facility is not active") }, + 1, ES("Facility is not active") }, { BSM_ERRNO_EMULTIHOP, #ifdef EMULTIHOP EMULTIHOP, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Multihop attempted") }, + 1, ES("Multihop attempted") }, { BSM_ERRNO_EBADMSG, #ifdef EBADMSG EBADMSG, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Bad message") }, - { BSM_ERRNO_ENAMETOOLONG, ENAMETOOLONG, ES("File name too long") }, + 1, ES("Bad message") }, + { BSM_ERRNO_ENAMETOOLONG, ENAMETOOLONG, 1, ES("File name too long") }, { BSM_ERRNO_EOVERFLOW, EOVERFLOW, - ES("Value too large to be stored in data type") }, + 1, ES("Value too large to be stored in data type") }, { BSM_ERRNO_ENOTUNIQ, #ifdef ENOTUNIQ ENOTUNIQ, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Given log name not unique") }, + 1, ES("Given log name not unique") }, { BSM_ERRNO_EBADFD, #ifdef EBADFD EBADFD, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Given f.d. invalid for this operation") }, + 1, ES("Given f.d. invalid for this operation") }, { BSM_ERRNO_EREMCHG, #ifdef EREMCHG EREMCHG, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Remote address changed") }, + 1, ES("Remote address changed") }, { BSM_ERRNO_ELIBACC, #ifdef ELIBACC ELIBACC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Can't access a needed shared lib") }, + 1, ES("Can't access a needed shared lib") }, { BSM_ERRNO_ELIBBAD, #ifdef ELIBBAD ELIBBAD, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Accessing a corrupted shared lib") }, + 1, ES("Accessing a corrupted shared lib") }, { BSM_ERRNO_ELIBSCN, #ifdef ELIBSCN ELIBSCN, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES(".lib section in a.out corrupted") }, + 1, ES(".lib section in a.out corrupted") }, { BSM_ERRNO_ELIBMAX, #ifdef ELIBMAX ELIBMAX, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Attempting to link in too many libs") }, + 1, ES("Attempting to link in too many libs") }, { BSM_ERRNO_ELIBEXEC, #ifdef ELIBEXEC ELIBEXEC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Attempting to exec a shared library") }, - { BSM_ERRNO_EILSEQ, EILSEQ, ES("Illegal byte sequence") }, - { BSM_ERRNO_ENOSYS, ENOSYS, ES("Function not implemented") }, - { BSM_ERRNO_ELOOP, ELOOP, ES("Too many levels of symbolic links") }, + 1, ES("Attempting to exec a shared library") }, + { BSM_ERRNO_EILSEQ, EILSEQ, 1, ES("Illegal byte sequence") }, + { BSM_ERRNO_ENOSYS, ENOSYS, 1, ES("Function not implemented") }, + { BSM_ERRNO_ELOOP, ELOOP, 1, ES("Too many levels of symbolic links") }, { BSM_ERRNO_ERESTART, #ifdef ERESTART ERESTART, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Restart syscall") }, + 1, ES("Restart syscall") }, { BSM_ERRNO_ESTRPIPE, #ifdef ESTRPIPE ESTRPIPE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("If pipe/FIFO, don't sleep in stream head") }, - { BSM_ERRNO_ENOTEMPTY, ENOTEMPTY, ES("Directory not empty") }, - { BSM_ERRNO_EUSERS, EUSERS, ES("Too many users") }, + 1, ES("If pipe/FIFO, don't sleep in stream head") }, + { BSM_ERRNO_ENOTEMPTY, ENOTEMPTY, 1, ES("Directory not empty") }, + { BSM_ERRNO_EUSERS, EUSERS, 1, ES("Too many users") }, { BSM_ERRNO_ENOTSOCK, ENOTSOCK, - ES("Socket operation on non-socket") }, + 1, ES("Socket operation on non-socket") }, { BSM_ERRNO_EDESTADDRREQ, EDESTADDRREQ, - ES("Destination address required") }, - { BSM_ERRNO_EMSGSIZE, EMSGSIZE, ES("Message too long") }, + 1, ES("Destination address required") }, + { BSM_ERRNO_EMSGSIZE, EMSGSIZE, 1, ES("Message too long") }, { BSM_ERRNO_EPROTOTYPE, EPROTOTYPE, - ES("Protocol wrong type for socket") }, - { BSM_ERRNO_ENOPROTOOPT, ENOPROTOOPT, ES("Protocol not available") }, + 1, ES("Protocol wrong type for socket") }, + { BSM_ERRNO_ENOPROTOOPT, ENOPROTOOPT, 1, ES("Protocol not available") }, { BSM_ERRNO_EPROTONOSUPPORT, EPROTONOSUPPORT, - ES("Protocol not supported") }, + 1, ES("Protocol not supported") }, { BSM_ERRNO_ESOCKTNOSUPPORT, ESOCKTNOSUPPORT, - ES("Socket type not supported") }, - { BSM_ERRNO_EOPNOTSUPP, EOPNOTSUPP, ES("Operation not supported") }, + 1, ES("Socket type not supported") }, + { BSM_ERRNO_EOPNOTSUPP, EOPNOTSUPP, 1, ES("Operation not supported") }, { BSM_ERRNO_EPFNOSUPPORT, EPFNOSUPPORT, - ES("Protocol family not supported") }, + 1, ES("Protocol family not supported") }, { BSM_ERRNO_EAFNOSUPPORT, EAFNOSUPPORT, - ES("Address family not supported by protocol family") }, - { BSM_ERRNO_EADDRINUSE, EADDRINUSE, ES("Address already in use") }, + 1, ES("Address family not supported by protocol family") }, + { BSM_ERRNO_EADDRINUSE, EADDRINUSE, 1, ES("Address already in use") }, { BSM_ERRNO_EADDRNOTAVAIL, EADDRNOTAVAIL, - ES("Can't assign requested address") }, - { BSM_ERRNO_ENETDOWN, ENETDOWN, ES("Network is down") }, + 1, ES("Can't assign requested address") }, + { BSM_ERRNO_ENETDOWN, ENETDOWN, 1, ES("Network is down") }, { BSM_ERRNO_ENETRESET, ENETRESET, - ES("Network dropped connection on reset") }, + 1, ES("Network dropped connection on reset") }, { BSM_ERRNO_ECONNABORTED, ECONNABORTED, - ES("Software caused connection abort") }, - { BSM_ERRNO_ECONNRESET, ECONNRESET, ES("Connection reset by peer") }, - { BSM_ERRNO_ENOBUFS, ENOBUFS, ES("No buffer space available") }, - { BSM_ERRNO_EISCONN, EISCONN, ES("Socket is already connected") }, - { BSM_ERRNO_ENOTCONN, ENOTCONN, ES("Socket is not connected") }, + 1, ES("Software caused connection abort") }, + { BSM_ERRNO_ECONNRESET, ECONNRESET, 1, ES("Connection reset by peer") }, + { BSM_ERRNO_ENOBUFS, ENOBUFS, 1, ES("No buffer space available") }, + { BSM_ERRNO_EISCONN, EISCONN, 1, ES("Socket is already connected") }, + { BSM_ERRNO_ENOTCONN, ENOTCONN, 1, ES("Socket is not connected") }, { BSM_ERRNO_ESHUTDOWN, ESHUTDOWN, - ES("Can't send after socket shutdown") }, + 1, ES("Can't send after socket shutdown") }, { BSM_ERRNO_ETOOMANYREFS, ETOOMANYREFS, - ES("Too many references: can't splice") }, - { BSM_ERRNO_ETIMEDOUT, ETIMEDOUT, ES("Operation timed out") }, - { BSM_ERRNO_ECONNREFUSED, ECONNREFUSED, ES("Connection refused") }, - { BSM_ERRNO_EHOSTDOWN, EHOSTDOWN, ES("Host is down") }, - { BSM_ERRNO_EHOSTUNREACH, EHOSTUNREACH, ES("No route to host") }, - { BSM_ERRNO_EALREADY, EALREADY, ES("Operation already in progress") }, + 1, ES("Too many references: can't splice") }, + { BSM_ERRNO_ETIMEDOUT, ETIMEDOUT, 1, ES("Operation timed out") }, + { BSM_ERRNO_ECONNREFUSED, ECONNREFUSED, 1, ES("Connection refused") }, + { BSM_ERRNO_EHOSTDOWN, EHOSTDOWN, 1, ES("Host is down") }, + { BSM_ERRNO_EHOSTUNREACH, EHOSTUNREACH, 1, ES("No route to host") }, + { BSM_ERRNO_EALREADY, EALREADY, 1, ES("Operation already in progress") }, { BSM_ERRNO_EINPROGRESS, EINPROGRESS, - ES("Operation now in progress") }, - { BSM_ERRNO_ESTALE, ESTALE, ES("Stale NFS file handle") }, + 1, ES("Operation now in progress") }, + { BSM_ERRNO_ESTALE, ESTALE, 1, ES("Stale NFS file handle") }, { BSM_ERRNO_EPROCLIM, #ifdef EPROCLIM EPROCLIM, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Too many processes") }, + 1, ES("Too many processes") }, { BSM_ERRNO_EBADRPC, #ifdef EBADRPC EBADRPC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("RPC struct is bad") }, + 1, ES("RPC struct is bad") }, { BSM_ERRNO_ERPCMISMATCH, #ifdef ERPCMISMATCH ERPCMISMATCH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("RPC version wrong") }, + 1, ES("RPC version wrong") }, { BSM_ERRNO_EPROGUNAVAIL, #ifdef EPROGUNAVAIL EPROGUNAVAIL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("RPC prog. not avail") }, + 1, ES("RPC prog. not avail") }, { BSM_ERRNO_EPROGMISMATCH, #ifdef EPROGMISMATCH EPROGMISMATCH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("RPC version wrong") }, + 1, ES("RPC version wrong") }, { BSM_ERRNO_EPROCUNAVAIL, #ifdef EPROCUNAVAIL EPROCUNAVAIL, #else - ERRNO_NO_LOCAL_MAPPING + ERRNO_NO_LOCAL_MAPPING, #endif - ES("Bad procedure for program") }, + 1, ES("Bad procedure for program") }, { BSM_ERRNO_EFTYPE, #ifdef EFTYPE EFTYPE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Inappropriate file type or format") }, + 1, ES("Inappropriate file type or format") }, { BSM_ERRNO_EAUTH, #ifdef EAUTH EAUTH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Authenticateion error") }, + 1, ES("Authenticateion error") }, { BSM_ERRNO_ENEEDAUTH, #ifdef ENEEDAUTH ENEEDAUTH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Need authenticator") }, + 1, ES("Need authenticator") }, { BSM_ERRNO_ENOATTR, #ifdef ENOATTR ENOATTR, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Attribute not found") }, + 1, ES("Attribute not found") }, { BSM_ERRNO_EDOOFUS, #ifdef EDOOFUS EDOOFUS, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Programming error") }, + 1, ES("Programming error") }, { BSM_ERRNO_EJUSTRETURN, #ifdef EJUSTRETURN EJUSTRETURN, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Just return") }, + 1, ES("Just return") }, { BSM_ERRNO_ENOIOCTL, #ifdef ENOIOCTL ENOIOCTL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("ioctl not handled by this layer") }, + 1, ES("ioctl not handled by this layer") }, { BSM_ERRNO_EDIRIOCTL, #ifdef EDIRIOCTL EDIRIOCTL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("do direct ioctl in GEOM") }, + 1, ES("do direct ioctl in GEOM") }, { BSM_ERRNO_EPWROFF, #ifdef EPWROFF EPWROFF, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Device power is off") }, + 1, ES("Device power is off") }, { BSM_ERRNO_EDEVERR, #ifdef EDEVERR EDEVERR, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Device error") }, + 1, ES("Device error") }, { BSM_ERRNO_EBADEXEC, #ifdef EBADEXEC EBADEXEC, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Bad executable") }, + 1, ES("Bad executable") }, { BSM_ERRNO_EBADARCH, #ifdef EBADARCH EBADARCH, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Bad CPU type in executable") }, + 1, ES("Bad CPU type in executable") }, { BSM_ERRNO_ESHLIBVERS, #ifdef ESHLIBVERS ESHLIBVERS, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Shared library version mismatch") }, + 1, ES("Shared library version mismatch") }, { BSM_ERRNO_EBADMACHO, #ifdef EBADMACHO EBADMACHO, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Malformed Macho file") }, + 1, ES("Malformed Macho file") }, { BSM_ERRNO_EPOLICY, #ifdef EPOLICY EPOLICY, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Operation failed by policy") }, + 1, ES("Operation failed by policy") }, { BSM_ERRNO_EDOTDOT, #ifdef EDOTDOT EDOTDOT, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("RFS specific error") }, + 1, ES("RFS specific error") }, { BSM_ERRNO_EUCLEAN, #ifdef EUCLEAN EUCLEAN, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Structure needs cleaning") }, + 1, ES("Structure needs cleaning") }, { BSM_ERRNO_ENOTNAM, #ifdef ENOTNAM ENOTNAM, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Not a XENIX named type file") }, + 1, ES("Not a XENIX named type file") }, { BSM_ERRNO_ENAVAIL, #ifdef ENAVAIL ENAVAIL, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("No XENIX semaphores available") }, + 1, ES("No XENIX semaphores available") }, { BSM_ERRNO_EISNAM, #ifdef EISNAM EISNAM, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Is a named type file") }, + 1, ES("Is a named type file") }, { BSM_ERRNO_EREMOTEIO, #ifdef EREMOTEIO EREMOTEIO, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Remote I/O error") }, + 1, ES("Remote I/O error") }, { BSM_ERRNO_ENOMEDIUM, #ifdef ENOMEDIUM ENOMEDIUM, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("No medium found") }, + 1, ES("No medium found") }, { BSM_ERRNO_EMEDIUMTYPE, #ifdef EMEDIUMTYPE EMEDIUMTYPE, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Wrong medium type") }, + 1, ES("Wrong medium type") }, { BSM_ERRNO_ENOKEY, #ifdef ENOKEY ENOKEY, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Required key not available") }, + 1, ES("Required key not available") }, { BSM_ERRNO_EKEYEXPIRED, #ifdef EKEEXPIRED EKEYEXPIRED, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Key has expired") }, + 1, ES("Key has expired") }, { BSM_ERRNO_EKEYREVOKED, #ifdef EKEYREVOKED EKEYREVOKED, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Key has been revoked") }, + 1, ES("Key has been revoked") }, { BSM_ERRNO_EKEYREJECTED, -#ifdef EKEREJECTED +#ifdef EKEYREJECTED EKEYREJECTED, #else ERRNO_NO_LOCAL_MAPPING, #endif - ES("Key was rejected by service") }, + 1, ES("Key was rejected by service") }, + { BSM_NFS_ERRNO_WFLUSH, +#ifdef NFSERR_WFLUSH + NFSERR_WFLUSH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("The server's write cache used in the WRITECACHE call got flushed to disk") }, + { BSM_NFS_ERRNO_BADHANDLE, +#ifdef NFSERR_BADHANDLE + NFSERR_BADHANDLE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("Illegal NFS filehandle") }, + { BSM_NFS_ERRNO_NOT_SYNC, +#ifdef NFSERR_NOT_SYNC + NFSERR_NOT_SYNC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("Update synchronization mismatch detected during a SETATTR operation") }, + { BSM_NFS_ERRNO_BAD_COOKIE, +#ifdef NFSERR_BAD_COOKIE + NFSERR_BAD_COOKIE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("READDIR cookie is stale") }, + { BSM_NFS_ERRNO_NOTSUPP, +#ifdef NFSERR_NOTSUPP + NFSERR_NOTSUPP, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("operation not supported") }, + { BSM_NFS_ERRNO_TOOSMALL, +#ifdef NFSERR_TOOSMALL + NFSERR_TOOSMALL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("response limit exceeded") }, + { BSM_NFS_ERRNO_SERVERFAULT, +#ifdef NFSERR_SERVERFAULT + NFSERR_SERVERFAULT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("undefined server error") }, + { BSM_NFS_ERRNO_BADTYPE, +#ifdef NFSERR_BADTYPE + NFSERR_BADTYPE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("type invalid for CREATE") }, + { BSM_NFS_ERRNO_DELAY, +#ifdef NFSERR_DELAY + NFSERR_DELAY, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("file \"busy\" - retry") }, + { BSM_NFS_ERRNO_SAME, +#ifdef NFSERR_SAME + NFSERR_SAME, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("nverify says attrs same") }, + { BSM_NFS_ERRNO_DENIED, +#ifdef NFSERR_DENIED + NFSERR_DENIED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("lock unavailable") }, + { BSM_NFS_ERRNO_EXPIRED, +#ifdef NFSERR_EXPIRED + NFSERR_EXPIRED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("lock lease expired") }, + { BSM_NFS_ERRNO_LOCKED, +#ifdef NFSERR_LOCKED + NFSERR_LOCKED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("I/O failed due to lock") }, + { BSM_NFS_ERRNO_GRACE, +#ifdef NFSERR_GRACE + NFSERR_GRACE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("in grace period") }, + { BSM_NFS_ERRNO_FHEXPIRED, +#ifdef NFSERR_FHEXPIRED + NFSERR_FHEXPIRED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("filehandle expired") }, + { BSM_NFS_ERRNO_SHAREDENIED, +#ifdef NFSERR_SHAREDENIED + NFSERR_SHAREDENIED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("share reserve denied") }, + { BSM_NFS_ERRNO_WRONGSEC, +#ifdef NFSERR_WRONGSEC + NFSERR_WRONGSEC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("wrong security flavor") }, + { BSM_NFS_ERRNO_CLIDINUSE, +#ifdef NFSERR_CLIDINUSE + NFSERR_CLIDINUSE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("clientid in use") }, + { BSM_NFS_ERRNO_RESOURCE, +#ifdef NFSERR_RESOURCE + NFSERR_RESOURCE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("resource exhaustion") }, + { BSM_NFS_ERRNO_MOVED, +#ifdef NFSERR_MOVED + NFSERR_MOVED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("filesystem relocated") }, + { BSM_NFS_ERRNO_NOFILEHANDLE, +#ifdef NFSERR_NOFILEHANDLE + NFSERR_NOFILEHANDLE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("current FH is not set") }, + { BSM_NFS_ERRNO_MINORVERMISMATCH, +#ifdef NFSERR_MINORVERMISMATCH + NFSERR_MINORVERMISMATCH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("minor vers not supp") }, + { BSM_NFS_ERRNO_STALECLIENTID, +#ifdef NFSERR_STALECLIENTID + NFSERR_STALECLIENTID, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("server has rebooted") }, + { BSM_NFS_ERRNO_STALESTATEID, +#ifdef NFSERR_STALESTATEID + NFSERR_STALESTATEID, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("server has rebooted") }, + { BSM_NFS_ERRNO_OLDSTATEID, +#ifdef NFSERR_OLDSTATEID + NFSERR_OLDSTATEID, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("state is out of sync") }, + { BSM_NFS_ERRNO_BADSTATEID, +#ifdef NFSERR_BADSTATEID + NFSERR_BADSTATEID, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("incorrect stateid") }, + { BSM_NFS_ERRNO_BADSEQID, +#ifdef NFSERR_BADSEQID + NFSERR_BADSEQID, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("request is out of seq") }, + { BSM_NFS_ERRNO_NOTSAME, +#ifdef NFSERR_NOTSAME + NFSERR_NOTSAME, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("verify - attrs not same") }, + { BSM_NFS_ERRNO_LOCKRANGE, +#ifdef NFSERR_LOCKRANGE + NFSERR_LOCKRANGE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("lock range not supported") }, + { BSM_NFS_ERRNO_SYMLINK, +#ifdef NFSERR_SYMLINK + NFSERR_SYMLINK, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("should be file/directory") }, + { BSM_NFS_ERRNO_RESTOREFH, +#ifdef NFSERR_RESTOREFH + NFSERR_RESTOREFH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("no saved filehandle") }, + { BSM_NFS_ERRNO_LEASEMOVED, +#ifdef NFSERR_LEASEMOVED + NFSERR_LEASEMOVED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("some filesystem moved") }, + { BSM_NFS_ERRNO_ATTRNOTSUPP, +#ifdef NFSERR_ATTRNOTSUPP + NFSERR_ATTRNOTSUPP, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("recommended attr not sup") }, + { BSM_NFS_ERRNO_NOGRACE, +#ifdef NFSERR_NOGRACE + NFSERR_NOGRACE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("reclaim outside of grace") }, + { BSM_NFS_ERRNO_RECLAIMBAD, +#ifdef NFSERR_RECLAIMBAD + NFSERR_RECLAIMBAD, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("reclaim error at server") }, + { BSM_NFS_ERRNO_RECLAIMCONFLICT, +#ifdef NFSERR_RECLAIMCONFLICT + NFSERR_RECLAIMCONFLICT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("conflict on reclaim") }, + { BSM_NFS_ERRNO_BADXDR, +#ifdef NFSERR_BADXDR + NFSERR_BADXDR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("XDR decode failed") }, + { BSM_NFS_ERRNO_LOCKSHELD, +#ifdef NFSERR_LOCKSHELD + NFSERR_LOCKSHELD, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("file locks held at CLOSE") }, + { BSM_NFS_ERRNO_OPENMODE, +#ifdef NFSERR_OPENMODE + NFSERR_OPENMODE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("conflict in OPEN and I/O") }, + { BSM_NFS_ERRNO_BADOWNER, +#ifdef NFSERR_BADOWNER + NFSERR_BADOWNER, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("owner translation bad") }, + { BSM_NFS_ERRNO_BADCHAR, +#ifdef NFSERR_BADCHAR + NFSERR_BADCHAR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("utf-8 char not supported") }, + { BSM_NFS_ERRNO_BADNAME, +#ifdef NFSERR_BADNAME + NFSERR_BADNAME, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("name not supported") }, + { BSM_NFS_ERRNO_BADRANGE, +#ifdef NFSERR_BADRANGE + NFSERR_BADRANGE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("lock range not supported") }, + { BSM_NFS_ERRNO_LOCKNOTSUPP, +#ifdef NFSERR_LOCKNOTSUPP + NFSERR_LOCKNOTSUPP, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("no atomic up/downgrade") }, + { BSM_NFS_ERRNO_OPILLEGAL, +#ifdef NFSERR_OPILLEGAL + NFSERR_OPILLEGAL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("undefined operation") }, + { BSM_NFS_ERRNO_DEADLOCK, +#ifdef NFSERR_DEADLOCK + NFSERR_DEADLOCK, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("file locking deadlock") }, + { BSM_NFS_ERRNO_FILEOPEN, +#ifdef NFSERR_FILEOPEN + NFSERR_FILEOPEN, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("open file blocks op") }, + { BSM_NFS_ERRNO_ADMINREVOKED, +#ifdef NFSERR_ADMINREVOKED + NFSERR_ADMINREVOKED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("lockowner state revoked") }, + { BSM_NFS_ERRNO_CBPATHDOWN, +#ifdef NFSERR_CBPATHDOWN + NFSERR_CBPATHDOWN, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + 0, ES("callback path down") }, }; static const int bsm_errnos_count = sizeof(bsm_errnos) / sizeof(bsm_errnos[0]); @@ -705,7 +1050,7 @@ * Conversion to the BSM errno space isn't allowed to fail; we simply map to * BSM_ERRNO_UNKNOWN and let the remote endpoint deal with it. */ -u_char +int au_errno_to_bsm(int local_errno) { const struct bsm_errno *bsme; @@ -717,7 +1062,7 @@ } static const struct bsm_errno * -bsm_lookup_errno_bsm(u_char bsm_errno) +bsm_lookup_errno_bsm(int bsm_errno) { int i; @@ -734,7 +1079,7 @@ * appropriate local mapping. */ int -au_bsm_to_errno(u_char bsm_errno, int *errorp) +au_bsm_to_errno(int bsm_errno, int *errorp) { const struct bsm_errno *bsme; @@ -747,14 +1092,14 @@ #if !defined(KERNEL) && !defined(_KERNEL) const char * -au_strerror(u_char bsm_errno) +au_strerror(int bsm_errno) { const struct bsm_errno *bsme; bsme = bsm_lookup_errno_bsm(bsm_errno); if (bsme == NULL) return ("Unrecognized BSM error"); - if (bsme->be_local_errno != ERRNO_NO_LOCAL_MAPPING) + if (bsme->be_local_errno != ERRNO_NO_LOCAL_MAPPING && bsme->be_use_strerror != 0) return (strerror(bsme->be_local_errno)); return (bsme->be_strerror); } --- //depot/vendor/freebsd/src/sys/security/audit/audit_bsm_klib.c 2009-07-28 21:45:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/security/audit/audit_bsm_klib.c 2010-08-16 13:30:34.000000000 0000 @@ -112,6 +112,22 @@ }; static const int aue_openat_count = sizeof(aue_openat) / sizeof(aue_openat[0]); +static const struct aue_open_event aue_nfs_open[] = { + { NFS_READACCESS, AUE_NFS_OPEN_R }, + { (NFS_READACCESS | NFS_CREATE), AUE_NFS_OPEN_RC }, + { (NFS_READACCESS | NFS_CREATE | NFS_TRUNC), AUE_NFS_OPEN_RTC }, + { (NFS_READACCESS | NFS_TRUNC), AUE_NFS_OPEN_RT }, + { NFS_RWACCESS, AUE_NFS_OPEN_RW }, + { (NFS_RWACCESS | NFS_CREATE), AUE_NFS_OPEN_RWC }, + { (NFS_RWACCESS | NFS_CREATE | NFS_TRUNC), AUE_NFS_OPEN_RWTC }, + { (NFS_RWACCESS | NFS_TRUNC), AUE_NFS_OPEN_RWT }, + { NFS_WRITEACCESS, AUE_NFS_OPEN_W }, + { (NFS_WRITEACCESS | NFS_CREATE), AUE_NFS_OPEN_WC }, + { (NFS_WRITEACCESS | NFS_CREATE | NFS_TRUNC), AUE_NFS_OPEN_WTC }, + { (NFS_WRITEACCESS | NFS_TRUNC), AUE_NFS_OPEN_WT }, +}; +static const int aue_nfs_open_count = sizeof(aue_nfs_open) / sizeof(aue_nfs_open[0]); + /* * Look up the class for an audit event in the class mapping table. */ @@ -319,6 +335,26 @@ return (AUE_OPENAT); } +au_event_t +audit_flags_to_nfs_openevent(int oflags) +{ + int i; + + /* + * Need to check only those flags we care about. + * XXXgpf: As it turns out, POSIX clients (including FreeBSD's + * client) will always provide DENY_NONE; ignore deny bits + * when determining a specific event type + */ + oflags = oflags & (NFS_READACCESS | NFS_WRITEACCESS | NFS_READDENY + | NFS_WRITEDENY | NFS_CREATE | NFS_TRUNC); + for (i = 0; i < aue_nfs_open_count; i++) { + if (aue_nfs_open[i].aoe_flags == oflags) + return (aue_nfs_open[i].aoe_event); + } + return (AUE_NFS_OPEN); +} + /* * Convert a MSGCTL command to a specific event. */ --- //depot/vendor/freebsd/src/sys/security/audit/audit_bsm_token.c 2009-09-08 13:25:13.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/security/audit/audit_bsm_token.c 2010-08-07 16:49:25.000000000 0000 @@ -581,6 +581,24 @@ /* * token ID 1 byte + * vtype 4 bytes + */ +token_t * +au_to_vtype(u_int32_t vtype) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); + + ADD_U_CHAR(dptr, AUT_VTYPE); + ADD_U_INT32(dptr, vtype); + + return (t); +} + +/* + * token ID 1 byte * path length 2 bytes * path N bytes + 1 terminating NULL byte */ @@ -786,41 +804,59 @@ /* * token ID 1 byte - * error status 1 byte + * protocol 4 bytes + */ +token_t * +au_to_protocol(u_int32_t protocol) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); + + ADD_U_CHAR(dptr, AUT_PROTOCOL); + ADD_U_INT32(dptr, protocol); + + return (t); +} + +/* + * token ID 1 byte + * error status 4 bytes * return value 4 bytes/8 bytes (32-bit/64-bit value) */ token_t * -au_to_return32(char status, u_int32_t ret) +au_to_return32(u_int32_t status, u_int32_t ret) { token_t *t; u_char *dptr = NULL; - GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + sizeof(u_int32_t)); ADD_U_CHAR(dptr, AUT_RETURN32); - ADD_U_CHAR(dptr, status); + ADD_U_INT32(dptr, status); ADD_U_INT32(dptr, ret); return (t); } token_t * -au_to_return64(char status, u_int64_t ret) +au_to_return64(u_int32_t status, u_int64_t ret) { token_t *t; u_char *dptr = NULL; - GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t)); + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + sizeof(u_int64_t)); ADD_U_CHAR(dptr, AUT_RETURN64); - ADD_U_CHAR(dptr, status); + ADD_U_INT32(dptr, status); ADD_U_INT64(dptr, ret); return (t); } token_t * -au_to_return(char status, u_int32_t ret) +au_to_return(u_int32_t status, u_int32_t ret) { return (au_to_return32(status, ret)); --- //depot/vendor/freebsd/src/sys/security/audit/audit_private.h 2009-07-29 07:50:15.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/security/audit/audit_private.h 2010-08-07 16:49:25.000000000 0000 @@ -51,6 +51,9 @@ MALLOC_DECLARE(M_AUDITPATH); MALLOC_DECLARE(M_AUDITTEXT); MALLOC_DECLARE(M_AUDITGIDSET); +MALLOC_DECLARE(M_AUDITLOCKOWNER); +MALLOC_DECLARE(M_AUDITCLIENTNAME); +MALLOC_DECLARE(M_AUDITRECORD); #endif /* @@ -229,6 +232,12 @@ int ar_arg_exitstatus; int ar_arg_exitretval; struct sockaddr_storage ar_arg_sockaddr; + int ar_arg_protocol; + int ar_arg_vtype; + uint64_t ar_arg_clientid; + char *ar_arg_lockowner; + int ar_arg_locktype; + char *ar_arg_clientname; }; /* @@ -259,7 +268,7 @@ #define ARG_SADDRINET 0x0000000000100000ULL #define ARG_SADDRINET6 0x0000000000200000ULL #define ARG_SADDRUNIX 0x0000000000400000ULL -#define ARG_TERMID_ADDR 0x0000000000400000ULL +#define ARG_TERMID_ADDR 0x0000000000800000ULL #define ARG_UNUSED2 0x0000000001000000ULL #define ARG_UPATH1 0x0000000002000000ULL #define ARG_UPATH2 0x0000000004000000ULL @@ -288,29 +297,40 @@ #define ARG_ENVV 0x0002000000000000ULL #define ARG_ATFD1 0x0004000000000000ULL #define ARG_ATFD2 0x0008000000000000ULL +#define ARG_VTYPE 0x0010000000000000ULL +#define ARG_PROTOCOL 0x0020000000000000ULL +#define ARG_CLIENTID 0x0040000000000000ULL +#define ARG_LOCKOWNER 0x0080000000000000ULL +#define ARG_LOCKTYPE 0x0100000000000000ULL +#define ARG_CLIENTNAME 0x0200000000000000ULL #define ARG_NONE 0x0000000000000000ULL #define ARG_ALL 0xFFFFFFFFFFFFFFFFULL -#define ARG_IS_VALID(kar, arg) ((kar)->k_ar.ar_valid_arg & (arg)) +#define ARG_IS_VALID(kar, arg) ((kar)->k_ar->ar_valid_arg & (arg)) #define ARG_SET_VALID(kar, arg) do { \ - (kar)->k_ar.ar_valid_arg |= (arg); \ + (kar)->k_ar->ar_valid_arg |= (arg); \ } while (0) #define ARG_CLEAR_VALID(kar, arg) do { \ - (kar)->k_ar.ar_valid_arg &= ~(arg); \ + (kar)->k_ar->ar_valid_arg &= ~(arg); \ } while (0) /* - * In-kernel version of audit record; the basic record plus queue meta-data. + * In-kernel version of audit record; the basic record plus queue meta-data, + * plus the necessary elements to maintain a tree like structure of multiple + * audit records per kernel thread. * This record can also have a pointer set to some opaque data that will be * passed through to the audit writing mechanism. */ struct kaudit_record { - struct audit_record k_ar; + struct audit_record *k_ar; u_int32_t k_ar_commit; void *k_udata; /* User data. */ u_int k_ulen; /* User data length. */ struct uthread *k_uthread; /* Audited thread. */ TAILQ_ENTRY(kaudit_record) k_q; + struct kaudit_record *k_parent; /* parent record */ + STAILQ_ENTRY(kaudit_record) k_record_q; + STAILQ_HEAD(kaudit_children_q, kaudit_record) kaudit_children_q; /* queue for children records */ }; TAILQ_HEAD(kaudit_queue, kaudit_record); @@ -319,11 +339,32 @@ * records. */ void audit_abort(struct kaudit_record *ar); -void audit_commit(struct kaudit_record *ar, int error, - int retval); +void audit_commit(struct kaudit_record *ar); struct kaudit_record *audit_new(int event, struct thread *td); /* + * Functions to manage the per thread audit record tree structure + */ + +void audit_tree_commit(struct kaudit_record *ar, int *signal_worker); +void audit_tree_go_up(struct thread *td); +void audit_tree_insert(struct thread *td, struct kaudit_record *ar); + +/* + * NFS specific stuff + */ +int audit_nfs_proc_to_event(unsigned int proc, au_event_t *event, int nfsprot); + +#define NFS_READACCESS 0x00000001 +#define NFS_WRITEACCESS 0x00000002 +#define NFS_RWACCESS NFS_READACCESS | NFS_WRITEACCESS +#define NFS_READDENY 0x00000004 +#define NFS_WRITEDENY 0x00000008 +#define NFS_RWDENY NFS_READDENY | NFS_WRITEDENY +#define NFS_CREATE 0x00000010 +#define NFS_TRUNC 0x00000020 + +/* * Functions relating to the conversion of internal kernel audit records to * the BSM file format. */ @@ -384,6 +425,7 @@ au_event_t audit_ctlname_to_sysctlevent(int name[], uint64_t valid_arg); au_event_t audit_flags_and_error_to_openevent(int oflags, int error); au_event_t audit_flags_and_error_to_openatevent(int oflags, int error); +au_event_t audit_flags_to_nfs_openevent(int oflags); au_event_t audit_msgctl_to_event(int cmd); au_event_t audit_semctl_to_event(int cmr); void audit_canon_path(struct thread *td, char *path, char *cpath); --- //depot/vendor/freebsd/src/sys/security/audit/audit_worker.c 2009-05-11 15:35:16.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/security/audit/audit_worker.c 2010-07-19 14:34:02.000000000 0000 @@ -342,10 +342,10 @@ (ar->k_ar_commit & AR_PRESELECT_TRAIL) == 0)) goto out; - auid = ar->k_ar.ar_subj_auid; - event = ar->k_ar.ar_event; + auid = ar->k_ar->ar_subj_auid; + event = ar->k_ar->ar_event; class = au_event_class(event); - if (ar->k_ar.ar_errno == 0) + if (ar->k_ar->ar_errno == 0) sorf = AU_PRS_SUCCESS; else sorf = AU_PRS_FAILURE; --- //depot/vendor/freebsd/src/sys/sys/mount.h 2010-04-24 07:10:17.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/sys/mount.h 2010-05-27 14:41:11.000000000 0000 @@ -567,6 +567,7 @@ typedef int vfs_vget_t(struct mount *mp, ino_t ino, int flags, struct vnode **vpp); typedef int vfs_fhtovp_t(struct mount *mp, struct fid *fhp, struct vnode **vpp); +typedef int vfs_fhhint_t(struct mount *mp, struct fid *fhp, uint64_t *hint); typedef int vfs_checkexp_t(struct mount *mp, struct sockaddr *nam, int *extflagsp, struct ucred **credanonp, int *numsecflavors, int **secflavors); @@ -590,6 +591,7 @@ vfs_sync_t *vfs_sync; vfs_vget_t *vfs_vget; vfs_fhtovp_t *vfs_fhtovp; + vfs_fhhint_t *vfs_fhhint; vfs_checkexp_t *vfs_checkexp; vfs_init_t *vfs_init; vfs_uninit_t *vfs_uninit; @@ -612,6 +614,8 @@ (*(MP)->mnt_op->vfs_vget)(MP, INO, FLAGS, VPP) #define VFS_FHTOVP(MP, FIDP, VPP) \ (*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, VPP) +#define VFS_FHHINT(MP, FIDP, HINT) \ + (*(MP)->mnt_op->vfs_fhhint)(MP, FIDP, HINT) #define VFS_CHECKEXP(MP, NAM, EXFLG, CRED, NUMSEC, SEC) \ (*(MP)->mnt_op->vfs_checkexp)(MP, NAM, EXFLG, CRED, NUMSEC, SEC) #define VFS_EXTATTRCTL(MP, C, FN, NS, N) \ @@ -763,6 +767,7 @@ vfs_sync_t vfs_stdnosync; vfs_vget_t vfs_stdvget; vfs_fhtovp_t vfs_stdfhtovp; +vfs_fhhint_t vfs_stdfhhint; vfs_checkexp_t vfs_stdcheckexp; vfs_init_t vfs_stdinit; vfs_uninit_t vfs_stduninit; --- //depot/vendor/freebsd/src/sys/sys/vnode.h 2010-04-02 14:05:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/sys/vnode.h 2010-05-27 14:41:11.000000000 0000 @@ -609,6 +609,8 @@ char **retbuf, char **freebuf); int vn_fullpath_global(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf); +int vn_fullpath_nocache(struct vnode *vp, char **fullpath, + char **freepath, uint64_t directory_hint, char flags); int vn_commname(struct vnode *vn, char *buf, u_int buflen); int vaccess(enum vtype type, mode_t file_mode, uid_t file_uid, gid_t file_gid, accmode_t accmode, struct ucred *cred, @@ -693,6 +695,7 @@ int vop_stdpoll(struct vop_poll_args *); int vop_stdvptocnp(struct vop_vptocnp_args *ap); int vop_stdvptofh(struct vop_vptofh_args *ap); +int vop_stdgetparent(struct vop_getparent_args *ap); int vop_eopnotsupp(struct vop_generic_args *ap); int vop_ebadf(struct vop_generic_args *ap); int vop_einval(struct vop_generic_args *ap); --- //depot/vendor/freebsd/src/sys/ufs/ffs/ffs_vfsops.c 2010-04-29 10:05:14.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/ufs/ffs/ffs_vfsops.c 2010-05-27 14:41:11.000000000 0000 @@ -88,11 +88,13 @@ static vfs_mount_t ffs_mount; static vfs_statfs_t ffs_statfs; static vfs_fhtovp_t ffs_fhtovp; +static vfs_fhhint_t ffs_fhhint; static vfs_sync_t ffs_sync; static struct vfsops ufs_vfsops = { .vfs_extattrctl = ffs_extattrctl, .vfs_fhtovp = ffs_fhtovp, + .vfs_fhhint = ffs_fhhint, .vfs_init = ffs_init, .vfs_mount = ffs_mount, .vfs_cmount = ffs_cmount, @@ -1631,6 +1633,19 @@ } /* + * Get Parent Directory Hint from the File Handle + */ +static int +ffs_fhhint(struct mount *mp, struct fid *fhp, uint64_t *hint) +{ + struct ufid *ufhp; + + ufhp = (struct ufid *)fhp; + *hint = ufhp->ufid_dino; + return (0); +} + +/* * Initialize the filesystem. */ static int --- //depot/vendor/freebsd/src/sys/ufs/ffs/ffs_vnops.c 2010-04-24 07:10:17.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/ufs/ffs/ffs_vnops.c 2010-08-02 18:01:42.000000000 0000 @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -119,7 +120,7 @@ static vop_openextattr_t ffs_openextattr; static vop_setextattr_t ffs_setextattr; static vop_vptofh_t ffs_vptofh; - +static vop_getparent_t ffs_getparent; /* Global vfs data structures for ufs. */ struct vop_vector ffs_vnodeops1 = { @@ -131,6 +132,7 @@ .vop_reallocblks = ffs_reallocblks, .vop_write = ffs_write, .vop_vptofh = ffs_vptofh, + .vop_getparent = ffs_getparent, }; struct vop_vector ffs_fifoops1 = { @@ -156,6 +158,7 @@ .vop_openextattr = ffs_openextattr, .vop_setextattr = ffs_setextattr, .vop_vptofh = ffs_vptofh, + .vop_getparent = ffs_getparent, }; struct vop_vector ffs_fifoops2 = { @@ -1771,16 +1774,274 @@ vop_vptofh { IN struct vnode *a_vp; IN struct fid *a_fhp; + IN struct vnode *a_dvp; }; */ { - struct inode *ip; + struct inode *ip, *dip; struct ufid *ufhp; ip = VTOI(ap->a_vp); ufhp = (struct ufid *)ap->a_fhp; ufhp->ufid_len = sizeof(struct ufid); ufhp->ufid_ino = ip->i_number; - ufhp->ufid_gen = ip->i_gen; + ufhp->ufid_gen = ip->i_gen; + if (ap->a_dvp != NULL) { + dip = VTOI(ap->a_dvp); + ufhp->ufid_dino = dip->i_number; + } return (0); } + +/* + * XXXgpf: should relocate them someplace else + * I just dont know where:S + */ +#define PARENTHINT 0x0001 +#define EXHAUSTSEARCH 0x0002 +#define WANTNAME 0x0004 + +/* + * XXXgpf: this function is used by VOP_GETPARENT + * + * find 'a' name that is used to reference vp inside some parent directory. + * flags should be set to WANTNAME if the filename should be copied to + * the supplied buffer, in which case the supplied buffer should be != NULL. + * + * flags should be set to EXHAUSTSEARCH if want to perform a depth first search + * on the filesystem that contains vp. In this case, tmpdvp should be the root vnode + * of the filesystem. If a parent directory is found, dvp will point to it, unless the + * third parameter is NULL which is a bad idea because that vnode will be locked/referenced on success + * and needs to be vput()d by the caller. + * + * If flags is not set to EXHAUSTSEARCH, only tmpdvp will be searched for the vnode in question - vp. + * In this case, it is acceptable to provide NULL as the third parameter. + * + * locks: tmpdvp must be locked on entry and will still be locked on exit. + * If we are performing an exhaustive search, dvp will be locked and have its reference count incremented + * on success. + * + * returns: + * - ENOENT a file that corresponds to vp was not found inside dvp, + * or dvp is not a directory vnode + * - EIO error occured while reading the directory + * - EOVERFLOW result does not fit in buffer "name" + */ +static int +dir_ilookup(struct vnode *vp, struct vnode *tmpdvp, struct vnode **dvp, char *name, int *namelen, int flags) +{ + struct uio io; + struct iovec iov; + struct dirent *dp, *edp; + struct thread *td; + struct mount *mp; + struct vnode *childvp; + char *dirbuf; + u_int64_t dirbuflen; + int error, eofflag; + char foundit; + + if (tmpdvp->v_type != VDIR) { + return ENOENT; + } + + foundit = 0; + mp = vp->v_mount; + dirbuflen = ((struct inode *)tmpdvp->v_data)->i_size; + dirbuf = malloc(dirbuflen, M_TEMP, M_WAITOK); + td = curthread; + + /* prep the call to VOP_READDIR() */ + iov.iov_base = dirbuf; + iov.iov_len = dirbuflen; + io.uio_iov = &iov; + io.uio_iovcnt = 1; + io.uio_offset = 0; + io.uio_resid = dirbuflen; + io.uio_segflg = UIO_SYSSPACE; + io.uio_rw = UIO_READ; + io.uio_td = td; + eofflag = 0; + + error = VOP_READDIR(tmpdvp, &io, td->td_ucred, &eofflag, NULL, NULL); + if (error) { + error = EIO; + goto out; + } + + /* search for the correct inode number inside the directory */ + edp = (struct dirent *)&dirbuf[dirbuflen - io.uio_resid]; + for (dp = (struct dirent *)dirbuf; dp < edp; ) { + if (!strcmp(((struct dirent *)dp)->d_name, ".") || + !strcmp(((struct dirent *)dp)->d_name, "..")) { + dp = (struct dirent *)((char *)dp + dp->d_reclen); + continue; + } + + if (dp->d_reclen > 0) { + /* found it */ + if ( ((struct inode *)vp->v_data)->i_number == ((struct dirent *)dp)->d_fileno) { + char *pch; + int len; + + if (dvp != NULL) + *dvp = tmpdvp; + + if (flags & WANTNAME) { + pch = ((struct dirent *)dp)->d_name; + len = strlen(pch); + + if (len >= *namelen) { + error = ENOMEM; + goto out; + } + + strlcpy(name, ((struct dirent *)dp)->d_name, *namelen); + *namelen -= len + 1; + } + + foundit = 1; + error = 0; + break; + } + /* recusivly traverse the fs if we have the EXHAUSTSEARCH flag set */ + else if ((flags & EXHAUSTSEARCH) && ((struct dirent *)dp)->d_type == DT_DIR) { + error = VFS_VGET(mp, ((struct dirent *)dp)->d_fileno, LK_SHARED, &childvp); + /* no reason to traverse other filesystems */ + if (!error && !(childvp->v_vflag & VV_ROOT)) { + error = dir_ilookup(vp, childvp, dvp, name, namelen, flags); + if (error) { + vput(childvp); + } + /* don't vput the directory vnode that contains vp */ + else if (childvp != *dvp) { + vput(childvp); + } + + if (!error) { + foundit = 1; + break; + } + } + } + dp = (struct dirent *)((char *)dp + dp->d_reclen); + } + else { + error = EIO; + break; + } + } + +out: + if (dirbuf != NULL) { + free(dirbuf, M_TEMP); + } + + if (foundit == 0 && error == 0) { + error = ENOENT; + } + + return (error); +} + +/* + * VOP_GETPARENT + * + * int VOP_GETPARENT(struct vnode *vp, struct vnode **dvp, uint64_t hint, + * int flags, char *buf, int *buflen); + * + * Find a parent directory -dvp- with vp as a child. The parent hint is used to + * facilitate the search. On success, the name used to reference the child -vp- + * will be copied to buf. buflen should contain the lenght of buf on entry. On + * success, it will contain the remaining length of the buffer. + * + * Flags should be set to: + * - PARENTHIT: if a hint ino_t of a directory is supplied to facilitate the search + * - EXHAUSTSEARCH: if we are willing to search the whole filesystem to find the directory + * - WANTNAME: if we want to copy the name used to reference the file inside the dir, to buf + * + * Locks: vp should be locked on entry and will still be locked on exit. + * On success, dvp will be locked and have its reference count incremented. + * + */ +static int +ffs_getparent(struct vop_getparent_args *ap) +/* +vop_getparent { + IN struct vnode *a_vp; + OUT struct vnode **a_vpp; + IN uint64_t a_hint; + IN int a_flags; + INOUT char *a_buf; + INOUT int *a_buflen; +}; +*/ +{ + struct mount *mp; + struct vnode *vp, *dvp, *startdvp; + int error, flags, tmpflags; + + error = 0; + vp = ap->a_vp; + mp = vp->v_mount; + dvp = NULL; + flags = ap->a_flags; + + KASSERT(vp != NULL, ("VOP_GEPARENT: null vp")); + if (flags & WANTNAME) + KASSERT(ap->a_buf != NULL, ("VOP_GEPARENT: null buffer")); + + /* XXXgpf:is this check necessary? */ + if (vp->v_type == VBAD) { + error = ENOENT; + dvp = NULL; + goto out; + } + + /* grab the parent directory using the directory_hint */ + if (flags & PARENTHINT) { + error = VFS_VGET(mp, ap->a_hint, LK_SHARED, &dvp); + /* in case of failure, proceed to exhaustive search */ + if (error) { + dvp = NULL; + } + /* make sure this directory contains vp */ + else { + /* avoid exhaustive search for now */ + tmpflags = flags & (PARENTHINT | WANTNAME); + error = dir_ilookup(vp, dvp, NULL, ap->a_buf, ap->a_buflen, tmpflags); + if (error) { + vput(dvp); + dvp = NULL; + } + } + } + + /* + * if we haven't found 'a' parent directory, do an exhaustive search on + * the filesystem + */ + if ((flags & EXHAUSTSEARCH) && dvp == NULL) { + error = VFS_VGET(mp, ROOTINO, LK_SHARED, &startdvp); + if (error == 0) { + error = dir_ilookup(vp, startdvp, &dvp, ap->a_buf, ap->a_buflen, flags); + /* dont vput if the parent vnode is the root vnode */ + if (error || startdvp != dvp) { + vput(startdvp); + } + } + else + error = ENOENT; + } + /* we failed to find a directory that contains the vnode, exit */ + else if (dvp == NULL) + error = ENOENT; + +out: + if (error == 0 && dvp != NULL) + *(ap->a_vpp) = dvp; + else + *(ap->a_vpp) = NULL; + + return (error); +} --- //depot/vendor/freebsd/src/sys/ufs/ufs/inode.h 2010-04-24 07:10:17.000000000 0000 +++ //depot/projects/soc2010/gpf_audit/freebsd/src/sys/ufs/ufs/inode.h 2010-05-24 11:27:15.000000000 0000 @@ -183,6 +183,8 @@ u_int16_t ufid_pad; /* Force 32-bit alignment. */ ino_t ufid_ino; /* File number (ino). */ int32_t ufid_gen; /* Generation number. */ + ino_t ufid_dino; /* ino of a directory that probably contains the inode */ + }; #endif /* _KERNEL */