root/source3/modules/vfs_aixacl_util.c

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

DEFINITIONS

This source file includes following definitions.
  1. aixacl_to_smbacl
  2. aixacl_smb_to_aixperm
  3. aixacl_smb_to_aixacl

   1 /*
   2    Unix SMB/Netbios implementation.
   3    VFS module to get and set posix acls
   4    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2006
   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 SMB_ACL_T aixacl_to_smbacl(struct acl *file_acl)
     /* [<][>][^][v][top][bottom][index][help] */
  23 {
  24         struct acl_entry *acl_entry;
  25         struct ace_id *idp;
  26         
  27         struct smb_acl_t *result = SMB_MALLOC_P(struct smb_acl_t);
  28         struct smb_acl_entry *ace;
  29         int i;
  30         
  31         if (result == NULL) {
  32                 return NULL;
  33         }
  34         ZERO_STRUCTP(result);
  35         
  36         /* Point to the first acl entry in the acl */
  37         acl_entry =  file_acl->acl_ext;
  38 
  39 
  40         
  41         DEBUG(10,("acl_entry is %d\n",acl_entry));
  42         DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
  43 
  44         /* Check if the extended acl bit is on.   *
  45          * If it isn't, do not show the           *
  46          * contents of the acl since AIX intends *
  47          * the extended info to remain unused     */
  48 
  49         if(file_acl->acl_mode & S_IXACL){
  50                 /* while we are not pointing to the very end */
  51                 while(acl_entry < acl_last(file_acl)) {
  52                         /* before we malloc anything, make sure this is  */
  53                         /* a valid acl entry and one that we want to map */
  54                         idp = id_nxt(acl_entry->ace_id);
  55                         if((acl_entry->ace_type == ACC_SPECIFY ||
  56                                 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
  57                                         acl_entry = acl_nxt(acl_entry);
  58                                         continue;
  59                         }
  60 
  61                         idp = acl_entry->ace_id;
  62                         DEBUG(10,("idp->id_data is %d\n",idp->id_data[0]));
  63                         
  64                         result = SMB_REALLOC(result, sizeof(struct smb_acl_t) +
  65                                      (sizeof(struct smb_acl_entry) *
  66                                       (result->count+1)));
  67                         if (result == NULL) {
  68                                 DEBUG(0, ("SMB_REALLOC failed\n"));
  69                                 errno = ENOMEM;
  70                                 return NULL;
  71                         }
  72                         
  73 
  74                         DEBUG(10,("idp->id_type is %d\n",idp->id_type));
  75                         ace = &result->acl[result->count];
  76                         
  77                         ace->a_type = idp->id_type;
  78                                                         
  79                         switch(ace->a_type) {
  80                         case ACEID_USER: {
  81                         ace->uid = idp->id_data[0];
  82                         DEBUG(10,("case ACEID_USER ace->uid is %d\n",ace->uid));
  83                         ace->a_type = SMB_ACL_USER;
  84                         break;
  85                         }
  86                 
  87                         case ACEID_GROUP: {
  88                         ace->gid = idp->id_data[0];
  89                         DEBUG(10,("case ACEID_GROUP ace->gid is %d\n",ace->gid));
  90                         ace->a_type = SMB_ACL_GROUP;
  91                         break;
  92                         }
  93                         default:
  94                                 break;
  95                         }
  96                         /* The access in the acl entries must be left shifted by *
  97                          * three bites, because they will ultimately be compared *
  98                          * to S_IRUSR, S_IWUSR, and S_IXUSR.                  */
  99 
 100                         switch(acl_entry->ace_type){
 101                         case ACC_PERMIT:
 102                         case ACC_SPECIFY:
 103                                 ace->a_perm = acl_entry->ace_access;
 104                                 ace->a_perm <<= 6;
 105                                 DEBUG(10,("ace->a_perm is %d\n",ace->a_perm));
 106                                 break;
 107                         case ACC_DENY:
 108                                 /* Since there is no way to return a DENY acl entry *
 109                                  * change to PERMIT and then shift.                 */
 110                                 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
 111                                 ace->a_perm = ~acl_entry->ace_access & 7;
 112                                 DEBUG(10,("ace->a_perm is %d\n",ace->a_perm));
 113                                 ace->a_perm <<= 6;
 114                                 break;
 115                         default:
 116                                 DEBUG(0, ("unknown ace->type\n"));
 117                                 SAFE_FREE(result);
 118                                 return(0);
 119                         }
 120                 
 121                         result->count++;
 122                         ace->a_perm |= (ace->a_perm & S_IRUSR) ? SMB_ACL_READ : 0;
 123                         ace->a_perm |= (ace->a_perm & S_IWUSR) ? SMB_ACL_WRITE : 0;
 124                         ace->a_perm |= (ace->a_perm & S_IXUSR) ? SMB_ACL_EXECUTE : 0;
 125                         DEBUG(10,("ace->a_perm is %d\n",ace->a_perm));
 126                         
 127                         DEBUG(10,("acl_entry = %d\n",acl_entry));
 128                         DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
 129  
 130                         acl_entry = acl_nxt(acl_entry);
 131                 }
 132         } /* end of if enabled */
 133 
 134         /* Since owner, group, other acl entries are not *
 135          * part of the acl entries in an acl, they must  *
 136          * be dummied up to become part of the list.     */
 137 
 138         for( i = 1; i < 4; i++) {
 139                 DEBUG(10,("i is %d\n",i));
 140 
 141                         result = SMB_REALLOC(result, sizeof(struct smb_acl_t) +
 142                                      (sizeof(struct smb_acl_entry) *
 143                                       (result->count+1)));
 144                         if (result == NULL) {
 145                                 DEBUG(0, ("SMB_REALLOC failed\n"));
 146                                 errno = ENOMEM;
 147                                 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
 148                                 return NULL;
 149                         }
 150                         
 151                 ace = &result->acl[result->count];
 152                 
 153                 ace->uid = 0;
 154                 ace->gid = 0;
 155                 DEBUG(10,("ace->uid = %d\n",ace->uid));
 156                 
 157                 switch(i) {
 158                 case 2:
 159                         ace->a_perm = file_acl->g_access << 6;
 160                         ace->a_type = SMB_ACL_GROUP_OBJ;
 161                         break;
 162 
 163                 case 3:
 164                         ace->a_perm = file_acl->o_access << 6;
 165                         ace->a_type = SMB_ACL_OTHER;
 166                         break;
 167  
 168                 case 1:
 169                         ace->a_perm = file_acl->u_access << 6;
 170                         ace->a_type = SMB_ACL_USER_OBJ;
 171                         break;
 172  
 173                 default:
 174                         return(NULL);
 175 
 176                 }
 177                 ace->a_perm |= ((ace->a_perm & S_IRUSR) ? SMB_ACL_READ : 0);
 178                 ace->a_perm |= ((ace->a_perm & S_IWUSR) ? SMB_ACL_WRITE : 0);
 179                 ace->a_perm |= ((ace->a_perm & S_IXUSR) ? SMB_ACL_EXECUTE : 0);
 180                 
 181                 memcpy(&result->acl[result->count],ace,sizeof(struct smb_acl_entry));
 182                 result->count++;
 183                 DEBUG(10,("ace->a_perm = %d\n",ace->a_perm));
 184                 DEBUG(10,("ace->a_type = %d\n",ace->a_type));
 185         }
 186 
 187 
 188         return result;
 189 
 190 
 191 }
 192 
 193 static ushort aixacl_smb_to_aixperm(SMB_ACL_PERM_T a_perm)
     /* [<][>][^][v][top][bottom][index][help] */
 194 {
 195         ushort ret = (ushort)0;
 196         if (a_perm & SMB_ACL_READ)
 197                 ret |= R_ACC;
 198         if (a_perm & SMB_ACL_WRITE)
 199                 ret |= W_ACC;
 200         if (a_perm & SMB_ACL_EXECUTE)
 201                 ret |= X_ACC;
 202         return ret;
 203 }
 204 
 205 struct acl *aixacl_smb_to_aixacl(SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
     /* [<][>][^][v][top][bottom][index][help] */
 206 {
 207         struct smb_acl_entry *smb_entry = NULL;
 208         struct acl *file_acl = NULL;
 209         struct acl *file_acl_temp = NULL;
 210         struct acl_entry *acl_entry = NULL;
 211         struct ace_id *ace_id = NULL;
 212         unsigned int id_type;
 213         unsigned int user_id;
 214         unsigned int acl_length;
 215         int     i;
 216  
 217         DEBUG(10,("Entering aixacl_smb_to_aixacl\n"));
 218         /* AIX has no default ACL */
 219         if(acltype == SMB_ACL_TYPE_DEFAULT)
 220                 return NULL;
 221 
 222         acl_length = BUFSIZ;
 223         file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
 224         if(file_acl == NULL) {
 225                 errno = ENOMEM;
 226                 DEBUG(0,("Error in aixacl_smb_to_aixacl is %d\n",errno));
 227                 return NULL;
 228         }
 229 
 230         memset(file_acl,0,BUFSIZ);
 231  
 232         file_acl->acl_len = ACL_SIZ;
 233         file_acl->acl_mode = S_IXACL;
 234 
 235         for(i=0; i<theacl->count; i++ ) {
 236                 smb_entry = &(theacl->acl[i]);
 237                 id_type = smb_entry->a_type;
 238                 DEBUG(10,("The id_type is %d\n",id_type));
 239 
 240                 switch(id_type) {
 241                         case SMB_ACL_USER_OBJ:
 242                                 file_acl->u_access = aixacl_smb_to_aixperm(smb_entry->a_perm);
 243                                 continue;
 244                         case SMB_ACL_GROUP_OBJ:
 245                                 file_acl->g_access = aixacl_smb_to_aixperm(smb_entry->a_perm);
 246                                 continue;
 247                         case SMB_ACL_OTHER:
 248                                 file_acl->o_access = aixacl_smb_to_aixperm(smb_entry->a_perm);
 249                                 continue;
 250                         case SMB_ACL_MASK:
 251                                 continue;
 252                         case SMB_ACL_GROUP:
 253                                 break; /* process this */
 254                         case SMB_ACL_USER:
 255                                 break; /* process this */
 256                         default: /* abnormal case */
 257                                 DEBUG(10,("The id_type is unknown !\n"));
 258                                 continue;
 259                 }
 260 
 261                 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
 262                         acl_length += sizeof(struct acl_entry);
 263                         file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
 264                         if(file_acl_temp == NULL) {
 265                                 SAFE_FREE(file_acl);
 266                                 errno = ENOMEM;
 267                                 DEBUG(0,("Error in aixacl_smb_to_aixacl is %d\n",errno));
 268                                 return NULL;
 269                         }
 270 
 271                         memcpy(file_acl_temp,file_acl,file_acl->acl_len);
 272                         SAFE_FREE(file_acl);
 273                         file_acl = file_acl_temp;
 274                 }
 275 
 276                 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
 277                 file_acl->acl_len += sizeof(struct acl_entry);
 278                 acl_entry->ace_len = sizeof(struct acl_entry); /* contains 1 ace_id */
 279                 acl_entry->ace_access = aixacl_smb_to_aixperm(smb_entry->a_perm);
 280 
 281                 /* In order to use this, we'll need to wait until we can get denies */
 282                 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
 283                 acl_entry->ace_type = ACC_SPECIFY; */
 284 
 285                 acl_entry->ace_type = ACC_SPECIFY;
 286 
 287                 ace_id = acl_entry->ace_id;
 288 
 289                 ace_id->id_type = (smb_entry->a_type==SMB_ACL_GROUP) ? ACEID_GROUP : ACEID_USER;
 290                 DEBUG(10,("The id type is %d\n",ace_id->id_type));
 291                 ace_id->id_len = sizeof(struct ace_id); /* contains 1 id_data */
 292                 ace_id->id_data[0] = (smb_entry->a_type==SMB_ACL_GROUP) ? smb_entry->gid : smb_entry->uid;
 293         }
 294 
 295         return file_acl;
 296 }

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