[LWN Logo]
[LWN.net]
/*
 * Linux Security plug
 *
 * Copyright (C) 2001 WireX Communications, Inc (chris@wirex.com)
 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
 * Copyright (C) 2001 Networks Associates Technology, Inc (ssmalley@nai.com)
 * Copyright (c) 2001 James Morris <jmorris@intercode.com.au>
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 */

#ifndef __LINUX_SECURITY_H
#define __LINUX_SECURITY_H

#ifdef __KERNEL__

#include <linux/fs.h>
#include <linux/binfmts.h>
#include <linux/signal.h>
#include <linux/resource.h>
#include <linux/sem.h>
#include <linux/sysctl.h>
#include <linux/shm.h>
#include <linux/msg.h>


/* change these every time the security_operations structure changes */
#define SECURITY_INTERFACE_VERSION	0x00000101
#define SECURITY_SCAFFOLD_VERSION	"1.0.0"

/*
 * Values used in the task_security_ops calls
 */
/* setuid or setgid, id0 == uid or gid */
#define LSM_SETID_ID	1

/* setreuid or setregid, id0 == real, id1 == eff */
#define LSM_SETID_RE	2

/* setresuid or setresgid, id0 == real, id1 == eff, uid2 == saved */
#define LSM_SETID_RES	4

/* setfsuid or setfsgid, id0 == fsuid or fsgid */
#define LSM_SETID_FS	8

/**
 * Security hooks for program execution operations.
 */
struct binprm_security_ops {
	/**
	 * alloc_security - allocate security structure for linux_binprm
	 * @bprm: linux_binprm structure to be modified
	 *
	 * called: do_execve <fs/exec.c>
	 *
	 * Allocate and attach a security structure to the bprm->security 
	 * field. The security field is initialized to NULL when the bprm
	 * structure is allocated.  Return 0 if operation was successful.
	 */
	int (* alloc_security) (struct linux_binprm *bprm);

	/**
	 * free_security - deallocate security structure for linux_binprm
	 * @bprm: linux_binprm structure to be modified
	 *
	 * called: do_execve <fs/exec.c>
	 *
	 * Deallocate and clear the bprm->security field.
	 */
	void (* free_security) (struct linux_binprm *bprm);

	/**
	 * compute_creds - compute and set process security attributes
	 * @bprm: linux_binprm structure 
	 *
	 * called: compute_creds <fs/exec.c>
	 *
	 * Compute and set the security attributes of a process
	 * being transformed by an execve operation based on the
	 * old attributes (current->security) and the information
	 * saved in bprm->security by the set_security hook.
	 * Since this hook function (and its caller) are void,
	 * this hook can not return an error.  However, it can
	 * leave the security attributes of the process unchanged
	 * if an access failure occurs at this point. It can 
	 * also perform other state changes on the process (e.g.
	 * closing open file descriptors to which access is no
	 * longer granted if the attributes were changed). 
	 */
	void (* compute_creds) (struct linux_binprm *bprm);

	/**
	 * set_security - save security information in linux_binprm
	 * @bprm: linux_binprm structure 
	 *
	 * called: prepare_binprm <fs/exec.c>
	 *
	 * Save security information in the bprm->security field,
	 * typically based on information about the bprm->file,
	 * for later use by the compute_creds hook.  This hook may 
	 * also optionally check permissions (e.g. for transitions between 
	 * security domains).  Return 0 if the hook is successful
	 * and permission is granted.
	 *
	 * This hook may be called multiple times during a single execve, 
	 * e.g. for interpreters.  The hook can tell whether it has already 
	 * been called by checking to see if bprm->security is non-NULL.  
	 * If so, then the hook may decide either to retain the security
	 * information saved earlier or to replace it.
	 */
	int (* set_security) (struct linux_binprm *bprm);
};

/**
 * Security hooks for filesystem operations.
 */
struct super_block_security_ops {
	/**
	 * alloc_security - allocate security structure for this filesystem
	 * @sb: super_block structure to be modified
	 *
	 * called: read_super <fs/super.c>
	 *
	 * locks:  lock_super() has been called, so the per-filesystem
	 *         semaphore is taken.  The big kernel lock is held
	 *         by sys_mount.
	 *
	 * Allocate and attach a security structure to the
	 * sb->s_security field. The s_security field is initialized to
	 * NULL when the structure is allocated.  Return 0 if
	 * operation was successful.
	 */
	int (* alloc_security) (struct super_block *sb);

	/**
	 * free_security - deallocate security structure for this filesystem
	 * @sb: super_block structure to be modified
	 *
	 * called: read_super <fs/super.c>
	 * called: kill_super <fs/super.c>
	 *
	 * locks:  lock_super() has been called, so the per-filesystem
	 *         semaphore is taken.  The big kernel lock is held
	 *         by sys_mount across the read_super call or by kill_super.
	 *
	 * Deallocate and clear the sb->s_security field.
	 */
	void (* free_security) (struct super_block *sb);

	/**
	 * statfs - check permission when obtaining filesystem statistics
	 * @sb: super_block structure for filesystem
	 *
	 * called: vfs_statfs <fs/open.c>
	 *
	 * Check permission before obtaining filesystem statistics 
	 * for the @sb filesystem.  Return 0 if permission is granted.  
	 */
	int (* statfs) (struct super_block *sb);

	/**
	 * mount - check permission when mounting or remounting 
	 * @dev_name: name for object being mounted
	 * @nd: nameidata structure for mount point object 
	 * @type: filesystem type
	 * @flags: mount flags
	 * @data: filesystem-specific data
	 *
	 * called: do_mount <fs/super.c>
	 *
	 * lock:  The big kernel lock is held by sys_mount.
	 *
	 * Check permission before an object specified by @dev_name 
	 * is mounted on the mount point named by @nd.  For an ordinary 
	 * mount, @dev_name identifies a device if the file system type 
	 * requires a device.  For a remount (@flags & MS_REMOUNT), @dev_name
	 * is irrelevant.  For a loopback/bind mount (@flags & MS_BIND), 
	 * @dev_name identifies the pathname of the object being mounted.
	 * Return 0 if permission is granted.
	 */
	int (* mount) (char * dev_name, struct nameidata *nd, char * type,
		       unsigned long flags, void * data);

	/**
	 * umount - check permission when unmounting a file system
	 * @mnt:  the mounted file system
	 * @flags: unmount flags, e.g. MNT_FORCE
	 *
	 * called: do_umount <fs/super.c>
	 *
	 * lock:  The mount semaphore and the big kernel lock are 
	 *        held by sys_umount.
	 *
	 * Check permission before the @mnt file system is
	 * unmounted.  Return 0 if permission is granted.
	 */
	int (* umount) (struct vfsmount *mnt, int flags);

	/**
	 * umount_close - close any files in a mounted filesystem held open by the security module
	 * @mnt: the mounted filesystem
	 *
	 * called: do_umount <fs/super.c>
	 *
	 * locks:  The mount semaphore and the big kernel lock are held 
	 *         by sys_umount.
	 *
	 * Close any files in the @mnt mounted filesystem that are
	 * held open by the security module.  This hook is called during 
	 * an umount operation prior to checking whether the filesystem is 
	 * still busy.
	 */
	void (* umount_close) (struct vfsmount *mnt);

	/**
	 * umount_busy - handle a failed umount of a filesystem
	 * @mnt: the mounted filesystem
	 *
	 * called: do_umount <fs/super.c>
	 *
	 * locks:  The mount semaphore and the big kernel lock are held 
	 *         by sys_umount.
	 *
	 * Handle a failed umount of the @mnt mounted filesystem, e.g. 
	 * re-opening any files that were closed by umount_close.  
	 * This hook is called during an umount operation if the umount
	 * fails after a call to the umount_close hook.
	 */
	void (* umount_busy) (struct vfsmount *mnt);

	/**
	 * post_remount - Update module state when a filesystem is remounted
	 * @mnt:  the mounted file system
	 * @flags: new filesystem flags
	 * @data:  filesystem-specific data
	 *
	 * called: do_remount <fs/super.c>
	 *
	 * lock:  The big kernel lock is held by sys_mount.
	 *
	 * Update the security module's state when a filesystem is remounted.
	 * This hook is only called if the remount was successful.
	 */
	void (* post_remount) (struct vfsmount *mnt, unsigned long flags,
			       void *data);

	/**
	 * post_mountroot - Update module state when the root filesystem is mounted
	 * @sb:  the super_block structure for the root filesystem
	 *
	 * called: mount_root <fs/super.c>
	 *
	 * Update the security module's state when the root filesystem
	 * is mounted.  This hook is only called if the mount was successful.
	 */
	void (* post_mountroot) (struct super_block *sb);

	/**
	 * post_addmount - Update module state when a non-root filesystem is mounted
	 * @mnt:  the mounted filesystem
	 * @mountpoint_nd:  the nameidata structure for the mount point
	 *
	 * called: do_add_mount <fs/super.c>
	 *
	 * lock:  The big kernel lock is held by sys_mount.
	 *
	 * Update the security module's state when a non-root filesystem is
	 * mounted.  This hook is not called after a loopback/bind mount.
	 */
	void (* post_addmount) (struct vfsmount *mnt, struct nameidata
				*mountpoint_nd);
};

/**
 * Security hooks for inode operations.
 */
struct inode_security_ops {
	/**
	 * alloc_security - allocate security structure for this inode
	 * @inode: the inode structure
	 * 
	 * called: alloc_inode <fs/inode.c>
	 *
	 * Allocate and attach a security structure to @inode->i_security.
	 * The i_security field is initialized to NULL when the inode 
	 * structure is allocated.  Return 0 if operation was successful.
	 */
	int (* alloc_security) (struct inode *inode);	

	/**
	 * free_security - deallocate security structure for this inode
	 * @inode: the inode structure
	 * 
	 * called: destroy_inode <fs/inode.c>
	 * 
	 * Deallocate the inode security structure and set @inode->i_security
	 * to NULL. 
	 */
	void (* free_security) (struct inode *inode);
	
