nfs-ganesha 1.4

access_check.c

Go to the documentation of this file.
00001 /*
00002  * file/object access checking
00003  */
00004 
00005 #ifdef HAVE_CONFIG_H
00006 #include "config.h"
00007 #endif
00008 
00009 #include  "fsal.h"
00010 #include <sys/stat.h>
00011 #include "FSAL/access_check.h"
00012 
00013 
00014 
00015 #ifdef _USE_NFS4_ACL
00016 #define ACL_DEBUG_BUF_SIZE 256
00017 static fsal_status_t fsal_check_access_acl(fsal_op_context_t * p_context,   /* IN */
00018                                                   fsal_aceperm_t v4mask,  /* IN */
00019                                                   fsal_attrib_list_t * p_object_attributes   /* IN */ );
00020 #endif                          /* _USE_NFS4_ACL */
00021 
00022 static fsal_status_t fsal_check_access_no_acl(fsal_op_context_t * p_context,   /* IN */
00023                                                      fsal_accessflags_t access_type,  /* IN */
00024                                                      struct stat *p_buffstat, /* IN */
00025                                                      fsal_attrib_list_t * p_object_attributes /* IN */ );
00026 
00027 
00028 #ifdef _USE_NFS4_ACL
00029 static fsal_boolean_t fsal_check_ace_owner(fsal_uid_t uid, fsal_op_context_t *p_context)
00030 {
00031   return (p_context->credential.user == uid);
00032 }
00033 
00034 static fsal_boolean_t fsal_check_ace_group(fsal_gid_t gid, fsal_op_context_t *p_context)
00035 {
00036   int i;
00037 
00038   if(p_context->credential.group == gid)
00039     return TRUE;
00040 
00041   for(i = 0; i < p_context->credential.nbgroups; i++)
00042     {
00043       if(p_context->credential.alt_groups[i] == gid)
00044         return TRUE;
00045     }
00046 
00047   return FALSE;
00048 }
00049 
00050 static fsal_boolean_t fsal_check_ace_matches(fsal_ace_t *pace,
00051                                              fsal_op_context_t *p_context,
00052                                              fsal_boolean_t is_owner,
00053                                              fsal_boolean_t is_group)
00054 {
00055   int matches = 0;
00056 
00057   if (IS_FSAL_ACE_SPECIAL_ID(*pace))
00058     switch(pace->who.uid)
00059       {
00060         case FSAL_ACE_SPECIAL_OWNER:
00061           if(is_owner)
00062             matches = 1;
00063         break;
00064 
00065         case FSAL_ACE_SPECIAL_GROUP:
00066           if(is_group)
00067             matches = 2;
00068         break;
00069 
00070         case FSAL_ACE_SPECIAL_EVERYONE:
00071           matches = 3;
00072         break;
00073 
00074         default:
00075         break;
00076       }
00077   else if (IS_FSAL_ACE_GROUP_ID(*pace))
00078     {
00079       if(fsal_check_ace_group(pace->who.gid, p_context))
00080         matches = 4;
00081     }
00082   else
00083     {
00084       if(fsal_check_ace_owner(pace->who.uid, p_context))
00085         matches = 5;
00086     }
00087 
00088   LogDebug(COMPONENT_FSAL,
00089            "fsal_check_ace_matches: matches %d flag 0x%X who %d",
00090            matches, pace->flag, GET_FSAL_ACE_WHO(*pace));
00091 
00092   return (matches != 0);
00093 }
00094 
00095 static fsal_boolean_t fsal_check_ace_applicable(fsal_ace_t *pace,
00096                                                 fsal_op_context_t *p_context,
00097                                                 fsal_boolean_t is_dir,
00098                                                 fsal_boolean_t is_owner,
00099                                                 fsal_boolean_t is_group)
00100 {
00101   fsal_boolean_t is_applicable = FALSE;
00102   fsal_boolean_t is_file = !is_dir;
00103 
00104   /* To be applicable, the entry should not be INHERIT_ONLY. */
00105   if (IS_FSAL_ACE_INHERIT_ONLY(*pace))
00106     {
00107       LogDebug(COMPONENT_FSAL, "fsal_check_ace_applicable: Not applicable, "
00108                "inherit only");
00109       return FALSE;
00110     }
00111 
00112   /* Use GPFS internal flag to further check the entry is applicable to this
00113    * object type. */
00114   if(is_file)
00115     {
00116       if(!IS_FSAL_FILE_APPLICABLE(*pace))
00117         {
00118           LogDebug(COMPONENT_FSAL, "fsal_check_ace_applicable: Not applicable to file");
00119           return FALSE;
00120         }
00121     }
00122   else  /* directory */
00123     {
00124       if(!IS_FSAL_DIR_APPLICABLE(*pace))
00125         {
00126           LogDebug(COMPONENT_FSAL, "fsal_check_ace_applicable: Not applicable to dir");
00127           return FALSE;
00128         }
00129     }
00130 
00131   /* The user should match who value. */
00132   is_applicable = fsal_check_ace_matches(pace, p_context, is_owner, is_group);
00133   if(is_applicable)
00134     LogDebug(COMPONENT_FSAL, "fsal_check_ace_applicable: Applicable, flag=0X%x",
00135              pace->flag);
00136   else
00137     LogDebug(COMPONENT_FSAL, "fsal_check_ace_applicable: Not applicable to given user");
00138 
00139   return is_applicable;
00140 }
00141 
00142 static void fsal_print_inherit_flags(fsal_ace_t *pace, char *p_buf)
00143 {
00144   if(!pace || !p_buf)
00145     return;
00146 
00147   memset(p_buf, 0, ACL_DEBUG_BUF_SIZE);
00148 
00149   sprintf(p_buf, "I(%c%c%c%c)",
00150           IS_FSAL_ACE_FILE_INHERIT(*pace)? 'f': '-',
00151           IS_FSAL_ACE_DIR_INHERIT(*pace) ? 'd': '-',
00152           IS_FSAL_ACE_INHERIT_ONLY(*pace)? 'o': '-',
00153           IS_FSAL_ACE_NO_PROPAGATE(*pace)? 'n': '-');
00154 }
00155 
00156 static void fsal_print_ace(int ace_number, fsal_ace_t *pace, char *p_acebuf)
00157 {
00158   char inherit_flags[ACL_DEBUG_BUF_SIZE];
00159 
00160   if(!pace || !p_acebuf)
00161     return;
00162 
00163   memset(p_acebuf, 0, ACL_DEBUG_BUF_SIZE);
00164   memset(inherit_flags, 0, ACL_DEBUG_BUF_SIZE);
00165 
00166   /* Get inherit flags if any. */
00167   fsal_print_inherit_flags(pace, inherit_flags);
00168 
00169   /* Print the entire ACE. */
00170   sprintf(p_acebuf, "ACE %d %s %s %d %c%c%c%c%c%c%c%c%c%c%c%c%c%c %s",
00171           ace_number,
00172           /* ACE type. */
00173           IS_FSAL_ACE_ALLOW(*pace)? "allow":
00174           IS_FSAL_ACE_DENY(*pace) ? "deny":
00175           IS_FSAL_ACE_AUDIT(*pace)? "audit": "?",
00176           /* ACE who and its type. */
00177           (IS_FSAL_ACE_SPECIAL_ID(*pace) && IS_FSAL_ACE_SPECIAL_OWNER(*pace))    ? "owner@":
00178           (IS_FSAL_ACE_SPECIAL_ID(*pace) && IS_FSAL_ACE_SPECIAL_GROUP(*pace))    ? "group@":
00179           (IS_FSAL_ACE_SPECIAL_ID(*pace) && IS_FSAL_ACE_SPECIAL_EVERYONE(*pace)) ? "everyone@":
00180           IS_FSAL_ACE_SPECIAL_ID(*pace)                                          ? "specialid":
00181           IS_FSAL_ACE_GROUP_ID(*pace)                                            ? "gid": "uid",
00182           GET_FSAL_ACE_WHO(*pace),
00183           /* ACE mask. */
00184           IS_FSAL_ACE_READ_DATA(*pace)           ? 'r':'-',
00185           IS_FSAL_ACE_WRITE_DATA(*pace)          ? 'w':'-',
00186           IS_FSAL_ACE_EXECUTE(*pace)             ? 'x':'-',
00187           IS_FSAL_ACE_ADD_SUBDIRECTORY(*pace)    ? 'm':'-',
00188           IS_FSAL_ACE_READ_NAMED_ATTR(*pace)     ? 'n':'-',
00189           IS_FSAL_ACE_WRITE_NAMED_ATTR(*pace)    ? 'N':'-',
00190           IS_FSAL_ACE_DELETE_CHILD(*pace)        ? 'p':'-',
00191           IS_FSAL_ACE_READ_ATTR(*pace)           ? 't':'-',
00192           IS_FSAL_ACE_WRITE_ATTR(*pace)          ? 'T':'-',
00193           IS_FSAL_ACE_DELETE(*pace)              ? 'd':'-',
00194           IS_FSAL_ACE_READ_ACL(*pace)            ? 'c':'-',
00195           IS_FSAL_ACE_WRITE_ACL(*pace)           ? 'C':'-',
00196           IS_FSAL_ACE_WRITE_OWNER(*pace)         ? 'o':'-',
00197           IS_FSAL_ACE_SYNCHRONIZE(*pace)         ? 'z':'-',
00198           /* ACE Inherit flags. */
00199           IS_FSAL_ACE_INHERIT(*pace)? inherit_flags: "");
00200 }
00201 
00202 static void fsal_print_access_by_acl(int naces, int ace_number,
00203                                      fsal_ace_t *pace, fsal_aceperm_t perm,
00204                                      unsigned int access_result,
00205                                      fsal_boolean_t is_dir,
00206                                      fsal_op_context_t *p_context)
00207 {
00208   char ace_data[ACL_DEBUG_BUF_SIZE];
00209   char access_data[2 * ACL_DEBUG_BUF_SIZE];
00210   fsal_uid_t user = p_context->credential.user;
00211   fsal_boolean_t is_last_ace = (naces == ace_number);
00212 
00213   if(!is_last_ace)
00214     fsal_print_ace(ace_number, pace, ace_data);
00215 
00216   /* Print the access result and the request. */
00217   sprintf(access_data, "%s: %s uid %d %s",
00218           (access_result == ERR_FSAL_NO_ERROR)                      ? "permit": "reject",
00219           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_READ_DATA)            ?"READ":
00220           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_WRITE_DATA) && is_dir ?"ADD_FILE":
00221           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_WRITE_DATA)           ?"WRITE":
00222           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_APPEND_DATA) && is_dir?"ADD_SUBDIR":
00223           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_APPEND_DATA)          ?"APPEND":
00224           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_READ_NAMED_ATTR)      ?"READ_NAMED":
00225           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_WRITE_NAMED_ATTR)     ?"WRITE_NAMED":
00226           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_EXECUTE)              ?"EXECUTE":
00227           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_DELETE_CHILD)         ?"DELETE_CHILD":
00228           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_READ_ATTR)            ?"READ_ATTR":
00229           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_WRITE_ATTR)           ?"WRITE_ATTR":
00230           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_DELETE)               ?"DELETE":
00231           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_READ_ACL)             ?"READ_ACL":
00232           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_WRITE_ACL)            ?"WRITE_ACL":
00233           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_WRITE_OWNER)          ?"WRITE_OWNER":
00234           IS_FSAL_ACE_BIT(perm, FSAL_ACE_PERM_SYNCHRONIZE)          ?"SYNCHRONIZE": "UNKNOWN",
00235           user, (!is_last_ace) ? ace_data: "");
00236 
00237   LogDebug(COMPONENT_FSAL, "fsal_check_access_by_acl_debug: %s", access_data);
00238 }
00239 
00240 static fsal_status_t fsal_check_access_acl(fsal_op_context_t * p_context,   /* IN */
00241                                                   fsal_aceperm_t v4mask,  /* IN */
00242                                                   fsal_attrib_list_t * p_object_attributes   /* IN */ )
00243 {
00244   fsal_aceperm_t missing_access;
00245   fsal_uid_t uid;
00246   fsal_gid_t gid;
00247   fsal_acl_t *pacl = NULL;
00248   fsal_ace_t *pace = NULL;
00249   int ace_number = 0;
00250   fsal_boolean_t is_dir = FALSE;
00251   fsal_boolean_t is_owner = FALSE;
00252   fsal_boolean_t is_group = FALSE;
00253 
00254   /* unsatisfied flags */
00255   missing_access = v4mask;
00256   if(!missing_access)
00257     {
00258       LogDebug(COMPONENT_FSAL, "fsal_check_access_acl: Nothing was requested");
00259       ReturnCode(ERR_FSAL_NO_ERROR, 0);
00260     }
00261 
00262   /* Get file ownership information. */
00263   uid = p_object_attributes->owner;
00264   gid = p_object_attributes->group;
00265   pacl = p_object_attributes->acl;
00266   is_dir = (p_object_attributes->type == FSAL_TYPE_DIR);
00267 
00268   LogDebug(COMPONENT_FSAL,
00269            "fsal_check_access_acl: file acl=%p, file uid=%d, file gid= %d",
00270            pacl,uid, gid);
00271   LogDebug(COMPONENT_FSAL,
00272            "fsal_check_access_acl: user uid=%d, user gid= %d, v4mask=0x%X",
00273            p_context->credential.user,
00274            p_context->credential.group,
00275            v4mask);
00276 
00277   is_owner = fsal_check_ace_owner(uid, p_context);
00278   is_group = fsal_check_ace_group(gid, p_context);
00279 
00280   /* Always grant READ_ACL, WRITE_ACL and READ_ATTR, WRITE_ATTR to the file
00281    * owner. */
00282   if(is_owner)
00283     {
00284       missing_access &= ~(FSAL_ACE_PERM_WRITE_ACL | FSAL_ACE_PERM_READ_ACL);
00285       missing_access &= ~(FSAL_ACE_PERM_WRITE_ATTR | FSAL_ACE_PERM_READ_ATTR);
00286       if(!missing_access)
00287         {
00288           LogDebug(COMPONENT_FSAL, "fsal_check_access_acl: Met owner privileges");
00289           ReturnCode(ERR_FSAL_NO_ERROR, 0);
00290         }
00291     }
00292 
00293   // TODO: Even if user is admin, audit/alarm checks should be done.
00294 
00295   ace_number = 1;
00296   for(pace = pacl->aces; pace < pacl->aces + pacl->naces; pace++)
00297     {
00298       LogDebug(COMPONENT_FSAL,
00299                "fsal_check_access_acl: ace type 0x%X perm 0x%X flag 0x%X who %d",
00300                pace->type, pace->perm, pace->flag, GET_FSAL_ACE_WHO(*pace));
00301 
00302       /* Process Allow and Deny entries. */
00303       if(IS_FSAL_ACE_ALLOW(*pace) || IS_FSAL_ACE_DENY(*pace))
00304         {
00305           LogDebug(COMPONENT_FSAL, "fsal_check_access_acl: allow or deny");
00306 
00307           /* Check if this ACE is applicable. */
00308           if(fsal_check_ace_applicable(pace, p_context, is_dir, is_owner, is_group))
00309             {
00310               if(IS_FSAL_ACE_ALLOW(*pace))
00311                 {
00312                   LogDebug(COMPONENT_FSAL,
00313                            "fsal_check_access_acl: allow perm 0x%X remainingPerms 0x%X",
00314                            pace->perm, missing_access);
00315 
00316                   missing_access &= ~(pace->perm & missing_access);
00317                   if(!missing_access)
00318                     {
00319                       LogDebug(COMPONENT_FSAL, "fsal_check_access_acl: access granted");
00320                       fsal_print_access_by_acl(pacl->naces, ace_number, pace,
00321                                                      v4mask, ERR_FSAL_NO_ERROR, is_dir, p_context);
00322                       ReturnCode(ERR_FSAL_NO_ERROR, 0);
00323                     }
00324                 }
00325              else if(pace->perm & missing_access)
00326                {
00327                  LogDebug(COMPONENT_FSAL, "fsal_check_access_acl: access denied");
00328                  fsal_print_access_by_acl(pacl->naces, ace_number, pace, v4mask,
00329                                                 ERR_FSAL_ACCESS, is_dir, p_context);
00330                  ReturnCode(ERR_FSAL_ACCESS, 0);
00331                }
00332             }
00333         }
00334 
00335         ace_number += 1;
00336     }
00337 
00338   if(missing_access)
00339     {
00340       LogDebug(COMPONENT_FSAL, "fsal_check_access_acl: access denied");
00341       ReturnCode(ERR_FSAL_ACCESS, 0);
00342     }
00343   else
00344     {
00345       LogDebug(COMPONENT_FSAL, "fsal_check_access_acl: access granted");
00346       ReturnCode(ERR_FSAL_NO_ERROR, 0);
00347     }
00348 
00349   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00350 }
00351 #endif                          /* _USE_NFS4_ACL */
00352 
00353 static fsal_status_t fsal_check_access_no_acl(fsal_op_context_t * p_context,   /* IN */
00354                                                      fsal_accessflags_t access_type,  /* IN */
00355                                                      struct stat *p_buffstat, /* IN */
00356                                                      fsal_attrib_list_t * p_object_attributes /* IN */ )
00357 {
00358   fsal_accessflags_t missing_access;
00359   unsigned int is_grp, i;
00360   fsal_uid_t uid;
00361   fsal_gid_t gid;
00362   fsal_accessmode_t mode;
00363 
00364   /* If the FSAL_F_OK flag is set, returns ERR INVAL */
00365 
00366   if(access_type & FSAL_F_OK)
00367     ReturnCode(ERR_FSAL_INVAL, 0);
00368 
00369   /* unsatisfied flags */
00370   missing_access = access_type;
00371   if(!missing_access)
00372     {
00373       LogDebug(COMPONENT_FSAL, "fsal_check_access_no_acl: Nothing was requested");
00374       ReturnCode(ERR_FSAL_NO_ERROR, 0);
00375     }
00376 
00377   if(p_object_attributes)
00378     {
00379       uid = p_object_attributes->owner;
00380       gid = p_object_attributes->group;
00381       mode = p_object_attributes->mode;
00382 
00383     }
00384   else
00385     {
00386       uid = p_buffstat->st_uid;
00387       gid = p_buffstat->st_gid;
00388       mode = unix2fsal_mode(p_buffstat->st_mode);
00389     }
00390 
00391   LogDebug(COMPONENT_FSAL,
00392                "fsal_check_access_no_acl: file Mode=%#o, file uid=%d, file gid= %d",
00393                mode,uid, gid);
00394 #ifdef _USE_HPSS
00395   LogDebug(COMPONENT_FSAL,
00396                "fsal_check_access_no_acl: user uid=%d, user gid= %d, access_type=0X%x",
00397                p_context->credential.hpss_usercred.Uid,
00398                p_context->credential.hpss_usercred.Gid,
00399                access_type);
00400 #else
00401   LogDebug(COMPONENT_FSAL,
00402                "fsal_check_access_no_acl: user uid=%d, user gid= %d, access_type=0X%x",
00403                p_context->credential.user,
00404                p_context->credential.group,
00405                access_type);
00406   /* If the uid of the file matches the uid of the user,
00407    * then the uid mode bits take precedence. */
00408   if(p_context->credential.user == uid)
00409 #endif
00410 
00411   /* If the uid of the file matches the uid of the user,
00412    * then the uid mode bits take precedence. */
00413 #ifdef _USE_HPSS
00414   if(p_context->credential.hpss_usercred.Uid == uid)
00415 #else
00416   if(p_context->credential.user == uid)
00417 #endif
00418     {
00419 
00420       LogDebug(COMPONENT_FSAL,
00421                    "fsal_check_access_no_acl: File belongs to user %d", uid);
00422 
00423       if(mode & FSAL_MODE_RUSR)
00424         missing_access &= ~FSAL_R_OK;
00425 
00426       if(mode & FSAL_MODE_WUSR)
00427         missing_access &= ~FSAL_W_OK;
00428 
00429       if(mode & FSAL_MODE_XUSR)
00430         missing_access &= ~FSAL_X_OK;
00431 
00432       /* handle the creation of a new 500 file correctly */
00433       if((missing_access & FSAL_OWNER_OK) != 0)
00434         missing_access = 0;
00435 
00436       if(missing_access == 0)
00437         ReturnCode(ERR_FSAL_NO_ERROR, 0);
00438       else
00439         {
00440           LogDebug(COMPONENT_FSAL,
00441                        "fsal_check_access_no_acl: Mode=%#o, Access=0X%x, Rights missing: 0X%x",
00442                        mode, access_type, missing_access);
00443           ReturnCode(ERR_FSAL_ACCESS, 0);
00444         }
00445 
00446     }
00447 
00448   /* missing_access will be nonzero triggering a failure
00449    * even though FSAL_OWNER_OK is not even a real posix file
00450    * permission */
00451   missing_access &= ~FSAL_OWNER_OK;
00452 
00453   /* Test if the file belongs to user's group. */
00454 #ifdef _USE_HPSS
00455   is_grp = (p_context->credential.hpss_usercred.Gid == gid);
00456   if(is_grp)
00457     LogDebug(COMPONENT_FSAL,
00458                  "fsal_check_access_no_acl: File belongs to user's group %d",
00459                  p_context->credential.hpss_usercred.Gid);
00460 
00461   /* Test if file belongs to alt user's groups */
00462   if(!is_grp)
00463     for(i = 0; i < p_context->credential.hpss_usercred.NumGroups; i++)
00464       {
00465         is_grp = (p_context->credential.hpss_usercred.AltGroups[i] == gid);
00466         if(is_grp)
00467           LogDebug(COMPONENT_FSAL,
00468                        "fsal_check_access_no_acl: File belongs to user's alt group %d",
00469                        p_context->credential.hpss_usercred.AltGroups[i]);
00470         if(is_grp)
00471           break;
00472       }
00473 #else
00474   is_grp = (p_context->credential.group == gid);
00475   if(is_grp)
00476     LogDebug(COMPONENT_FSAL,
00477                  "fsal_check_access_no_acl: File belongs to user's group %d",
00478                  p_context->credential.group);
00479 
00480   /* Test if file belongs to alt user's groups */
00481   if(!is_grp)
00482     for(i = 0; i < p_context->credential.nbgroups; i++)
00483       {
00484         is_grp = (p_context->credential.alt_groups[i] == gid);
00485         if(is_grp)
00486           LogDebug(COMPONENT_FSAL,
00487                        "fsal_check_access_no_acl: File belongs to user's alt group %d",
00488                        p_context->credential.alt_groups[i]);
00489         if(is_grp)
00490           break;
00491       }
00492 #endif
00493 
00494   /* If the gid of the file matches the gid of the user or
00495    * one of the alternatve gids of the user, then the uid mode
00496    * bits take precedence. */
00497   if(is_grp)
00498     {
00499       if(mode & FSAL_MODE_RGRP)
00500         missing_access &= ~FSAL_R_OK;
00501 
00502       if(mode & FSAL_MODE_WGRP)
00503         missing_access &= ~FSAL_W_OK;
00504 
00505       if(mode & FSAL_MODE_XGRP)
00506         missing_access &= ~FSAL_X_OK;
00507 
00508       if(missing_access == 0)
00509         ReturnCode(ERR_FSAL_NO_ERROR, 0);
00510       else
00511         ReturnCode(ERR_FSAL_ACCESS, 0);
00512 
00513     }
00514 
00515   /* If the user uid is not 0, the uid does not match the file's, and
00516    * the user's gids do not match the file's gid, we apply the "other"
00517    * mode bits to the user. */
00518   if(mode & FSAL_MODE_ROTH)
00519     missing_access &= ~FSAL_R_OK;
00520 
00521   if(mode & FSAL_MODE_WOTH)
00522     missing_access &= ~FSAL_W_OK;
00523 
00524   if(mode & FSAL_MODE_XOTH)
00525     missing_access &= ~FSAL_X_OK;
00526 
00527   if(missing_access == 0)
00528     ReturnCode(ERR_FSAL_NO_ERROR, 0);
00529   else {
00530     LogDebug(COMPONENT_FSAL,
00531                  "fsal_check_access_no_acl: Mode=%#o, Access=0X%x, Rights missing: 0X%x",
00532                  mode, access_type, missing_access);
00533     ReturnCode(ERR_FSAL_ACCESS, 0);
00534   }
00535 
00536 }
00537 
00538 /* fsal_check_access
00539  * Check the access by using NFS4 ACL if it exists. Otherwise, use mode.
00540  */
00541 
00542 fsal_status_t fsal_check_access(fsal_op_context_t * p_context,   /* IN */
00543                                 fsal_accessflags_t access_type,  /* IN */
00544                                 struct stat *p_buffstat, /* IN */
00545                                 fsal_attrib_list_t * p_object_attributes /* IN */ )
00546 {
00547   /* sanity checks. */
00548   if((!p_object_attributes && !p_buffstat) || !p_context)
00549     ReturnCode(ERR_FSAL_FAULT, 0);
00550 
00551   /* The root user ignores the mode/uid/gid of the file */
00552 #ifdef _USE_HPSS
00553   if(p_context->credential.hpss_usercred.Uid == 0)
00554     ReturnCode(ERR_FSAL_NO_ERROR, 0);
00555 #else
00556   if(p_context->credential.user == 0)
00557     ReturnCode(ERR_FSAL_NO_ERROR, 0);
00558 #endif
00559 
00560 #ifdef _USE_NFS4_ACL
00561   /* If ACL exists and given access type is ace4 mask, use ACL to check access. */
00562   LogDebug(COMPONENT_FSAL, "fsal_check_access: pattr=%p, pacl=%p, is_ace4_mask=%d",
00563            p_object_attributes, p_object_attributes ? p_object_attributes->acl : 0,
00564            IS_FSAL_ACE4_MASK_VALID(access_type));
00565 
00566   if(p_object_attributes && p_object_attributes->acl &&
00567      IS_FSAL_ACE4_MASK_VALID(access_type))
00568     {
00569       return fsal_check_access_acl(p_context, FSAL_ACE4_MASK(access_type),
00570                                           p_object_attributes);
00571     }
00572 #endif
00573 
00574   /* Use mode to check access. */
00575   return fsal_check_access_no_acl(p_context, FSAL_MODE_MASK(access_type),
00576                                            p_buffstat, p_object_attributes);
00577 
00578   LogDebug(COMPONENT_FSAL, "fsal_check_access: invalid access_type = 0X%x",
00579            access_type);
00580 
00581   ReturnCode(ERR_FSAL_ACCESS, 0);
00582 }