00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "rsync.h"
00022 #include "sysacls.h"
00023
00024
00025 void SAFE_FREE(void *mem)
00026 {
00027 if (mem)
00028 free(mem);
00029 }
00030
00031 char *uidtoname(uid_t uid)
00032 {
00033 static char idbuf[12];
00034 struct passwd *pw;
00035
00036 if ((pw = getpwuid(uid)) == NULL) {
00037 slprintf(idbuf, sizeof(idbuf)-1, "%ld", (long)uid);
00038 return idbuf;
00039 }
00040 return pw->pw_name;
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 #if defined(HAVE_POSIX_ACLS)
00090
00091
00092
00093 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
00094 {
00095 return acl_get_entry( the_acl, entry_id, entry_p);
00096 }
00097
00098 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
00099 {
00100 return acl_get_tag_type( entry_d, tag_type_p);
00101 }
00102
00103 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
00104 {
00105 return acl_get_permset( entry_d, permset_p);
00106 }
00107
00108 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
00109 {
00110 return acl_get_qualifier( entry_d);
00111 }
00112
00113 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
00114 {
00115 return acl_get_file( path_p, type);
00116 }
00117
00118 SMB_ACL_T sys_acl_get_fd(int fd)
00119 {
00120 return acl_get_fd(fd);
00121 }
00122
00123 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
00124 {
00125 return acl_clear_perms(permset);
00126 }
00127
00128 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
00129 {
00130 return acl_add_perm(permset, perm);
00131 }
00132
00133 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
00134 {
00135 #if defined(HAVE_ACL_GET_PERM_NP)
00136
00137
00138
00139
00140
00141 return acl_get_perm_np(permset, perm);
00142 #else
00143 return acl_get_perm(permset, perm);
00144 #endif
00145 }
00146
00147 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
00148 {
00149 return acl_to_text( the_acl, plen);
00150 }
00151
00152 SMB_ACL_T sys_acl_init( int count)
00153 {
00154 return acl_init(count);
00155 }
00156
00157 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
00158 {
00159 return acl_create_entry(pacl, pentry);
00160 }
00161
00162 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
00163 {
00164 return acl_set_tag_type(entry, tagtype);
00165 }
00166
00167 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
00168 {
00169 return acl_set_qualifier(entry, qual);
00170 }
00171
00172 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
00173 {
00174 return acl_set_permset(entry, permset);
00175 }
00176
00177 int sys_acl_valid( SMB_ACL_T theacl )
00178 {
00179 return acl_valid(theacl);
00180 }
00181
00182 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
00183 {
00184 return acl_set_file(name, acltype, theacl);
00185 }
00186
00187 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
00188 {
00189 return acl_set_fd(fd, theacl);
00190 }
00191
00192 int sys_acl_delete_def_file(const char *name)
00193 {
00194 return acl_delete_def_file(name);
00195 }
00196
00197 int sys_acl_free_text(char *text)
00198 {
00199 return acl_free(text);
00200 }
00201
00202 int sys_acl_free_acl(SMB_ACL_T the_acl)
00203 {
00204 return acl_free(the_acl);
00205 }
00206
00207 int sys_acl_free_qualifier(void *qual, UNUSED(SMB_ACL_TAG_T tagtype))
00208 {
00209 return acl_free(qual);
00210 }
00211
00212 #elif defined(HAVE_TRU64_ACLS)
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
00224 {
00225 SMB_ACL_ENTRY_T entry;
00226
00227 if (entry_id == SMB_ACL_FIRST_ENTRY && acl_first_entry(the_acl) != 0) {
00228 return -1;
00229 }
00230
00231 errno = 0;
00232 if ((entry = acl_get_entry(the_acl)) != NULL) {
00233 *entry_p = entry;
00234 return 1;
00235 }
00236
00237 return errno ? -1 : 0;
00238 }
00239
00240 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
00241 {
00242 return acl_get_tag_type( entry_d, tag_type_p);
00243 }
00244
00245 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
00246 {
00247 return acl_get_permset( entry_d, permset_p);
00248 }
00249
00250 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
00251 {
00252 return acl_get_qualifier( entry_d);
00253 }
00254
00255 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
00256 {
00257 return acl_get_file((char *)path_p, type);
00258 }
00259
00260 SMB_ACL_T sys_acl_get_fd(int fd)
00261 {
00262 return acl_get_fd(fd, ACL_TYPE_ACCESS);
00263 }
00264
00265 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
00266 {
00267 *permset = 0;
00268
00269 return 0;
00270 }
00271
00272 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
00273 {
00274 if (perm & ~(SMB_ACL_READ | SMB_ACL_WRITE | SMB_ACL_EXECUTE)) {
00275 errno = EINVAL;
00276 return -1;
00277 }
00278
00279 *permset |= perm;
00280
00281 return 0;
00282 }
00283
00284 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
00285 {
00286 return *permset & perm;
00287 }
00288
00289 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
00290 {
00291 return acl_to_text( the_acl, plen);
00292 }
00293
00294 SMB_ACL_T sys_acl_init( int count)
00295 {
00296 return acl_init(count);
00297 }
00298
00299 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
00300 {
00301 SMB_ACL_ENTRY_T entry;
00302
00303 if ((entry = acl_create_entry(pacl)) == NULL) {
00304 return -1;
00305 }
00306
00307 *pentry = entry;
00308 return 0;
00309 }
00310
00311 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
00312 {
00313 return acl_set_tag_type(entry, tagtype);
00314 }
00315
00316 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
00317 {
00318 return acl_set_qualifier(entry, qual);
00319 }
00320
00321 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
00322 {
00323 return acl_set_permset(entry, permset);
00324 }
00325
00326 int sys_acl_valid( SMB_ACL_T theacl )
00327 {
00328 acl_entry_t entry;
00329
00330 return acl_valid(theacl, &entry);
00331 }
00332
00333 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
00334 {
00335 return acl_set_file((char *)name, acltype, theacl);
00336 }
00337
00338 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
00339 {
00340 return acl_set_fd(fd, ACL_TYPE_ACCESS, theacl);
00341 }
00342
00343 int sys_acl_delete_def_file(const char *name)
00344 {
00345 return acl_delete_def_file((char *)name);
00346 }
00347
00348 int sys_acl_free_text(char *text)
00349 {
00350
00351
00352
00353
00354 (void) acl_free_text(text);
00355 return 0;
00356 }
00357
00358 int sys_acl_free_acl(SMB_ACL_T the_acl)
00359 {
00360 return acl_free(the_acl);
00361 }
00362
00363 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
00364 {
00365 return acl_free_qualifier(qual, tagtype);
00366 }
00367
00368 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 #if defined(HAVE_UNIXWARE_ACLS)
00395
00396 #define SETACL ACL_SET
00397 #define GETACL ACL_GET
00398 #define GETACLCNT ACL_CNT
00399
00400 #endif
00401
00402
00403 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
00404 {
00405 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
00406 errno = EINVAL;
00407 return -1;
00408 }
00409
00410 if (entry_p == NULL) {
00411 errno = EINVAL;
00412 return -1;
00413 }
00414
00415 if (entry_id == SMB_ACL_FIRST_ENTRY) {
00416 acl_d->next = 0;
00417 }
00418
00419 if (acl_d->next < 0) {
00420 errno = EINVAL;
00421 return -1;
00422 }
00423
00424 if (acl_d->next >= acl_d->count) {
00425 return 0;
00426 }
00427
00428 *entry_p = &acl_d->acl[acl_d->next++];
00429
00430 return 1;
00431 }
00432
00433 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
00434 {
00435 *type_p = entry_d->a_type;
00436
00437 return 0;
00438 }
00439
00440 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
00441 {
00442 *permset_p = &entry_d->a_perm;
00443
00444 return 0;
00445 }
00446
00447 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
00448 {
00449 if (entry_d->a_type != SMB_ACL_USER
00450 && entry_d->a_type != SMB_ACL_GROUP) {
00451 errno = EINVAL;
00452 return NULL;
00453 }
00454
00455 return &entry_d->a_id;
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 #define INITIAL_ACL_SIZE 16
00471
00472 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
00473 {
00474 SMB_ACL_T acl_d;
00475 int count;
00476 int naccess;
00477 int ndefault;
00478
00479 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
00480 errno = EINVAL;
00481 return NULL;
00482 }
00483
00484 count = INITIAL_ACL_SIZE;
00485 if ((acl_d = sys_acl_init(count)) == NULL) {
00486 return NULL;
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 while ((count = acl(path_p, GETACL, count, &acl_d->acl[0])) < 0
00498 && errno == ENOSPC) {
00499
00500 sys_acl_free_acl(acl_d);
00501
00502 if ((count = acl(path_p, GETACLCNT, 0, NULL)) < 0) {
00503 return NULL;
00504 }
00505
00506 if ((acl_d = sys_acl_init(count)) == NULL) {
00507 return NULL;
00508 }
00509 }
00510
00511 if (count < 0) {
00512 sys_acl_free_acl(acl_d);
00513 return NULL;
00514 }
00515
00516
00517
00518
00519
00520
00521
00522
00523 for (naccess = 0; naccess < count; naccess++) {
00524 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
00525 break;
00526 }
00527 ndefault = count - naccess;
00528
00529
00530
00531
00532
00533
00534 if (type == SMB_ACL_TYPE_DEFAULT) {
00535 int i, j;
00536
00537 for (i = 0, j = naccess; i < ndefault; i++, j++) {
00538 acl_d->acl[i] = acl_d->acl[j];
00539 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
00540 }
00541
00542 acl_d->count = ndefault;
00543 } else {
00544 acl_d->count = naccess;
00545 }
00546
00547 return acl_d;
00548 }
00549
00550 SMB_ACL_T sys_acl_get_fd(int fd)
00551 {
00552 SMB_ACL_T acl_d;
00553 int count;
00554 int naccess;
00555
00556 count = INITIAL_ACL_SIZE;
00557 if ((acl_d = sys_acl_init(count)) == NULL) {
00558 return NULL;
00559 }
00560
00561 while ((count = facl(fd, GETACL, count, &acl_d->acl[0])) < 0
00562 && errno == ENOSPC) {
00563
00564 sys_acl_free_acl(acl_d);
00565
00566 if ((count = facl(fd, GETACLCNT, 0, NULL)) < 0) {
00567 return NULL;
00568 }
00569
00570 if ((acl_d = sys_acl_init(count)) == NULL) {
00571 return NULL;
00572 }
00573 }
00574
00575 if (count < 0) {
00576 sys_acl_free_acl(acl_d);
00577 return NULL;
00578 }
00579
00580
00581
00582
00583 for (naccess = 0; naccess < count; naccess++) {
00584 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
00585 break;
00586 }
00587
00588 acl_d->count = naccess;
00589
00590 return acl_d;
00591 }
00592
00593 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
00594 {
00595 *permset_d = 0;
00596
00597 return 0;
00598 }
00599
00600 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
00601 {
00602 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
00603 && perm != SMB_ACL_EXECUTE) {
00604 errno = EINVAL;
00605 return -1;
00606 }
00607
00608 if (permset_d == NULL) {
00609 errno = EINVAL;
00610 return -1;
00611 }
00612
00613 *permset_d |= perm;
00614
00615 return 0;
00616 }
00617
00618 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
00619 {
00620 return *permset_d & perm;
00621 }
00622
00623 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
00624 {
00625 int i;
00626 int len, maxlen;
00627 char *text;
00628
00629
00630
00631
00632
00633
00634 len = 0;
00635 maxlen = 20 * acl_d->count;
00636 if ((text = SMB_MALLOC(maxlen)) == NULL) {
00637 errno = ENOMEM;
00638 return NULL;
00639 }
00640
00641 for (i = 0; i < acl_d->count; i++) {
00642 struct acl *ap = &acl_d->acl[i];
00643 struct group *gr;
00644 char tagbuf[12];
00645 char idbuf[12];
00646 char *tag;
00647 char *id = "";
00648 char perms[4];
00649 int nbytes;
00650
00651 switch (ap->a_type) {
00652
00653
00654
00655
00656
00657 default:
00658 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
00659 ap->a_type);
00660 tag = tagbuf;
00661 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
00662 (long)ap->a_id);
00663 id = idbuf;
00664 break;
00665
00666 case SMB_ACL_USER:
00667 id = uidtoname(ap->a_id);
00668 case SMB_ACL_USER_OBJ:
00669 tag = "user";
00670 break;
00671
00672 case SMB_ACL_GROUP:
00673 if ((gr = getgrgid(ap->a_id)) == NULL) {
00674 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
00675 (long)ap->a_id);
00676 id = idbuf;
00677 } else {
00678 id = gr->gr_name;
00679 }
00680 case SMB_ACL_GROUP_OBJ:
00681 tag = "group";
00682 break;
00683
00684 case SMB_ACL_OTHER:
00685 tag = "other";
00686 break;
00687
00688 case SMB_ACL_MASK:
00689 tag = "mask";
00690 break;
00691
00692 }
00693
00694 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
00695 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
00696 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
00697 perms[3] = '\0';
00698
00699
00700 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
00701
00702
00703
00704
00705
00706
00707
00708 if ((len + nbytes) > maxlen) {
00709 char *oldtext = text;
00710
00711 maxlen += nbytes + 20 * (acl_d->count - i);
00712
00713 if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) {
00714 SAFE_FREE(oldtext);
00715 errno = ENOMEM;
00716 return NULL;
00717 }
00718 }
00719
00720 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
00721 len += nbytes - 1;
00722 }
00723
00724 if (len_p)
00725 *len_p = len;
00726
00727 return text;
00728 }
00729
00730 SMB_ACL_T sys_acl_init(int count)
00731 {
00732 SMB_ACL_T a;
00733
00734 if (count < 0) {
00735 errno = EINVAL;
00736 return NULL;
00737 }
00738
00739
00740
00741
00742
00743
00744
00745 if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
00746 errno = ENOMEM;
00747 return NULL;
00748 }
00749
00750 a->size = count + 1;
00751 a->count = 0;
00752 a->next = -1;
00753
00754 return a;
00755 }
00756
00757
00758 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
00759 {
00760 SMB_ACL_T acl_d;
00761 SMB_ACL_ENTRY_T entry_d;
00762
00763 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
00764 errno = EINVAL;
00765 return -1;
00766 }
00767
00768 if (acl_d->count >= acl_d->size) {
00769 errno = ENOSPC;
00770 return -1;
00771 }
00772
00773 entry_d = &acl_d->acl[acl_d->count++];
00774 entry_d->a_type = 0;
00775 entry_d->a_id = -1;
00776 entry_d->a_perm = 0;
00777 *entry_p = entry_d;
00778
00779 return 0;
00780 }
00781
00782 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
00783 {
00784 switch (tag_type) {
00785 case SMB_ACL_USER:
00786 case SMB_ACL_USER_OBJ:
00787 case SMB_ACL_GROUP:
00788 case SMB_ACL_GROUP_OBJ:
00789 case SMB_ACL_OTHER:
00790 case SMB_ACL_MASK:
00791 entry_d->a_type = tag_type;
00792 break;
00793 default:
00794 errno = EINVAL;
00795 return -1;
00796 }
00797
00798 return 0;
00799 }
00800
00801 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
00802 {
00803 if (entry_d->a_type != SMB_ACL_GROUP
00804 && entry_d->a_type != SMB_ACL_USER) {
00805 errno = EINVAL;
00806 return -1;
00807 }
00808
00809 entry_d->a_id = *((id_t *)qual_p);
00810
00811 return 0;
00812 }
00813
00814 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
00815 {
00816 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
00817 return EINVAL;
00818 }
00819
00820 entry_d->a_perm = *permset_d;
00821
00822 return 0;
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842 static int acl_sort(SMB_ACL_T acl_d)
00843 {
00844 int fixmask = (acl_d->count <= 4);
00845
00846 if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) {
00847 errno = EINVAL;
00848 return -1;
00849 }
00850 return 0;
00851 }
00852
00853 int sys_acl_valid(SMB_ACL_T acl_d)
00854 {
00855 return acl_sort(acl_d);
00856 }
00857
00858 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
00859 {
00860 struct stat s;
00861 struct acl *acl_p;
00862 int acl_count;
00863 struct acl *acl_buf = NULL;
00864 int ret;
00865
00866 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
00867 errno = EINVAL;
00868 return -1;
00869 }
00870
00871 if (acl_sort(acl_d) != 0) {
00872 return -1;
00873 }
00874
00875 acl_p = &acl_d->acl[0];
00876 acl_count = acl_d->count;
00877
00878
00879
00880
00881
00882
00883 if (stat(name, &s) != 0) {
00884 return -1;
00885 }
00886 if (S_ISDIR(s.st_mode)) {
00887 SMB_ACL_T acc_acl;
00888 SMB_ACL_T def_acl;
00889 SMB_ACL_T tmp_acl;
00890 int i;
00891
00892 if (type == SMB_ACL_TYPE_ACCESS) {
00893 acc_acl = acl_d;
00894 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
00895
00896 } else {
00897 def_acl = acl_d;
00898 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
00899 }
00900
00901 if (tmp_acl == NULL) {
00902 return -1;
00903 }
00904
00905
00906
00907
00908 acl_count = acc_acl->count + def_acl->count;
00909 acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
00910
00911 if (acl_buf == NULL) {
00912 sys_acl_free_acl(tmp_acl);
00913 errno = ENOMEM;
00914 return -1;
00915 }
00916
00917
00918
00919
00920 memcpy(&acl_buf[0], &acc_acl->acl[0],
00921 acc_acl->count * sizeof(acl_buf[0]));
00922
00923 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
00924 def_acl->count * sizeof(acl_buf[0]));
00925
00926
00927
00928
00929 for (i = acc_acl->count; i < acl_count; i++) {
00930 acl_buf[i].a_type |= ACL_DEFAULT;
00931 }
00932
00933 sys_acl_free_acl(tmp_acl);
00934
00935 } else if (type != SMB_ACL_TYPE_ACCESS) {
00936 errno = EINVAL;
00937 return -1;
00938 }
00939
00940 ret = acl(name, SETACL, acl_count, acl_p);
00941
00942 SAFE_FREE(acl_buf);
00943
00944 return ret;
00945 }
00946
00947 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
00948 {
00949 if (acl_sort(acl_d) != 0) {
00950 return -1;
00951 }
00952
00953 return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);
00954 }
00955
00956 int sys_acl_delete_def_file(const char *path)
00957 {
00958 SMB_ACL_T acl_d;
00959 int ret;
00960
00961
00962
00963
00964
00965 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
00966 return -1;
00967 }
00968
00969 ret = acl(path, SETACL, acl_d->count, acl_d->acl);
00970
00971 sys_acl_free_acl(acl_d);
00972
00973 return ret;
00974 }
00975
00976 int sys_acl_free_text(char *text)
00977 {
00978 SAFE_FREE(text);
00979 return 0;
00980 }
00981
00982 int sys_acl_free_acl(SMB_ACL_T acl_d)
00983 {
00984 SAFE_FREE(acl_d);
00985 return 0;
00986 }
00987
00988 int sys_acl_free_qualifier(UNUSED(void *qual), UNUSED(SMB_ACL_TAG_T tagtype))
00989 {
00990 return 0;
00991 }
00992
00993 #elif defined(HAVE_HPUX_ACLS)
00994 #include <dl.h>
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 static BOOL hpux_acl_call_presence(void)
01023 {
01024
01025 shl_t handle = NULL;
01026 void *value;
01027 int ret_val=0;
01028 static BOOL already_checked=0;
01029
01030 if(already_checked)
01031 return True;
01032
01033
01034 ret_val = shl_findsym(&handle, "acl", TYPE_PROCEDURE, &value);
01035
01036 if(ret_val != 0) {
01037 DEBUG(5, ("hpux_acl_call_presence: shl_findsym() returned %d, errno = %d, error %s\n",
01038 ret_val, errno, strerror(errno)));
01039 DEBUG(5,("hpux_acl_call_presence: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));
01040 return False;
01041 }
01042
01043 DEBUG(10,("hpux_acl_call_presence: acl() system call is present. We have JFS 3.3 or above \n"));
01044
01045 already_checked = True;
01046 return True;
01047 }
01048
01049 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
01050 {
01051 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
01052 errno = EINVAL;
01053 return -1;
01054 }
01055
01056 if (entry_p == NULL) {
01057 errno = EINVAL;
01058 return -1;
01059 }
01060
01061 if (entry_id == SMB_ACL_FIRST_ENTRY) {
01062 acl_d->next = 0;
01063 }
01064
01065 if (acl_d->next < 0) {
01066 errno = EINVAL;
01067 return -1;
01068 }
01069
01070 if (acl_d->next >= acl_d->count) {
01071 return 0;
01072 }
01073
01074 *entry_p = &acl_d->acl[acl_d->next++];
01075
01076 return 1;
01077 }
01078
01079 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
01080 {
01081 *type_p = entry_d->a_type;
01082
01083 return 0;
01084 }
01085
01086 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
01087 {
01088 *permset_p = &entry_d->a_perm;
01089
01090 return 0;
01091 }
01092
01093 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
01094 {
01095 if (entry_d->a_type != SMB_ACL_USER
01096 && entry_d->a_type != SMB_ACL_GROUP) {
01097 errno = EINVAL;
01098 return NULL;
01099 }
01100
01101 return &entry_d->a_id;
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116 #define INITIAL_ACL_SIZE 16
01117
01118 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
01119 {
01120 SMB_ACL_T acl_d;
01121 int count;
01122 int naccess;
01123 int ndefault;
01124
01125 if(hpux_acl_call_presence() == False) {
01126
01127
01128
01129 return NULL;
01130 }
01131
01132 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
01133 errno = EINVAL;
01134 return NULL;
01135 }
01136
01137 count = INITIAL_ACL_SIZE;
01138 if ((acl_d = sys_acl_init(count)) == NULL) {
01139 return NULL;
01140 }
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150 while ((count = acl(path_p, ACL_GET, count, &acl_d->acl[0])) < 0 && errno == ENOSPC) {
01151
01152 sys_acl_free_acl(acl_d);
01153
01154 if ((count = acl(path_p, ACL_CNT, 0, NULL)) < 0) {
01155 return NULL;
01156 }
01157
01158 if ((acl_d = sys_acl_init(count)) == NULL) {
01159 return NULL;
01160 }
01161 }
01162
01163 if (count < 0) {
01164 sys_acl_free_acl(acl_d);
01165 return NULL;
01166 }
01167
01168
01169
01170
01171
01172
01173
01174
01175 for (naccess = 0; naccess < count; naccess++) {
01176 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
01177 break;
01178 }
01179 ndefault = count - naccess;
01180
01181
01182
01183
01184
01185
01186 if (type == SMB_ACL_TYPE_DEFAULT) {
01187 int i, j;
01188
01189 for (i = 0, j = naccess; i < ndefault; i++, j++) {
01190 acl_d->acl[i] = acl_d->acl[j];
01191 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
01192 }
01193
01194 acl_d->count = ndefault;
01195 } else {
01196 acl_d->count = naccess;
01197 }
01198
01199 return acl_d;
01200 }
01201
01202 SMB_ACL_T sys_acl_get_fd(int fd)
01203 {
01204
01205
01206
01207
01208 files_struct *fsp = file_find_fd(fd);
01209
01210 if (fsp == NULL) {
01211 errno = EBADF;
01212 return NULL;
01213 }
01214
01215
01216
01217
01218
01219
01220 return sys_acl_get_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
01221 }
01222
01223 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
01224 {
01225 *permset_d = 0;
01226
01227 return 0;
01228 }
01229
01230 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
01231 {
01232 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
01233 && perm != SMB_ACL_EXECUTE) {
01234 errno = EINVAL;
01235 return -1;
01236 }
01237
01238 if (permset_d == NULL) {
01239 errno = EINVAL;
01240 return -1;
01241 }
01242
01243 *permset_d |= perm;
01244
01245 return 0;
01246 }
01247
01248 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
01249 {
01250 return *permset_d & perm;
01251 }
01252
01253 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
01254 {
01255 int i;
01256 int len, maxlen;
01257 char *text;
01258
01259
01260
01261
01262
01263
01264 len = 0;
01265 maxlen = 20 * acl_d->count;
01266 if ((text = SMB_MALLOC(maxlen)) == NULL) {
01267 errno = ENOMEM;
01268 return NULL;
01269 }
01270
01271 for (i = 0; i < acl_d->count; i++) {
01272 struct acl *ap = &acl_d->acl[i];
01273 struct group *gr;
01274 char tagbuf[12];
01275 char idbuf[12];
01276 char *tag;
01277 char *id = "";
01278 char perms[4];
01279 int nbytes;
01280
01281 switch (ap->a_type) {
01282
01283
01284
01285
01286
01287 default:
01288 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
01289 ap->a_type);
01290 tag = tagbuf;
01291 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
01292 (long)ap->a_id);
01293 id = idbuf;
01294 break;
01295
01296 case SMB_ACL_USER:
01297 id = uidtoname(ap->a_id);
01298 case SMB_ACL_USER_OBJ:
01299 tag = "user";
01300 break;
01301
01302 case SMB_ACL_GROUP:
01303 if ((gr = getgrgid(ap->a_id)) == NULL) {
01304 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
01305 (long)ap->a_id);
01306 id = idbuf;
01307 } else {
01308 id = gr->gr_name;
01309 }
01310 case SMB_ACL_GROUP_OBJ:
01311 tag = "group";
01312 break;
01313
01314 case SMB_ACL_OTHER:
01315 tag = "other";
01316 break;
01317
01318 case SMB_ACL_MASK:
01319 tag = "mask";
01320 break;
01321
01322 }
01323
01324 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
01325 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
01326 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
01327 perms[3] = '\0';
01328
01329
01330 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
01331
01332
01333
01334
01335
01336
01337
01338 if ((len + nbytes) > maxlen) {
01339 char *oldtext = text;
01340
01341 maxlen += nbytes + 20 * (acl_d->count - i);
01342
01343 if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) {
01344 free(oldtext);
01345 errno = ENOMEM;
01346 return NULL;
01347 }
01348 }
01349
01350 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
01351 len += nbytes - 1;
01352 }
01353
01354 if (len_p)
01355 *len_p = len;
01356
01357 return text;
01358 }
01359
01360 SMB_ACL_T sys_acl_init(int count)
01361 {
01362 SMB_ACL_T a;
01363
01364 if (count < 0) {
01365 errno = EINVAL;
01366 return NULL;
01367 }
01368
01369
01370
01371
01372
01373
01374
01375 if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
01376 errno = ENOMEM;
01377 return NULL;
01378 }
01379
01380 a->size = count + 1;
01381 a->count = 0;
01382 a->next = -1;
01383
01384 return a;
01385 }
01386
01387
01388 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
01389 {
01390 SMB_ACL_T acl_d;
01391 SMB_ACL_ENTRY_T entry_d;
01392
01393 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
01394 errno = EINVAL;
01395 return -1;
01396 }
01397
01398 if (acl_d->count >= acl_d->size) {
01399 errno = ENOSPC;
01400 return -1;
01401 }
01402
01403 entry_d = &acl_d->acl[acl_d->count++];
01404 entry_d->a_type = 0;
01405 entry_d->a_id = -1;
01406 entry_d->a_perm = 0;
01407 *entry_p = entry_d;
01408
01409 return 0;
01410 }
01411
01412 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
01413 {
01414 switch (tag_type) {
01415 case SMB_ACL_USER:
01416 case SMB_ACL_USER_OBJ:
01417 case SMB_ACL_GROUP:
01418 case SMB_ACL_GROUP_OBJ:
01419 case SMB_ACL_OTHER:
01420 case SMB_ACL_MASK:
01421 entry_d->a_type = tag_type;
01422 break;
01423 default:
01424 errno = EINVAL;
01425 return -1;
01426 }
01427
01428 return 0;
01429 }
01430
01431 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
01432 {
01433 if (entry_d->a_type != SMB_ACL_GROUP
01434 && entry_d->a_type != SMB_ACL_USER) {
01435 errno = EINVAL;
01436 return -1;
01437 }
01438
01439 entry_d->a_id = *((id_t *)qual_p);
01440
01441 return 0;
01442 }
01443
01444 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
01445 {
01446 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
01447 return EINVAL;
01448 }
01449
01450 entry_d->a_perm = *permset_d;
01451
01452 return 0;
01453 }
01454
01455
01456
01457 struct hpux_acl_types {
01458 int n_user;
01459 int n_def_user;
01460 int n_user_obj;
01461 int n_def_user_obj;
01462
01463 int n_group;
01464 int n_def_group;
01465 int n_group_obj;
01466 int n_def_group_obj;
01467
01468 int n_other;
01469 int n_other_obj;
01470 int n_def_other_obj;
01471
01472 int n_class_obj;
01473 int n_def_class_obj;
01474
01475 int n_illegal_obj;
01476 };
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493 static int hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_types *acl_type_count)
01494 {
01495 int i;
01496
01497 memset(acl_type_count, 0, sizeof(struct hpux_acl_types));
01498
01499 for(i=0;i<acl_count;i++) {
01500 switch(aclp[i].a_type) {
01501 case USER:
01502 acl_type_count->n_user++;
01503 break;
01504 case USER_OBJ:
01505 acl_type_count->n_user_obj++;
01506 break;
01507 case DEF_USER_OBJ:
01508 acl_type_count->n_def_user_obj++;
01509 break;
01510 case GROUP:
01511 acl_type_count->n_group++;
01512 break;
01513 case GROUP_OBJ:
01514 acl_type_count->n_group_obj++;
01515 break;
01516 case DEF_GROUP_OBJ:
01517 acl_type_count->n_def_group_obj++;
01518 break;
01519 case OTHER_OBJ:
01520 acl_type_count->n_other_obj++;
01521 break;
01522 case DEF_OTHER_OBJ:
01523 acl_type_count->n_def_other_obj++;
01524 break;
01525 case CLASS_OBJ:
01526 acl_type_count->n_class_obj++;
01527 break;
01528 case DEF_CLASS_OBJ:
01529 acl_type_count->n_def_class_obj++;
01530 break;
01531 case DEF_USER:
01532 acl_type_count->n_def_user++;
01533 break;
01534 case DEF_GROUP:
01535 acl_type_count->n_def_group++;
01536 break;
01537 default:
01538 acl_type_count->n_illegal_obj++;
01539 break;
01540 }
01541 }
01542 }
01543
01544
01545
01546
01547
01548
01549 static void hpux_swap_acl_entries(struct acl *aclp0, struct acl *aclp1)
01550 {
01551 struct acl temp_acl;
01552
01553 temp_acl.a_type = aclp0->a_type;
01554 temp_acl.a_id = aclp0->a_id;
01555 temp_acl.a_perm = aclp0->a_perm;
01556
01557 aclp0->a_type = aclp1->a_type;
01558 aclp0->a_id = aclp1->a_id;
01559 aclp0->a_perm = aclp1->a_perm;
01560
01561 aclp1->a_type = temp_acl.a_type;
01562 aclp1->a_id = temp_acl.a_id;
01563 aclp1->a_perm = temp_acl.a_perm;
01564 }
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580 static BOOL hpux_prohibited_duplicate_type(int acl_type)
01581 {
01582 switch(acl_type) {
01583 case USER:
01584 case GROUP:
01585 case DEF_USER:
01586 case DEF_GROUP:
01587 return True;
01588 default:
01589 return False;
01590 }
01591 }
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601 static int hpux_get_needed_class_perm(struct acl *aclp)
01602 {
01603 switch(aclp->a_type) {
01604 case USER:
01605 case GROUP_OBJ:
01606 case GROUP:
01607 case DEF_USER_OBJ:
01608 case DEF_USER:
01609 case DEF_GROUP_OBJ:
01610 case DEF_GROUP:
01611 case DEF_CLASS_OBJ:
01612 case DEF_OTHER_OBJ:
01613 return aclp->a_perm;
01614 default:
01615 return 0;
01616 }
01617 }
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640 static int hpux_acl_sort(int acl_count, int calclass, struct acl *aclp)
01641 {
01642 #if !defined(HAVE_HPUX_ACLSORT)
01643
01644
01645
01646
01647
01648
01649
01650 struct hpux_acl_types acl_obj_count;
01651 int n_class_obj_perm = 0;
01652 int i, j;
01653
01654 if(!acl_count) {
01655 DEBUG(10,("Zero acl count passed. Returning Success\n"));
01656 return 0;
01657 }
01658
01659 if(aclp == NULL) {
01660 DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
01661 return -1;
01662 }
01663
01664
01665
01666 hpux_count_obj(acl_count, aclp, &acl_obj_count);
01667
01668
01669
01670
01671
01672 if( (acl_obj_count.n_user_obj != 1) ||
01673 (acl_obj_count.n_group_obj != 1) ||
01674 (acl_obj_count.n_class_obj != 1) ||
01675 (acl_obj_count.n_other_obj != 1)
01676 ) {
01677 DEBUG(0,("hpux_acl_sort: More than one entry or no entries for \
01678 USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
01679 return -1;
01680 }
01681
01682
01683
01684
01685
01686 if( (acl_obj_count.n_def_user_obj > 1) || (acl_obj_count.n_def_group_obj > 1) ||
01687 (acl_obj_count.n_def_other_obj > 1) || (acl_obj_count.n_def_class_obj > 1) ) {
01688 DEBUG(0,("hpux_acl_sort: More than one entry for DEF_CLASS_OBJ \
01689 or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
01690 return -1;
01691 }
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704 for(i=0; i<acl_count;i++) {
01705 for (j=i+1; j<acl_count; j++) {
01706 if( aclp[i].a_type > aclp[j].a_type ) {
01707
01708
01709 hpux_swap_acl_entries((aclp+i), (aclp+j));
01710
01711 } else if ( aclp[i].a_type == aclp[j].a_type ) {
01712
01713
01714
01715 if(aclp[i].a_id > aclp[j].a_id) {
01716 hpux_swap_acl_entries((aclp+i), (aclp+j));
01717 } else if (aclp[i].a_id == aclp[j].a_id) {
01718
01719 if(hpux_prohibited_duplicate_type(aclp[i].a_type)) {
01720 DEBUG(0, ("hpux_acl_sort: Duplicate entry: Type(hex): %x Id: %d\n",
01721 aclp[i].a_type, aclp[i].a_id));
01722 return -1;
01723 }
01724 }
01725
01726 }
01727 }
01728 }
01729
01730
01731 if(calclass) {
01732 int n_class_obj_index = -1;
01733
01734 for(i=0;i<acl_count;i++) {
01735 n_class_obj_perm |= hpux_get_needed_class_perm((aclp+i));
01736
01737 if(aclp[i].a_type == CLASS_OBJ)
01738 n_class_obj_index = i;
01739 }
01740 aclp[n_class_obj_index].a_perm = n_class_obj_perm;
01741 }
01742
01743 return 0;
01744 #else
01745 return aclsort(acl_count, calclass, aclp);
01746 #endif
01747 }
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766 static int acl_sort(SMB_ACL_T acl_d)
01767 {
01768 int fixmask = (acl_d->count <= 4);
01769
01770 if (hpux_acl_sort(acl_d->count, fixmask, acl_d->acl) != 0) {
01771 errno = EINVAL;
01772 return -1;
01773 }
01774 return 0;
01775 }
01776
01777 int sys_acl_valid(SMB_ACL_T acl_d)
01778 {
01779 return acl_sort(acl_d);
01780 }
01781
01782 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
01783 {
01784 struct stat s;
01785 struct acl *acl_p;
01786 int acl_count;
01787 struct acl *acl_buf = NULL;
01788 int ret;
01789
01790 if(hpux_acl_call_presence() == False) {
01791
01792
01793
01794 errno=ENOSYS;
01795 return -1;
01796 }
01797
01798 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
01799 errno = EINVAL;
01800 return -1;
01801 }
01802
01803 if (acl_sort(acl_d) != 0) {
01804 return -1;
01805 }
01806
01807 acl_p = &acl_d->acl[0];
01808 acl_count = acl_d->count;
01809
01810
01811
01812
01813
01814
01815 if (stat(name, &s) != 0) {
01816 return -1;
01817 }
01818 if (S_ISDIR(s.st_mode)) {
01819 SMB_ACL_T acc_acl;
01820 SMB_ACL_T def_acl;
01821 SMB_ACL_T tmp_acl;
01822 int i;
01823
01824 if (type == SMB_ACL_TYPE_ACCESS) {
01825 acc_acl = acl_d;
01826 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
01827
01828 } else {
01829 def_acl = acl_d;
01830 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
01831 }
01832
01833 if (tmp_acl == NULL) {
01834 return -1;
01835 }
01836
01837
01838
01839
01840 acl_count = acc_acl->count + def_acl->count;
01841 acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
01842
01843 if (acl_buf == NULL) {
01844 sys_acl_free_acl(tmp_acl);
01845 errno = ENOMEM;
01846 return -1;
01847 }
01848
01849
01850
01851
01852 memcpy(&acl_buf[0], &acc_acl->acl[0],
01853 acc_acl->count * sizeof(acl_buf[0]));
01854
01855 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
01856 def_acl->count * sizeof(acl_buf[0]));
01857
01858
01859
01860
01861 for (i = acc_acl->count; i < acl_count; i++) {
01862 acl_buf[i].a_type |= ACL_DEFAULT;
01863 }
01864
01865 sys_acl_free_acl(tmp_acl);
01866
01867 } else if (type != SMB_ACL_TYPE_ACCESS) {
01868 errno = EINVAL;
01869 return -1;
01870 }
01871
01872 ret = acl(name, ACL_SET, acl_count, acl_p);
01873
01874 if (acl_buf) {
01875 free(acl_buf);
01876 }
01877
01878 return ret;
01879 }
01880
01881 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
01882 {
01883
01884
01885
01886
01887 files_struct *fsp = file_find_fd(fd);
01888
01889 if (fsp == NULL) {
01890 errno = EBADF;
01891 return NULL;
01892 }
01893
01894 if (acl_sort(acl_d) != 0) {
01895 return -1;
01896 }
01897
01898
01899
01900
01901
01902
01903 return sys_acl_set_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS, acl_d);
01904 }
01905
01906 int sys_acl_delete_def_file(const char *path)
01907 {
01908 SMB_ACL_T acl_d;
01909 int ret;
01910
01911
01912
01913
01914
01915 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
01916 return -1;
01917 }
01918
01919 ret = acl(path, ACL_SET, acl_d->count, acl_d->acl);
01920
01921 sys_acl_free_acl(acl_d);
01922
01923 return ret;
01924 }
01925
01926 int sys_acl_free_text(char *text)
01927 {
01928 free(text);
01929 return 0;
01930 }
01931
01932 int sys_acl_free_acl(SMB_ACL_T acl_d)
01933 {
01934 free(acl_d);
01935 return 0;
01936 }
01937
01938 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
01939 {
01940 return 0;
01941 }
01942
01943 #elif defined(HAVE_IRIX_ACLS)
01944
01945 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
01946 {
01947 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
01948 errno = EINVAL;
01949 return -1;
01950 }
01951
01952 if (entry_p == NULL) {
01953 errno = EINVAL;
01954 return -1;
01955 }
01956
01957 if (entry_id == SMB_ACL_FIRST_ENTRY) {
01958 acl_d->next = 0;
01959 }
01960
01961 if (acl_d->next < 0) {
01962 errno = EINVAL;
01963 return -1;
01964 }
01965
01966 if (acl_d->next >= acl_d->aclp->acl_cnt) {
01967 return 0;
01968 }
01969
01970 *entry_p = &acl_d->aclp->acl_entry[acl_d->next++];
01971
01972 return 1;
01973 }
01974
01975 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
01976 {
01977 *type_p = entry_d->ae_tag;
01978
01979 return 0;
01980 }
01981
01982 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
01983 {
01984 *permset_p = entry_d;
01985
01986 return 0;
01987 }
01988
01989 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
01990 {
01991 if (entry_d->ae_tag != SMB_ACL_USER
01992 && entry_d->ae_tag != SMB_ACL_GROUP) {
01993 errno = EINVAL;
01994 return NULL;
01995 }
01996
01997 return &entry_d->ae_id;
01998 }
01999
02000 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
02001 {
02002 SMB_ACL_T a;
02003
02004 if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
02005 errno = ENOMEM;
02006 return NULL;
02007 }
02008 if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
02009 SAFE_FREE(a);
02010 return NULL;
02011 }
02012 a->next = -1;
02013 a->freeaclp = True;
02014 return a;
02015 }
02016
02017 SMB_ACL_T sys_acl_get_fd(int fd)
02018 {
02019 SMB_ACL_T a;
02020
02021 if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
02022 errno = ENOMEM;
02023 return NULL;
02024 }
02025 if ((a->aclp = acl_get_fd(fd)) == NULL) {
02026 SAFE_FREE(a);
02027 return NULL;
02028 }
02029 a->next = -1;
02030 a->freeaclp = True;
02031 return a;
02032 }
02033
02034 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
02035 {
02036 permset_d->ae_perm = 0;
02037
02038 return 0;
02039 }
02040
02041 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
02042 {
02043 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
02044 && perm != SMB_ACL_EXECUTE) {
02045 errno = EINVAL;
02046 return -1;
02047 }
02048
02049 if (permset_d == NULL) {
02050 errno = EINVAL;
02051 return -1;
02052 }
02053
02054 permset_d->ae_perm |= perm;
02055
02056 return 0;
02057 }
02058
02059 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
02060 {
02061 return permset_d->ae_perm & perm;
02062 }
02063
02064 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
02065 {
02066 return acl_to_text(acl_d->aclp, len_p);
02067 }
02068
02069 SMB_ACL_T sys_acl_init(int count)
02070 {
02071 SMB_ACL_T a;
02072
02073 if (count < 0) {
02074 errno = EINVAL;
02075 return NULL;
02076 }
02077
02078 if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + sizeof(struct acl))) == NULL) {
02079 errno = ENOMEM;
02080 return NULL;
02081 }
02082
02083 a->next = -1;
02084 a->freeaclp = False;
02085 a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *));
02086 a->aclp->acl_cnt = 0;
02087
02088 return a;
02089 }
02090
02091
02092 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
02093 {
02094 SMB_ACL_T acl_d;
02095 SMB_ACL_ENTRY_T entry_d;
02096
02097 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
02098 errno = EINVAL;
02099 return -1;
02100 }
02101
02102 if (acl_d->aclp->acl_cnt >= ACL_MAX_ENTRIES) {
02103 errno = ENOSPC;
02104 return -1;
02105 }
02106
02107 entry_d = &acl_d->aclp->acl_entry[acl_d->aclp->acl_cnt++];
02108 entry_d->ae_tag = 0;
02109 entry_d->ae_id = 0;
02110 entry_d->ae_perm = 0;
02111 *entry_p = entry_d;
02112
02113 return 0;
02114 }
02115
02116 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
02117 {
02118 switch (tag_type) {
02119 case SMB_ACL_USER:
02120 case SMB_ACL_USER_OBJ:
02121 case SMB_ACL_GROUP:
02122 case SMB_ACL_GROUP_OBJ:
02123 case SMB_ACL_OTHER:
02124 case SMB_ACL_MASK:
02125 entry_d->ae_tag = tag_type;
02126 break;
02127 default:
02128 errno = EINVAL;
02129 return -1;
02130 }
02131
02132 return 0;
02133 }
02134
02135 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
02136 {
02137 if (entry_d->ae_tag != SMB_ACL_GROUP
02138 && entry_d->ae_tag != SMB_ACL_USER) {
02139 errno = EINVAL;
02140 return -1;
02141 }
02142
02143 entry_d->ae_id = *((id_t *)qual_p);
02144
02145 return 0;
02146 }
02147
02148 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
02149 {
02150 if (permset_d->ae_perm & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
02151 return EINVAL;
02152 }
02153
02154 entry_d->ae_perm = permset_d->ae_perm;
02155
02156 return 0;
02157 }
02158
02159 int sys_acl_valid(SMB_ACL_T acl_d)
02160 {
02161 return acl_valid(acl_d->aclp);
02162 }
02163
02164 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
02165 {
02166 return acl_set_file(name, type, acl_d->aclp);
02167 }
02168
02169 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
02170 {
02171 return acl_set_fd(fd, acl_d->aclp);
02172 }
02173
02174 int sys_acl_delete_def_file(const char *name)
02175 {
02176 return acl_delete_def_file(name);
02177 }
02178
02179 int sys_acl_free_text(char *text)
02180 {
02181 return acl_free(text);
02182 }
02183
02184 int sys_acl_free_acl(SMB_ACL_T acl_d)
02185 {
02186 if (acl_d->freeaclp) {
02187 acl_free(acl_d->aclp);
02188 }
02189 acl_free(acl_d);
02190 return 0;
02191 }
02192
02193 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
02194 {
02195 return 0;
02196 }
02197
02198 #elif defined(HAVE_AIX_ACLS)
02199
02200
02201
02202 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
02203 {
02204 struct acl_entry_link *link;
02205 struct new_acl_entry *entry;
02206 int keep_going;
02207
02208 DEBUG(10,("This is the count: %d\n",theacl->count));
02209
02210
02211
02212
02213 if(theacl->count == -1)
02214 return(0);
02215
02216 link = theacl;
02217
02218
02219
02220
02221 for(keep_going = 0; keep_going < theacl->count; keep_going++)
02222 link = link->nextp;
02223
02224 entry = *entry_p = link->entryp;
02225
02226 DEBUG(10,("*entry_p is %d\n",entry_p));
02227 DEBUG(10,("*entry_p->ace_access is %d\n",entry->ace_access));
02228
02229
02230 theacl->count++;
02231 if(link->nextp == NULL)
02232 theacl->count = -1;
02233
02234 return(1);
02235 }
02236
02237 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
02238 {
02239
02240
02241 *tag_type_p = -1;
02242 DEBUG(10,("the tagtype is %d\n",entry_d->ace_id->id_type));
02243
02244
02245
02246 switch(entry_d->ace_id->id_type) {
02247 case ACEID_USER:
02248 *tag_type_p = SMB_ACL_USER;
02249 break;
02250 case ACEID_GROUP:
02251 *tag_type_p = SMB_ACL_GROUP;
02252 break;
02253
02254 case SMB_ACL_USER_OBJ:
02255 case SMB_ACL_GROUP_OBJ:
02256 case SMB_ACL_OTHER:
02257 *tag_type_p = entry_d->ace_id->id_type;
02258 break;
02259
02260 default:
02261 return(-1);
02262 }
02263
02264 return(0);
02265 }
02266
02267 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
02268 {
02269 DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
02270 *permset_p = &entry_d->ace_access;
02271 DEBUG(10,("**permset_p is %d\n",**permset_p));
02272 if(!(**permset_p & S_IXUSR) &&
02273 !(**permset_p & S_IWUSR) &&
02274 !(**permset_p & S_IRUSR) &&
02275 (**permset_p != 0))
02276 return(-1);
02277
02278 DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
02279 return(0);
02280 }
02281
02282 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
02283 {
02284 return(entry_d->ace_id->id_data);
02285 }
02286
02287 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
02288 {
02289 struct acl *file_acl = (struct acl *)NULL;
02290 struct acl_entry *acl_entry;
02291 struct new_acl_entry *new_acl_entry;
02292 struct ace_id *idp;
02293 struct acl_entry_link *acl_entry_link;
02294 struct acl_entry_link *acl_entry_link_head;
02295 int i;
02296 int rc = 0;
02297 uid_t user_id;
02298
02299
02300 if ( type == SMB_ACL_TYPE_DEFAULT )
02301 return NULL;
02302
02303
02304
02305 DEBUG(10,("Entering sys_acl_get_file\n"));
02306 DEBUG(10,("path_p is %s\n",path_p));
02307
02308 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
02309
02310 if(file_acl == NULL) {
02311 errno=ENOMEM;
02312 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
02313 return(NULL);
02314 }
02315
02316 memset(file_acl,0,BUFSIZ);
02317
02318 rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
02319 if(rc == -1) {
02320 DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
02321 SAFE_FREE(file_acl);
02322 return(NULL);
02323 }
02324
02325 DEBUG(10,("Got facl and returned it\n"));
02326
02327
02328 acl_entry = file_acl->acl_ext;
02329
02330
02331
02332
02333
02334
02335 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
02336 if(acl_entry_link_head == NULL)
02337 return(NULL);
02338
02339 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
02340 if(acl_entry_link->entryp == NULL) {
02341 SAFE_FREE(file_acl);
02342 errno = ENOMEM;
02343 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
02344 return(NULL);
02345 }
02346
02347 DEBUG(10,("acl_entry is %d\n",acl_entry));
02348 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
02349
02350
02351
02352
02353
02354
02355 if(file_acl->acl_mode & S_IXACL){
02356
02357 while(acl_entry < acl_last(file_acl)) {
02358
02359
02360 idp = id_nxt(acl_entry->ace_id);
02361 if((acl_entry->ace_type == ACC_SPECIFY ||
02362 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
02363 acl_entry = acl_nxt(acl_entry);
02364 continue;
02365 }
02366
02367 idp = acl_entry->ace_id;
02368
02369
02370
02371
02372
02373 if(acl_entry_link_head->count != 0) {
02374 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
02375
02376 if(acl_entry_link->nextp == NULL) {
02377 SAFE_FREE(file_acl);
02378 errno = ENOMEM;
02379 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
02380 return(NULL);
02381 }
02382
02383 acl_entry_link->nextp->prevp = acl_entry_link;
02384 acl_entry_link = acl_entry_link->nextp;
02385 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
02386 if(acl_entry_link->entryp == NULL) {
02387 SAFE_FREE(file_acl);
02388 errno = ENOMEM;
02389 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
02390 return(NULL);
02391 }
02392 acl_entry_link->nextp = NULL;
02393 }
02394
02395 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
02396
02397
02398
02399
02400 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
02401
02402 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
02403
02404 memcpy(acl_entry_link->entryp->ace_id,idp,sizeof(struct ace_id));
02405
02406
02407
02408
02409
02410 switch(acl_entry->ace_type){
02411 case ACC_PERMIT:
02412 case ACC_SPECIFY:
02413 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
02414 acl_entry_link->entryp->ace_access <<= 6;
02415 acl_entry_link_head->count++;
02416 break;
02417 case ACC_DENY:
02418
02419
02420 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
02421 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
02422 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
02423 acl_entry_link->entryp->ace_access <<= 6;
02424 acl_entry_link_head->count++;
02425 break;
02426 default:
02427 return(0);
02428 }
02429
02430 DEBUG(10,("acl_entry = %d\n",acl_entry));
02431 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
02432
02433 acl_entry = acl_nxt(acl_entry);
02434 }
02435 }
02436
02437
02438
02439
02440
02441 for( i = 1; i < 4; i++) {
02442 DEBUG(10,("i is %d\n",i));
02443 if(acl_entry_link_head->count != 0) {
02444 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
02445 if(acl_entry_link->nextp == NULL) {
02446 SAFE_FREE(file_acl);
02447 errno = ENOMEM;
02448 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
02449 return(NULL);
02450 }
02451
02452 acl_entry_link->nextp->prevp = acl_entry_link;
02453 acl_entry_link = acl_entry_link->nextp;
02454 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
02455 if(acl_entry_link->entryp == NULL) {
02456 SAFE_FREE(file_acl);
02457 errno = ENOMEM;
02458 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
02459 return(NULL);
02460 }
02461 }
02462
02463 acl_entry_link->nextp = NULL;
02464
02465 new_acl_entry = acl_entry_link->entryp;
02466 idp = new_acl_entry->ace_id;
02467
02468 new_acl_entry->ace_len = sizeof(struct acl_entry);
02469 new_acl_entry->ace_type = ACC_PERMIT;
02470 idp->id_len = sizeof(struct ace_id);
02471 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
02472 memset(idp->id_data,0,sizeof(uid_t));
02473
02474 switch(i) {
02475 case 2:
02476 new_acl_entry->ace_access = file_acl->g_access << 6;
02477 idp->id_type = SMB_ACL_GROUP_OBJ;
02478 break;
02479
02480 case 3:
02481 new_acl_entry->ace_access = file_acl->o_access << 6;
02482 idp->id_type = SMB_ACL_OTHER;
02483 break;
02484
02485 case 1:
02486 new_acl_entry->ace_access = file_acl->u_access << 6;
02487 idp->id_type = SMB_ACL_USER_OBJ;
02488 break;
02489
02490 default:
02491 return(NULL);
02492
02493 }
02494
02495 acl_entry_link_head->count++;
02496 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
02497 }
02498
02499 acl_entry_link_head->count = 0;
02500 SAFE_FREE(file_acl);
02501
02502 return(acl_entry_link_head);
02503 }
02504
02505 SMB_ACL_T sys_acl_get_fd(int fd)
02506 {
02507 struct acl *file_acl = (struct acl *)NULL;
02508 struct acl_entry *acl_entry;
02509 struct new_acl_entry *new_acl_entry;
02510 struct ace_id *idp;
02511 struct acl_entry_link *acl_entry_link;
02512 struct acl_entry_link *acl_entry_link_head;
02513 int i;
02514 int rc = 0;
02515 uid_t user_id;
02516
02517
02518
02519 DEBUG(10,("Entering sys_acl_get_fd\n"));
02520 DEBUG(10,("fd is %d\n",fd));
02521 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
02522
02523 if(file_acl == NULL) {
02524 errno=ENOMEM;
02525 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
02526 return(NULL);
02527 }
02528
02529 memset(file_acl,0,BUFSIZ);
02530
02531 rc = fstatacl(fd,0,file_acl,BUFSIZ);
02532 if(rc == -1) {
02533 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
02534 SAFE_FREE(file_acl);
02535 return(NULL);
02536 }
02537
02538 DEBUG(10,("Got facl and returned it\n"));
02539
02540
02541
02542 acl_entry = file_acl->acl_ext;
02543
02544
02545
02546
02547
02548 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
02549 if(acl_entry_link_head == NULL){
02550 SAFE_FREE(file_acl);
02551 return(NULL);
02552 }
02553
02554 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
02555
02556 if(acl_entry_link->entryp == NULL) {
02557 errno = ENOMEM;
02558 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
02559 SAFE_FREE(file_acl);
02560 return(NULL);
02561 }
02562
02563 DEBUG(10,("acl_entry is %d\n",acl_entry));
02564 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
02565
02566
02567
02568
02569
02570
02571 if(file_acl->acl_mode & S_IXACL){
02572
02573 while(acl_entry < acl_last(file_acl)) {
02574
02575
02576
02577 idp = id_nxt(acl_entry->ace_id);
02578 if((acl_entry->ace_type == ACC_SPECIFY ||
02579 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
02580 acl_entry = acl_nxt(acl_entry);
02581 continue;
02582 }
02583
02584 idp = acl_entry->ace_id;
02585
02586
02587
02588
02589
02590 if(acl_entry_link_head->count != 0) {
02591 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
02592 if(acl_entry_link->nextp == NULL) {
02593 errno = ENOMEM;
02594 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
02595 SAFE_FREE(file_acl);
02596 return(NULL);
02597 }
02598 acl_entry_link->nextp->prevp = acl_entry_link;
02599 acl_entry_link = acl_entry_link->nextp;
02600 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
02601 if(acl_entry_link->entryp == NULL) {
02602 errno = ENOMEM;
02603 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
02604 SAFE_FREE(file_acl);
02605 return(NULL);
02606 }
02607
02608 acl_entry_link->nextp = NULL;
02609 }
02610
02611 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
02612
02613
02614
02615
02616 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
02617 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
02618
02619 memcpy(acl_entry_link->entryp->ace_id, idp, sizeof(struct ace_id));
02620
02621
02622
02623
02624
02625 switch(acl_entry->ace_type){
02626 case ACC_PERMIT:
02627 case ACC_SPECIFY:
02628 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
02629 acl_entry_link->entryp->ace_access <<= 6;
02630 acl_entry_link_head->count++;
02631 break;
02632 case ACC_DENY:
02633
02634
02635 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
02636 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
02637 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
02638 acl_entry_link->entryp->ace_access <<= 6;
02639 acl_entry_link_head->count++;
02640 break;
02641 default:
02642 return(0);
02643 }
02644
02645 DEBUG(10,("acl_entry = %d\n",acl_entry));
02646 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
02647
02648 acl_entry = acl_nxt(acl_entry);
02649 }
02650 }
02651
02652
02653
02654
02655
02656 for( i = 1; i < 4; i++) {
02657 DEBUG(10,("i is %d\n",i));
02658 if(acl_entry_link_head->count != 0){
02659 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
02660 if(acl_entry_link->nextp == NULL) {
02661 errno = ENOMEM;
02662 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
02663 SAFE_FREE(file_acl);
02664 return(NULL);
02665 }
02666
02667 acl_entry_link->nextp->prevp = acl_entry_link;
02668 acl_entry_link = acl_entry_link->nextp;
02669 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
02670
02671 if(acl_entry_link->entryp == NULL) {
02672 SAFE_FREE(file_acl);
02673 errno = ENOMEM;
02674 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
02675 return(NULL);
02676 }
02677 }
02678
02679 acl_entry_link->nextp = NULL;
02680
02681 new_acl_entry = acl_entry_link->entryp;
02682 idp = new_acl_entry->ace_id;
02683
02684 new_acl_entry->ace_len = sizeof(struct acl_entry);
02685 new_acl_entry->ace_type = ACC_PERMIT;
02686 idp->id_len = sizeof(struct ace_id);
02687 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
02688 memset(idp->id_data,0,sizeof(uid_t));
02689
02690 switch(i) {
02691 case 2:
02692 new_acl_entry->ace_access = file_acl->g_access << 6;
02693 idp->id_type = SMB_ACL_GROUP_OBJ;
02694 break;
02695
02696 case 3:
02697 new_acl_entry->ace_access = file_acl->o_access << 6;
02698 idp->id_type = SMB_ACL_OTHER;
02699 break;
02700
02701 case 1:
02702 new_acl_entry->ace_access = file_acl->u_access << 6;
02703 idp->id_type = SMB_ACL_USER_OBJ;
02704 break;
02705
02706 default:
02707 return(NULL);
02708 }
02709
02710 acl_entry_link_head->count++;
02711 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
02712 }
02713
02714 acl_entry_link_head->count = 0;
02715 SAFE_FREE(file_acl);
02716
02717 return(acl_entry_link_head);
02718 }
02719
02720 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
02721 {
02722 *permset = *permset & ~0777;
02723 return(0);
02724 }
02725
02726 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
02727 {
02728 if((perm != 0) &&
02729 (perm & (S_IXUSR | S_IWUSR | S_IRUSR)) == 0)
02730 return(-1);
02731
02732 *permset |= perm;
02733 DEBUG(10,("This is the permset now: %d\n",*permset));
02734 return(0);
02735 }
02736
02737 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
02738 {
02739 return(NULL);
02740 }
02741
02742 SMB_ACL_T sys_acl_init( int count)
02743 {
02744 struct acl_entry_link *theacl = NULL;
02745
02746 DEBUG(10,("Entering sys_acl_init\n"));
02747
02748 theacl = SMB_MALLOC_P(struct acl_entry_link);
02749 if(theacl == NULL) {
02750 errno = ENOMEM;
02751 DEBUG(0,("Error in sys_acl_init is %d\n",errno));
02752 return(NULL);
02753 }
02754
02755 theacl->count = 0;
02756 theacl->nextp = NULL;
02757 theacl->prevp = NULL;
02758 theacl->entryp = NULL;
02759 DEBUG(10,("Exiting sys_acl_init\n"));
02760 return(theacl);
02761 }
02762
02763 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
02764 {
02765 struct acl_entry_link *theacl;
02766 struct acl_entry_link *acl_entryp;
02767 struct acl_entry_link *temp_entry;
02768 int counting;
02769
02770 DEBUG(10,("Entering the sys_acl_create_entry\n"));
02771
02772 theacl = acl_entryp = *pacl;
02773
02774
02775
02776 for(counting=0; counting < theacl->count; counting++){
02777 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
02778 temp_entry = acl_entryp;
02779 acl_entryp = acl_entryp->nextp;
02780 }
02781
02782 if(theacl->count != 0){
02783 temp_entry->nextp = acl_entryp = SMB_MALLOC_P(struct acl_entry_link);
02784 if(acl_entryp == NULL) {
02785 errno = ENOMEM;
02786 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
02787 return(-1);
02788 }
02789
02790 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
02791 acl_entryp->prevp = temp_entry;
02792 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
02793 }
02794
02795 *pentry = acl_entryp->entryp = SMB_MALLOC_P(struct new_acl_entry);
02796 if(*pentry == NULL) {
02797 errno = ENOMEM;
02798 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
02799 return(-1);
02800 }
02801
02802 memset(*pentry,0,sizeof(struct new_acl_entry));
02803 acl_entryp->entryp->ace_len = sizeof(struct acl_entry);
02804 acl_entryp->entryp->ace_type = ACC_PERMIT;
02805 acl_entryp->entryp->ace_id->id_len = sizeof(struct ace_id);
02806 acl_entryp->nextp = NULL;
02807 theacl->count++;
02808 DEBUG(10,("Exiting sys_acl_create_entry\n"));
02809 return(0);
02810 }
02811
02812 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
02813 {
02814 DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
02815 entry->ace_id->id_type = tagtype;
02816 DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type));
02817 DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
02818 }
02819
02820 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
02821 {
02822 DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
02823 memcpy(entry->ace_id->id_data,qual,sizeof(uid_t));
02824 DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
02825 return(0);
02826 }
02827
02828 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
02829 {
02830 DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
02831 if(!(*permset & S_IXUSR) &&
02832 !(*permset & S_IWUSR) &&
02833 !(*permset & S_IRUSR) &&
02834 (*permset != 0))
02835 return(-1);
02836
02837 entry->ace_access = *permset;
02838 DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
02839 DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
02840 return(0);
02841 }
02842
02843 int sys_acl_valid( SMB_ACL_T theacl )
02844 {
02845 int user_obj = 0;
02846 int group_obj = 0;
02847 int other_obj = 0;
02848 struct acl_entry_link *acl_entry;
02849
02850 for(acl_entry=theacl; acl_entry != NULL; acl_entry = acl_entry->nextp) {
02851 user_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_USER_OBJ);
02852 group_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_GROUP_OBJ);
02853 other_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_OTHER);
02854 }
02855
02856 DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj,group_obj,other_obj));
02857
02858 if(user_obj != 1 || group_obj != 1 || other_obj != 1)
02859 return(-1);
02860
02861 return(0);
02862 }
02863
02864 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
02865 {
02866 struct acl_entry_link *acl_entry_link = NULL;
02867 struct acl *file_acl = NULL;
02868 struct acl *file_acl_temp = NULL;
02869 struct acl_entry *acl_entry = NULL;
02870 struct ace_id *ace_id = NULL;
02871 uint id_type;
02872 uint ace_access;
02873 uint user_id;
02874 uint acl_length;
02875 uint rc;
02876
02877 DEBUG(10,("Entering sys_acl_set_file\n"));
02878 DEBUG(10,("File name is %s\n",name));
02879
02880
02881 if(acltype == SMB_ACL_TYPE_DEFAULT)
02882 return(0);
02883
02884 acl_length = BUFSIZ;
02885 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
02886
02887 if(file_acl == NULL) {
02888 errno = ENOMEM;
02889 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
02890 return(-1);
02891 }
02892
02893 memset(file_acl,0,BUFSIZ);
02894
02895 file_acl->acl_len = ACL_SIZ;
02896 file_acl->acl_mode = S_IXACL;
02897
02898 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
02899 acl_entry_link->entryp->ace_access >>= 6;
02900 id_type = acl_entry_link->entryp->ace_id->id_type;
02901
02902 switch(id_type) {
02903 case SMB_ACL_USER_OBJ:
02904 file_acl->u_access = acl_entry_link->entryp->ace_access;
02905 continue;
02906 case SMB_ACL_GROUP_OBJ:
02907 file_acl->g_access = acl_entry_link->entryp->ace_access;
02908 continue;
02909 case SMB_ACL_OTHER:
02910 file_acl->o_access = acl_entry_link->entryp->ace_access;
02911 continue;
02912 case SMB_ACL_MASK:
02913 continue;
02914 }
02915
02916 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
02917 acl_length += sizeof(struct acl_entry);
02918 file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
02919 if(file_acl_temp == NULL) {
02920 SAFE_FREE(file_acl);
02921 errno = ENOMEM;
02922 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
02923 return(-1);
02924 }
02925
02926 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
02927 SAFE_FREE(file_acl);
02928 file_acl = file_acl_temp;
02929 }
02930
02931 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
02932 file_acl->acl_len += sizeof(struct acl_entry);
02933 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
02934 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
02935
02936
02937
02938
02939
02940 acl_entry->ace_type = ACC_SPECIFY;
02941
02942 ace_id = acl_entry->ace_id;
02943
02944 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
02945 DEBUG(10,("The id type is %d\n",ace_id->id_type));
02946 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
02947 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
02948 memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
02949 }
02950
02951 rc = chacl(name,file_acl,file_acl->acl_len);
02952 DEBUG(10,("errno is %d\n",errno));
02953 DEBUG(10,("return code is %d\n",rc));
02954 SAFE_FREE(file_acl);
02955 DEBUG(10,("Exiting the sys_acl_set_file\n"));
02956 return(rc);
02957 }
02958
02959 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
02960 {
02961 struct acl_entry_link *acl_entry_link = NULL;
02962 struct acl *file_acl = NULL;
02963 struct acl *file_acl_temp = NULL;
02964 struct acl_entry *acl_entry = NULL;
02965 struct ace_id *ace_id = NULL;
02966 uint id_type;
02967 uint user_id;
02968 uint acl_length;
02969 uint rc;
02970
02971 DEBUG(10,("Entering sys_acl_set_fd\n"));
02972 acl_length = BUFSIZ;
02973 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
02974
02975 if(file_acl == NULL) {
02976 errno = ENOMEM;
02977 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
02978 return(-1);
02979 }
02980
02981 memset(file_acl,0,BUFSIZ);
02982
02983 file_acl->acl_len = ACL_SIZ;
02984 file_acl->acl_mode = S_IXACL;
02985
02986 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
02987 acl_entry_link->entryp->ace_access >>= 6;
02988 id_type = acl_entry_link->entryp->ace_id->id_type;
02989 DEBUG(10,("The id_type is %d\n",id_type));
02990
02991 switch(id_type) {
02992 case SMB_ACL_USER_OBJ:
02993 file_acl->u_access = acl_entry_link->entryp->ace_access;
02994 continue;
02995 case SMB_ACL_GROUP_OBJ:
02996 file_acl->g_access = acl_entry_link->entryp->ace_access;
02997 continue;
02998 case SMB_ACL_OTHER:
02999 file_acl->o_access = acl_entry_link->entryp->ace_access;
03000 continue;
03001 case SMB_ACL_MASK:
03002 continue;
03003 }
03004
03005 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
03006 acl_length += sizeof(struct acl_entry);
03007 file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
03008 if(file_acl_temp == NULL) {
03009 SAFE_FREE(file_acl);
03010 errno = ENOMEM;
03011 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
03012 return(-1);
03013 }
03014
03015 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
03016 SAFE_FREE(file_acl);
03017 file_acl = file_acl_temp;
03018 }
03019
03020 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
03021 file_acl->acl_len += sizeof(struct acl_entry);
03022 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
03023 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
03024
03025
03026
03027
03028
03029 acl_entry->ace_type = ACC_SPECIFY;
03030
03031 ace_id = acl_entry->ace_id;
03032
03033 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
03034 DEBUG(10,("The id type is %d\n",ace_id->id_type));
03035 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
03036 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
03037 memcpy(ace_id->id_data, &user_id, sizeof(uid_t));
03038 }
03039
03040 rc = fchacl(fd,file_acl,file_acl->acl_len);
03041 DEBUG(10,("errno is %d\n",errno));
03042 DEBUG(10,("return code is %d\n",rc));
03043 SAFE_FREE(file_acl);
03044 DEBUG(10,("Exiting sys_acl_set_fd\n"));
03045 return(rc);
03046 }
03047
03048 int sys_acl_delete_def_file(const char *name)
03049 {
03050
03051 return 0;
03052 }
03053
03054 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
03055 {
03056 return(*permset & perm);
03057 }
03058
03059 int sys_acl_free_text(char *text)
03060 {
03061 return(0);
03062 }
03063
03064 int sys_acl_free_acl(SMB_ACL_T posix_acl)
03065 {
03066 struct acl_entry_link *acl_entry_link;
03067
03068 for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
03069 SAFE_FREE(acl_entry_link->prevp->entryp);
03070 SAFE_FREE(acl_entry_link->prevp);
03071 }
03072
03073 SAFE_FREE(acl_entry_link->prevp->entryp);
03074 SAFE_FREE(acl_entry_link->prevp);
03075 SAFE_FREE(acl_entry_link->entryp);
03076 SAFE_FREE(acl_entry_link);
03077
03078 return(0);
03079 }
03080
03081 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
03082 {
03083 return(0);
03084 }
03085
03086 #else
03087
03088 int sys_acl_get_entry(UNUSED(SMB_ACL_T the_acl), UNUSED(int entry_id), UNUSED(SMB_ACL_ENTRY_T *entry_p))
03089 {
03090 errno = ENOSYS;
03091 return -1;
03092 }
03093
03094 int sys_acl_get_tag_type(UNUSED(SMB_ACL_ENTRY_T entry_d), UNUSED(SMB_ACL_TAG_T *tag_type_p))
03095 {
03096 errno = ENOSYS;
03097 return -1;
03098 }
03099
03100 int sys_acl_get_permset(UNUSED(SMB_ACL_ENTRY_T entry_d), UNUSED(SMB_ACL_PERMSET_T *permset_p))
03101 {
03102 errno = ENOSYS;
03103 return -1;
03104 }
03105
03106 void *sys_acl_get_qualifier(UNUSED(SMB_ACL_ENTRY_T entry_d))
03107 {
03108 errno = ENOSYS;
03109 return NULL;
03110 }
03111
03112 SMB_ACL_T sys_acl_get_file(UNUSED(const char *path_p), UNUSED(SMB_ACL_TYPE_T type))
03113 {
03114 errno = ENOSYS;
03115 return (SMB_ACL_T)NULL;
03116 }
03117
03118 SMB_ACL_T sys_acl_get_fd(UNUSED(int fd))
03119 {
03120 errno = ENOSYS;
03121 return (SMB_ACL_T)NULL;
03122 }
03123
03124 int sys_acl_clear_perms(UNUSED(SMB_ACL_PERMSET_T permset))
03125 {
03126 errno = ENOSYS;
03127 return -1;
03128 }
03129
03130 int sys_acl_add_perm( UNUSED(SMB_ACL_PERMSET_T permset), UNUSED(SMB_ACL_PERM_T perm))
03131 {
03132 errno = ENOSYS;
03133 return -1;
03134 }
03135
03136 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
03137 {
03138 errno = ENOSYS;
03139 return (permset & perm) ? 1 : 0;
03140 }
03141
03142 char *sys_acl_to_text(UNUSED(SMB_ACL_T the_acl), UNUSED(ssize_t *plen))
03143 {
03144 errno = ENOSYS;
03145 return NULL;
03146 }
03147
03148 int sys_acl_free_text(UNUSED(char *text))
03149 {
03150 errno = ENOSYS;
03151 return -1;
03152 }
03153
03154 SMB_ACL_T sys_acl_init(UNUSED(int count))
03155 {
03156 errno = ENOSYS;
03157 return NULL;
03158 }
03159
03160 int sys_acl_create_entry(UNUSED(SMB_ACL_T *pacl), UNUSED(SMB_ACL_ENTRY_T *pentry))
03161 {
03162 errno = ENOSYS;
03163 return -1;
03164 }
03165
03166 int sys_acl_set_tag_type(UNUSED(SMB_ACL_ENTRY_T entry), UNUSED(SMB_ACL_TAG_T tagtype))
03167 {
03168 errno = ENOSYS;
03169 return -1;
03170 }
03171
03172 int sys_acl_set_qualifier(UNUSED(SMB_ACL_ENTRY_T entry), UNUSED(void *qual))
03173 {
03174 errno = ENOSYS;
03175 return -1;
03176 }
03177
03178 int sys_acl_set_permset(UNUSED(SMB_ACL_ENTRY_T entry), UNUSED(SMB_ACL_PERMSET_T permset))
03179 {
03180 errno = ENOSYS;
03181 return -1;
03182 }
03183
03184 int sys_acl_valid(UNUSED(SMB_ACL_T theacl))
03185 {
03186 errno = ENOSYS;
03187 return -1;
03188 }
03189
03190 int sys_acl_set_file(UNUSED(const char *name), UNUSED(SMB_ACL_TYPE_T acltype), UNUSED(SMB_ACL_T theacl))
03191 {
03192 errno = ENOSYS;
03193 return -1;
03194 }
03195
03196 int sys_acl_set_fd(UNUSED(int fd), UNUSED(SMB_ACL_T theacl))
03197 {
03198 errno = ENOSYS;
03199 return -1;
03200 }
03201
03202 int sys_acl_delete_def_file(UNUSED(const char *name))
03203 {
03204 errno = ENOSYS;
03205 return -1;
03206 }
03207
03208 int sys_acl_free_acl(UNUSED(SMB_ACL_T the_acl))
03209 {
03210 errno = ENOSYS;
03211 return -1;
03212 }
03213
03214 int sys_acl_free_qualifier(UNUSED(void *qual), UNUSED(SMB_ACL_TAG_T tagtype))
03215 {
03216 errno = ENOSYS;
03217 return -1;
03218 }
03219
03220 #endif
03221
03222
03223
03224
03225
03226
03227 int no_acl_syscall_error(int err)
03228 {
03229 #if defined(ENOSYS)
03230 if (err == ENOSYS) {
03231 return 1;
03232 }
03233 #endif
03234 #if defined(ENOTSUP)
03235 if (err == ENOTSUP) {
03236 return 1;
03237 }
03238 #endif
03239 return 0;
03240 }