nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=4:tabstop=4: 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 <unistd.h> 00022 #include <fcntl.h> 00023 #include <sys/fsuid.h> 00024 00053 fsal_status_t GPFSFSAL_create(fsal_handle_t * p_parent_directory_handle, /* IN */ 00054 fsal_name_t * p_filename, /* IN */ 00055 fsal_op_context_t * p_context, /* IN */ 00056 fsal_accessmode_t accessmode, /* IN */ 00057 fsal_handle_t * p_object_handle, /* OUT */ 00058 fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ 00059 ) 00060 { 00061 00062 int fsuid, fsgid; 00063 fsal_status_t status; 00064 00065 mode_t unix_mode; 00066 fsal_accessflags_t access_mask = 0; 00067 fsal_attrib_list_t parent_dir_attrs; 00068 00069 /* sanity checks. 00070 * note : object_attributes is optional. 00071 */ 00072 if(!p_parent_directory_handle || !p_context || !p_object_handle || !p_filename) 00073 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create); 00074 00075 /* convert fsal mode to unix mode. */ 00076 unix_mode = fsal2unix_mode(accessmode); 00077 00078 /* Apply umask */ 00079 unix_mode = unix_mode & ~global_fs_info.umask; 00080 00081 LogFullDebug(COMPONENT_FSAL, "Creation mode: 0%o", accessmode); 00082 00083 /* retrieve directory metadata */ 00084 parent_dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES; 00085 status = GPFSFSAL_getattrs(p_parent_directory_handle, p_context, &parent_dir_attrs); 00086 if(FSAL_IS_ERROR(status)) 00087 ReturnStatus(status, INDEX_FSAL_create); 00088 00089 /* Check the user can write in the directory */ 00090 00091 /* Set both mode and ace4 mask */ 00092 access_mask = FSAL_MODE_MASK_SET(FSAL_W_OK | FSAL_X_OK) | 00093 FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_ADD_FILE); 00094 00095 if(!p_context->export_context->fe_static_fs_info->accesscheck_support) 00096 status = fsal_internal_testAccess(p_context, access_mask, NULL, &parent_dir_attrs); 00097 else 00098 status = fsal_internal_access(p_context, p_parent_directory_handle, access_mask, 00099 &parent_dir_attrs); 00100 if(FSAL_IS_ERROR(status)) 00101 ReturnStatus(status, INDEX_FSAL_create); 00102 00103 /* call to filesystem */ 00104 00105 fsuid = setfsuid(p_context->credential.user); 00106 fsgid = setfsgid(p_context->credential.group); 00107 TakeTokenFSCall(); 00108 status = fsal_internal_create(p_context, p_parent_directory_handle, 00109 p_filename, unix_mode | S_IFREG, 0, 00110 p_object_handle, NULL); 00111 ReleaseTokenFSCall(); 00112 setfsuid(fsuid); 00113 setfsgid(fsgid); 00114 if(FSAL_IS_ERROR(status)) 00115 ReturnStatus(status, INDEX_FSAL_create); 00116 00117 /* retrieve file attributes */ 00118 if(p_object_attributes) 00119 { 00120 status = GPFSFSAL_getattrs(p_object_handle, p_context, p_object_attributes); 00121 00122 /* on error, we set a special bit in the mask. */ 00123 if(FSAL_IS_ERROR(status)) 00124 { 00125 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00126 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00127 } 00128 00129 } 00130 00131 /* OK */ 00132 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_create); 00133 00134 } 00135 00165 fsal_status_t GPFSFSAL_mkdir(fsal_handle_t * p_parent_directory_handle, /* IN */ 00166 fsal_name_t * p_dirname, /* IN */ 00167 fsal_op_context_t * p_context, /* IN */ 00168 fsal_accessmode_t accessmode, /* IN */ 00169 fsal_handle_t * p_object_handle, /* OUT */ 00170 fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ 00171 ) 00172 { 00173 /* int setgid_bit = 0; */ 00174 mode_t unix_mode; 00175 fsal_status_t status; 00176 fsal_accessflags_t access_mask = 0; 00177 fsal_attrib_list_t parent_dir_attrs; 00178 int fsuid, fsgid; 00179 00180 /* sanity checks. 00181 * note : object_attributes is optional. 00182 */ 00183 if(!p_parent_directory_handle || !p_context || !p_object_handle || !p_dirname) 00184 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mkdir); 00185 00186 /* convert FSAL mode to unix mode. */ 00187 unix_mode = fsal2unix_mode(accessmode); 00188 00189 /* Apply umask */ 00190 unix_mode = unix_mode & ~global_fs_info.umask; 00191 00192 /* get directory metadata */ 00193 parent_dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES; 00194 status = GPFSFSAL_getattrs(p_parent_directory_handle, p_context, &parent_dir_attrs); 00195 if(FSAL_IS_ERROR(status)) 00196 ReturnStatus(status, INDEX_FSAL_mkdir); 00197 00198 /* Check the user can write in the directory, and check the setgid bit on the directory */ 00199 00200 /* if(fsal2unix_mode(parent_dir_attrs.mode) & S_ISGID) */ 00201 /* setgid_bit = 1; */ 00202 00203 /* Set both mode and ace4 mask */ 00204 access_mask = FSAL_MODE_MASK_SET(FSAL_W_OK | FSAL_X_OK) | 00205 FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_ADD_SUBDIRECTORY); 00206 00207 if(!p_context->export_context->fe_static_fs_info->accesscheck_support) 00208 status = fsal_internal_testAccess(p_context, access_mask, NULL, &parent_dir_attrs); 00209 else 00210 status = fsal_internal_access(p_context, p_parent_directory_handle, access_mask, 00211 &parent_dir_attrs); 00212 if(FSAL_IS_ERROR(status)) 00213 ReturnStatus(status, INDEX_FSAL_mkdir); 00214 00215 /* build new entry path */ 00216 00217 /* creates the directory and get its handle */ 00218 00219 fsuid = setfsuid(p_context->credential.user); 00220 fsgid = setfsgid(p_context->credential.group); 00221 00222 TakeTokenFSCall(); 00223 status = fsal_internal_create(p_context, p_parent_directory_handle, 00224 p_dirname, unix_mode | S_IFDIR, 0, 00225 p_object_handle, NULL); 00226 ReleaseTokenFSCall(); 00227 setfsuid(fsuid); 00228 setfsgid(fsgid); 00229 00230 if(FSAL_IS_ERROR(status)) 00231 ReturnStatus(status, INDEX_FSAL_mkdir); 00232 00233 /* retrieve file attributes */ 00234 if(p_object_attributes) 00235 { 00236 status = GPFSFSAL_getattrs(p_object_handle, p_context, p_object_attributes); 00237 00238 /* on error, we set a special bit in the mask. */ 00239 if(FSAL_IS_ERROR(status)) 00240 { 00241 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00242 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00243 } 00244 00245 } 00246 00247 /* OK */ 00248 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_mkdir); 00249 00250 } 00251 00281 fsal_status_t GPFSFSAL_link(fsal_handle_t * p_target_handle, /* IN */ 00282 fsal_handle_t * p_dir_handle, /* IN */ 00283 fsal_name_t * p_link_name, /* IN */ 00284 fsal_op_context_t * p_context, /* IN */ 00285 fsal_attrib_list_t * p_attributes /* [ IN/OUT ] */ 00286 ) 00287 { 00288 fsal_status_t status; 00289 fsal_accessflags_t access_mask = 0; 00290 fsal_attrib_list_t parent_dir_attrs; 00291 00292 /* sanity checks. 00293 * note : attributes is optional. 00294 */ 00295 if(!p_target_handle || !p_dir_handle || !p_context || !p_context->export_context 00296 || !p_link_name || !p_link_name->name) 00297 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link); 00298 00299 /* Tests if hardlinking is allowed by configuration. */ 00300 00301 if(!global_fs_info.link_support) 00302 Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_link); 00303 00304 /* retrieve target directory metadata */ 00305 parent_dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES; 00306 status = GPFSFSAL_getattrs(p_dir_handle, p_context, &parent_dir_attrs); 00307 if(FSAL_IS_ERROR(status)) 00308 goto out_status_fsal_err; 00309 00310 /* check permission on target directory */ 00311 00312 /* Set both mode and ace4 mask */ 00313 access_mask = FSAL_MODE_MASK_SET(FSAL_W_OK | FSAL_X_OK) | 00314 FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_ADD_FILE); 00315 00316 if(!p_context->export_context->fe_static_fs_info->accesscheck_support) 00317 status = fsal_internal_testAccess(p_context, access_mask, NULL, &parent_dir_attrs); 00318 else 00319 status = fsal_internal_access(p_context, p_dir_handle, access_mask, 00320 &parent_dir_attrs); 00321 if(FSAL_IS_ERROR(status)) 00322 goto out_status_fsal_err; 00323 00324 /* Create the link on the filesystem */ 00325 00326 TakeTokenFSCall(); 00327 status = fsal_internal_link_fh(p_context, p_target_handle, p_dir_handle, 00328 p_link_name); 00329 ReleaseTokenFSCall(); 00330 00331 if(FSAL_IS_ERROR(status)) 00332 goto out_status_fsal_err; 00333 00334 /* optionnaly get attributes */ 00335 00336 if(p_attributes) 00337 { 00338 status = GPFSFSAL_getattrs(p_target_handle, p_context, p_attributes); 00339 00340 /* on error, we set a special bit in the mask. */ 00341 if(FSAL_IS_ERROR(status)) 00342 { 00343 FSAL_CLEAR_MASK(p_attributes->asked_attributes); 00344 FSAL_SET_MASK(p_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00345 } 00346 } 00347 00348 /* OK */ 00349 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_link); 00350 00351 out_status_fsal_err: 00352 00353 ReturnStatus(status, INDEX_FSAL_link); 00354 } 00355 00363 fsal_status_t GPFSFSAL_mknode(fsal_handle_t * parentdir_handle, /* IN */ 00364 fsal_name_t * p_node_name, /* IN */ 00365 fsal_op_context_t * p_context, /* IN */ 00366 fsal_accessmode_t accessmode, /* IN */ 00367 fsal_nodetype_t nodetype, /* IN */ 00368 fsal_dev_t * dev, /* IN */ 00369 fsal_handle_t * p_object_handle, /* OUT (handle to the created node) */ 00370 fsal_attrib_list_t * node_attributes /* [ IN/OUT ] */ 00371 ) 00372 { 00373 fsal_status_t status; 00374 /* int flags=(O_RDONLY|O_NOFOLLOW); */ 00375 int fsuid, fsgid; 00376 00377 mode_t unix_mode = 0; 00378 dev_t unix_dev = 0; 00379 fsal_accessflags_t access_mask = 0; 00380 fsal_attrib_list_t parent_dir_attrs; 00381 00382 /* sanity checks. 00383 * note : link_attributes is optional. 00384 */ 00385 if(!parentdir_handle || !p_context || !p_node_name) 00386 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mknode); 00387 00388 unix_mode = fsal2unix_mode(accessmode); 00389 00390 /* Apply umask */ 00391 unix_mode = unix_mode & ~global_fs_info.umask; 00392 00393 switch (nodetype) 00394 { 00395 case FSAL_TYPE_BLK: 00396 if(!dev) 00397 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mknode); 00398 unix_mode |= S_IFBLK; 00399 unix_dev = (dev->major << 8) | (dev->minor & 0xFF); 00400 break; 00401 00402 case FSAL_TYPE_CHR: 00403 if(!dev) 00404 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mknode); 00405 unix_mode |= S_IFCHR; 00406 unix_dev = (dev->major << 8) | (dev->minor & 0xFF); 00407 break; 00408 00409 case FSAL_TYPE_SOCK: 00410 unix_mode |= S_IFSOCK; 00411 break; 00412 00413 case FSAL_TYPE_FIFO: 00414 unix_mode |= S_IFIFO; 00415 /* flags = (O_RDONLY | O_NOFOLLOW | O_NONBLOCK); */ 00416 break; 00417 00418 default: 00419 LogMajor(COMPONENT_FSAL, 00420 "Invalid node type in FSAL_mknode: %d", nodetype); 00421 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_mknode); 00422 } 00423 00424 /* retrieve directory attributes */ 00425 parent_dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES; 00426 status = GPFSFSAL_getattrs(parentdir_handle, p_context, &parent_dir_attrs); 00427 if(FSAL_IS_ERROR(status)) 00428 ReturnStatus(status, INDEX_FSAL_mknode); 00429 00430 /* Check the user can write in the directory */ 00431 00432 /* Set both mode and ace4 mask */ 00433 access_mask = FSAL_MODE_MASK_SET(FSAL_W_OK | FSAL_X_OK) | 00434 FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_ADD_FILE); 00435 00436 if(!p_context->export_context->fe_static_fs_info->accesscheck_support) 00437 status = fsal_internal_testAccess(p_context, access_mask, NULL, &parent_dir_attrs); 00438 else 00439 status = fsal_internal_access(p_context, parentdir_handle, access_mask, 00440 &parent_dir_attrs); 00441 if(FSAL_IS_ERROR(status)) 00442 ReturnStatus(status, INDEX_FSAL_mknode); 00443 00444 fsuid = setfsuid(p_context->credential.user); 00445 fsgid = setfsgid(p_context->credential.group); 00446 00447 TakeTokenFSCall(); 00448 status = fsal_internal_create(p_context, parentdir_handle, 00449 p_node_name, unix_mode, unix_dev, 00450 p_object_handle, NULL); 00451 ReleaseTokenFSCall(); 00452 00453 setfsuid(fsuid); 00454 setfsgid(fsgid); 00455 00456 if(FSAL_IS_ERROR(status)) 00457 ReturnStatus(status, INDEX_FSAL_mknode); 00458 00459 /* Fills the attributes if needed */ 00460 if(node_attributes) 00461 { 00462 00463 status = GPFSFSAL_getattrs(p_object_handle, p_context, node_attributes); 00464 00465 /* on error, we set a special bit in the mask. */ 00466 00467 if(FSAL_IS_ERROR(status)) 00468 { 00469 FSAL_CLEAR_MASK(node_attributes->asked_attributes); 00470 FSAL_SET_MASK(node_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00471 } 00472 00473 } 00474 00475 /* Finished */ 00476 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_mknode); 00477 00478 }