filesystem.cc File Reference


Detailed Description

Implementation of the sefs_filesystem class.

Author:
Jeremy A. Mowery jmowery@tresys.com

Jason Tang jtang@tresys.com

Copyright (C) 2007 Tresys Technology, LLC

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Definition in file filesystem.cc.

#include <config.h>
#include "sefs_internal.hh"
#include "new_ftw.h"
#include <sefs/entry.hh>
#include <sefs/filesystem.hh>
#include <apol/util.h>
#include <selinux/context.h>
#include <selinux/selinux.h>
#include <assert.h>
#include <errno.h>
#include <mntent.h>
#include <regex.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

Go to the source code of this file.


Classes

struct  filesystem_ftw_struct
struct  filesystem_dev

Functions

int lgetfilecon_raw (const char *, security_context_t *) __attribute__((weak))
int filesystem_lgetfilecon (const char *path, security_context_t *context)
 As that setools must work with older libselinux versions that may not have the _raw() functions, declare them as weak.
sefs_context_nodefilesystem_get_context (sefs_filesystem *fs, security_context_t scon) throw (std::bad_alloc)
sefs_entryfilesystem_get_entry (sefs_filesystem *fs, const struct sefs_context_node *node, uint32_t objClass, const char *path, ino64_t ino, const char *dev_name) throw (std::bad_alloc)
bool filesystem_is_query_match (sefs_filesystem *fs, const sefs_query *query, const char *path, const char *dev, const struct stat64 *sb, apol_vector_t *type_list, apol_mls_range_t *range) throw (std::runtime_error)
uint32_t filesystem_stat_to_objclass (const struct stat64 *sb)
int filesystem_dev_cmp (const void *a, const void *b __attribute__((unused)), void *arg)
int filesystem_ftw_handler (const char *fpath, const struct stat64 *sb, int typeflag __attribute__((unused)), struct FTW *ftwbuf __attribute__((unused)), void *data)
void filesystem_dev_free (void *elem)
sefs_filesystem_tsefs_filesystem_create (const char *root, sefs_callback_fn_t msg_callback, void *varg)
 Allocate and return a new sefs filesystem structure representing the filesystem rooted at directory root.
const char * sefs_filesystem_get_root (const sefs_filesystem_t *fs)
 Get the root directory of a sefs filesystem structure.
const char * sefs_filesystem_get_dev_name (sefs_filesystem_t *fs, const dev_t dev)
 Look up the given device number on the currently running system, and convert it to its device name.

Function Documentation

int lgetfilecon_raw const char *  ,
security_context_t * 
 

Referenced by filesystem_lgetfilecon().

int filesystem_lgetfilecon const char *  path,
security_context_t *  context
[static]
 

As that setools must work with older libselinux versions that may not have the _raw() functions, declare them as weak.

If libselinux does indeed have the new functions then use them; otherwise fallback to the originals.

Definition at line 53 of file filesystem.cc.

References lgetfilecon_raw().

Referenced by filesystem_ftw_handler(), sefs_filesystem::isQueryMatch(), and sefs_filesystem::sefs_filesystem().

00054 {
00055         if (lgetfilecon_raw != NULL)
00056         {
00057                 return lgetfilecon_raw(path, context);
00058         }
00059         else
00060         {
00061                 return lgetfilecon(path, context);
00062         }
00063 }

struct sefs_context_node* filesystem_get_context sefs_filesystem fs,
security_context_t  scon
throw (std::bad_alloc) [inline]
 

Definition at line 236 of file filesystem.cc.

Referenced by filesystem_ftw_handler().

00237 {
00238         return fs->getContext(scon);
00239 }

sefs_entry* filesystem_get_entry sefs_filesystem fs,
const struct sefs_context_node node,
uint32_t  objClass,
const char *  path,
ino64_t  ino,
const char *  dev_name
throw (std::bad_alloc) [inline]
 

Definition at line 241 of file filesystem.cc.

Referenced by filesystem_ftw_handler().

00243 {
00244         return fs->getEntry(node, objClass, path, ino, dev_name);
00245 }

