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 usleep in case we don't have one.
48 ********************************************************************/
50 int sys_usleep(long usecs)
57 * We need this braindamage as the glibc usleep
58 * is not SPEC1170 complient... grumble... JRA.
61 if(usecs < 0 || usecs > 1000000) {
69 #else /* HAVE_USLEEP */
71 * Fake it with select...
74 tval.tv_usec = usecs/1000;
75 select(0,NULL,NULL,NULL,&tval);
77 #endif /* HAVE_USLEEP */
80 /*******************************************************************
81 A read wrapper that will deal with EINTR.
82 ********************************************************************/
84 ssize_t sys_read(int fd, void *buf, size_t count)
89 ret = read(fd, buf, count);
90 } while (ret == -1 && errno == EINTR);
94 /*******************************************************************
95 A write wrapper that will deal with EINTR.
96 ********************************************************************/
98 ssize_t sys_write(int fd, const void *buf, size_t count)
103 ret = write(fd, buf, count);
104 } while (ret == -1 && errno == EINTR);
108 /*******************************************************************
109 A pread wrapper that will deal with EINTR and 64-bit file offsets.
110 ********************************************************************/
112 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
113 ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
118 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
119 ret = pread64(fd, buf, count, off);
121 ret = pread(fd, buf, count, off);
123 } while (ret == -1 && errno == EINTR);
128 /*******************************************************************
129 A write wrapper that will deal with EINTR and 64-bit file offsets.
130 ********************************************************************/
132 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
133 ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
138 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
139 ret = pwrite64(fd, buf, count, off);
141 ret = pwrite(fd, buf, count, off);
143 } while (ret == -1 && errno == EINTR);
148 /*******************************************************************
149 A send wrapper that will deal with EINTR.
150 ********************************************************************/
152 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
157 ret = send(s, msg, len, flags);
158 } while (ret == -1 && errno == EINTR);
162 /*******************************************************************
163 A sendto wrapper that will deal with EINTR.
164 ********************************************************************/
166 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
171 ret = sendto(s, msg, len, flags, to, tolen);
172 } while (ret == -1 && errno == EINTR);
176 /*******************************************************************
177 A recv wrapper that will deal with EINTR.
178 ********************************************************************/
180 ssize_t sys_recv(int fd, void *buf, size_t count, int flags)
185 ret = recv(fd, buf, count, flags);
186 } while (ret == -1 && errno == EINTR);
190 /*******************************************************************
191 A recvfrom wrapper that will deal with EINTR.
192 ********************************************************************/
194 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
199 ret = recvfrom(s, buf, len, flags, from, fromlen);
200 } while (ret == -1 && errno == EINTR);
204 /*******************************************************************
205 A fcntl wrapper that will deal with EINTR.
206 ********************************************************************/
208 int sys_fcntl_ptr(int fd, int cmd, void *arg)
213 ret = fcntl(fd, cmd, arg);
214 } while (ret == -1 && errno == EINTR);
218 /*******************************************************************
219 A fcntl wrapper that will deal with EINTR.
220 ********************************************************************/
222 int sys_fcntl_long(int fd, int cmd, long arg)
227 ret = fcntl(fd, cmd, arg);
228 } while (ret == -1 && errno == EINTR);
232 /*******************************************************************
233 A stat() wrapper that will deal with 64 bit filesizes.
234 ********************************************************************/
236 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
239 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
240 ret = stat64(fname, sbuf);
242 ret = stat(fname, sbuf);
244 /* we always want directories to appear zero size */
245 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
249 /*******************************************************************
250 An fstat() wrapper that will deal with 64 bit filesizes.
251 ********************************************************************/
253 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
256 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
257 ret = fstat64(fd, sbuf);
259 ret = fstat(fd, sbuf);
261 /* we always want directories to appear zero size */
262 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
266 /*******************************************************************
267 An lstat() wrapper that will deal with 64 bit filesizes.
268 ********************************************************************/
270 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
273 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
274 ret = lstat64(fname, sbuf);
276 ret = lstat(fname, sbuf);
278 /* we always want directories to appear zero size */
279 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
283 /*******************************************************************
284 An ftruncate() wrapper that will deal with 64 bit filesizes.
285 ********************************************************************/
287 int sys_ftruncate(int fd, SMB_OFF_T offset)
289 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
290 return ftruncate64(fd, offset);
292 return ftruncate(fd, offset);
296 /*******************************************************************
297 An lseek() wrapper that will deal with 64 bit filesizes.
298 ********************************************************************/
300 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
302 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
303 return lseek64(fd, offset, whence);
305 return lseek(fd, offset, whence);
309 /*******************************************************************
310 An fseek() wrapper that will deal with 64 bit filesizes.
311 ********************************************************************/
313 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
315 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
316 return fseek64(fp, offset, whence);
317 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
318 return fseeko64(fp, offset, whence);
320 return fseek(fp, offset, whence);
324 /*******************************************************************
325 An ftell() wrapper that will deal with 64 bit filesizes.
326 ********************************************************************/
328 SMB_OFF_T sys_ftell(FILE *fp)
330 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
331 return (SMB_OFF_T)ftell64(fp);
332 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
333 return (SMB_OFF_T)ftello64(fp);
335 return (SMB_OFF_T)ftell(fp);
339 /*******************************************************************
340 A creat() wrapper that will deal with 64 bit filesizes.
341 ********************************************************************/
343 int sys_creat(const char *path, mode_t mode)
345 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
346 return creat64(path, mode);
349 * If creat64 isn't defined then ensure we call a potential open64.
352 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
356 /*******************************************************************
357 An open() wrapper that will deal with 64 bit filesizes.
358 ********************************************************************/
360 int sys_open(const char *path, int oflag, mode_t mode)
362 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
363 return open64(path, oflag, mode);
365 return open(path, oflag, mode);
369 /*******************************************************************
370 An fopen() wrapper that will deal with 64 bit filesizes.
371 ********************************************************************/
373 FILE *sys_fopen(const char *path, const char *type)
375 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
376 return fopen64(path, type);
378 return fopen(path, type);
382 /*******************************************************************
383 An opendir wrapper that will deal with 64 bit filesizes.
384 ********************************************************************/
386 SMB_STRUCT_DIR *sys_opendir(const char *name)
388 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
389 return opendir64(name);
391 return opendir(name);
395 /*******************************************************************
396 A readdir wrapper that will deal with 64 bit filesizes.
397 ********************************************************************/
399 SMB_STRUCT_DIRENT *sys_readdir(SMB_STRUCT_DIR *dirp)
401 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
402 return readdir64(dirp);
404 return readdir(dirp);
408 /*******************************************************************
409 A seekdir wrapper that will deal with 64 bit filesizes.
410 ********************************************************************/
412 void sys_seekdir(SMB_STRUCT_DIR *dirp, long offset)
414 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
415 seekdir64(dirp, offset);
417 seekdir(dirp, offset);
421 /*******************************************************************
422 A telldir wrapper that will deal with 64 bit filesizes.
423 ********************************************************************/
425 long sys_telldir(SMB_STRUCT_DIR *dirp)
427 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
428 return (long)telldir64(dirp);
430 return (long)telldir(dirp);
434 /*******************************************************************
435 A rewinddir wrapper that will deal with 64 bit filesizes.
436 ********************************************************************/
438 void sys_rewinddir(SMB_STRUCT_DIR *dirp)
440 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
447 /*******************************************************************
448 A close wrapper that will deal with 64 bit filesizes.
449 ********************************************************************/
451 int sys_closedir(SMB_STRUCT_DIR *dirp)
453 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
454 return closedir64(dirp);
456 return closedir(dirp);
460 /*******************************************************************
461 An mknod() wrapper that will deal with 64 bit filesizes.
462 ********************************************************************/
464 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
466 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
467 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
468 return mknod64(path, mode, dev);
470 return mknod(path, mode, dev);
473 /* No mknod system call. */
479 /*******************************************************************
480 Wrapper for realpath.
481 ********************************************************************/
483 char *sys_realpath(const char *path, char *resolved_path)
485 #if defined(HAVE_REALPATH)
486 return realpath(path, resolved_path);
488 /* As realpath is not a system call we can't return ENOSYS. */
494 /*******************************************************************
495 The wait() calls vary between systems
496 ********************************************************************/
498 int sys_waitpid(pid_t pid,int *status,int options)
501 return waitpid(pid,status,options);
502 #else /* HAVE_WAITPID */
503 return wait4(pid, status, options, NULL);
504 #endif /* HAVE_WAITPID */
507 /*******************************************************************
508 System wrapper for getwd
509 ********************************************************************/
511 char *sys_getwd(char *s)
515 wd = (char *)getcwd(s, sizeof (pstring));
517 wd = (char *)getwd(s);
522 /*******************************************************************
523 system wrapper for symlink
524 ********************************************************************/
526 int sys_symlink(const char *oldpath, const char *newpath)
532 return symlink(oldpath, newpath);
536 /*******************************************************************
537 system wrapper for readlink
538 ********************************************************************/
540 int sys_readlink(const char *path, char *buf, size_t bufsiz)
542 #ifndef HAVE_READLINK
546 return readlink(path, buf, bufsiz);
550 /*******************************************************************
551 system wrapper for link
552 ********************************************************************/
554 int sys_link(const char *oldpath, const char *newpath)
560 return link(oldpath, newpath);
564 /*******************************************************************
565 chown isn't used much but OS/2 doesn't have it
566 ********************************************************************/
568 int sys_chown(const char *fname,uid_t uid,gid_t gid)
573 DEBUG(1,("WARNING: no chown!\n"));
579 return(chown(fname,uid,gid));
583 /*******************************************************************
584 os/2 also doesn't have chroot
585 ********************************************************************/
586 int sys_chroot(const char *dname)
591 DEBUG(1,("WARNING: no chroot!\n"));
597 return(chroot(dname));
601 /**************************************************************************
602 A wrapper for gethostbyname() that tries avoids looking up hostnames
603 in the root domain, which can cause dial-on-demand links to come up for no
605 ****************************************************************************/
607 struct hostent *sys_gethostbyname(const char *name)
609 #ifdef REDUCE_ROOT_DNS_LOOKUPS
610 char query[256], hostname[256];
613 /* Does this name have any dots in it? If so, make no change */
615 if (strchr_m(name, '.'))
616 return(gethostbyname(name));
618 /* Get my hostname, which should have domain name
619 attached. If not, just do the gethostname on the
623 gethostname(hostname, sizeof(hostname) - 1);
624 hostname[sizeof(hostname) - 1] = 0;
625 if ((domain = strchr_m(hostname, '.')) == NULL)
626 return(gethostbyname(name));
628 /* Attach domain name to query and do modified query.
629 If names too large, just do gethostname on the
633 if((strlen(name) + strlen(domain)) >= sizeof(query))
634 return(gethostbyname(name));
636 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
637 return(gethostbyname(query));
638 #else /* REDUCE_ROOT_DNS_LOOKUPS */
639 return(gethostbyname(name));
640 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
644 #if defined(HAVE_POSIX_CAPABILITIES)
646 #ifdef HAVE_SYS_CAPABILITY_H
648 #if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H)
649 #define _I386_STATFS_H
650 #define _PPC_STATFS_H
651 #define BROKEN_REDHAT_7_STATFS_WORKAROUND
654 #include <sys/capability.h>
656 #ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND
657 #undef _I386_STATFS_H
659 #undef BROKEN_REDHAT_7_STATFS_WORKAROUND
662 #endif /* HAVE_SYS_CAPABILITY_H */
664 /**************************************************************************
665 Try and abstract process capabilities (for systems that have them).
666 ****************************************************************************/
668 /* Set the POSIX capabilities needed for the given purpose into the effective
669 * capability set of the current process. Make sure they are always removed
670 * from the inheritable set, because there is no circumstance in which our
671 * children should inherit our elevated privileges.
673 static BOOL set_process_capability(enum smbd_capability capability,
676 cap_value_t cap_vals[2] = {0};
677 int num_cap_vals = 0;
681 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
682 /* On Linux, make sure that any capabilities we grab are sticky
683 * across UID changes. We expect that this would allow us to keep both
684 * the effective and permitted capability sets, but as of circa 2.6.16,
685 * only the permitted set is kept. It is a bug (which we work around)
686 * that the effective set is lost, but we still require the effective
689 if (!prctl(PR_GET_KEEPCAPS)) {
690 prctl(PR_SET_KEEPCAPS, 1);
694 cap = cap_get_proc();
696 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
701 switch (capability) {
702 case KERNEL_OPLOCK_CAPABILITY:
703 #ifdef CAP_NETWORK_MGT
704 /* IRIX has CAP_NETWORK_MGT for oplocks. */
705 cap_vals[num_cap_vals++] = CAP_NETWORK_MGT;
708 case DMAPI_ACCESS_CAPABILITY:
709 #ifdef CAP_DEVICE_MGT
710 /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
711 cap_vals[num_cap_vals++] = CAP_DEVICE_MGT;
713 /* Linux has CAP_MKNOD for DMAPI access. */
714 cap_vals[num_cap_vals++] = CAP_MKNOD;
719 SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals));
721 if (num_cap_vals == 0) {
726 cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
727 enable ? CAP_SET : CAP_CLEAR);
729 /* We never want to pass capabilities down to our children, so make
730 * sure they are not inherited.
732 cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
734 if (cap_set_proc(cap) == -1) {
735 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
745 #endif /* HAVE_POSIX_CAPABILITIES */
747 /****************************************************************************
748 Gain the oplock capability from the kernel if possible.
749 ****************************************************************************/
751 void set_effective_capability(enum smbd_capability capability)
753 #if defined(HAVE_POSIX_CAPABILITIES)
754 set_process_capability(capability, True);
755 #endif /* HAVE_POSIX_CAPABILITIES */
758 void drop_effective_capability(enum smbd_capability capability)
760 #if defined(HAVE_POSIX_CAPABILITIES)
761 set_process_capability(capability, False);
762 #endif /* HAVE_POSIX_CAPABILITIES */
765 /**************************************************************************
766 Wrapper for random().
767 ****************************************************************************/
769 long sys_random(void)
771 #if defined(HAVE_RANDOM)
772 return (long)random();
773 #elif defined(HAVE_RAND)
776 DEBUG(0,("Error - no random function available !\n"));
781 /**************************************************************************
782 Wrapper for srandom().
783 ****************************************************************************/
785 void sys_srandom(unsigned int seed)
787 #if defined(HAVE_SRANDOM)
789 #elif defined(HAVE_SRAND)
792 DEBUG(0,("Error - no srandom function available !\n"));
797 /**************************************************************************
798 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
799 ****************************************************************************/
803 #if defined(SYSCONF_SC_NGROUPS_MAX)
804 int ret = sysconf(_SC_NGROUPS_MAX);
805 return (ret == -1) ? NGROUPS_MAX : ret;
811 /**************************************************************************
812 Wrapper for getgroups. Deals with broken (int) case.
813 ****************************************************************************/
815 int sys_getgroups(int setlen, gid_t *gidset)
817 #if !defined(HAVE_BROKEN_GETGROUPS)
818 return getgroups(setlen, gidset);
826 return getgroups(setlen, &gid);
830 * Broken case. We need to allocate a
831 * GID_T array of size setlen.
840 setlen = groups_max();
842 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
843 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
847 if((ngroups = getgroups(setlen, group_list)) < 0) {
848 int saved_errno = errno;
849 SAFE_FREE(group_list);
854 for(i = 0; i < ngroups; i++)
855 gidset[i] = (gid_t)group_list[i];
857 SAFE_FREE(group_list);
859 #endif /* HAVE_BROKEN_GETGROUPS */
863 /**************************************************************************
864 Wrapper for setgroups. Deals with broken (int) case. Automatically used
865 if we have broken getgroups.
866 ****************************************************************************/
868 int sys_setgroups(int setlen, gid_t *gidset)
870 #if !defined(HAVE_SETGROUPS)
873 #endif /* HAVE_SETGROUPS */
875 #if !defined(HAVE_BROKEN_GETGROUPS)
876 return setgroups(setlen, gidset);
885 if (setlen < 0 || setlen > groups_max()) {
891 * Broken case. We need to allocate a
892 * GID_T array of size setlen.
895 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
896 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
900 for(i = 0; i < setlen; i++)
901 group_list[i] = (GID_T) gidset[i];
903 if(setgroups(setlen, group_list) != 0) {
904 int saved_errno = errno;
905 SAFE_FREE(group_list);
910 SAFE_FREE(group_list);
912 #endif /* HAVE_BROKEN_GETGROUPS */
915 /**************************************************************************
916 Wrappers for setpwent(), getpwent() and endpwent()
917 ****************************************************************************/
919 void sys_setpwent(void)
924 struct passwd *sys_getpwent(void)
929 void sys_endpwent(void)
934 /**************************************************************************
935 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
936 ****************************************************************************/
938 #ifdef ENABLE_BUILD_FARM_HACKS
941 * In the build farm we want to be able to join machines to the domain. As we
942 * don't have root access, we need to bypass direct access to /etc/passwd
943 * after a user has been created via samr. Fake those users.
946 static struct passwd *fake_pwd;
947 static int num_fake_pwd;
949 struct passwd *sys_getpwnam(const char *name)
953 for (i=0; i<num_fake_pwd; i++) {
954 if (strcmp(fake_pwd[i].pw_name, name) == 0) {
955 DEBUG(10, ("Returning fake user %s\n", name));
960 return getpwnam(name);
963 struct passwd *sys_getpwuid(uid_t uid)
967 for (i=0; i<num_fake_pwd; i++) {
968 if (fake_pwd[i].pw_uid == uid) {
969 DEBUG(10, ("Returning fake user %s\n",
970 fake_pwd[i].pw_name));
975 return getpwuid(uid);
978 void faked_create_user(const char *name)
982 struct passwd new_pwd;
984 for (i=0; i<10; i++) {
985 generate_random_buffer((unsigned char *)&uid,
987 if (getpwuid(uid) == NULL) {
993 /* Weird. No free uid found... */
997 new_pwd.pw_name = SMB_STRDUP(name);
998 new_pwd.pw_passwd = SMB_STRDUP("x");
999 new_pwd.pw_uid = uid;
1000 new_pwd.pw_gid = 100;
1001 new_pwd.pw_gecos = SMB_STRDUP("faked user");
1002 new_pwd.pw_dir = SMB_STRDUP("/nodir");
1003 new_pwd.pw_shell = SMB_STRDUP("/bin/false");
1005 ADD_TO_ARRAY(NULL, struct passwd, new_pwd, &fake_pwd,
1008 DEBUG(10, ("Added fake user %s, have %d fake users\n",
1009 name, num_fake_pwd));
1014 struct passwd *sys_getpwnam(const char *name)
1016 return getpwnam(name);
1019 struct passwd *sys_getpwuid(uid_t uid)
1021 return getpwuid(uid);
1026 struct group *sys_getgrnam(const char *name)
1028 return getgrnam(name);
1031 struct group *sys_getgrgid(gid_t gid)
1033 return getgrgid(gid);
1036 #if 0 /* NOT CURRENTLY USED - JRA */
1037 /**************************************************************************
1038 The following are the UNICODE versions of *all* system interface functions
1039 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
1040 which currently are left as ascii as they are not used other than in name
1042 ****************************************************************************/
1044 /**************************************************************************
1045 Wide stat. Just narrow and call sys_xxx.
1046 ****************************************************************************/
1048 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
1051 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
1054 /**************************************************************************
1055 Wide lstat. Just narrow and call sys_xxx.
1056 ****************************************************************************/
1058 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
1061 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
1064 /**************************************************************************
1065 Wide creat. Just narrow and call sys_xxx.
1066 ****************************************************************************/
1068 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
1071 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
1074 /**************************************************************************
1075 Wide open. Just narrow and call sys_xxx.
1076 ****************************************************************************/
1078 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
1081 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
1084 /**************************************************************************
1085 Wide fopen. Just narrow and call sys_xxx.
1086 ****************************************************************************/
1088 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
1091 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
1094 /**************************************************************************
1095 Wide opendir. Just narrow and call sys_xxx.
1096 ****************************************************************************/
1098 SMB_STRUCT_DIR *wsys_opendir(const smb_ucs2_t *wfname)
1101 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
1104 /**************************************************************************
1105 Wide readdir. Return a structure pointer containing a wide filename.
1106 ****************************************************************************/
1108 SMB_STRUCT_WDIRENT *wsys_readdir(SMB_STRUCT_DIR *dirp)
1110 static SMB_STRUCT_WDIRENT retval;
1111 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
1117 * The only POSIX defined member of this struct is d_name.
1120 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
1125 /**************************************************************************
1126 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
1127 ****************************************************************************/
1129 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
1132 char *p = sys_getwd(fname);
1137 return unix_to_unicode(s, p, sizeof(wpstring));
1140 /**************************************************************************
1141 Wide chown. Just narrow and call sys_xxx.
1142 ****************************************************************************/
1144 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
1147 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
1150 /**************************************************************************
1151 Wide chroot. Just narrow and call sys_xxx.
1152 ****************************************************************************/
1154 int wsys_chroot(const smb_ucs2_t *wfname)
1157 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
1160 /**************************************************************************
1161 Wide getpwnam. Return a structure pointer containing wide names.
1162 ****************************************************************************/
1164 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
1166 static SMB_STRUCT_WPASSWD retval;
1168 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
1173 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1174 retval.pw_passwd = pwret->pw_passwd;
1175 retval.pw_uid = pwret->pw_uid;
1176 retval.pw_gid = pwret->pw_gid;
1177 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1178 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1179 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1184 /**************************************************************************
1185 Wide getpwuid. Return a structure pointer containing wide names.
1186 ****************************************************************************/
1188 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
1190 static SMB_STRUCT_WPASSWD retval;
1191 struct passwd *pwret = sys_getpwuid(uid);
1196 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1197 retval.pw_passwd = pwret->pw_passwd;
1198 retval.pw_uid = pwret->pw_uid;
1199 retval.pw_gid = pwret->pw_gid;
1200 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1201 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1202 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1206 #endif /* NOT CURRENTLY USED - JRA */
1208 /**************************************************************************
1209 Extract a command into an arg list. Uses a static pstring for storage.
1210 Caller frees returned arg list (which contains pointers into the static pstring).
1211 ****************************************************************************/
1213 static char **extract_args(const char *command)
1215 static pstring trunc_cmd;
1221 pstrcpy(trunc_cmd, command);
1223 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1232 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1235 if((argl = (char **)SMB_MALLOC((argcl + 1) * sizeof(char *))) == NULL)
1239 * Now do the extraction.
1242 pstrcpy(trunc_cmd, command);
1244 ptr = strtok(trunc_cmd, " \t");
1248 while((ptr = strtok(NULL, " \t")) != NULL)
1255 /**************************************************************************
1256 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1257 a sys_getpid() that only does a system call *once*.
1258 ****************************************************************************/
1260 static pid_t mypid = (pid_t)-1;
1262 pid_t sys_fork(void)
1264 pid_t forkret = fork();
1266 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1272 /**************************************************************************
1273 Wrapper for getpid. Ensures we only do a system call *once*.
1274 ****************************************************************************/
1276 pid_t sys_getpid(void)
1278 if (mypid == (pid_t)-1)
1284 /**************************************************************************
1285 Wrapper for popen. Safer as it doesn't search a path.
1286 Modified from the glibc sources.
1287 modified by tridge to return a file descriptor. We must kick our FILE* habit
1288 ****************************************************************************/
1290 typedef struct _popen_list
1294 struct _popen_list *next;
1297 static popen_list *popen_chain;
1299 int sys_popen(const char *command)
1301 int parent_end, child_end;
1303 popen_list *entry = NULL;
1306 if (pipe(pipe_fds) < 0)
1309 parent_end = pipe_fds[0];
1310 child_end = pipe_fds[1];
1317 if((entry = SMB_MALLOC_P(popen_list)) == NULL)
1320 ZERO_STRUCTP(entry);
1323 * Extract the command and args into a NULL terminated array.
1326 if(!(argl = extract_args(command)))
1329 entry->child_pid = sys_fork();
1331 if (entry->child_pid == -1) {
1335 if (entry->child_pid == 0) {
1341 int child_std_end = STDOUT_FILENO;
1345 if (child_end != child_std_end) {
1346 dup2 (child_end, child_std_end);
1351 * POSIX.2: "popen() shall ensure that any streams from previous
1352 * popen() calls that remain open in the parent process are closed
1353 * in the new child process."
1356 for (p = popen_chain; p; p = p->next)
1359 execv(argl[0], argl);
1370 /* Link into popen_chain. */
1371 entry->next = popen_chain;
1372 popen_chain = entry;
1373 entry->fd = parent_end;
1386 /**************************************************************************
1387 Wrapper for pclose. Modified from the glibc sources.
1388 ****************************************************************************/
1390 int sys_pclose(int fd)
1393 popen_list **ptr = &popen_chain;
1394 popen_list *entry = NULL;
1398 /* Unlink from popen_chain. */
1399 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1400 if ((*ptr)->fd == fd) {
1402 *ptr = (*ptr)->next;
1408 if (status < 0 || close(entry->fd) < 0)
1412 * As Samba is catching and eating child process
1413 * exits we don't really care about the child exit
1414 * code, a -1 with errno = ECHILD will do fine for us.
1418 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1419 } while (wait_pid == -1 && errno == EINTR);
1428 /**************************************************************************
1429 Wrappers for dlopen, dlsym, dlclose.
1430 ****************************************************************************/
1432 void *sys_dlopen(const char *name, int flags)
1434 #if defined(HAVE_DLOPEN)
1435 return dlopen(name, flags);
1441 void *sys_dlsym(void *handle, const char *symbol)
1443 #if defined(HAVE_DLSYM)
1444 return dlsym(handle, symbol);
1450 int sys_dlclose (void *handle)
1452 #if defined(HAVE_DLCLOSE)
1453 return dlclose(handle);
1459 const char *sys_dlerror(void)
1461 #if defined(HAVE_DLERROR)
1468 int sys_dup2(int oldfd, int newfd)
1470 #if defined(HAVE_DUP2)
1471 return dup2(oldfd, newfd);
1478 /**************************************************************************
1479 Wrapper for Admin Logs.
1480 ****************************************************************************/
1482 void sys_adminlog(int priority, const char *format_str, ...)
1486 char *msgbuf = NULL;
1488 va_start( ap, format_str );
1489 ret = vasprintf( &msgbuf, format_str, ap );
1495 #if defined(HAVE_SYSLOG)
1496 syslog( priority, "%s", msgbuf );
1498 DEBUG(0,("%s", msgbuf ));
1503 /**************************************************************************
1504 Wrappers for extented attribute calls. Based on the Linux package with
1505 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1506 ****************************************************************************/
1508 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
1510 #if defined(HAVE_GETXATTR)
1511 #ifndef XATTR_ADD_OPT
1512 return getxattr(path, name, value, size);
1515 return getxattr(path, name, value, size, 0, options);
1517 #elif defined(HAVE_GETEA)
1518 return getea(path, name, value, size);
1519 #elif defined(HAVE_EXTATTR_GET_FILE)
1522 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1523 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1524 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1526 * The BSD implementation has a nasty habit of silently truncating
1527 * the returned value to the size of the buffer, so we have to check
1528 * that the buffer is large enough to fit the returned value.
1530 if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1535 if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
1539 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno)));
1541 #elif defined(HAVE_ATTR_GET)
1542 int retval, flags = 0;
1543 int valuelength = (int)size;
1544 char *attrname = strchr(name,'.') + 1;
1546 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1548 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1550 return retval ? retval : valuelength;
1557 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1559 #if defined(HAVE_LGETXATTR)
1560 return lgetxattr(path, name, value, size);
1561 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
1562 int options = XATTR_NOFOLLOW;
1563 return getxattr(path, name, value, size, 0, options);
1564 #elif defined(HAVE_LGETEA)
1565 return lgetea(path, name, value, size);
1566 #elif defined(HAVE_EXTATTR_GET_LINK)
1569 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1570 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1571 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1573 if((retval=extattr_get_link(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1578 if((retval=extattr_get_link(path, attrnamespace, attrname, value, size)) >= 0)
1582 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno)));
1584 #elif defined(HAVE_ATTR_GET)
1585 int retval, flags = ATTR_DONTFOLLOW;
1586 int valuelength = (int)size;
1587 char *attrname = strchr(name,'.') + 1;
1589 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1591 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1593 return retval ? retval : valuelength;
1600 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1602 #if defined(HAVE_FGETXATTR)
1603 #ifndef XATTR_ADD_OPT
1604 return fgetxattr(filedes, name, value, size);
1607 return fgetxattr(filedes, name, value, size, 0, options);
1609 #elif defined(HAVE_FGETEA)
1610 return fgetea(filedes, name, value, size);
1611 #elif defined(HAVE_EXTATTR_GET_FD)
1614 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1615 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1616 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1618 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
1623 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0)
1627 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno)));
1629 #elif defined(HAVE_ATTR_GETF)
1630 int retval, flags = 0;
1631 int valuelength = (int)size;
1632 char *attrname = strchr(name,'.') + 1;
1634 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1636 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1638 return retval ? retval : valuelength;
1645 #if defined(HAVE_EXTATTR_LIST_FILE)
1647 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1655 { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
1656 { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
1664 static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
1666 ssize_t list_size, total_size = 0;
1669 /* Iterate through extattr(2) namespaces */
1670 for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
1672 #if defined(HAVE_EXTATTR_LIST_FILE)
1674 list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
1677 #if defined(HAVE_EXTATTR_LIST_LINK)
1679 list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
1682 #if defined(HAVE_EXTATTR_LIST_FD)
1684 list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
1691 /* Some error happend. Errno should be set by the previous call */
1697 /* XXX: Call with an empty buffer may be used to calculate
1698 necessary buffer size. Unfortunately, we can't say, how
1699 many attributes were returned, so here is the potential
1700 problem with the emulation.
1703 /* Take the worse case of one char attribute names -
1704 two bytes per name plus one more for sanity.
1706 total_size += list_size + (list_size/2 + 1)*extattr[t].len;
1709 /* Count necessary offset to fit namespace prefixes */
1711 for(i = 0; i < list_size; i += list[i] + 1)
1712 len += extattr[t].len;
1714 total_size += list_size + len;
1715 /* Buffer is too small to fit the results */
1716 if(total_size > size) {
1720 /* Shift results back, so we can prepend prefixes */
1721 buf = memmove(list + len, list, list_size);
1723 for(i = 0; i < list_size; i += len + 1) {
1725 strncpy(list, extattr[t].name, extattr[t].len + 1);
1726 list += extattr[t].len;
1727 strncpy(list, buf + i + 1, len);
1738 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1739 static char attr_buffer[ATTR_MAX_VALUELEN];
1741 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1743 int retval = 0, index;
1744 attrlist_cursor_t *cursor = 0;
1746 attrlist_t * al = (attrlist_t *)attr_buffer;
1748 size_t ent_size, left = size;
1753 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1755 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1757 for (index = 0; index < al->al_count; index++) {
1758 ae = ATTR_ENTRY(attr_buffer, index);
1759 ent_size = strlen(ae->a_name) + sizeof("user.");
1760 if (left >= ent_size) {
1761 strncpy(bp, "user.", sizeof("user."));
1762 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1770 total_size += ent_size;
1772 if (al->al_more == 0) break;
1779 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1781 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1783 for (index = 0; index < al->al_count; index++) {
1784 ae = ATTR_ENTRY(attr_buffer, index);
1785 ent_size = strlen(ae->a_name) + sizeof("system.");
1786 if (left >= ent_size) {
1787 strncpy(bp, "system.", sizeof("system."));
1788 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1796 total_size += ent_size;
1798 if (al->al_more == 0) break;
1801 return (ssize_t)(retval ? retval : total_size);
1806 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1808 #if defined(HAVE_LISTXATTR)
1809 #ifndef XATTR_ADD_OPT
1810 return listxattr(path, list, size);
1813 return listxattr(path, list, size, options);
1815 #elif defined(HAVE_LISTEA)
1816 return listea(path, list, size);
1817 #elif defined(HAVE_EXTATTR_LIST_FILE)
1820 return bsd_attr_list(0, arg, list, size);
1821 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1822 return irix_attr_list(path, 0, list, size, 0);
1829 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1831 #if defined(HAVE_LLISTXATTR)
1832 return llistxattr(path, list, size);
1833 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
1834 int options = XATTR_NOFOLLOW;
1835 return listxattr(path, list, size, options);
1836 #elif defined(HAVE_LLISTEA)
1837 return llistea(path, list, size);
1838 #elif defined(HAVE_EXTATTR_LIST_LINK)
1841 return bsd_attr_list(1, arg, list, size);
1842 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1843 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1850 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1852 #if defined(HAVE_FLISTXATTR)
1853 #ifndef XATTR_ADD_OPT
1854 return flistxattr(filedes, list, size);
1857 return flistxattr(filedes, list, size, options);
1859 #elif defined(HAVE_FLISTEA)
1860 return flistea(filedes, list, size);
1861 #elif defined(HAVE_EXTATTR_LIST_FD)
1863 arg.filedes = filedes;
1864 return bsd_attr_list(2, arg, list, size);
1865 #elif defined(HAVE_ATTR_LISTF)
1866 return irix_attr_list(NULL, filedes, list, size, 0);
1873 int sys_removexattr (const char *path, const char *name)
1875 #if defined(HAVE_REMOVEXATTR)
1876 #ifndef XATTR_ADD_OPT
1877 return removexattr(path, name);
1880 return removexattr(path, name, options);
1882 #elif defined(HAVE_REMOVEEA)
1883 return removeea(path, name);
1884 #elif defined(HAVE_EXTATTR_DELETE_FILE)
1886 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1887 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1888 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1890 return extattr_delete_file(path, attrnamespace, attrname);
1891 #elif defined(HAVE_ATTR_REMOVE)
1893 char *attrname = strchr(name,'.') + 1;
1895 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1897 return attr_remove(path, attrname, flags);
1904 int sys_lremovexattr (const char *path, const char *name)
1906 #if defined(HAVE_LREMOVEXATTR)
1907 return lremovexattr(path, name);
1908 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
1909 int options = XATTR_NOFOLLOW;
1910 return removexattr(path, name, options);
1911 #elif defined(HAVE_LREMOVEEA)
1912 return lremoveea(path, name);
1913 #elif defined(HAVE_EXTATTR_DELETE_LINK)
1915 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1916 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1917 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1919 return extattr_delete_link(path, attrnamespace, attrname);
1920 #elif defined(HAVE_ATTR_REMOVE)
1921 int flags = ATTR_DONTFOLLOW;
1922 char *attrname = strchr(name,'.') + 1;
1924 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1926 return attr_remove(path, attrname, flags);
1933 int sys_fremovexattr (int filedes, const char *name)
1935 #if defined(HAVE_FREMOVEXATTR)
1936 #ifndef XATTR_ADD_OPT
1937 return fremovexattr(filedes, name);
1940 return fremovexattr(filedes, name, options);
1942 #elif defined(HAVE_FREMOVEEA)
1943 return fremoveea(filedes, name);
1944 #elif defined(HAVE_EXTATTR_DELETE_FD)
1946 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1947 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1948 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1950 return extattr_delete_fd(filedes, attrnamespace, attrname);
1951 #elif defined(HAVE_ATTR_REMOVEF)
1953 char *attrname = strchr(name,'.') + 1;
1955 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1957 return attr_removef(filedes, attrname, flags);
1964 #if !defined(HAVE_SETXATTR)
1965 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
1966 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
1969 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1971 #if defined(HAVE_SETXATTR)
1972 #ifndef XATTR_ADD_OPT
1973 return setxattr(path, name, value, size, flags);
1976 return setxattr(path, name, value, size, 0, options);
1978 #elif defined(HAVE_SETEA)
1979 return setea(path, name, value, size, flags);
1980 #elif defined(HAVE_EXTATTR_SET_FILE)
1983 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1984 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1985 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1987 /* Check attribute existence */
1988 retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
1990 /* REPLACE attribute, that doesn't exist */
1991 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1995 /* Ignore other errors */
1998 /* CREATE attribute, that already exists */
1999 if (flags & XATTR_CREATE) {
2005 retval = extattr_set_file(path, attrnamespace, attrname, value, size);
2006 return (retval < 0) ? -1 : 0;
2007 #elif defined(HAVE_ATTR_SET)
2009 char *attrname = strchr(name,'.') + 1;
2011 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2012 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2013 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2015 return attr_set(path, attrname, (const char *)value, size, myflags);
2022 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
2024 #if defined(HAVE_LSETXATTR)
2025 return lsetxattr(path, name, value, size, flags);
2026 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
2027 int options = XATTR_NOFOLLOW;
2028 return setxattr(path, name, value, size, 0, options);
2029 #elif defined(LSETEA)
2030 return lsetea(path, name, value, size, flags);
2031 #elif defined(HAVE_EXTATTR_SET_LINK)
2034 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2035 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2036 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2038 /* Check attribute existence */
2039 retval = extattr_get_link(path, attrnamespace, attrname, NULL, 0);
2041 /* REPLACE attribute, that doesn't exist */
2042 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2046 /* Ignore other errors */
2049 /* CREATE attribute, that already exists */
2050 if (flags & XATTR_CREATE) {
2057 retval = extattr_set_link(path, attrnamespace, attrname, value, size);
2058 return (retval < 0) ? -1 : 0;
2059 #elif defined(HAVE_ATTR_SET)
2060 int myflags = ATTR_DONTFOLLOW;
2061 char *attrname = strchr(name,'.') + 1;
2063 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2064 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2065 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2067 return attr_set(path, attrname, (const char *)value, size, myflags);
2074 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
2076 #if defined(HAVE_FSETXATTR)
2077 #ifndef XATTR_ADD_OPT
2078 return fsetxattr(filedes, name, value, size, flags);
2081 return fsetxattr(filedes, name, value, size, 0, options);
2083 #elif defined(HAVE_FSETEA)
2084 return fsetea(filedes, name, value, size, flags);
2085 #elif defined(HAVE_EXTATTR_SET_FD)
2088 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2089 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2090 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2092 /* Check attribute existence */
2093 retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
2095 /* REPLACE attribute, that doesn't exist */
2096 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2100 /* Ignore other errors */
2103 /* CREATE attribute, that already exists */
2104 if (flags & XATTR_CREATE) {
2110 retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
2111 return (retval < 0) ? -1 : 0;
2112 #elif defined(HAVE_ATTR_SETF)
2114 char *attrname = strchr(name,'.') + 1;
2116 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2117 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2118 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2120 return attr_setf(filedes, attrname, (const char *)value, size, myflags);
2127 /****************************************************************************
2128 Return the major devicenumber for UNIX extensions.
2129 ****************************************************************************/
2131 uint32 unix_dev_major(SMB_DEV_T dev)
2133 #if defined(HAVE_DEVICE_MAJOR_FN)
2134 return (uint32)major(dev);
2136 return (uint32)(dev >> 8);
2140 /****************************************************************************
2141 Return the minor devicenumber for UNIX extensions.
2142 ****************************************************************************/
2144 uint32 unix_dev_minor(SMB_DEV_T dev)
2146 #if defined(HAVE_DEVICE_MINOR_FN)
2147 return (uint32)minor(dev);
2149 return (uint32)(dev & 0xff);
2153 #if defined(WITH_AIO)
2155 /*******************************************************************
2156 An aio_read wrapper that will deal with 64-bit sizes.
2157 ********************************************************************/
2159 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2161 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2162 return aio_read64(aiocb);
2163 #elif defined(HAVE_AIO_READ)
2164 return aio_read(aiocb);
2171 /*******************************************************************
2172 An aio_write wrapper that will deal with 64-bit sizes.
2173 ********************************************************************/
2175 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2177 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2178 return aio_write64(aiocb);
2179 #elif defined(HAVE_AIO_WRITE)
2180 return aio_write(aiocb);
2187 /*******************************************************************
2188 An aio_return wrapper that will deal with 64-bit sizes.
2189 ********************************************************************/
2191 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2193 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2194 return aio_return64(aiocb);
2195 #elif defined(HAVE_AIO_RETURN)
2196 return aio_return(aiocb);
2203 /*******************************************************************
2204 An aio_cancel wrapper that will deal with 64-bit sizes.
2205 ********************************************************************/
2207 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2209 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2210 return aio_cancel64(fd, aiocb);
2211 #elif defined(HAVE_AIO_CANCEL)
2212 return aio_cancel(fd, aiocb);
2219 /*******************************************************************
2220 An aio_error wrapper that will deal with 64-bit sizes.
2221 ********************************************************************/
2223 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2225 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2226 return aio_error64(aiocb);
2227 #elif defined(HAVE_AIO_ERROR)
2228 return aio_error(aiocb);
2235 /*******************************************************************
2236 An aio_fsync wrapper that will deal with 64-bit sizes.
2237 ********************************************************************/
2239 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2241 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2242 return aio_fsync64(op, aiocb);
2243 #elif defined(HAVE_AIO_FSYNC)
2244 return aio_fsync(op, aiocb);
2251 /*******************************************************************
2252 An aio_fsync wrapper that will deal with 64-bit sizes.
2253 ********************************************************************/
2255 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2257 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2258 return aio_suspend64(cblist, n, timeout);
2259 #elif defined(HAVE_AIO_FSYNC)
2260 return aio_suspend(cblist, n, timeout);
2266 #else /* !WITH_AIO */
2268 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2274 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2280 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2286 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2292 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2298 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2304 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2309 #endif /* WITH_AIO */
2311 int sys_getpeereid( int s, uid_t *uid)
2313 #if defined(HAVE_PEERCRED)
2315 socklen_t cred_len = sizeof(struct ucred);
2318 ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
2323 if (cred_len != sizeof(struct ucred)) {