/*
 * This is an example Linux Security Module for the purpose of demonstrating
 * the concept to the University of Texas Linux kernel class.         
 *
 *	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.
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/security.h>
#include <linux/stat.h>
#include <linux/netfilter.h>
#include <linux/netlink.h>
#include <linux/ctype.h>
#include <linux/file.h>

#include "lsm_example.h"

/* flag to keep track of how we were registered */
static int secondary;

static int example_sethostname (char *hostname)
{
	return 0;
}

static int example_setdomainname (char *domainname)
{
	return 0;
}

static int example_reboot (unsigned int cmd)
{
	return 0;
}

static int example_ioperm (unsigned long from, unsigned long num, int turn_on)
{
	return 0;
}

static int example_iopl (unsigned int old, unsigned int level)
{
	return 0;
}

static int example_ptrace (struct task_struct *parent, struct task_struct *child) 
{ 
	return 0; 
}

static int example_capget (struct task_struct *target, kernel_cap_t * effective,
                        kernel_cap_t * inheritable, kernel_cap_t * permitted)
{
	return 0;
}

static int example_capset_check (struct task_struct *target,
                             kernel_cap_t * effective,
                             kernel_cap_t * inheritable,
                             kernel_cap_t * permitted)
{
	return 0;
}

static void example_capset_set (struct task_struct *target,
                            kernel_cap_t * effective,
                            kernel_cap_t * inheritable,
                            kernel_cap_t * permitted)
{
	return;
}

static int example_acct (struct file *file) 
{
	return 0;
}

static int example_capable (struct task_struct *tsk, int cap)
{
	/* from dummy.c */
	if (cap_is_fs_cap (cap) ? tsk->fsuid == 0 : tsk->euid == 0)
		/* capability granted */
		return 0;

	/* capability denied */
	return -EPERM;
}

static int example_sysctl (ctl_table * table, int op) 
{
	return 0;
}

static int example_sys_security (unsigned int id, unsigned int call,
                             unsigned long *args)
{
        return -ENOSYS;
}

static int example_swapon (struct swap_info_struct *swap)
{
        return 0;
}

static int example_swapoff (struct swap_info_struct *swap)
{
        return 0;
}

static int example_nfsservctl (int cmd, struct nfsctl_arg *arg)
{
        return 0;
}

static int example_quotactl (int cmds, int type, int id, struct super_block *sb)
{
        return 0;
}

static int example_quota_on (struct file *f)
{
        return 0;
}

static int example_bdflush (int func, long data)
{
        return 0;
}

static int example_syslog (int type)
{
        return 0;
}

static int example_netlink_send (struct sk_buff *skb)
{
	/* from dummy.c */
	if (current->euid == 0)
		cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
	else
		NETLINK_CB (skb).eff_cap = 0;
	return 0;
}

static int example_netlink_recv (struct sk_buff *skb)
{
	/* from dummy.c */
	if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN))
		return -EPERM;
	return 0;
}

static int example_binprm_alloc_security(struct linux_binprm *bprm)
{
	return 0;
}

static void example_binprm_free_security (struct linux_binprm *bprm)
{
	return;
}

static void example_binprm_compute_creds (struct linux_binprm *bprm) 
{
	return;
}

static int example_binprm_set_security (struct linux_binprm *bprm) 
{
	return 0;
}

static int example_sb_alloc_security (struct super_block *sb)
{
	return 0;
}

static void example_sb_free_security (struct super_block *sb)
{
	return;
}

static int example_sb_statfs (struct super_block *sb) 
{
	return 0;
}

static int example_sb_mount (char *devname, struct nameidata *nd, char *type, 
			  unsigned long flags, void *data) 
{
	return 0;
}

static int example_sb_check_sb (struct vfsmount *mnt, struct nameidata *nd)
{
	return 0;
}

static int example_sb_umount (struct vfsmount *mnt, int flags) 
{
	return 0;
}

static void example_sb_umount_close (struct vfsmount *mnt)
{
	return;
}