bool filesystem_is_query_match sefs_filesystem fs,
const sefs_query query,
const char *  path,
const char *  dev,
const struct stat64 *  sb,
apol_vector_t type_list,
apol_mls_range_t range
throw (std::runtime_error) [inline]
 

Definition at line 247 of file filesystem.cc.

References apol_mls_range_t, and apol_vector_t.

Referenced by filesystem_ftw_handler().

00250 {
00251         return fs->isQueryMatch(query, path, dev, sb, type_list, range);
00252 }

uint32_t filesystem_stat_to_objclass const struct stat64 *  sb  )  [static]
 

Definition at line 254 of file filesystem.cc.

Referenced by filesystem_ftw_handler(), and sefs_filesystem::isQueryMatch().

00255 {
00256         if (S_ISREG(sb->st_mode))
00257         {
00258                 return QPOL_CLASS_FILE;
00259         }
00260         if (S_ISDIR(sb->st_mode))
00261         {
00262                 return QPOL_CLASS_DIR;
00263         }
00264         if (S_ISCHR(sb->st_mode))
00265         {
00266                 return QPOL_CLASS_CHR_FILE;
00267         }
00268         if (S_ISBLK(sb->st_mode))
00269         {
00270                 return QPOL_CLASS_BLK_FILE;
00271         }
00272         if (S_ISFIFO(sb->st_mode))
00273         {
00274                 return QPOL_CLASS_FIFO_FILE;
00275         }
00276         if (S_ISLNK(sb->st_mode))
00277         {
00278                 return QPOL_CLASS_LNK_FILE;
00279         }
00280         if (S_ISSOCK(sb->st_mode))
00281         {
00282                 return QPOL_CLASS_SOCK_FILE;
00283         }
00284         assert(0);                     // should never get here
00285         return 0;
00286 }

int filesystem_dev_cmp const void *  a,
const void *b   __attribute__((unused)),
void *  arg
[static]
 

Definition at line 294 of file filesystem.cc.

References filesystem_dev::dev.

Referenced by filesystem_ftw_handler(), and sefs_filesystem::getDevName().

00295 {
00296         const struct filesystem_dev *d1 = static_cast < const struct filesystem_dev *>(a);
00297         dev_t *d2 = static_cast < dev_t * >(arg);
00298         if (d1->dev < *d2)
00299         {
00300                 return -1;
00301         }
00302         else if (d1->dev > *d2)
00303         {
00304                 return 1;
00305         }
00306         return 0;
00307 }

int filesystem_ftw_handler const char *  fpath,
const struct stat64 *  sb,
int typeflag   __attribute__((unused)),
struct FTW *ftwbuf   __attribute__((unused)),
void *  data
[static]
 

Definition at line 309 of file filesystem.cc.

References filesystem_ftw_struct::aborted, apol_vector_get_element(), apol_vector_get_index(), filesystem_ftw_struct::data, filesystem_ftw_struct::dev_map, filesystem_dev::dev_name, filesystem_dev_cmp(), filesystem_get_context(), filesystem_get_entry(), filesystem_is_query_match(), filesystem_lgetfilecon(), filesystem_stat_to_objclass(), filesystem_ftw_struct::fn, filesystem_ftw_struct::fs, filesystem_ftw_struct::query, filesystem_ftw_struct::range, filesystem_ftw_struct::retval, SEFS_ERR, SEFS_WARN, and filesystem_ftw_struct::type_list.

Referenced by sefs_filesystem::runQueryMap().

