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);
109 /*******************************************************************
110 A pread wrapper that will deal with EINTR and 64-bit file offsets.
111 ********************************************************************/
113 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
114 ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
119 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
120 ret = pread64(fd, buf, count, off);
122 ret = pread(fd, buf, count, off);
124 } while (ret == -1 && errno == EINTR);
129 /*******************************************************************
130 A write wrapper that will deal with EINTR and 64-bit file offsets.
131 ********************************************************************/
133 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
134 ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
139 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
140 ret = pwrite64(fd, buf, count, off);
142 ret = pwrite(fd, buf, count, off);
144 } while (ret == -1 && errno == EINTR);
149 /*******************************************************************
150 A send wrapper that will deal with EINTR.
151 ********************************************************************/
153 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
158 ret = send(s, msg, len, flags);
159 } while (ret == -1 && errno == EINTR);
163 /*******************************************************************
164 A sendto wrapper that will deal with EINTR.
165 ********************************************************************/
167 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
172 ret = sendto(s, msg, len, flags, to, tolen);
173 } while (ret == -1 && errno == EINTR);
177 /*******************************************************************
178 A recvfrom wrapper that will deal with EINTR.
179 ********************************************************************/
181 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
186 ret = recvfrom(s, buf, len, flags, from, fromlen);
187 } while (ret == -1 && errno == EINTR);
191 /*******************************************************************
192 A fcntl wrapper that will deal with EINTR.
193 ********************************************************************/
195 int sys_fcntl_ptr(int fd, int cmd, void *arg)
200 ret = fcntl(fd, cmd, arg);
201 } while (ret == -1 && errno == EINTR);
205 /*******************************************************************
206 A fcntl wrapper that will deal with EINTR.
207 ********************************************************************/
209 int sys_fcntl_long(int fd, int cmd, long arg)
214 ret = fcntl(fd, cmd, arg);
215 } while (ret == -1 && errno == EINTR);
219 /*******************************************************************
220 A stat() wrapper that will deal with 64 bit filesizes.
221 ********************************************************************/
223 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
226 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
227 ret = stat64(fname, sbuf);
229 ret = stat(fname, sbuf);
231 /* we always want directories to appear zero size */
232 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
236 /*******************************************************************
237 An fstat() wrapper that will deal with 64 bit filesizes.
238 ********************************************************************/
240 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
243 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
244 ret = fstat64(fd, sbuf);
246 ret = fstat(fd, sbuf);
248 /* we always want directories to appear zero size */
249 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
253 /*******************************************************************
254 An lstat() wrapper that will deal with 64 bit filesizes.
255 ********************************************************************/
257 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
260 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
261 ret = lstat64(fname, sbuf);
263 ret = lstat(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 ftruncate() wrapper that will deal with 64 bit filesizes.
272 ********************************************************************/
274 int sys_ftruncate(int fd, SMB_OFF_T offset)
276 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
277 return ftruncate64(fd, offset);
279 return ftruncate(fd, offset);
283 /*******************************************************************
284 An lseek() wrapper that will deal with 64 bit filesizes.
285 ********************************************************************/
287 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
289 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
290 return lseek64(fd, offset, whence);
292 return lseek(fd, offset, whence);
296 /*******************************************************************
297 An fseek() wrapper that will deal with 64 bit filesizes.
298 ********************************************************************/
300 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
302 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
303 return fseek64(fp, offset, whence);
304 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
305 return fseeko64(fp, offset, whence);
307 return fseek(fp, offset, whence);
311 /*******************************************************************
312 An ftell() wrapper that will deal with 64 bit filesizes.
313 ********************************************************************/
315 SMB_OFF_T sys_ftell(FILE *fp)
317 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
318 return (SMB_OFF_T)ftell64(fp);
319 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
320 return (SMB_OFF_T)ftello64(fp);
322 return (SMB_OFF_T)ftell(fp);
326 /*******************************************************************
327 A creat() wrapper that will deal with 64 bit filesizes.
328 ********************************************************************/
330 int sys_creat(const char *path, mode_t mode)
332 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
333 return creat64(path, mode);
336 * If creat64 isn't defined then ensure we call a potential open64.
339 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
343 /*******************************************************************
344 An open() wrapper that will deal with 64 bit filesizes.
345 ********************************************************************/
347 int sys_open(const char *path, int oflag, mode_t mode)
349 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
350 return open64(path, oflag, mode);
352 return open(path, oflag, mode);
356 /*******************************************************************
357 An fopen() wrapper that will deal with 64 bit filesizes.
358 ********************************************************************/
360 FILE *sys_fopen(const char *path, const char *type)
362 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
363 return fopen64(path, type);
365 return fopen(path, type);
369 /*******************************************************************
370 An opendir wrapper that will deal with 64 bit filesizes.
371 ********************************************************************/
373 SMB_STRUCT_DIR *sys_opendir(const char *name)
375 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
376 return opendir64(name);
378 return opendir(name);
382 /*******************************************************************
383 A readdir wrapper that will deal with 64 bit filesizes.
384 ********************************************************************/
386 SMB_STRUCT_DIRENT *sys_readdir(SMB_STRUCT_DIR *dirp)
388 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
389 return readdir64(dirp);
391 return readdir(dirp);
395 /*******************************************************************
396 A seekdir wrapper that will deal with 64 bit filesizes.
397 ********************************************************************/
399 void sys_seekdir(SMB_STRUCT_DIR *dirp, long offset)
401 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
402 seekdir64(dirp, offset);
404 seekdir(dirp, offset);
408 /*******************************************************************
409 A telldir wrapper that will deal with 64 bit filesizes.
410 ********************************************************************/
412 long sys_telldir(SMB_STRUCT_DIR *dirp)
414 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
415 return (long)telldir64(dirp);
417 return (long)telldir(dirp);
421 /*******************************************************************
422 A rewinddir wrapper that will deal with 64 bit filesizes.
423 ********************************************************************/
425 void sys_rewinddir(SMB_STRUCT_DIR *dirp)
427 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
434 /*******************************************************************
435 A close wrapper that will deal with 64 bit filesizes.
436 ********************************************************************/
438 int sys_closedir(SMB_STRUCT_DIR *dirp)
440 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
441 return closedir64(dirp);
443 return closedir(dirp);
447 /*******************************************************************
448 An mknod() wrapper that will deal with 64 bit filesizes.
449 ********************************************************************/
451 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
453 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
454 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
455 return mknod64(path, mode, dev);
457 return mknod(path, mode, dev);
460 /* No mknod system call. */
466 /*******************************************************************
467 Wrapper for realpath.
468 ********************************************************************/
470 char *sys_realpath(const char *path, char *resolved_path)
472 #if defined(HAVE_REALPATH)
473 return realpath(path, resolved_path);
475 /* As realpath is not a system call we can't return ENOSYS. */
481 /*******************************************************************
482 The wait() calls vary between systems
483 ********************************************************************/
485 int sys_waitpid(pid_t pid,int *status,int options)
488 return waitpid(pid,status,options);
489 #else /* HAVE_WAITPID */
490 return wait4(pid, status, options, NULL);
491 #endif /* HAVE_WAITPID */
494 /*******************************************************************
495 System wrapper for getwd
496 ********************************************************************/
498 char *sys_getwd(char *s)
502 wd = (char *)getcwd(s, sizeof (pstring));
504 wd = (char *)getwd(s);
509 /*******************************************************************
510 system wrapper for symlink
511 ********************************************************************/
513 int sys_symlink(const char *oldpath, const char *newpath)
519 return symlink(oldpath, newpath);
523 /*******************************************************************
524 system wrapper for readlink
525 ********************************************************************/
527 int sys_readlink(const char *path, char *buf, size_t bufsiz)
529 #ifndef HAVE_READLINK
533 return readlink(path, buf, bufsiz);
537 /*******************************************************************
538 system wrapper for link
539 ********************************************************************/
541 int sys_link(const char *oldpath, const char *newpath)
547 return link(oldpath, newpath);
551 /*******************************************************************
552 chown isn't used much but OS/2 doesn't have it
553 ********************************************************************/
555 int sys_chown(const char *fname,uid_t uid,gid_t gid)
560 DEBUG(1,("WARNING: no chown!\n"));
566 return(chown(fname,uid,gid));
570 /*******************************************************************
571 os/2 also doesn't have chroot
572 ********************************************************************/
573 int sys_chroot(const char *dname)
578 DEBUG(1,("WARNING: no chroot!\n"));
584 return(chroot(dname));
588 /**************************************************************************
589 A wrapper for gethostbyname() that tries avoids looking up hostnames
590 in the root domain, which can cause dial-on-demand links to come up for no
592 ****************************************************************************/
594 struct hostent *sys_gethostbyname(const char *name)
596 #ifdef REDUCE_ROOT_DNS_LOOKUPS
597 char query[256], hostname[256];
600 /* Does this name have any dots in it? If so, make no change */
602 if (strchr_m(name, '.'))
603 return(gethostbyname(name));
605 /* Get my hostname, which should have domain name
606 attached. If not, just do the gethostname on the
610 gethostname(hostname, sizeof(hostname) - 1);
611 hostname[sizeof(hostname) - 1] = 0;
612 if ((domain = strchr_m(hostname, '.')) == NULL)
613 return(gethostbyname(name));
615 /* Attach domain name to query and do modified query.
616 If names too large, just do gethostname on the
620 if((strlen(name) + strlen(domain)) >= sizeof(query))
621 return(gethostbyname(name));
623 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
624 return(gethostbyname(query));
625 #else /* REDUCE_ROOT_DNS_LOOKUPS */
626 return(gethostbyname(name));
627 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
631 #if defined(HAVE_POSIX_CAPABILITIES)
633 #ifdef HAVE_SYS_CAPABILITY_H
635 #if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H)
636 #define _I386_STATFS_H
637 #define _PPC_STATFS_H
638 #define BROKEN_REDHAT_7_STATFS_WORKAROUND
641 #include <sys/capability.h>
643 #ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND
644 #undef _I386_STATFS_H
646 #undef BROKEN_REDHAT_7_STATFS_WORKAROUND
649 #endif /* HAVE_SYS_CAPABILITY_H */
651 /**************************************************************************
652 Try and abstract process capabilities (for systems that have them).
653 ****************************************************************************/
655 /* Set the POSIX capabilities needed for the given purpose into the effective
656 * capability set of the current process. Make sure they are always removed
657 * from the inheritable set, because there is no circumstance in which our
658 * children should inherit our elevated privileges.
660 static BOOL set_process_capability(enum smbd_capability capability,
663 cap_value_t cap_vals[2] = {0};
664 int num_cap_vals = 0;
668 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
669 /* On Linux, make sure that any capabilities we grab are sticky
670 * across UID changes. We expect that this would allow us to keep both
671 * the effective and permitted capability sets, but as of circa 2.6.16,
672 * only the permitted set is kept. It is a bug (which we work around)
673 * that the effective set is lost, but we still require the effective
676 if (!prctl(PR_GET_KEEPCAPS)) {
677 prctl(PR_SET_KEEPCAPS, 1);
681 cap = cap_get_proc();
683 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
688 switch (capability) {
689 case KERNEL_OPLOCK_CAPABILITY:
690 #ifdef CAP_NETWORK_MGT
691 /* IRIX has CAP_NETWORK_MGT for oplocks. */
692 cap_vals[num_cap_vals++] = CAP_NETWORK_MGT;
695 case DMAPI_ACCESS_CAPABILITY:
696 #ifdef CAP_DEVICE_MGT
697 /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
698 cap_vals[num_cap_vals++] = CAP_DEVICE_MGT;
700 /* Linux has CAP_MKNOD for DMAPI access. */
701 cap_vals[num_cap_vals++] = CAP_MKNOD;
706 SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals));
708 if (num_cap_vals == 0) {
713 cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
714 enable ? CAP_SET : CAP_CLEAR);
716 /* We never want to pass capabilities down to our children, so make
717 * sure they are not inherited.
719 cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
721 if (cap_set_proc(cap) == -1) {
722 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
732 #endif /* HAVE_POSIX_CAPABILITIES */
734 /****************************************************************************
735 Gain the oplock capability from the kernel if possible.
736 ****************************************************************************/
738 void set_effective_capability(enum smbd_capability capability)
740 #if defined(HAVE_POSIX_CAPABILITIES)
741 set_process_capability(capability, True);
742 #endif /* HAVE_POSIX_CAPABILITIES */
745 void drop_effective_capability(enum smbd_capability capability)
747 #if defined(HAVE_POSIX_CAPABILITIES)
748 set_process_capability(capability, False);
749 #endif /* HAVE_POSIX_CAPABILITIES */
752 /**************************************************************************
753 Wrapper for random().
754 ****************************************************************************/
756 long sys_random(void)
758 #if defined(HAVE_RANDOM)
759 return (long)random();
760 #elif defined(HAVE_RAND)
763 DEBUG(0,("Error - no random function available !\n"));
768 /**************************************************************************
769 Wrapper for srandom().
770 ****************************************************************************/
772 void sys_srandom(unsigned int seed)
774 #if defined(HAVE_SRANDOM)
776 #elif defined(HAVE_SRAND)
779 DEBUG(0,("Error - no srandom function available !\n"));
784 /**************************************************************************
785 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
786 ****************************************************************************/
790 #if defined(SYSCONF_SC_NGROUPS_MAX)
791 int ret = sysconf(_SC_NGROUPS_MAX);
792 return (ret == -1) ? NGROUPS_MAX : ret;
798 /**************************************************************************
799 Wrapper for getgroups. Deals with broken (int) case.
800 ****************************************************************************/
802 int sys_getgroups(int setlen, gid_t *gidset)
804 #if !defined(HAVE_BROKEN_GETGROUPS)
805 return getgroups(setlen, gidset);
813 return getgroups(setlen, &gid);
817 * Broken case. We need to allocate a
818 * GID_T array of size setlen.
827 setlen = groups_max();
829 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
830 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
834 if((ngroups = getgroups(setlen, group_list)) < 0) {
835 int saved_errno = errno;
836 SAFE_FREE(group_list);
841 for(i = 0; i < ngroups; i++)
842 gidset[i] = (gid_t)group_list[i];
844 SAFE_FREE(group_list);
846 #endif /* HAVE_BROKEN_GETGROUPS */
850 /**************************************************************************
851 Wrapper for setgroups. Deals with broken (int) case. Automatically used
852 if we have broken getgroups.
853 ****************************************************************************/
855 int sys_setgroups(int setlen, gid_t *gidset)
857 #if !defined(HAVE_SETGROUPS)
860 #endif /* HAVE_SETGROUPS */
862 #if !defined(HAVE_BROKEN_GETGROUPS)
863 return setgroups(setlen, gidset);
872 if (setlen < 0 || setlen > groups_max()) {
878 * Broken case. We need to allocate a
879 * GID_T array of size setlen.
882 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
883 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
887 for(i = 0; i < setlen; i++)
888 group_list[i] = (GID_T) gidset[i];
890 if(setgroups(setlen, group_list) != 0) {
891 int saved_errno = errno;
892 SAFE_FREE(group_list);
897 SAFE_FREE(group_list);
899 #endif /* HAVE_BROKEN_GETGROUPS */
902 /**************************************************************************
903 Wrappers for setpwent(), getpwent() and endpwent()
904 ****************************************************************************/
906 void sys_setpwent(void)
911 struct passwd *sys_getpwent(void)
916 void sys_endpwent(void)
921 /**************************************************************************
922 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
923 ****************************************************************************/
925 #ifdef ENABLE_BUILD_FARM_HACKS
928 * In the build farm we want to be able to join machines to the domain. As we
929 * don't have root access, we need to bypass direct access to /etc/passwd
930 * after a user has been created via samr. Fake those users.
933 static struct passwd *fake_pwd;
934 static int num_fake_pwd;
936 struct passwd *sys_getpwnam(const char *name)
940 for (i=0; i<num_fake_pwd; i++) {
941 if (strcmp(fake_pwd[i].pw_name, name) == 0) {
942 DEBUG(10, ("Returning fake user %s\n", name));
947 return getpwnam(name);
950 struct passwd *sys_getpwuid(uid_t uid)
954 for (i=0; i<num_fake_pwd; i++) {
955 if (fake_pwd[i].pw_uid == uid) {
956 DEBUG(10, ("Returning fake user %s\n",
957 fake_pwd[i].pw_name));
962 return getpwuid(uid);
965 void faked_create_user(const char *name)
969 struct passwd new_pwd;
971 for (i=0; i<10; i++) {
972 generate_random_buffer((unsigned char *)&uid,
974 if (getpwuid(uid) == NULL) {
980 /* Weird. No free uid found... */
984 new_pwd.pw_name = SMB_STRDUP(name);
985 new_pwd.pw_passwd = SMB_STRDUP("x");
986 new_pwd.pw_uid = uid;
987 new_pwd.pw_gid = 100;
988 new_pwd.pw_gecos = SMB_STRDUP("faked user");
989 new_pwd.pw_dir = SMB_STRDUP("/nodir");
990 new_pwd.pw_shell = SMB_STRDUP("/bin/false");
992 ADD_TO_ARRAY(NULL, struct passwd, new_pwd, &fake_pwd,
995 DEBUG(10, ("Added fake user %s, have %d fake users\n",
996 name, num_fake_pwd));
1001 struct passwd *sys_getpwnam(const char *name)
1003 return getpwnam(name);
1006 struct passwd *sys_getpwuid(uid_t uid)
1008 return getpwuid(uid);
1013 struct group *sys_getgrnam(const char *name)
1015 return getgrnam(name);
1018 struct group *sys_getgrgid(gid_t gid)
1020 return getgrgid(gid);
1023 #if 0 /* NOT CURRENTLY USED - JRA */
1024 /**************************************************************************
1025 The following are the UNICODE versions of *all* system interface functions
1026 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
1027 which currently are left as ascii as they are not used other than in name
1029 ****************************************************************************/
1031 /**************************************************************************
1032 Wide stat. Just narrow and call sys_xxx.
1033 ****************************************************************************/
1035 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
1038 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
1041 /**************************************************************************
1042 Wide lstat. Just narrow and call sys_xxx.
1043 ****************************************************************************/
1045 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
1048 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
1051 /**************************************************************************
1052 Wide creat. Just narrow and call sys_xxx.
1053 ****************************************************************************/
1055 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
1058 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
1061 /**************************************************************************
1062 Wide open. Just narrow and call sys_xxx.
1063 ****************************************************************************/
1065 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
1068 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
1071 /**************************************************************************
1072 Wide fopen. Just narrow and call sys_xxx.
1073 ****************************************************************************/
1075 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
1078 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
1081 /**************************************************************************
1082 Wide opendir. Just narrow and call sys_xxx.
1083 ****************************************************************************/
1085 SMB_STRUCT_DIR *wsys_opendir(const smb_ucs2_t *wfname)
1088 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
1091 /**************************************************************************
1092 Wide readdir. Return a structure pointer containing a wide filename.
1093 ****************************************************************************/
1095 SMB_STRUCT_WDIRENT *wsys_readdir(SMB_STRUCT_DIR *dirp)
1097 static SMB_STRUCT_WDIRENT retval;
1098 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
1104 * The only POSIX defined member of this struct is d_name.
1107 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
1112 /**************************************************************************
1113 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
1114 ****************************************************************************/
1116 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
1119 char *p = sys_getwd(fname);
1124 return unix_to_unicode(s, p, sizeof(wpstring));
1127 /**************************************************************************
1128 Wide chown. Just narrow and call sys_xxx.
1129 ****************************************************************************/
1131 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
1134 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
1137 /**************************************************************************
1138 Wide chroot. Just narrow and call sys_xxx.
1139 ****************************************************************************/
1141 int wsys_chroot(const smb_ucs2_t *wfname)
1144 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
1147 /**************************************************************************
1148 Wide getpwnam. Return a structure pointer containing wide names.
1149 ****************************************************************************/
1151 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
1153 static SMB_STRUCT_WPASSWD retval;
1155 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
1160 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1161 retval.pw_passwd = pwret->pw_passwd;
1162 retval.pw_uid = pwret->pw_uid;
1163 retval.pw_gid = pwret->pw_gid;
1164 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1165 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1166 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1171 /**************************************************************************
1172 Wide getpwuid. Return a structure pointer containing wide names.
1173 ****************************************************************************/
1175 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
1177 static SMB_STRUCT_WPASSWD retval;
1178 struct passwd *pwret = sys_getpwuid(uid);
1183 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1184 retval.pw_passwd = pwret->pw_passwd;
1185 retval.pw_uid = pwret->pw_uid;
1186 retval.pw_gid = pwret->pw_gid;
1187 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1188 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1189 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1193 #endif /* NOT CURRENTLY USED - JRA */
1195 /**************************************************************************
1196 Extract a command into an arg list. Uses a static pstring for storage.
1197 Caller frees returned arg list (which contains pointers into the static pstring).
1198 ****************************************************************************/
1200 static char **extract_args(const char *command)
1202 static pstring trunc_cmd;
1208 pstrcpy(trunc_cmd, command);
1210 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1219 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1222 if((argl = (char **)SMB_MALLOC((argcl + 1) * sizeof(char *))) == NULL)
1226 * Now do the extraction.
1229 pstrcpy(trunc_cmd, command);
1231 ptr = strtok(trunc_cmd, " \t");
1235 while((ptr = strtok(NULL, " \t")) != NULL)
1242 /**************************************************************************
1243 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1244 a sys_getpid() that only does a system call *once*.
1245 ****************************************************************************/
1247 static pid_t mypid = (pid_t)-1;
1249 pid_t sys_fork(void)
1251 pid_t forkret = fork();
1253 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1259 /**************************************************************************
1260 Wrapper for getpid. Ensures we only do a system call *once*.
1261 ****************************************************************************/
1263 pid_t sys_getpid(void)
1265 if (mypid == (pid_t)-1)
1271 /**************************************************************************
1272 Wrapper for popen. Safer as it doesn't search a path.
1273 Modified from the glibc sources.
1274 modified by tridge to return a file descriptor. We must kick our FILE* habit
1275 ****************************************************************************/
1277 typedef struct _popen_list
1281 struct _popen_list *next;
1284 static popen_list *popen_chain;
1286 int sys_popen(const char *command)
1288 int parent_end, child_end;
1290 popen_list *entry = NULL;
1293 if (pipe(pipe_fds) < 0)
1296 parent_end = pipe_fds[0];
1297 child_end = pipe_fds[1];
1304 if((entry = SMB_MALLOC_P(popen_list)) == NULL)
1307 ZERO_STRUCTP(entry);
1310 * Extract the command and args into a NULL terminated array.
1313 if(!(argl = extract_args(command)))
1316 entry->child_pid = sys_fork();
1318 if (entry->child_pid == -1) {
1322 if (entry->child_pid == 0) {
1328 int child_std_end = STDOUT_FILENO;
1332 if (child_end != child_std_end) {
1333 dup2 (child_end, child_std_end);
1338 * POSIX.2: "popen() shall ensure that any streams from previous
1339 * popen() calls that remain open in the parent process are closed
1340 * in the new child process."
1343 for (p = popen_chain; p; p = p->next)
1346 execv(argl[0], argl);
1357 /* Link into popen_chain. */
1358 entry->next = popen_chain;
1359 popen_chain = entry;
1360 entry->fd = parent_end;
1373 /**************************************************************************
1374 Wrapper for pclose. Modified from the glibc sources.
1375 ****************************************************************************/
1377 int sys_pclose(int fd)
1380 popen_list **ptr = &popen_chain;
1381 popen_list *entry = NULL;
1385 /* Unlink from popen_chain. */
1386 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1387 if ((*ptr)->fd == fd) {
1389 *ptr = (*ptr)->next;
1395 if (status < 0 || close(entry->fd) < 0)
1399 * As Samba is catching and eating child process
1400 * exits we don't really care about the child exit
1401 * code, a -1 with errno = ECHILD will do fine for us.
1405 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1406 } while (wait_pid == -1 && errno == EINTR);
1415 /**************************************************************************
1416 Wrappers for dlopen, dlsym, dlclose.
1417 ****************************************************************************/
1419 void *sys_dlopen(const char *name, int flags)
1421 #if defined(HAVE_DLOPEN)
1422 return dlopen(name, flags);
1428 void *sys_dlsym(void *handle, const char *symbol)
1430 #if defined(HAVE_DLSYM)
1431 return dlsym(handle, symbol);
1437 int sys_dlclose (void *handle)
1439 #if defined(HAVE_DLCLOSE)
1440 return dlclose(handle);
1446 const char *sys_dlerror(void)
1448 #if defined(HAVE_DLERROR)
1455 int sys_dup2(int oldfd, int newfd)
1457 #if defined(HAVE_DUP2)
1458 return dup2(oldfd, newfd);
1465 /**************************************************************************
1466 Wrapper for Admin Logs.
1467 ****************************************************************************/
1469 void sys_adminlog(int priority, const char *format_str, ...)
1473 char *msgbuf = NULL;
1475 va_start( ap, format_str );
1476 ret = vasprintf( &msgbuf, format_str, ap );
1482 #if defined(HAVE_SYSLOG)
1483 syslog( priority, "%s", msgbuf );
1485 DEBUG(0,("%s", msgbuf ));
1490 /**************************************************************************
1491 Wrappers for extented attribute calls. Based on the Linux package with
1492 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1493 ****************************************************************************/
1495 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
1497 #if defined(HAVE_GETXATTR)
1498 return getxattr(path, name, value, size);
1499 #elif defined(HAVE_GETEA)
1500 return getea(path, name, value, size);
1501 #elif defined(HAVE_EXTATTR_GET_FILE)
1504 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1505 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1506 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1508 * The BSD implementation has a nasty habit of silently truncating
1509 * the returned value to the size of the buffer, so we have to check
1510 * that the buffer is large enough to fit the returned value.
1512 if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1517 if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
1521 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno)));
1523 #elif defined(HAVE_ATTR_GET)
1524 int retval, flags = 0;
1525 int valuelength = (int)size;
1526 char *attrname = strchr(name,'.') + 1;
1528 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1530 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1532 return retval ? retval : valuelength;
1539 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1541 #if defined(HAVE_LGETXATTR)
1542 return lgetxattr(path, name, value, size);
1543 #elif defined(HAVE_LGETEA)
1544 return lgetea(path, name, value, size);
1545 #elif defined(HAVE_EXTATTR_GET_LINK)
1548 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1549 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1550 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1552 if((retval=extattr_get_link(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1557 if((retval=extattr_get_link(path, attrnamespace, attrname, value, size)) >= 0)
1561 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno)));
1563 #elif defined(HAVE_ATTR_GET)
1564 int retval, flags = ATTR_DONTFOLLOW;
1565 int valuelength = (int)size;
1566 char *attrname = strchr(name,'.') + 1;
1568 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1570 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1572 return retval ? retval : valuelength;
1579 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1581 #if defined(HAVE_FGETXATTR)
1582 return fgetxattr(filedes, name, value, size);
1583 #elif defined(HAVE_FGETEA)
1584 return fgetea(filedes, name, value, size);
1585 #elif defined(HAVE_EXTATTR_GET_FD)
1588 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1589 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1590 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1592 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
1597 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0)
1601 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno)));
1603 #elif defined(HAVE_ATTR_GETF)
1604 int retval, flags = 0;
1605 int valuelength = (int)size;
1606 char *attrname = strchr(name,'.') + 1;
1608 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1610 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1612 return retval ? retval : valuelength;
1619 #if defined(HAVE_EXTATTR_LIST_FILE)
1621 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1629 { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
1630 { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
1638 static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
1640 ssize_t list_size, total_size = 0;
1643 /* Iterate through extattr(2) namespaces */
1644 for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
1646 #if defined(HAVE_EXTATTR_LIST_FILE)
1648 list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
1651 #if defined(HAVE_EXTATTR_LIST_LINK)
1653 list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
1656 #if defined(HAVE_EXTATTR_LIST_FD)
1658 list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
1665 /* Some error happend. Errno should be set by the previous call */
1671 /* XXX: Call with an empty buffer may be used to calculate
1672 necessary buffer size. Unfortunately, we can't say, how
1673 many attributes were returned, so here is the potential
1674 problem with the emulation.
1677 /* Take the worse case of one char attribute names -
1678 two bytes per name plus one more for sanity.
1680 total_size += list_size + (list_size/2 + 1)*extattr[t].len;
1683 /* Count necessary offset to fit namespace prefixes */
1685 for(i = 0; i < list_size; i += list[i] + 1)
1686 len += extattr[t].len;
1688 total_size += list_size + len;
1689 /* Buffer is too small to fit the results */
1690 if(total_size > size) {
1694 /* Shift results back, so we can prepend prefixes */
1695 buf = memmove(list + len, list, list_size);
1697 for(i = 0; i < list_size; i += len + 1) {
1699 strncpy(list, extattr[t].name, extattr[t].len + 1);
1700 list += extattr[t].len;
1701 strncpy(list, buf + i + 1, len);
1712 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1713 static char attr_buffer[ATTR_MAX_VALUELEN];
1715 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1717 int retval = 0, index;
1718 attrlist_cursor_t *cursor = 0;
1720 attrlist_t * al = (attrlist_t *)attr_buffer;
1722 size_t ent_size, left = size;
1727 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1729 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1731 for (index = 0; index < al->al_count; index++) {
1732 ae = ATTR_ENTRY(attr_buffer, index);
1733 ent_size = strlen(ae->a_name) + sizeof("user.");
1734 if (left >= ent_size) {
1735 strncpy(bp, "user.", sizeof("user."));
1736 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1744 total_size += ent_size;
1746 if (al->al_more == 0) break;
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("system.");
1760 if (left >= ent_size) {
1761 strncpy(bp, "system.", sizeof("system."));
1762 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1770 total_size += ent_size;
1772 if (al->al_more == 0) break;
1775 return (ssize_t)(retval ? retval : total_size);
1780 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1782 #if defined(HAVE_LISTXATTR)
1783 return listxattr(path, list, size);
1784 #elif defined(HAVE_LISTEA)
1785 return listea(path, list, size);
1786 #elif defined(HAVE_EXTATTR_LIST_FILE)
1789 return bsd_attr_list(0, arg, list, size);
1790 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1791 return irix_attr_list(path, 0, list, size, 0);
1798 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1800 #if defined(HAVE_LLISTXATTR)
1801 return llistxattr(path, list, size);
1802 #elif defined(HAVE_LLISTEA)
1803 return llistea(path, list, size);
1804 #elif defined(HAVE_EXTATTR_LIST_LINK)
1807 return bsd_attr_list(1, arg, list, size);
1808 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1809 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1816 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1818 #if defined(HAVE_FLISTXATTR)
1819 return flistxattr(filedes, list, size);
1820 #elif defined(HAVE_FLISTEA)
1821 return flistea(filedes, list, size);
1822 #elif defined(HAVE_EXTATTR_LIST_FD)
1824 arg.filedes = filedes;
1825 return bsd_attr_list(2, arg, list, size);
1826 #elif defined(HAVE_ATTR_LISTF)
1827 return irix_attr_list(NULL, filedes, list, size, 0);
1834 int sys_removexattr (const char *path, const char *name)
1836 #if defined(HAVE_REMOVEXATTR)
1837 return removexattr(path, name);
1838 #elif defined(HAVE_REMOVEEA)
1839 return removeea(path, name);
1840 #elif defined(HAVE_EXTATTR_DELETE_FILE)
1842 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1843 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1844 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1846 return extattr_delete_file(path, attrnamespace, attrname);
1847 #elif defined(HAVE_ATTR_REMOVE)
1849 char *attrname = strchr(name,'.') + 1;
1851 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1853 return attr_remove(path, attrname, flags);
1860 int sys_lremovexattr (const char *path, const char *name)
1862 #if defined(HAVE_LREMOVEXATTR)
1863 return lremovexattr(path, name);
1864 #elif defined(HAVE_LREMOVEEA)
1865 return lremoveea(path, name);
1866 #elif defined(HAVE_EXTATTR_DELETE_LINK)
1868 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1869 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1870 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1872 return extattr_delete_link(path, attrnamespace, attrname);
1873 #elif defined(HAVE_ATTR_REMOVE)
1874 int flags = ATTR_DONTFOLLOW;
1875 char *attrname = strchr(name,'.') + 1;
1877 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1879 return attr_remove(path, attrname, flags);
1886 int sys_fremovexattr (int filedes, const char *name)
1888 #if defined(HAVE_FREMOVEXATTR)
1889 return fremovexattr(filedes, name);
1890 #elif defined(HAVE_FREMOVEEA)
1891 return fremoveea(filedes, name);
1892 #elif defined(HAVE_EXTATTR_DELETE_FD)
1894 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1895 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1896 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1898 return extattr_delete_fd(filedes, attrnamespace, attrname);
1899 #elif defined(HAVE_ATTR_REMOVEF)
1901 char *attrname = strchr(name,'.') + 1;
1903 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1905 return attr_removef(filedes, attrname, flags);
1912 #if !defined(HAVE_SETXATTR)
1913 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
1914 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
1917 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1919 #if defined(HAVE_SETXATTR)
1920 return setxattr(path, name, value, size, flags);
1921 #elif defined(HAVE_SETEA)
1922 return setea(path, name, value, size, flags);
1923 #elif defined(HAVE_EXTATTR_SET_FILE)
1926 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1927 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1928 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1930 /* Check attribute existence */
1931 retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
1933 /* REPLACE attribute, that doesn't exist */
1934 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1938 /* Ignore other errors */
1941 /* CREATE attribute, that already exists */
1942 if (flags & XATTR_CREATE) {
1948 retval = extattr_set_file(path, attrnamespace, attrname, value, size);
1949 return (retval < 0) ? -1 : 0;
1950 #elif defined(HAVE_ATTR_SET)
1952 char *attrname = strchr(name,'.') + 1;
1954 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1955 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1956 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1958 return attr_set(path, attrname, (const char *)value, size, myflags);
1965 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1967 #if defined(HAVE_LSETXATTR)
1968 return lsetxattr(path, name, value, size, flags);
1969 #elif defined(LSETEA)
1970 return lsetea(path, name, value, size, flags);
1971 #elif defined(HAVE_EXTATTR_SET_LINK)
1974 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1975 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1976 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1978 /* Check attribute existence */
1979 retval = extattr_get_link(path, attrnamespace, attrname, NULL, 0);
1981 /* REPLACE attribute, that doesn't exist */
1982 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1986 /* Ignore other errors */
1989 /* CREATE attribute, that already exists */
1990 if (flags & XATTR_CREATE) {
1997 retval = extattr_set_link(path, attrnamespace, attrname, value, size);
1998 return (retval < 0) ? -1 : 0;
1999 #elif defined(HAVE_ATTR_SET)
2000 int myflags = ATTR_DONTFOLLOW;
2001 char *attrname = strchr(name,'.') + 1;
2003 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2004 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2005 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2007 return attr_set(path, attrname, (const char *)value, size, myflags);
2014 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
2016 #if defined(HAVE_FSETXATTR)
2017 return fsetxattr(filedes, name, value, size, flags);
2018 #elif defined(HAVE_FSETEA)
2019 return fsetea(filedes, name, value, size, flags);
2020 #elif defined(HAVE_EXTATTR_SET_FD)
2023 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2024 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2025 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2027 /* Check attribute existence */
2028 retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
2030 /* REPLACE attribute, that doesn't exist */
2031 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2035 /* Ignore other errors */
2038 /* CREATE attribute, that already exists */
2039 if (flags & XATTR_CREATE) {
2045 retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
2046 return (retval < 0) ? -1 : 0;
2047 #elif defined(HAVE_ATTR_SETF)
2049 char *attrname = strchr(name,'.') + 1;
2051 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2052 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2053 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2055 return attr_setf(filedes, attrname, (const char *)value, size, myflags);
2062 /****************************************************************************
2063 Return the major devicenumber for UNIX extensions.
2064 ****************************************************************************/
2066 uint32 unix_dev_major(SMB_DEV_T dev)
2068 #if defined(HAVE_DEVICE_MAJOR_FN)
2069 return (uint32)major(dev);
2071 return (uint32)(dev >> 8);
2075 /****************************************************************************
2076 Return the minor devicenumber for UNIX extensions.
2077 ****************************************************************************/
2079 uint32 unix_dev_minor(SMB_DEV_T dev)
2081 #if defined(HAVE_DEVICE_MINOR_FN)
2082 return (uint32)minor(dev);
2084 return (uint32)(dev & 0xff);
2088 #if defined(WITH_AIO)
2090 /*******************************************************************
2091 An aio_read wrapper that will deal with 64-bit sizes.
2092 ********************************************************************/
2094 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2096 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2097 return aio_read64(aiocb);
2098 #elif defined(HAVE_AIO_READ)
2099 return aio_read(aiocb);
2106 /*******************************************************************
2107 An aio_write wrapper that will deal with 64-bit sizes.
2108 ********************************************************************/
2110 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2112 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2113 return aio_write64(aiocb);
2114 #elif defined(HAVE_AIO_WRITE)
2115 return aio_write(aiocb);
2122 /*******************************************************************
2123 An aio_return wrapper that will deal with 64-bit sizes.
2124 ********************************************************************/
2126 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2128 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2129 return aio_return64(aiocb);
2130 #elif defined(HAVE_AIO_RETURN)
2131 return aio_return(aiocb);
2138 /*******************************************************************
2139 An aio_cancel wrapper that will deal with 64-bit sizes.
2140 ********************************************************************/
2142 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2144 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2145 return aio_cancel64(fd, aiocb);
2146 #elif defined(HAVE_AIO_CANCEL)
2147 return aio_cancel(fd, aiocb);
2154 /*******************************************************************
2155 An aio_error wrapper that will deal with 64-bit sizes.
2156 ********************************************************************/
2158 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2160 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2161 return aio_error64(aiocb);
2162 #elif defined(HAVE_AIO_ERROR)
2163 return aio_error(aiocb);
2170 /*******************************************************************
2171 An aio_fsync wrapper that will deal with 64-bit sizes.
2172 ********************************************************************/
2174 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2176 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2177 return aio_fsync64(op, aiocb);
2178 #elif defined(HAVE_AIO_FSYNC)
2179 return aio_fsync(op, aiocb);
2186 /*******************************************************************
2187 An aio_fsync wrapper that will deal with 64-bit sizes.
2188 ********************************************************************/
2190 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2192 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2193 return aio_suspend64(cblist, n, timeout);
2194 #elif defined(HAVE_AIO_FSYNC)
2195 return aio_suspend(cblist, n, timeout);
2201 #else /* !WITH_AIO */
2203 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2209 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2215 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2221 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2227 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2233 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2239 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2244 #endif /* WITH_AIO */
2246 int sys_getpeereid( int s, uid_t *uid)
2248 #if defined(HAVE_PEERCRED)
2250 socklen_t cred_len = sizeof(struct ucred);
2253 ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
2258 if (cred_len != sizeof(struct ucred)) {