	/**
	 * create - check the permissions when creating a directory or file
	 * @dir: inode structure of the parent of the new file
	 * @dentry: the dentry structure for the file to be created
	 * @mode: the file mode of the file to be created
	 * 
	 * called: vfs_create <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 * lock: The @dir i_zombie semaphore is held.
	 *
	 * Check permission to create a regular file.
	 * Return 0 if permission is granted.
	 */
	int (* create)	(struct inode *dir, struct dentry *dentry, int mode);

	/**
	 * post_create - set the security attributes on a newly created file
	 * @dir: inode structure of the parent directory of the new file
	 * @dentry: the dentry structure for the newly created file
	 * @mode: the file mode 
	 * 
	 * called: vfs_create <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 *
	 * Set the security attributes on a newly created regular file.
	 * This hook is called after a file has been successfully created.
	 */
	void (* post_create) (struct inode *dir, struct dentry *dentry, 
			      int mode);

	/**
	 * link - check permissions when creating a hard link to a file
	 * @old_dentry: dentry structure for an existing link to the file
	 * @dir: the inode structure of the parent directory of the new link
	 * @new_dentry: dentry structure for the new link 
	 * 
	 * called: vfs_link <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 * lock: The @dir i_zombie semaphore is held.
	 *
	 * Check permission before creating a new hard link to a file.
	 * Return 0 if permission is granted.
	 */
	int (* link) (struct dentry *old_dentry, struct inode *dir, 
		      struct dentry *new_dentry);

	/**
	 * post_link - set security attributes for a new file link
	 * @old_dentry: dentry structure for the existing link
	 * @dir: the inode structure of the parent directory of the new file
	 * @new_dentry: dentry structure for the new file link
	 * 
	 * called: vfs_link <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 * 
	 * Set security attributes for a new hard link to a file.
	 */
	void (* post_link) (struct dentry *old_dentry, struct inode *dir, 
			    struct dentry *new_dentry);

	/**
	 * unlink - check permissions when unlinking a file
	 * @dir: inode structure of parent directory of the file
	 * @dentry: dentry structure for file to be unlinked
	 * 
	 * called: vfs_unlink <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 * lock: The @dir i_zombie semaphore is held.
	 *
	 * Check the permission to remove a hard link to a file. 
	 * Return 0 if permission is granted.
	 */
	int (* unlink) (struct inode *dir, struct dentry *dentry);

	/**
	 * symlink - check permissions when creating a symbolic link to a file
	 * @dir: inode structure of parent directory of the symbolic link
	 * @dentry: dentry structure of the symbolic link
	 * @old_name: pathname of file
	 * 
	 * called: vfs_symlink <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 * lock: The @dir i_zombie semaphore is held.
	 *
	 * Check the permission to create a symbolic link to a file.
	 * Return 0 if permission is granted.
	 */
	int (* symlink)	(struct inode *dir, struct dentry *dentry, 
			 const char *old_name);

	/**
	 * post_symlink - set security attributes on a new symbolic link
	 * @dir: inode structure of the parent directory of the new link
	 * @dentry: dentry structure of new symbolic link
	 * @old_name: pathname of file
	 * 
	 * called: vfs_symlink <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 *
	 * Set security attributes for a newly created symbolic link.
	 * Note that @dentry->d_inode may be NULL, since the filesystem
	 * might not instantiate the dentry (e.g. NFS).
	 */
	void (* post_symlink) (struct inode *dir, struct dentry *dentry, 
			       const char *old_name);

	/**
	 * mkdir - check permissions when creating a directory
	 * @dir: inode structure of parent of the directory to be created
	 * @dentry: dentry structure of new directory
	 * @mode: mode of new directory
	 * 
	 * called: vfs_mkdir <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 * lock: The @dir i_zombie semaphore is held.
	 *
	 * Check permissions to create a new directory in the existing 
	 * directory associated with inode strcture @dir. 
	 * Return 0 if permission is granted.
	 */
	int (* mkdir) (struct inode *dir, struct dentry *dentry, int mode);

	/**
	 * post_mkdir - set security attributes on new directory
	 * @dir: inode structure of parent of the directory to be created
	 * @dentry: dentry structure of new directory
	 * @mode: mode of new directory
	 * 
	 * called: vfs_mkdir <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 *
	 * Set security attributes on a newly created directory.
	 */
	void (* post_mkdir) (struct inode *dir, struct dentry *dentry, 
			     int mode);

	/**
	 * rmdir - check permissions when removing a directory
	 * @dir: inode structure of parent of the directory to be removed
	 * @dentry: dentry structure of directory to be removed
	 * 
	 * called: vfs_rmdir <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 * lock: The @dir i_zombie semaphore is held.
	 * lock: The @dentry->d_inode i_zombie semaphore is held.
	 *
	 * Check the permission to remove a directory.
	 * Return 0 if permission is granted.
	 */
	int (* rmdir) (struct inode *dir, struct dentry *dentry);

	/**
	 * mknod - check permissions when creating a special file
	 * @dir: inode structure of parent of the new file
	 * @dentry: dentry structure of the new file
	 * @mode: mode of the new file
	 * @dev: the device number
	 * 
	 * called: vfs_mknod <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 * lock: The @dir i_zombie semaphore is held.
	 *
	 * Check permissions when creating a special file (or a 
	 * socket or a fifo file created via the mknod system call).  
	 * Note that if mknod operation is being done for a regular file, 
	 * then the create hook will be called and not this hook.
	 * Return 0 if permission is granted.
	 */
	int (* mknod) (struct inode *dir, struct dentry *dentry, int mode, 
		       dev_t dev);

	/**
	 * post_mknod - set security attributes on a special file
	 * @dir: inode structure of parent of the new node
	 * @dentry: dentry structure of the new node
	 * @mode: mode of the new node
	 * @dev: the device number
	 * 
	 * called: vfs_mknod <fs/namei.c>
	 *
	 * lock: The @dir i_sem semaphore is held.
	 *
	 * Set security attributes on a newly created special file
	 * (or socket or fifo file created via the mknod system call).
	 */
	void (* post_mknod) (struct inode *dir, struct dentry *dentry, 
			     int mode, dev_t dev);

	/**
	 * rename - check permissions to rename a file or directory
	 * @old_dir: inode structure for parent of the old link
	 * @old_dentry: dentry structure of the old link
	 * @new_dir: inode structure for parent of the new link
	 * @new_dentry: dentry structure of the new link
	 * 
	 * called: vfs_rename_dir <fs/namei.c>
	 * called: vfs_rename_other <fs/namei.c>
	 *
	 * lock: The @old_dir->d_inode i_sem lock is held by do_rename.
	 * lock: The @new_dir_d_inode i_sem lock is held by do_rename.
	 * lock:  The big kernel lock is held by do_rename <fs/namei.c>
	 *
	 * Check for permission to rename a file or directory.
	 * Return 0 if permission is granted.
	 */
	int (* rename) (struct inode *old_dir, struct dentry *old_dentry,
			struct inode *new_dir, struct dentry *new_dentry);
 
	/**
	 * post_rename - set security attributes on newly renamed file or directory
	 * @old_dir: inode structure for parent of the old link
	 * @old_dentry: dentry structure of the old link
	 * @new_dir: inode structure for parent of the new link
	 * @new_dentry: dentry structure of the new link
	 * 
	 * called: vfs_rename_dir <fs/namei.c>
	 * called: vfs_rename_other <fs/namei.c>
	 * 
	 * lock: The big kernel lock is held by do_rename <fs/namei.c>
	 * lock: The @old_dir->i_sb->s_vfs_rename_sem semaphore is held.
	 *
	 * Set security attributes on a renamed file or directory.
	 */
	void (* post_rename) (struct inode *old_dir, struct dentry *old_dentry,
			      struct inode *new_dir, struct dentry *new_dentry);

	/**
	 * readlink - check permissions when reading a symbolic link
	 * @dentry: dentry structure for the file link
	 * 
	 * called: sys_readlink <fs/stat.c>
	 *
	 * Check the permission to read the symbolic link.
	 * Return 0 if permission is granted.
	 */
	int (* readlink) (struct dentry *dentry);

	/**
	 * follow_link - check permission to follow symbolic links 
	 * @dentry: dentry structure for the link
	 * @nd: nameidata structure for the parent directory
	 * 
	 * called: do_follow_link <fs/namei.c>
	 * called: open_namei <fs/namei.c>
	 *
	 * Check permission to follow a symbolic link when looking up
	 * a pathname.  Return 0 if permission is granted.
	 */
	int (* follow_link) (struct dentry *dentry, struct nameidata *nd);

	/**
	 * permission - check permission when accessing an inode
	 * @inode: inode structure to check
	 * @mask: permission mask
	 * 
	 * called: permission <fs/namei.c>
	 * 
	 * Check permission before accessing an inode.  This hook
	 * is called by the existing Linux permission function,
	 * so a security module can use it to provide additional
	 * checking for existing Linux permission checks.  Notice
	 * that this hook is called when a file is opened (as well
	 * as many other operations), whereas the file_security_ops
	 * permission hook is called when the actual read/write
	 * operations are performed.
	 * Return 0 if permission is granted.
	 */
	int (* permission) (struct inode *inode, int mask);

	/**
	 * revalidate - revalidate the inode attributes
	 * @dentry: dentry structure associated with the inode
	 * 
	 * called: do_revalidate <fs/stat.c>
	 *
	 * Revalidate the inode attributes.  This hook can be used
	 * by a security module to revalidate the attributes stored in 
	 * the i_security field to maintain consistency when the file
	 * is remote.  Return 0 if successful.
	 */
	int (* revalidate) (struct dentry *dentry);

	/**
	 * setattr - check permissions to set file attributes
	 * @dentry: dentry structure for the file
	 * @attr: iattr structure containing the new file attributes
	 * 
	 * called: notify_change <fs/attr.c>
	 *
	 * lock:  The big kernel lock is held by notify_change
	 *
	 * Check permission before setting file attributes.
	 * Note that the kernel call to notify_change is performed from several
	 * locations, whenever file attributes change (such as when a file
	 * is truncated, chown/chmod operations, transferring disk quotas, 
	 * etc).   Return 0 if permission is granted.
	 */
	int (* setattr)	(struct dentry *dentry, struct iattr *attr);

