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 return getxattr(path, name, value, size);
1512 #elif defined(HAVE_GETEA)
1513 return getea(path, name, value, size);
1514 #elif defined(HAVE_EXTATTR_GET_FILE)
1517 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1518 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1519 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1521 * The BSD implementation has a nasty habit of silently truncating
1522 * the returned value to the size of the buffer, so we have to check
1523 * that the buffer is large enough to fit the returned value.
1525 if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1530 if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
1534 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno)));
1536 #elif defined(HAVE_ATTR_GET)
1537 int retval, flags = 0;
1538 int valuelength = (int)size;
1539 char *attrname = strchr(name,'.') + 1;
1541 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1543 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1545 return retval ? retval : valuelength;
1552 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1554 #if defined(HAVE_LGETXATTR)
1555 return lgetxattr(path, name, value, size);
1556 #elif defined(HAVE_LGETEA)
1557 return lgetea(path, name, value, size);
1558 #elif defined(HAVE_EXTATTR_GET_LINK)
1561 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1562 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1563 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1565 if((retval=extattr_get_link(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1570 if((retval=extattr_get_link(path, attrnamespace, attrname, value, size)) >= 0)
1574 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno)));
1576 #elif defined(HAVE_ATTR_GET)
1577 int retval, flags = ATTR_DONTFOLLOW;
1578 int valuelength = (int)size;
1579 char *attrname = strchr(name,'.') + 1;
1581 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1583 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1585 return retval ? retval : valuelength;
1592 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1594 #if defined(HAVE_FGETXATTR)
1595 return fgetxattr(filedes, name, value, size);
1596 #elif defined(HAVE_FGETEA)
1597 return fgetea(filedes, name, value, size);
1598 #elif defined(HAVE_EXTATTR_GET_FD)
1601 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1602 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1603 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1605 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
1610 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0)
1614 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno)));
1616 #elif defined(HAVE_ATTR_GETF)
1617 int retval, flags = 0;
1618 int valuelength = (int)size;
1619 char *attrname = strchr(name,'.') + 1;
1621 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1623 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1625 return retval ? retval : valuelength;
1632 #if defined(HAVE_EXTATTR_LIST_FILE)
1634 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1642 { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
1643 { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
1651 static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
1653 ssize_t list_size, total_size = 0;
1656 /* Iterate through extattr(2) namespaces */
1657 for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
1659 #if defined(HAVE_EXTATTR_LIST_FILE)
1661 list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
1664 #if defined(HAVE_EXTATTR_LIST_LINK)
1666 list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
1669 #if defined(HAVE_EXTATTR_LIST_FD)
1671 list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
1678 /* Some error happend. Errno should be set by the previous call */
1684 /* XXX: Call with an empty buffer may be used to calculate
1685 necessary buffer size. Unfortunately, we can't say, how
1686 many attributes were returned, so here is the potential
1687 problem with the emulation.
1690 /* Take the worse case of one char attribute names -
1691 two bytes per name plus one more for sanity.
1693 total_size += list_size + (list_size/2 + 1)*extattr[t].len;
1696 /* Count necessary offset to fit namespace prefixes */
1698 for(i = 0; i < list_size; i += list[i] + 1)
1699 len += extattr[t].len;
1701 total_size += list_size + len;
1702 /* Buffer is too small to fit the results */
1703 if(total_size > size) {
1707 /* Shift results back, so we can prepend prefixes */
1708 buf = memmove(list + len, list, list_size);
1710 for(i = 0; i < list_size; i += len + 1) {
1712 strncpy(list, extattr[t].name, extattr[t].len + 1);
1713 list += extattr[t].len;
1714 strncpy(list, buf + i + 1, len);
1725 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1726 static char attr_buffer[ATTR_MAX_VALUELEN];
1728 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1730 int retval = 0, index;
1731 attrlist_cursor_t *cursor = 0;
1733 attrlist_t * al = (attrlist_t *)attr_buffer;
1735 size_t ent_size, left = size;
1740 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1742 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1744 for (index = 0; index < al->al_count; index++) {
1745 ae = ATTR_ENTRY(attr_buffer, index);
1746 ent_size = strlen(ae->a_name) + sizeof("user.");
1747 if (left >= ent_size) {
1748 strncpy(bp, "user.", sizeof("user."));
1749 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1757 total_size += ent_size;
1759 if (al->al_more == 0) break;
1766 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1768 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1770 for (index = 0; index < al->al_count; index++) {
1771 ae = ATTR_ENTRY(attr_buffer, index);
1772 ent_size = strlen(ae->a_name) + sizeof("system.");
1773 if (left >= ent_size) {
1774 strncpy(bp, "system.", sizeof("system."));
1775 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1783 total_size += ent_size;
1785 if (al->al_more == 0) break;
1788 return (ssize_t)(retval ? retval : total_size);
1793 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1795 #if defined(HAVE_LISTXATTR)
1796 return listxattr(path, list, size);
1797 #elif defined(HAVE_LISTEA)
1798 return listea(path, list, size);
1799 #elif defined(HAVE_EXTATTR_LIST_FILE)
1802 return bsd_attr_list(0, arg, list, size);
1803 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1804 return irix_attr_list(path, 0, list, size, 0);
1811 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1813 #if defined(HAVE_LLISTXATTR)
1814 return llistxattr(path, list, size);
1815 #elif defined(HAVE_LLISTEA)
1816 return llistea(path, list, size);
1817 #elif defined(HAVE_EXTATTR_LIST_LINK)
1820 return bsd_attr_list(1, arg, list, size);
1821 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1822 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1829 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1831 #if defined(HAVE_FLISTXATTR)
1832 return flistxattr(filedes, list, size);
1833 #elif defined(HAVE_FLISTEA)
1834 return flistea(filedes, list, size);
1835 #elif defined(HAVE_EXTATTR_LIST_FD)
1837 arg.filedes = filedes;
1838 return bsd_attr_list(2, arg, list, size);
1839 #elif defined(HAVE_ATTR_LISTF)
1840 return irix_attr_list(NULL, filedes, list, size, 0);
1847 int sys_removexattr (const char *path, const char *name)
1849 #if defined(HAVE_REMOVEXATTR)
1850 return removexattr(path, name);
1851 #elif defined(HAVE_REMOVEEA)
1852 return removeea(path, name);
1853 #elif defined(HAVE_EXTATTR_DELETE_FILE)
1855 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1856 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1857 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1859 return extattr_delete_file(path, attrnamespace, attrname);
1860 #elif defined(HAVE_ATTR_REMOVE)
1862 char *attrname = strchr(name,'.') + 1;
1864 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1866 return attr_remove(path, attrname, flags);
1873 int sys_lremovexattr (const char *path, const char *name)
1875 #if defined(HAVE_LREMOVEXATTR)
1876 return lremovexattr(path, name);
1877 #elif defined(HAVE_LREMOVEEA)
1878 return lremoveea(path, name);
1879 #elif defined(HAVE_EXTATTR_DELETE_LINK)
1881 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1882 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1883 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1885 return extattr_delete_link(path, attrnamespace, attrname);
1886 #elif defined(HAVE_ATTR_REMOVE)
1887 int flags = ATTR_DONTFOLLOW;
1888 char *attrname = strchr(name,'.') + 1;
1890 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1892 return attr_remove(path, attrname, flags);
1899 int sys_fremovexattr (int filedes, const char *name)
1901 #if defined(HAVE_FREMOVEXATTR)
1902 return fremovexattr(filedes, name);
1903 #elif defined(HAVE_FREMOVEEA)
1904 return fremoveea(filedes, name);
1905 #elif defined(HAVE_EXTATTR_DELETE_FD)
1907 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1908 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1909 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1911 return extattr_delete_fd(filedes, attrnamespace, attrname);
1912 #elif defined(HAVE_ATTR_REMOVEF)
1914 char *attrname = strchr(name,'.') + 1;
1916 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1918 return attr_removef(filedes, attrname, flags);
1925 #if !defined(HAVE_SETXATTR)
1926 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
1927 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
1930 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1932 #if defined(HAVE_SETXATTR)
1933 return setxattr(path, name, value, size, flags);
1934 #elif defined(HAVE_SETEA)
1935 return setea(path, name, value, size, flags);
1936 #elif defined(HAVE_EXTATTR_SET_FILE)
1939 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1940 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1941 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1943 /* Check attribute existence */
1944 retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
1946 /* REPLACE attribute, that doesn't exist */
1947 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1951 /* Ignore other errors */
1954 /* CREATE attribute, that already exists */
1955 if (flags & XATTR_CREATE) {
1961 retval = extattr_set_file(path, attrnamespace, attrname, value, size);
1962 return (retval < 0) ? -1 : 0;
1963 #elif defined(HAVE_ATTR_SET)
1965 char *attrname = strchr(name,'.') + 1;
1967 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1968 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1969 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1971 return attr_set(path, attrname, (const char *)value, size, myflags);
1978 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1980 #if defined(HAVE_LSETXATTR)
1981 return lsetxattr(path, name, value, size, flags);
1982 #elif defined(LSETEA)
1983 return lsetea(path, name, value, size, flags);
1984 #elif defined(HAVE_EXTATTR_SET_LINK)
1987 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1988 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1989 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1991 /* Check attribute existence */
1992 retval = extattr_get_link(path, attrnamespace, attrname, NULL, 0);
1994 /* REPLACE attribute, that doesn't exist */
1995 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1999 /* Ignore other errors */
2002 /* CREATE attribute, that already exists */
2003 if (flags & XATTR_CREATE) {
2010 retval = extattr_set_link(path, attrnamespace, attrname, value, size);
2011 return (retval < 0) ? -1 : 0;
2012 #elif defined(HAVE_ATTR_SET)
2013 int myflags = ATTR_DONTFOLLOW;
2014 char *attrname = strchr(name,'.') + 1;
2016 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2017 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2018 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2020 return attr_set(path, attrname, (const char *)value, size, myflags);
2027 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
2029 #if defined(HAVE_FSETXATTR)
2030 return fsetxattr(filedes, name, value, size, flags);
2031 #elif defined(HAVE_FSETEA)
2032 return fsetea(filedes, name, value, size, flags);
2033 #elif defined(HAVE_EXTATTR_SET_FD)
2036 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2037 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2038 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2040 /* Check attribute existence */
2041 retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
2043 /* REPLACE attribute, that doesn't exist */
2044 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2048 /* Ignore other errors */
2051 /* CREATE attribute, that already exists */
2052 if (flags & XATTR_CREATE) {
2058 retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
2059 return (retval < 0) ? -1 : 0;
2060 #elif defined(HAVE_ATTR_SETF)
2062 char *attrname = strchr(name,'.') + 1;
2064 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2065 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2066 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2068 return attr_setf(filedes, attrname, (const char *)value, size, myflags);
2075 /****************************************************************************
2076 Return the major devicenumber for UNIX extensions.
2077 ****************************************************************************/
2079 uint32 unix_dev_major(SMB_DEV_T dev)
2081 #if defined(HAVE_DEVICE_MAJOR_FN)
2082 return (uint32)major(dev);
2084 return (uint32)(dev >> 8);
2088 /****************************************************************************
2089 Return the minor devicenumber for UNIX extensions.
2090 ****************************************************************************/
2092 uint32 unix_dev_minor(SMB_DEV_T dev)
2094 #if defined(HAVE_DEVICE_MINOR_FN)
2095 return (uint32)minor(dev);
2097 return (uint32)(dev & 0xff);
2101 #if defined(WITH_AIO)
2103 /*******************************************************************
2104 An aio_read wrapper that will deal with 64-bit sizes.
2105 ********************************************************************/
2107 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2109 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2110 return aio_read64(aiocb);
2111 #elif defined(HAVE_AIO_READ)
2112 return aio_read(aiocb);
2119 /*******************************************************************
2120 An aio_write wrapper that will deal with 64-bit sizes.
2121 ********************************************************************/
2123 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2125 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2126 return aio_write64(aiocb);
2127 #elif defined(HAVE_AIO_WRITE)
2128 return aio_write(aiocb);
2135 /*******************************************************************
2136 An aio_return wrapper that will deal with 64-bit sizes.
2137 ********************************************************************/
2139 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2141 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2142 return aio_return64(aiocb);
2143 #elif defined(HAVE_AIO_RETURN)
2144 return aio_return(aiocb);
2151 /*******************************************************************
2152 An aio_cancel wrapper that will deal with 64-bit sizes.
2153 ********************************************************************/
2155 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2157 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2158 return aio_cancel64(fd, aiocb);
2159 #elif defined(HAVE_AIO_CANCEL)
2160 return aio_cancel(fd, aiocb);
2167 /*******************************************************************
2168 An aio_error wrapper that will deal with 64-bit sizes.
2169 ********************************************************************/
2171 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2173 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2174 return aio_error64(aiocb);
2175 #elif defined(HAVE_AIO_ERROR)
2176 return aio_error(aiocb);
2183 /*******************************************************************
2184 An aio_fsync wrapper that will deal with 64-bit sizes.
2185 ********************************************************************/
2187 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2189 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2190 return aio_fsync64(op, aiocb);
2191 #elif defined(HAVE_AIO_FSYNC)
2192 return aio_fsync(op, aiocb);
2199 /*******************************************************************
2200 An aio_fsync wrapper that will deal with 64-bit sizes.
2201 ********************************************************************/
2203 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2205 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2206 return aio_suspend64(cblist, n, timeout);
2207 #elif defined(HAVE_AIO_FSYNC)
2208 return aio_suspend(cblist, n, timeout);
2214 #else /* !WITH_AIO */
2216 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2222 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2228 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2234 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2240 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2246 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2252 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2257 #endif /* WITH_AIO */
2259 int sys_getpeereid( int s, uid_t *uid)
2261 #if defined(HAVE_PEERCRED)
2263 socklen_t cred_len = sizeof(struct ucred);
2266 ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
2271 if (cred_len != sizeof(struct ucred)) {