nfs-ganesha 1.4

fsal_access.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 
00014 #ifdef HAVE_CONFIG_H
00015 #include "config.h"
00016 #endif
00017 
00018 #include "fsal.h"
00019 #include "fsal_internal.h"
00020 #include "fsal_convert.h"
00021 #include "namespace.h"
00022 
00057 fsal_status_t FUSEFSAL_access(fsal_handle_t * obj_handle,        /* IN */
00058                               fsal_op_context_t * p_context,        /* IN */
00059                               fsal_accessflags_t access_type,   /* IN */
00060                               fsal_attrib_list_t * object_attributes    /* [ IN/OUT ] */
00061     )
00062 {
00063 
00064   int mask, rc;
00065   char object_path[FSAL_MAX_PATH_LEN];
00066   fsal_attrib_list_t tmp_attrs;
00067   fusefsal_handle_t * object_handle = (fusefsal_handle_t *)obj_handle;
00068 
00069   /* sanity checks.
00070    * note : object_attributes is optional in FSAL_access.
00071    */
00072   if(!object_handle || !p_context)
00073     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_access);
00074 
00075   /* convert fsal access mask to FUSE access mask */
00076   mask = fsal2posix_testperm(access_type);
00077 
00078   /* get the full path for the object */
00079   rc = NamespacePath(object_handle->data.inode, object_handle->data.device,
00080                      object_handle->data.validator, object_path);
00081 
00082   if(rc)
00083     Return(ERR_FSAL_STALE, rc, INDEX_FSAL_access);
00084 
00085   /* set context for the next operation, so it can be retrieved by FS thread */
00086   fsal_set_thread_context(p_context);
00087 
00088   if(p_fs_ops->access)
00089     {
00090 
00091       TakeTokenFSCall();
00092 
00093       rc = p_fs_ops->access(object_path, mask);
00094 
00095       ReleaseTokenFSCall();
00096 
00097       /* TODO : remove entry from namespace if entry is stale */
00098       if(rc)
00099         Return(fuse2fsal_error(rc, TRUE), rc, INDEX_FSAL_access);
00100     }
00101   else if(p_fs_ops->getattr)
00102     {
00103       /* we emulate 'access' call using getattr + fsal_test_access
00104        * from attributes value (mode, owner, group, ...)
00105        */
00106       fsal_status_t status;
00107 
00108       FSAL_CLEAR_MASK(tmp_attrs.asked_attributes);
00109       FSAL_SET_MASK(tmp_attrs.asked_attributes, FSAL_ATTR_TYPE);
00110       FSAL_SET_MASK(tmp_attrs.asked_attributes, FSAL_ATTR_MODE);
00111       FSAL_SET_MASK(tmp_attrs.asked_attributes, FSAL_ATTR_OWNER);
00112       FSAL_SET_MASK(tmp_attrs.asked_attributes, FSAL_ATTR_GROUP);
00113 
00114       status = FUSEFSAL_getattrs(obj_handle, p_context, &tmp_attrs);
00115 
00116       if(FSAL_IS_ERROR(status))
00117         Return(status.major, status.minor, INDEX_FSAL_access);
00118 
00119       status = FUSEFSAL_test_access(p_context, access_type, &tmp_attrs);
00120 
00121       if(FSAL_IS_ERROR(status))
00122         Return(status.major, status.minor, INDEX_FSAL_access);
00123 
00124     }
00125   /* else : always grant access */
00126 
00127   /* get attributes if object_attributes is not null.
00128    * If an error occures during getattr operation,
00129    * an error bit is set in the output structure.
00130    */
00131   if(object_attributes)
00132     {
00133       fsal_status_t status;
00134 
00135       status = FUSEFSAL_getattrs(obj_handle, p_context, object_attributes);
00136 
00137       /* on error, we set a special bit in the mask. */
00138       if(FSAL_IS_ERROR(status))
00139         {
00140           FSAL_CLEAR_MASK(object_attributes->asked_attributes);
00141           FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00142         }
00143     }
00144 
00145   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_access);
00146 
00147 }
00148 
00181 fsal_status_t FUSEFSAL_test_access(fsal_op_context_t * p_context,   /* IN */
00182                                    fsal_accessflags_t access_type,      /* IN */
00183                                    fsal_attrib_list_t * object_attributes       /* IN */
00184     )
00185 {
00186   fsal_accessflags_t missing_access;
00187   int is_grp;
00188 
00189   /* sanity checks. */
00190 
00191   if(!object_attributes || !p_context)
00192     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_test_access);
00193 
00194   /* If the FSAL_F_OK flag is set, returns ERR INVAL */
00195 
00196   if(access_type & FSAL_F_OK)
00197     Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_test_access);
00198 
00199   LogFullDebug(COMPONENT_FSAL, "test_access: mode=%#o, user=%d, owner=%u",
00200                object_attributes->mode, p_context->credential.user,
00201                object_attributes->owner);
00202 
00203   /* test root access */
00204 
00205   if(p_context->credential.user == 0)
00206     Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_test_access);
00207 
00208   /* unsatisfied permissions */
00209 
00210   missing_access = FSAL_MODE_MASK(access_type); /* only modes, no ACLs here */
00211 
00212   /* Test if file belongs to user. */
00213 
00214   if(p_context->credential.user == object_attributes->owner)
00215     {
00216 
00217       if(object_attributes->mode & FSAL_MODE_RUSR)
00218         missing_access &= ~FSAL_R_OK;
00219 
00220       if(object_attributes->mode & FSAL_MODE_WUSR)
00221         missing_access &= ~FSAL_W_OK;
00222 
00223       if(object_attributes->mode & FSAL_MODE_XUSR)
00224         missing_access &= ~FSAL_X_OK;
00225 
00226       if(missing_access == 0)
00227         Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_test_access);
00228       else
00229         Return(ERR_FSAL_ACCESS, 0, INDEX_FSAL_test_access);
00230 
00231     }
00232 
00233   /* Test if the file belongs to user's group. */
00234 
00235   is_grp = (p_context->credential.group == object_attributes->group);
00236 
00237   /* XXX Test here if file belongs to user's alt groups */
00238 
00239   /* finally apply group rights */
00240 
00241   if(is_grp)
00242     {
00243       if(object_attributes->mode & FSAL_MODE_RGRP)
00244         missing_access &= ~FSAL_R_OK;
00245 
00246       if(object_attributes->mode & FSAL_MODE_WGRP)
00247         missing_access &= ~FSAL_W_OK;
00248 
00249       if(object_attributes->mode & FSAL_MODE_XGRP)
00250         missing_access &= ~FSAL_X_OK;
00251 
00252       if(missing_access == 0)
00253         Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_test_access);
00254       else
00255         Return(ERR_FSAL_ACCESS, 0, INDEX_FSAL_test_access);
00256 
00257     }
00258 
00259   /* test other perms */
00260 
00261   if(object_attributes->mode & FSAL_MODE_ROTH)
00262     missing_access &= ~FSAL_R_OK;
00263 
00264   if(object_attributes->mode & FSAL_MODE_WOTH)
00265     missing_access &= ~FSAL_W_OK;
00266 
00267   if(object_attributes->mode & FSAL_MODE_XOTH)
00268     missing_access &= ~FSAL_X_OK;
00269 
00272   if(missing_access == 0)
00273     Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_test_access);
00274   else
00275     Return(ERR_FSAL_ACCESS, 0, INDEX_FSAL_test_access);
00276 
00277 }