	/**
	 * stat - check permissions to get file attributes
	 * @inode: inode structure for the file
	 * 
	 * called: cp_old_stat <fs/stat.c> 
	 * called: cp_new_stat <fs/stat.c> 
	 * called: cp_new_stat64 <fs/stat.c> 
	 *
	 * Check permission before obtaining file attributes.
	 * Return 0 if permission is granted.
	 */
	int (* stat) (struct inode *inode);

	/**
	 * post_lookup - set security attributes for looked up file
	 * @ino: inode structure for parent directory
	 * @d: dentry structure for the file
	 * 
	 * called: real_lookup <fs/namei.c>
	 * called: lookup_hash <fs/namei.c>
	 *
	 * lock: The @ino i_sem semaphore MAY be held.
	 *
	 * Set the security attributes for a file after it has
	 * been looked up.
	 */
	void (* post_lookup) (struct inode *ino, struct dentry *d);

	/**
	 * delete - update module's state when an inode is deleted
	 * @ino: inode structure for deleted inode
	 * 
	 * called: iput <fs/inode.c>
	 *
	 * This hook is called when a deleted inode is released 
	 * (i.e. an inode with no hard links has its use count drop to
	 * zero).  A security module can use this hook to release any
	 * persistent label associated with the inode.
	 */
        void (* delete) (struct inode *ino);

};

struct file_security_ops {
	/**
	 * permission - check permission when accessing an open file
	 * @file: file structure being accessed
	 * @mask: requested permissions
	 *
	 * called: sys_read <fs/read_write.c>
	 * called: sys_write <fs/read_write.c>
	 * called: sys_readv <fs/read_write.c>
	 * called: sys_writev <fs/read_write.c>
	 * called: sys_pread <fs/read_write.c>
	 * called: sys_pwrite <fs/read_write.c>
	 * called: vfs_readdir <fs/readdir.c>
	 * called: sys_sendfile <mm/filemap.c>
	 * called: sys_sendfile <mm/filemap.c>
	 *
	 * Check file permissions before accessing an open file.
	 * This hook is called by various operations that read
	 * or write files.  A security module can use this hook
	 * to perform additional checking on these operations, e.g. 
	 * to revalidate permissions on use to support privilege 
	 * bracketing or policy changes.  Notice that this hook
	 * is used when the actual read/write operations are
	 * performed, whereas the inode_security_ops hook is called
	 * when a file is opened (as well as many other operations).
	 * Return 0 if permission is granted.
	 * 
	 * Caveat:  Although this hook can be used to revalidate
	 * permissions for various system call operations that
	 * read or write files, it does not address the revalidation 
	 * of permissions for memory-mapped files.  Security modules
	 * must handle this separately if they need such revalidation.
	 */
	int (*permission) (struct file * file, int mask);

	/**
	 * alloc_security - allocate file security information
	 * @file: file structure to secure
	 *
	 * called: get_empty_filp <fs/file_table.c>
	 *
	 * lock: a spin lock is held on the file list
	 *
	 * Allocate and attach a security structure to the
	 * file->f_security field.  The security field is initialized
	 * to NULL when the structure is first created.  Return 0 if
	 * the hook is successful and permission is granted.
	 */
	int (*alloc_security) (struct file * file);

	/**
	 * free_security - deallocate file security information
	 * @file: file structure being modified
	 *
	 * called: fput <fs/file_table.c>
	 * called: put_filp <fs/file_table.c>
	 *
	 * Deallocate and free any security structures stored in
	 * file->f_security.
	 */
	void (*free_security) (struct file * file);

	/**
	 * llseek - check permission when changing the file offset
	 * @file: file structure being modified
	 *
	 * called: sys_lseek <fs/read_write.c>
	 * called: sys_llseek <fs/read_write.c>
	 *
	 * Check permission before re-positioning the file offset in
	 * @file.  Return 0 if permission is granted.
	 */
	int (*llseek) (struct file * file);

	/**
	 * ioctl - check permission for an ioctl operation
	 * @file: file structure
	 * @cmd: operation to perform
	 * @arg: operational arguments
	 *
	 * called: sys_ioctl <fs/ioctl.c>
	 *
	 * Check permission for an ioctl operation on @file.  Note that @arg
	 * can sometimes represents a user space pointer; in other
	 * cases, it may be a simple integer value.  When @arg represents
	 * a user space pointer, it should never be used by the security
	 * module.  Return 0 if permission is granted.
	 */
	int (*ioctl) (struct file * file, unsigned int cmd, unsigned long arg);

	/**
	 * mmap - check permission for a mmap operation
	 * @file: file structure for file to map (may be NULL)
	 * @prot: requested permissions
	 * @flags: operational flags
	 *
	 * called: do_mmap_pgoff <mm/mmap.c>
	 *
	 * Check permissions for a mmap operation.  Return 0 if
	 * permission is granted.  The @file may be NULL, e.g. 
	 * if mapping anonymous memory.
	 */
	int (*mmap) (struct file * file, unsigned long prot,
		     unsigned long flags);

	/**
	 * mprotect - check permissions when changing memory protections
	 * @vma: memory region to modify
	 * @prot: requested permissions
	 *
	 * called: sys_mprotect <mm/mprotect.c>
	 *
	 * locks: down_write has been called on current->mm->mmap_sem
	 *
	 * Check permissions before changing memory access
	 * permissions.  Return 0 if permission is granted.
	 */
	int (*mprotect) (struct vm_area_struct * vma, unsigned long prot);

	/**
	 * lock - check permission to perform file locking operations
	 * @file: file structure
	 * @cmd: operation to perform
	 *
	 * called: sys_flock <fs/locks.c>
	 *
	 * Check permission before performing file locking operations.
	 * Return 0 if permission is granted.
	 */
	int (*lock) (struct file * file, unsigned int cmd);

	/**
	 * fcntl - check permission for file control operations
	 * @file: file structure
	 * @cmd: operation to be performed
	 * @arg: operational arguments
	 *
	 * called: sys_fcntl <fs/fcntl.c>
	 * called: sys_fcntl64 <fs/fcntl.c>
	 *
	 * Check permission before allowing the file operation
	 * specified by @cmd from being performed on the file @file.
	 * Note that @arg can sometimes represents a user space
	 * pointer; in other cases, it may be a simple integer value.
	 * When @arg represents a user space pointer, it should never be 
	 * used by the security module.  Return 0 if permission is granted.
	 */
	int (*fcntl) (struct file * file, unsigned int cmd, unsigned long arg);

	/**
	 * set_fowner - save owner security information
	 * @file: file structure to update
	 *
	 * called: do_fcntl <fs/fcntl.c>
	 * called: fcntl_dirnotify <fs/dnotify.c>
	 * called: tty_fasync <drivers/char/tty_io.c>
	 * called: fcntl_setlease <fs/locks.c>
	 *
	 * lock:  The big kernel lock is held by do_fcntl and fcntl_setlease
	 *
	 * Save owner security information (typically from current->security)
	 * in file->f_security for later use by the send_sigiotask hook.
	 * Return 0 on success.
	 */
	int (*set_fowner) (struct file * file);

	/**
	 * send_sigiotask - check permission to send SIGIO
	 * @tsk: structure of task receiving signal
	 * @fown: file owner information
	 * @fd: file descriptor
	 * @reason: operational flags
	 *
	 * called: send_sigio_to_task <fs/fcntl.c>
	 *
	 * Check permission for the file owner @fown to send
	 * SIGIO to the process @tsk.  Note that this hook is always
	 * called from interrupt.  Note that the fown_struct, @fown,
	 * is never outside the context of a struct file, so the file
	 * structure (and associated security information) can always
	 * be obtained:
	 *     (struct file *)((long)fown - offsetof(struct file,f_owner));
	 * Return 0 if permission is granted.
	 */
	int (*send_sigiotask) (struct task_struct * tsk,
			       struct fown_struct * fown, int fd, int reason);

	/**
	 * receive - check permission when receiving file descriptors via IPC
	 * @file: file structure being received
	 *
	 * called: scm_detach_fds <net/core/scm.c>
	 * 
	 * This hook allows security modules to control the ability of
	 * a process to receive an open file descriptor via socket
	 * IPC.  Return 0 if permission is granted.
	 */
	int (*receive) (struct file * file);
};

struct sched_param;
/**
 * Security hooks for task operations.
 */
struct task_security_ops {
	/**
	 * create - check permission when creating a child process
	 * @clone_flags: flags indicating what should be shared
	 *
	 * called: do_fork <kernel/fork.c>
	 *
	 * Check permission before creating a child process.
	 * Return 0 if permission is granted.
	 * See the clone(2) manual page for definitions of the @clone_flags.
	 */
	int (* create) (unsigned long clone_flags);

	/**
	 * alloc_security - allocate security structure for child process
	 * @p: task_struct for child process
	 *
	 * called: do_fork <kernel/fork.c>
	 *
	 * Allocate and attach a security structure to the p->security
	 * field. The security field is initialized to NULL when the 
	 * task structure is allocated.  Return 0 if operation was successful.
	 */
	int (* alloc_security) (struct task_struct *p);

	/**
	 * free_security - deallocate security structure for this process
	 * @p: task_struct for process
	 *
	 * called: release_task <kernel/exit.c>
	 *
	 * Deallocate and clear the p->security field.
	 */
	void (* free_security) (struct task_struct *p);

	/**
	 * setuid - check permission when setting user identity attributes
	 * @id0: uid
	 * @id1: uid
	 * @id2: uid
	 * @flags: one of the LSM_SETID_* values  
	 *
	 * called: sys_setreuid <kernel/sys.c>
	 * called: sys_setuid <kernel/sys.c>
	 * called: sys_setresuid <kernel/sys.c>
	 * called: sys_setfsuid <kernel/sys.c>
	 *
	 * Check permission before setting one or more of the user identity 
	 * attributes of the current process.  The @flags parameter indicates
	 * which of the set*uid system calls invoked this hook and how
	 * to interpret the @id0, @id1, and @id2 parameters.  See the 
	 * LSM_SETID definitions at the beginning of this file for the
	 * @flags values and their meanings.  Return 0 if permission is
	 * granted.
	 */
	int (* setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);

