diff --git a/content/content.cpp b/content/content.cpp index 58ec3d9..5ecb8c7 100755 --- a/content/content.cpp +++ b/content/content.cpp @@ -216,12 +216,13 @@ void Content::MakeStandardFunction() else if( request.pfunction->code == FUN_UNAME ) FunUname(); +*/ else if( request.pfunction->code == FUN_CHMOD ) - FunChmod(); + FunPriv(); else if( request.pfunction->code == FUN_CHOWN ) - FunChown();*/ + FunPriv(); else request.status = Error::permission_denied; @@ -268,6 +269,8 @@ void Content::MakePost() break; case FUN_PRIV: + case FUN_CHMOD: + case FUN_CHOWN: PostFunPriv(); break; diff --git a/content/content.h b/content/content.h index dc6bb9a..3e4c80b 100755 --- a/content/content.h +++ b/content/content.h @@ -51,7 +51,7 @@ class Content void FunLogout(); void FunLs(); void FunEmacs(); - void FunPriv(); + void FunCKEditor(); @@ -101,18 +101,32 @@ class Content long PostFunDefaultParsePath(); void PostFunDefault(); + + /* + function: priv, chmod, chown + */ bool PrivCheckAccess(); - void PrivLog(const char * what, const std::string & url, long user, long group, int priv); + void PrivLogStart(const char * what, long user, long group, int priv); + void PrivLog(const char * what, long id, const std::string & url); + bool ChangeOwner(Item & item, long user_id, long group_id); + bool ChangePrivileges(Item & item, int privileges); + void ChangePriv(Item & item, long user_id, long group_id, int privileges); void PostFunPriv(); void PrivFilesInDir(long parent_id); void PrivDir(long parent_id); - void FunPriv(Item & item, long user_id, long group_id, int privileges); + + bool ReadPriv(const char * user_in, const char * group_in, const char * priv_in, long & user_id, long & group_id, int & priv); void PrivDir(); void PrivOneItem(); + void FunPriv(); long user_id_file, group_id_file, user_id_dir, group_id_dir; int priv_file, priv_dir; + bool subdirectories; + bool change_owner, change_priv; + + bool FunCreateThreadCheckAccess(); bool FunCreateThreadCheckAbuse(); diff --git a/content/priv.cpp b/content/priv.cpp index 6783129..e865ef1 100755 --- a/content/priv.cpp +++ b/content/priv.cpp @@ -2,7 +2,7 @@ * This file is a part of CMSLU -- Content Management System like Unix * and is not publicly distributed * - * Copyright (c) 2008-2009, Tomasz Sowa + * Copyright (c) 2008-2010, Tomasz Sowa * All rights reserved. * */ @@ -14,6 +14,10 @@ #include "../core/data.h" + + + + bool Content::PrivCheckAccess() { // we do not check permissions here @@ -32,61 +36,135 @@ return true; - -void Content::FunPriv(Item & item, long user_id, long group_id, int privileges) +bool Content::ChangeOwner(Item & item, long user_id, long group_id) { - if( user_id==item.user_id && group_id==item.group_id && privileges==item.privileges ) - return; - - if( !request.CanChangeUser(item, user_id) ) + if( user_id!=item.user_id || group_id!=item.group_id ) { - log << log3 << "Content: can't change the user" << logend; - return; - } - - if( !request.CanChangeGroup(item, group_id) ) - { - log << log3 << "Content: can't change the group" << logend; - return; + if( !request.CanChangeUser(item, user_id) ) + { + log << log3 << "Content: can't change the user" << logend; + return false; + } + + if( !request.CanChangeGroup(item, group_id) ) + { + log << log3 << "Content: can't change the group" << logend; + return false; + } } - if( !request.CanChangePrivileges(item, privileges) ) + item.user_id = user_id; + item.group_id = group_id; + +return true; +} + + + +bool Content::ChangePrivileges(Item & item, int privileges) +{ + if( privileges != item.privileges ) { - log << log3 << "Content: can't change privileges" << logend; - return; + if( !request.CanChangePrivileges(item, privileges) ) + { + log << log3 << "Content: can't change privileges" << logend; + return false; + } } - item.user_id = user_id; - item.group_id = group_id; item.privileges = privileges; +return true; +} + + + +void Content::ChangePriv(Item & item, long user_id, long group_id, int privileges) +{ + if( change_owner ) + { + if( !ChangeOwner(item, user_id, group_id) ) + return; + } + + if( change_priv ) + { + if( !ChangePrivileges(item, privileges) ) + return; + } + request.session->done_status = db.EditPrivById(item, item.id); } -void Content::PrivLog(const char * what, const std::string & url, long user, long group, int priv) + +void Content::PrivLogStart(const char * what, long user, long group, int priv) { - log << log3 << "Content: " - << what << url - << ", user: " << user - << ", group: " << group - << ", priv: " << priv - << logend; + log << log2 << what; + + if( change_owner ) + { + User * puser = data.users.GetUser(user); + Group * pgroup = data.groups.GetGroup(group); + + log << "new user: "; + + if( puser ) + log << puser->name; + else + log << "id: " << user; + + log << ", new group: "; + + if( pgroup ) + log << pgroup->name; + else + log << "id: " << group; + + if( change_priv ) + log << ", "; + } + + if( change_priv ) + { + char buf[30]; + sprintf(buf, "0%o", priv); + log << "privileges: " << buf; + } + + log << logend; } +void Content::PrivLog(const char * what, long id, const std::string & url) +{ +Item * root = 0; + + if( id != -1 ) + root = data.dirs.GetRootDir(); + + log << log3 << "Content: " << what; + + if( root && root->id == id ) + log << "(root)"; + else + log << url; + + log << logend; +} + + void Content::PrivFilesInDir(long parent_id) { - request.item_table.clear(); db.GetItems(request.item_table, parent_id, Item::file, false, false, true); std::vector::iterator i = request.item_table.begin(); for( ; i != request.item_table.end() ; ++i) { - PrivLog("changed file: ", i->url, user_id_file, group_id_file, priv_file); - FunPriv(*i, user_id_file, group_id_file, priv_file); + PrivLog("changed file: ", -1, i->url); + ChangePriv(*i, user_id_file, group_id_file, priv_file); } } @@ -101,9 +179,11 @@ void Content::PrivDir(long parent_id) for( ; i != data.dirs.ParentEnd() ; i = data.dirs.NextParent(i) ) { - PrivLog("changed dir: ", i->second->url, user_id_dir, group_id_dir, priv_dir); - FunPriv(*(i->second), user_id_dir, group_id_dir, priv_dir); - PrivDir(i->second->id); + PrivLog("changed dir: ", -1, i->second->url); + ChangePriv(*(i->second), user_id_dir, group_id_dir, priv_dir); + + if( subdirectories ) + PrivDir(i->second->id); } } @@ -115,15 +195,26 @@ bool Content::ReadPriv(const char * user_in, const char * group_in, const char * std::string * group_str = request.PostVar(group_in); std::string * priv_str = request.PostVar(priv_in); - if( !user_str || !group_str || !priv_str ) + if( change_owner && (!user_str || !group_str) ) { - log << log1 << "Content: PostFunPriv: there is no some post variables" << logend; + log << log1 << "Content: PostFunPriv: there is no some post variables for changing the owner" << logend; return false; } - user_id = data.users.GetUserId( *user_str ); - group_id = data.groups.GetGroupId( *group_str ); - priv = strtol( priv_str->c_str() , 0, 8); + if( change_priv && !priv_str ) + { + log << log1 << "Content: PostFunPriv: there is no some post variables for changing privileges" << logend; + return false; + } + + if( change_owner ) + { + user_id = data.users.GetUserId( *user_str ); + group_id = data.groups.GetGroupId( *group_str ); + } + + if( change_priv ) + priv = strtol( priv_str->c_str() , 0, 8); return true; } @@ -137,13 +228,21 @@ void Content::PrivDir() if( !ReadPriv("userdir", "groupdir", "privilegesdir", user_id_dir, group_id_dir, priv_dir) ) return; + PrivLogStart("Content: changes for files: ", user_id_file, group_id_file, priv_file); + PrivLogStart("Content: changes for dirs: ", user_id_dir, group_id_dir, priv_dir); + + if( request.IsPostVar("changecurrentdir") ) { - PrivLog("changed dir: ", request.dir_table.back()->url, user_id_dir, group_id_dir, priv_dir); - FunPriv(*request.dir_table.back(), user_id_dir, group_id_dir, priv_dir); + Item & last_dir = *request.dir_table.back(); + PrivLog("changed dir: ", last_dir.id, last_dir.url); + ChangePriv(*request.dir_table.back(), user_id_dir, group_id_dir, priv_dir); } - // go through all directories (recurrence) + + subdirectories = request.IsPostVar("changesubdirs"); + + // go through all directories PrivDir(request.dir_table.back()->id); RedirectToLastDir(); @@ -157,14 +256,16 @@ void Content::PrivOneItem() if( !ReadPriv("user", "group", "privileges", user_id_file, group_id_file, priv_file) ) return; + PrivLogStart("Content: changes: ", user_id_file, group_id_file, priv_file); + if( request.is_item ) { - FunPriv(request.item, user_id_file, group_id_file, priv_file); + ChangePriv(request.item, user_id_file, group_id_file, priv_file); RedirectTo(request.item); } else { - FunPriv(*request.dir_table.back(), user_id_file, group_id_file, priv_file); + ChangePriv(*request.dir_table.back(), user_id_file, group_id_file, priv_file); RedirectToLastDir(); } } @@ -176,6 +277,8 @@ void Content::PostFunPriv() if( !PrivCheckAccess() ) return; + change_owner = (request.pfunction->code == FUN_PRIV || request.pfunction->code == FUN_CHOWN); + change_priv = (request.pfunction->code == FUN_PRIV || request.pfunction->code == FUN_CHMOD); if( request.IsParam("r") ) { @@ -185,6 +288,8 @@ void Content::PostFunPriv() { PrivOneItem(); } + + data.dirs.CheckRootDir(); } @@ -193,3 +298,5 @@ void Content::FunPriv() { PrivCheckAccess(); } + + diff --git a/core/Makefile.dep b/core/Makefile.dep index ca47d24..8aaeab1 100755 --- a/core/Makefile.dep +++ b/core/Makefile.dep @@ -20,6 +20,9 @@ dircontainer.o: dircontainer.h item.h log.h dirs.o: dirs.h item.h dircontainer.h error.h log.h db.h user.h group.h dirs.o: thread.h ugcontainer.h ticket.h data.h users.h groups.h functions.h dirs.o: function.h lastcontainer.h mounts.h mount.h rebus.h loadavg.h +dirs.o: request.h requesttypes.h session.h done.h compress.h +dirs.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h +dirs.o: postmultiparser.h done.o: done.h error.o: error.h log.h function.o: function.h item.h diff --git a/core/dirs.cpp b/core/dirs.cpp index 1488ba4..8b508eb 100755 --- a/core/dirs.cpp +++ b/core/dirs.cpp @@ -12,6 +12,7 @@ #include "log.h" #include "db.h" #include "data.h" +#include "request.h" void Dirs::Clear() @@ -26,7 +27,17 @@ void Dirs::CheckRootDir() DirContainer::Iterator i = dir_table.GetRoot(); if( i != dir_table.End() ) + { + if( !request.HasReadExecAccessForRoot(*i) ) + { + i->privileges = 0755; + log << log1 << "Dirs: there is no access for root (admin) to the root dir, setting 0755 for root dir" << logend; + db.EditPrivById(*i, i->id); + } + return; + } + log << log1 << "Dirs: there is no a root dir in the database (creating one)" << logend; @@ -272,7 +283,8 @@ void Dirs::SplitPath(const std::string & path, std::string & dir, std::string & - +// !! przeniesc to do rm +// mamy juz interfejs do chodzenia po parentach void Dirs::DeleteDir(long id) { DirContainer::ParentIterator pnext, p = dir_table.FindFirstParent(id); diff --git a/core/function.h b/core/function.h index 7aacc0b..b5f4c9e 100755 --- a/core/function.h +++ b/core/function.h @@ -38,8 +38,8 @@ #define FUN_UPTIME 21 //#define FUN_MV 23 //#define FUN_UNAME 24 -//#define FUN_CHMOD 25 -//#define FUN_CHOWN 26 +#define FUN_CHMOD 25 +#define FUN_CHOWN 26 #define FUN_CKEDITOR 27 diff --git a/core/functions.cpp b/core/functions.cpp index 5009fa4..f768e67 100755 --- a/core/functions.cpp +++ b/core/functions.cpp @@ -124,6 +124,7 @@ void Functions::ReadFunctions() f.code = FUN_UNAME; f.item.url = "uname"; table.insert( std::make_pair(f.item.url, f) ); + */ f.code = FUN_CHMOD; f.item.url = "chmod"; @@ -132,7 +133,7 @@ void Functions::ReadFunctions() f.code = FUN_CHOWN; f.item.url = "chown"; table.insert( std::make_pair(f.item.url, f) ); - */ + f.code = FUN_CKEDITOR; f.item.url = "ckeditor"; diff --git a/core/request.cpp b/core/request.cpp index aa42d1d..b5a53e4 100755 --- a/core/request.cpp +++ b/core/request.cpp @@ -676,6 +676,14 @@ bool Request::HasReadExecAccess(const Item & item) } +bool Request::HasReadExecAccessForRoot(const Item & item) +{ + // there must be at least one 'x' (for the root) + + return (item.privileges & 0111) != 0; +} + + // returning true if we can create a thread in the current directory bool Request::CanCreateThread(bool check_root) { diff --git a/core/request.h b/core/request.h index a7baab4..d363af2 100755 --- a/core/request.h +++ b/core/request.h @@ -150,6 +150,7 @@ struct Request bool HasWriteAccess(const Item & item); bool HasReadWriteAccess(const Item & item); bool HasReadExecAccess(const Item & item); + bool HasReadExecAccessForRoot(const Item & item); bool CanCreateThread(bool check_root = false); bool CanCreateTicket(bool check_root = false); diff --git a/html/fun_priv.html b/html/fun_priv.html index 08df4a2..5e0d484 100755 --- a/html/fun_priv.html +++ b/html/fun_priv.html @@ -1,3 +1,6 @@ +[# this template is for following functions: priv, chmod, chown] + +