static void example_sb_umount_busy (struct vfsmount *mnt) 
{
	return;
}
static void example_sb_post_remount (struct vfsmount *mnt, unsigned long flags, 
				  void *data)
{
	return;
}

static void example_sb_post_mountroot (void)
{
	return;
}

static void example_sb_post_addmount (struct vfsmount *mnt, struct nameidata *nd)
{
	return;
}

static int example_inode_alloc_security (struct inode *inode)
{
	return 0;
}

static void example_inode_free_security (struct inode *inode)
{
	return;
}

static int example_inode_create (struct inode *inode, struct dentry *dentry, 
			      int mask) 
{
	return 0;
}

static void example_inode_post_create (struct inode *inode, struct dentry *dentry,
				    int mask) 
{
	return;
}

static int example_inode_link (struct dentry *old_dentry, struct inode *inode, 
			    struct dentry *new_dentry) 
{
	return 0;
}

static void example_inode_post_link (struct dentry *old_dentry, 
				  struct inode *inode, 
				  struct dentry *new_dentry) 
{
	return;
}

static int example_inode_unlink (struct inode *inode, struct dentry *dentry)
{
	return 0;
}

static int example_inode_symlink (struct inode *inode, struct dentry *dentry, 
			       const char *name)
{
	return 0;
}

static void example_inode_post_symlink (struct inode *inode, 
				      struct dentry *dentry, const char *name)
{
	return;
}

static int example_inode_mkdir (struct inode *inode, struct dentry *dentry, 
			     int mask) 
{
	return 0;
}

static void example_inode_post_mkdir (struct inode *inode, struct dentry *dentry, 
				   int mask) 
{
	return;
}

static int example_inode_rmdir (struct inode *inode, struct dentry *dentry) 
{
	return 0;
}

static int example_inode_mknod (struct inode *inode, struct dentry *dentry, 
			     int major, dev_t minor) 
{
	return 0;
}

static void example_inode_post_mknod (struct inode *inode, struct dentry *dentry, 
				   int major, dev_t minor)
{
	return;
}

static int example_inode_rename (struct inode *old_inode, 
			      struct dentry *old_dentry, 
			      struct inode *new_inode, 
			      struct dentry *new_dentry) 
{
	return 0;
}

static void example_inode_post_rename (struct inode *old_inode, 
				    struct dentry *old_dentry, 
				    struct inode *new_inode, 
				    struct dentry *new_dentry) 
{
	return;
}

static int example_inode_readlink (struct dentry *dentry)
{
	return 0;
}

static int example_inode_follow_link (struct dentry *dentry, 
				   struct nameidata *nameidata) 
{
	return 0;
}

static int example_inode_permission (struct inode *inode, int mask)
{
	return do_example_inode_permission(inode, mask);
}

static int example_inode_revalidate (struct dentry *inode)
{
	return 0;
}

static int example_inode_setattr (struct dentry *dentry, struct iattr *iattr)
{
	return 0;
}

static int example_inode_stat (struct inode *inode)
{
	return 0;
}

static void example_post_lookup (struct inode *ino, struct dentry *d) 
{
	return;
}

static void example_delete (struct inode *ino) 
{
	return;
}

static int example_file_permission (struct file *file, int mask)
{
	return 0;
}

static int example_file_alloc_security (struct file *file)	
{
	return 0;
}

static void example_file_free_security (struct file *file)	
{
	return;
}

static int example_file_llseek (struct file *file)	
{
	return 0;
}

static int example_file_ioctl (struct file *file, unsigned int command , 
			    unsigned long arg)
{
	return 0;
}

static int example_file_mmap (struct file *file, unsigned long prot, 
			   unsigned long flags)	
{
	return 0;
}

static int example_file_mprotect (struct vm_area_struct *vma, unsigned long prot)
{
	return 0;
}

static int example_file_lock (struct file *file, unsigned int cmd)
{
	return 0;
}

static int example_file_fcntl (struct file *file, unsigned int cmd, 
			     unsigned long arg)
{
	return 0;
}