	/**
	 * post_setuid - update state after setting user identity attributes
	 * @old_ruid: old real uid (or fs uid if LSM_SETID_FS)
	 * @old_euid: old effective uid (or -1 if LSM_SETID_FS)
	 * @old_suid: old saved uid (or -1 if LSM_SETID_FS)
	 * @flags: one of the LSM_SETID_* values
	 *
	 * called: sys_setreuid <kernel/sys.c>
	 * called: sys_setuid <kernel/sys.c>
	 * called: sys_setresuid <kernel/sys.c>
	 * called: sys_setfsuid <kernel/sys.c>
	 *
	 * Update the module's state after setting one or more of the 
	 * user identity attributes of the current process.  The @flags 
	 * parameter indicates which of the set*uid system calls invoked 
	 * this hook.  If @flags is LSM_SETID_FS, then @old_ruid is
	 * the old fs uid and the other parameters are not used.  Return
	 * 0 on success.
	 */
	int (* post_setuid) (uid_t old_ruid /* or fsuid */, uid_t old_euid, 
			     uid_t old_suid, int flags);

	/**
	 * setgid - check permission when setting group identity attributes
	 * @id0: gid
	 * @id1: gid
	 * @id2: gid
	 * @flags: one of the LSM_SETID_* values  
	 *
	 * called: sys_setregid <kernel/sys.c>
	 * called: sys_setgid <kernel/sys.c>
	 * called: sys_setresgid <kernel/sys.c>
	 * called: sys_setfsgid <kernel/sys.c>
	 *
	 * Check permission before setting one or more of the group identity 
	 * attributes of the current process.  The @flags parameter indicates
	 * which of the set*gid system calls invoked this hook and how
	 * to interpret the @id0, @id1, and @id2 parameters.  See the 
	 * LSM_SETID definitions at the beginning of this file for the
	 * @flags values and their meanings.  Return 0 if permission is
	 * granted.
	 */
	int (* setgid) (gid_t id0, gid_t id1, gid_t id2, int flags);

	/**
	 * setpgid - check permission when setting process group identifier
	 * @p: task_struct for process being modified
	 * @pgid: new pgid
	 *
	 * called: sys_setpgid <kernel/sys.c>
	 *
	 * lock:  tasklist_lock is read-locked.
	 *
	 * Check permission before setting the process group identifier
	 * of the process @p to @pgid.  Return 0 if permission is
	 * granted.
	 */
	int (* setpgid)	(struct task_struct *p, pid_t pgid);

	/**
	 * getpgid - check permission when getting process group identifier
	 * @p: task_struct for process 
	 *
	 * called: sys_getpgid <kernel/sys.c>
	 *
	 * lock:  tasklist_lock is read-locked.
	 *
	 * Check permission before getting the process group identifier
	 * of the process @p.  Return 0 if permission is granted.
	 */
	int (* getpgid)	(struct task_struct *p);

	/**
	 * getsid - check permission when getting session identifier
	 * @p: task_struct for process 
	 *
	 * called: sys_getsid <kernel/sys.c>
	 *
	 * lock:  tasklist_lock is read-locked.
	 *
	 * Check permission before getting the session identifier
	 * of the process @p.  Return 0 if permission is granted.
	 */
	int (* getsid) (struct task_struct *p);

	/**
	 * setgroups - check permission when setting supplementary group set
	 * @gidsetsize: number of elements in @grouplist
	 * @grouplist: array of gids
	 *
	 * called: sys_setgroups <kernel/sys.c>
	 *
	 * Check permission before setting the supplementary group set
	 * of the current process to @grouplist.  Return 0 if permission 
	 * is granted.
	 */
	int (* setgroups) (int gidsetsize, gid_t *grouplist);

	/**
	 * setnice - check permission when setting process nice value
	 * @p: task_struct of process
	 * @nice: new nice value
	 *
	 * called: sys_setpriority <kernel/sys.c>
	 * called: sys_nice <kernel/sched.c>
	 *
	 * lock: the tasklist_lock is read-locked in sys_setpriority.
	 *
	 * Check permission before setting the nice value of @p
	 * to @nice.  Return 0 if permission is granted.
	 */
	int (* setnice)	(struct task_struct *p, int nice);

	/**
	 * setrlimit - check permission when setting resource limits
	 * @resource: resource whose limit is being set
	 * @new_rlim: new limits for @resource
	 *
	 * called: sys_setrlimit <kernel/sys.c>
	 *
	 * Check permission before setting the resource limits
	 * of the current process for @resource to @new_rlim.
	 * The old resource limit values can be examined by
	 * dereferencing (current->rlim + resource).
	 * Return 0 if permission is granted.
	 */
	int (* setrlimit) (unsigned int resource, struct rlimit *new_rlim);

	/**
	 * setscheduler - check permission when setting scheduling info
	 * @p: task_struct for process
	 * @policy: scheduling policy
	 * @lp: scheduling parameters
	 *
	 * called: setscheduler <kernel/sched.c>
	 *
	 * lock:  tasklist_lock is read-locked, and runqueue_lock is locked.
	 *
	 * Check permission before setting scheduling policy
	 * and/or parameters of process @p based on @policy
	 * and @lp.  Return 0 if permission is granted.
	 */
	int (* setscheduler) (struct task_struct *p, int policy, 
			      struct sched_param *lp);

	/**
	 * getscheduler - check permission when obtaining scheduling info
	 * @p: task_struct for process
	 *
	 * called: sys_sched_getscheduler <kernel/sched.c>
	 * called: sys_sched_getparam <kernel/sched.c>
	 * called: sys_sched_rr_get_interval <kernel/sched.c>
	 *
	 * lock:  tasklist_lock is read-locked.
	 *
	 * Check permission before obtaining scheduling information
	 * for process @p.  Return 0 if permission is granted.
	 */
	int (* getscheduler) (struct task_struct *p);

	/**
	 * kill - check permission when sending a signal
	 * @p: task_struct for process
	 * @info: signal information
	 * @sig: signal value
	 *
	 * called: send_sig_info <kernel/signal.c>
	 *
	 * lock:  tasklist_lock may be read-locked by the caller.
	 *
	 * Check permission before sending signal @sig to @p.
	 * @info can be NULL, the constant 1, or a pointer to
	 * a siginfo structure.  If @info is 1 or SI_FROMKERNEL(info)
	 * is true, then the signal should be viewed as coming from
	 * the kernel and should typically be permitted.
	 * Return 0 if permission is granted.
	 *
	 * SIGIO signals are handled separately by the send_sigiotask
	 * hook in file_security_ops.
	 */
	int (* kill) (struct task_struct *p, struct siginfo *info, int sig);

	/**
	 * wait - check permission when reaping a child process
	 * @p: task_struct for process
	 *
	 * called: sys_wait4 <kernel/exit.c>
	 *
	 * lock:  tasklist_lock is read-locked.
	 *
	 * Check permission before allowing a process to reap
	 * a child process @p and collect its status information.
	 * Return 0 if permission is granted.
	 */
	int (* wait) (struct task_struct *p);

	/**
	 * prctl - check permission when performing process control operations
	 * @option: the operation
	 * @arg2: argument
	 * @arg3: argument
	 * @arg4: argument
	 * @arg5: argument
	 *
	 * called: sys_prctl <kernel/sys.c>
	 *
	 * Check permission before performing a process control operation
	 * on the current process.  Return 0 if permission is granted.
	 */
	int (* prctl) (int option, unsigned long arg2, unsigned long arg3,
		       unsigned long arg4, unsigned long arg5);

	/**
	 * kmod_set_label - set security attributes for kernel module loader
	 *
	 * called: exec_usermodehelper <kernel/kmod.c>
	 *
	 * Set the security attributes in current->security 
	 * for the kernel module loader thread, so that it
	 * has the permissions needed to perform its function.
	 */
	void (* kmod_set_label)	        (void);
};

struct sk_buff;
/**
 * Security hooks for socket operations.
 */
struct socket_security_ops {
	/**
	 * create - Check socket create permission
	 * @family: requested protocol family 
	 * @type: requested communications type
	 * @protocol: requested protocol
	 *
	 * called: sock_create <net/socket.c>
	 *
	 * Check permissions prior to creating a new socket.  Return 0
	 * if permission is granted.
	 */
	int (*create) (int family, int type, int protocol);

	/**
	 * post_create - Update socket security information after creation
	 * @sock: newly created socket structure
	 * @family: requested protocol family 
	 * @type: requested communications type
	 * @protocol: requested protocol
	 *
	 * called: sock_create <net/socket.c>
	 *
	 * This hook allows a module to update or allocate a
	 * per-socket security structure. Note that the security field
	 * was not added directly to the socket structure, but rather,
	 * the socket security information is stored in the associated
	 * inode.  Typically, the inode alloc_security hook will allocate and
	 * and attach security information to sock->inode->i_security.
	 * This hook may be used to update the sock->inode->i_security field 
	 * with additional information that wasn't available when the inode 
	 * was allocated.
	 */
	void (*post_create) (struct socket * sock, int family, int type,
			     int protocol);

	/**
	 * bind - check permission for socket bind operation
	 * @sock: socket structure
	 * @address: address to bind to
	 * @addrlen: length of address
	 *
	 * called: sys_bind <net/socket.c>
	 *
	 * Check permission before socket protocol layer bind operation
	 * is performed and the socket @sock is bound to the address
	 * specified in the @address parameter.  Return 0 if permission
	 * is granted.  
	 */
	int (*bind) (struct socket * sock, struct sockaddr * address,
		     int addrlen);

	/**
	 * connect - check permission for socket connect operation
	 * @sock: socket structure
	 * @address: address of remote endpoint
	 * @addrlen: length of address
	 *
	 * called: sys_connect <net/socket.c>
	 *
	 * Check permission before socket protocol layer connect
	 * operation attempts to connect socket @sock to a remote
	 * address, @address.  Return 0 if permission is granted.  
	 */
	int (*connect) (struct socket * sock, struct sockaddr * address,
			int addrlen);

	/**
	 * listen - check permission for socket listen operation
	 * @sock: socket structure
	 * @backlog: maximum length for the pending connection queue
	 *
	 * called: sys_listen <net/socket.c>
	 *
	 * Check permission before socket protocol layer listen operation.
	 * Return 0 if permission is granted.
	 */
	int (*listen) (struct socket * sock, int backlog);

