* Accounting system call. Written based on the specification and previous * implementation done by Mark Tinguely. */
| 203 | * implementation done by Mark Tinguely. |
| 204 | */ |
| 205 | int |
| 206 | sys_acct(struct thread *td, struct acct_args *uap) |
| 207 | { |
| 208 | struct nameidata nd; |
| 209 | int error, flags, i, replacing; |
| 210 | |
| 211 | error = priv_check(td, PRIV_ACCT); |
| 212 | if (error) |
| 213 | return (error); |
| 214 | |
| 215 | /* |
| 216 | * If accounting is to be started to a file, open that file for |
| 217 | * appending and make sure it's a 'normal'. |
| 218 | */ |
| 219 | if (uap->path != NULL) { |
| 220 | NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, |
| 221 | UIO_USERSPACE, uap->path, td); |
| 222 | flags = FWRITE | O_APPEND; |
| 223 | error = vn_open(&nd, &flags, 0, NULL); |
| 224 | if (error) |
| 225 | return (error); |
| 226 | NDFREE(&nd, NDF_ONLY_PNBUF); |
| 227 | #ifdef MAC |
| 228 | error = mac_system_check_acct(td->td_ucred, nd.ni_vp); |
| 229 | if (error) { |
| 230 | VOP_UNLOCK(nd.ni_vp); |
| 231 | vn_close(nd.ni_vp, flags, td->td_ucred, td); |
| 232 | return (error); |
| 233 | } |
| 234 | #endif |
| 235 | VOP_UNLOCK(nd.ni_vp); |
| 236 | if (nd.ni_vp->v_type != VREG) { |
| 237 | vn_close(nd.ni_vp, flags, td->td_ucred, td); |
| 238 | return (EACCES); |
| 239 | } |
| 240 | #ifdef MAC |
| 241 | } else { |
| 242 | error = mac_system_check_acct(td->td_ucred, NULL); |
| 243 | if (error) |
| 244 | return (error); |
| 245 | #endif |
| 246 | } |
| 247 | |
| 248 | /* |
| 249 | * Disallow concurrent access to the accounting vnode while we swap |
| 250 | * it out, in order to prevent access after close. |
| 251 | */ |
| 252 | sx_xlock(&acct_sx); |
| 253 | |
| 254 | /* |
| 255 | * Don't log spurious disable/enable messages if we are |
| 256 | * switching from one accounting file to another due to log |
| 257 | * rotation. |
| 258 | */ |
| 259 | replacing = (acct_vp != NULL && uap->path != NULL); |
| 260 | |
| 261 | /* |
| 262 | * If accounting was previously enabled, kill the old space-watcher, |
nothing calls this directly
no test coverage detected