static int example_file_set_fowner (struct file *file)
{
	return 0;
}

static int example_file_send_sigiotask (struct task_struct *tsk, 
				      struct fown_struct *fown, 
				      int fd, int reason) 
{ 
	return 0;
}

static int example_file_receive (struct file *file)
{
	return 0;
}

static int example_task_create (unsigned long clone_flags)
{
	return 0;
}

static int example_task_alloc_security (struct task_struct *p)
{
	return 0;
}

static void example_task_free_security (struct task_struct *p)
{
	return;
}

static int example_task_setuid (uid_t id0, uid_t id1, uid_t id2, int flags)
{ 
	return 0; 
}

static int example_task_post_setuid(uid_t old_ruid, uid_t old_euid, 
				 uid_t old_suid, int flags)
{
	return 0;
}

static int example_task_setgid (gid_t id0, gid_t id1, gid_t id2, int flags) 
{
	return 0;
}

static int example_task_setpgid (struct task_struct *p, pid_t pgid) 
{
	return 0;
}

static int example_task_getpgid (struct task_struct *p) 
{
	return 0;
}

static int example_task_getsid (struct task_struct *p) 
{
	return 0;
}

static int example_task_setgroups (int gidsetsize, gid_t *grouplist)
{
	return 0;
}

static int example_task_setnice (struct task_struct *p, int nice)
{
	return 0;
}

static int example_task_setrlimit (unsigned int resource, struct rlimit *new_rlim)
{
	return 0;
}

static int example_task_setscheduler (struct task_struct *p, int policy,
				   struct sched_param *lp)
{
	return 0;
}

static int example_task_getscheduler (struct task_struct *p) 
{ 
	return 0; 
}

static int example_task_wait (struct task_struct *p) 
{
	return 0;
}

static int example_task_kill (struct task_struct *p, struct siginfo *info, int sig)
{
	return 0;
}

static int example_task_prctl (int option, unsigned long arg2, unsigned long arg3,
			     unsigned long arg4, unsigned long arg5)
{
	return 0;
}

static void example_task_kmod_set_label (void) 
{ 
	return; 
}

static unsigned int example_ip_preroute_first (unsigned int hooknum, 
					    struct sk_buff **pskb,
					    const struct net_device *in, 
					    const struct net_device *out,
					    int (*okfn)(struct sk_buff *))
{
	return NF_ACCEPT;
}

static unsigned int example_ip_preroute_last (unsigned int hooknum, 
					   struct sk_buff **pskb, 
					   const struct net_device *in, 
					   const struct net_device *out, 
					   int (*okfn)(struct sk_buff *))
{
	return NF_ACCEPT;
}

static unsigned int example_ip_input_first	(unsigned int hooknum, 
					 struct sk_buff **pskb,
					 const struct net_device *in,
					 const struct net_device *out, 
					 int (*okfn)(struct sk_buff *))
{
	return NF_ACCEPT;
}

static unsigned int example_ip_input_last (unsigned int hooknum, 
					struct sk_buff **pskb, 
					const struct net_device *in, 
					const struct net_device *out, 
					int (*okfn)(struct sk_buff *)) 
{
	return NF_ACCEPT;
}

static unsigned int example_ip_forward_first (unsigned int hooknum, 
					   struct sk_buff **pskb, 
					   const struct net_device *in, 
					   const struct net_device *out, 
					   int (*okfn)(struct sk_buff *))
{
	return NF_ACCEPT;
}

static unsigned int example_ip_forward_last (unsigned int hooknum, 
					  struct sk_buff **pskb, 
					  const struct net_device *in, 
					  const struct net_device *out, 
					  int (*okfn)(struct sk_buff *))
{
	return NF_ACCEPT;
}

static unsigned int example_ip_output_first (unsigned int hooknum, 
					  struct sk_buff **pskb, 
					  const struct net_device *in, 
					  const struct net_device *out, 
					  int (*okfn)(struct sk_buff *)) 
{
	return NF_ACCEPT;
}

