00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include "includes.h"
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #undef GROUP
00064 #include <sys/aclv.h>
00065
00066 #include <dl.h>
00067
00068 typedef struct acl HPUX_ACE_T;
00069 typedef struct acl *HPUX_ACL_T;
00070 typedef int HPUX_ACL_TAG_T;
00071 typedef ushort HPUX_PERM_T;
00072
00073
00074
00075 struct hpux_acl_types {
00076 int n_user;
00077 int n_def_user;
00078 int n_user_obj;
00079 int n_def_user_obj;
00080
00081 int n_group;
00082 int n_def_group;
00083 int n_group_obj;
00084 int n_def_group_obj;
00085
00086 int n_other;
00087 int n_other_obj;
00088 int n_def_other_obj;
00089
00090 int n_class_obj;
00091 int n_def_class_obj;
00092
00093 int n_illegal_obj;
00094 };
00095
00096
00097 #define _IS_DEFAULT(ace) ((ace).a_type & ACL_DEFAULT)
00098 #define _IS_OF_TYPE(ace, type) ( \
00099 (((type) == SMB_ACL_TYPE_ACCESS) && !_IS_DEFAULT(ace)) \
00100 || \
00101 (((type) == SMB_ACL_TYPE_DEFAULT) && _IS_DEFAULT(ace)) \
00102 )
00103
00104
00105
00106
00107 static HPUX_ACL_T hpux_acl_init(int count);
00108 static BOOL smb_acl_to_hpux_acl(SMB_ACL_T smb_acl,
00109 HPUX_ACL_T *solariacl, int *count,
00110 SMB_ACL_TYPE_T type);
00111 static SMB_ACL_T hpux_acl_to_smb_acl(HPUX_ACL_T hpuxacl, int count,
00112 SMB_ACL_TYPE_T type);
00113 static HPUX_ACL_TAG_T smb_tag_to_hpux_tag(SMB_ACL_TAG_T smb_tag);
00114 static SMB_ACL_TAG_T hpux_tag_to_smb_tag(HPUX_ACL_TAG_T hpux_tag);
00115 static BOOL hpux_add_to_acl(HPUX_ACL_T *hpux_acl, int *count,
00116 HPUX_ACL_T add_acl, int add_count, SMB_ACL_TYPE_T type);
00117 static BOOL hpux_acl_get_file(const char *name, HPUX_ACL_T *hpuxacl,
00118 int *count);
00119 static SMB_ACL_PERM_T hpux_perm_to_smb_perm(const HPUX_PERM_T perm);
00120 static HPUX_PERM_T smb_perm_to_hpux_perm(const SMB_ACL_PERM_T perm);
00121 #if 0
00122 static BOOL hpux_acl_check(HPUX_ACL_T hpux_acl, int count);
00123 #endif
00124
00125 static BOOL hpux_acl_sort(HPUX_ACL_T acl, int count);
00126 static int hpux_internal_aclsort(int acl_count, int calclass, HPUX_ACL_T aclp);
00127 static void hpux_count_obj(int acl_count, HPUX_ACL_T aclp,
00128 struct hpux_acl_types *acl_type_count);
00129 static void hpux_swap_acl_entries(HPUX_ACE_T *aclp0, HPUX_ACE_T *aclp1);
00130 static BOOL hpux_prohibited_duplicate_type(int acl_type);
00131
00132 static BOOL hpux_acl_call_present(void);
00133 static BOOL hpux_aclsort_call_present(void);
00134
00135
00136
00137
00138 SMB_ACL_T hpuxacl_sys_acl_get_file(vfs_handle_struct *handle,
00139 const char *path_p,
00140 SMB_ACL_TYPE_T type)
00141 {
00142 SMB_ACL_T result = NULL;
00143 int count;
00144 HPUX_ACL_T hpux_acl = NULL;
00145
00146 DEBUG(10, ("hpuxacl_sys_acl_get_file called for file '%s'.\n",
00147 path_p));
00148
00149 if(hpux_acl_call_present() == False) {
00150
00151
00152
00153 goto done;
00154 }
00155
00156 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
00157 DEBUG(10, ("invalid SMB_ACL_TYPE given (%d)\n", type));
00158 errno = EINVAL;
00159 goto done;
00160 }
00161
00162 DEBUGADD(10, ("getting %s acl\n",
00163 ((type == SMB_ACL_TYPE_ACCESS) ? "access" : "default")));
00164
00165 if (!hpux_acl_get_file(path_p, &hpux_acl, &count)) {
00166 goto done;
00167 }
00168 result = hpux_acl_to_smb_acl(hpux_acl, count, type);
00169 if (result == NULL) {
00170 DEBUG(10, ("conversion hpux_acl -> smb_acl failed (%s).\n",
00171 strerror(errno)));
00172 }
00173
00174 done:
00175 DEBUG(10, ("hpuxacl_sys_acl_get_file %s.\n",
00176 ((result == NULL) ? "failed" : "succeeded" )));
00177 SAFE_FREE(hpux_acl);
00178 return result;
00179 }
00180
00181
00182
00183
00184
00185 SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle,
00186 files_struct *fsp,
00187 int fd)
00188 {
00189
00190
00191
00192
00193
00194 files_struct *file_struct_p = file_find_fd(fd);
00195 if (file_struct_p == NULL) {
00196 errno = EBADF;
00197 return NULL;
00198 }
00199
00200
00201
00202
00203 DEBUG(10, ("redirecting call of hpuxacl_sys_acl_get_fd to "
00204 "hpuxacl_sys_acl_get_file (no facl syscall on HPUX).\n"));
00205
00206 return hpuxacl_sys_acl_get_file(handle, file_struct_p->fsp_name,
00207 SMB_ACL_TYPE_ACCESS);
00208 }
00209
00210
00211 int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
00212 const char *name,
00213 SMB_ACL_TYPE_T type,
00214 SMB_ACL_T theacl)
00215 {
00216 int ret = -1;
00217 SMB_STRUCT_STAT s;
00218 HPUX_ACL_T hpux_acl = NULL;
00219 int count;
00220
00221 DEBUG(10, ("hpuxacl_sys_acl_set_file called for file '%s'\n",
00222 name));
00223
00224
00225 if(hpux_acl_call_present() == False) {
00226
00227
00228
00229 goto done;
00230 }
00231
00232 if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT)) {
00233 errno = EINVAL;
00234 DEBUG(10, ("invalid smb acl type given (%d).\n", type));
00235 goto done;
00236 }
00237 DEBUGADD(10, ("setting %s acl\n",
00238 ((type == SMB_ACL_TYPE_ACCESS) ? "access" : "default")));
00239
00240 if(!smb_acl_to_hpux_acl(theacl, &hpux_acl, &count, type)) {
00241 DEBUG(10, ("conversion smb_acl -> hpux_acl failed (%s).\n",
00242 strerror(errno)));
00243 goto done;
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253 if (SMB_VFS_STAT(handle->conn, name, &s) != 0) {
00254 DEBUG(10, ("Error in stat call: %s\n", strerror(errno)));
00255 goto done;
00256 }
00257 if (S_ISDIR(s.st_mode)) {
00258 HPUX_ACL_T other_acl;
00259 int other_count;
00260 SMB_ACL_TYPE_T other_type;
00261
00262 other_type = (type == SMB_ACL_TYPE_ACCESS)
00263 ? SMB_ACL_TYPE_DEFAULT
00264 : SMB_ACL_TYPE_ACCESS;
00265 DEBUGADD(10, ("getting acl from filesystem\n"));
00266 if (!hpux_acl_get_file(name, &other_acl, &other_count)) {
00267 DEBUG(10, ("error getting acl from directory\n"));
00268 goto done;
00269 }
00270 DEBUG(10, ("adding %s part of fs acl to given acl\n",
00271 ((other_type == SMB_ACL_TYPE_ACCESS)
00272 ? "access"
00273 : "default")));
00274 if (!hpux_add_to_acl(&hpux_acl, &count, other_acl,
00275 other_count, other_type))
00276 {
00277 DEBUG(10, ("error adding other acl.\n"));
00278 SAFE_FREE(other_acl);
00279 goto done;
00280 }
00281 SAFE_FREE(other_acl);
00282 }
00283 else if (type != SMB_ACL_TYPE_ACCESS) {
00284 errno = EINVAL;
00285 goto done;
00286 }
00287
00288 if (!hpux_acl_sort(hpux_acl, count)) {
00289 DEBUG(10, ("resulting acl is not valid!\n"));
00290 goto done;
00291 }
00292 DEBUG(10, ("resulting acl is valid.\n"));
00293
00294 ret = acl(CONST_DISCARD(char *, name), ACL_SET, count, hpux_acl);
00295 if (ret != 0) {
00296 DEBUG(0, ("ERROR calling acl: %s\n", strerror(errno)));
00297 }
00298
00299 done:
00300 DEBUG(10, ("hpuxacl_sys_acl_set_file %s.\n",
00301 ((ret != 0) ? "failed" : "succeeded")));
00302 SAFE_FREE(hpux_acl);
00303 return ret;
00304 }
00305
00306
00307
00308
00309 int hpuxacl_sys_acl_set_fd(vfs_handle_struct *handle,
00310 files_struct *fsp,
00311 int fd, SMB_ACL_T theacl)
00312 {
00313
00314
00315
00316
00317
00318 files_struct *file_struct_p = file_find_fd(fd);
00319 if (file_struct_p == NULL) {
00320 errno = EBADF;
00321 return -1;
00322 }
00323
00324
00325
00326
00327 DEBUG(10, ("redirecting call of hpuxacl_sys_acl_set_fd to "
00328 "hpuxacl_sys_acl_set_file (no facl syscall on HPUX)\n"));
00329
00330 return hpuxacl_sys_acl_set_file(handle, file_struct_p->fsp_name,
00331 SMB_ACL_TYPE_ACCESS, theacl);
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 int hpuxacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
00352 const char *path)
00353 {
00354 SMB_ACL_T smb_acl;
00355 int ret = -1;
00356 HPUX_ACL_T hpux_acl;
00357 int count;
00358
00359 DEBUG(10, ("entering hpuxacl_sys_acl_delete_def_file.\n"));
00360
00361 smb_acl = hpuxacl_sys_acl_get_file(handle, path,
00362 SMB_ACL_TYPE_ACCESS);
00363 if (smb_acl == NULL) {
00364 DEBUG(10, ("getting file acl failed!\n"));
00365 goto done;
00366 }
00367 if (!smb_acl_to_hpux_acl(smb_acl, &hpux_acl, &count,
00368 SMB_ACL_TYPE_ACCESS))
00369 {
00370 DEBUG(10, ("conversion smb_acl -> hpux_acl failed.\n"));
00371 goto done;
00372 }
00373 if (!hpux_acl_sort(hpux_acl, count)) {
00374 DEBUG(10, ("resulting acl is not valid!\n"));
00375 goto done;
00376 }
00377 ret = acl(CONST_DISCARD(char *, path), ACL_SET, count, hpux_acl);
00378 if (ret != 0) {
00379 DEBUG(10, ("settinge file acl failed!\n"));
00380 }
00381
00382 done:
00383 DEBUG(10, ("hpuxacl_sys_acl_delete_def_file %s.\n",
00384 ((ret != 0) ? "failed" : "succeeded" )));
00385 SAFE_FREE(smb_acl);
00386 return ret;
00387 }
00388
00389
00390
00391
00392
00393
00394 static HPUX_ACL_T hpux_acl_init(int count)
00395 {
00396 HPUX_ACL_T hpux_acl =
00397 (HPUX_ACL_T)SMB_MALLOC(sizeof(HPUX_ACE_T) * count);
00398 if (hpux_acl == NULL) {
00399 errno = ENOMEM;
00400 }
00401 return hpux_acl;
00402 }
00403
00404
00405
00406
00407
00408 static BOOL smb_acl_to_hpux_acl(SMB_ACL_T smb_acl,
00409 HPUX_ACL_T *hpux_acl, int *count,
00410 SMB_ACL_TYPE_T type)
00411 {
00412 BOOL ret = False;
00413 int i;
00414 int check_which, check_rc;
00415
00416 DEBUG(10, ("entering smb_acl_to_hpux_acl\n"));
00417
00418 *hpux_acl = NULL;
00419 *count = 0;
00420
00421 for (i = 0; i < smb_acl->count; i++) {
00422 const struct smb_acl_entry *smb_entry = &(smb_acl->acl[i]);
00423 HPUX_ACE_T hpux_entry;
00424
00425 ZERO_STRUCT(hpux_entry);
00426
00427 hpux_entry.a_type = smb_tag_to_hpux_tag(smb_entry->a_type);
00428 if (hpux_entry.a_type == 0) {
00429 DEBUG(10, ("smb_tag to hpux_tag failed\n"));
00430 goto fail;
00431 }
00432 switch(hpux_entry.a_type) {
00433 case USER:
00434 DEBUG(10, ("got tag type USER with uid %d\n",
00435 smb_entry->uid));
00436 hpux_entry.a_id = (uid_t)smb_entry->uid;
00437 break;
00438 case GROUP:
00439 DEBUG(10, ("got tag type GROUP with gid %d\n",
00440 smb_entry->gid));
00441 hpux_entry.a_id = (uid_t)smb_entry->gid;
00442 break;
00443 default:
00444 break;
00445 }
00446 if (type == SMB_ACL_TYPE_DEFAULT) {
00447 DEBUG(10, ("adding default bit to hpux ace\n"));
00448 hpux_entry.a_type |= ACL_DEFAULT;
00449 }
00450
00451 hpux_entry.a_perm =
00452 smb_perm_to_hpux_perm(smb_entry->a_perm);
00453 DEBUG(10, ("assembled the following hpux ace:\n"));
00454 DEBUGADD(10, (" - type: 0x%04x\n", hpux_entry.a_type));
00455 DEBUGADD(10, (" - id: %d\n", hpux_entry.a_id));
00456 DEBUGADD(10, (" - perm: o%o\n", hpux_entry.a_perm));
00457 if (!hpux_add_to_acl(hpux_acl, count, &hpux_entry,
00458 1, type))
00459 {
00460 DEBUG(10, ("error adding acl entry\n"));
00461 goto fail;
00462 }
00463 DEBUG(10, ("count after adding: %d (i: %d)\n", *count, i));
00464 DEBUG(10, ("test, if entry has been copied into acl:\n"));
00465 DEBUGADD(10, (" - type: 0x%04x\n",
00466 (*hpux_acl)[(*count)-1].a_type));
00467 DEBUGADD(10, (" - id: %d\n",
00468 (*hpux_acl)[(*count)-1].a_id));
00469 DEBUGADD(10, (" - perm: o%o\n",
00470 (*hpux_acl)[(*count)-1].a_perm));
00471 }
00472
00473 ret = True;
00474 goto done;
00475
00476 fail:
00477 SAFE_FREE(*hpux_acl);
00478 done:
00479 DEBUG(10, ("smb_acl_to_hpux_acl %s\n",
00480 ((ret == True) ? "succeeded" : "failed")));
00481 return ret;
00482 }
00483
00484
00485
00486
00487
00488 static SMB_ACL_T hpux_acl_to_smb_acl(HPUX_ACL_T hpux_acl, int count,
00489 SMB_ACL_TYPE_T type)
00490 {
00491 SMB_ACL_T result;
00492 int i;
00493
00494 if ((result = sys_acl_init(0)) == NULL) {
00495 DEBUG(10, ("error allocating memory for SMB_ACL\n"));
00496 goto fail;
00497 }
00498 for (i = 0; i < count; i++) {
00499 SMB_ACL_ENTRY_T smb_entry;
00500 SMB_ACL_PERM_T smb_perm;
00501
00502 if (!_IS_OF_TYPE(hpux_acl[i], type)) {
00503 continue;
00504 }
00505 result = SMB_REALLOC(result,
00506 sizeof(struct smb_acl_t) +
00507 (sizeof(struct smb_acl_entry) *
00508 (result->count + 1)));
00509 if (result == NULL) {
00510 DEBUG(10, ("error reallocating memory for SMB_ACL\n"));
00511 goto fail;
00512 }
00513 smb_entry = &result->acl[result->count];
00514 if (sys_acl_set_tag_type(smb_entry,
00515 hpux_tag_to_smb_tag(hpux_acl[i].a_type)) != 0)
00516 {
00517 DEBUG(10, ("invalid tag type given: 0x%04x\n",
00518 hpux_acl[i].a_type));
00519 goto fail;
00520 }
00521
00522 sys_acl_set_qualifier(smb_entry, (void *)&hpux_acl[i].a_id);
00523 smb_perm = hpux_perm_to_smb_perm(hpux_acl[i].a_perm);
00524 if (sys_acl_set_permset(smb_entry, &smb_perm) != 0) {
00525 DEBUG(10, ("invalid permset given: %d\n",
00526 hpux_acl[i].a_perm));
00527 goto fail;
00528 }
00529 result->count += 1;
00530 }
00531 goto done;
00532
00533 fail:
00534 SAFE_FREE(result);
00535 done:
00536 DEBUG(10, ("hpux_acl_to_smb_acl %s\n",
00537 ((result == NULL) ? "failed" : "succeeded")));
00538 return result;
00539 }
00540
00541
00542
00543 static HPUX_ACL_TAG_T smb_tag_to_hpux_tag(SMB_ACL_TAG_T smb_tag)
00544 {
00545 HPUX_ACL_TAG_T hpux_tag = 0;
00546
00547 DEBUG(10, ("smb_tag_to_hpux_tag\n"));
00548 DEBUGADD(10, (" --> got smb tag 0x%04x\n", smb_tag));
00549
00550 switch (smb_tag) {
00551 case SMB_ACL_USER:
00552 hpux_tag = USER;
00553 break;
00554 case SMB_ACL_USER_OBJ:
00555 hpux_tag = USER_OBJ;
00556 break;
00557 case SMB_ACL_GROUP:
00558 hpux_tag = GROUP;
00559 break;
00560 case SMB_ACL_GROUP_OBJ:
00561 hpux_tag = GROUP_OBJ;
00562 break;
00563 case SMB_ACL_OTHER:
00564 hpux_tag = OTHER_OBJ;
00565 break;
00566 case SMB_ACL_MASK:
00567 hpux_tag = CLASS_OBJ;
00568 break;
00569 default:
00570 DEBUGADD(10, (" !!! unknown smb tag type 0x%04x\n", smb_tag));
00571 break;
00572 }
00573
00574 DEBUGADD(10, (" --> determined hpux tag 0x%04x\n", hpux_tag));
00575
00576 return hpux_tag;
00577 }
00578
00579 static SMB_ACL_TAG_T hpux_tag_to_smb_tag(HPUX_ACL_TAG_T hpux_tag)
00580 {
00581 SMB_ACL_TAG_T smb_tag = 0;
00582
00583 DEBUG(10, ("hpux_tag_to_smb_tag:\n"));
00584 DEBUGADD(10, (" --> got hpux tag 0x%04x\n", hpux_tag));
00585
00586 hpux_tag &= ~ACL_DEFAULT;
00587
00588 switch (hpux_tag) {
00589 case USER:
00590 smb_tag = SMB_ACL_USER;
00591 break;
00592 case USER_OBJ:
00593 smb_tag = SMB_ACL_USER_OBJ;
00594 break;
00595 case GROUP:
00596 smb_tag = SMB_ACL_GROUP;
00597 break;
00598 case GROUP_OBJ:
00599 smb_tag = SMB_ACL_GROUP_OBJ;
00600 break;
00601 case OTHER_OBJ:
00602 smb_tag = SMB_ACL_OTHER;
00603 break;
00604 case CLASS_OBJ:
00605 smb_tag = SMB_ACL_MASK;
00606 break;
00607 default:
00608 DEBUGADD(10, (" !!! unknown hpux tag type: 0x%04x\n",
00609 hpux_tag));
00610 break;
00611 }
00612
00613 DEBUGADD(10, (" --> determined smb tag 0x%04x\n", smb_tag));
00614
00615 return smb_tag;
00616 }
00617
00618
00619
00620
00621
00622
00623
00624 static SMB_ACL_PERM_T hpux_perm_to_smb_perm(const HPUX_PERM_T perm)
00625 {
00626 SMB_ACL_PERM_T smb_perm = 0;
00627 smb_perm |= ((perm & SMB_ACL_READ) ? SMB_ACL_READ : 0);
00628 smb_perm |= ((perm & SMB_ACL_WRITE) ? SMB_ACL_WRITE : 0);
00629 smb_perm |= ((perm & SMB_ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0);
00630 return smb_perm;
00631 }
00632
00633
00634 static HPUX_PERM_T smb_perm_to_hpux_perm(const SMB_ACL_PERM_T perm)
00635 {
00636 HPUX_PERM_T hpux_perm = 0;
00637 hpux_perm |= ((perm & SMB_ACL_READ) ? SMB_ACL_READ : 0);
00638 hpux_perm |= ((perm & SMB_ACL_WRITE) ? SMB_ACL_WRITE : 0);
00639 hpux_perm |= ((perm & SMB_ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0);
00640 return hpux_perm;
00641 }
00642
00643
00644 static BOOL hpux_acl_get_file(const char *name, HPUX_ACL_T *hpux_acl,
00645 int *count)
00646 {
00647 BOOL result = False;
00648 static HPUX_ACE_T dummy_ace;
00649
00650 DEBUG(10, ("hpux_acl_get_file called for file '%s'\n", name));
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 *count = acl(CONST_DISCARD(char *, name), ACL_CNT, 0, &dummy_ace);
00666 if (*count < 0) {
00667 DEBUG(10, ("acl ACL_CNT failed: %s\n", strerror(errno)));
00668 goto done;
00669 }
00670 *hpux_acl = hpux_acl_init(*count);
00671 if (*hpux_acl == NULL) {
00672 DEBUG(10, ("error allocating memory for hpux acl...\n"));
00673 goto done;
00674 }
00675 *count = acl(CONST_DISCARD(char *, name), ACL_GET, *count, *hpux_acl);
00676 if (*count < 0) {
00677 DEBUG(10, ("acl ACL_GET failed: %s\n", strerror(errno)));
00678 goto done;
00679 }
00680 result = True;
00681
00682 done:
00683 DEBUG(10, ("hpux_acl_get_file %s.\n",
00684 ((result == True) ? "succeeded" : "failed" )));
00685 return result;
00686 }
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 static BOOL hpux_add_to_acl(HPUX_ACL_T *hpux_acl, int *count,
00708 HPUX_ACL_T add_acl, int add_count,
00709 SMB_ACL_TYPE_T type)
00710 {
00711 int i;
00712
00713 if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT))
00714 {
00715 DEBUG(10, ("invalid acl type given: %d\n", type));
00716 errno = EINVAL;
00717 return False;
00718 }
00719 for (i = 0; i < add_count; i++) {
00720 if (!_IS_OF_TYPE(add_acl[i], type)) {
00721 continue;
00722 }
00723 ADD_TO_ARRAY(NULL, HPUX_ACE_T, add_acl[i],
00724 hpux_acl, count);
00725 if (hpux_acl == NULL) {
00726 DEBUG(10, ("error enlarging acl.\n"));
00727 errno = ENOMEM;
00728 return False;
00729 }
00730 }
00731 return True;
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753 static BOOL hpux_acl_sort(HPUX_ACL_T hpux_acl, int count)
00754 {
00755 int fixmask = (count <= 4);
00756
00757 if (hpux_internal_aclsort(count, fixmask, hpux_acl) != 0) {
00758 errno = EINVAL;
00759 return False;
00760 }
00761 return True;
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 static void hpux_count_obj(int acl_count, HPUX_ACL_T aclp, struct hpux_acl_types *acl_type_count)
00789 {
00790 int i;
00791
00792 memset(acl_type_count, 0, sizeof(struct hpux_acl_types));
00793
00794 for(i=0;i<acl_count;i++) {
00795 switch(aclp[i].a_type) {
00796 case USER:
00797 acl_type_count->n_user++;
00798 break;
00799 case USER_OBJ:
00800 acl_type_count->n_user_obj++;
00801 break;
00802 case DEF_USER_OBJ:
00803 acl_type_count->n_def_user_obj++;
00804 break;
00805 case GROUP:
00806 acl_type_count->n_group++;
00807 break;
00808 case GROUP_OBJ:
00809 acl_type_count->n_group_obj++;
00810 break;
00811 case DEF_GROUP_OBJ:
00812 acl_type_count->n_def_group_obj++;
00813 break;
00814 case OTHER_OBJ:
00815 acl_type_count->n_other_obj++;
00816 break;
00817 case DEF_OTHER_OBJ:
00818 acl_type_count->n_def_other_obj++;
00819 break;
00820 case CLASS_OBJ:
00821 acl_type_count->n_class_obj++;
00822 break;
00823 case DEF_CLASS_OBJ:
00824 acl_type_count->n_def_class_obj++;
00825 break;
00826 case DEF_USER:
00827 acl_type_count->n_def_user++;
00828 break;
00829 case DEF_GROUP:
00830 acl_type_count->n_def_group++;
00831 break;
00832 default:
00833 acl_type_count->n_illegal_obj++;
00834 break;
00835 }
00836 }
00837 }
00838
00839
00840
00841
00842
00843
00844 static void hpux_swap_acl_entries(HPUX_ACE_T *aclp0, HPUX_ACE_T *aclp1)
00845 {
00846 HPUX_ACE_T temp_acl;
00847
00848 temp_acl.a_type = aclp0->a_type;
00849 temp_acl.a_id = aclp0->a_id;
00850 temp_acl.a_perm = aclp0->a_perm;
00851
00852 aclp0->a_type = aclp1->a_type;
00853 aclp0->a_id = aclp1->a_id;
00854 aclp0->a_perm = aclp1->a_perm;
00855
00856 aclp1->a_type = temp_acl.a_type;
00857 aclp1->a_id = temp_acl.a_id;
00858 aclp1->a_perm = temp_acl.a_perm;
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 static BOOL hpux_prohibited_duplicate_type(int acl_type)
00876 {
00877 switch(acl_type) {
00878 case USER:
00879 case GROUP:
00880 case DEF_USER:
00881 case DEF_GROUP:
00882 return True;
00883 default:
00884 return False;
00885 }
00886 }
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896 static int hpux_get_needed_class_perm(struct acl *aclp)
00897 {
00898 switch(aclp->a_type) {
00899 case USER:
00900 case GROUP_OBJ:
00901 case GROUP:
00902 case DEF_USER_OBJ:
00903 case DEF_USER:
00904 case DEF_GROUP_OBJ:
00905 case DEF_GROUP:
00906 case DEF_CLASS_OBJ:
00907 case DEF_OTHER_OBJ:
00908 return aclp->a_perm;
00909 default:
00910 return 0;
00911 }
00912 }
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941 static int hpux_internal_aclsort(int acl_count, int calclass, HPUX_ACL_T aclp)
00942 {
00943 struct hpux_acl_types acl_obj_count;
00944 int n_class_obj_perm = 0;
00945 int i, j;
00946
00947 DEBUG(10,("Entering hpux_internal_aclsort. (calclass = %d)\n", calclass));
00948
00949 if (hpux_aclsort_call_present()) {
00950 DEBUG(10, ("calling hpux aclsort\n"));
00951 return aclsort(acl_count, calclass, aclp);
00952 }
00953
00954 DEBUG(10, ("using internal aclsort\n"));
00955
00956 if(!acl_count) {
00957 DEBUG(10,("Zero acl count passed. Returning Success\n"));
00958 return 0;
00959 }
00960
00961 if(aclp == NULL) {
00962 DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
00963 return -1;
00964 }
00965
00966
00967
00968 hpux_count_obj(acl_count, aclp, &acl_obj_count);
00969
00970
00971
00972
00973
00974 if ( (acl_obj_count.n_user_obj != 1) ||
00975 (acl_obj_count.n_group_obj != 1) ||
00976 (acl_obj_count.n_class_obj != 1) ||
00977 (acl_obj_count.n_other_obj != 1) )
00978 {
00979 DEBUG(0,("hpux_internal_aclsort: More than one entry or no entries for \
00980 USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
00981 return -1;
00982 }
00983
00984
00985
00986
00987
00988 if ( (acl_obj_count.n_def_user_obj > 1) ||
00989 (acl_obj_count.n_def_group_obj > 1) ||
00990 (acl_obj_count.n_def_other_obj > 1) ||
00991 (acl_obj_count.n_def_class_obj > 1) )
00992 {
00993 DEBUG(0,("hpux_internal_aclsort: More than one entry for DEF_CLASS_OBJ \
00994 or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
00995 return -1;
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 for(i=0; i<acl_count;i++) {
01010 for (j=i+1; j<acl_count; j++) {
01011 if( aclp[i].a_type > aclp[j].a_type ) {
01012
01013 hpux_swap_acl_entries((aclp+i), (aclp+j));
01014 } else if ( aclp[i].a_type == aclp[j].a_type ) {
01015
01016 if(aclp[i].a_id > aclp[j].a_id) {
01017 hpux_swap_acl_entries((aclp+i), (aclp+j));
01018 } else if (aclp[i].a_id == aclp[j].a_id) {
01019
01020 if(hpux_prohibited_duplicate_type(aclp[i].a_type)) {
01021 DEBUG(0, ("hpux_internal_aclsort: Duplicate entry: Type(hex): %x Id: %d\n",
01022 aclp[i].a_type, aclp[i].a_id));
01023 return -1;
01024 }
01025 }
01026 }
01027 }
01028 }
01029
01030
01031 if(calclass) {
01032 int n_class_obj_index = -1;
01033
01034 for(i=0;i<acl_count;i++) {
01035 n_class_obj_perm |= hpux_get_needed_class_perm((aclp+i));
01036
01037 if(aclp[i].a_type == CLASS_OBJ)
01038 n_class_obj_index = i;
01039 }
01040 aclp[n_class_obj_index].a_perm = n_class_obj_perm;
01041 }
01042
01043 return 0;
01044 }
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058 static BOOL hpux_acl_call_present(void)
01059 {
01060
01061 shl_t handle = NULL;
01062 void *value;
01063 int ret_val=0;
01064 static BOOL already_checked = False;
01065
01066 if(already_checked)
01067 return True;
01068
01069 errno = 0;
01070
01071 ret_val = shl_findsym(&handle, "acl", TYPE_PROCEDURE, &value);
01072
01073 if(ret_val != 0) {
01074 DEBUG(5, ("hpux_acl_call_present: shl_findsym() returned %d, errno = %d, error %s\n",
01075 ret_val, errno, strerror(errno)));
01076 DEBUG(5,("hpux_acl_call_present: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));
01077 errno = ENOSYS;
01078 return False;
01079 }
01080
01081 DEBUG(10,("hpux_acl_call_present: acl() system call is present. We have JFS 3.3 or above \n"));
01082
01083 already_checked = True;
01084 return True;
01085 }
01086
01087
01088
01089
01090
01091
01092
01093 static BOOL hpux_aclsort_call_present(void)
01094 {
01095 shl_t handle = NULL;
01096 void *value;
01097 int ret_val = 0;
01098 static BOOL already_checked = False;
01099
01100 if (already_checked) {
01101 return True;
01102 }
01103
01104 errno = 0;
01105 ret_val = shl_findsym(&handle, "aclsort", TYPE_PROCEDURE, &value);
01106 if (ret_val != 0) {
01107 DEBUG(5, ("hpux_aclsort_call_present: shl_findsym "
01108 "returned %d, errno = %d, error %s",
01109 ret_val, errno, strerror(errno)));
01110 DEBUG(5, ("hpux_aclsort_call_present: "
01111 "aclsort() function not available.\n"));
01112 return False;
01113 }
01114 DEBUG(10,("hpux_aclsort_call_present: aclsort() function present.\n"));
01115 already_checked = True;
01116 return True;
01117 }
01118
01119 #if 0
01120
01121
01122
01123
01124
01125
01126 static BOOL hpux_acl_check(HPUX_ACL_T hpux_acl, int count)
01127 {
01128 int check_rc;
01129 int check_which;
01130
01131 check_rc = aclcheck(hpux_acl, count, &check_which);
01132 if (check_rc != 0) {
01133 DEBUG(10, ("acl is not valid:\n"));
01134 DEBUGADD(10, (" - return code: %d\n", check_rc));
01135 DEBUGADD(10, (" - which: %d\n", check_which));
01136 if (check_which != -1) {
01137 DEBUGADD(10, (" - invalid entry:\n"));
01138 DEBUGADD(10, (" * type: %d:\n",
01139 hpux_acl[check_which].a_type));
01140 DEBUGADD(10, (" * id: %d\n",
01141 hpux_acl[check_which].a_id));
01142 DEBUGADD(10, (" * perm: 0o%o\n",
01143 hpux_acl[check_which].a_perm));
01144 }
01145 return False;
01146 }
01147 return True;
01148 }
01149 #endif
01150
01151
01152
01153 static vfs_op_tuple hpuxacl_op_tuples[] = {
01154
01155 {SMB_VFS_OP(hpuxacl_sys_acl_get_file),
01156 SMB_VFS_OP_SYS_ACL_GET_FILE,
01157 SMB_VFS_LAYER_TRANSPARENT},
01158
01159 {SMB_VFS_OP(hpuxacl_sys_acl_get_fd),
01160 SMB_VFS_OP_SYS_ACL_GET_FD,
01161 SMB_VFS_LAYER_TRANSPARENT},
01162
01163 {SMB_VFS_OP(hpuxacl_sys_acl_set_file),
01164 SMB_VFS_OP_SYS_ACL_SET_FILE,
01165 SMB_VFS_LAYER_TRANSPARENT},
01166
01167 {SMB_VFS_OP(hpuxacl_sys_acl_set_fd),
01168 SMB_VFS_OP_SYS_ACL_SET_FD,
01169 SMB_VFS_LAYER_TRANSPARENT},
01170
01171 {SMB_VFS_OP(hpuxacl_sys_acl_delete_def_file),
01172 SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
01173 SMB_VFS_LAYER_TRANSPARENT},
01174
01175 {SMB_VFS_OP(NULL),
01176 SMB_VFS_OP_NOOP,
01177 SMB_VFS_LAYER_NOOP}
01178 };
01179
01180 NTSTATUS vfs_hpuxacl_init(void)
01181 {
01182 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "hpuxacl",
01183 hpuxacl_op_tuples);
01184 }
01185
01186