00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026 #ifdef HAVE_SYS_PRCTL_H
00027 #include <sys/prctl.h>
00028 #endif
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 void *sys_memalign( size_t align, size_t size )
00052 {
00053 #if defined(HAVE_POSIX_MEMALIGN)
00054 void *p = NULL;
00055 int ret = posix_memalign( &p, align, size );
00056 if ( ret == 0 )
00057 return p;
00058
00059 return NULL;
00060 #elif defined(HAVE_MEMALIGN)
00061 return memalign( align, size );
00062 #else
00063
00064
00065 #if defined(SYSCONF_SC_PAGESIZE)
00066 size_t pagesize = (size_t)sysconf(_SC_PAGESIZE);
00067 #elif defined(HAVE_GETPAGESIZE)
00068 size_t pagesize = (size_t)getpagesize();
00069 #else
00070 size_t pagesize = (size_t)-1;
00071 #endif
00072 if (pagesize == (size_t)-1) {
00073 DEBUG(0,("memalign functionalaity not available on this platform!\n"));
00074 return NULL;
00075 }
00076 if (size < pagesize) {
00077 size = pagesize;
00078 }
00079 return SMB_MALLOC(size);
00080 #endif
00081 }
00082
00083
00084
00085
00086
00087 int sys_usleep(long usecs)
00088 {
00089 #ifndef HAVE_USLEEP
00090 struct timeval tval;
00091 #endif
00092
00093
00094
00095
00096
00097
00098 if(usecs < 0 || usecs > 1000000) {
00099 errno = EINVAL;
00100 return -1;
00101 }
00102
00103 #if HAVE_USLEEP
00104 usleep(usecs);
00105 return 0;
00106 #else
00107
00108
00109
00110 tval.tv_sec = 0;
00111 tval.tv_usec = usecs/1000;
00112 select(0,NULL,NULL,NULL,&tval);
00113 return 0;
00114 #endif
00115 }
00116
00117
00118
00119
00120
00121 ssize_t sys_read(int fd, void *buf, size_t count)
00122 {
00123 ssize_t ret;
00124
00125 do {
00126 ret = read(fd, buf, count);
00127 } while (ret == -1 && errno == EINTR);
00128 return ret;
00129 }
00130
00131
00132
00133
00134
00135 ssize_t sys_write(int fd, const void *buf, size_t count)
00136 {
00137 ssize_t ret;
00138
00139 do {
00140 ret = write(fd, buf, count);
00141 } while (ret == -1 && errno == EINTR);
00142 return ret;
00143 }
00144
00145
00146
00147
00148
00149 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
00150 ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
00151 {
00152 ssize_t ret;
00153
00154 do {
00155 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
00156 ret = pread64(fd, buf, count, off);
00157 #else
00158 ret = pread(fd, buf, count, off);
00159 #endif
00160 } while (ret == -1 && errno == EINTR);
00161 return ret;
00162 }
00163 #endif
00164
00165
00166
00167
00168
00169 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
00170 ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
00171 {
00172 ssize_t ret;
00173
00174 do {
00175 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
00176 ret = pwrite64(fd, buf, count, off);
00177 #else
00178 ret = pwrite(fd, buf, count, off);
00179 #endif
00180 } while (ret == -1 && errno == EINTR);
00181 return ret;
00182 }
00183 #endif
00184
00185
00186
00187
00188
00189 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
00190 {
00191 ssize_t ret;
00192
00193 do {
00194 ret = send(s, msg, len, flags);
00195 } while (ret == -1 && errno == EINTR);
00196 return ret;
00197 }
00198
00199
00200
00201
00202
00203 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
00204 {
00205 ssize_t ret;
00206
00207 do {
00208 ret = sendto(s, msg, len, flags, to, tolen);
00209 } while (ret == -1 && errno == EINTR);
00210 return ret;
00211 }
00212
00213
00214
00215
00216
00217 ssize_t sys_recv(int fd, void *buf, size_t count, int flags)
00218 {
00219 ssize_t ret;
00220
00221 do {
00222 ret = recv(fd, buf, count, flags);
00223 } while (ret == -1 && errno == EINTR);
00224 return ret;
00225 }
00226
00227
00228
00229
00230
00231 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
00232 {
00233 ssize_t ret;
00234
00235 do {
00236 ret = recvfrom(s, buf, len, flags, from, fromlen);
00237 } while (ret == -1 && errno == EINTR);
00238 return ret;
00239 }
00240
00241
00242
00243
00244
00245 int sys_fcntl_ptr(int fd, int cmd, void *arg)
00246 {
00247 int ret;
00248
00249 do {
00250 ret = fcntl(fd, cmd, arg);
00251 } while (ret == -1 && errno == EINTR);
00252 return ret;
00253 }
00254
00255
00256
00257
00258
00259 int sys_fcntl_long(int fd, int cmd, long arg)
00260 {
00261 int ret;
00262
00263 do {
00264 ret = fcntl(fd, cmd, arg);
00265 } while (ret == -1 && errno == EINTR);
00266 return ret;
00267 }
00268
00269
00270
00271
00272
00273 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
00274 {
00275 int ret;
00276 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
00277 ret = stat64(fname, sbuf);
00278 #else
00279 ret = stat(fname, sbuf);
00280 #endif
00281
00282 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
00283 return ret;
00284 }
00285
00286
00287
00288
00289
00290 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
00291 {
00292 int ret;
00293 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
00294 ret = fstat64(fd, sbuf);
00295 #else
00296 ret = fstat(fd, sbuf);
00297 #endif
00298
00299 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
00300 return ret;
00301 }
00302
00303
00304
00305
00306
00307 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
00308 {
00309 int ret;
00310 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
00311 ret = lstat64(fname, sbuf);
00312 #else
00313 ret = lstat(fname, sbuf);
00314 #endif
00315
00316 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
00317 return ret;
00318 }
00319
00320
00321
00322
00323
00324 int sys_ftruncate(int fd, SMB_OFF_T offset)
00325 {
00326 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
00327 return ftruncate64(fd, offset);
00328 #else
00329 return ftruncate(fd, offset);
00330 #endif
00331 }
00332
00333
00334
00335
00336
00337 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
00338 {
00339 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
00340 return lseek64(fd, offset, whence);
00341 #else
00342 return lseek(fd, offset, whence);
00343 #endif
00344 }
00345
00346
00347
00348
00349
00350 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
00351 {
00352 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
00353 return fseek64(fp, offset, whence);
00354 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
00355 return fseeko64(fp, offset, whence);
00356 #else
00357 return fseek(fp, offset, whence);
00358 #endif
00359 }
00360
00361
00362
00363
00364
00365 SMB_OFF_T sys_ftell(FILE *fp)
00366 {
00367 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
00368 return (SMB_OFF_T)ftell64(fp);
00369 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
00370 return (SMB_OFF_T)ftello64(fp);
00371 #else
00372 return (SMB_OFF_T)ftell(fp);
00373 #endif
00374 }
00375
00376
00377
00378
00379
00380 int sys_creat(const char *path, mode_t mode)
00381 {
00382 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
00383 return creat64(path, mode);
00384 #else
00385
00386
00387
00388
00389 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
00390 #endif
00391 }
00392
00393
00394
00395
00396
00397 int sys_open(const char *path, int oflag, mode_t mode)
00398 {
00399 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
00400 return open64(path, oflag, mode);
00401 #else
00402 return open(path, oflag, mode);
00403 #endif
00404 }
00405
00406
00407
00408
00409
00410 FILE *sys_fopen(const char *path, const char *type)
00411 {
00412 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
00413 return fopen64(path, type);
00414 #else
00415 return fopen(path, type);
00416 #endif
00417 }
00418
00419
00420
00421
00422
00423
00424 void kernel_flock(int fd, uint32 share_mode)
00425 {
00426 #if HAVE_KERNEL_SHARE_MODES
00427 int kernel_mode = 0;
00428 if (share_mode == FILE_SHARE_WRITE) {
00429 kernel_mode = LOCK_MAND|LOCK_WRITE;
00430 } else if (share_mode == FILE_SHARE_READ) {
00431 kernel_mode = LOCK_MAND|LOCK_READ;
00432 } else if (share_mode == FILE_SHARE_NONE) {
00433 kernel_mode = LOCK_MAND;
00434 }
00435 if (kernel_mode) {
00436 flock(fd, kernel_mode);
00437 }
00438 #endif
00439 ;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448 SMB_STRUCT_DIR *sys_opendir(const char *name)
00449 {
00450 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
00451 return opendir64(name);
00452 #else
00453 return opendir(name);
00454 #endif
00455 }
00456
00457
00458
00459
00460
00461 SMB_STRUCT_DIRENT *sys_readdir(SMB_STRUCT_DIR *dirp)
00462 {
00463 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
00464 return readdir64(dirp);
00465 #else
00466 return readdir(dirp);
00467 #endif
00468 }
00469
00470
00471
00472
00473
00474 void sys_seekdir(SMB_STRUCT_DIR *dirp, long offset)
00475 {
00476 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
00477 seekdir64(dirp, offset);
00478 #else
00479 seekdir(dirp, offset);
00480 #endif
00481 }
00482
00483
00484
00485
00486
00487 long sys_telldir(SMB_STRUCT_DIR *dirp)
00488 {
00489 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
00490 return (long)telldir64(dirp);
00491 #else
00492 return (long)telldir(dirp);
00493 #endif
00494 }
00495
00496
00497
00498
00499
00500 void sys_rewinddir(SMB_STRUCT_DIR *dirp)
00501 {
00502 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
00503 rewinddir64(dirp);
00504 #else
00505 rewinddir(dirp);
00506 #endif
00507 }
00508
00509
00510
00511
00512
00513 int sys_closedir(SMB_STRUCT_DIR *dirp)
00514 {
00515 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
00516 return closedir64(dirp);
00517 #else
00518 return closedir(dirp);
00519 #endif
00520 }
00521
00522
00523
00524
00525
00526 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
00527 {
00528 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
00529 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
00530 return mknod64(path, mode, dev);
00531 #else
00532 return mknod(path, mode, dev);
00533 #endif
00534 #else
00535
00536 errno = ENOSYS;
00537 return -1;
00538 #endif
00539 }
00540
00541
00542
00543
00544
00545 char *sys_realpath(const char *path, char *resolved_path)
00546 {
00547 #if defined(HAVE_REALPATH)
00548 return realpath(path, resolved_path);
00549 #else
00550
00551 errno = EINVAL;
00552 return NULL;
00553 #endif
00554 }
00555
00556
00557
00558
00559
00560 int sys_waitpid(pid_t pid,int *status,int options)
00561 {
00562 #ifdef HAVE_WAITPID
00563 return waitpid(pid,status,options);
00564 #else
00565 return wait4(pid, status, options, NULL);
00566 #endif
00567 }
00568
00569
00570
00571
00572
00573 char *sys_getwd(char *s)
00574 {
00575 char *wd;
00576 #ifdef HAVE_GETCWD
00577 wd = (char *)getcwd(s, sizeof (pstring));
00578 #else
00579 wd = (char *)getwd(s);
00580 #endif
00581 return wd;
00582 }
00583
00584
00585
00586
00587
00588 int sys_symlink(const char *oldpath, const char *newpath)
00589 {
00590 #ifndef HAVE_SYMLINK
00591 errno = ENOSYS;
00592 return -1;
00593 #else
00594 return symlink(oldpath, newpath);
00595 #endif
00596 }
00597
00598
00599
00600
00601
00602 int sys_readlink(const char *path, char *buf, size_t bufsiz)
00603 {
00604 #ifndef HAVE_READLINK
00605 errno = ENOSYS;
00606 return -1;
00607 #else
00608 return readlink(path, buf, bufsiz);
00609 #endif
00610 }
00611
00612
00613
00614
00615
00616 int sys_link(const char *oldpath, const char *newpath)
00617 {
00618 #ifndef HAVE_LINK
00619 errno = ENOSYS;
00620 return -1;
00621 #else
00622 return link(oldpath, newpath);
00623 #endif
00624 }
00625
00626
00627
00628
00629
00630 int sys_chown(const char *fname,uid_t uid,gid_t gid)
00631 {
00632 #ifndef HAVE_CHOWN
00633 static int done;
00634 if (!done) {
00635 DEBUG(1,("WARNING: no chown!\n"));
00636 done=1;
00637 }
00638 errno = ENOSYS;
00639 return -1;
00640 #else
00641 return(chown(fname,uid,gid));
00642 #endif
00643 }
00644
00645
00646
00647
00648 int sys_chroot(const char *dname)
00649 {
00650 #ifndef HAVE_CHROOT
00651 static int done;
00652 if (!done) {
00653 DEBUG(1,("WARNING: no chroot!\n"));
00654 done=1;
00655 }
00656 errno = ENOSYS;
00657 return -1;
00658 #else
00659 return(chroot(dname));
00660 #endif
00661 }
00662
00663
00664
00665
00666
00667
00668
00669 struct hostent *sys_gethostbyname(const char *name)
00670 {
00671 #ifdef REDUCE_ROOT_DNS_LOOKUPS
00672 char query[256], hostname[256];
00673 char *domain;
00674
00675
00676
00677 if (strchr_m(name, '.'))
00678 return(gethostbyname(name));
00679
00680
00681
00682
00683
00684
00685 gethostname(hostname, sizeof(hostname) - 1);
00686 hostname[sizeof(hostname) - 1] = 0;
00687 if ((domain = strchr_m(hostname, '.')) == NULL)
00688 return(gethostbyname(name));
00689
00690
00691
00692
00693
00694
00695 if((strlen(name) + strlen(domain)) >= sizeof(query))
00696 return(gethostbyname(name));
00697
00698 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
00699 return(gethostbyname(query));
00700 #else
00701 return(gethostbyname(name));
00702 #endif
00703 }
00704
00705
00706 #if defined(HAVE_POSIX_CAPABILITIES)
00707
00708 #ifdef HAVE_SYS_CAPABILITY_H
00709
00710 #if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H)
00711 #define _I386_STATFS_H
00712 #define _PPC_STATFS_H
00713 #define BROKEN_REDHAT_7_STATFS_WORKAROUND
00714 #endif
00715
00716 #include <sys/capability.h>
00717
00718 #ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND
00719 #undef _I386_STATFS_H
00720 #undef _PPC_STATFS_H
00721 #undef BROKEN_REDHAT_7_STATFS_WORKAROUND
00722 #endif
00723
00724 #endif
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 static BOOL set_process_capability(enum smbd_capability capability,
00736 BOOL enable)
00737 {
00738 cap_value_t cap_vals[2] = {0};
00739 int num_cap_vals = 0;
00740
00741 cap_t cap;
00742
00743 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
00744
00745
00746
00747
00748
00749
00750
00751 if (!prctl(PR_GET_KEEPCAPS)) {
00752 prctl(PR_SET_KEEPCAPS, 1);
00753 }
00754 #endif
00755
00756 cap = cap_get_proc();
00757 if (cap == NULL) {
00758 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
00759 strerror(errno)));
00760 return False;
00761 }
00762
00763 switch (capability) {
00764 case KERNEL_OPLOCK_CAPABILITY:
00765 #ifdef CAP_NETWORK_MGT
00766
00767 cap_vals[num_cap_vals++] = CAP_NETWORK_MGT;
00768 #endif
00769 break;
00770 case DMAPI_ACCESS_CAPABILITY:
00771 #ifdef CAP_DEVICE_MGT
00772
00773 cap_vals[num_cap_vals++] = CAP_DEVICE_MGT;
00774 #elif CAP_MKNOD
00775
00776 cap_vals[num_cap_vals++] = CAP_MKNOD;
00777 #endif
00778 break;
00779 case LEASE_CAPABILITY:
00780 #ifdef CAP_LEASE
00781 cap_vals[num_cap_vals++] = CAP_LEASE;
00782 #endif
00783 break;
00784 }
00785
00786 SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals));
00787
00788 if (num_cap_vals == 0) {
00789 cap_free(cap);
00790 return True;
00791 }
00792
00793 cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
00794 enable ? CAP_SET : CAP_CLEAR);
00795
00796
00797
00798
00799 cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
00800
00801 if (cap_set_proc(cap) == -1) {
00802 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
00803 strerror(errno)));
00804 cap_free(cap);
00805 return False;
00806 }
00807
00808 cap_free(cap);
00809 return True;
00810 }
00811
00812 #endif
00813
00814
00815
00816
00817
00818 void set_effective_capability(enum smbd_capability capability)
00819 {
00820 #if defined(HAVE_POSIX_CAPABILITIES)
00821 set_process_capability(capability, True);
00822 #endif
00823 }
00824
00825 void drop_effective_capability(enum smbd_capability capability)
00826 {
00827 #if defined(HAVE_POSIX_CAPABILITIES)
00828 set_process_capability(capability, False);
00829 #endif
00830 }
00831
00832
00833
00834
00835
00836 long sys_random(void)
00837 {
00838 #if defined(HAVE_RANDOM)
00839 return (long)random();
00840 #elif defined(HAVE_RAND)
00841 return (long)rand();
00842 #else
00843 DEBUG(0,("Error - no random function available !\n"));
00844 exit(1);
00845 #endif
00846 }
00847
00848
00849
00850
00851
00852 void sys_srandom(unsigned int seed)
00853 {
00854 #if defined(HAVE_SRANDOM)
00855 srandom(seed);
00856 #elif defined(HAVE_SRAND)
00857 srand(seed);
00858 #else
00859 DEBUG(0,("Error - no srandom function available !\n"));
00860 exit(1);
00861 #endif
00862 }
00863
00864
00865
00866
00867
00868 int groups_max(void)
00869 {
00870 #if defined(SYSCONF_SC_NGROUPS_MAX)
00871 int ret = sysconf(_SC_NGROUPS_MAX);
00872 return (ret == -1) ? NGROUPS_MAX : ret;
00873 #else
00874 return NGROUPS_MAX;
00875 #endif
00876 }
00877
00878
00879
00880
00881
00882 int sys_getgroups(int setlen, gid_t *gidset)
00883 {
00884 #if !defined(HAVE_BROKEN_GETGROUPS)
00885 return getgroups(setlen, gidset);
00886 #else
00887
00888 GID_T gid;
00889 GID_T *group_list;
00890 int i, ngroups;
00891
00892 if(setlen == 0) {
00893 return getgroups(setlen, &gid);
00894 }
00895
00896
00897
00898
00899
00900
00901 if(setlen < 0) {
00902 errno = EINVAL;
00903 return -1;
00904 }
00905
00906 if (setlen == 0)
00907 setlen = groups_max();
00908
00909 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
00910 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
00911 return -1;
00912 }
00913
00914 if((ngroups = getgroups(setlen, group_list)) < 0) {
00915 int saved_errno = errno;
00916 SAFE_FREE(group_list);
00917 errno = saved_errno;
00918 return -1;
00919 }
00920
00921 for(i = 0; i < ngroups; i++)
00922 gidset[i] = (gid_t)group_list[i];
00923
00924 SAFE_FREE(group_list);
00925 return ngroups;
00926 #endif
00927 }
00928
00929
00930
00931
00932
00933
00934
00935 int sys_setgroups(int setlen, gid_t *gidset)
00936 {
00937 #if !defined(HAVE_SETGROUPS)
00938 errno = ENOSYS;
00939 return -1;
00940 #endif
00941
00942 #if !defined(HAVE_BROKEN_GETGROUPS)
00943 return setgroups(setlen, gidset);
00944 #else
00945
00946 GID_T *group_list;
00947 int i ;
00948
00949 if (setlen == 0)
00950 return 0 ;
00951
00952 if (setlen < 0 || setlen > groups_max()) {
00953 errno = EINVAL;
00954 return -1;
00955 }
00956
00957
00958
00959
00960
00961
00962 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
00963 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
00964 return -1;
00965 }
00966
00967 for(i = 0; i < setlen; i++)
00968 group_list[i] = (GID_T) gidset[i];
00969
00970 if(setgroups(setlen, group_list) != 0) {
00971 int saved_errno = errno;
00972 SAFE_FREE(group_list);
00973 errno = saved_errno;
00974 return -1;
00975 }
00976
00977 SAFE_FREE(group_list);
00978 return 0 ;
00979 #endif
00980 }
00981
00982
00983
00984
00985
00986 void sys_setpwent(void)
00987 {
00988 setpwent();
00989 }
00990
00991 struct passwd *sys_getpwent(void)
00992 {
00993 return getpwent();
00994 }
00995
00996 void sys_endpwent(void)
00997 {
00998 endpwent();
00999 }
01000
01001
01002
01003
01004
01005 #ifdef ENABLE_BUILD_FARM_HACKS
01006
01007
01008
01009
01010
01011
01012
01013 static struct passwd *fake_pwd;
01014 static int num_fake_pwd;
01015
01016 struct passwd *sys_getpwnam(const char *name)
01017 {
01018 int i;
01019
01020 for (i=0; i<num_fake_pwd; i++) {
01021 if (strcmp(fake_pwd[i].pw_name, name) == 0) {
01022 DEBUG(10, ("Returning fake user %s\n", name));
01023 return &fake_pwd[i];
01024 }
01025 }
01026
01027 return getpwnam(name);
01028 }
01029
01030 struct passwd *sys_getpwuid(uid_t uid)
01031 {
01032 int i;
01033
01034 for (i=0; i<num_fake_pwd; i++) {
01035 if (fake_pwd[i].pw_uid == uid) {
01036 DEBUG(10, ("Returning fake user %s\n",
01037 fake_pwd[i].pw_name));
01038 return &fake_pwd[i];
01039 }
01040 }
01041
01042 return getpwuid(uid);
01043 }
01044
01045 void faked_create_user(const char *name)
01046 {
01047 int i;
01048 uid_t uid;
01049 struct passwd new_pwd;
01050
01051 for (i=0; i<10; i++) {
01052 generate_random_buffer((unsigned char *)&uid,
01053 sizeof(uid));
01054 if (getpwuid(uid) == NULL) {
01055 break;
01056 }
01057 }
01058
01059 if (i==10) {
01060
01061 return;
01062 }
01063
01064 new_pwd.pw_name = SMB_STRDUP(name);
01065 new_pwd.pw_passwd = SMB_STRDUP("x");
01066 new_pwd.pw_uid = uid;
01067 new_pwd.pw_gid = 100;
01068 new_pwd.pw_gecos = SMB_STRDUP("faked user");
01069 new_pwd.pw_dir = SMB_STRDUP("/nodir");
01070 new_pwd.pw_shell = SMB_STRDUP("/bin/false");
01071
01072 ADD_TO_ARRAY(NULL, struct passwd, new_pwd, &fake_pwd,
01073 &num_fake_pwd);
01074
01075 DEBUG(10, ("Added fake user %s, have %d fake users\n",
01076 name, num_fake_pwd));
01077 }
01078
01079 #else
01080
01081 struct passwd *sys_getpwnam(const char *name)
01082 {
01083 return getpwnam(name);
01084 }
01085
01086 struct passwd *sys_getpwuid(uid_t uid)
01087 {
01088 return getpwuid(uid);
01089 }
01090
01091 #endif
01092
01093 struct group *sys_getgrnam(const char *name)
01094 {
01095 return getgrnam(name);
01096 }
01097
01098 struct group *sys_getgrgid(gid_t gid)
01099 {
01100 return getgrgid(gid);
01101 }
01102
01103 #if 0
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
01116 {
01117 pstring fname;
01118 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
01119 }
01120
01121
01122
01123
01124
01125 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
01126 {
01127 pstring fname;
01128 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
01129 }
01130
01131
01132
01133
01134
01135 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
01136 {
01137 pstring fname;
01138 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
01139 }
01140
01141
01142
01143
01144
01145 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
01146 {
01147 pstring fname;
01148 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
01149 }
01150
01151
01152
01153
01154
01155 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
01156 {
01157 pstring fname;
01158 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
01159 }
01160
01161
01162
01163
01164
01165 SMB_STRUCT_DIR *wsys_opendir(const smb_ucs2_t *wfname)
01166 {
01167 pstring fname;
01168 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
01169 }
01170
01171
01172
01173
01174
01175 SMB_STRUCT_WDIRENT *wsys_readdir(SMB_STRUCT_DIR *dirp)
01176 {
01177 static SMB_STRUCT_WDIRENT retval;
01178 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
01179
01180 if(!dirval)
01181 return NULL;
01182
01183
01184
01185
01186
01187 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
01188
01189 return &retval;
01190 }
01191
01192
01193
01194
01195
01196 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
01197 {
01198 pstring fname;
01199 char *p = sys_getwd(fname);
01200
01201 if(!p)
01202 return NULL;
01203
01204 return unix_to_unicode(s, p, sizeof(wpstring));
01205 }
01206
01207
01208
01209
01210
01211 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
01212 {
01213 pstring fname;
01214 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
01215 }
01216
01217
01218
01219
01220
01221 int wsys_chroot(const smb_ucs2_t *wfname)
01222 {
01223 pstring fname;
01224 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
01225 }
01226
01227
01228
01229
01230
01231 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
01232 {
01233 static SMB_STRUCT_WPASSWD retval;
01234 fstring name;
01235 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
01236
01237 if(!pwret)
01238 return NULL;
01239
01240 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
01241 retval.pw_passwd = pwret->pw_passwd;
01242 retval.pw_uid = pwret->pw_uid;
01243 retval.pw_gid = pwret->pw_gid;
01244 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
01245 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
01246 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
01247
01248 return &retval;
01249 }
01250
01251
01252
01253
01254
01255 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
01256 {
01257 static SMB_STRUCT_WPASSWD retval;
01258 struct passwd *pwret = sys_getpwuid(uid);
01259
01260 if(!pwret)
01261 return NULL;
01262
01263 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
01264 retval.pw_passwd = pwret->pw_passwd;
01265 retval.pw_uid = pwret->pw_uid;
01266 retval.pw_gid = pwret->pw_gid;
01267 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
01268 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
01269 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
01270
01271 return &retval;
01272 }
01273 #endif
01274
01275
01276
01277
01278
01279
01280 static char **extract_args(const char *command)
01281 {
01282 static pstring trunc_cmd;
01283 char *ptr;
01284 int argcl;
01285 char **argl = NULL;
01286 int i;
01287
01288 pstrcpy(trunc_cmd, command);
01289
01290 if(!(ptr = strtok(trunc_cmd, " \t"))) {
01291 errno = EINVAL;
01292 return NULL;
01293 }
01294
01295
01296
01297
01298
01299 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
01300 argcl++;
01301
01302 if((argl = (char **)SMB_MALLOC((argcl + 1) * sizeof(char *))) == NULL)
01303 return NULL;
01304
01305
01306
01307
01308
01309 pstrcpy(trunc_cmd, command);
01310
01311 ptr = strtok(trunc_cmd, " \t");
01312 i = 0;
01313 argl[i++] = ptr;
01314
01315 while((ptr = strtok(NULL, " \t")) != NULL)
01316 argl[i++] = ptr;
01317
01318 argl[i++] = NULL;
01319 return argl;
01320 }
01321
01322
01323
01324
01325
01326
01327 static pid_t mypid = (pid_t)-1;
01328
01329 pid_t sys_fork(void)
01330 {
01331 pid_t forkret = fork();
01332
01333 if (forkret == (pid_t)0)
01334 mypid = (pid_t) -1;
01335
01336 return forkret;
01337 }
01338
01339
01340
01341
01342
01343 pid_t sys_getpid(void)
01344 {
01345 if (mypid == (pid_t)-1)
01346 mypid = getpid();
01347
01348 return mypid;
01349 }
01350
01351
01352
01353
01354
01355
01356
01357 typedef struct _popen_list
01358 {
01359 int fd;
01360 pid_t child_pid;
01361 struct _popen_list *next;
01362 } popen_list;
01363
01364 static popen_list *popen_chain;
01365
01366 int sys_popen(const char *command)
01367 {
01368 int parent_end, child_end;
01369 int pipe_fds[2];
01370 popen_list *entry = NULL;
01371 char **argl = NULL;
01372
01373 if (pipe(pipe_fds) < 0)
01374 return -1;
01375
01376 parent_end = pipe_fds[0];
01377 child_end = pipe_fds[1];
01378
01379 if (!*command) {
01380 errno = EINVAL;
01381 goto err_exit;
01382 }
01383
01384 if((entry = SMB_MALLOC_P(popen_list)) == NULL)
01385 goto err_exit;
01386
01387 ZERO_STRUCTP(entry);
01388
01389
01390
01391
01392
01393 if(!(argl = extract_args(command)))
01394 goto err_exit;
01395
01396 entry->child_pid = sys_fork();
01397
01398 if (entry->child_pid == -1) {
01399 goto err_exit;
01400 }
01401
01402 if (entry->child_pid == 0) {
01403
01404
01405
01406
01407
01408 int child_std_end = STDOUT_FILENO;
01409 popen_list *p;
01410
01411 close(parent_end);
01412 if (child_end != child_std_end) {
01413 dup2 (child_end, child_std_end);
01414 close (child_end);
01415 }
01416
01417
01418
01419
01420
01421
01422
01423 for (p = popen_chain; p; p = p->next)
01424 close(p->fd);
01425
01426 execv(argl[0], argl);
01427 _exit (127);
01428 }
01429
01430
01431
01432
01433
01434 close (child_end);
01435 SAFE_FREE(argl);
01436
01437
01438 entry->next = popen_chain;
01439 popen_chain = entry;
01440 entry->fd = parent_end;
01441
01442 return entry->fd;
01443
01444 err_exit:
01445
01446 SAFE_FREE(entry);
01447 SAFE_FREE(argl);
01448 close(pipe_fds[0]);
01449 close(pipe_fds[1]);
01450 return -1;
01451 }
01452
01453
01454
01455
01456
01457 int sys_pclose(int fd)
01458 {
01459 int wstatus;
01460 popen_list **ptr = &popen_chain;
01461 popen_list *entry = NULL;
01462 pid_t wait_pid;
01463 int status = -1;
01464
01465
01466 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
01467 if ((*ptr)->fd == fd) {
01468 entry = *ptr;
01469 *ptr = (*ptr)->next;
01470 status = 0;
01471 break;
01472 }
01473 }
01474
01475 if (status < 0 || close(entry->fd) < 0)
01476 return -1;
01477
01478
01479
01480
01481
01482
01483
01484 do {
01485 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
01486 } while (wait_pid == -1 && errno == EINTR);
01487
01488 SAFE_FREE(entry);
01489
01490 if (wait_pid == -1)
01491 return -1;
01492 return wstatus;
01493 }
01494
01495
01496
01497
01498
01499 void *sys_dlopen(const char *name, int flags)
01500 {
01501 #if defined(HAVE_DLOPEN)
01502 return dlopen(name, flags);
01503 #else
01504 return NULL;
01505 #endif
01506 }
01507
01508 void *sys_dlsym(void *handle, const char *symbol)
01509 {
01510 #if defined(HAVE_DLSYM)
01511 return dlsym(handle, symbol);
01512 #else
01513 return NULL;
01514 #endif
01515 }
01516
01517 int sys_dlclose (void *handle)
01518 {
01519 #if defined(HAVE_DLCLOSE)
01520 return dlclose(handle);
01521 #else
01522 return 0;
01523 #endif
01524 }
01525
01526 const char *sys_dlerror(void)
01527 {
01528 #if defined(HAVE_DLERROR)
01529 return dlerror();
01530 #else
01531 return NULL;
01532 #endif
01533 }
01534
01535 int sys_dup2(int oldfd, int newfd)
01536 {
01537 #if defined(HAVE_DUP2)
01538 return dup2(oldfd, newfd);
01539 #else
01540 errno = ENOSYS;
01541 return -1;
01542 #endif
01543 }
01544
01545
01546
01547
01548
01549 void sys_adminlog(int priority, const char *format_str, ...)
01550 {
01551 va_list ap;
01552 int ret;
01553 char *msgbuf = NULL;
01554
01555 va_start( ap, format_str );
01556 ret = vasprintf( &msgbuf, format_str, ap );
01557 va_end( ap );
01558
01559 if (ret == -1)
01560 return;
01561
01562 #if defined(HAVE_SYSLOG)
01563 syslog( priority, "%s", msgbuf );
01564 #else
01565 DEBUG(0,("%s", msgbuf ));
01566 #endif
01567 SAFE_FREE(msgbuf);
01568 }
01569
01570
01571 #ifdef HAVE_ATTROPEN
01572 #define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
01573 static int solaris_write_xattr(int attrfd, const char *value, size_t size);
01574 static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size);
01575 static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size);
01576 static int solaris_unlinkat(int attrdirfd, const char *name);
01577 static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode);
01578 static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode);
01579 #endif
01580
01581
01582
01583
01584
01585
01586 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
01587 {
01588 #if defined(HAVE_GETXATTR)
01589 #ifndef XATTR_ADD_OPT
01590 return getxattr(path, name, value, size);
01591 #else
01592 int options = 0;
01593 return getxattr(path, name, value, size, 0, options);
01594 #endif
01595 #elif defined(HAVE_GETEA)
01596 return getea(path, name, value, size);
01597 #elif defined(HAVE_EXTATTR_GET_FILE)
01598 char *s;
01599 ssize_t retval;
01600 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
01601 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
01602 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
01603
01604
01605
01606
01607
01608 if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
01609 if(retval > size) {
01610 errno = ERANGE;
01611 return -1;
01612 }
01613 if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
01614 return retval;
01615 }
01616
01617 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno)));
01618 return -1;
01619 #elif defined(HAVE_ATTR_GET)
01620 int retval, flags = 0;
01621 int valuelength = (int)size;
01622 char *attrname = strchr(name,'.') + 1;
01623
01624 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
01625
01626 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
01627
01628 return retval ? retval : valuelength;
01629 #elif defined(HAVE_ATTROPEN)
01630 ssize_t ret = -1;
01631 int attrfd = solaris_attropen(path, name, O_RDONLY, 0);
01632 if (attrfd >= 0) {
01633 ret = solaris_read_xattr(attrfd, value, size);
01634 close(attrfd);
01635 }
01636 return ret;
01637 #else
01638 errno = ENOSYS;
01639 return -1;
01640 #endif
01641 }
01642
01643 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
01644 {
01645 #if defined(HAVE_LGETXATTR)
01646 return lgetxattr(path, name, value, size);
01647 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
01648 int options = XATTR_NOFOLLOW;
01649 return getxattr(path, name, value, size, 0, options);
01650 #elif defined(HAVE_LGETEA)
01651 return lgetea(path, name, value, size);
01652 #elif defined(HAVE_EXTATTR_GET_LINK)
01653 char *s;
01654 ssize_t retval;
01655 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
01656 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
01657 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
01658
01659 if((retval=extattr_get_link(path, attrnamespace, attrname, NULL, 0)) >= 0) {
01660 if(retval > size) {
01661 errno = ERANGE;
01662 return -1;
01663 }
01664 if((retval=extattr_get_link(path, attrnamespace, attrname, value, size)) >= 0)
01665 return retval;
01666 }
01667
01668 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno)));
01669 return -1;
01670 #elif defined(HAVE_ATTR_GET)
01671 int retval, flags = ATTR_DONTFOLLOW;
01672 int valuelength = (int)size;
01673 char *attrname = strchr(name,'.') + 1;
01674
01675 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
01676
01677 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
01678
01679 return retval ? retval : valuelength;
01680 #elif defined(HAVE_ATTROPEN)
01681 ssize_t ret = -1;
01682 int attrfd = solaris_attropen(path, name, O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
01683 if (attrfd >= 0) {
01684 ret = solaris_read_xattr(attrfd, value, size);
01685 close(attrfd);
01686 }
01687 return ret;
01688 #else
01689 errno = ENOSYS;
01690 return -1;
01691 #endif
01692 }
01693
01694 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
01695 {
01696 #if defined(HAVE_FGETXATTR)
01697 #ifndef XATTR_ADD_OPT
01698 return fgetxattr(filedes, name, value, size);
01699 #else
01700 int options = 0;
01701 return fgetxattr(filedes, name, value, size, 0, options);
01702 #endif
01703 #elif defined(HAVE_FGETEA)
01704 return fgetea(filedes, name, value, size);
01705 #elif defined(HAVE_EXTATTR_GET_FD)
01706 char *s;
01707 ssize_t retval;
01708 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
01709 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
01710 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
01711
01712 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
01713 if(retval > size) {
01714 errno = ERANGE;
01715 return -1;
01716 }
01717 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0)
01718 return retval;
01719 }
01720
01721 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno)));
01722 return -1;
01723 #elif defined(HAVE_ATTR_GETF)
01724 int retval, flags = 0;
01725 int valuelength = (int)size;
01726 char *attrname = strchr(name,'.') + 1;
01727
01728 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
01729
01730 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
01731
01732 return retval ? retval : valuelength;
01733 #elif defined(HAVE_ATTROPEN)
01734 ssize_t ret = -1;
01735 int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0);
01736 if (attrfd >= 0) {
01737 ret = solaris_read_xattr(attrfd, value, size);
01738 close(attrfd);
01739 }
01740 return ret;
01741 #else
01742 errno = ENOSYS;
01743 return -1;
01744 #endif
01745 }
01746
01747 #if defined(HAVE_EXTATTR_LIST_FILE)
01748
01749 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
01750
01751 static struct {
01752 int space;
01753 const char *name;
01754 size_t len;
01755 }
01756 extattr[] = {
01757 { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
01758 { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
01759 };
01760
01761 typedef union {
01762 const char *path;
01763 int filedes;
01764 } extattr_arg;
01765
01766 static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
01767 {
01768 ssize_t list_size, total_size = 0;
01769 int i, t, len;
01770 char *buf;
01771
01772 for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
01773 switch(type) {
01774 #if defined(HAVE_EXTATTR_LIST_FILE)
01775 case 0:
01776 list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
01777 break;
01778 #endif
01779 #if defined(HAVE_EXTATTR_LIST_LINK)
01780 case 1:
01781 list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
01782 break;
01783 #endif
01784 #if defined(HAVE_EXTATTR_LIST_FD)
01785 case 2:
01786 list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
01787 break;
01788 #endif
01789 default:
01790 errno = ENOSYS;
01791 return -1;
01792 }
01793
01794 if(list_size < 0)
01795 return -1;
01796
01797 if(list_size == 0)
01798 continue;
01799
01800
01801
01802
01803
01804 if(list == NULL) {
01805
01806
01807
01808 total_size += list_size + (list_size/2 + 1)*extattr[t].len;
01809 continue;
01810 }
01811
01812 len = 0;
01813 for(i = 0; i < list_size; i += list[i] + 1)
01814 len += extattr[t].len;
01815
01816 total_size += list_size + len;
01817
01818 if(total_size > size) {
01819 errno = ERANGE;
01820 return -1;
01821 }
01822
01823 buf = memmove(list + len, list, list_size);
01824
01825 for(i = 0; i < list_size; i += len + 1) {
01826 len = buf[i];
01827 strncpy(list, extattr[t].name, extattr[t].len + 1);
01828 list += extattr[t].len;
01829 strncpy(list, buf + i + 1, len);
01830 list[len] = '\0';
01831 list += len + 1;
01832 }
01833 size -= total_size;
01834 }
01835 return total_size;
01836 }
01837
01838 #endif
01839
01840 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
01841 static char attr_buffer[ATTR_MAX_VALUELEN];
01842
01843 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
01844 {
01845 int retval = 0, index;
01846 attrlist_cursor_t *cursor = 0;
01847 int total_size = 0;
01848 attrlist_t * al = (attrlist_t *)attr_buffer;
01849 attrlist_ent_t *ae;
01850 size_t ent_size, left = size;
01851 char *bp = list;
01852
01853 while (True) {
01854 if (filedes)
01855 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
01856 else
01857 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
01858 if (retval) break;
01859 for (index = 0; index < al->al_count; index++) {
01860 ae = ATTR_ENTRY(attr_buffer, index);
01861 ent_size = strlen(ae->a_name) + sizeof("user.");
01862 if (left >= ent_size) {
01863 strncpy(bp, "user.", sizeof("user."));
01864 strncat(bp, ae->a_name, ent_size - sizeof("user."));
01865 bp += ent_size;
01866 left -= ent_size;
01867 } else if (size) {
01868 errno = ERANGE;
01869 retval = -1;
01870 break;
01871 }
01872 total_size += ent_size;
01873 }
01874 if (al->al_more == 0) break;
01875 }
01876 if (retval == 0) {
01877 flags |= ATTR_ROOT;
01878 cursor = 0;
01879 while (True) {
01880 if (filedes)
01881 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
01882 else
01883 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
01884 if (retval) break;
01885 for (index = 0; index < al->al_count; index++) {
01886 ae = ATTR_ENTRY(attr_buffer, index);
01887 ent_size = strlen(ae->a_name) + sizeof("system.");
01888 if (left >= ent_size) {
01889 strncpy(bp, "system.", sizeof("system."));
01890 strncat(bp, ae->a_name, ent_size - sizeof("system."));
01891 bp += ent_size;
01892 left -= ent_size;
01893 } else if (size) {
01894 errno = ERANGE;
01895 retval = -1;
01896 break;
01897 }
01898 total_size += ent_size;
01899 }
01900 if (al->al_more == 0) break;
01901 }
01902 }
01903 return (ssize_t)(retval ? retval : total_size);
01904 }
01905
01906 #endif
01907
01908 ssize_t sys_listxattr (const char *path, char *list, size_t size)
01909 {
01910 #if defined(HAVE_LISTXATTR)
01911 #ifndef XATTR_ADD_OPT
01912 return listxattr(path, list, size);
01913 #else
01914 int options = 0;
01915 return listxattr(path, list, size, options);
01916 #endif
01917 #elif defined(HAVE_LISTEA)
01918 return listea(path, list, size);
01919 #elif defined(HAVE_EXTATTR_LIST_FILE)
01920 extattr_arg arg;
01921 arg.path = path;
01922 return bsd_attr_list(0, arg, list, size);
01923 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
01924 return irix_attr_list(path, 0, list, size, 0);
01925 #elif defined(HAVE_ATTROPEN)
01926 ssize_t ret = -1;
01927 int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0);
01928 if (attrdirfd >= 0) {
01929 ret = solaris_list_xattr(attrdirfd, list, size);
01930 close(attrdirfd);
01931 }
01932 return ret;
01933 #else
01934 errno = ENOSYS;
01935 return -1;
01936 #endif
01937 }
01938
01939 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
01940 {
01941 #if defined(HAVE_LLISTXATTR)
01942 return llistxattr(path, list, size);
01943 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
01944 int options = XATTR_NOFOLLOW;
01945 return listxattr(path, list, size, options);
01946 #elif defined(HAVE_LLISTEA)
01947 return llistea(path, list, size);
01948 #elif defined(HAVE_EXTATTR_LIST_LINK)
01949 extattr_arg arg;
01950 arg.path = path;
01951 return bsd_attr_list(1, arg, list, size);
01952 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
01953 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
01954 #elif defined(HAVE_ATTROPEN)
01955 ssize_t ret = -1;
01956 int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
01957 if (attrdirfd >= 0) {
01958 ret = solaris_list_xattr(attrdirfd, list, size);
01959 close(attrdirfd);
01960 }
01961 return ret;
01962 #else
01963 errno = ENOSYS;
01964 return -1;
01965 #endif
01966 }
01967
01968 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
01969 {
01970 #if defined(HAVE_FLISTXATTR)
01971 #ifndef XATTR_ADD_OPT
01972 return flistxattr(filedes, list, size);
01973 #else
01974 int options = 0;
01975 return flistxattr(filedes, list, size, options);
01976 #endif
01977 #elif defined(HAVE_FLISTEA)
01978 return flistea(filedes, list, size);
01979 #elif defined(HAVE_EXTATTR_LIST_FD)
01980 extattr_arg arg;
01981 arg.filedes = filedes;
01982 return bsd_attr_list(2, arg, list, size);
01983 #elif defined(HAVE_ATTR_LISTF)
01984 return irix_attr_list(NULL, filedes, list, size, 0);
01985 #elif defined(HAVE_ATTROPEN)
01986 ssize_t ret = -1;
01987 int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
01988 if (attrdirfd >= 0) {
01989 ret = solaris_list_xattr(attrdirfd, list, size);
01990 close(attrdirfd);
01991 }
01992 return ret;
01993 #else
01994 errno = ENOSYS;
01995 return -1;
01996 #endif
01997 }
01998
01999 int sys_removexattr (const char *path, const char *name)
02000 {
02001 #if defined(HAVE_REMOVEXATTR)
02002 #ifndef XATTR_ADD_OPT
02003 return removexattr(path, name);
02004 #else
02005 int options = 0;
02006 return removexattr(path, name, options);
02007 #endif
02008 #elif defined(HAVE_REMOVEEA)
02009 return removeea(path, name);
02010 #elif defined(HAVE_EXTATTR_DELETE_FILE)
02011 char *s;
02012 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
02013 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
02014 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
02015
02016 return extattr_delete_file(path, attrnamespace, attrname);
02017 #elif defined(HAVE_ATTR_REMOVE)
02018 int flags = 0;
02019 char *attrname = strchr(name,'.') + 1;
02020
02021 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
02022
02023 return attr_remove(path, attrname, flags);
02024 #elif defined(HAVE_ATTROPEN)
02025 int ret = -1;
02026 int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0);
02027 if (attrdirfd >= 0) {
02028 ret = solaris_unlinkat(attrdirfd, name);
02029 close(attrdirfd);
02030 }
02031 return ret;
02032 #else
02033 errno = ENOSYS;
02034 return -1;
02035 #endif
02036 }
02037
02038 int sys_lremovexattr (const char *path, const char *name)
02039 {
02040 #if defined(HAVE_LREMOVEXATTR)
02041 return lremovexattr(path, name);
02042 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
02043 int options = XATTR_NOFOLLOW;
02044 return removexattr(path, name, options);
02045 #elif defined(HAVE_LREMOVEEA)
02046 return lremoveea(path, name);
02047 #elif defined(HAVE_EXTATTR_DELETE_LINK)
02048 char *s;
02049 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
02050 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
02051 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
02052
02053 return extattr_delete_link(path, attrnamespace, attrname);
02054 #elif defined(HAVE_ATTR_REMOVE)
02055 int flags = ATTR_DONTFOLLOW;
02056 char *attrname = strchr(name,'.') + 1;
02057
02058 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
02059
02060 return attr_remove(path, attrname, flags);
02061 #elif defined(HAVE_ATTROPEN)
02062 int ret = -1;
02063 int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
02064 if (attrdirfd >= 0) {
02065 ret = solaris_unlinkat(attrdirfd, name);
02066 close(attrdirfd);
02067 }
02068 return ret;
02069 #else
02070 errno = ENOSYS;
02071 return -1;
02072 #endif
02073 }
02074
02075 int sys_fremovexattr (int filedes, const char *name)
02076 {
02077 #if defined(HAVE_FREMOVEXATTR)
02078 #ifndef XATTR_ADD_OPT
02079 return fremovexattr(filedes, name);
02080 #else
02081 int options = 0;
02082 return fremovexattr(filedes, name, options);
02083 #endif
02084 #elif defined(HAVE_FREMOVEEA)
02085 return fremoveea(filedes, name);
02086 #elif defined(HAVE_EXTATTR_DELETE_FD)
02087 char *s;
02088 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
02089 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
02090 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
02091
02092 return extattr_delete_fd(filedes, attrnamespace, attrname);
02093 #elif defined(HAVE_ATTR_REMOVEF)
02094 int flags = 0;
02095 char *attrname = strchr(name,'.') + 1;
02096
02097 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
02098
02099 return attr_removef(filedes, attrname, flags);
02100 #elif defined(HAVE_ATTROPEN)
02101 int ret = -1;
02102 int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
02103 if (attrdirfd >= 0) {
02104 ret = solaris_unlinkat(attrdirfd, name);
02105 close(attrdirfd);
02106 }
02107 return ret;
02108 #else
02109 errno = ENOSYS;
02110 return -1;
02111 #endif
02112 }
02113
02114 #if !defined(HAVE_SETXATTR)
02115 #define XATTR_CREATE 0x1
02116 #define XATTR_REPLACE 0x2
02117 #endif
02118
02119 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
02120 {
02121 #if defined(HAVE_SETXATTR)
02122 #ifndef XATTR_ADD_OPT
02123 return setxattr(path, name, value, size, flags);
02124 #else
02125 int options = 0;
02126 return setxattr(path, name, value, size, 0, options);
02127 #endif
02128 #elif defined(HAVE_SETEA)
02129 return setea(path, name, value, size, flags);
02130 #elif defined(HAVE_EXTATTR_SET_FILE)
02131 char *s;
02132 int retval = 0;
02133 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
02134 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
02135 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
02136 if (flags) {
02137
02138 retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
02139 if (retval < 0) {
02140
02141 if (flags & XATTR_REPLACE && errno == ENOATTR) {
02142 errno = ENOATTR;
02143 return -1;
02144 }
02145
02146 }
02147 else {
02148
02149 if (flags & XATTR_CREATE) {
02150 errno = EEXIST;
02151 return -1;
02152 }
02153 }
02154 }
02155 retval = extattr_set_file(path, attrnamespace, attrname, value, size);
02156 return (retval < 0) ? -1 : 0;
02157 #elif defined(HAVE_ATTR_SET)
02158 int myflags = 0;
02159 char *attrname = strchr(name,'.') + 1;
02160
02161 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
02162 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
02163 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
02164
02165 return attr_set(path, attrname, (const char *)value, size, myflags);
02166 #elif defined(HAVE_ATTROPEN)
02167 int ret = -1;
02168 int myflags = O_RDWR;
02169 int attrfd;
02170 if (flags & XATTR_CREATE) myflags |= O_EXCL;
02171 if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
02172 attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
02173 if (attrfd >= 0) {
02174 ret = solaris_write_xattr(attrfd, value, size);
02175 close(attrfd);
02176 }
02177 return ret;
02178 #else
02179 errno = ENOSYS;
02180 return -1;
02181 #endif
02182 }
02183
02184 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
02185 {
02186 #if defined(HAVE_LSETXATTR)
02187 return lsetxattr(path, name, value, size, flags);
02188 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
02189 int options = XATTR_NOFOLLOW;
02190 return setxattr(path, name, value, size, 0, options);
02191 #elif defined(LSETEA)
02192 return lsetea(path, name, value, size, flags);
02193 #elif defined(HAVE_EXTATTR_SET_LINK)
02194 char *s;
02195 int retval = 0;
02196 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
02197 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
02198 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
02199 if (flags) {
02200
02201 retval = extattr_get_link(path, attrnamespace, attrname, NULL, 0);
02202 if (retval < 0) {
02203
02204 if (flags & XATTR_REPLACE && errno == ENOATTR) {
02205 errno = ENOATTR;
02206 return -1;
02207 }
02208
02209 }
02210 else {
02211
02212 if (flags & XATTR_CREATE) {
02213 errno = EEXIST;
02214 return -1;
02215 }
02216 }
02217 }
02218
02219 retval = extattr_set_link(path, attrnamespace, attrname, value, size);
02220 return (retval < 0) ? -1 : 0;
02221 #elif defined(HAVE_ATTR_SET)
02222 int myflags = ATTR_DONTFOLLOW;
02223 char *attrname = strchr(name,'.') + 1;
02224
02225 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
02226 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
02227 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
02228
02229 return attr_set(path, attrname, (const char *)value, size, myflags);
02230 #elif defined(HAVE_ATTROPEN)
02231 int ret = -1;
02232 int myflags = O_RDWR | AT_SYMLINK_NOFOLLOW;
02233 int attrfd;
02234 if (flags & XATTR_CREATE) myflags |= O_EXCL;
02235 if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
02236 attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
02237 if (attrfd >= 0) {
02238 ret = solaris_write_xattr(attrfd, value, size);
02239 close(attrfd);
02240 }
02241 return ret;
02242 #else
02243 errno = ENOSYS;
02244 return -1;
02245 #endif
02246 }
02247
02248 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
02249 {
02250 #if defined(HAVE_FSETXATTR)
02251 #ifndef XATTR_ADD_OPT
02252 return fsetxattr(filedes, name, value, size, flags);
02253 #else
02254 int options = 0;
02255 return fsetxattr(filedes, name, value, size, 0, options);
02256 #endif
02257 #elif defined(HAVE_FSETEA)
02258 return fsetea(filedes, name, value, size, flags);
02259 #elif defined(HAVE_EXTATTR_SET_FD)
02260 char *s;
02261 int retval = 0;
02262 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
02263 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
02264 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
02265 if (flags) {
02266
02267 retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
02268 if (retval < 0) {
02269
02270 if (flags & XATTR_REPLACE && errno == ENOATTR) {
02271 errno = ENOATTR;
02272 return -1;
02273 }
02274
02275 }
02276 else {
02277
02278 if (flags & XATTR_CREATE) {
02279 errno = EEXIST;
02280 return -1;
02281 }
02282 }
02283 }
02284 retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
02285 return (retval < 0) ? -1 : 0;
02286 #elif defined(HAVE_ATTR_SETF)
02287 int myflags = 0;
02288 char *attrname = strchr(name,'.') + 1;
02289
02290 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
02291 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
02292 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
02293
02294 return attr_setf(filedes, attrname, (const char *)value, size, myflags);
02295 #elif defined(HAVE_ATTROPEN)
02296 int ret = -1;
02297 int myflags = O_RDWR | O_XATTR;
02298 int attrfd;
02299 if (flags & XATTR_CREATE) myflags |= O_EXCL;
02300 if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
02301 attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE);
02302 if (attrfd >= 0) {
02303 ret = solaris_write_xattr(attrfd, value, size);
02304 close(attrfd);
02305 }
02306 return ret;
02307 #else
02308 errno = ENOSYS;
02309 return -1;
02310 #endif
02311 }
02312
02313
02314
02315
02316 #ifdef HAVE_ATTROPEN
02317 static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size)
02318 {
02319 struct stat sbuf;
02320
02321 if (fstat(attrfd, &sbuf) == -1) {
02322 errno = ENOATTR;
02323 return -1;
02324 }
02325
02326
02327 if (size == 0) {
02328 return sbuf.st_size;
02329 }
02330
02331
02332 if (sbuf.st_size > size) {
02333 errno = ERANGE;
02334 return -1;
02335 }
02336
02337 return read(attrfd, value, sbuf.st_size);
02338 }
02339
02340 static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size)
02341 {
02342 ssize_t len = 0;
02343 int stop = 0;
02344 DIR *dirp;
02345 struct dirent *de;
02346 int newfd = dup(attrdirfd);
02347
02348
02349
02350
02351 dirp = fdopendir(newfd);
02352
02353 while ((de = readdir(dirp))) {
02354 size_t listlen = strlen(de->d_name);
02355 if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
02356
02357 DEBUG(10,("skipped EA %s\n",de->d_name));
02358 continue;
02359 }
02360
02361 if (size == 0) {
02362
02363 len += listlen + 1;
02365