00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022 #include "nfs4_acls.h"
00023
00024 #undef DBGC_CLASS
00025 #define DBGC_CLASS DBGC_VFS
00026
00027 #define AIXACL2_MODULE_NAME "aixacl2"
00028
00029 extern struct current_user current_user;
00030 extern int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid);
00031 extern BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp,
00032 uint32 security_info_sent, SEC_DESC *psd);
00033
00034 extern SMB_ACL_T aixacl_to_smbacl( struct acl *file_acl);
00035 extern struct acl *aixacl_smb_to_aixacl(SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
00036
00037 typedef union aixjfs2_acl_t {
00038 nfs4_acl_int_t jfs2_acl[1];
00039 aixc_acl_t aixc_acl[1];
00040 }AIXJFS2_ACL_T;
00041
00042 static int32_t aixacl2_getlen(AIXJFS2_ACL_T *acl, acl_type_t *type)
00043 {
00044 int32_t len;
00045
00046 if(type->u64 == ACL_NFS4) {
00047 len = acl->jfs2_acl[0].aclLength;
00048 }
00049 else {
00050 if(type->u64 == ACL_AIXC) {
00051 len = acl->aixc_acl[0].acl_len;
00052 } else {
00053 DEBUG(0,("aixacl2_getlen:unknown type:%d\n",type->u64));
00054 return False;
00055 }
00056 }
00057 DEBUG(10,("aixacl2_getlen:%d\n",len));
00058 return len;
00059 }
00060
00061 static AIXJFS2_ACL_T *aixjfs2_getacl_alloc(const char *fname, acl_type_t *type)
00062 {
00063 AIXJFS2_ACL_T *acl;
00064 size_t len = 200;
00065 mode_t mode;
00066 int ret;
00067 uint64_t ctl_flag=0;
00068 TALLOC_CTX *mem_ctx;
00069
00070 mem_ctx = main_loop_talloc_get();
00071 acl = (AIXJFS2_ACL_T *)TALLOC_SIZE(mem_ctx, len);
00072 if (acl == NULL) {
00073 errno = ENOMEM;
00074 return NULL;
00075 }
00076
00077 if(type->u64 == ACL_ANY) {
00078 ctl_flag = ctl_flag | GET_ACLINFO_ONLY;
00079 }
00080
00081 ret = aclx_get((char *)fname, ctl_flag, type, acl, &len, &mode);
00082 if ((ret != 0) && (errno == ENOSPC)) {
00083 len = aixacl2_getlen(acl, type) + sizeof(AIXJFS2_ACL_T);
00084 DEBUG(10,("aixjfs2_getacl_alloc - acl_len:%d\n",len));
00085
00086 acl = (AIXJFS2_ACL_T *)TALLOC_SIZE(mem_ctx, len);
00087 if (acl == NULL) {
00088 errno = ENOMEM;
00089 return NULL;
00090 }
00091
00092 ret = aclx_get((char *)fname, ctl_flag, type, acl, &len, &mode);
00093 }
00094 if (ret != 0) {
00095 DEBUG(8, ("aclx_get failed with %s\n", strerror(errno)));
00096 return NULL;
00097 }
00098
00099 return acl;
00100 }
00101
00102 static BOOL aixjfs2_get_nfs4_acl(files_struct *fsp,
00103 SMB4ACL_T **ppacl, BOOL *pretryPosix)
00104 {
00105 int32_t i;
00106
00107 AIXJFS2_ACL_T *pacl = NULL;
00108 nfs4_acl_int_t *jfs2_acl = NULL;
00109 nfs4_ace_int_t *jfs2_ace = NULL;
00110 acl_type_t type;
00111
00112 DEBUG(10,("jfs2 get_nt_acl invoked for %s\n", fsp->fsp_name));
00113
00114 memset(&type, 0, sizeof(acl_type_t));
00115 type.u64 = ACL_NFS4;
00116
00117 pacl = aixjfs2_getacl_alloc(fsp->fsp_name, &type);
00118 if (pacl == NULL) {
00119 DEBUG(9, ("aixjfs2_getacl_alloc failed for %s with %s\n",
00120 fsp->fsp_name, strerror(errno)));
00121 if (errno==ENOSYS)
00122 *pretryPosix = True;
00123 return False;
00124 }
00125
00126 jfs2_acl = &pacl->jfs2_acl[0];
00127 DEBUG(10, ("len: %d, version: %d, nace: %d, type: 0x%x\n",
00128 jfs2_acl->aclLength, jfs2_acl->aclVersion, jfs2_acl->aclEntryN, type.u64));
00129
00130 *ppacl = smb_create_smb4acl();
00131 if (*ppacl==NULL)
00132 return False;
00133
00134 jfs2_ace = &jfs2_acl->aclEntry[0];
00135 for (i=0; i<jfs2_acl->aclEntryN; i++) {
00136 SMB_ACE4PROP_T aceprop;
00137
00138 DEBUG(10, ("type: %d, iflags: %x, flags: %x, mask: %x, "
00139 "who: %d, aclLen: %d\n", jfs2_ace->aceType, jfs2_ace->flags,
00140 jfs2_ace->aceFlags, jfs2_ace->aceMask, jfs2_ace->aceWho.id, jfs2_ace->entryLen));
00141
00142 aceprop.aceType = jfs2_ace->aceType;
00143 aceprop.aceFlags = jfs2_ace->aceFlags;
00144 aceprop.aceMask = jfs2_ace->aceMask;
00145 aceprop.flags = (jfs2_ace->flags&ACE4_ID_SPECIAL) ? SMB_ACE4_ID_SPECIAL : 0;
00146
00147
00148 aceprop.who.id = jfs2_ace->aceWho.id;
00149
00150 if (smb_add_ace4(*ppacl, &aceprop)==NULL)
00151 return False;
00152
00153
00154 jfs2_ace = (nfs4_ace_int_t *)(((char *)jfs2_ace) + jfs2_ace->entryLen);
00155 }
00156
00157 DEBUG(10,("jfs2 get_nt_acl finished successfully\n"));
00158
00159 return True;
00160 }
00161
00162 static size_t aixjfs2_get_nt_acl_common(files_struct *fsp,
00163 uint32 security_info, SEC_DESC **ppdesc)
00164 {
00165 SMB4ACL_T *pacl = NULL;
00166 BOOL result;
00167 BOOL retryPosix = False;
00168
00169 *ppdesc = NULL;
00170 result = aixjfs2_get_nfs4_acl(fsp, &pacl, &retryPosix);
00171 if (retryPosix)
00172 {
00173 DEBUG(10, ("retrying with posix acl...\n"));
00174 return get_nt_acl(fsp, security_info, ppdesc);
00175 }
00176 if (result==False)
00177 return 0;
00178
00179 return smb_get_nt_acl_nfs4(fsp, security_info, ppdesc, pacl);
00180 }
00181
00182 size_t aixjfs2_fget_nt_acl(vfs_handle_struct *handle,
00183 files_struct *fsp, int fd, uint32 security_info,
00184 SEC_DESC **ppdesc)
00185 {
00186 return aixjfs2_get_nt_acl_common(fsp, security_info, ppdesc);
00187 }
00188
00189 size_t aixjfs2_get_nt_acl(vfs_handle_struct *handle,
00190 files_struct *fsp, const char *name,
00191 uint32 security_info, SEC_DESC **ppdesc)
00192 {
00193 return aixjfs2_get_nt_acl_common(fsp, security_info, ppdesc);
00194 }
00195
00196 static SMB_ACL_T aixjfs2_get_posix_acl(const char *path, acl_type_t type)
00197 {
00198 aixc_acl_t *pacl;
00199 AIXJFS2_ACL_T *acl;
00200 SMB_ACL_T result = NULL;
00201 int ret;
00202
00203 acl = aixjfs2_getacl_alloc(path, &type);
00204
00205 if (acl == NULL) {
00206 DEBUG(10, ("aixjfs2_getacl failed for %s with %s\n",
00207 path, strerror(errno)));
00208 if (errno == 0) {
00209 errno = EINVAL;
00210 }
00211 goto done;
00212 }
00213
00214 pacl = &acl->aixc_acl[0];
00215 DEBUG(10, ("len: %d, mode: %d\n",
00216 pacl->acl_len, pacl->acl_mode));
00217
00218 result = aixacl_to_smbacl(pacl);
00219 if (result == NULL) {
00220 goto done;
00221 }
00222
00223 done:
00224 if (errno != 0) {
00225 SAFE_FREE(result);
00226 }
00227 return result;
00228 }
00229
00230 SMB_ACL_T aixjfs2_sys_acl_get_file(vfs_handle_struct *handle,
00231 const char *path_p,
00232 SMB_ACL_TYPE_T type)
00233 {
00234 acl_type_t aixjfs2_type;
00235
00236 switch(type) {
00237 case SMB_ACL_TYPE_ACCESS:
00238 aixjfs2_type.u64 = ACL_AIXC;
00239 break;
00240 case SMB_ACL_TYPE_DEFAULT:
00241 DEBUG(0, ("Got AIX JFS2 unsupported type: %d\n", type));
00242 return NULL;
00243 default:
00244 DEBUG(0, ("Got invalid type: %d\n", type));
00245 smb_panic("exiting");
00246 }
00247
00248 return aixjfs2_get_posix_acl(path_p, aixjfs2_type);
00249 }
00250
00251 SMB_ACL_T aixjfs2_sys_acl_get_fd(vfs_handle_struct *handle,
00252 files_struct *fsp,
00253 int fd)
00254 {
00255 acl_type_t aixjfs2_type;
00256 aixjfs2_type.u64 = ACL_AIXC;
00257
00258 return aixjfs2_get_posix_acl(fsp->fsp_name, aixjfs2_type);
00259 }
00260
00261
00262
00263
00264 static int aixjfs2_query_acl_support(
00265 char *filepath,
00266 uint64_t aclType,
00267 acl_type_t *pacl_type_info
00268 )
00269 {
00270 acl_types_list_t acl_type_list;
00271 size_t acl_type_list_len = sizeof(acl_types_list_t);
00272 uint32_t i;
00273
00274 memset(&acl_type_list, 0, sizeof(acl_type_list));
00275
00276 if (aclx_gettypes(filepath, &acl_type_list, &acl_type_list_len)) {
00277 DEBUG(2, ("aclx_gettypes failed with error %s for %s\n",
00278 strerror(errno), filepath));
00279 return -1;
00280 }
00281
00282 for(i=0; i<acl_type_list.num_entries; i++) {
00283 if (acl_type_list.entries[i].u64==aclType) {
00284 memcpy(pacl_type_info, acl_type_list.entries + i, sizeof(acl_type_t));
00285 DEBUG(10, ("found %s ACL support for %s\n",
00286 pacl_type_info->acl_type, filepath));
00287 return 0;
00288 }
00289 }
00290
00291 return 1;
00292 }
00293
00294 static BOOL aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
00295 {
00296 SMB4ACE_T *smbace;
00297 TALLOC_CTX *mem_ctx;
00298 nfs4_acl_int_t *jfs2acl;
00299 int32_t entryLen;
00300 uint32 aclLen, naces;
00301 int rc;
00302 acl_type_t acltype;
00303
00304 DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp->fsp_name));
00305
00306
00307 mem_ctx = main_loop_talloc_get();
00308
00309 entryLen = sizeof(nfs4_ace_int_t);
00310 if (entryLen & 0x03)
00311 entryLen = entryLen + 4 - (entryLen%4);
00312
00313 naces = smb_get_naces(smbacl);
00314 aclLen = ACL_V4_SIZ + naces * entryLen;
00315 jfs2acl = (nfs4_acl_int_t *)TALLOC_SIZE(mem_ctx, aclLen);
00316 if (jfs2acl==NULL) {
00317 DEBUG(0, ("TALLOC_SIZE failed\n"));
00318 errno = ENOMEM;
00319 return False;
00320 }
00321
00322 jfs2acl->aclLength = ACL_V4_SIZ;
00323 jfs2acl->aclVersion = NFS4_ACL_INT_STRUCT_VERSION;
00324 jfs2acl->aclEntryN = 0;
00325
00326 for(smbace = smb_first_ace4(smbacl); smbace!=NULL; smbace = smb_next_ace4(smbace))
00327 {
00328 SMB_ACE4PROP_T *aceprop = smb_get_ace4(smbace);
00329 nfs4_ace_int_t *jfs2_ace = (nfs4_ace_int_t *)(((char *)jfs2acl) + jfs2acl->aclLength);
00330
00331 memset(jfs2_ace, 0, entryLen);
00332 jfs2_ace->entryLen = entryLen;
00333 jfs2_ace->aceType = aceprop->aceType;
00334 jfs2_ace->aceFlags = aceprop->aceFlags;
00335 jfs2_ace->aceMask = aceprop->aceMask;
00336 jfs2_ace->flags = (aceprop->flags&SMB_ACE4_ID_SPECIAL) ? ACE4_ID_SPECIAL : 0;
00337
00338
00339 jfs2_ace->aceWho.id = aceprop->who.id;
00340
00341
00342 jfs2acl->aclLength += jfs2_ace->entryLen;
00343 jfs2acl->aclEntryN++;
00344 }
00345 SMB_ASSERT(jfs2acl->aclEntryN==naces);
00346
00347
00348 memset(&acltype, 0, sizeof(acl_type_t));
00349 acltype.u64 = ACL_NFS4;
00350
00351
00352 rc = aclx_put(
00353 fsp->fsp_name,
00354 SET_ACL,
00355 acltype,
00356 jfs2acl,
00357 jfs2acl->aclLength,
00358 0
00359 );
00360 if (rc) {
00361 DEBUG(8, ("aclx_put failed with %s\n", strerror(errno)));
00362 return False;
00363 }
00364
00365 DEBUG(10, ("jfs2_process_smbacl succeeded.\n"));
00366 return True;
00367 }
00368
00369 static BOOL aixjfs2_set_nt_acl_common(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
00370 {
00371 acl_type_t acl_type_info;
00372 BOOL result = False;
00373 int rc;
00374
00375 rc = aixjfs2_query_acl_support(
00376 fsp->fsp_name,
00377 ACL_NFS4,
00378 &acl_type_info);
00379
00380 if (rc==0)
00381 {
00382 result = smb_set_nt_acl_nfs4(
00383 fsp, security_info_sent, psd,
00384 aixjfs2_process_smbacl);
00385 } else if (rc==1) {
00386 result = set_nt_acl(fsp, security_info_sent, psd);
00387 } else
00388 result = False;
00389
00390 return result;
00391 }
00392
00393 BOOL aixjfs2_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
00394 {
00395 return aixjfs2_set_nt_acl_common(fsp, security_info_sent, psd);
00396 }
00397
00398 BOOL aixjfs2_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
00399 {
00400 return aixjfs2_set_nt_acl_common(fsp, security_info_sent, psd);
00401 }
00402
00403 int aixjfs2_sys_acl_set_file(vfs_handle_struct *handle,
00404 const char *name,
00405 SMB_ACL_TYPE_T type,
00406 SMB_ACL_T theacl)
00407 {
00408 struct acl *acl_aixc;
00409 acl_type_t acl_type_info;
00410 int rc;
00411
00412 DEBUG(10, ("aixjfs2_sys_acl_set_file invoked for %s", name));
00413
00414 rc = aixjfs2_query_acl_support((char *)name, ACL_AIXC, &acl_type_info);
00415 if (rc) {
00416 DEBUG(8, ("jfs2_set_nt_acl: AIXC support not found\n"));
00417 return -1;
00418 }
00419
00420 acl_aixc = aixacl_smb_to_aixacl(type, theacl);
00421 if (!acl_aixc)
00422 return -1;
00423
00424 rc = aclx_put(
00425 (char *)name,
00426 SET_ACL,
00427 acl_type_info,
00428 acl_aixc,
00429 acl_aixc->acl_len,
00430 0
00431 );
00432 if (rc) {
00433 DEBUG(2, ("aclx_put failed with %s for %s\n",
00434 strerror(errno), name));
00435 return -1;
00436 }
00437
00438 return 0;
00439 }
00440
00441 int aixjfs2_sys_acl_set_fd(vfs_handle_struct *handle,
00442 files_struct *fsp,
00443 int fd, SMB_ACL_T theacl)
00444 {
00445 struct acl *acl_aixc;
00446 acl_type_t acl_type_info;
00447 int rc;
00448
00449 DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp->fsp_name));
00450
00451 rc = aixjfs2_query_acl_support(fsp->fsp_name, ACL_AIXC, &acl_type_info);
00452 if (rc) {
00453 DEBUG(8, ("jfs2_set_nt_acl: AIXC support not found\n"));
00454 return -1;
00455 }
00456
00457 acl_aixc = aixacl_smb_to_aixacl(SMB_ACL_TYPE_ACCESS, theacl);
00458 if (!acl_aixc)
00459 return -1;
00460
00461 rc = aclx_fput(
00462 fd,
00463 SET_ACL,
00464 acl_type_info,
00465 acl_aixc,
00466 acl_aixc->acl_len,
00467 0
00468 );
00469 if (rc) {
00470 DEBUG(2, ("aclx_fput failed with %s for %s\n",
00471 strerror(errno), fsp->fsp_name));
00472 return -1;
00473 }
00474
00475 return 0;
00476 }
00477
00478 int aixjfs2_sys_acl_delete_def_file(vfs_handle_struct *handle,
00479 const char *path)
00480 {
00481
00482
00483
00484 return 0;
00485 }
00486
00487
00488
00489
00490 static vfs_op_tuple aixjfs2_ops[] =
00491 {
00492 {SMB_VFS_OP(aixjfs2_fget_nt_acl),
00493 SMB_VFS_OP_FGET_NT_ACL,
00494 SMB_VFS_LAYER_TRANSPARENT},
00495
00496 {SMB_VFS_OP(aixjfs2_get_nt_acl),
00497 SMB_VFS_OP_GET_NT_ACL,
00498 SMB_VFS_LAYER_TRANSPARENT},
00499
00500 {SMB_VFS_OP(aixjfs2_fset_nt_acl),
00501 SMB_VFS_OP_FSET_NT_ACL,
00502 SMB_VFS_LAYER_TRANSPARENT},
00503
00504 {SMB_VFS_OP(aixjfs2_set_nt_acl),
00505 SMB_VFS_OP_SET_NT_ACL,
00506 SMB_VFS_LAYER_TRANSPARENT},
00507
00508 {SMB_VFS_OP(aixjfs2_sys_acl_get_file),
00509 SMB_VFS_OP_SYS_ACL_GET_FILE,
00510 SMB_VFS_LAYER_TRANSPARENT},
00511
00512 {SMB_VFS_OP(aixjfs2_sys_acl_get_fd),
00513 SMB_VFS_OP_SYS_ACL_GET_FD,
00514 SMB_VFS_LAYER_TRANSPARENT},
00515
00516 {SMB_VFS_OP(aixjfs2_sys_acl_set_file),
00517 SMB_VFS_OP_SYS_ACL_SET_FILE,
00518 SMB_VFS_LAYER_TRANSPARENT},
00519
00520 {SMB_VFS_OP(aixjfs2_sys_acl_set_fd),
00521 SMB_VFS_OP_SYS_ACL_SET_FD,
00522 SMB_VFS_LAYER_TRANSPARENT},
00523
00524 {SMB_VFS_OP(aixjfs2_sys_acl_delete_def_file),
00525 SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
00526 SMB_VFS_LAYER_TRANSPARENT},
00527
00528 {SMB_VFS_OP(NULL),
00529 SMB_VFS_OP_NOOP,
00530 SMB_VFS_LAYER_NOOP}
00531 };
00532
00533 NTSTATUS vfs_aixacl2_init(void);
00534 NTSTATUS vfs_aixacl2_init(void)
00535 {
00536 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, AIXACL2_MODULE_NAME,
00537 aixjfs2_ops);
00538 }