	/**
	 * accept - check permission for socket accept operation
	 * @sock: listening socket structure
	 * @newsock: newly created server socket for connection
	 *
	 * called: sys_accept <net/socket.c>
	 *
	 * Check permission before accepting a new connection.
	 * Note that the new socket, @newsock, has been created and
	 * some information copied to it, but the accept operation has
	 * not actually been performed. This hook also allows a
	 * security module to copy security information into the newly
	 * created socket's inode.  Return 0 if permission is granted.
	 */
	int (*accept) (struct socket * sock, struct socket * newsock);

	/**
	 * sendmsg - check permission when sending message from this socket
	 * @sock: socket structure
	 * @msg: message to be transmitted
	 * @size: size of message
	 *
	 * called: sock_sendmsg <net/socket.c>
	 *
	 * Check permission before transmitting a message to another
	 * socket.  Return 0 if permission is granted.
	 */
	int (*sendmsg) (struct socket * sock, struct msghdr * msg, int size);

	/**
	 * recvmsg - check permission when receiving messages from this socket
	 * @sock: socket structure
	 * @msg: message structure
	 * @size: size of message structure
	 * @flags: operational flags
	 *
	 * called: sock_recvmsg <net/socket.c>
	 *
	 * Check permission before receiving a message from a socket.
	 * Return 0 if permission is granted.  
	 */
	int (*recvmsg) (struct socket * sock, struct msghdr * msg, int size,
			int flags);

	/**
	 * getsockname - check permission when retrieving socket name
	 * @sock: socket structure
	 *
	 * called: sys_getsockname <net/socket.c>
	 *
	 * Check permission before the local address (name) of the
	 * socket object @sock is retrieved. Return 0 if permission is
	 * granted.
	 */
	int (*getsockname) (struct socket * sock);

	/**
	 * getpeername - check permission when retrieving socket peer name
	 * @sock: socket structure
	 *
	 * called: sys_getpeername <net/socket.c>
	 *
	 * Check permission before the remote address (name) of a
	 * socket object @sock is retrieved.  Return 0 if permission
	 * is granted.
	 */
	int (*getpeername) (struct socket * sock);

	/**
	 * getsockopt - check permission when retrieving socket options
	 * @sock: socket structure
	 * @level: protocol level to retrieve option from
	 * @optname: name of option to retrieve
	 *
	 * called: sys_getsockopt <net/socket.c>
	 *
	 * Check permissions before retrieving the options associated
	 * with socket @sock.  Return 0 if permission is granted.
	 */
	int (*getsockopt) (struct socket * sock, int level, int optname);

	/**
	 * setsockopt - check permission when setting socket options
	 * @sock: socket structure
	 * @level: protocol level to set options for
	 * @optname: name of the option to set
	 *
	 * called: sys_setsockopt <net/socket.c>
	 *
	 * Check permissions before setting the options associated
	 * with socket @sock. Return 0 if permission is granted.  
	 */
	int (*setsockopt) (struct socket * sock, int level, int optname);

	/**
	 * shutdown - check permission when shutting down a socket
	 * @sock: socket structure
	 * @how: flag indicating how future sends and receives are handled
	 *
	 * called: sys_shutdown <net/socket.c>
	 *
	 * Checks permission before all or part of a connection on the
	 * socket @sock is shut down.  Return 0 if permission is
	 * granted.
	 */
	int (*shutdown) (struct socket * sock, int how);

	/**
	 * sock_rcv_skb - check permissions on incoming network packets
	 * @sk: sock (not socket) associated with the incoming sk_buff
	 * @skb: incoming network data
	 *
	 * called: tcp_v4_rcv <net/ipv4/tcp_ipv4.c>
	 * called: sock_queue_rcv_skb <include/net/sock.h>
	 *
	 * Check permissions on incoming network packets.  This hook is
	 * distinct from the network input hooks of ip_security_ops since
	 * it is the first time that the incoming sk_buff @skb has been 
	 * associated with a particular socket, @sk.  Security modules
	 * should not try to dereference @sk->socket if the socket is
	 * in a time wait state (@sk->state == TCP_TIME_WAIT), since
	 * the @sk refers to a tcp_tw_bucket structure in that case.
	 * Also, even if the socket is not in this state, @sk->socket
	 * may be NULL, e.g. a newly created server socket for a connection 
	 * that has not yet been accepted by a process.  Return 0 if
	 * permission is granted.
	 */
	int (*sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);

	/** Security hooks for Unix domain socket IPC.
	 *
	 * The following two hooks were necessary because Linux provides
	 * an alternative to the conventional file name space for Unix
	 * domain sockets.  Whereas binding and connecting to sockets
	 * in the file name space is mediated by the typical file
	 * permissions (and caught by the mknod and permission hooks in
	 * inode_security_ops), binding and connecting to sockets in the
	 * abstract name space is completely unmediated.  Sufficient
	 * control of Unix domain sockets in the abstract name space isn't
	 * possible using only the socket layer hooks, since we need
	 * to know the actual target socket, which is not looked up
	 * until we are inside the af_unix code.
	 */

	/**
	 * unix_stream_connect - check permissions for Unix domain stream IPC
	 * @sock: socket structure
	 * @other: peer socket structure
	 *
	 * called: unix_stream_connect <net/unix/af_unix.c>
	 *
	 * Check permissions before establishing a Unix domain stream
	 * connection between @sock and @other.  Return 0 if
	 * permission is granted.
	 */
	int (*unix_stream_connect) (struct socket * sock,
				    struct socket * other);

	/**
	 * unix_may_send - check permissions for Unix domain datagram IPC
	 * @sock: socket structure
	 * @sock: peer socket structure
	 *
	 * called: unix_dgram_connect <net/unix/af_unix.>
	 * called: unix_dgram_sendmsg <net/unix/af_unix.>
	 *
	 * Check permissions before connecting or sending datagrams
	 * from @sock to @other.  Return 0 if permission is granted.
	 */
	int (*unix_may_send) (struct socket * sock, struct socket * other);
};

/**
 * Lifecycle hooks for network buffers.
 *
 * These hooks are used to help manage the lifecycle of security blobs for
 * &sk_buff structures, and are not intended to be used for access decisions.
 */
struct skb_security_ops {
	/**
	 * alloc_security - new buffer allocation hook
	 * @skb: the buffer being allocated
	 *
	 * called: alloc_skb <net/core/skbuff.c>
	 *
	 * This hook is called by the &sk_buff allocator when a new
	 * buffer is being allocated.  An LSM module may allocate and
	 * assign a new security blob for the &sk_buff via this hook.
	 *
	 * Return 0 if successful, or -ENOMEM on out of memory condition.
	 */
	int (* alloc_security) (struct sk_buff *skb);
	
	/**
	 * clone - sk_buff clone hook
	 * @newskb: the newly cloned buffer
	 * @oldskb: the buffer being cloned
	 *
	 * called: skb_clone <net/core/skbuff.c>
	 *
	 * This hook is called when an &sk_buff is being cloned, and may
	 * be used, for example, to increment a reference count on the
	 * associated security blob.  The security blob in the @newskb
	 * will not have been allocated.
	 *
	 * Returns 0 on success -ENOMEM on failure.
	 */
	int (* clone) (struct sk_buff *newskb, const struct sk_buff *oldskb);
	
	/**
	 * copy - sk_buff copy hook
	 * @newskb: the newly copied buffer
	 * @oldskb: the buffer being copied
	 *
	 * called: copy_skb_header <net/core/skbuff.c>
	 *
	 * This hook is called when an &sk_buff header is being copied,
	 * which occurs during the skb_copy() and pskb_copy() functions in
	 * <net/core/skbuff.c>
	 */
	void (* copy) (struct sk_buff *newskb, const struct sk_buff *oldskb);
	
	/**
	 * free_security - sk_buff destruction hook
	 * @skb: the buffer being destroyed
	 *
	 * called: __kfree_skb <net/core/skbuff.c>
	 *
	 * This hook is called when an &sk_buff is being destroyed, and
	 * should be used to free any associated security blob.
	 */ 
	void (* free_security) (struct sk_buff *skb);
};

struct net_device;
typedef unsigned int (*ip_opfn)(unsigned int hooknum, struct sk_buff **skb,
                                const struct net_device *in, const struct net_device *out,
                                int (*okfn)(struct sk_buff *));
/**
 * IPv4 networking hooks.
 */
struct ip_security_ops {
	/**
	 * Hooks declared with the &ip_opfn function pointer make use
	 * of the Netfilter API for intercepting packets as they traverse
	 * the IP layer.  Each Netfilter hook is grabbed twice: before and
	 * after packets are passed through the standard iptables-based
	 * packet filtering and mangling mechanisms.
	 *
	 * Parameters for these hooks are as follows:
	 *
	 * @hooknum - hook the packet arrived on
	 * @skb - &sk_buff containing the packet
	 * @in - incoming netdevice associated with the packet
	 * @out - outgoing netdevice associated with the packet
	 * @okfn - used internally by Netfilter
	 *
	 * These hooks may return NF_ACCEPT to allow the packet through
	 * and NF_DROP to drop the packet.
	 *
	 * Further information on the Netfilter API may be found in the
	 * Netfilter Hacking HOWTO at http://netfilter.samba.org/ 
	 */
	ip_opfn preroute_first;
	ip_opfn preroute_last;
	ip_opfn input_first;
	ip_opfn input_last;
	ip_opfn forward_first;
	ip_opfn forward_last;
	ip_opfn output_first;
	ip_opfn output_last;
	ip_opfn postroute_first;
	ip_opfn postroute_last;
	
	/**
	 * fragment - IP packet fragmentation hook
	 * @newskb: the newly created fragment
	 * @oldskb: the original packet being fragmented
	 *
	 * called: ip_fragment <net/ipv4/ip_output.c>
	 *
	 * This is called for each fragment generated when an outgoing packet
	 * is being fragmented, and may be used to copy security attributes
	 * from the original packet to each fragment.
	 */
	void (* fragment) (struct sk_buff *newskb,
	                   const struct sk_buff *oldskb);