static unsigned int example_ip_output_last	(unsigned int hooknum, 
					 struct sk_buff **pskb,
					 const struct net_device *in, 
					 const struct net_device *out, 
					 int (*okfn)(struct sk_buff *)) 
{
	return NF_ACCEPT;
}

static unsigned int example_ip_postroute_first (unsigned int hooknum, 
					     struct sk_buff **pskb, 
					     const struct net_device *in, 
					     const struct net_device *out, 
					     int (*okfn)(struct sk_buff *))
{
	return NF_ACCEPT;
}

static unsigned int example_ip_postroute_last (unsigned int hooknum, 
					    struct sk_buff **pskb, 
					    const struct net_device *in, 
					    const struct net_device *out, 
					    int (*okfn)(struct sk_buff *)) 
{
	return NF_ACCEPT;
}

static void example_ip_fragment (struct sk_buff *newskb, 
			      const struct sk_buff *oldskb) 
{
	return;
}

static int example_ip_defragment (struct sk_buff *skb) 
{
	return 0;
}

static void example_ip_encapsulate (struct sk_buff *skb) 
{
	return;
}

static void example_ip_decapsulate (struct sk_buff *skb) 
{
	return;
}

static int example_decode_options (struct sk_buff *skb, const char *optptr,
				unsigned char **pp_ptr)
{
	/* from dummy.c */
	if (!skb && !capable (CAP_NET_RAW)) {
		(const unsigned char *) *pp_ptr = optptr;
		return -EPERM;
	}
	return 0;
}

static void example_netdev_unregister (struct net_device *dev) 
{
	return;
}

static int example_socket_create (int family, int type, int protocol) 
{
	return 0;
}
static void example_socket_post_create (struct socket *sock, int family, 
				      int type, int protocol) 
{
	return;
}

static int example_socket_bind (struct socket *sock, struct sockaddr *address, 
			      int addrlen) 
{
	return 0;
}

static int example_socket_connect (struct socket *sock, struct sockaddr *address, 
				 int addrlen) 
{
	return 0;
}

static int example_socket_listen (struct socket *sock, int backlog) 
{
	return 0;
}

static int example_socket_accept (struct socket *sock, struct socket *newsock) 
{
	return 0;
}

static int example_socket_sendmsg (struct socket *sock, struct msghdr *msg, 
				int size) 
{
	return 0;
}

static int example_socket_recvmsg (struct socket *sock, struct msghdr *msg, 
				int size, int flags) 
{
	return 0;
}

static int example_socket_getsockname (struct socket *sock) 
{
	return 0;
}

static int example_socket_getpeername (struct socket *sock) 
{
	return 0;
}

static int example_socket_setsockopt (struct socket *sock, int level, int optname)
{
	return 0;
}

static int example_socket_getsockopt (struct socket *sock, int level, int optname)
{
	return 0;
}

static int example_socket_shutdown (struct socket *sock, int how) 
{
	return 0;
}

static int example_socket_sock_rcv_skb (struct sock *sk, struct sk_buff *skb)
{
	return 0;
}

static int example_socket_unix_stream_connect (struct socket *sock, 
					     struct socket *other)
{
	return 0;
}

static int example_socket_unix_may_send (struct socket *sock, 
				       struct socket *other)
{
	return 0;
}

static int example_module_create_module (const char *name_user, size_t size)
{
	return 0;
}

static int example_module_init_module (struct module *mod)
{
	return 0;
}

static int example_module_delete_module (const struct module *mod)	
{
	return 0;
}

static int example_ipc_permission (struct kern_ipc_perm *ipcp, short flag) 
{
	return 0;
}

static int example_ipc_getinfo (int id, int cmd) 
{
	return 0;
}

static int example_msg_msg_alloc_security (struct msg_msg *msg)	
{
	return 0;
}

static void example_msg_msg_free_security	(struct msg_msg *msg)
{
	return;
}

