diff --git a/src/ws.cpp b/src/ws.cpp index 54c2b9d..dcd5b8a 100644 --- a/src/ws.cpp +++ b/src/ws.cpp @@ -727,32 +727,6 @@ string Workspace::getfilesystem() } -/* - * get list of restorable workspaces, as names - */ -vector Workspace::getRestorable(string username) -{ - string dbprefix = config["workspaces"][filesystem]["database"].as() + "/" + - config["workspaces"][filesystem]["deleted"].as(); - - vector namelist; - - fs::directory_iterator end; - for (fs::directory_iterator it(dbprefix); it!=end; ++it) { -#if BOOST_VERSION < 105000 - if (boost::starts_with(it->path().filename(), username + "-" )) { - namelist.push_back(it->path().filename()); - } -#else - if (boost::starts_with(it->path().filename().string(), username + "-" )) { - namelist.push_back(it->path().filename().string()); - } -#endif - } - - return namelist; -} - /* * restore a workspace, argument is name of workspace DB entry including username and timestamp, form user-name-timestamp */ diff --git a/src/ws.h b/src/ws.h index 8d8b32b..f042f3b 100644 --- a/src/ws.h +++ b/src/ws.h @@ -79,6 +79,7 @@ class Workspace { int mv(const char * source, const char *target); + std::vector get_valid_fslist(); public: diff --git a/src/ws_restore.cpp b/src/ws_restore.cpp index 337925f..42ee157 100644 --- a/src/ws_restore.cpp +++ b/src/ws_restore.cpp @@ -159,6 +159,123 @@ bool check_name(const string name, const string username, const string real_user } } +// get list of valid filesystems for current user +std::vector get_valid_fslist() { + vector fslist; + + YAML::Node config; + // read config + try { + config = YAML::LoadFile("/etc/ws.conf"); + } catch (YAML::BadFile) { + cerr << "Error: no config file!" << endl; + exit(-1); + } + + // get user name, group names etc + vector groupnames; + + string username = Workspace::getusername(); // FIXME is this correct? what if username given on commandline? + + struct group *grp; + int ngroups = 128; + gid_t gids[128]; + int nrgroups; + string primarygroup; + + nrgroups = getgrouplist(username.c_str(), geteuid(), gids, &ngroups); + if(nrgroups<=0) { + cerr << "Error: user in too many groups!" << endl; + } + for(int i=0; igr_name)); + } + // get current group + grp=getgrgid(getegid()); + if(grp==NULL) { + cerr << "Error: user has no group anymore!" << endl; + } + primarygroup=string(grp->gr_name); + + // iterate over all filesystems and search the ones allowed for current user + YAML::Node node = config["workspaces"]; + for(YAML::const_iterator it = node.begin(); it!=node.end(); ++it ) { + std::string cfilesystem = it->first.as(); + // check ACLs + vectoruser_acl; + vectorgroup_acl; + + // read ACL lists + if ( config["workspaces"][cfilesystem]["user_acl"]) { + BOOST_FOREACH(string v, + config["workspaces"][cfilesystem]["user_acl"].as >()) + user_acl.push_back(v); + } + if ( config["workspaces"][cfilesystem]["group_acl"]) { + BOOST_FOREACH(string v, + config["workspaces"][cfilesystem]["group_acl"].as >()) + group_acl.push_back(v); + } + + // check ACLs + bool userok=true; + if(user_acl.size()>0 || group_acl.size()>0) userok=false; + + if( find(group_acl.begin(), group_acl.end(), primarygroup) != group_acl.end() ) { + userok=true; + } +#ifdef CHECK_ALL_GROUPS + BOOST_FOREACH(string grp, groupnames) { + if( find(group_acl.begin(), group_acl.end(), grp) != group_acl.end() ) { + userok=true; + break; + } + } +#endif + if( find(user_acl.begin(), user_acl.end(), username) != user_acl.end() ) { + userok=true; + } + if(userok || getuid()==0) { + fslist.push_back(cfilesystem); + } + } + return fslist; +} + +// get restorable workspaces as names +vector getRestorable(string filesystem, string username) +{ + YAML::Node config; + // read config + try { + config = YAML::LoadFile("/etc/ws.conf"); + } catch (YAML::BadFile) { + cerr << "Error: no config file!" << endl; + exit(-1); + } + + string dbprefix = config["workspaces"][filesystem]["database"].as() + "/" + + config["workspaces"][filesystem]["deleted"].as(); + + vector namelist; + + fs::directory_iterator end; + for (fs::directory_iterator it(dbprefix); it!=end; ++it) { +#if BOOST_VERSION < 105000 + if (boost::starts_with(it->path().filename(), username + "-" )) { + namelist.push_back(it->path().filename()); + } +#else + if (boost::starts_with(it->path().filename().string(), username + "-" )) { + namelist.push_back(it->path().filename().string()); + } +#endif + } + + return namelist; +} + int main(int argc, char **argv) { po::variables_map opt; string name, target, filesystem, acctcode, username; @@ -175,34 +292,51 @@ int main(int argc, char **argv) { // check commandline, get flags which are used to create ws object or for workspace allocation commandline(opt, name, target, filesystem, listflag, terse, username, argc, argv); - // get workspace object - Workspace ws(WS_Release, opt, duration, filesystem); - - // construct db-entry username name - string real_username = ws.getusername(); - if (username == "") { - username = real_username; - } else if (real_username != username) { - if (real_username != "root") { - cerr << "Error: only root can do that. 2" << endl; - username = real_username; - exit(-1); - } - } - openlog("ws_restore", 0, LOG_USER); // SYSLOG if (listflag) { - BOOST_FOREACH(string dn, ws.getRestorable(username)) { - cout << dn << endl; - if (!terse) { - std::vector splitted; - boost::split(splitted, dn, boost::is_any_of("-")); - time_t t = atol(splitted[splitted.size()-1].c_str()); - cout << "\tunavailable since " << std::ctime(&t); + + BOOST_FOREACH(string fs, get_valid_fslist()) { + std::cout << fs << ":" << std::endl; + + // construct db-entry username name + string real_username = Workspace::getusername(); + if (username == "") { + username = real_username; + } else if (real_username != username) { + if (real_username != "root") { + cerr << "Error: only root can do that. 2" << endl; + username = real_username; + exit(-1); + } + } + BOOST_FOREACH(string dn, getRestorable(fs, username)) { + cout << dn << endl; + if (!terse) { + std::vector splitted; + boost::split(splitted, dn, boost::is_any_of("-")); + time_t t = atol(splitted[splitted.size()-1].c_str()); + cout << "\tunavailable since " << std::ctime(&t); + } } + } + } else { + // get workspace object + Workspace ws(WS_Release, opt, duration, filesystem); + + // construct db-entry username name + string real_username = ws.getusername(); + if (username == "") { + username = real_username; + } else if (real_username != username) { + if (real_username != "root") { + cerr << "Error: only root can do that. 2" << endl; + username = real_username; + exit(-1); + } + } if (check_name(name, username, real_username)) { if (ruh()) { ws.restore(name, target, username);