	/**
	 * defragment - IP packet defragmentation hook
	 * @skb: the incoming fragment
	 *
	 * called: ip_frag_queue <net/ipv4/ip_fragment.c>
	 *
	 * This hook is called when an incoming fragment is about to be
	 * inserted into a reassembly queue.  It's purpose is to enable the
	 * validation of security attributes for each fragment.  An LSM
	 * module using this hook will likely need to maintain its own
	 * fragment queue information, handle fragment expiration and
	 * implement DoS countermeasures.
	 *
	 * Returns 0 on success.
	 *
	 */
	int (* defragment) (struct sk_buff *skb);
	
	/**
	 * encapsulate - IP encapsulation hook
	 * @skb: the encapsulated packet
	 *
	 * called: ipgre_tunnel_xmit <net/ipv4/ip_gre.c>
	 * called: ipip_tunnel_xmit <net/ipv4/ipip.c>
	 * called: ip_encap <net/ipv4/ipmr.c>
	 *
	 * This hook is called when an IP packet is encapsulated, and
	 * may be used to update security attributes prior to reprocessing
	 * via the local_out or forward hooks.
	 */
	void (* encapsulate) (struct sk_buff *skb);
	
	/**
	 * decapsulate - IP decapsulation hook
	 * @skb: the decapsulated packet
	 *
	 * called: ipgre_rcv <net/ipv4/ip_gre.c>
	 * called: ipip_rcv <net/ipv4/ipip.c>
	 * called: pim_rcv_v1 <net/ipv4/ipmr.c>
	 * called: pim_rcv <net/ipv4/ipmr.c>
	 *
	 * This hook is called when a packet is decapsulated, and may
	 * be used to process security attributes at each level of
	 * encapsulation.  An example of this would be keeping track of
	 * nested security associations for an incoming packet.
	 */
	void (* decapsulate) (struct sk_buff *skb);
	
	/**
	 * decode_options - IP options decoding hook
	 * @skb: &sk_buff containing IP packet (usually NULL for outgoing) 
	 * @optptr: &ip_options structure
	 * @pp_ptr: parameter problem pointer
	 *
	 * called: ip_options_compile <net/ipv4/ip_options.c>
	 *
	 * This hook is used for processing IP security options
	 * at the network layer when labeled networking (e.g. CIPSO)
	 * is implemented.
	 *
	 * For outgoing packets, IP options passed down from the
	 * application or transport layers may be verified here
	 * prior the packet being built.
	 *
	 * For incoming packets, IP options may be verified and
	 * their values recorded via the &sk_buff security blob
	 * for later processing.
	 *
	 * Returns 0 on success.
	 *
	 * A non-zero return value will cause an ICMP parameter problem
	 * message to be generated and transmitted to the sender.  The
	 * @pp_ptr parameter may be used to point to the offending option
	 * parameter.
	 */
	int (* decode_options) (struct sk_buff *skb,
	                        const char *optptr, unsigned char **pp_ptr);
};

/**
 * Security hooks for network devices.
 */
struct netdev_security_ops {
	/**
	 * unregister - update state when a network device is unregistered
	 * @dev: the network device
	 *
	 * called: unregister_netdevice <net/core/dev.c>
	 *
	 * lock:  the rtnl semaphore is held by the caller.
	 *
	 * Update the module's state when a network device is unregistered,
	 * deallocating the dev->security field if it was previously allocated.
	 * Since it would be quite invasive to provide hooks in every
	 * location where a network device might be probed or initialized,
	 * there are no separate hooks for allocation or initialization.
	 * Security modules can allocate and initialize the dev->security
	 * field on the first access to the device, but should be
	 * careful to use nonblocking allocation.
	 */
	void (*unregister) (struct net_device *dev);
};

/**
 * Security hooks for kernel module operations.
 */
struct module_security_ops {
	/**
	 * create_module - check permission when allocating space for a module
	 * @name: module name
	 * @size: module size
	 *
	 * called: sys_create_module <kernel/module.c>
	 *
	 * lock:  The big kernel lock is held.
	 *
	 * Check permission before allocating space for a kernel module.
	 * Return 0 if permission is granted.
	 */
 	int  (* create_module) (const char *name, size_t size);

	/**
	 * init_module - check permission when initializing a module
	 * @name: module name
	 * @mod: the module
	 *
	 * called: sys_init_module <kernel/module.c>
	 *
	 * lock:  The big kernel lock is held.
	 *
	 * Check permission before initializing a kernel module.
	 * Return 0 if permission is granted.
	 */
 	int  (* init_module) (const char *name, struct module *mod);

	/**
	 * delete_module - check permission when removing a module
	 * @name: module name
	 *
	 * called: sys_delete_module <kernel/module.c>
	 *
	 * lock:  The big kernel lock is held.
	 *
	 * Check permission before removing a kernel module.
	 * Return 0 if permission is granted.
	 */
 	int  (* delete_module) (const char *name);
};

/**
 * Security hooks affecting all System V IPC operations.
 */
struct ipc_security_ops {
	/**
	 * permission - check IPC permissions
	 * @ipcp: IPC permission set
	 * @flag: desired (requested) permission set
	 *
	 * called: ipcperms <ipc/util.c>
	 *
	 * Check user, group, and other permissions for access to ipc
	 * resources.  Return 0 if permission is granted.  
	 */
	int (* permission) (struct kern_ipc_perm *ipcp, short flag);

	/**
	 * getinfo - check retrieval permission
	 * @id: resource identifier
	 * @cmd: operation to be performed
	 *
	 * called: sys_msgctl <ipc/msg.c>
	 * called: semctl_nolock <ipc/sem.c> by: sys_semctl <ipc/sem.c>
	 * called: sys_shmctl <ipc/shm.c>
	 * called: sys_shmctl <ipc/shm.c>
	 *
	 * Check permission to retrieve information on previously
	 * allocated IPC resources.  Called by the IPC resource
	 * control syscalls, shmctl, msgctl, semctl with a @cmd
	 * argument of: IPC_INFO, SEM_INFO, MSG_INFO, or SHM_INFO as
	 * appropriate.  Return 0 if permission is granted.
	 */
	int (* getinfo) (int id, int cmd);
};

/**
 * Security hooks for individual Messages held in System V IPC Message Queues
 */
struct msg_msg_security_ops {
	/**
	 * alloc_security - allocate security structure for this message
	 * @msg: message structure to be modified
	 *
	 * called: load_msg <ipc/msg.c>
	 *
	 * Allocate and attach a security structure to the
	 * msg->security field. The security field is initialized to
	 * NULL when the structure is first created.  Return 0 if
	 * operation was successful and permission is granted.
	 */
	int (* alloc_security) (struct msg_msg *msg);

	/**
	 * free_security - deallocate security structure for this message
	 * @msg: message structure to be modified
	 *
	 * called: free_msg <ipc/msg.c>
	 */
	void (* free_security) (struct msg_msg *msg);
};

/**
 * Security hooks for System V IPC Message Queues
 */
struct msg_queue_security_ops {
	/**
	 * alloc_security - allocate security structure for this message queue
	 * @msq: message queue structure to be modified
	 *
	 * called: newque <ipc/msg.c>
	 *
	 * Allocate and attach a security structure to the
	 * msq->q_perm.security field. The security field is
	 * initialized to NULL when the structure is first created.
	 * Return 0 if operation was successful and permission is
	 * granted.
	 */
	int (* alloc_security) (struct msg_queue *msq);

	/**
	 * free_security - deallocate security structure for this message queue
	 * @msq: message queue structure to be modified
	 *
	 * called: free_msg <ipc/msg.c>
	 */
	void (* free_security) (struct msg_queue *msq);

	/**
	 * associate - check resource associate permission
	 * @msq: message queue to act upon
	 * @msqid: resource identifier
	 * @msqflg: operation control flags
	 *
	 * called: sys_msgget <ipc/msg.c>
	 *
	 * lock: msg_lock() has been called, so there is a spin_lock
	 * 	 held on 'struct ipc_ids msg_ids'
	 *
	 * Check permission when a message queue is requested through
	 * the msgget system call.  This hook is only called when
	 * returning the message queue identifier for an existing
	 * message queue, not when a new message queue is created.
	 * Return 0 if permission is granted.
	 */
	int (* associate) (struct msg_queue *msq, int msqid, int msqflg);

	/**
	 * msgctl - check permission for message queue control operations
	 * @msq: message queue to act upon
	 * @msqid: resource identifier
	 * @cmd: operation to be performed
	 *
	 * called: sys_msgctl <ipc/msg.c>
	 * called: sys_msgctl <ipc/msg.c>
	 * called: sys_msgctl <ipc/msg.c>
	 *
	 * lock: depending on @cmd, msg_lock() may have been called,
	 * 	so there may be a spin_lock held on 'struct ipc_ids
	 * 	msg_ids'
	 *
	 * Check permission when a message control operation specified
	 * by @cmd is to be performed on the message queue @msq, with
	 * identifier @msqid.  Return 0 if permission is granted.  
	 */
	int (* msgctl) (struct msg_queue *msq, int msqid, int cmd);

	/**
	 * msgsnd - check permission when sending a message to a queue
	 * @msq: message queue to send message to
	 * @msg: message to be enqueued
	 * @msqid: resource identifier 
	 * @msqflg: operational flags
	 *
	 * called: sys_msgsnd <ipc/msg.c>
	 *
	 * lock: msg_lock() has been called, so there is a spin_lock
	 * 	 held on 'struct ipc_ids msg_ids'
	 *
	 * Check permission before a message, @msg, is enqueued on the
	 * message queue, @msq, whose identifier is specified by the
	 * value of @msqid. Return 0 if permission is granted.
	 */
	int (* msgsnd) (struct msg_queue *msq, struct msg_msg *msg, int msqid,
			int msqflg);

	/**
	 * msgrcv - check permission when receiving a message from a queue
	 * @msq: message queue to retrieve message from
	 * @msg: message destination 
	 * @target: task structure for recipient process
	 * @type: type of message requested
	 * @mode: operational flags
	 *
	 * called: pipelined_send <ipc/msg.c>
	 * called: sys_msgrcv <ipc/msg.c>
	 *
	 * lock: msg_lock() has been called, so there is a spin_lock
	 * 	 held on 'struct ipc_ids msg_ids'
	 *
	 * Check permission before a message, @msg, is removed from the
	 * message queue, @msq, whose identifier is specified by the
	 * value of @msqid.  The @target task structure contains a
	 * pointer to the process that will be receiving the message
	 * (not equal to the current process when inline receives are
	 * being performed).  Return 0 if permission is granted.
	 */
	int  (* msgrcv) (struct msg_queue *msq, struct msg_msg *msg,
			 struct task_struct *target, long type, int mode);
};