static int example_msg_queue_alloc_security (struct msg_queue *msq)	
{
	return 0;
}

static void example_msg_queue_free_security (struct msg_queue *msq)	
{
	return;
}

static int example_msg_queue_associate (struct msg_queue *msq, int msgid, 
				     int msgflg)	
{
	return 0;
}

static int example_msg_queue_msgctl (struct msg_queue *msq, int msgid, int cmd)
{
	return 0;
}

static int example_msg_queue_msgsnd (struct msg_queue *msq, struct msg_msg *msg, 
				  int msgid, int msgflg)
{
	return 0;
}

static int example_msg_queue_msgrcv (struct msg_queue *msq, struct msg_msg *msg, 
				  struct task_struct *target, 
				  long type, int mode)
{
	return 0;
}

static int example_shm_alloc_security (struct shmid_kernel *shp)
{
	return 0;
}

static void example_shm_free_security (struct shmid_kernel *shp)
{
	return;
}

static int example_shm_associate (struct shmid_kernel *shp, int shmid, int shmflg)
{
	return 0;
}

static int example_shm_shmctl (struct shmid_kernel *shp, int shmid, int cmd)
{
	return 0;
}

static int example_shm_shmat (struct shmid_kernel *shp, int shmid, char *shmaddr, 
			   int shmflg) 
{
	return 0;
}

static int example_sem_alloc_security (struct sem_array *sma) 
{
	return 0;
}

static void example_sem_free_security (struct sem_array *sma) 
{
	return;
}

static int example_sem_associate (struct sem_array *sma, int semid, int semflg) 
{
	return 0;
}

static int example_sem_semctl (struct sem_array *sma, int semid, int cmd) 
{
	return 0;
}

static int example_sem_semop (struct sem_array *sma, int semid, 
			   struct sembuf *sops, unsigned nsops, int alter)
{
	return 0;
}

static int example_skb_alloc_security (struct sk_buff *skb)
{
	return 0;
}

static int example_skb_clone (struct sk_buff *newskb, 
			    const struct sk_buff *oldskb)
{
	return 0;
}

static void example_skb_copy (struct sk_buff *newskb, 
			    const struct sk_buff *oldskb) 
{
	return;
}

static void example_skb_set_owner_w (struct sk_buff *skb, struct sock *sk)
{
        return;
}

static void example_skb_free_security (struct sk_buff *skb)
{
	return;
}

static int example_register (const char *name, struct security_operations *ops)	
{
	return -EINVAL;
}

static int example_unregister (const char *name, struct security_operations *ops)
{
	return -EINVAL;
}

static struct binprm_security_ops example_binprm_ops = {
	alloc_security:	example_binprm_alloc_security,
	free_security:	example_binprm_free_security,
	compute_creds:	example_binprm_compute_creds,
	set_security:	example_binprm_set_security,
};

static struct super_block_security_ops example_sb_ops = {
	alloc_security:	example_sb_alloc_security,
	free_security:	example_sb_free_security,
	statfs:	        example_sb_statfs,
	mount:		example_sb_mount,
	check_sb:	example_sb_check_sb,
	umount:		example_sb_umount,
	umount_close:	example_sb_umount_close,
	umount_busy:	example_sb_umount_busy,
	post_remount:	example_sb_post_remount,
	post_mountroot:	example_sb_post_mountroot,
	post_addmount:	example_sb_post_addmount,
};

static struct inode_security_ops example_inode_ops = {
	alloc_security:	example_inode_alloc_security,
	free_security:	example_inode_free_security,
	create:		example_inode_create,
	post_create:	example_inode_post_create,
	link:		example_inode_link,
	post_link:	example_inode_post_link,
	unlink:		example_inode_unlink,
	symlink:	example_inode_symlink,
	post_symlink:	example_inode_post_symlink,
	mkdir:		example_inode_mkdir,
	post_mkdir:	example_inode_post_mkdir,
	rmdir:		example_inode_rmdir,
	mknod:		example_inode_mknod,
	post_mknod:	example_inode_post_mknod,
	rename:		example_inode_rename,
	post_rename:	example_inode_post_rename,
	readlink:	example_inode_readlink,
	follow_link:	example_inode_follow_link,
	permission:	example_inode_permission,
	revalidate:	example_inode_revalidate,
	setattr:	example_inode_setattr,
	stat:           example_inode_stat,
	post_lookup:	example_post_lookup,
	delete:		example_delete,
};

