diff -u -w -r /usr/src/linux-origin/fs/namei.c /usr/src/linux/fs/namei.c
--- /usr/src/linux-origin/fs/namei.c	Sun Jan 30 17:03:48 2000
+++ /usr/src/linux/fs/namei.c	Sat Feb 12 10:35:53 2000
@@ -12,11 +12,17 @@
  * lookup logic.
  */
 
+#define __KERNEL_SYSCALLS__
+
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
 #include <linux/quotaops.h>
 
+#include <linux/string.h>
+#include <linux/unistd.h>
+#include <linux/sched.h>
+
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 #include <asm/semaphore.h>
@@ -24,6 +30,8 @@
 #include <asm/pgtable.h>
 
 #include <asm/namei.h>
+#include <linux/ext2_fs.h>  /* for EXT2_SECRM_FL */
+
 
 /* This can be removed after the beta phase. */
 #define CACHE_SUPERVISE	/* debug the correctness of dcache entries */
@@ -1025,25 +1033,202 @@
 	return error;
 }
 
-int vfs_unlink(struct inode *dir, struct dentry *dentry)
+
+
+
+
+
+/* call program secrm - security delete */
+static int vfs_unlink_exec_srm(void *file_name)
+{
+ 
+   static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
+   char *argv[]={"/bin/secrm",(char *)file_name,NULL };
+   
+   
+   
+	/* Prevent parent user process from sending signals to child.
+	   Otherwise, if the secrm program does not exist, it might
+	   be possible to get a user defined signal handler to execute
+	   as the super user right after the execve fails if you time
+	   the signal just right.
+	*/
+	spin_lock_irq(&current->sigmask_lock);
+	flush_signals(current);
+	flush_signal_handlers(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+
+   /* Drop the "current user" thing */
+	free_uid(current);
+
+	/* Give secrm all privileges.. 
+	   Waitpid reports error without it. */
+	current->uid = current->euid = current->fsuid = 0;
+	cap_set_full(current->cap_inheritable);
+	cap_set_full(current->cap_effective); 
+
+   
+   
+   
+   
+   /* Allow execve args to be in kernel space. */
+
+   
+   
+/*   printk("set_fs(KERNEL_DS)\n");*/
+   
+	set_fs(KERNEL_DS);
+
+/*   printk("Execve\n"); */
+   
+	/* Go, go, go... */
+	if (execve("/bin/secrm", argv, envp) < 0) {
+	   
+	   printk("vfs_unlink_exec_srm: can't exec /bin/secrm\n");
+	   return -errno;
+	}
+   
+   return 0;
+   
+   
+}
+
+
+int vfs_unlink(struct inode *dir, struct dentry *dentry, const char *name, struct dentry **dir2)
 {
 	int error;
+        pid_t pid,waitpid_result;
+        int status;
+        sigset_t tmpsig;
+        mm_segment_t addr_limit;
+   
 
 	error = may_delete(dir, dentry, 0);
 	if (!error) {
 		error = -EPERM;
 		if (dir->i_op && dir->i_op->unlink) {
+					   
+		       /*dentry->d_inode->i_sb->s_type->name == ext2*/
+		       /* filesystem type*/
+		       
+		   if (!strcmp(dentry->d_inode->i_sb->s_type->name,"ext2"))
+		     {
+			
+		
+			if (dentry->d_inode->u.ext2_i.i_flags  & EXT2_SECRM_FL )
+			  {
+			     
+			  
+			 /*  printk("Security flag set.\n"); */
+			     
+			     if (S_ISREG(dentry->d_inode->i_mode)) {
+			/*	printk("Regular file: %s\n",name); */
+			
+			/*	printk("Starting thread...\n"); */
+				
+				unlock_dir(*dir2);
+				unlock_kernel();
+			
+				*dir2=NULL; /* do_unlink - don't unlock*/
+				/* printk("vfs_unlink: unlock\n"); */
+				
+				pid = kernel_thread(vfs_unlink_exec_srm, (void*) name, 0);
+				
+				
+				
+				if (pid<0) {
+				   printk("fork failed:  vfs_unlink_exec_srm\n");
+				   lock_kernel();
+				   return -EIO;
+				   
+				}
+				
+       
+				
+	/* Block everything but SIGKILL/SIGSTOP */
+	spin_lock_irq(&current->sigmask_lock);
+	tmpsig = current->blocked;
+	siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	/*printk("Waitpid...\n");*/
+
+        addr_limit=get_fs();
+				
+	 set_fs(KERNEL_DS);
+        
+				
+	waitpid_result = waitpid(pid, &status,__WCLONE);
+
+	set_fs(addr_limit);
+				
+	/* Allow signals again.. */
+	spin_lock_irq(&current->sigmask_lock);
+	current->blocked = tmpsig;
+	recalc_sigpending(current);
+	spin_unlock_irq(&current->sigmask_lock);
+
+				
+			       
+	/*printk("\npid:%i\nwaitpid:%i\nresult:%i\n\n",pid,waitpid_result,status);*/
+				
+				lock_kernel();
+					      
+				if (waitpid_result != pid) {
+				   
+				   printk("vfs_unlink: secrm error (waitpid)\n");
+				   return -EIO;
+				}
+				      				
+				if (!status) return 0; /* OK */
+				
+        			if (status<0x100) {
+				   
+				   			   
+				   printk("vfs_unlink: secrm - signal %i caught.\n",status);
+				   
+				   return -EINTR;
+				   
+				   
+				}
+				
+				
+				status=status>>8;
+				
+				/* printk("vfs_unlink: secrm exit code:%i\n",status); */
+				
+				return -status;
+				      
+								     
+			     }
+
+			  }
+				
+				
+		     }
+			     
+			     		     
+		
+	
+		   
 			DQUOT_INIT(dir);
 			error = dir->i_op->unlink(dir, dentry);
+	
 		}
+	   
 	}
+
 	return error;
 }
 
+   
+   
 static inline int do_unlink(const char * name)
 {
 	int error;
-	struct dentry *dir;
+	struct dentry *dir,*dir2;
 	struct dentry *dentry;
 
 	dentry = lookup_dentry(name, NULL, 0);
@@ -1051,12 +1236,15 @@
 	if (IS_ERR(dentry))
 		goto exit;
 
-	dir = lock_parent(dentry);
+	dir=dir2= lock_parent(dentry);
 	error = -ENOENT;
 	if (check_parent(dir, dentry))
-		error = vfs_unlink(dir->d_inode, dentry);
+	       error = vfs_unlink(dir->d_inode, dentry,name,&dir2);
 
-        unlock_dir(dir);
+   /* dir2 == NULL - dir unlocked */
+
+        if (dir2) unlock_dir(dir);
+/*        else printk("do_unlock: don't unlock\n"); */
 	dput(dentry);
 exit:
 	return error;
diff -u -w -r /usr/src/linux-origin/include/linux/fs.h /usr/src/linux/include/linux/fs.h
--- /usr/src/linux-origin/include/linux/fs.h	Sun Jan 30 17:48:15 2000
+++ /usr/src/linux/include/linux/fs.h	Wed Feb  9 23:49:16 2000
@@ -566,7 +566,7 @@
  * VFS helper functions..
  */
 extern int vfs_rmdir(struct inode *, struct dentry *);
-extern int vfs_unlink(struct inode *, struct dentry *);
+extern int vfs_unlink(struct inode *, struct dentry *, const char * name, struct dentry **) ;
 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
 
 /*