{priv_header}

@@ -8,11 +11,14 @@ [is-no winix_function_param_is "r"] -
+
{priv_form_legend} + + [if-one priv_show_form_chown] + + [end] + + [if-one priv_show_form_chmod] + [end] +
{user}:
{permissions}:
@@ -38,13 +49,15 @@ [else] - +
{priv_form_legend}

{priv_change_in_dir}: [dir]

{priv_for_all_files}:

+ + [if-one priv_show_form_chown] - + [end] + + [if-one priv_show_form_chmod] + [end] +
{user}:
{permissions}:

{priv_for_all_dirs}:

+ + [if-one priv_show_form_chown] - + [end] + + [if-one priv_show_form_chmod] + [end] + +
{user}:
{permissions}:
- + +
diff --git a/locale/en b/locale/en index 30eedb7..e01dbf9 100755 --- a/locale/en +++ b/locale/en @@ -117,9 +117,9 @@ priv_form_legend = Permissions priv_change_in_dir = Change permissions for all items in the following directory priv_for_all_files = For all files to priv_for_all_dirs = For all directories to +priv_change_all = Change subdirectories as well priv_change_current_dir = Change also the current directory - reload_header = Reload reload_was_error = We are sorry but there were errors while reloading. templates_reloaded_successfully = Templates reloaded successfully. diff --git a/locale/pl b/locale/pl index af82148..790c909 100755 --- a/locale/pl +++ b/locale/pl @@ -16,7 +16,7 @@ home_page = Strona g button_login = Loguj load_avg = średnie obciążenie -req_per_sec = Wywołań na sekundę +req_per_sec = wywołań na sekundę added_by = Dodane przez last_modified = ostatnio modyfikowany @@ -116,8 +116,10 @@ priv_form_legend = Uprawnienia priv_change_in_dir = Zmień hurtowo uprawnienia w katalogu priv_for_all_files = Dla wszystkich plików na priv_for_all_dirs = Dla wszystkich katalogów na +priv_change_all = Zmień także w podkatalogach priv_change_current_dir = Zmień także sam katalog bieżący + reload_header = Przeładuj reload_was_error = Przykro nam ale wystąpiły błędy podczas ponownego wczytywania. templates_reloaded_successfully = Szablony zostały pomyślnie wczytane. diff --git a/static/layout1/winix.css b/static/layout1/winix.css index b35e4c0..1f8a6a4 100755 --- a/static/layout1/winix.css +++ b/static/layout1/winix.css @@ -420,6 +420,16 @@ display: block; width: 530px; } +#additem .check { +vertical-align: middle; +} + +#additem label { +vertical-align: middle; +margin: 0.3em 0 0.3em 0; +padding: 0.2em; +display: block; +} #additem select { border: 1px solid #dedede; diff --git a/templates/priv.cpp b/templates/priv.cpp index 76ed1e2..a8e3b94 100755 --- a/templates/priv.cpp +++ b/templates/priv.cpp @@ -266,6 +266,19 @@ void priv_privileges_for_dirs(Info & i) } +void priv_show_form_chown(Info & i) +{ + i.result = (request.pfunction->code == FUN_PRIV || request.pfunction->code == FUN_CHOWN); +} + + +void priv_show_form_chmod(Info & i) +{ + i.result = (request.pfunction->code == FUN_PRIV || request.pfunction->code == FUN_CHMOD); +} + + + } // namespace TemplatesFunctions diff --git a/templates/templates.cpp b/templates/templates.cpp index cc9c1dd..173b270 100755 --- a/templates/templates.cpp +++ b/templates/templates.cpp @@ -50,6 +50,8 @@ Ezc::Pattern * p = 0; {FUN_MKDIR, pat_fun_mkdir}, {FUN_DEFAULT, pat_fun_default}, {FUN_PRIV, pat_fun_priv}, + {FUN_CHMOD, pat_fun_priv}, + {FUN_CHOWN, pat_fun_priv}, {FUN_RUN, pat_fun_run}, {FUN_WHO, pat_fun_who}, {FUN_LAST, pat_fun_last}, @@ -309,7 +311,10 @@ void Templates::CreateFunctions() functions.Insert("priv_privileges", priv_privileges); functions.Insert("priv_privileges_for_files", priv_privileges_for_files); functions.Insert("priv_privileges_for_dirs", priv_privileges_for_dirs); - + functions.Insert("priv_show_form_chown", priv_show_form_chown); + functions.Insert("priv_show_form_chmod", priv_show_form_chmod); + + /* done @@ -457,6 +462,7 @@ void Templates::CreateFunctions() */ functions.Insert("winix_cur_time", winix_cur_time); functions.Insert("winix_users_logged", winix_users_logged); + functions.Insert("winix_function", winix_function); functions.Insert("winix_function_is", winix_function_is); functions.Insert("winix_function_param_is", winix_function_param_is); functions.Insert("winix_loadavg_now", winix_loadavg_now); diff --git a/templates/templates.h b/templates/templates.h index ea1f8d2..c29e4f0 100755 --- a/templates/templates.h +++ b/templates/templates.h @@ -207,6 +207,7 @@ namespace TemplatesFunctions void user_can_use_bbcode(Info & i); void user_can_use_raw(Info & i); + /* privileges */ @@ -222,6 +223,9 @@ namespace TemplatesFunctions void priv_privileges_for_files(Info & i); void priv_privileges_for_dirs(Info & i); + void priv_show_form_chown(Info & i); + void priv_show_form_chmod(Info & i); + /* done @@ -365,6 +369,7 @@ namespace TemplatesFunctions */ void winix_cur_time(Info & i); void winix_users_logged(Info & i); + void winix_function(Info & i); void winix_function_is(Info & i); void winix_function_param_is(Info & i); void winix_loadavg_now(Info & i); diff --git a/templates/winix.cpp b/templates/winix.cpp index d24ac80..33f063b 100755 --- a/templates/winix.cpp +++ b/templates/winix.cpp @@ -37,6 +37,11 @@ void winix_users_logged(Info & i) } +void winix_function(Info & i) +{ + i.out << request.pfunction->item.url; +} + void winix_function_is(Info & i) {