root/source3/modules/vfs_cap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cap_disk_free
  2. cap_opendir
  3. cap_readdir
  4. cap_mkdir
  5. cap_rmdir
  6. cap_open
  7. cap_rename
  8. cap_stat
  9. cap_lstat
  10. cap_unlink
  11. cap_chmod
  12. cap_chown
  13. cap_lchown
  14. cap_chdir
  15. cap_ntimes
  16. cap_symlink
  17. cap_readlink
  18. cap_link
  19. cap_mknod
  20. cap_realpath
  21. cap_chmod_acl
  22. cap_sys_acl_get_file
  23. cap_sys_acl_set_file
  24. cap_sys_acl_delete_def_file
  25. cap_getxattr
  26. cap_lgetxattr
  27. cap_fgetxattr
  28. cap_listxattr
  29. cap_llistxattr
  30. cap_removexattr
  31. cap_lremovexattr
  32. cap_fremovexattr
  33. cap_setxattr
  34. cap_lsetxattr
  35. cap_fsetxattr
  36. vfs_cap_init
  37. capencode
  38. capdecode

   1 /*
   2  * CAP VFS module for Samba 3.x Version 0.3
   3  *
   4  * Copyright (C) Tim Potter, 1999-2000
   5  * Copyright (C) Alexander Bokovoy, 2002-2003
   6  * Copyright (C) Stefan (metze) Metzmacher, 2003
   7  * Copyright (C) TAKAHASHI Motonobu (monyo), 2003
   8  * Copyright (C) Jeremy Allison, 2007
   9  *
  10  * This program is free software; you can redistribute it and/or modify
  11  * it under the terms of the GNU General Public License as published by
  12  * the Free Software Foundation; either version 3 of the License, or
  13  * (at your option) any later version.
  14  *
  15  * This program is distributed in the hope that it will be useful,
  16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18  * GNU General Public License for more details.
  19  *
  20  * You should have received a copy of the GNU General Public License
  21  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  22  */
  23 
  24 
  25 #include "includes.h"
  26 
  27 /* cap functions */
  28 static char *capencode(TALLOC_CTX *ctx, const char *from);
  29 static char *capdecode(TALLOC_CTX *ctx, const char *from);
  30 
  31 static uint64_t cap_disk_free(vfs_handle_struct *handle, const char *path,
     /* [<][>][^][v][top][bottom][index][help] */
  32         bool small_query, uint64_t *bsize,
  33         uint64_t *dfree, uint64_t *dsize)
  34 {
  35         char *cappath = capencode(talloc_tos(), path);
  36 
  37         if (!cappath) {
  38                 errno = ENOMEM;
  39                 return (uint64_t)-1;
  40         }
  41         return SMB_VFS_NEXT_DISK_FREE(handle, cappath, small_query, bsize,
  42                                         dfree, dsize);
  43 }
  44 
  45 static SMB_STRUCT_DIR *cap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
     /* [<][>][^][v][top][bottom][index][help] */
  46 {
  47         char *capname = capencode(talloc_tos(), fname);
  48 
  49         if (!capname) {
  50                 errno = ENOMEM;
  51                 return NULL;
  52         }
  53         return SMB_VFS_NEXT_OPENDIR(handle, capname, mask, attr);
  54 }
  55 
  56 static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
     /* [<][>][^][v][top][bottom][index][help] */
  57 {
  58         SMB_STRUCT_DIRENT *result;
  59         SMB_STRUCT_DIRENT *newdirent;
  60         char *newname;
  61         size_t newnamelen;
  62         DEBUG(3,("cap: cap_readdir\n"));
  63 
  64         result = SMB_VFS_NEXT_READDIR(handle, dirp, NULL);
  65         if (!result) {
  66                 return NULL;
  67         }
  68 
  69         newname = capdecode(talloc_tos(), result->d_name);
  70         if (!newname) {
  71                 return NULL;
  72         }
  73         DEBUG(3,("cap: cap_readdir: %s\n", newname));
  74         newnamelen = strlen(newname)+1;
  75         newdirent = (SMB_STRUCT_DIRENT *)TALLOC_ARRAY(talloc_tos(),
  76                         char,
  77                         sizeof(SMB_STRUCT_DIRENT)+
  78                                 newnamelen);
  79         if (!newdirent) {
  80                 return NULL;
  81         }
  82         memcpy(newdirent, result, sizeof(SMB_STRUCT_DIRENT));
  83         memcpy(&newdirent->d_name, newname, newnamelen);
  84         return newdirent;
  85 }
  86 
  87 static int cap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
  88 {
  89         char *cappath = capencode(talloc_tos(), path);
  90 
  91         if (!cappath) {
  92                 errno = ENOMEM;
  93                 return -1;
  94         }
  95         return SMB_VFS_NEXT_MKDIR(handle, cappath, mode);
  96 }
  97 
  98 static int cap_rmdir(vfs_handle_struct *handle, const char *path)
     /* [<][>][^][v][top][bottom][index][help] */
  99 {
 100         char *cappath = capencode(talloc_tos(), path);
 101 
 102         if (!cappath) {
 103                 errno = ENOMEM;
 104                 return -1;
 105         }
 106         return SMB_VFS_NEXT_RMDIR(handle, cappath);
 107 }
 108 
 109 static int cap_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 110 {
 111         char *cappath = capencode(talloc_tos(), fname);
 112 
 113         if (!cappath) {
 114                 errno = ENOMEM;
 115                 return -1;
 116         }
 117         DEBUG(3,("cap: cap_open for %s\n", fname));
 118         return SMB_VFS_NEXT_OPEN(handle, cappath, fsp, flags, mode);
 119 }
 120 
 121 static int cap_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
     /* [<][>][^][v][top][bottom][index][help] */
 122 {
 123         char *capold = capencode(talloc_tos(), oldname);
 124         char *capnew = capencode(talloc_tos(), newname);
 125 
 126         if (!capold || !capnew) {
 127                 errno = ENOMEM;
 128                 return -1;
 129         }
 130         return SMB_VFS_NEXT_RENAME(handle, capold, capnew);
 131 }
 132 
 133 static int cap_stat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf)
     /* [<][>][^][v][top][bottom][index][help] */
 134 {
 135         char *cappath = capencode(talloc_tos(), path);
 136 
 137         if (!cappath) {
 138                 errno = ENOMEM;
 139                 return -1;
 140         }
 141         return SMB_VFS_NEXT_STAT(handle, cappath, sbuf);
 142 }
 143 
 144 static int cap_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf)
     /* [<][>][^][v][top][bottom][index][help] */
 145 {
 146         char *cappath = capencode(talloc_tos(), path);
 147 
 148         if (!cappath) {
 149                 errno = ENOMEM;
 150                 return -1;
 151         }
 152         return SMB_VFS_NEXT_LSTAT(handle, cappath, sbuf);
 153 }
 154 
 155 static int cap_unlink(vfs_handle_struct *handle, const char *path)
     /* [<][>][^][v][top][bottom][index][help] */
 156 {
 157         char *cappath = capencode(talloc_tos(), path);
 158 
 159         if (!cappath) {
 160                 errno = ENOMEM;
 161                 return -1;
 162         }
 163         return SMB_VFS_NEXT_UNLINK(handle, cappath);
 164 }
 165 
 166 static int cap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 167 {
 168         char *cappath = capencode(talloc_tos(), path);
 169 
 170         if (!cappath) {
 171                 errno = ENOMEM;
 172                 return -1;
 173         }
 174         return SMB_VFS_NEXT_CHMOD(handle, cappath, mode);
 175 }
 176 
 177 static int cap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
     /* [<][>][^][v][top][bottom][index][help] */
 178 {
 179         char *cappath = capencode(talloc_tos(), path);
 180 
 181         if (!cappath) {
 182                 errno = ENOMEM;
 183                 return -1;
 184         }
 185         return SMB_VFS_NEXT_CHOWN(handle, cappath, uid, gid);
 186 }
 187 
 188 static int cap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
     /* [<][>][^][v][top][bottom][index][help] */
 189 {
 190         char *cappath = capencode(talloc_tos(), path);
 191 
 192         if (!cappath) {
 193                 errno = ENOMEM;
 194                 return -1;
 195         }
 196         return SMB_VFS_NEXT_LCHOWN(handle, cappath, uid, gid);
 197 }
 198 
 199 static int cap_chdir(vfs_handle_struct *handle, const char *path)
     /* [<][>][^][v][top][bottom][index][help] */
 200 {
 201         char *cappath = capencode(talloc_tos(), path);
 202 
 203         if (!cappath) {
 204                 errno = ENOMEM;
 205                 return -1;
 206         }
 207         DEBUG(3,("cap: cap_chdir for %s\n", path));
 208         return SMB_VFS_NEXT_CHDIR(handle, cappath);
 209 }
 210 
 211 static int cap_ntimes(vfs_handle_struct *handle, const char *path,
     /* [<][>][^][v][top][bottom][index][help] */
 212                       struct smb_file_time *ft)
 213 {
 214         char *cappath = capencode(talloc_tos(), path);
 215 
 216         if (!cappath) {
 217                 errno = ENOMEM;
 218                 return -1;
 219         }
 220         return SMB_VFS_NEXT_NTIMES(handle, cappath, ft);
 221 }
 222 
 223 
 224 static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
     /* [<][>][^][v][top][bottom][index][help] */
 225 {
 226         char *capold = capencode(talloc_tos(), oldpath);
 227         char *capnew = capencode(talloc_tos(), newpath);
 228 
 229         if (!capold || !capnew) {
 230                 errno = ENOMEM;
 231                 return -1;
 232         }
 233         return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew);
 234 }
 235 
 236 static bool cap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
     /* [<][>][^][v][top][bottom][index][help] */
 237 {
 238         char *cappath = capencode(talloc_tos(), path);
 239 
 240         if (!cappath) {
 241                 errno = ENOMEM;
 242                 return -1;
 243         }
 244         return SMB_VFS_NEXT_READLINK(handle, cappath, buf, bufsiz);
 245 }
 246 
 247 static int cap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
     /* [<][>][^][v][top][bottom][index][help] */
 248 {
 249         char *capold = capencode(talloc_tos(), oldpath);
 250         char *capnew = capencode(talloc_tos(), newpath);
 251 
 252         if (!capold || !capnew) {
 253                 errno = ENOMEM;
 254                 return -1;
 255         }
 256         return SMB_VFS_NEXT_LINK(handle, capold, capnew);
 257 }
 258 
 259 static int cap_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev)
     /* [<][>][^][v][top][bottom][index][help] */
 260 {
 261         char *cappath = capencode(talloc_tos(), path);
 262 
 263         if (!cappath) {
 264                 errno = ENOMEM;
 265                 return -1;
 266         }
 267         return SMB_VFS_NEXT_MKNOD(handle, cappath, mode, dev);
 268 }
 269 
 270 static char *cap_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path)
     /* [<][>][^][v][top][bottom][index][help] */
 271 {
 272         /* monyo need capencode'ed and capdecode'ed? */
 273         char *cappath = capencode(talloc_tos(), path);
 274 
 275         if (!cappath) {
 276                 errno = ENOMEM;
 277                 return NULL;
 278         }
 279         return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path);
 280 }
 281 
 282 static int cap_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 283 {
 284         char *cappath = capencode(talloc_tos(), path);
 285 
 286         /* If the underlying VFS doesn't have ACL support... */
 287         if (!handle->vfs_next.ops.chmod_acl) {
 288                 errno = ENOSYS;
 289                 return -1;
 290         }
 291         if (!cappath) {
 292                 errno = ENOMEM;
 293                 return -1;
 294         }
 295         return SMB_VFS_NEXT_CHMOD_ACL(handle, cappath, mode);
 296 }
 297 
 298 static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T type)
     /* [<][>][^][v][top][bottom][index][help] */
 299 {
 300         char *cappath = capencode(talloc_tos(), path);
 301 
 302         if (!cappath) {
 303                 errno = ENOMEM;
 304                 return (SMB_ACL_T)NULL;
 305         }
 306         return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cappath, type);
 307 }
 308 
 309 static int cap_sys_acl_set_file(vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
     /* [<][>][^][v][top][bottom][index][help] */
 310 {
 311         char *cappath = capencode(talloc_tos(), path);
 312 
 313         if (!cappath) {
 314                 errno = ENOMEM;
 315                 return -1;
 316         }
 317         return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, cappath, acltype, theacl);
 318 }
 319 
 320 static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
     /* [<][>][^][v][top][bottom][index][help] */
 321 {
 322         char *cappath = capencode(talloc_tos(), path);
 323 
 324         if (!cappath) {
 325                 errno = ENOMEM;
 326                 return -1;
 327         }
 328         return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cappath);
 329 }
 330 
 331 static ssize_t cap_getxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
 332 {
 333         char *cappath = capencode(talloc_tos(), path);
 334         char *capname = capencode(talloc_tos(), name);
 335 
 336         if (!cappath || !capname) {
 337                 errno = ENOMEM;
 338                 return -1;
 339         }
 340         return SMB_VFS_NEXT_GETXATTR(handle, cappath, capname, value, size);
 341 }
 342 
 343 static ssize_t cap_lgetxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t
     /* [<][>][^][v][top][bottom][index][help] */
 344 size)
 345 {
 346         char *cappath = capencode(talloc_tos(), path);
 347         char *capname = capencode(talloc_tos(), name);
 348 
 349         if (!cappath || !capname) {
 350                 errno = ENOMEM;
 351                 return -1;
 352         }
 353         return SMB_VFS_NEXT_LGETXATTR(handle, cappath, capname, value, size);
 354 }
 355 
 356 static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, void *value, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
 357 {
 358         char *cappath = capencode(talloc_tos(), path);
 359 
 360         if (!cappath) {
 361                 errno = ENOMEM;
 362                 return -1;
 363         }
 364         return SMB_VFS_NEXT_FGETXATTR(handle, fsp, cappath, value, size);
 365 }
 366 
 367 static ssize_t cap_listxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
 368 {
 369         char *cappath = capencode(talloc_tos(), path);
 370 
 371         if (!cappath) {
 372                 errno = ENOMEM;
 373                 return -1;
 374         }
 375         return SMB_VFS_NEXT_LISTXATTR(handle, cappath, list, size);
 376 }
 377 
 378 static ssize_t cap_llistxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
 379 {
 380         char *cappath = capencode(talloc_tos(), path);
 381 
 382         if (!cappath) {
 383                 errno = ENOMEM;
 384                 return -1;
 385         }
 386         return SMB_VFS_NEXT_LLISTXATTR(handle, cappath, list, size);
 387 }
 388 
 389 static int cap_removexattr(vfs_handle_struct *handle, const char *path, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 390 {
 391         char *cappath = capencode(talloc_tos(), path);
 392         char *capname = capencode(talloc_tos(), name);
 393 
 394         if (!cappath || !capname) {
 395                 errno = ENOMEM;
 396                 return -1;
 397         }
 398         return SMB_VFS_NEXT_REMOVEXATTR(handle, cappath, capname);
 399 }
 400 
 401 static int cap_lremovexattr(vfs_handle_struct *handle, const char *path, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 402 {
 403         char *cappath = capencode(talloc_tos(), path);
 404         char *capname = capencode(talloc_tos(), name);
 405 
 406         if (!cappath || !capname) {
 407                 errno = ENOMEM;
 408                 return -1;
 409         }
 410         return SMB_VFS_NEXT_LREMOVEXATTR(handle, cappath, capname);
 411 }
 412 
 413 static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path)
     /* [<][>][^][v][top][bottom][index][help] */
 414 {
 415         char *cappath = capencode(talloc_tos(), path);
 416 
 417         if (!cappath) {
 418                 errno = ENOMEM;
 419                 return -1;
 420         }
 421         return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, cappath);
 422 }
 423 
 424 static int cap_setxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
     /* [<][>][^][v][top][bottom][index][help] */
 425 {
 426         char *cappath = capencode(talloc_tos(), path);
 427         char *capname = capencode(talloc_tos(), name);
 428 
 429         if (!cappath || !capname) {
 430                 errno = ENOMEM;
 431                 return -1;
 432         }
 433         return SMB_VFS_NEXT_SETXATTR(handle, cappath, capname, value, size, flags);
 434 }
 435 
 436 static int cap_lsetxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
     /* [<][>][^][v][top][bottom][index][help] */
 437 {
 438         char *cappath = capencode(talloc_tos(), path);
 439         char *capname = capencode(talloc_tos(), name);
 440 
 441         if (!cappath || !capname) {
 442                 errno = ENOMEM;
 443                 return -1;
 444         }
 445         return SMB_VFS_NEXT_LSETXATTR(handle, cappath, capname, value, size, flags);
 446 }
 447 
 448 static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, const void *value, size_t size, int flags)
     /* [<][>][^][v][top][bottom][index][help] */
 449 {
 450         char *cappath = capencode(talloc_tos(), path);
 451 
 452         if (!cappath) {
 453                 errno = ENOMEM;
 454                 return -1;
 455         }
 456         return SMB_VFS_NEXT_FSETXATTR(handle, fsp, cappath, value, size, flags);
 457 }
 458 
 459 /* VFS operations structure */
 460 
 461 static vfs_op_tuple cap_op_tuples[] = {
 462 
 463         /* Disk operations */
 464 
 465         {SMB_VFS_OP(cap_disk_free),                     SMB_VFS_OP_DISK_FREE,           SMB_VFS_LAYER_TRANSPARENT},
 466 
 467         /* Directory operations */
 468 
 469         {SMB_VFS_OP(cap_opendir),                       SMB_VFS_OP_OPENDIR,             SMB_VFS_LAYER_TRANSPARENT},
 470         {SMB_VFS_OP(cap_readdir),                       SMB_VFS_OP_READDIR,             SMB_VFS_LAYER_TRANSPARENT},
 471         {SMB_VFS_OP(cap_mkdir),                 SMB_VFS_OP_MKDIR,               SMB_VFS_LAYER_TRANSPARENT},
 472         {SMB_VFS_OP(cap_rmdir),                 SMB_VFS_OP_RMDIR,               SMB_VFS_LAYER_TRANSPARENT},
 473 
 474         /* File operations */
 475 
 476         {SMB_VFS_OP(cap_open),                          SMB_VFS_OP_OPEN,                SMB_VFS_LAYER_TRANSPARENT},
 477         {SMB_VFS_OP(cap_rename),                        SMB_VFS_OP_RENAME,              SMB_VFS_LAYER_TRANSPARENT},
 478         {SMB_VFS_OP(cap_stat),                          SMB_VFS_OP_STAT,                SMB_VFS_LAYER_TRANSPARENT},
 479         {SMB_VFS_OP(cap_lstat),                 SMB_VFS_OP_LSTAT,               SMB_VFS_LAYER_TRANSPARENT},
 480         {SMB_VFS_OP(cap_unlink),                        SMB_VFS_OP_UNLINK,              SMB_VFS_LAYER_TRANSPARENT},
 481         {SMB_VFS_OP(cap_chmod),                 SMB_VFS_OP_CHMOD,               SMB_VFS_LAYER_TRANSPARENT},
 482         {SMB_VFS_OP(cap_chown),                 SMB_VFS_OP_CHOWN,               SMB_VFS_LAYER_TRANSPARENT},
 483         {SMB_VFS_OP(cap_lchown),                SMB_VFS_OP_LCHOWN,              SMB_VFS_LAYER_TRANSPARENT},
 484         {SMB_VFS_OP(cap_chdir),                 SMB_VFS_OP_CHDIR,               SMB_VFS_LAYER_TRANSPARENT},
 485         {SMB_VFS_OP(cap_ntimes),                        SMB_VFS_OP_NTIMES,              SMB_VFS_LAYER_TRANSPARENT},
 486         {SMB_VFS_OP(cap_symlink),                       SMB_VFS_OP_SYMLINK,             SMB_VFS_LAYER_TRANSPARENT},
 487         {SMB_VFS_OP(cap_readlink),                      SMB_VFS_OP_READLINK,            SMB_VFS_LAYER_TRANSPARENT},
 488         {SMB_VFS_OP(cap_link),                          SMB_VFS_OP_LINK,                SMB_VFS_LAYER_TRANSPARENT},
 489         {SMB_VFS_OP(cap_mknod),                 SMB_VFS_OP_MKNOD,               SMB_VFS_LAYER_TRANSPARENT},
 490         {SMB_VFS_OP(cap_realpath),                      SMB_VFS_OP_REALPATH,            SMB_VFS_LAYER_TRANSPARENT},
 491 
 492         /* POSIX ACL operations */
 493 
 494         {SMB_VFS_OP(cap_chmod_acl),                     SMB_VFS_OP_CHMOD_ACL,           SMB_VFS_LAYER_TRANSPARENT},
 495 
 496         {SMB_VFS_OP(cap_sys_acl_get_file),              SMB_VFS_OP_SYS_ACL_GET_FILE,            SMB_VFS_LAYER_TRANSPARENT},
 497         {SMB_VFS_OP(cap_sys_acl_set_file),              SMB_VFS_OP_SYS_ACL_SET_FILE,            SMB_VFS_LAYER_TRANSPARENT},
 498         {SMB_VFS_OP(cap_sys_acl_delete_def_file),       SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,     SMB_VFS_LAYER_TRANSPARENT},
 499 
 500         /* EA operations. */
 501         {SMB_VFS_OP(cap_getxattr),                      SMB_VFS_OP_GETXATTR,                    SMB_VFS_LAYER_TRANSPARENT},
 502         {SMB_VFS_OP(cap_lgetxattr),                     SMB_VFS_OP_LGETXATTR,                   SMB_VFS_LAYER_TRANSPARENT},
 503         {SMB_VFS_OP(cap_fgetxattr),                     SMB_VFS_OP_FGETXATTR,                   SMB_VFS_LAYER_TRANSPARENT},
 504         {SMB_VFS_OP(cap_listxattr),                     SMB_VFS_OP_LISTXATTR,                   SMB_VFS_LAYER_TRANSPARENT},
 505         {SMB_VFS_OP(cap_llistxattr),                    SMB_VFS_OP_LLISTXATTR,                  SMB_VFS_LAYER_TRANSPARENT},
 506         {SMB_VFS_OP(cap_removexattr),                   SMB_VFS_OP_REMOVEXATTR,                 SMB_VFS_LAYER_TRANSPARENT},
 507         {SMB_VFS_OP(cap_lremovexattr),                  SMB_VFS_OP_LREMOVEXATTR,                SMB_VFS_LAYER_TRANSPARENT},
 508         {SMB_VFS_OP(cap_fremovexattr),                  SMB_VFS_OP_FREMOVEXATTR,                SMB_VFS_LAYER_TRANSPARENT},
 509         {SMB_VFS_OP(cap_setxattr),                      SMB_VFS_OP_SETXATTR,                    SMB_VFS_LAYER_TRANSPARENT},
 510         {SMB_VFS_OP(cap_lsetxattr),                     SMB_VFS_OP_LSETXATTR,                   SMB_VFS_LAYER_TRANSPARENT},
 511         {SMB_VFS_OP(cap_fsetxattr),                     SMB_VFS_OP_FSETXATTR,                   SMB_VFS_LAYER_TRANSPARENT},
 512 
 513         {NULL,                                          SMB_VFS_OP_NOOP,                        SMB_VFS_LAYER_NOOP}
 514 };
 515 
 516 NTSTATUS vfs_cap_init(void);
 517 NTSTATUS vfs_cap_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 518 {
 519         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap", cap_op_tuples);
 520 }
 521 
 522 /* For CAP functions */
 523 #define hex_tag ':'
 524 #define hex2bin(c)              hex2bin_table[(unsigned char)(c)]
 525 #define bin2hex(c)              bin2hex_table[(unsigned char)(c)]
 526 #define is_hex(s)               ((s)[0] == hex_tag)
 527 
 528 static unsigned char hex2bin_table[256] = {
 529 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
 530 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
 531 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
 532 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
 533 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x40 */
 534 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
 535 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
 536 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x60 */
 537 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
 538 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */
 539 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
 540 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
 541 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
 542 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
 543 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
 544 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
 545 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 */
 546 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  /* 0xf0 */
 547 };
 548 static unsigned char bin2hex_table[256] = "0123456789abcdef";
 549 
 550 /*******************************************************************
 551   original code -> ":xx"  - CAP format
 552 ********************************************************************/
 553 
 554 static char *capencode(TALLOC_CTX *ctx, const char *from)
     /* [<][>][^][v][top][bottom][index][help] */
 555 {
 556         char *out = NULL;
 557         const char *p1;
 558         char *to = NULL;
 559         size_t len = 0;
 560 
 561         for (p1 = from; *p1; p1++) {
 562                 if ((unsigned char)*p1 >= 0x80) {
 563                         len += 3;
 564                 } else {
 565                         len++;
 566                 }
 567         }
 568         len++;
 569 
 570         to = TALLOC_ARRAY(ctx, char, len);
 571         if (!to) {
 572                 return NULL;
 573         }
 574 
 575         for (out = to; *from;) {
 576                 /* buffer husoku error */
 577                 if ((unsigned char)*from >= 0x80) {
 578                         *out++ = hex_tag;
 579                         *out++ = bin2hex (((*from)>>4)&0x0f);
 580                         *out++ = bin2hex ((*from)&0x0f);
 581                         from++;
 582                 } else {
 583                         *out++ = *from++;
 584                 }
 585         }
 586         *out = '\0';
 587         return to;
 588 }
 589 
 590 /*******************************************************************
 591   CAP -> original code
 592 ********************************************************************/
 593 /* ":xx" -> a byte */
 594 
 595 static char *capdecode(TALLOC_CTX *ctx, const char *from)
     /* [<][>][^][v][top][bottom][index][help] */
 596 {
 597         const char *p1;
 598         char *out = NULL;
 599         char *to = NULL;
 600         size_t len = 0;
 601 
 602         for (p1 = from; *p1; len++) {
 603                 if (is_hex(from)) {
 604                         p1 += 3;
 605                 } else {
 606                         p1++;
 607                 }
 608         }
 609 
 610         to = TALLOC_ARRAY(ctx, char, len);
 611         if (!to) {
 612                 return NULL;
 613         }
 614 
 615         for (out = to; *from;) {
 616                 if (is_hex(from)) {
 617                         *out++ = (hex2bin(from[1])<<4) | (hex2bin(from[2]));
 618                         from += 3;
 619                 } else {
 620                         *out++ = *from++;
 621                 }
 622         }
 623         *out = '\0';
 624         return to;
 625 }

/* [<][>][^][v][top][bottom][index][help] */