/incron/trunk/incrontab.5 |
---|
1,4 → 1,4 |
.TH "incrontab" "5" "0.3.4" "Lukas Jelinek" "incron documentation" |
.TH "incrontab" "5" "0.3.5" "Lukas Jelinek" "incron documentation" |
.SH "NAME" |
incrontab \- tables for driving inotify cron (incron) |
.SH "DESCRIPTION" |
/incron/trunk/ict-main.cpp |
---|
152,14 → 152,12 |
/** |
* \param[in] user user name |
* \return true = success, false = failure |
* |
* \attention Listing is currently done through 'cat'. |
*/ |
bool list_table(const char* user) |
{ |
std::string tp(InCronTab::GetUserTablePath(user)); |
if (access(tp.c_str(), R_OK) != 0) { |
if (eaccess(tp.c_str(), R_OK) != 0) { |
if (errno == ENOENT) { |
fprintf(stderr, "no table for %s\n", user); |
return true; |
170,9 → 168,18 |
} |
} |
std::string cmd("cat "); |
cmd.append(tp); |
return system(cmd.c_str()) == 0; |
FILE* f = fopen(tp.c_str(), "r"); |
if (f == NULL) |
return false; |
char s[1024]; |
while (fgets(s, 1024, f) != NULL) { |
fputs(s, stdout); |
} |
fclose(f); |
return true; |
} |
/// Allows to edit an user table. |
/incron/trunk/CHANGELOG |
---|
1,3 → 1,10 |
0.3.5 2007-01-09 |
* based on inotify-cxx 0.6.3 |
* a security bug related to access rights to watched files fixed (#0000119) |
* crashing on table reload after removing a watched path fixed (#0000123) |
* 'incrontab --list' dysfunction fixed (#0000122) |
0.3.4 2007-01-03 |
* based on inotify-cxx 0.6.2 |
* problems with wrong ordered setting of UID/GID fixed (#0000115, #0000117) |
/incron/trunk/incrond.8 |
---|
1,4 → 1,4 |
.TH "incrond" "8" "0.3.4" "Lukas Jelinek" "incron documentation" |
.TH "incrond" "8" "0.3.5" "Lukas Jelinek" "incron documentation" |
.SH "NAME" |
incrond \- inotify cron (incron) daemon |
/incron/trunk/inotify-cxx.cpp |
---|
270,7 → 270,7 |
IN_WRITE_END |
} |
void InotifyWatch::OnOneshotEvent() |
void InotifyWatch::__Disable() |
{ |
IN_WRITE_BEGIN |
446,8 → 446,9 |
InotifyWatch* pW = FindWatch(pEvt->wd); |
if (pW != NULL) { |
InotifyEvent evt(pEvt, pW); |
if (InotifyEvent::IsType(pW->GetMask(), IN_ONESHOT)) |
pW->OnOneshotEvent(); |
if ( InotifyEvent::IsType(pW->GetMask(), IN_ONESHOT) |
|| InotifyEvent::IsType(evt.GetMask(), IN_IGNORED)) |
pW->__Disable(); |
m_events.push_back(evt); |
} |
i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len; |
/incron/trunk/inotify-cxx.h |
---|
503,13 → 503,13 |
IN_LOCK_DECL |
/// Disables the watch (if it has the one-shot flag). |
/// Disables the watch (due to removing by the kernel). |
/** |
* This method must be called after receiving an event. |
* It ensures the watch object is consistent with the kernel |
* data. |
*/ |
void OnOneshotEvent(); |
void __Disable(); |
}; |
/incron/trunk/usertable.cpp |
---|
18,10 → 18,19 |
#include <syslog.h> |
#include <errno.h> |
#include <sys/wait.h> |
#include <unistd.h> |
#include <grp.h> |
#include <sys/stat.h> |
#include "usertable.h" |
#ifdef IN_DONT_FOLLOW |
#define NO_FOLLOW(mask) InotifyEvent::IsType(mask, IN_DONT_FOLLOW) |
#else // IN_DONT_FOLLOW |
#define NO_FOLLOW(mask) (false) |
#endif // IN_DONT_FOLLOW |
PROC_LIST UserTable::s_procList; |
112,6 → 121,11 |
for (int i=0; i<cnt; i++) { |
InCronTabEntry& rE = m_tab.GetEntry(i); |
InotifyWatch* pW = new InotifyWatch(rE.GetPath(), rE.GetMask()); |
// warning only - permissions may change later |
if (!MayAccess(rE.GetPath(), NO_FOLLOW(rE.GetMask()))) |
syslog(LOG_WARNING, "access denied on %s - events will be discarded silently", rE.GetPath().c_str()); |
try { |
m_pIn->Add(pW); |
m_pEd->Register(pW, this); |
142,9 → 156,14 |
InotifyWatch* pW = rEvt.GetWatch(); |
InCronTabEntry* pE = FindEntry(pW); |
// no entry found - this shouldn't occur |
if (pE == NULL) |
return; |
// discard event if user has no access rights to watch path |
if (!MayAccess(pW->GetPath(), NO_FOLLOW(rEvt.GetMask()))) |
return; |
std::string cmd; |
const std::string& cs = pE->GetCmd(); |
size_t pos = 0; |
304,4 → 323,51 |
} |
} |
bool UserTable::MayAccess(const std::string& rPath, bool fNoFollow) const |
{ |
// first, retrieve file permissions |
struct stat st; |
int res = fNoFollow |
? lstat(rPath.c_str(), &st) // don't follow symlink |
: stat(rPath.c_str(), &st); |
if (res != 0) |
return false; // retrieving permissions failed |
// file accessible to everyone |
if (st.st_mode & S_IRWXO) |
return true; |
// retrieve user data |
struct passwd* pwd = getpwnam(m_user.c_str()); |
// file accesible to group |
if (st.st_mode & S_IRWXG) { |
// user's primary group |
if (pwd != NULL && pwd->pw_gid == st.st_gid) |
return true; |
// now check group database |
struct group *gr = getgrgid(st.st_gid); |
if (gr != NULL) { |
int pos = 0; |
const char* un; |
while ((un = gr->gr_mem[pos]) != NULL) { |
if (strcmp(un, m_user.c_str()) == 0) |
return true; |
pos++; |
} |
} |
} |
// file accessible to owner |
if (st.st_mode & S_IRWXU) { |
if (pwd != NULL && pwd->pw_uid == st.st_uid) |
return true; |
} |
return false; // no access right found |
} |
/incron/trunk/usertable.h |
---|
146,6 → 146,17 |
* which has been caused by the processes. |
*/ |
static void FinishDone(); |
/// Checks whether the user may access a file. |
/** |
* Any access right (RWX) is sufficient. |
* |
* \param[in] rPath absolute file path |
* \param[in] fNoFollow don't follow a symbolic link |
* \return true = access granted, false = otherwise |
*/ |
bool MayAccess(const std::string& rPath, bool fNoFollow) const; |
private: |
Inotify* m_pIn; ///< inotify object |
EventDispatcher* m_pEd; ///< event dispatcher |
/incron/trunk/incrontab.1 |
---|
1,4 → 1,4 |
.TH "incrontab" "1" "0.3.4" "Lukas Jelinek" "incron documentation" |
.TH "incrontab" "1" "0.3.5" "Lukas Jelinek" "incron documentation" |
.SH "NAME" |
incrontab \- table manipulator for inotify cron (incron) |
.SH "SYNOPSIS" |
/incron/trunk/incron.h |
---|
27,7 → 27,7 |
#define INCRON_TAB_NAME "incrontab" |
/// Application version (release) |
#define INCRON_VERSION "0.3.4" |
#define INCRON_VERSION "0.3.5" |
/// Address for sending bugs |
#define INCRON_BUG_ADDRESS "<bugs@aiken.cz>" |