root/source3/modules/vfs_tru64acl.c

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

DEFINITIONS

This source file includes following definitions.
  1. tru64acl_sys_acl_get_file
  2. tru64acl_sys_acl_get_fd
  3. tru64acl_sys_acl_set_file
  4. tru64acl_sys_acl_set_fd
  5. tru64acl_sys_acl_delete_def_file
  6. tru64_acl_to_smb_acl
  7. tru64_ace_to_smb_ace
  8. smb_acl_to_tru64_acl
  9. smb_tag_to_tru64
  10. tru64_tag_to_smb
  11. smb_permset_to_tru64
  12. tru64_permset_to_smb
  13. vfs_tru64acl_init

   1 /*
   2    Unix SMB/Netbios implementation.
   3    VFS module to get and set Tru64 acls
   4    Copyright (C) Michael Adam 2006,2008
   5 
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 3 of the License, or
   9    (at your option) any later version.
  10 
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15 
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 
  20 #include "includes.h"
  21 
  22 /* prototypes for private functions first - for clarity */
  23 
  24 static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl);
  25 static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace, 
  26                                 struct smb_acl_entry *smb_ace);
  27 static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl);
  28 static acl_tag_t smb_tag_to_tru64(SMB_ACL_TAG_T smb_tag);
  29 static SMB_ACL_TAG_T tru64_tag_to_smb(acl_tag_t tru64_tag);
  30 static acl_perm_t smb_permset_to_tru64(SMB_ACL_PERM_T smb_permset);
  31 static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset);
  32 
  33 
  34 /* public functions - the api */
  35 
  36 SMB_ACL_T tru64acl_sys_acl_get_file(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
  37                                     const char *path_p,
  38                                     SMB_ACL_TYPE_T type)
  39 {
  40         struct smb_acl_t *result;
  41         acl_type_t the_acl_type;
  42         acl_t tru64_acl;
  43 
  44         DEBUG(10, ("Hi! This is tru64acl_sys_acl_get_file.\n"));
  45 
  46         switch(type) {
  47         case SMB_ACL_TYPE_ACCESS:
  48                 the_acl_type = ACL_TYPE_ACCESS;
  49                 break;
  50         case SMB_ACL_TYPE_DEFAULT:
  51                 the_acl_type = ACL_TYPE_DEFAULT;
  52                 break;
  53         default:
  54                 errno = EINVAL;
  55                 return NULL;
  56         }
  57 
  58         tru64_acl = acl_get_file((char *)path_p, the_acl_type);
  59 
  60         if (tru64_acl == NULL) {
  61                 return NULL;
  62         }
  63 
  64         result = tru64_acl_to_smb_acl(tru64_acl);
  65         acl_free(tru64_acl);
  66         return result;
  67 }
  68 
  69 SMB_ACL_T tru64acl_sys_acl_get_fd(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
  70                                   files_struct *fsp)
  71 {
  72         struct smb_acl_t *result;
  73         acl_t tru64_acl = acl_get_fd(fsp->fh->fd, ACL_TYPE_ACCESS);
  74 
  75         if (tru64_acl == NULL) {
  76                 return NULL;
  77         }
  78         
  79         result = tru64_acl_to_smb_acl(tru64_acl);
  80         acl_free(tru64_acl);
  81         return result;
  82 }
  83 
  84 int tru64acl_sys_acl_set_file(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
  85                               const char *name,
  86                               SMB_ACL_TYPE_T type,
  87                               SMB_ACL_T theacl)
  88 {
  89         int res;
  90         acl_type_t the_acl_type;
  91         acl_t tru64_acl;
  92 
  93         DEBUG(10, ("tru64acl_sys_acl_set_file called with name %s, type %d\n", 
  94                         name, type));
  95 
  96         switch(type) {
  97         case SMB_ACL_TYPE_ACCESS:
  98                 DEBUGADD(10, ("got acl type ACL_TYPE_ACCESS\n"));
  99                 the_acl_type = ACL_TYPE_ACCESS;
 100                 break;
 101         case SMB_ACL_TYPE_DEFAULT:
 102                 DEBUGADD(10, ("got acl type ACL_TYPE_DEFAULT\n"));
 103                 the_acl_type = ACL_TYPE_DEFAULT;
 104                 break;
 105         default:
 106                 DEBUGADD(10, ("invalid acl type\n"));
 107                 errno = EINVAL;
 108                 goto fail;
 109         }
 110 
 111         tru64_acl = smb_acl_to_tru64_acl(theacl);
 112         if (tru64_acl == NULL) {
 113                 DEBUG(10, ("smb_acl_to_tru64_acl failed!\n"));
 114                 goto fail;
 115         }
 116         DEBUG(10, ("got tru64 acl...\n"));
 117         res = acl_set_file((char *)name, the_acl_type, tru64_acl);
 118         acl_free(tru64_acl);
 119         if (res != 0) {
 120                 DEBUG(10, ("acl_set_file failed: %s\n", strerror(errno)));
 121                 goto fail;
 122         }
 123         return res;
 124 fail:
 125         DEBUG(1, ("tru64acl_sys_acl_set_file failed!\n"));
 126         return -1;
 127 }
 128 
 129 int tru64acl_sys_acl_set_fd(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 130                             files_struct *fsp,
 131                             SMB_ACL_T theacl)
 132 {
 133         int res;
 134         acl_t tru64_acl = smb_acl_to_tru64_acl(theacl);
 135         if (tru64_acl == NULL) {
 136                 return -1;
 137         }
 138         res =  acl_set_fd(fsp->fh->fd, ACL_TYPE_ACCESS, tru64_acl);
 139         acl_free(tru64_acl);
 140         return res;
 141 
 142 }
 143 
 144 int tru64acl_sys_acl_delete_def_file(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 145                                      const char *path)
 146 {
 147         return acl_delete_def_file((char *)path);
 148 }
 149 
 150 
 151 /* private functions */
 152 
 153 static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl) 
     /* [<][>][^][v][top][bottom][index][help] */
 154 {
 155         struct smb_acl_t *result;
 156         acl_entry_t entry;
 157 
 158         DEBUG(10, ("Hi! This is tru64_acl_to_smb_acl.\n"));
 159         
 160         if ((result = SMB_MALLOC_P(struct smb_acl_t)) == NULL) {
 161                 DEBUG(0, ("SMB_MALLOC_P failed in tru64_acl_to_smb_acl\n"));
 162                 errno = ENOMEM;
 163                 goto fail;
 164         }
 165         ZERO_STRUCTP(result);
 166         if (acl_first_entry((struct acl *)tru64_acl) != 0) {
 167                 DEBUG(10, ("acl_first_entry failed: %s\n", strerror(errno)));
 168                 goto fail;
 169         }
 170         while ((entry = acl_get_entry((struct acl *)tru64_acl)) != NULL) {
 171                 result = SMB_REALLOC(result, sizeof(struct smb_acl_t) +
 172                                         (sizeof(struct smb_acl_entry) * 
 173                                          (result->count + 1)));
 174                 if (result == NULL) {
 175                         DEBUG(0, ("SMB_REALLOC failed in tru64_acl_to_smb_acl\n"));
 176                         errno = ENOMEM;
 177                         goto fail;
 178                 }
 179                 /* XYZ */
 180                 if (!tru64_ace_to_smb_ace(entry, &result->acl[result->count])) {
 181                         SAFE_FREE(result);
 182                         goto fail;
 183                 }
 184                 result->count += 1;
 185         }
 186         return result;
 187 
 188 fail:
 189         if (result != NULL) {
 190                 SAFE_FREE(result);
 191         }
 192         DEBUG(1, ("tru64_acl_to_smb_acl failed!\n"));
 193         return NULL;
 194 }
 195 
 196 static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace, 
     /* [<][>][^][v][top][bottom][index][help] */
 197                                 struct smb_acl_entry *smb_ace) 
 198 {
 199         acl_tag_t tru64_tag;
 200         acl_permset_t permset;
 201         SMB_ACL_TAG_T smb_tag_type;
 202         SMB_ACL_PERM_T smb_permset;
 203         void *qualifier;
 204 
 205         if (acl_get_tag_type(tru64_ace, &tru64_tag) != 0) {
 206                 DEBUG(0, ("acl_get_tag_type failed: %s\n", strerror(errno)));
 207                 return False;
 208         }
 209         
 210         /* On could set the tag type directly to save a function call, 
 211          * but I like this better... */
 212         smb_tag_type = tru64_tag_to_smb(tru64_tag);
 213         if (smb_tag_type == 0) {
 214                 DEBUG(3, ("invalid tag type given: %d\n", tru64_tag));
 215                 return False;
 216         }
 217         if (sys_acl_set_tag_type(smb_ace, smb_tag_type) != 0) {
 218                 DEBUG(3, ("sys_acl_set_tag_type failed: %s\n", 
 219                                 strerror(errno)));
 220                 return False;
 221         }
 222         qualifier = acl_get_qualifier(tru64_ace);
 223         if (qualifier != NULL) {
 224                 if (sys_acl_set_qualifier(smb_ace, qualifier) != 0) {
 225                         DEBUG(3, ("sys_acl_set_qualifier failed\n"));
 226                         return False;
 227                 }
 228         }
 229         if (acl_get_permset(tru64_ace, &permset) != 0) {
 230                 DEBUG(3, ("acl_get_permset failed: %s\n", strerror(errno)));
 231                 return False;
 232         }
 233         smb_permset = tru64_permset_to_smb(*permset);
 234         if (sys_acl_set_permset(smb_ace, &smb_permset) != 0) {
 235                 DEBUG(3, ("sys_acl_set_permset failed: %s\n", strerror(errno)));
 236                 return False;
 237         }
 238         return True;
 239 }
 240 
 241 static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl) 
     /* [<][>][^][v][top][bottom][index][help] */
 242 {
 243         acl_t result;
 244         acl_entry_t tru64_entry;
 245         int i;
 246         char *acl_text;
 247         ssize_t acl_text_len;
 248         
 249         /* The tru64 acl_init function takes a size_t value
 250          * instead of a count of entries (as with posix). 
 251          * the size parameter "Specifies the size of the working
 252          * storage in bytes" (according to the man page). 
 253          * But it is unclear to me, how this size is to be 
 254          * calculated. 
 255          *
 256          * It should not matter, since acl_create_entry enlarges 
 257          * the working storage at need. ... */
 258 
 259         DEBUG(10, ("Hi! This is smb_acl_to_tru64_acl.\n"));
 260 
 261         result = acl_init(1);
 262 
 263         if (result == NULL) {
 264                 DEBUG(3, ("acl_init failed!\n"));
 265                 goto fail;
 266         }
 267         
 268         DEBUGADD(10, ("parsing acl entries...\n"));
 269         for (i = 0; i < smb_acl->count; i++) {
 270                 /* XYZ - maybe eliminate this direct access? */
 271                 const struct smb_acl_entry *smb_entry = &smb_acl->acl[i];
 272                 acl_tag_t tru64_tag;
 273                 acl_perm_t tru64_permset;
 274 
 275                 tru64_tag = smb_tag_to_tru64(smb_entry->a_type);
 276                 if (tru64_tag == -1) {
 277                         DEBUG(3, ("smb_tag_to_tru64 failed!\n"));
 278                         goto fail;
 279                 }
 280 
 281                 if (tru64_tag == ACL_MASK) {
 282                         DEBUGADD(10, (" - acl type ACL_MASK: not implemented on Tru64 ==> skipping\n"));
 283                         continue;
 284                 }
 285                 
 286                 tru64_entry = acl_create_entry(&result);
 287                 if (tru64_entry == NULL) {
 288                         DEBUG(3, ("acl_create_entry failed: %s\n", 
 289                                         strerror(errno)));
 290                         goto fail;
 291                 }
 292 
 293                 if (acl_set_tag_type(tru64_entry, tru64_tag) != 0) {
 294                         DEBUG(3, ("acl_set_tag_type(%d) failed: %s\n",
 295                                         strerror(errno)));
 296                         goto fail;
 297                 }
 298                 
 299                 switch (smb_entry->a_type) {
 300                 case SMB_ACL_USER:
 301                         if (acl_set_qualifier(tru64_entry, 
 302                                                 (int *)&smb_entry->uid) != 0) 
 303                         {
 304                                 DEBUG(3, ("acl_set_qualifier failed: %s\n",
 305                                         strerror(errno)));
 306                                 goto fail;
 307                         }
 308                         DEBUGADD(10, (" - setting uid to %d\n", smb_entry->uid));
 309                         break;
 310                 case SMB_ACL_GROUP:
 311                         if (acl_set_qualifier(tru64_entry, 
 312                                                 (int *)&smb_entry->gid) != 0)
 313                         {
 314                                 DEBUG(3, ("acl_set_qualifier failed: %s\n",
 315                                         strerror(errno)));
 316                                 goto fail;
 317                         }
 318                         DEBUGADD(10, (" - setting gid to %d\n", smb_entry->gid));
 319                         break;
 320                 default:
 321                         break;
 322                 }
 323 
 324                 tru64_permset = smb_permset_to_tru64(smb_entry->a_perm);
 325                 if (tru64_permset == -1) {
 326                         DEBUG(3, ("smb_permset_to_tru64 failed!\n"));
 327                         goto fail;
 328                 }
 329                 DEBUGADD(10, (" - setting perms to %0d\n", tru64_permset));
 330                 if (acl_set_permset(tru64_entry, &tru64_permset) != 0)
 331                 {
 332                         DEBUG(3, ("acl_set_permset failed: %s\n", strerror(errno)));
 333                         goto fail;
 334                 }
 335         } /* for */
 336         DEBUGADD(10, ("done parsing acl entries\n"));
 337 
 338         tru64_entry = NULL;
 339         if (acl_valid(result, &tru64_entry) != 0) {
 340                 DEBUG(1, ("smb_acl_to_tru64_acl: ACL is invalid (%s)\n",
 341                                 strerror(errno)));
 342                 if (tru64_entry != NULL) {
 343                         DEBUGADD(1, ("the acl contains duplicate entries\n"));
 344                 }
 345                 goto fail;
 346         }
 347         DEBUGADD(10, ("acl is valid\n"));
 348 
 349         acl_text = acl_to_text(result, &acl_text_len);
 350         if (acl_text == NULL) {
 351                 DEBUG(3, ("acl_to_text failed: %s\n", strerror(errno)));
 352                 goto fail;
 353         }
 354         DEBUG(1, ("acl_text: %s\n", acl_text));
 355         free(acl_text);
 356 
 357         return result;
 358 
 359 fail:
 360         if (result != NULL) {
 361                 acl_free(result);
 362         }
 363         DEBUG(1, ("smb_acl_to_tru64_acl failed!\n"));
 364         return NULL;
 365 }
 366 
 367 static acl_tag_t smb_tag_to_tru64(SMB_ACL_TAG_T smb_tag)
     /* [<][>][^][v][top][bottom][index][help] */
 368 {
 369         acl_tag_t result;
 370         switch (smb_tag) {
 371         case SMB_ACL_USER:
 372                 result = ACL_USER;
 373                 DEBUGADD(10, ("got acl type ACL_USER\n"));
 374                 break;
 375         case SMB_ACL_USER_OBJ:
 376                 result = ACL_USER_OBJ;
 377                 DEBUGADD(10, ("got acl type ACL_USER_OBJ\n"));
 378                 break;
 379         case SMB_ACL_GROUP:
 380                 result = ACL_GROUP;
 381                 DEBUGADD(10, ("got acl type ACL_GROUP\n"));
 382                 break;
 383         case SMB_ACL_GROUP_OBJ:
 384                 result = ACL_GROUP_OBJ;
 385                 DEBUGADD(10, ("got acl type ACL_GROUP_OBJ\n"));
 386                 break;
 387         case SMB_ACL_OTHER:
 388                 result = ACL_OTHER;
 389                 DEBUGADD(10, ("got acl type ACL_OTHER\n"));
 390                 break;
 391         case SMB_ACL_MASK:
 392                 result = ACL_MASK;
 393                 DEBUGADD(10, ("got acl type ACL_MASK\n"));
 394                 break;
 395         default:
 396                 DEBUG(1, ("Unknown tag type %d\n", smb_tag));
 397                 result = -1;
 398         }
 399         return result;
 400 }
 401 
 402 
 403 static SMB_ACL_TAG_T tru64_tag_to_smb(acl_tag_t tru64_tag)
     /* [<][>][^][v][top][bottom][index][help] */
 404 {
 405         SMB_ACL_TAG_T smb_tag_type;
 406         switch(tru64_tag) {
 407         case ACL_USER:
 408                 smb_tag_type = SMB_ACL_USER;
 409                 DEBUGADD(10, ("got smb acl tag type SMB_ACL_USER\n"));
 410                 break;
 411         case ACL_USER_OBJ:
 412                 smb_tag_type = SMB_ACL_USER_OBJ;
 413                 DEBUGADD(10, ("got smb acl tag type SMB_ACL_USER_OBJ\n"));
 414                 break;
 415         case ACL_GROUP:
 416                 smb_tag_type = SMB_ACL_GROUP;
 417                 DEBUGADD(10, ("got smb acl tag type SMB_ACL_GROUP\n"));
 418                 break;
 419         case ACL_GROUP_OBJ:
 420                 smb_tag_type = SMB_ACL_GROUP_OBJ;
 421                 DEBUGADD(10, ("got smb acl tag type SMB_ACL_GROUP_OBJ\n"));
 422                 break;
 423         case ACL_OTHER:
 424                 smb_tag_type = SMB_ACL_OTHER;
 425                 DEBUGADD(10, ("got smb acl tag type SMB_ACL_OTHER\n"));
 426                 break;
 427         case ACL_MASK:
 428                 smb_tag_type = SMB_ACL_MASK;
 429                 DEBUGADD(10, ("got smb acl tag type SMB_ACL_MASK\n"));
 430                 break;
 431         default:
 432                 DEBUG(0, ("Unknown tag type %d\n", (unsigned int)tru64_tag));
 433                 smb_tag_type = 0;
 434         }
 435         return smb_tag_type;
 436 }
 437 
 438 static acl_perm_t smb_permset_to_tru64(SMB_ACL_PERM_T smb_permset)
     /* [<][>][^][v][top][bottom][index][help] */
 439 {
 440         /* originally, I thought that acl_clear_perm was the
 441          * proper way to reset the permset to 0. but without 
 442          * initializing it to 0, acl_clear_perm fails.
 443          * so probably, acl_clear_perm is not necessary here... ?! */
 444         acl_perm_t tru64_permset = 0;
 445         if (acl_clear_perm(&tru64_permset) != 0) {
 446                 DEBUG(5, ("acl_clear_perm failed: %s\n", strerror(errno)));
 447                 return -1;
 448         }
 449         /* according to original lib/sysacls.c, acl_add_perm is
 450          * broken on tru64 ... */
 451         tru64_permset |= ((smb_permset & SMB_ACL_READ) ? ACL_READ : 0);
 452         tru64_permset |= ((smb_permset & SMB_ACL_WRITE) ? ACL_WRITE : 0);
 453         tru64_permset |= ((smb_permset & SMB_ACL_EXECUTE) ? ACL_EXECUTE : 0);
 454         return tru64_permset;
 455 }
 456 
 457 static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset)
     /* [<][>][^][v][top][bottom][index][help] */
 458 {
 459         SMB_ACL_PERM_T smb_permset  = 0;
 460         smb_permset |= ((tru64_permset & ACL_READ) ? SMB_ACL_READ : 0);
 461         smb_permset |= ((tru64_permset & ACL_WRITE) ? SMB_ACL_WRITE : 0);
 462         smb_permset |= ((tru64_permset & ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0);
 463         return smb_permset;
 464 }
 465 
 466 
 467 /* VFS operations structure */
 468 
 469 static vfs_op_tuple tru64acl_op_tuples[] = {
 470         /* Disk operations */
 471   {SMB_VFS_OP(tru64acl_sys_acl_get_file),
 472    SMB_VFS_OP_SYS_ACL_GET_FILE,
 473    SMB_VFS_LAYER_TRANSPARENT},
 474 
 475   {SMB_VFS_OP(tru64acl_sys_acl_get_fd),
 476    SMB_VFS_OP_SYS_ACL_GET_FD,
 477    SMB_VFS_LAYER_TRANSPARENT},
 478 
 479   {SMB_VFS_OP(tru64acl_sys_acl_set_file),
 480    SMB_VFS_OP_SYS_ACL_SET_FILE,
 481    SMB_VFS_LAYER_TRANSPARENT},
 482 
 483   {SMB_VFS_OP(tru64acl_sys_acl_set_fd),
 484    SMB_VFS_OP_SYS_ACL_SET_FD,
 485    SMB_VFS_LAYER_TRANSPARENT},
 486 
 487   {SMB_VFS_OP(tru64acl_sys_acl_delete_def_file),
 488    SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
 489    SMB_VFS_LAYER_TRANSPARENT},
 490 
 491   {SMB_VFS_OP(NULL),
 492    SMB_VFS_OP_NOOP,
 493    SMB_VFS_LAYER_NOOP}
 494 };
 495 
 496 NTSTATUS vfs_tru64acl_init(void);
 497 NTSTATUS vfs_tru64acl_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 498 {
 499         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "tru64acl",
 500                                 tru64acl_op_tuples);
 501 }
 502 
 503 /* ENTE */

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