/**
 * Security hooks for System V Shared Memory Segments
 */
struct shm_security_ops {
	/**
	 * alloc_security - allocate security structure for this memory segment
	 * @shp: shared memory structure to be modified
	 *
	 * called: newseg <ipc/shm.c>
	 *
	 * Allocate and attach a security structure to the
	 * shp->shm_perm.security field.  The security field is
	 * initialized to NULL when the structure is first created.
	 * Return 0 if operation was successful and permission is
	 * granted.
	 */
	int (* alloc_security) (struct shmid_kernel *shp);

	/**
	 * free_security - deallocate security struct for this memory segment 
	 * @shp: shared memory structure to be modified
	 *
	 * called: shm_destroy <ipc/shm.c>
	 */
	void (* free_security) (struct shmid_kernel *shp);

	/**
	 * associate - check resource associate permission
	 * @shp: shared memory structure to be modified
	 * @shmid: resource identifier
	 * @shmflg: operation control flags
	 *
	 * called: sys_shmget <ipc/shm.c>
	 *
	 * lock: shm_lock() has been called, so there is a spin_lock
	 * 	 held on 'struct shmid_kernel shm_ids'
	 *
	 * Check permission when a shared memory region is requested
	 * through the shmget system call.  This hook is only called
	 * when returning the shared memory region identifier for an
	 * existing region, not when a new shared memory region is
	 * created.  Return 0 if permission is granted.
	 */
	int (* associate) (struct shmid_kernel *shp, int shmid, int shmflg);

	/**
	 * shmctl - check permission for shared memory control operations
	 * @shp: shared memory structure to be modified
	 * @shmid: resource identifier
	 * @cmd: operation to be performed
	 *
	 * called: sys_shmctl <ipc/shm.c>
	 * called: sys_shmctl <ipc/shm.c>
	 * called: sys_shmctl <ipc/shm.c>
	 * called: sys_shmctl <ipc/shm.c>
	 *
	 * lock: depending on @cmd, shm_lock() may have been called,
	 * so there may be a spin_lock held on 'struct shmid_kernel
	 * shm_ids'
	 *
	 * Check permission when a shared memory control operation
	 * specified by @cmd is to be performed on the shared memory
	 * region @shp, with identifier @shmid.  Return 0 if
	 * permission is granted.
	 */
	int (* shmctl) (struct shmid_kernel *shp, int shmid, int cmd);

	/** shmat - check permissions when attaching a memory segment
	 * @shp: shared memory structure to be modified
	 * @shmid: resource identifier
	 * @shmaddr: address to attach memory region to
	 * @shmflg: operational flags
	 *
	 * called: sys_shmat <ipc/shm.c>
	 *
	 * lock: shm_lock() has been called, so there is a spin_lock
	 * 	 held on 'struct shmid_kernel shm_ids'
	 *
	 * Check permissions prior to allowing the shmat system call
	 * to attach the shared memory segment @shp, identified by
	 * @shmid, to the data segment of the calling process. The
	 * attaching address is specified by @shmaddr.  Return 0 if
	 * permission is granted.
	 */
	int (* shmat) (struct shmid_kernel *shp, int shmid, char *shmaddr, 
		       int shmflg);
};

/**
 * Security hooks for System V Semaphores
 */
struct sem_security_ops {
	/**
	 * alloc_security - allocate security structure for this semaphore
	 * @sma: semaphore structure
	 *
	 * called: newary <ipc/sem.c>
	 *
	 * Allocate and attach a security structure to the
	 * sma->sem_perm.security field.  The security field is
	 * initialized to NULL when the structure is first created.
	 * Return 0 if operation was successful and permission is
	 * granted.
	 */
	int (* alloc_security) (struct sem_array *sma);

	/**
	 * free_security - deallocate security struct for this semaphore
	 * @sma: semaphore structure
	 *
	 * called: freeary <ipc/sem.c>
	 */
	void (* free_security) (struct sem_array *sma);

	/**
	 * associate - check resource associate permission
	 * @sma: semaphore structure
	 * @semid: resource identifier
	 * @semflg: operation control flags
	 *
	 * called: sys_semget <ipc/sem.c>
	 *
	 * lock: sem_lock() has been called, so there is a spin_lock
	 * 	 held on 'struct sem_array sem_ids'
	 *
	 * Check permission when a semaphore is requested through the
	 * semget system call.  This hook is only called when
	 * returning the semaphore identifier for an existing
	 * semaphore, not when a new one must be created.  Return 0 if
	 * permission is granted.
	 */
	int (* associate) (struct sem_array *sma, int semid, int semflg);

	/**
	 * semctl - check permission for semaphore control operations
	 * @sma: semaphore structure
	 * @semid: resource identifier
	 * @cmd: operation to be performed
	 *
	 * called: semctl_nolock <ipc/sem.c> by: sys_semctl <ipc/sem.c>
	 * called: semctl_main <ipc/sem.c> by: sys_semctl <ipc/sem.c>
	 * called: semctl_down <ipc/sem.c> by: sys_semctl <ipc/sem.c>
	 *
	 * lock: depending on @cmd, sem_lock() may have been called,
	 * so there may be a spin_lock held on 'sem_array sem_ids'
	 *
	 * Check permission when a semaphore operation specified by
	 * @cmd is to be performed on the semaphore @sma, with
	 * identifier @semid.  Return 0 if permission is granted.
	 */
	int (* semctl) (struct sem_array *sma, int semid, int cmd);

	/** semop - check permission for semaphore operations
	 * @sma: semaphore structure
	 * @semid: resource identifier
	 * @sops: operations to perform
	 * @nsops: number of operations to perform
	 * @alter: flag indicating whether changes are to be made
	 *
	 * called: sys_semop <ipc/sem.c>
	 *
	 * Check permissions before performing operations on members
	 * of the semaphore set @sma, identified by @semid.  If the
	 * @alter flag is nonzero, the semaphore set may be modified.
	 * Return 0 if permission is granted.
	 */
	int (* semop) (struct sem_array *sma, int semid, struct sembuf *sops,
		       unsigned nsops, int alter);
};

struct nfsctl_arg;  /* forward declare to avoid warnings */

struct security_operations {
	int	version;
	
	/**
	 * sethostname - check permission when setting the hostname
	 * @hostname: new hostname
	 *
	 * called: sys_sethostname <kernel/sys.c>
	 *
	 * Check permission before the hostname is set to @hostname.
	 * Return 0 if permission is granted.
	 */
	int (* sethostname) (char *hostname);

	/**
	 * setdomainname - check permission when setting the domainname
	 * @domainname: new domainname
	 *
	 * called: sys_setdomainname <kernel/sys.c>
	 *
	 * Check permission before the domainname is set to @domainname.
	 * Return 0 if permission is granted.
	 */
	int (* setdomainname) (char *domainname);

	/**
	 * reboot - check permission when rebooting or enabling/disabling Ctrl-Alt-Del
	 * @cmd: reboot command
	 *
	 * called: sys_reboot <kernel/sys.c>
	 *
	 * Check permission before rebooting or enabling/disabling the
	 * Ctrl-Alt-Del key sequence.  Return 0 if permission is granted.
	 * The values for @cmd are defined in the reboot(2) manual page.
	 */
	int (* reboot) (unsigned int cmd);	

	/**
	 * ioperm - check permission when setting port input/output permissions
	 * @from: starting port address
	 * @num:  number of bytes starting from @from
	 * @turn_on: permissions value
	 *
	 * called: sys_ioperm <arch/i386/kernel/ioport.c>
	 *
	 * Check permission before setting port input/output permissions
	 * for the process for @num bytes starting from the port address 
	 * @from to the value @turn_on.  Return 0 if permission is granted.
	 */
	int (* ioperm) (unsigned long from, unsigned long num, int turn_on);

	/**
	 * iopl - check permission when changing input/output privilege level
	 * @old: old level
	 * @level: new level
	 *
	 * called: sys_iopl <arch/i386/kernel/ioport.c>
	 * called: sys_iopl <arch/ia64/ia32/sys_ia32.c>
	 *
	 * Check permission before changing the I/O privilege level of the
	 * current process from @old to @level.  Return 0 if permission is
	 * granted.
	 */
	int (* iopl) (unsigned int old, unsigned int level);

	/**
	 * ptrace - check permission when tracing a process
	 * @parent: task_struct structure for parent process 
	 * @child:  task_struct structure for child process 
	 *
	 * called: ptrace_attach <kernel/ptrace.c>
	 * called: sys_ptrace <arch/i386/kernel/ptrace.c>
	 * called: sys_ptrace <arch/ia64/kernel/ptrace.c>
	 * called: MAY_PTRACE <fs/proc/base.c>
	 *
	 * locks:  task_lock is called by ptrace_attach on the child task.
	 *         The big kernel lock is held by sys_ptrace.
	 *
	 * Check permission before allowing the @parent process to trace
	 * the @child process.  Return 0 if permission is granted.
	 *
	 * Security modules may also want to perform a process tracing
	 * check during an execve in the set_security or compute_creds
	 * hooks of binprm_security_ops if the process is being traced
	 * and its security attributes would be changed by the execve.
	 */
	int (* ptrace) (struct task_struct *parent, struct task_struct *child);

	/**
	 * capget - get the capability sets for a process
	 * @target: task_struct structure for target process 
	 * @effective:  effective capability set
	 * @inheritable:  inheritable capability set
	 * @permitted:  permitted capability set
	 *
	 * called: sys_capget <kernel/capability.c>
	 *
	 * locks:  The task_capability_lock is held by sys_capget.
	 *         The tasklist_lock is read-locked by sys_capget
	 *         unless @target is the current process.
	 *
	 * Get the @effective, @inheritable, and @permitted capability
	 * sets for the @target process.  The hook may also perform
	 * permission checking to determine if the current process is
	 * allowed to see the capability sets of the @target process.
	 * Return 0 if the capability sets were successfully obtained.
	 */
	int (*capget) (struct task_struct *target, kernel_cap_t *effective,
		       kernel_cap_t *inheritable, kernel_cap_t *permitted);

