]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Client gets cap back and begins passing to OSD
authoranwleung <anwleung@29311d96-e01e-0410-9327-a35deaab8ce9>
Sat, 17 Feb 2007 06:22:05 +0000 (06:22 +0000)
committeranwleung <anwleung@29311d96-e01e-0410-9327-a35deaab8ce9>
Sat, 17 Feb 2007 06:22:05 +0000 (06:22 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1100 29311d96-e01e-0410-9327-a35deaab8ce9

branches/aleung/security1/ceph/client/Client.cc
branches/aleung/security1/ceph/client/Client.h
branches/aleung/security1/ceph/client/FileCache.h
branches/aleung/security1/ceph/mds/CInode.h
branches/aleung/security1/ceph/mds/Locker.cc
branches/aleung/security1/ceph/mds/Locker.h
branches/aleung/security1/ceph/mds/MDS.cc
branches/aleung/security1/ceph/mds/MDS.h
branches/aleung/security1/ceph/mds/Server.cc
branches/aleung/security1/ceph/messages/MClientReply.h
branches/aleung/security1/ceph/messages/MClientRequest.h

index baf2dad0216cd76cb372a026fb13d1714c3400b2..947316200ea2c27d18332a060ff050f984fee05d 100644 (file)
@@ -1247,8 +1247,17 @@ int Client::link(const char *existing, const char *newname,
   tout << "link" << endl;
   tout << existing << endl;
   tout << newname << endl;
+
+  // fix uid/gid if not supplied
+  // get it from the system
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
   
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
+  // This is for FUSE support of passing the userid
   //Ticket *tk;
   //if (uid == -1 || gid == -1)
   //  tk = get_user_ticket(getuid(), getgid());
@@ -1270,8 +1279,8 @@ int Client::link(const char *existing, const char *newname,
   req->set_sarg(existing);
   
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
   
   MClientReply *reply = make_request(req, true);
   int res = reply->get_result();
@@ -1291,7 +1300,15 @@ int Client::unlink(const char *relpath, __int64_t uid, __int64_t gid)
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                                
+  // get it from the system                                                     
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
 
   if (!tk) {
     client_lock.Unlock();
@@ -1311,8 +1328,8 @@ int Client::unlink(const char *relpath, __int64_t uid, __int64_t gid)
   req->set_path(path);
  
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
 
   //FIXME enforce caller uid rights?
    
@@ -1342,7 +1359,16 @@ int Client::rename(const char *relfrom, const char *relto,
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                              
+  // get it from the system                                               
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1366,8 +1392,8 @@ int Client::rename(const char *relfrom, const char *relto,
   req->set_sarg(to);
  
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
 
   //FIXME enforce caller uid rights?
    
@@ -1389,7 +1415,15 @@ int Client::mkdir(const char *relpath, mode_t mode, __int64_t uid, __int64_t gid
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied
+  // get it from the system
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1410,8 +1444,8 @@ int Client::mkdir(const char *relpath, mode_t mode, __int64_t uid, __int64_t gid
   req->set_iarg( (int)mode );
  
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
 
   //FIXME enforce caller uid rights?
    
@@ -1431,7 +1465,16 @@ int Client::rmdir(const char *relpath, __int64_t uid, __int64_t gid)
 {
   client_lock.Lock();
   
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1450,8 +1493,8 @@ int Client::rmdir(const char *relpath, __int64_t uid, __int64_t gid)
   req->set_path(path);
  
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
 
   //FIXME enforce caller uid rights?
    
@@ -1484,7 +1527,15 @@ int Client::symlink(const char *reltarget, const char *rellink,
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1508,8 +1559,8 @@ int Client::symlink(const char *reltarget, const char *rellink,
   req->set_sarg(target);
  
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
 
   //FIXME enforce caller uid rights?
    
@@ -1530,7 +1581,15 @@ int Client::readlink(const char *relpath, char *buf, off_t size,
 { 
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1580,6 +1639,16 @@ int Client::_lstat(const char *path, int mask, Inode **in,
   // check whether cache content is fresh enough
   int res = 0;
 
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+  // the ticket should be used since it must look at
+  // execute permissions in path
+  //Ticket *tk = get_user_ticket(uid, gid);
+
   Dentry *dn = lookup(fpath);
   inode_t inode;
   time_t now = time(NULL);
@@ -1676,7 +1745,15 @@ int Client::lstat(const char *relpath, struct stat *stbuf,
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1711,7 +1788,15 @@ int Client::lstatlite(const char *relpath, struct statlite *stl,
 {
   client_lock.Lock();
    
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1753,7 +1838,15 @@ int Client::chmod(const char *relpath, mode_t mode,
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied
+  // get it from the system
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1774,8 +1867,8 @@ int Client::chmod(const char *relpath, mode_t mode,
   req->set_iarg( (int)mode );
 
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
   
   MClientReply *reply = make_request(req, true);
   int res = reply->get_result();
@@ -1795,7 +1888,15 @@ int Client::chown(const char *relpath, __int64_t uid, __int64_t gid)
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1818,8 +1919,8 @@ int Client::chown(const char *relpath, __int64_t uid, __int64_t gid)
   req->set_iarg2( (int)gid );
 
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
 
   //FIXME enforce caller uid rights?
 
@@ -1840,7 +1941,15 @@ int Client::utime(const char *relpath, struct utimbuf *buf,
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1864,8 +1973,8 @@ int Client::utime(const char *relpath, struct utimbuf *buf,
   req->set_targ2( buf->actime );
 
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
 
   //FIXME enforce caller uid rights?
    
@@ -1889,7 +1998,15 @@ int Client::mknod(const char *relpath, mode_t mode,
 { 
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1910,8 +2027,8 @@ int Client::mknod(const char *relpath, mode_t mode,
   req->set_iarg( mode );
 
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
 
   //FIXME enforce caller uid rights?
    
@@ -1939,11 +2056,20 @@ int Client::mknod(const char *relpath, mode_t mode,
 
 // fyi: typedef int (*dirfillerfunc_t) (void *handle, const char *name, int type, inodeno_t ino);
 
-int Client::getdir(const char *relpath, map<string,inode_t>& contents) 
+int Client::getdir(const char *relpath, map<string,inode_t>& contents,
+                  __int64_t uid, __int64_t gid) 
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -1962,8 +2088,8 @@ int Client::getdir(const char *relpath, map<string,inode_t>& contents)
   req->set_path(path); 
 
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
 
   //FIXME enforce caller uid rights?
    
@@ -2051,6 +2177,7 @@ int Client::closedir(DIR *dir, __int64_t uid, __int64_t gid)
 
 struct dirent *Client::readdir(DIR *dirp, __int64_t uid, __int64_t gid)
 {
+  
   DirResult *d = (DirResult*)dirp;
 
   // end of dir?
@@ -2218,7 +2345,14 @@ int Client::open(const char *relpath, int flags, __int64_t uid, __int64_t gid)
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                   
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
 
   if (!tk) {
     client_lock.Unlock();
@@ -2256,9 +2390,18 @@ int Client::open(const char *relpath, int flags, __int64_t uid, __int64_t gid)
   req->set_iarg(flags);
   req->set_iarg2(cmode);
 
+  // don't need a cap if I have one cached
+  ExtCap *ext_cap;
+  //ExtCap *ext_cap = fc->get_ext_caps(uid);
+  // !!FIX ME!! Set flag to not ask for cap if I have one already
+  if (!ext_cap)
+    cout << "No capability cached at client for file " << path << endl;
+  else
+    cout << "Cached capability found! for file " << path << endl;
+
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
   
   MClientReply *reply = make_request(req, tryauth); // try auth if writer
   
@@ -2295,6 +2438,12 @@ int Client::open(const char *relpath, int flags, __int64_t uid, __int64_t gid)
 
     int new_caps = reply->get_file_caps();
 
+    // need security caps? check if I even asked for one
+    ext_cap = reply->get_ext_cap();
+
+    // cache it
+    f->inode->set_ext_cap(uid, ext_cap);
+    
     assert(reply->get_file_caps_seq() >= f->inode->caps[mds].seq);
     if (reply->get_file_caps_seq() > f->inode->caps[mds].seq) {   
       dout(7) << "open got caps " << cap_string(new_caps)
@@ -2369,7 +2518,15 @@ int Client::close(fh_t fh, __int64_t uid, __int64_t gid)
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                            
+  // get it from the system                                                
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -2451,7 +2608,15 @@ int Client::read(fh_t fh, char *buf, off_t size, off_t offset,
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -2581,7 +2746,15 @@ int Client::write(fh_t fh, const char *buf, off_t size, off_t offset,
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                             
+  // get it from the system                                               
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -2707,7 +2880,15 @@ int Client::truncate(const char *file, off_t size, __int64_t uid, __int64_t gid)
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -2724,8 +2905,8 @@ int Client::truncate(const char *file, off_t size, __int64_t uid, __int64_t gid)
   req->set_sizearg( size );
 
   // FIXME where does FUSE maintain user information
-  req->set_caller_uid(getuid());
-  req->set_caller_gid(getgid());
+  req->set_caller_uid(uid);
+  req->set_caller_gid(gid);
   
   MClientReply *reply = make_request(req, true);
   int res = reply->get_result();
@@ -2744,7 +2925,15 @@ int Client::fsync(fh_t fh, bool syncdataonly, __int64_t uid, __int64_t gid)
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -2828,7 +3017,15 @@ int Client::lazyio_propogate(int fd, off_t offset, size_t count,
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
@@ -2873,7 +3070,15 @@ int Client::lazyio_synchronize(int fd, off_t offset, size_t count,
 {
   client_lock.Lock();
 
-  Ticket *tk = get_user_ticket(getuid(), getgid());
+  // fix uid/gid if not supplied                                               
+  // get it from the system                                                    
+  if (uid == -1 || gid == -1) {
+    uid = getuid();
+    gid = getgid();
+  }
+
+  Ticket *tk = get_user_ticket(uid, gid);
+  //Ticket *tk = get_user_ticket(getuid(), getgid());
   if (!tk) {
     client_lock.Unlock();
     return -EPERM;
index 35ca1ccb2016eb39e01999da2a294f3ebe7e8889..a454aa87175f35262c2c8b1133dbdaf24fbabb1c 100644 (file)
@@ -152,6 +152,9 @@ class Inode {
   Dentry    *dn;      // if i'm linked to a dentry.
   string    *symlink; // symlink content, if it's a symlink
 
+  // secure caps
+  map<uid_t, ExtCap*> ext_cap_cache;
+
   // for caching i/o mode
   FileCache fc;
 
@@ -193,6 +196,13 @@ class Inode {
     return (inode.mode & INODE_TYPE_MASK) == INODE_MODE_DIR;
   }
 
+  void set_ext_cap(uid_t user, ExtCap *ecap) { ext_cap_cache[user] = ecap; }
+  ExtCap* get_ext_cap(uid_t user) {
+    if (ext_cap_cache.count(user))
+      return ext_cap_cache[user]; 
+    return 0;
+  }
+
   int file_caps() {
     int c = 0;
     for (map<int,InodeCap>::iterator it = caps.begin();
@@ -560,8 +570,10 @@ protected:
   int chdir(const char *s, __int64_t uid, __int64_t gid);
 
   // namespace ops
-  int getdir(const char *path, list<string>& contents);
-  int getdir(const char *path, map<string,inode_t>& contents);
+  int getdir(const char *path, list<string>& contents,
+            __int64_t uid = -1, __int64_t gid = -1);
+  int getdir(const char *path, map<string,inode_t>& contents,
+            __int64_t uid = -1, __int64_t gid = -1);
 
   DIR *opendir(const char *name, __int64_t uid = -1, __int64_t gid = -1);
   int closedir(DIR *dir, __int64_t uid = -1, __int64_t gid = -1);
index 742ec98733d9b5ae8e15b6861c565d8a8d89e10d..06644d65d43599b9807349b57aa8982a10e16632 100644 (file)
@@ -7,6 +7,8 @@ using namespace std;
 #include "common/Cond.h"
 #include "mds/Capability.h"
 
+#include "crypto/ExtCap.h"
+
 class ObjectCacher;
 
 class FileCache {
@@ -55,7 +57,7 @@ class FileCache {
   int get_caps() { return latest_caps; }
   void set_caps(int caps, Context *onimplement=0);
   void check_caps();
-  
+
   int read(off_t offset, size_t size, bufferlist& blist, Mutex& client_lock);  // may block.
   void write(off_t offset, size_t size, bufferlist& blist, Mutex& client_lock);  // may block.
 
index 3d754ad9c4fbce4821b3b0861dae6cb929165224..50924e91b21c95bfca3d028c57179a90ba4009cd 100644 (file)
@@ -34,7 +34,9 @@
 #include <iostream>
 using namespace std;
 
-
+#include "crypto/CryptoLib.h"
+using namespace std;
+#include "crypto/ExtCap.h"
 
 
 
@@ -211,6 +213,14 @@ class CInode : public LRUObject {
   // file capabilities
   map<int, Capability>  client_caps;         // client -> caps
 
+  
+  // secure capabilities
+  // will be dependant based on MDS collection policy!
+  map<uid_t, ExtCap>  ext_caps;
+  //ExtCap *user_cap;
+  //ExtCap *group_cap;
+  //ExtCap *world_cap;
+
   map<int, int>         mds_caps_wanted;     // [auth] mds -> caps wanted
   int                   replica_caps_wanted; // [replica] what i've requested from auth
   utime_t               replica_caps_wanted_keep_until;
@@ -255,6 +265,8 @@ class CInode : public LRUObject {
   int get_replica_nonce() { assert(!is_auth()); return replica_nonce; }
 
   inodeno_t ino() { return inode.ino; }
+  uid_t get_uid() { return inode.uid; }
+  gid_t get_gid() { return inode.gid; }
   inode_t& get_inode() { return inode; }
   CDentry* get_parent_dn() { return parent; }
   CDir *get_parent_dir();
@@ -458,6 +470,27 @@ class CInode : public LRUObject {
     return w;
   }
 
+  // secure extended caps
+  //map<int,ExtCap*>& get_client_extcaps() { return ext_caps; }
+
+  void add_user_extcap(uid_t user, ExtCap extcap) {
+    //if (ext_caps.empty())
+    //  get(CINODE_PIN_CAPS);
+    assert(ext_caps.count(user) == 0);
+    ext_caps[user] = extcap;
+  }
+  void remove_user_extcap(uid_t user) {
+    assert(ext_caps.count(user) == 1);
+    ext_caps.erase(user);
+    //if (client_caps.empty())
+    //  put(CINODE_PIN_CAPS);
+  }
+  ExtCap* get_user_extcap(uid_t user) {
+    if (ext_caps.count(user))
+      return &(ext_caps[user]);
+    return 0;
+  }
+
 
   void replicate_relax_locks() {
     assert(is_auth());
index 08c1900eec9f268a5888ecf8bbd9f060e12c6ea7..6517a26d8b00e820bfda8db411a4e27260b7014c 100644 (file)
@@ -111,28 +111,40 @@ Capability* Locker::issue_new_caps(CInode *in,
   if (mode & FILE_MODE_W) my_want |= CAP_FILE_WRBUFFER | CAP_FILE_WR;
 
   // register a capability
+  // checks capabilities for the file indexed by client id
+  // returns 0 if there is no cached capability
   Capability *cap = in->get_client_cap(my_client);
   if (!cap) {
     // new cap
+    // makes a cap which only contains the desired mode (my_want)
     Capability c(my_want);
+    // caches this capability in the inode
     in->add_client_cap(my_client, c);
+    // pull the cap back out, why? you have a pointer to it already
+    // ah, because this is the variable used later
     cap = in->get_client_cap(my_client);
     
     // note client addr
+    // increase reference count on this clientid
     mds->clientmap.add_open(my_client, req->get_client_inst());
     
   } else {
     // make sure it has sufficient caps
+    // if the mode cached is not the mode were looking for
     if (cap->wanted() & ~my_want) {
       // augment wanted caps for this client
+      // just changed  the cached capability to the mode we want
       cap->set_wanted( cap->wanted() | my_want );
     }
   }
 
   // suppress file cap messages for this guy for a few moments (we'll bundle with the open() reply)
+  // is this so that issue_caps() does actually send caps to the client?
   cap->set_suppress(true);
+  // checks the mode the client asked for previously
   int before = cap->pending();
 
+  // if this MDS is the authority for the inode
   if (in->is_auth()) {
     // [auth] twiddle mode?
     inode_file_eval(in);
@@ -145,11 +157,13 @@ Capability* Locker::issue_new_caps(CInode *in,
   issue_caps(in);  // note: _eval above may have done this already...
 
   // re-issue whatever we can
+  // this doesn't actually seem to do anything
   cap->issue(cap->pending());
   
   // ok, stop suppressing.
   cap->set_suppress(false);
 
+  // the mode of the most recently sent, should be the desired mode?
   int now = cap->pending();
   if (before != now &&
       (before & CAP_FILE_WR) == 0 &&
@@ -167,7 +181,46 @@ Capability* Locker::issue_new_caps(CInode *in,
   return cap;
 }
 
+/**********
+ * This function returns a new extended capability
+ * for the user for file
+ * This function does nothing for synchronization
+ **********/
+ExtCap* Locker::issue_new_extcaps(CInode *in, int mode, MClientRequest *req) {
+  dout(3) << "issue_new_EXTcaps for mode " << mode << " on " << *in << endl;
 
+  // get the uid
+  int my_client = req->get_client();
+  uid_t my_user = req->get_caller_uid();
+  int my_want = 0;
+  // only care about reading a writing, no sync
+  if (mode & FILE_MODE_R) my_want |= CAP_FILE_RD;
+  if (mode & FILE_MODE_W) my_want |= CAP_FILE_WR;
+
+  // checks capabilities for the file indexed by client id
+  // returns 0 if there is no cached capability
+  ExtCap *ext_cap = in->get_user_extcap(my_user);
+  if (!ext_cap) {
+    // need to create new cap
+    ExtCap my_cap(my_want, my_user, in->ino());
+    
+    // caches this capability in the inode
+    in->add_user_extcap(my_user, my_cap);
+
+    //ext_cap = (&my_cap);
+    ext_cap = in->get_user_extcap(my_user);
+    
+  }
+  // we want to index based on mode, so we can cache more caps
+  // does the cached cap have the write mode?
+  else {
+    // augment the capability if not right mode
+    if (ext_cap->mode() != mode)
+      ext_cap->set_mode(mode);
+      
+  }
+  return ext_cap;  
+}
 
 bool Locker::issue_caps(CInode *in)
 {
index 20b5a178966100cee7ba8a48cdfafc66afa4d1c0..a7f5d380538aabb22bb503403715f13eab6fdf09 100644 (file)
@@ -91,6 +91,9 @@ private:
  public:
   version_t issue_file_data_version(CInode *in);
   Capability* issue_new_caps(CInode *in, int mode, MClientRequest *req);
+  // returns a secured extended capability for the user
+  ExtCap* issue_new_extcaps(CInode *in, int mode, MClientRequest *req);
+  // sign the extcap
   bool issue_caps(CInode *in);
 
  protected:
index 48f38150cf41dc3084d467a732e7ed86f39fa260..1649bc3642f2b910699f2b823aee7b0b21548cfe 100644 (file)
@@ -91,6 +91,10 @@ MDS::MDS(int whoami, Messenger *m, MonMap *mm) {
   server = new Server(this);
   locker = new Locker(this, mdcache);
 
+  // init keys
+  myPrivKey = esignPrivKey("crypto/esig1536.dat");
+  myPubKey = esignPubKey(myPrivKey);
+
 
   req_rate = 0;
 
@@ -199,6 +203,8 @@ void MDS::send_message_mds(Message *m, int mds, int port, int fromport)
 
 int MDS::init()
 {
+  // generate my key pair
+  
   // request osd map
   dout(5) << "requesting mds and osd maps from mon" << endl;
   int mon = monmap->pick_mon();
index b67a7e58e98e7c06fde984582b11a4cae6c2bfe3..4de10ea877914946333b21123998e5698fd568f3 100644 (file)
@@ -37,6 +37,10 @@ using namespace __gnu_cxx;
 
 #include "ClientMap.h"
 
+#include "crypto/CryptoLib.h"
+using namespace CryptoLib;
+
+#include "crypto/ExtCap.h"
 
 #define MDS_PORT_MAIN     0
 #define MDS_PORT_SERVER   1
@@ -143,6 +147,10 @@ class MDS : public Dispatcher {
   int state;
   list<Context*> waitfor_active;
 
+  // mds pub/priv keys
+  esignPriv myPrivKey;
+  esignPub myPubKey;
+
 public:
   void queue_waitfor_active(Context *c) { waitfor_active.push_back(c); }
 
@@ -207,6 +215,9 @@ public:
   int shutdown_start();
   int shutdown_final();
 
+  esignPub getPubKey() { return myPubKey; }
+  esignPriv getPrvKey() { return myPrivKey; }
+
   int hash_dentry(inodeno_t ino, const string& s) {
     return 0; // fixme
   }
index d333330002c2bc04178991d5757063ccdc07658f..63eb5421518a6a7cdc3220ec1c3795955dcb0dbb 100644 (file)
@@ -292,6 +292,7 @@ void Server::handle_client_request(MClientRequest *req)
     }
   }
 
+  // file specific operations
   if (!ref) {
     // we need to traverse a path
     filepath refpath = req->get_filepath();
@@ -370,7 +371,8 @@ void Server::handle_client_request(MClientRequest *req)
       delete req;
       return;
     }
-    
+
+    // if not an error return from path_traverse
     if (trace.size()) 
       ref = trace[trace.size()-1]->inode;
     else
@@ -2078,6 +2080,8 @@ void Server::handle_client_open(MClientRequest *req,
 {
   int flags = req->get_iarg();
   int mode = req->get_iarg2();
+  //uid_t uid = req->get_caller_uid();
+  //gid_t gid = req->get_caller_gid();
 
   dout(7) << "open " << flags << " on " << *cur << endl;
   dout(10) << "open flags = " << flags << "  mode = " << mode << endl;
@@ -2090,6 +2094,7 @@ void Server::handle_client_open(MClientRequest *req,
   }
 
   // auth for write access
+  // redirect the write open to the auth?
   if (mode != FILE_MODE_R && mode != FILE_MODE_LAZY &&
       !cur->is_auth()) {
     int auth = cur->authority();
@@ -2102,11 +2107,17 @@ void Server::handle_client_open(MClientRequest *req,
 
 
   // hmm, check permissions or something.
+  // permissions must be checked at the user/group/world level
 
 
   // can we issue the caps they want?
   version_t fdv = mds->locker->issue_file_data_version(cur);
   Capability *cap = mds->locker->issue_new_caps(cur, mode, req);
+
+  // create security capability
+  ExtCap *ext_cap = mds->locker->issue_new_extcaps(cur, mode, req);
+  ext_cap->sign_extcap(mds->getPrvKey());
+
   if (!cap) return; // can't issue (yet), so wait!
 
   dout(12) << "open gets caps " << cap_string(cap->pending()) << " for " << req->get_source() << " on " << *cur << endl;
@@ -2118,6 +2129,8 @@ void Server::handle_client_open(MClientRequest *req,
   reply->set_file_caps(cap->pending());
   reply->set_file_caps_seq(cap->get_last_seq());
   reply->set_file_data_version(fdv);
+  // set security cap
+  reply->set_ext_cap((*ext_cap));
   reply_request(req, reply, cur);
 }
 
index 6206b909b0c056d6f52bdf59064a784dbe4d43fc..676b65b87c449b058bb5a9aea325f584b58b27f8 100644 (file)
@@ -146,6 +146,9 @@ class MClientReply : public Message {
   list<InodeStat*> dir_in;
   list<string>     dir_dn;
 
+  // security capability
+  ExtCap ext_cap;
+
  public:
   void set_pcid(long pcid) { this->st.pcid = pcid; }
   long get_pcid() { return st.pcid; }
@@ -168,12 +171,16 @@ class MClientReply : public Message {
   unsigned char get_file_caps() { return st.file_caps; }
   long get_file_caps_seq() { return st.file_caps_seq; }
   __uint64_t get_file_data_version() { return st.file_data_version; }
+
+  ExtCap* get_ext_cap() { return &ext_cap; }
   
   void set_result(int r) { st.result = r; }
   void set_file_caps(unsigned char c) { st.file_caps = c; }
   void set_file_caps_seq(long s) { st.file_caps_seq = s; }
   void set_file_data_version(__uint64_t v) { st.file_data_version = v; }
 
+  void set_ext_cap(ExtCap ecap) { ext_cap = ecap; }
+
   MClientReply() {};
   MClientReply(MClientRequest *req, int result = 0) : 
     Message(MSG_CLIENT_REPLY) {
@@ -226,6 +233,9 @@ class MClientReply : public Message {
       ::_decode(dn, payload, off);
       dir_dn.push_back(dn);
     }
+
+    //_decode(ext_cap, payload, off);
+    ext_cap._decode(payload, off);
   }
   virtual void encode_payload() {
     payload.append((char*)&st, sizeof(st));
@@ -252,6 +262,8 @@ class MClientReply : public Message {
       (*pin)->_encode(payload);
       ::_encode(*pdn, payload);
     }
+    //_encode(ext_cap, payload);
+    ext_cap._encode(payload);
   }
 
   // builders
index dff2af23deb5fa00cb614000c9c9111b1b024e00..235b17618a20cfeed616840c409785eef999c62d 100644 (file)
@@ -51,6 +51,8 @@ typedef struct {
   long tid;
   int client;
   int op;
+  uid_t uid;
+  gid_t gid;
   
   entity_inst_t client_inst;
 
@@ -81,6 +83,15 @@ class MClientRequest : public Message {
     this->st.client = client;
     this->st.iarg = 0;
   }
+  MClientRequest(int op, int client, uid_t u, gid_t g)
+    : Message(MSG_CLIENT_REQUEST) {
+    memset(&st, 0, sizeof(st));
+    this->st.op = op;
+    this->st.client = client;
+    this->st.uid = u;
+    this->st.gid = g;
+    this->st.iarg = 0;
+  }
   virtual char *get_type_name() { return "creq"; }
 
   // keep a pcid (procedure call id) to match up request+reply
@@ -112,8 +123,8 @@ class MClientRequest : public Message {
   int get_client() { return st.client; }
   long get_tid() { return st.tid; }
   int get_op() { return st.op; }
-  int get_caller_uid() { return st.caller_uid; }
-  int get_caller_gid() { return st.caller_gid; }
+  uid_t get_caller_uid() { return st.caller_uid; }
+  gid_t get_caller_gid() { return st.caller_gid; }
   inodeno_t get_ino() { return st.ino; }
   string& get_path() { return path.get_path(); }
   filepath& get_filepath() { return path; }