nfs-ganesha 1.4
|
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 }