	/**
	 * capset_check - check permission when setting capability sets 
	 * @target: task_struct structure for target process 
	 * @effective:  effective capability set
	 * @inheritable:  inheritable capability set
	 * @permitted:  permitted capability set
	 *
	 * called: sys_capset <kernel/capability.c>
	 *
	 * locks:  The task_capability_lock is held by sys_capset.
	 *         The tasklist_lock is read-locked by sys_capset if
	 *         a single target process other than current was
	 *         specified.
	 *
	 * Check permission before setting the @effective, @inheritable, and 
	 * @permitted capability sets for the @target process.  Return 0
	 * if permission is granted.
	 *
	 * Caveat:  @target is also set to current if a set of processes
	 * is specified (i.e. all processes other than current and init or
	 * a particular process group).  Hence, the capset_set hook may need 
	 * to revalidate permission to the actual target process.
	 */
	int (*capset_check) (struct task_struct *target,
			     kernel_cap_t *effective, 
			     kernel_cap_t *inheritable,
			     kernel_cap_t *permitted);

	/**
	 * capset_set - Set the capability sets for a process
	 * @target: task_struct structure for target process 
	 * @effective:  effective capability set
	 * @inheritable:  inheritable capability set
	 * @permitted:  permitted capability set
	 *
	 * called: sys_capset <kernel/capability.c>
	 * called: cap_set_pg <kernel/capability.c>
	 * called: cap_set_all <kernel/capability.c>
	 *
	 * locks:  The task_capability_lock is held by sys_capset.
	 *         The tasklist_lock is read-locked unless only the
	 *         capability sets for current are being set.
	 *
	 * Set the @effective, @inheritable, and @permitted capability sets
	 * for the @target process.  Since capset_check cannot always check
	 * permission to the real @target process, this hook may also perform
	 * permission checking to determine if the current process is
	 * allowed to set the capability sets of the @target process.
	 * However, this hook has no way of returning an error due to
	 * the structure of the sys_capset code.
	 */
	void (*capset_set) (struct task_struct *target,
			    kernel_cap_t *effective, kernel_cap_t *inheritable,
			    kernel_cap_t *permitted);

	/**
	 * acct - Check permission when enabling or disabling process accounting
	 * @file: file structure for the accounting file (may be NULL)
	 *
	 * called: sys_acct <kernel/acct.c>
	 *
	 * Check permission before enabling or disabling process accounting.
	 * If accounting is being enabled, then @file refers to the open
	 * file used to store accounting records.  If accounting is being
	 * disabled, then @file is NULL.  Return 0 if permission is granted.
	 */
	int (* acct) (struct file *file);

	/**
	 * sysctl - Check permission when accessing a sysctl variable
	 * @table: the ctl_table structure for the sysctl variable
	 * @op:  the operation (001 = search, 002 = write, 004 = read)
	 *
	 * called: ctl_perm <kernel/sysctl.c>
	 *
	 * Check permission before accessing the @table sysctl variable
	 * in the manner specified by @op.  Return 0 if permission is granted.
	 */
	int (* sysctl) (ctl_table * table, int op);

	/**
	 * capable - Check a particular capability for a process
	 * @tsk: the task_struct for the process
	 * @cap: the capability <include/linux/capability.h>
	 *
	 * called: capable <security/security.c>
	 * called: must_not_trace_exec <fs/exec.c>
	 * called: badness <mm/oom_kill.c>
	 * called: oom_kill_task <mm/oom_kill.c>
	 *
	 * Check whether the @tsk process has the @cap capability.
	 * Return 0 if the capability is granted for @tsk.
	 */
	int (* capable) (struct task_struct *tsk, int cap);

	/**
	 * sys_security - Security system call multiplexor
	 * @id: security module identifier 
	 * @call: call value
	 * @args: call arguments (user space pointer)
	 *
	 * called: sys_security <security/security.c>
	 *
	 * Security modules may use this hook to implement new system 
	 * calls for security-aware applications.  The interface is similar 
	 * to socketcall, but with an @id parameter to help identify the 
	 * security module whose call is being invoked.  The module is 
	 * responsible for interpreting the parameters, and must copy in the 
	 * @args array from user space if it is used.  The module should
	 * return -ENOSYS if it does not implement any new system calls.
	 */
	int (* sys_security) (unsigned int id, unsigned call,
			      unsigned long *args);

	/**
	 * swapon - Check permission before enabling swapping to a file/device.
	 * @dentry: dentry structure for the swap file or device
	 *
	 * called: sys_swapon <mm/swapfile.c>
	 *
	 * lock:  The big kernel lock is held by sys_swapon.
	 * 
	 * Check permission before enabling swapping to the file
	 * or block device identified by @dentry.  Return 0 if
	 * permission is granted.
	 */
	int (* swapon) (struct dentry *dentry);

	/**
	 * swapoff - Check permission before disabling swapping to a file/device.
	 * @dentry: dentry structure for the swap file or device
	 *
	 * called: sys_swapoff <mm/swapfile.c>
	 *
	 * Check permission before disabling swapping to the file
	 * or block device identified by @dentry.  Return 0 if
	 * permission is granted.
	 */
	int (* swapoff) (struct dentry *dentry);

	/**
	 * nfsservctl - Check permission before accessing the kernel NFS daemon
	 * @cmd: command value 
	 * @arg: command arguments
	 *
	 * called: handle_sys_nfsservctl <fs/nfsd/nfsctl.c> 
	 *
	 * lock:  The big kernel lock is held.
	 *
	 * Check permission before having the kernel NFS daemon 
	 * perform command @cmd with arguments @arg.  Return 0 if 
	 * permission is granted.  See the nfsservctl(2) manual page
	 * for an explanation of @cmd and @arg values.
	 */
	int (* nfsservctl) (int cmd, struct nfsctl_arg *arg);

	/**
	 * quotactl - Check permission before manipulating disk quotas
	 * @cmd: command value
	 * @type: type of quota (USRQUOTA or GRPQUOTA)
	 * @id: user or group identifier
	 * @sb: super_block structure for the filesystem (may be NULL)
	 *
	 * called: sys_quotactl <fs/dquot.c>
	 *
	 * Check permission before performing the quota operation 
	 * identified by @cmd for the specified @type, @id, and
	 * @sb.  The @sb parameter may be NULL, e.g. for the Q_SYNC
	 * and Q_GETSTATS commands.  Return 0 if permission is granted.
	 */
	int (* quotactl) (int cmds, int type, int id, struct super_block *sb);

	/**
	 * quota_on - Check permission when enabling quotas 
	 * @f: the open file for storing quotas
	 *
	 * called: quota_on <fs/dquot.c>
	 *
	 * Check permission before enabling quotas for a file
	 * system using @f as the quota file.  Return 0 if permission 
	 * is granted.
	 */
	int (* quota_on) (struct file *f);

	/**
	 * bdflush - Check permission before tuning the bdflush daemon
	 * @func: the tuning function 
	 * @data: tuning parameter pointer (user space pointer) or value
	 *
	 * called: sys_bdflush <fs/buffer.c>
	 *
	 * Check permission before tuning the bdflush parameter.  
	 * See the bdflush(2) manual page for an explanation of
	 * the @func and @data parameters.  The @data parameter
	 * should only be used by the module if it is an input
	 * value.  Return 0 if permission is granted.
	 */
	int (* bdflush) (int func, long data);

	/**
	 * syslog - Check permission before accessing the kernel message ring
	 * @type: the type of action
	 *
	 * called: do_syslog <kernel/printk.c>
	 *
	 * Check permission before accessing the kernel message ring or
	 * changing logging to the console.  Return 0 if permission is 
	 * granted.  See the syslog(2) manual page for an explanation of
	 * the @type values.  
	 */
	int (* syslog) (int type);

	/**
	 * netlink_send - Save security information for a netlink message.
	 * @skb: the sk_buff structure for the netlink message
	 *
	 * called: netlink_sendmsg <net/netlink/af_netlink.c>
	 *
	 * Save security information for a netlink message so that
	 * permission checking can be performed when the message
	 * is processed.  The security information can either be
	 * saved using the existing eff_cap field of the netlink_skb_parms
	 * structure or it can be saved using the skbuff lsm_security field.
	 * Return 0 if the information was successfully saved.
	 */
	int (* netlink_send) (struct sk_buff *skb);

	/**
	 * netlink_recv - Check permission when receiving a netlink message
	 * @skb: the sk_buff structure for the netlink message
	 *
	 * called: rtnetlink_rcv_msg <net/core/rtnetlink.c>
	 * called: netlink_receive_user_skb <net/ipv4/netfilter/ip_queue.c>
	 *
	 * Check permission before processing the received netlink message
	 * in @skb.  Return 0 if permission is granted.
	 */
	int (* netlink_recv) (struct sk_buff *skb);

	struct binprm_security_ops	* bprm_ops;
	struct super_block_security_ops	* sb_ops;
	struct inode_security_ops	* inode_ops;
	struct file_security_ops	* file_ops;
	struct task_security_ops	* task_ops;
	struct socket_security_ops	* socket_ops;
	struct skb_security_ops		* skb_ops;
	struct ip_security_ops		* ip_ops;
	struct netdev_security_ops	* netdev_ops;
	struct module_security_ops	* module_ops;
	struct ipc_security_ops		* ipc_ops;
	struct msg_msg_security_ops	* msg_msg_ops;
	struct msg_queue_security_ops	* msg_queue_ops;
	struct shm_security_ops		* shm_ops;
	struct sem_security_ops		* sem_ops;

	/* allow module stacking */
	int (* register_security)	(const char *name, struct security_operations *ops);
	int (* unregister_security)	(const char *name, struct security_operations *ops);
};


/* prototypes */
extern int security_scaffolding_startup	(void);
extern int register_security	(struct security_operations *ops);
extern int unregister_security	(struct security_operations *ops);
extern int mod_reg_security	(const char *name, struct security_operations *ops);
extern int mod_unreg_security	(const char *name, struct security_operations *ops);
extern int capable		(int cap);

/* global variables */
extern struct security_operations *security_ops;


#endif /* __KERNEL__ */

#endif /* ! __LINUX_SECURITY_H */