static struct file_security_ops	example_file_ops = {
	permission:	example_file_permission,
	alloc_security:	example_file_alloc_security,
	free_security:	example_file_free_security,
	llseek:		example_file_llseek,
	ioctl:		example_file_ioctl,
	mmap:		example_file_mmap,
	mprotect:	example_file_mprotect,
	lock:		example_file_lock,
	fcntl:		example_file_fcntl,
	set_fowner:	example_file_set_fowner,
	send_sigiotask:	example_file_send_sigiotask,
	receive:        example_file_receive,
};

static struct task_security_ops	example_task_ops = {
	create:		example_task_create,
	alloc_security:	example_task_alloc_security,
	free_security:	example_task_free_security,
	setuid:		example_task_setuid,
	post_setuid:	example_task_post_setuid,
	setgid:		example_task_setgid,
	setpgid:	example_task_setpgid,
	getpgid:	example_task_getpgid,
	getsid:		example_task_getsid,
	setgroups:	example_task_setgroups,
	setnice:	example_task_setnice,
	setrlimit:	example_task_setrlimit,
	setscheduler:	example_task_setscheduler,
	getscheduler:	example_task_getscheduler,
	wait:		example_task_wait,
	kill:		example_task_kill,
	prctl:		example_task_prctl,
	kmod_set_label:	example_task_kmod_set_label,
};

static struct socket_security_ops example_socket_ops = {
	create:			example_socket_create,
	post_create:		example_socket_post_create,
	bind:			example_socket_bind,
	connect:		example_socket_connect,
	listen:			example_socket_listen,
	accept:			example_socket_accept,
	sendmsg:		example_socket_sendmsg,
	recvmsg:		example_socket_recvmsg,
	getsockname:		example_socket_getsockname,
	getpeername:		example_socket_getpeername,
	getsockopt:		example_socket_getsockopt,
	setsockopt:		example_socket_setsockopt,
	shutdown:		example_socket_shutdown,
	sock_rcv_skb:		example_socket_sock_rcv_skb,
	unix_stream_connect:	example_socket_unix_stream_connect,
	unix_may_send:		example_socket_unix_may_send,
};

static struct skb_security_ops example_skb_ops = {
	alloc_security:	example_skb_alloc_security,
	clone:		example_skb_clone,
	copy:		example_skb_copy,
	set_owner_w:	example_skb_set_owner_w,
	free_security:	example_skb_free_security,
};

static struct ip_security_ops example_ip_ops = {
	preroute_first:		example_ip_preroute_first,
	preroute_last:		example_ip_preroute_last,
	input_first:		example_ip_input_first,
	input_last:		example_ip_input_last,
	forward_first:		example_ip_forward_first,
	forward_last:		example_ip_forward_last,
	output_first:		example_ip_output_first,
	output_last:		example_ip_output_last,
	postroute_first:	example_ip_postroute_first,
	postroute_last:		example_ip_postroute_last,
	fragment:		example_ip_fragment,
	defragment:		example_ip_defragment,
	encapsulate:		example_ip_encapsulate,
	decapsulate:		example_ip_decapsulate,
	decode_options:		example_decode_options,
};

static struct netdev_security_ops example_netdev_ops = {
	unregister:	example_netdev_unregister,
};

static struct module_security_ops example_module_ops = {
	create_module:	example_module_create_module,
	init_module:	example_module_init_module,
	delete_module:	example_module_delete_module,

};

static struct ipc_security_ops example_ipc_ops = {
	permission:	example_ipc_permission,
	getinfo:	example_ipc_getinfo,
};

