Как использовать FAN_DENY? (Fanotify)

0

Я прочитал manpages для Fanotify и флаг FAN_DENY. Интересно.

Я не нашел примеров, которые используют FAN_DENY.

Manpage: http://www.xypron.de/projects/fanotify-manpages/man7/fanotify.7.html

Теги:
fanotify

1 ответ

0
Лучший ответ

После исследования нашла необходимую документацию о FAN_DENY.

Пример:

/* 
    Technical details:

    Fanotify is a system for handle file system actions, default in Linux kernel since 2.6.
*/

#define _GNU_SOURCE
#define _ATFILE_SOURCE
#include <linux/fanotify.h>
#include <errno.h>
#include <inttypes.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

//#define FANOTIFY_ARGUMENTS "cdfhmnp"
int fan_fd;

/* Mark a object */
int mark_object(int fan_fd, const char *path, int fd, uint64_t mask, unsigned int flags)
{
    return fanotify_mark(fan_fd, flags, mask, fd, path);
}

/* Usage */
int usage(char** file[])
{
   fprintf(stdout, "Application for deny acess to your files.\nUsage: %s [file]\n", file[0]);
}

/* Main */
int main(int argc, char** argv[])
{
   /* Check for arguments.. */
   if(argc != 2) // if user not give file argument
   {
     usage(argv);
     return 1;
   }
   /* Fanotify options */
   uint64_t fan_mask = FAN_OPEN | FAN_CLOSE | FAN_ACCESS | FAN_MODIFY | FAN_EVENT_ON_CHILD | FAN_ALL_PERM_EVENTS;
   unsigned int mark_flags = FAN_MARK_ADD, init_flags = 0;
   /* Other declarations */
   ssize_t len;
   char buf[4096];
   fd_set rfds;
   /* Initalize Fanotify */
   if(fan_mask & FAN_ALL_PERM_EVENTS)
     init_flags |= FAN_CLASS_CONTENT;
   else
     init_flags |= FAN_CLASS_NOTIF;
   fan_fd = fanotify_init(init_flags, O_RDONLY | O_LARGEFILE);
   if(fan_fd < 0)
   {
     goto fail;
   }
   /* Mark object/Initalize object control with Fanotify */
   for(; optind < argc; optind++)
   {
      if(mark_object(fan_fd, argv[optind], AT_FDCWD, fan_mask, mark_flags) != 0)
      {
        //fprintf(stderr, "Can't set Fanotify on this file '%s'!", argv[optind]);
        goto fail;
        //return 1;
      }
   }
   /* Restore fan_fd variable */
   FD_ZERO(&rfds);
   FD_SET(fan_fd, &rfds);
   /* Loop for start another loop for check fanotify events */
   while((len = read(fan_fd, buf, sizeof(buf))) > 0)
   {
       /* Declarations */
       struct fanotify_event_metadata *metadata;
       struct fanotify_response response;
       char path[PATH_MAX];
       int path_len;
       metadata = (void *)buf;

       /* New loop for check fanotify events */ 
       while(FAN_EVENT_OK(metadata, len)) 
       {
           /* Check if fanotify version are too old */
           if(metadata->vers < 2)
           {
             fprintf(stderr, "Kernel fanotify version too old\n");
             return 1;
           }
           /* Get path that acesser trys */
           if(metadata->fd >= 0)
           {
             sprintf(path, "/proc/self/fd/%d", metadata->fd);
             path_len = readlink(path, path, sizeof(path)-1);
             if(path_len < 0)
               goto fail;
             path[path_len] = '\0';
             fprintf(stdout, "%s:", path);
       }
           /* Can't get path */ 
           else
           {
              fprintf(stdout, "?:");
           }
           if(!strcmp(path, argv[1]))
           { 
             response.fd = metadata->fd;
             response.response = FAN_DENY;
             write(fan_fd, &response, sizeof(struct fanotify_response));
           }
           /* Pid of acesser */
           fprintf(stdout, " pid=%ld", (long)metadata->pid);
           /* Check actions by acesser and kill acesser */
           if(metadata->mask & FAN_ACCESS)
           {
         fprintf(stdout, " access");
             if(!strcmp(path, argv[1]))
             { 
               response.fd = metadata->fd;
               response.response = FAN_DENY;
               write(fan_fd, &response, sizeof(struct fanotify_response));
             }
           }
       if(metadata->mask & FAN_OPEN)
           {
         fprintf(stdout, " open");
             if(!strcmp(path, argv[1]))
             { 
               response.fd = metadata->fd;
               response.response = FAN_DENY;
               write(fan_fd, &response, sizeof(struct fanotify_response));
             }
           }
       if(metadata->mask & FAN_MODIFY)
           {
         fprintf(stdout, " modify");
             if(!strcmp(path, argv[1]))
             { 
               response.fd = metadata->fd;
               response.response = FAN_DENY;
               write(fan_fd, &response, sizeof(struct fanotify_response));
             }
           }
       if(metadata->mask & FAN_CLOSE)
           {
              if(metadata->mask & FAN_CLOSE_WRITE)
            fprintf(stdout, " close(writable)");
           }
           /* Setup the output */
           fprintf(stdout, "\n");
           fflush(stdout);
           /* Check for internal error */
           if(metadata->fd >= 0 && close(metadata->fd) != 0)
           {
         goto fail;
           }
           /* Next fanotify event.. */
           metadata = FAN_EVENT_NEXT(metadata, len);
       } // end of loop 2
   } // end of loop 1

   /* Check for len error */
   if(len < 0)
   {
     goto fail;
   }
   /* Declare fail */
fail:
   fprintf(stderr, "%s\n", strerror(errno));
   return 1;
   /* Quit */
   return 0;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню