2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1998-2005
6 Copyright (C) Timur Bakeyev 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #ifdef HAVE_SYS_PRCTL_H
26 #include <sys/prctl.h>
30 The idea is that this file will eventually have wrappers around all
31 important system calls in samba. The aims are:
33 - to enable easier porting by putting OS dependent stuff in here
35 - to allow for hooks into other "pseudo-filesystems"
37 - to allow easier integration of things like the japanese extensions
39 - to support the philosophy of Samba to expose the features of
40 the OS within the SMB model. In general whatever file/printer/variable
41 expansions/etc make sense to the OS should be acceptable to Samba.
46 /*******************************************************************
47 A wrapper for memalign
48 ********************************************************************/
50 void* sys_memalign( size_t align, size_t size )
52 #if defined(HAVE_MEMALIGN)
53 return memalign( align, size );
54 #elif defined(HAVE_POSIX_MEMALIGN)
56 int ret = posix_memalign( &p, align, size );
62 DEBUG(0,("memalign functionalaity not available on this platform!\n"));
67 /*******************************************************************
68 A wrapper for usleep in case we don't have one.
69 ********************************************************************/
71 int sys_usleep(long usecs)
78 * We need this braindamage as the glibc usleep
79 * is not SPEC1170 complient... grumble... JRA.
82 if(usecs < 0 || usecs > 1000000) {
90 #else /* HAVE_USLEEP */
92 * Fake it with select...
95 tval.tv_usec = usecs/1000;
96 select(0,NULL,NULL,NULL,&tval);
98 #endif /* HAVE_USLEEP */
101 /*******************************************************************
102 A read wrapper that will deal with EINTR.
103 ********************************************************************/
105 ssize_t sys_read(int fd, void *buf, size_t count)
110 ret = read(fd, buf, count);
111 } while (ret == -1 && errno == EINTR);
115 /*******************************************************************
116 A write wrapper that will deal with EINTR.
117 ********************************************************************/
119 ssize_t sys_write(int fd, const void *buf, size_t count)
124 ret = write(fd, buf, count);
125 } while (ret == -1 && errno == EINTR);
129 /*******************************************************************
130 A pread wrapper that will deal with EINTR and 64-bit file offsets.
131 ********************************************************************/
133 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
134 ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
139 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
140 ret = pread64(fd, buf, count, off);
142 ret = pread(fd, buf, count, off);
144 } while (ret == -1 && errno == EINTR);
149 /*******************************************************************
150 A write wrapper that will deal with EINTR and 64-bit file offsets.
151 ********************************************************************/
153 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
154 ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
159 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
160 ret = pwrite64(fd, buf, count, off);
162 ret = pwrite(fd, buf, count, off);
164 } while (ret == -1 && errno == EINTR);
169 /*******************************************************************
170 A send wrapper that will deal with EINTR.
171 ********************************************************************/
173 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
178 ret = send(s, msg, len, flags);
179 } while (ret == -1 && errno == EINTR);
183 /*******************************************************************
184 A sendto wrapper that will deal with EINTR.
185 ********************************************************************/
187 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
192 ret = sendto(s, msg, len, flags, to, tolen);
193 } while (ret == -1 && errno == EINTR);
197 /*******************************************************************
198 A recv wrapper that will deal with EINTR.
199 ********************************************************************/
201 ssize_t sys_recv(int fd, void *buf, size_t count, int flags)
206 ret = recv(fd, buf, count, flags);
207 } while (ret == -1 && errno == EINTR);
211 /*******************************************************************
212 A recvfrom wrapper that will deal with EINTR.
213 ********************************************************************/
215 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
220 ret = recvfrom(s, buf, len, flags, from, fromlen);
221 } while (ret == -1 && errno == EINTR);
225 /*******************************************************************
226 A fcntl wrapper that will deal with EINTR.
227 ********************************************************************/
229 int sys_fcntl_ptr(int fd, int cmd, void *arg)
234 ret = fcntl(fd, cmd, arg);
235 } while (ret == -1 && errno == EINTR);
239 /*******************************************************************
240 A fcntl wrapper that will deal with EINTR.
241 ********************************************************************/
243 int sys_fcntl_long(int fd, int cmd, long arg)
248 ret = fcntl(fd, cmd, arg);
249 } while (ret == -1 && errno == EINTR);
253 /*******************************************************************
254 A stat() wrapper that will deal with 64 bit filesizes.
255 ********************************************************************/
257 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
260 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
261 ret = stat64(fname, sbuf);
263 ret = stat(fname, sbuf);
265 /* we always want directories to appear zero size */
266 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
270 /*******************************************************************
271 An fstat() wrapper that will deal with 64 bit filesizes.
272 ********************************************************************/
274 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
277 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
278 ret = fstat64(fd, sbuf);
280 ret = fstat(fd, sbuf);
282 /* we always want directories to appear zero size */
283 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
287 /*******************************************************************
288 An lstat() wrapper that will deal with 64 bit filesizes.
289 ********************************************************************/
291 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
294 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
295 ret = lstat64(fname, sbuf);
297 ret = lstat(fname, sbuf);
299 /* we always want directories to appear zero size */
300 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
304 /*******************************************************************
305 An ftruncate() wrapper that will deal with 64 bit filesizes.
306 ********************************************************************/
308 int sys_ftruncate(int fd, SMB_OFF_T offset)
310 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
311 return ftruncate64(fd, offset);
313 return ftruncate(fd, offset);
317 /*******************************************************************
318 An lseek() wrapper that will deal with 64 bit filesizes.
319 ********************************************************************/
321 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
323 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
324 return lseek64(fd, offset, whence);
326 return lseek(fd, offset, whence);
330 /*******************************************************************
331 An fseek() wrapper that will deal with 64 bit filesizes.
332 ********************************************************************/
334 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
336 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
337 return fseek64(fp, offset, whence);
338 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
339 return fseeko64(fp, offset, whence);
341 return fseek(fp, offset, whence);
345 /*******************************************************************
346 An ftell() wrapper that will deal with 64 bit filesizes.
347 ********************************************************************/
349 SMB_OFF_T sys_ftell(FILE *fp)
351 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
352 return (SMB_OFF_T)ftell64(fp);
353 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
354 return (SMB_OFF_T)ftello64(fp);
356 return (SMB_OFF_T)ftell(fp);
360 /*******************************************************************
361 A creat() wrapper that will deal with 64 bit filesizes.
362 ********************************************************************/
364 int sys_creat(const char *path, mode_t mode)
366 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
367 return creat64(path, mode);
370 * If creat64 isn't defined then ensure we call a potential open64.
373 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
377 /*******************************************************************
378 An open() wrapper that will deal with 64 bit filesizes.
379 ********************************************************************/
381 int sys_open(const char *path, int oflag, mode_t mode)
383 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
384 return open64(path, oflag, mode);
386 return open(path, oflag, mode);
390 /*******************************************************************
391 An fopen() wrapper that will deal with 64 bit filesizes.
392 ********************************************************************/
394 FILE *sys_fopen(const char *path, const char *type)
396 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
397 return fopen64(path, type);
399 return fopen(path, type);
404 /*******************************************************************
405 A flock() wrapper that will perform the kernel flock.
406 ********************************************************************/
408 void kernel_flock(int fd, uint32 share_mode)
410 #if HAVE_KERNEL_SHARE_MODES
412 if (share_mode == FILE_SHARE_WRITE) {
413 kernel_mode = LOCK_MAND|LOCK_WRITE;
414 } else if (share_mode == FILE_SHARE_READ) {
415 kernel_mode = LOCK_MAND|LOCK_READ;
416 } else if (share_mode == FILE_SHARE_NONE) {
417 kernel_mode = LOCK_MAND;
420 flock(fd, kernel_mode);
428 /*******************************************************************
429 An opendir wrapper that will deal with 64 bit filesizes.
430 ********************************************************************/
432 SMB_STRUCT_DIR *sys_opendir(const char *name)
434 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
435 return opendir64(name);
437 return opendir(name);
441 /*******************************************************************
442 A readdir wrapper that will deal with 64 bit filesizes.
443 ********************************************************************/
445 SMB_STRUCT_DIRENT *sys_readdir(SMB_STRUCT_DIR *dirp)
447 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
448 return readdir64(dirp);
450 return readdir(dirp);
454 /*******************************************************************
455 A seekdir wrapper that will deal with 64 bit filesizes.
456 ********************************************************************/
458 void sys_seekdir(SMB_STRUCT_DIR *dirp, long offset)
460 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
461 seekdir64(dirp, offset);
463 seekdir(dirp, offset);
467 /*******************************************************************
468 A telldir wrapper that will deal with 64 bit filesizes.
469 ********************************************************************/
471 long sys_telldir(SMB_STRUCT_DIR *dirp)
473 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
474 return (long)telldir64(dirp);
476 return (long)telldir(dirp);
480 /*******************************************************************
481 A rewinddir wrapper that will deal with 64 bit filesizes.
482 ********************************************************************/
484 void sys_rewinddir(SMB_STRUCT_DIR *dirp)
486 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
493 /*******************************************************************
494 A close wrapper that will deal with 64 bit filesizes.
495 ********************************************************************/
497 int sys_closedir(SMB_STRUCT_DIR *dirp)
499 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
500 return closedir64(dirp);
502 return closedir(dirp);
506 /*******************************************************************
507 An mknod() wrapper that will deal with 64 bit filesizes.
508 ********************************************************************/
510 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
512 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
513 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
514 return mknod64(path, mode, dev);
516 return mknod(path, mode, dev);
519 /* No mknod system call. */
525 /*******************************************************************
526 Wrapper for realpath.
527 ********************************************************************/
529 char *sys_realpath(const char *path, char *resolved_path)
531 #if defined(HAVE_REALPATH)
532 return realpath(path, resolved_path);
534 /* As realpath is not a system call we can't return ENOSYS. */
540 /*******************************************************************
541 The wait() calls vary between systems
542 ********************************************************************/
544 int sys_waitpid(pid_t pid,int *status,int options)
547 return waitpid(pid,status,options);
548 #else /* HAVE_WAITPID */
549 return wait4(pid, status, options, NULL);
550 #endif /* HAVE_WAITPID */
553 /*******************************************************************
554 System wrapper for getwd
555 ********************************************************************/
557 char *sys_getwd(char *s)
561 wd = (char *)getcwd(s, sizeof (pstring));
563 wd = (char *)getwd(s);
568 /*******************************************************************
569 system wrapper for symlink
570 ********************************************************************/
572 int sys_symlink(const char *oldpath, const char *newpath)
578 return symlink(oldpath, newpath);
582 /*******************************************************************
583 system wrapper for readlink
584 ********************************************************************/
586 int sys_readlink(const char *path, char *buf, size_t bufsiz)
588 #ifndef HAVE_READLINK
592 return readlink(path, buf, bufsiz);
596 /*******************************************************************
597 system wrapper for link
598 ********************************************************************/
600 int sys_link(const char *oldpath, const char *newpath)
606 return link(oldpath, newpath);
610 /*******************************************************************
611 chown isn't used much but OS/2 doesn't have it
612 ********************************************************************/
614 int sys_chown(const char *fname,uid_t uid,gid_t gid)
619 DEBUG(1,("WARNING: no chown!\n"));
625 return(chown(fname,uid,gid));
629 /*******************************************************************
630 os/2 also doesn't have chroot
631 ********************************************************************/
632 int sys_chroot(const char *dname)
637 DEBUG(1,("WARNING: no chroot!\n"));
643 return(chroot(dname));
647 /**************************************************************************
648 A wrapper for gethostbyname() that tries avoids looking up hostnames
649 in the root domain, which can cause dial-on-demand links to come up for no
651 ****************************************************************************/
653 struct hostent *sys_gethostbyname(const char *name)
655 #ifdef REDUCE_ROOT_DNS_LOOKUPS
656 char query[256], hostname[256];
659 /* Does this name have any dots in it? If so, make no change */
661 if (strchr_m(name, '.'))
662 return(gethostbyname(name));
664 /* Get my hostname, which should have domain name
665 attached. If not, just do the gethostname on the
669 gethostname(hostname, sizeof(hostname) - 1);
670 hostname[sizeof(hostname) - 1] = 0;
671 if ((domain = strchr_m(hostname, '.')) == NULL)
672 return(gethostbyname(name));
674 /* Attach domain name to query and do modified query.
675 If names too large, just do gethostname on the
679 if((strlen(name) + strlen(domain)) >= sizeof(query))
680 return(gethostbyname(name));
682 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
683 return(gethostbyname(query));
684 #else /* REDUCE_ROOT_DNS_LOOKUPS */
685 return(gethostbyname(name));
686 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
690 #if defined(HAVE_POSIX_CAPABILITIES)
692 #ifdef HAVE_SYS_CAPABILITY_H
694 #if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H)
695 #define _I386_STATFS_H
696 #define _PPC_STATFS_H
697 #define BROKEN_REDHAT_7_STATFS_WORKAROUND
700 #include <sys/capability.h>
702 #ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND
703 #undef _I386_STATFS_H
705 #undef BROKEN_REDHAT_7_STATFS_WORKAROUND
708 #endif /* HAVE_SYS_CAPABILITY_H */
710 /**************************************************************************
711 Try and abstract process capabilities (for systems that have them).
712 ****************************************************************************/
714 /* Set the POSIX capabilities needed for the given purpose into the effective
715 * capability set of the current process. Make sure they are always removed
716 * from the inheritable set, because there is no circumstance in which our
717 * children should inherit our elevated privileges.
719 static BOOL set_process_capability(enum smbd_capability capability,
722 cap_value_t cap_vals[2] = {0};
723 int num_cap_vals = 0;
727 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
728 /* On Linux, make sure that any capabilities we grab are sticky
729 * across UID changes. We expect that this would allow us to keep both
730 * the effective and permitted capability sets, but as of circa 2.6.16,
731 * only the permitted set is kept. It is a bug (which we work around)
732 * that the effective set is lost, but we still require the effective
735 if (!prctl(PR_GET_KEEPCAPS)) {
736 prctl(PR_SET_KEEPCAPS, 1);
740 cap = cap_get_proc();
742 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
747 switch (capability) {
748 case KERNEL_OPLOCK_CAPABILITY:
749 #ifdef CAP_NETWORK_MGT
750 /* IRIX has CAP_NETWORK_MGT for oplocks. */
751 cap_vals[num_cap_vals++] = CAP_NETWORK_MGT;
754 case DMAPI_ACCESS_CAPABILITY:
755 #ifdef CAP_DEVICE_MGT
756 /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
757 cap_vals[num_cap_vals++] = CAP_DEVICE_MGT;
759 /* Linux has CAP_MKNOD for DMAPI access. */
760 cap_vals[num_cap_vals++] = CAP_MKNOD;
765 SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals));
767 if (num_cap_vals == 0) {
772 cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
773 enable ? CAP_SET : CAP_CLEAR);
775 /* We never want to pass capabilities down to our children, so make
776 * sure they are not inherited.
778 cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
780 if (cap_set_proc(cap) == -1) {
781 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
791 #endif /* HAVE_POSIX_CAPABILITIES */
793 /****************************************************************************
794 Gain the oplock capability from the kernel if possible.
795 ****************************************************************************/
797 void set_effective_capability(enum smbd_capability capability)
799 #if defined(HAVE_POSIX_CAPABILITIES)
800 set_process_capability(capability, True);
801 #endif /* HAVE_POSIX_CAPABILITIES */
804 void drop_effective_capability(enum smbd_capability capability)
806 #if defined(HAVE_POSIX_CAPABILITIES)
807 set_process_capability(capability, False);
808 #endif /* HAVE_POSIX_CAPABILITIES */
811 /**************************************************************************
812 Wrapper for random().
813 ****************************************************************************/
815 long sys_random(void)
817 #if defined(HAVE_RANDOM)
818 return (long)random();
819 #elif defined(HAVE_RAND)
822 DEBUG(0,("Error - no random function available !\n"));
827 /**************************************************************************
828 Wrapper for srandom().
829 ****************************************************************************/
831 void sys_srandom(unsigned int seed)
833 #if defined(HAVE_SRANDOM)
835 #elif defined(HAVE_SRAND)
838 DEBUG(0,("Error - no srandom function available !\n"));
843 /**************************************************************************
844 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
845 ****************************************************************************/
849 #if defined(SYSCONF_SC_NGROUPS_MAX)
850 int ret = sysconf(_SC_NGROUPS_MAX);
851 return (ret == -1) ? NGROUPS_MAX : ret;
857 /**************************************************************************
858 Wrapper for getgroups. Deals with broken (int) case.
859 ****************************************************************************/
861 int sys_getgroups(int setlen, gid_t *gidset)
863 #if !defined(HAVE_BROKEN_GETGROUPS)
864 return getgroups(setlen, gidset);
872 return getgroups(setlen, &gid);
876 * Broken case. We need to allocate a
877 * GID_T array of size setlen.
886 setlen = groups_max();
888 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
889 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
893 if((ngroups = getgroups(setlen, group_list)) < 0) {
894 int saved_errno = errno;
895 SAFE_FREE(group_list);
900 for(i = 0; i < ngroups; i++)
901 gidset[i] = (gid_t)group_list[i];
903 SAFE_FREE(group_list);
905 #endif /* HAVE_BROKEN_GETGROUPS */
909 /**************************************************************************
910 Wrapper for setgroups. Deals with broken (int) case. Automatically used
911 if we have broken getgroups.
912 ****************************************************************************/
914 int sys_setgroups(int setlen, gid_t *gidset)
916 #if !defined(HAVE_SETGROUPS)
919 #endif /* HAVE_SETGROUPS */
921 #if !defined(HAVE_BROKEN_GETGROUPS)
922 return setgroups(setlen, gidset);
931 if (setlen < 0 || setlen > groups_max()) {
937 * Broken case. We need to allocate a
938 * GID_T array of size setlen.
941 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
942 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
946 for(i = 0; i < setlen; i++)
947 group_list[i] = (GID_T) gidset[i];
949 if(setgroups(setlen, group_list) != 0) {
950 int saved_errno = errno;
951 SAFE_FREE(group_list);
956 SAFE_FREE(group_list);
958 #endif /* HAVE_BROKEN_GETGROUPS */
961 /**************************************************************************
962 Wrappers for setpwent(), getpwent() and endpwent()
963 ****************************************************************************/
965 void sys_setpwent(void)
970 struct passwd *sys_getpwent(void)
975 void sys_endpwent(void)
980 /**************************************************************************
981 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
982 ****************************************************************************/
984 #ifdef ENABLE_BUILD_FARM_HACKS
987 * In the build farm we want to be able to join machines to the domain. As we
988 * don't have root access, we need to bypass direct access to /etc/passwd
989 * after a user has been created via samr. Fake those users.
992 static struct passwd *fake_pwd;
993 static int num_fake_pwd;
995 struct passwd *sys_getpwnam(const char *name)
999 for (i=0; i<num_fake_pwd; i++) {
1000 if (strcmp(fake_pwd[i].pw_name, name) == 0) {
1001 DEBUG(10, ("Returning fake user %s\n", name));
1002 return &fake_pwd[i];
1006 return getpwnam(name);
1009 struct passwd *sys_getpwuid(uid_t uid)
1013 for (i=0; i<num_fake_pwd; i++) {
1014 if (fake_pwd[i].pw_uid == uid) {
1015 DEBUG(10, ("Returning fake user %s\n",
1016 fake_pwd[i].pw_name));
1017 return &fake_pwd[i];
1021 return getpwuid(uid);
1024 void faked_create_user(const char *name)
1028 struct passwd new_pwd;
1030 for (i=0; i<10; i++) {
1031 generate_random_buffer((unsigned char *)&uid,
1033 if (getpwuid(uid) == NULL) {
1039 /* Weird. No free uid found... */
1043 new_pwd.pw_name = SMB_STRDUP(name);
1044 new_pwd.pw_passwd = SMB_STRDUP("x");
1045 new_pwd.pw_uid = uid;
1046 new_pwd.pw_gid = 100;
1047 new_pwd.pw_gecos = SMB_STRDUP("faked user");
1048 new_pwd.pw_dir = SMB_STRDUP("/nodir");
1049 new_pwd.pw_shell = SMB_STRDUP("/bin/false");
1051 ADD_TO_ARRAY(NULL, struct passwd, new_pwd, &fake_pwd,
1054 DEBUG(10, ("Added fake user %s, have %d fake users\n",
1055 name, num_fake_pwd));
1060 struct passwd *sys_getpwnam(const char *name)
1062 return getpwnam(name);
1065 struct passwd *sys_getpwuid(uid_t uid)
1067 return getpwuid(uid);
1072 struct group *sys_getgrnam(const char *name)
1074 return getgrnam(name);
1077 struct group *sys_getgrgid(gid_t gid)
1079 return getgrgid(gid);
1082 #if 0 /* NOT CURRENTLY USED - JRA */
1083 /**************************************************************************
1084 The following are the UNICODE versions of *all* system interface functions
1085 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
1086 which currently are left as ascii as they are not used other than in name
1088 ****************************************************************************/
1090 /**************************************************************************
1091 Wide stat. Just narrow and call sys_xxx.
1092 ****************************************************************************/
1094 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
1097 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
1100 /**************************************************************************
1101 Wide lstat. Just narrow and call sys_xxx.
1102 ****************************************************************************/
1104 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
1107 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
1110 /**************************************************************************
1111 Wide creat. Just narrow and call sys_xxx.
1112 ****************************************************************************/
1114 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
1117 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
1120 /**************************************************************************
1121 Wide open. Just narrow and call sys_xxx.
1122 ****************************************************************************/
1124 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
1127 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
1130 /**************************************************************************
1131 Wide fopen. Just narrow and call sys_xxx.
1132 ****************************************************************************/
1134 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
1137 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
1140 /**************************************************************************
1141 Wide opendir. Just narrow and call sys_xxx.
1142 ****************************************************************************/
1144 SMB_STRUCT_DIR *wsys_opendir(const smb_ucs2_t *wfname)
1147 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
1150 /**************************************************************************
1151 Wide readdir. Return a structure pointer containing a wide filename.
1152 ****************************************************************************/
1154 SMB_STRUCT_WDIRENT *wsys_readdir(SMB_STRUCT_DIR *dirp)
1156 static SMB_STRUCT_WDIRENT retval;
1157 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
1163 * The only POSIX defined member of this struct is d_name.
1166 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
1171 /**************************************************************************
1172 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
1173 ****************************************************************************/
1175 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
1178 char *p = sys_getwd(fname);
1183 return unix_to_unicode(s, p, sizeof(wpstring));
1186 /**************************************************************************
1187 Wide chown. Just narrow and call sys_xxx.
1188 ****************************************************************************/
1190 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
1193 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
1196 /**************************************************************************
1197 Wide chroot. Just narrow and call sys_xxx.
1198 ****************************************************************************/
1200 int wsys_chroot(const smb_ucs2_t *wfname)
1203 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
1206 /**************************************************************************
1207 Wide getpwnam. Return a structure pointer containing wide names.
1208 ****************************************************************************/
1210 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
1212 static SMB_STRUCT_WPASSWD retval;
1214 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
1219 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1220 retval.pw_passwd = pwret->pw_passwd;
1221 retval.pw_uid = pwret->pw_uid;
1222 retval.pw_gid = pwret->pw_gid;
1223 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1224 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1225 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1230 /**************************************************************************
1231 Wide getpwuid. Return a structure pointer containing wide names.
1232 ****************************************************************************/
1234 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
1236 static SMB_STRUCT_WPASSWD retval;
1237 struct passwd *pwret = sys_getpwuid(uid);
1242 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1243 retval.pw_passwd = pwret->pw_passwd;
1244 retval.pw_uid = pwret->pw_uid;
1245 retval.pw_gid = pwret->pw_gid;
1246 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1247 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1248 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1252 #endif /* NOT CURRENTLY USED - JRA */
1254 /**************************************************************************
1255 Extract a command into an arg list. Uses a static pstring for storage.
1256 Caller frees returned arg list (which contains pointers into the static pstring).
1257 ****************************************************************************/
1259 static char **extract_args(const char *command)
1261 static pstring trunc_cmd;
1267 pstrcpy(trunc_cmd, command);
1269 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1278 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1281 if((argl = (char **)SMB_MALLOC((argcl + 1) * sizeof(char *))) == NULL)
1285 * Now do the extraction.
1288 pstrcpy(trunc_cmd, command);
1290 ptr = strtok(trunc_cmd, " \t");
1294 while((ptr = strtok(NULL, " \t")) != NULL)
1301 /**************************************************************************
1302 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1303 a sys_getpid() that only does a system call *once*.
1304 ****************************************************************************/
1306 static pid_t mypid = (pid_t)-1;
1308 pid_t sys_fork(void)
1310 pid_t forkret = fork();
1312 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1318 /**************************************************************************
1319 Wrapper for getpid. Ensures we only do a system call *once*.
1320 ****************************************************************************/
1322 pid_t sys_getpid(void)
1324 if (mypid == (pid_t)-1)
1330 /**************************************************************************
1331 Wrapper for popen. Safer as it doesn't search a path.
1332 Modified from the glibc sources.
1333 modified by tridge to return a file descriptor. We must kick our FILE* habit
1334 ****************************************************************************/
1336 typedef struct _popen_list
1340 struct _popen_list *next;
1343 static popen_list *popen_chain;
1345 int sys_popen(const char *command)
1347 int parent_end, child_end;
1349 popen_list *entry = NULL;
1352 if (pipe(pipe_fds) < 0)
1355 parent_end = pipe_fds[0];
1356 child_end = pipe_fds[1];
1363 if((entry = SMB_MALLOC_P(popen_list)) == NULL)
1366 ZERO_STRUCTP(entry);
1369 * Extract the command and args into a NULL terminated array.
1372 if(!(argl = extract_args(command)))
1375 entry->child_pid = sys_fork();
1377 if (entry->child_pid == -1) {
1381 if (entry->child_pid == 0) {
1387 int child_std_end = STDOUT_FILENO;
1391 if (child_end != child_std_end) {
1392 dup2 (child_end, child_std_end);
1397 * POSIX.2: "popen() shall ensure that any streams from previous
1398 * popen() calls that remain open in the parent process are closed
1399 * in the new child process."
1402 for (p = popen_chain; p; p = p->next)
1405 execv(argl[0], argl);
1416 /* Link into popen_chain. */
1417 entry->next = popen_chain;
1418 popen_chain = entry;
1419 entry->fd = parent_end;
1432 /**************************************************************************
1433 Wrapper for pclose. Modified from the glibc sources.
1434 ****************************************************************************/
1436 int sys_pclose(int fd)
1439 popen_list **ptr = &popen_chain;
1440 popen_list *entry = NULL;
1444 /* Unlink from popen_chain. */
1445 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1446 if ((*ptr)->fd == fd) {
1448 *ptr = (*ptr)->next;
1454 if (status < 0 || close(entry->fd) < 0)
1458 * As Samba is catching and eating child process
1459 * exits we don't really care about the child exit
1460 * code, a -1 with errno = ECHILD will do fine for us.
1464 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1465 } while (wait_pid == -1 && errno == EINTR);
1474 /**************************************************************************
1475 Wrappers for dlopen, dlsym, dlclose.
1476 ****************************************************************************/
1478 void *sys_dlopen(const char *name, int flags)
1480 #if defined(HAVE_DLOPEN)
1481 return dlopen(name, flags);
1487 void *sys_dlsym(void *handle, const char *symbol)
1489 #if defined(HAVE_DLSYM)
1490 return dlsym(handle, symbol);
1496 int sys_dlclose (void *handle)
1498 #if defined(HAVE_DLCLOSE)
1499 return dlclose(handle);
1505 const char *sys_dlerror(void)
1507 #if defined(HAVE_DLERROR)
1514 int sys_dup2(int oldfd, int newfd)
1516 #if defined(HAVE_DUP2)
1517 return dup2(oldfd, newfd);
1524 /**************************************************************************
1525 Wrapper for Admin Logs.
1526 ****************************************************************************/
1528 void sys_adminlog(int priority, const char *format_str, ...)
1532 char *msgbuf = NULL;
1534 va_start( ap, format_str );
1535 ret = vasprintf( &msgbuf, format_str, ap );
1541 #if defined(HAVE_SYSLOG)
1542 syslog( priority, "%s", msgbuf );
1544 DEBUG(0,("%s", msgbuf ));
1549 /**************************************************************************
1550 Wrappers for extented attribute calls. Based on the Linux package with
1551 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1552 ****************************************************************************/
1554 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
1556 #if defined(HAVE_GETXATTR)
1557 #ifndef XATTR_ADD_OPT
1558 return getxattr(path, name, value, size);
1561 return getxattr(path, name, value, size, 0, options);
1563 #elif defined(HAVE_GETEA)
1564 return getea(path, name, value, size);
1565 #elif defined(HAVE_EXTATTR_GET_FILE)
1568 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1569 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1570 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1572 * The BSD implementation has a nasty habit of silently truncating
1573 * the returned value to the size of the buffer, so we have to check
1574 * that the buffer is large enough to fit the returned value.
1576 if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1581 if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
1585 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno)));
1587 #elif defined(HAVE_ATTR_GET)
1588 int retval, flags = 0;
1589 int valuelength = (int)size;
1590 char *attrname = strchr(name,'.') + 1;
1592 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1594 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1596 return retval ? retval : valuelength;
1603 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1605 #if defined(HAVE_LGETXATTR)
1606 return lgetxattr(path, name, value, size);
1607 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
1608 int options = XATTR_NOFOLLOW;
1609 return getxattr(path, name, value, size, 0, options);
1610 #elif defined(HAVE_LGETEA)
1611 return lgetea(path, name, value, size);
1612 #elif defined(HAVE_EXTATTR_GET_LINK)
1615 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1616 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1617 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1619 if((retval=extattr_get_link(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1624 if((retval=extattr_get_link(path, attrnamespace, attrname, value, size)) >= 0)
1628 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno)));
1630 #elif defined(HAVE_ATTR_GET)
1631 int retval, flags = ATTR_DONTFOLLOW;
1632 int valuelength = (int)size;
1633 char *attrname = strchr(name,'.') + 1;
1635 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1637 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1639 return retval ? retval : valuelength;
1646 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1648 #if defined(HAVE_FGETXATTR)
1649 #ifndef XATTR_ADD_OPT
1650 return fgetxattr(filedes, name, value, size);
1653 return fgetxattr(filedes, name, value, size, 0, options);
1655 #elif defined(HAVE_FGETEA)
1656 return fgetea(filedes, name, value, size);
1657 #elif defined(HAVE_EXTATTR_GET_FD)
1660 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1661 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1662 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1664 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
1669 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0)
1673 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno)));
1675 #elif defined(HAVE_ATTR_GETF)
1676 int retval, flags = 0;
1677 int valuelength = (int)size;
1678 char *attrname = strchr(name,'.') + 1;
1680 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1682 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1684 return retval ? retval : valuelength;
1691 #if defined(HAVE_EXTATTR_LIST_FILE)
1693 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1701 { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
1702 { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
1710 static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
1712 ssize_t list_size, total_size = 0;
1715 /* Iterate through extattr(2) namespaces */
1716 for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
1718 #if defined(HAVE_EXTATTR_LIST_FILE)
1720 list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
1723 #if defined(HAVE_EXTATTR_LIST_LINK)
1725 list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
1728 #if defined(HAVE_EXTATTR_LIST_FD)
1730 list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
1737 /* Some error happend. Errno should be set by the previous call */
1743 /* XXX: Call with an empty buffer may be used to calculate
1744 necessary buffer size. Unfortunately, we can't say, how
1745 many attributes were returned, so here is the potential
1746 problem with the emulation.
1749 /* Take the worse case of one char attribute names -
1750 two bytes per name plus one more for sanity.
1752 total_size += list_size + (list_size/2 + 1)*extattr[t].len;
1755 /* Count necessary offset to fit namespace prefixes */
1757 for(i = 0; i < list_size; i += list[i] + 1)
1758 len += extattr[t].len;
1760 total_size += list_size + len;
1761 /* Buffer is too small to fit the results */
1762 if(total_size > size) {
1766 /* Shift results back, so we can prepend prefixes */
1767 buf = memmove(list + len, list, list_size);
1769 for(i = 0; i < list_size; i += len + 1) {
1771 strncpy(list, extattr[t].name, extattr[t].len + 1);
1772 list += extattr[t].len;
1773 strncpy(list, buf + i + 1, len);
1784 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1785 static char attr_buffer[ATTR_MAX_VALUELEN];
1787 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1789 int retval = 0, index;
1790 attrlist_cursor_t *cursor = 0;
1792 attrlist_t * al = (attrlist_t *)attr_buffer;
1794 size_t ent_size, left = size;
1799 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1801 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1803 for (index = 0; index < al->al_count; index++) {
1804 ae = ATTR_ENTRY(attr_buffer, index);
1805 ent_size = strlen(ae->a_name) + sizeof("user.");
1806 if (left >= ent_size) {
1807 strncpy(bp, "user.", sizeof("user."));
1808 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1816 total_size += ent_size;
1818 if (al->al_more == 0) break;
1825 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1827 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1829 for (index = 0; index < al->al_count; index++) {
1830 ae = ATTR_ENTRY(attr_buffer, index);
1831 ent_size = strlen(ae->a_name) + sizeof("system.");
1832 if (left >= ent_size) {
1833 strncpy(bp, "system.", sizeof("system."));
1834 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1842 total_size += ent_size;
1844 if (al->al_more == 0) break;
1847 return (ssize_t)(retval ? retval : total_size);
1852 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1854 #if defined(HAVE_LISTXATTR)
1855 #ifndef XATTR_ADD_OPT
1856 return listxattr(path, list, size);
1859 return listxattr(path, list, size, options);
1861 #elif defined(HAVE_LISTEA)
1862 return listea(path, list, size);
1863 #elif defined(HAVE_EXTATTR_LIST_FILE)
1866 return bsd_attr_list(0, arg, list, size);
1867 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1868 return irix_attr_list(path, 0, list, size, 0);
1875 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1877 #if defined(HAVE_LLISTXATTR)
1878 return llistxattr(path, list, size);
1879 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
1880 int options = XATTR_NOFOLLOW;
1881 return listxattr(path, list, size, options);
1882 #elif defined(HAVE_LLISTEA)
1883 return llistea(path, list, size);
1884 #elif defined(HAVE_EXTATTR_LIST_LINK)
1887 return bsd_attr_list(1, arg, list, size);
1888 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1889 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1896 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1898 #if defined(HAVE_FLISTXATTR)
1899 #ifndef XATTR_ADD_OPT
1900 return flistxattr(filedes, list, size);
1903 return flistxattr(filedes, list, size, options);
1905 #elif defined(HAVE_FLISTEA)
1906 return flistea(filedes, list, size);
1907 #elif defined(HAVE_EXTATTR_LIST_FD)
1909 arg.filedes = filedes;
1910 return bsd_attr_list(2, arg, list, size);
1911 #elif defined(HAVE_ATTR_LISTF)
1912 return irix_attr_list(NULL, filedes, list, size, 0);
1919 int sys_removexattr (const char *path, const char *name)
1921 #if defined(HAVE_REMOVEXATTR)
1922 #ifndef XATTR_ADD_OPT
1923 return removexattr(path, name);
1926 return removexattr(path, name, options);
1928 #elif defined(HAVE_REMOVEEA)
1929 return removeea(path, name);
1930 #elif defined(HAVE_EXTATTR_DELETE_FILE)
1932 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1933 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1934 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1936 return extattr_delete_file(path, attrnamespace, attrname);
1937 #elif defined(HAVE_ATTR_REMOVE)
1939 char *attrname = strchr(name,'.') + 1;
1941 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1943 return attr_remove(path, attrname, flags);
1950 int sys_lremovexattr (const char *path, const char *name)
1952 #if defined(HAVE_LREMOVEXATTR)
1953 return lremovexattr(path, name);
1954 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
1955 int options = XATTR_NOFOLLOW;
1956 return removexattr(path, name, options);
1957 #elif defined(HAVE_LREMOVEEA)
1958 return lremoveea(path, name);
1959 #elif defined(HAVE_EXTATTR_DELETE_LINK)
1961 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1962 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1963 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1965 return extattr_delete_link(path, attrnamespace, attrname);
1966 #elif defined(HAVE_ATTR_REMOVE)
1967 int flags = ATTR_DONTFOLLOW;
1968 char *attrname = strchr(name,'.') + 1;
1970 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1972 return attr_remove(path, attrname, flags);
1979 int sys_fremovexattr (int filedes, const char *name)
1981 #if defined(HAVE_FREMOVEXATTR)
1982 #ifndef XATTR_ADD_OPT
1983 return fremovexattr(filedes, name);
1986 return fremovexattr(filedes, name, options);
1988 #elif defined(HAVE_FREMOVEEA)
1989 return fremoveea(filedes, name);
1990 #elif defined(HAVE_EXTATTR_DELETE_FD)
1992 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1993 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1994 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1996 return extattr_delete_fd(filedes, attrnamespace, attrname);
1997 #elif defined(HAVE_ATTR_REMOVEF)
1999 char *attrname = strchr(name,'.') + 1;
2001 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
2003 return attr_removef(filedes, attrname, flags);
2010 #if !defined(HAVE_SETXATTR)
2011 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
2012 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
2015 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
2017 #if defined(HAVE_SETXATTR)
2018 #ifndef XATTR_ADD_OPT
2019 return setxattr(path, name, value, size, flags);
2022 return setxattr(path, name, value, size, 0, options);
2024 #elif defined(HAVE_SETEA)
2025 return setea(path, name, value, size, flags);
2026 #elif defined(HAVE_EXTATTR_SET_FILE)
2029 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2030 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2031 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2033 /* Check attribute existence */
2034 retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
2036 /* REPLACE attribute, that doesn't exist */
2037 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2041 /* Ignore other errors */
2044 /* CREATE attribute, that already exists */
2045 if (flags & XATTR_CREATE) {
2051 retval = extattr_set_file(path, attrnamespace, attrname, value, size);
2052 return (retval < 0) ? -1 : 0;
2053 #elif defined(HAVE_ATTR_SET)
2055 char *attrname = strchr(name,'.') + 1;
2057 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2058 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2059 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2061 return attr_set(path, attrname, (const char *)value, size, myflags);
2068 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
2070 #if defined(HAVE_LSETXATTR)
2071 return lsetxattr(path, name, value, size, flags);
2072 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
2073 int options = XATTR_NOFOLLOW;
2074 return setxattr(path, name, value, size, 0, options);
2075 #elif defined(LSETEA)
2076 return lsetea(path, name, value, size, flags);
2077 #elif defined(HAVE_EXTATTR_SET_LINK)
2080 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2081 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2082 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2084 /* Check attribute existence */
2085 retval = extattr_get_link(path, attrnamespace, attrname, NULL, 0);
2087 /* REPLACE attribute, that doesn't exist */
2088 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2092 /* Ignore other errors */
2095 /* CREATE attribute, that already exists */
2096 if (flags & XATTR_CREATE) {
2103 retval = extattr_set_link(path, attrnamespace, attrname, value, size);
2104 return (retval < 0) ? -1 : 0;
2105 #elif defined(HAVE_ATTR_SET)
2106 int myflags = ATTR_DONTFOLLOW;
2107 char *attrname = strchr(name,'.') + 1;
2109 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2110 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2111 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2113 return attr_set(path, attrname, (const char *)value, size, myflags);
2120 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
2122 #if defined(HAVE_FSETXATTR)
2123 #ifndef XATTR_ADD_OPT
2124 return fsetxattr(filedes, name, value, size, flags);
2127 return fsetxattr(filedes, name, value, size, 0, options);
2129 #elif defined(HAVE_FSETEA)
2130 return fsetea(filedes, name, value, size, flags);
2131 #elif defined(HAVE_EXTATTR_SET_FD)
2134 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2135 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2136 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2138 /* Check attribute existence */
2139 retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
2141 /* REPLACE attribute, that doesn't exist */
2142 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2146 /* Ignore other errors */
2149 /* CREATE attribute, that already exists */
2150 if (flags & XATTR_CREATE) {
2156 retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
2157 return (retval < 0) ? -1 : 0;
2158 #elif defined(HAVE_ATTR_SETF)
2160 char *attrname = strchr(name,'.') + 1;
2162 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2163 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2164 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2166 return attr_setf(filedes, attrname, (const char *)value, size, myflags);
2173 /****************************************************************************
2174 Return the major devicenumber for UNIX extensions.
2175 ****************************************************************************/
2177 uint32 unix_dev_major(SMB_DEV_T dev)
2179 #if defined(HAVE_DEVICE_MAJOR_FN)
2180 return (uint32)major(dev);
2182 return (uint32)(dev >> 8);
2186 /****************************************************************************
2187 Return the minor devicenumber for UNIX extensions.
2188 ****************************************************************************/
2190 uint32 unix_dev_minor(SMB_DEV_T dev)
2192 #if defined(HAVE_DEVICE_MINOR_FN)
2193 return (uint32)minor(dev);
2195 return (uint32)(dev & 0xff);
2199 #if defined(WITH_AIO)
2201 /*******************************************************************
2202 An aio_read wrapper that will deal with 64-bit sizes.
2203 ********************************************************************/
2205 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2207 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2208 return aio_read64(aiocb);
2209 #elif defined(HAVE_AIO_READ)
2210 return aio_read(aiocb);
2217 /*******************************************************************
2218 An aio_write wrapper that will deal with 64-bit sizes.
2219 ********************************************************************/
2221 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2223 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2224 return aio_write64(aiocb);
2225 #elif defined(HAVE_AIO_WRITE)
2226 return aio_write(aiocb);
2233 /*******************************************************************
2234 An aio_return wrapper that will deal with 64-bit sizes.
2235 ********************************************************************/
2237 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2239 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2240 return aio_return64(aiocb);
2241 #elif defined(HAVE_AIO_RETURN)
2242 return aio_return(aiocb);
2249 /*******************************************************************
2250 An aio_cancel wrapper that will deal with 64-bit sizes.
2251 ********************************************************************/
2253 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2255 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2256 return aio_cancel64(fd, aiocb);
2257 #elif defined(HAVE_AIO_CANCEL)
2258 return aio_cancel(fd, aiocb);
2265 /*******************************************************************
2266 An aio_error wrapper that will deal with 64-bit sizes.
2267 ********************************************************************/
2269 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2271 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2272 return aio_error64(aiocb);
2273 #elif defined(HAVE_AIO_ERROR)
2274 return aio_error(aiocb);
2281 /*******************************************************************
2282 An aio_fsync wrapper that will deal with 64-bit sizes.
2283 ********************************************************************/
2285 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2287 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2288 return aio_fsync64(op, aiocb);
2289 #elif defined(HAVE_AIO_FSYNC)
2290 return aio_fsync(op, aiocb);
2297 /*******************************************************************
2298 An aio_fsync wrapper that will deal with 64-bit sizes.
2299 ********************************************************************/
2301 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2303 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2304 return aio_suspend64(cblist, n, timeout);
2305 #elif defined(HAVE_AIO_FSYNC)
2306 return aio_suspend(cblist, n, timeout);
2312 #else /* !WITH_AIO */
2314 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2320 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2326 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2332 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2338 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2344 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2350 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2355 #endif /* WITH_AIO */
2357 int sys_getpeereid( int s, uid_t *uid)
2359 #if defined(HAVE_PEERCRED)
2361 socklen_t cred_len = sizeof(struct ucred);
2364 ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
2369 if (cred_len != sizeof(struct ucred)) {