static struct msg_msg_security_ops example_msg_ops = {
	alloc_security:	example_msg_msg_alloc_security,
	free_security:	example_msg_msg_free_security,
};

static struct msg_queue_security_ops example_msg_queue_ops = {
	alloc_security:	example_msg_queue_alloc_security,
	free_security:	example_msg_queue_free_security,
	associate:	example_msg_queue_associate,
	msgctl:		example_msg_queue_msgctl,
	msgsnd:		example_msg_queue_msgsnd,
	msgrcv:		example_msg_queue_msgrcv,
};

static struct shm_security_ops example_shm_ops = {
	alloc_security: example_shm_alloc_security,
	free_security:  example_shm_free_security,
	associate:	example_shm_associate,
	shmctl:		example_shm_shmctl,
	shmat:		example_shm_shmat,
};

static struct sem_security_ops example_sem_ops = {
	alloc_security: example_sem_alloc_security,
	free_security:  example_sem_free_security,
	associate:	example_sem_associate,
	semctl:		example_sem_semctl,
	semop:		example_sem_semop,
};

static struct security_operations example_ops = {
	sethostname:		example_sethostname,
	setdomainname:		example_setdomainname,
	reboot:			example_reboot,
	ioperm:			example_ioperm,
	iopl:			example_iopl,
	ptrace:			example_ptrace,
	capget:			example_capget,
	capset_check:		example_capset_check,
	capset_set:		example_capset_set,
	acct:			example_acct,
	sysctl:			example_sysctl,
	capable:		example_capable,
	sys_security:		example_sys_security,
	swapon:			example_swapon,
	swapoff:		example_swapoff,
	nfsservctl:		example_nfsservctl,
	quotactl:		example_quotactl,
	quota_on:		example_quota_on,
	bdflush:		example_bdflush,
	syslog:			example_syslog,
	netlink_send:		example_netlink_send,
	netlink_recv:		example_netlink_recv,

	bprm_ops:		&example_binprm_ops,
	sb_ops:			&example_sb_ops,
	inode_ops:		&example_inode_ops,
	file_ops:		&example_file_ops,
	task_ops:		&example_task_ops,
	socket_ops:		&example_socket_ops,
	skb_ops:		&example_skb_ops,
	ip_ops:			&example_ip_ops,
	netdev_ops:		&example_netdev_ops,
	module_ops:		&example_module_ops,
	ipc_ops:		&example_ipc_ops,
	msg_msg_ops:		&example_msg_ops,
	msg_queue_ops:		&example_msg_queue_ops,
	shm_ops:		&example_shm_ops,
	sem_ops:		&example_sem_ops,
	
	register_security:	example_register,
	unregister_security:	example_unregister,
};

#if defined(CONFIG_SECURITY_example_MODULE)
#define MY_NAME THIS_MODULE->name
#else
#define MY_NAME "example"
#endif

static int __init example_init (void)
{
	/* register ourselves with the security framework */
	if (register_security (&example_ops)) {
		printk (KERN_INFO 
			"Failure registering example module with the kernel\n");
		/* try registering with primary module */
		if (mod_reg_security (MY_NAME, &example_ops)) {
			printk (KERN_INFO "Failure registering example module "
				"with primary security module.\n");
			return -EINVAL;
		}
		secondary = 1;
	}
	printk(KERN_INFO "example LSM initialized\n");
	return 0;
}

static void __exit example_exit (void)
{
	/* remove ourselves from the security framework */
	if (secondary) {
		if (mod_unreg_security (MY_NAME, &example_ops))
			printk (KERN_INFO "Failure unregistering example module "
				"with primary module.\n");
		return;
	}
 
	if (unregister_security (&example_ops)) {
		printk (KERN_INFO
			"Failure unregistering example module with the kernel\n");
	}
}

module_init (example_init);
module_exit (example_exit);

MODULE_DESCRIPTION("Example Linux Security Module");
MODULE_LICENSE("GPL");