00311 {
00312         struct filesystem_ftw_struct *s = static_cast < struct filesystem_ftw_struct *>(data);
00313 
00314         size_t i;
00315         void *dev_num = const_cast < void *>(static_cast < const void *>(&(sb->st_dev)));
00316         int rc = apol_vector_get_index(s->dev_map, NULL, filesystem_dev_cmp, dev_num, &i);
00317         const char *dev = "<unknown>";
00318         if (rc == 0)
00319         {
00320                 // if the device number was discovered in buildDevMap
00321                 // then store the device name within the entry
00322                 struct filesystem_dev *d = static_cast < struct filesystem_dev *>(apol_vector_get_element(s->dev_map, i));
00323                 dev = d->dev_name;
00324         }
00325         else
00326         {
00327                 SEFS_WARN(s->fs, "Unknown device for %s.", fpath);
00328         }
00329         try
00330         {
00331                 if (!filesystem_is_query_match(s->fs, s->query, fpath, dev, sb, s->type_list, s->range))
00332                 {
00333                         return 0;
00334                 }
00335         }
00336         catch(...)
00337         {
00338                 return -1;
00339         }
00340 
00341         security_context_t scon;
00342         if (filesystem_lgetfilecon(fpath, &scon) < 0)
00343         {
00344                 SEFS_ERR(s->fs, "Could not read SELinux file context for %s.", fpath);
00345                 return -1;
00346         }
00347         struct sefs_context_node *node = NULL;
00348         try
00349         {
00350                 node = filesystem_get_context(s->fs, scon);
00351         }
00352         catch(...)
00353         {
00354                 freecon(scon);
00355                 return -1;
00356         }
00357         freecon(scon);
00358 
00359         uint32_t objClass = filesystem_stat_to_objclass(sb);
00360 
00361         sefs_entry *entry = NULL;
00362         try
00363         {
00364                 entry = filesystem_get_entry(s->fs, node, objClass, fpath, sb->st_ino, dev);
00365         }
00366         catch(...)
00367         {
00368                 return -1;
00369         }
00370 
00371         // invoke real callback (not just the nftw handler)
00372         s->retval = s->fn(s->fs, entry, s->data);
00373         delete entry;
00374         if (s->retval < 0)
00375         {
00376                 s->aborted = true;
00377                 return s->retval;
00378         }
00379 
00380         return 0;
00381 }

void filesystem_dev_free void *  elem  )  [static]
 

Definition at line 454 of file filesystem.cc.

Referenced by sefs_filesystem::buildDevMap().

00455 {
00456         if (elem != NULL)
00457         {
00458                 struct filesystem_dev *d = static_cast < struct filesystem_dev *>(elem);
00459                 // don't free the device name pointer, because it's pointing
00460                 // into the dev_tree BST
00461                 free(d);
00462         }
00463 }

sefs_filesystem_t* sefs_filesystem_create const char *  root,
sefs_callback_fn_t  msg_callback,
void *  varg
 

Allocate and return a new sefs filesystem structure representing the filesystem rooted at directory root.

See also:
sefs_filesystem::sefs_filesystem()

Definition at line 689 of file filesystem.cc.

References sefs_filesystem_t.

00690 {
00691         sefs_filesystem_t *fs;
00692         try
00693         {
00694                 fs = new sefs_filesystem(root, msg_callback, varg);
00695         }
00696         catch(...)
00697         {
00698                 errno = ENOMEM;
00699                 return NULL;
00700         }
00701         return fs;
00702 }

const char* sefs_filesystem_get_root const sefs_filesystem_t fs  ) 
 

Get the root directory of a sefs filesystem structure.

See also:
sefs_filesystem::root()

Definition at line 704 of file filesystem.cc.

References sefs_filesystem::root(), SEFS_ERR, and sefs_filesystem_t.

00705 {
00706         if (fs == NULL)
00707         {
00708                 SEFS_ERR(NULL, "%s", strerror(EINVAL));
00709                 errno = EINVAL;
00710                 return NULL;
00711         }
00712         return fs->root();
00713 }

const char* sefs_filesystem_get_dev_name sefs_filesystem_t fs,
const dev_t  dev
 

Look up the given device number on the currently running system, and convert it to its device name.

See also:
sefs_filesystem::ged_dev_name()

Definition at line 715 of file filesystem.cc.

References sefs_filesystem::getDevName(), SEFS_ERR, and sefs_filesystem_t.

00716 {
00717         if (fs == NULL)
00718         {
00719                 SEFS_ERR(NULL, "%s", strerror(EINVAL));
00720                 errno = EINVAL;
00721                 return NULL;
00722         }
00723         const char *dev_name = NULL;
00724         try
00725         {
00726                 dev_name = fs->getDevName(dev);
00727         }
00728         catch(...)
00729         {
00730                 return NULL;
00731         }
00732         return dev_name;
00733 }