build: Rationalise AIO support in configure, ensure on by default
[ddiss/samba.git] / source3 / lib / system.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba system utilities
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison  1998-2005
6    Copyright (C) Timur Bakeyev        2005
7    Copyright (C) Bjoern Jacke    2006-2007
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "system/syslog.h"
25 #include "system/capability.h"
26 #include "system/passwd.h"
27 #include "system/filesys.h"
28
29 #ifdef HAVE_SYS_SYSCTL_H
30 #include <sys/sysctl.h>
31 #endif
32
33 #ifdef HAVE_SYS_PRCTL_H
34 #include <sys/prctl.h>
35 #endif
36
37 /*
38    The idea is that this file will eventually have wrappers around all
39    important system calls in samba. The aims are:
40
41    - to enable easier porting by putting OS dependent stuff in here
42
43    - to allow for hooks into other "pseudo-filesystems"
44
45    - to allow easier integration of things like the japanese extensions
46
47    - to support the philosophy of Samba to expose the features of
48      the OS within the SMB model. In general whatever file/printer/variable
49      expansions/etc make sense to the OS should be acceptable to Samba.
50 */
51
52
53
54 /*******************************************************************
55 A read wrapper that will deal with EINTR.
56 ********************************************************************/
57
58 ssize_t sys_read(int fd, void *buf, size_t count)
59 {
60         ssize_t ret;
61
62         do {
63                 ret = read(fd, buf, count);
64 #if defined(EWOULDBLOCK)
65         } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
66 #else
67         } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
68 #endif
69         return ret;
70 }
71
72 /*******************************************************************
73 A write wrapper that will deal with EINTR.
74 ********************************************************************/
75
76 ssize_t sys_write(int fd, const void *buf, size_t count)
77 {
78         ssize_t ret;
79
80         do {
81                 ret = write(fd, buf, count);
82 #if defined(EWOULDBLOCK)
83         } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
84 #else
85         } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
86 #endif
87         return ret;
88 }
89
90 /*******************************************************************
91 A writev wrapper that will deal with EINTR.
92 ********************************************************************/
93
94 ssize_t sys_writev(int fd, const struct iovec *iov, int iovcnt)
95 {
96         ssize_t ret;
97
98 #if 0
99         /* Try to confuse write_data_iov a bit */
100         if ((random() % 5) == 0) {
101                 return sys_write(fd, iov[0].iov_base, iov[0].iov_len);
102         }
103         if (iov[0].iov_len > 1) {
104                 return sys_write(fd, iov[0].iov_base,
105                                  (random() % (iov[0].iov_len-1)) + 1);
106         }
107 #endif
108
109         do {
110                 ret = writev(fd, iov, iovcnt);
111 #if defined(EWOULDBLOCK)
112         } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
113 #else
114         } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
115 #endif
116         return ret;
117 }
118
119 /*******************************************************************
120 A pread wrapper that will deal with EINTR
121 ********************************************************************/
122
123 #if defined(HAVE_PREAD)
124 ssize_t sys_pread(int fd, void *buf, size_t count, off_t off)
125 {
126         ssize_t ret;
127
128         do {
129                 ret = pread(fd, buf, count, off);
130         } while (ret == -1 && errno == EINTR);
131         return ret;
132 }
133 #endif
134
135 /*******************************************************************
136 A write wrapper that will deal with EINTR
137 ********************************************************************/
138
139 #if defined(HAVE_PWRITE)
140 ssize_t sys_pwrite(int fd, const void *buf, size_t count, off_t off)
141 {
142         ssize_t ret;
143
144         do {
145                 ret = pwrite(fd, buf, count, off);
146         } while (ret == -1 && errno == EINTR);
147         return ret;
148 }
149 #endif
150
151 /*******************************************************************
152 A send wrapper that will deal with EINTR or EAGAIN or EWOULDBLOCK.
153 ********************************************************************/
154
155 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
156 {
157         ssize_t ret;
158
159         do {
160                 ret = send(s, msg, len, flags);
161 #if defined(EWOULDBLOCK)
162         } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
163 #else
164         } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
165 #endif
166         return ret;
167 }
168
169 /*******************************************************************
170 A recvfrom wrapper that will deal with EINTR.
171 ********************************************************************/
172
173 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
174 {
175         ssize_t ret;
176
177         do {
178                 ret = recvfrom(s, buf, len, flags, from, fromlen);
179 #if defined(EWOULDBLOCK)
180         } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
181 #else
182         } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
183 #endif
184         return ret;
185 }
186
187 /*******************************************************************
188 A fcntl wrapper that will deal with EINTR.
189 ********************************************************************/
190
191 int sys_fcntl_ptr(int fd, int cmd, void *arg)
192 {
193         int ret;
194
195         do {
196                 ret = fcntl(fd, cmd, arg);
197         } while (ret == -1 && errno == EINTR);
198         return ret;
199 }
200
201 /****************************************************************************
202  Get/Set all the possible time fields from a stat struct as a timespec.
203 ****************************************************************************/
204
205 static struct timespec get_atimespec(const struct stat *pst)
206 {
207 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
208         struct timespec ret;
209
210         /* Old system - no ns timestamp. */
211         ret.tv_sec = pst->st_atime;
212         ret.tv_nsec = 0;
213         return ret;
214 #else
215 #if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
216         return pst->st_atim;
217 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
218         struct timespec ret;
219         ret.tv_sec = pst->st_atime;
220         ret.tv_nsec = pst->st_atimensec;
221         return ret;
222 #elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
223         struct timespec ret;
224         ret.tv_sec = pst->st_atime;
225         ret.tv_nsec = pst->st_atime_n;
226         return ret;
227 #elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
228         struct timespec ret;
229         ret.tv_sec = pst->st_atime;
230         ret.tv_nsec = pst->st_uatime * 1000;
231         return ret;
232 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
233         return pst->st_atimespec;
234 #else
235 #error  CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
236 #endif
237 #endif
238 }
239
240 static struct timespec get_mtimespec(const struct stat *pst)
241 {
242 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
243         struct timespec ret;
244
245         /* Old system - no ns timestamp. */
246         ret.tv_sec = pst->st_mtime;
247         ret.tv_nsec = 0;
248         return ret;
249 #else
250 #if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
251         return pst->st_mtim;
252 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
253         struct timespec ret;
254         ret.tv_sec = pst->st_mtime;
255         ret.tv_nsec = pst->st_mtimensec;
256         return ret;
257 #elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
258         struct timespec ret;
259         ret.tv_sec = pst->st_mtime;
260         ret.tv_nsec = pst->st_mtime_n;
261         return ret;
262 #elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
263         struct timespec ret;
264         ret.tv_sec = pst->st_mtime;
265         ret.tv_nsec = pst->st_umtime * 1000;
266         return ret;
267 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
268         return pst->st_mtimespec;
269 #else
270 #error  CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
271 #endif
272 #endif
273 }
274
275 static struct timespec get_ctimespec(const struct stat *pst)
276 {
277 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
278         struct timespec ret;
279
280         /* Old system - no ns timestamp. */
281         ret.tv_sec = pst->st_ctime;
282         ret.tv_nsec = 0;
283         return ret;
284 #else
285 #if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
286         return pst->st_ctim;
287 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
288         struct timespec ret;
289         ret.tv_sec = pst->st_ctime;
290         ret.tv_nsec = pst->st_ctimensec;
291         return ret;
292 #elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
293         struct timespec ret;
294         ret.tv_sec = pst->st_ctime;
295         ret.tv_nsec = pst->st_ctime_n;
296         return ret;
297 #elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
298         struct timespec ret;
299         ret.tv_sec = pst->st_ctime;
300         ret.tv_nsec = pst->st_uctime * 1000;
301         return ret;
302 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
303         return pst->st_ctimespec;
304 #else
305 #error  CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
306 #endif
307 #endif
308 }
309
310 /****************************************************************************
311  Return the best approximation to a 'create time' under UNIX from a stat
312  structure.
313 ****************************************************************************/
314
315 static struct timespec calc_create_time_stat(const struct stat *st)
316 {
317         struct timespec ret, ret1;
318         struct timespec c_time = get_ctimespec(st);
319         struct timespec m_time = get_mtimespec(st);
320         struct timespec a_time = get_atimespec(st);
321
322         ret = timespec_compare(&c_time, &m_time) < 0 ? c_time : m_time;
323         ret1 = timespec_compare(&ret, &a_time) < 0 ? ret : a_time;
324
325         if(!null_timespec(ret1)) {
326                 return ret1;
327         }
328
329         /*
330          * One of ctime, mtime or atime was zero (probably atime).
331          * Just return MIN(ctime, mtime).
332          */
333         return ret;
334 }
335
336 /****************************************************************************
337  Return the best approximation to a 'create time' under UNIX from a stat_ex
338  structure.
339 ****************************************************************************/
340
341 static struct timespec calc_create_time_stat_ex(const struct stat_ex *st)
342 {
343         struct timespec ret, ret1;
344         struct timespec c_time = st->st_ex_ctime;
345         struct timespec m_time = st->st_ex_mtime;
346         struct timespec a_time = st->st_ex_atime;
347
348         ret = timespec_compare(&c_time, &m_time) < 0 ? c_time : m_time;
349         ret1 = timespec_compare(&ret, &a_time) < 0 ? ret : a_time;
350
351         if(!null_timespec(ret1)) {
352                 return ret1;
353         }
354
355         /*
356          * One of ctime, mtime or atime was zero (probably atime).
357          * Just return MIN(ctime, mtime).
358          */
359         return ret;
360 }
361
362 /****************************************************************************
363  Return the 'create time' from a stat struct if it exists (birthtime) or else
364  use the best approximation.
365 ****************************************************************************/
366
367 static void make_create_timespec(const struct stat *pst, struct stat_ex *dst,
368                                  bool fake_dir_create_times)
369 {
370         if (S_ISDIR(pst->st_mode) && fake_dir_create_times) {
371                 dst->st_ex_btime.tv_sec = 315493200L;          /* 1/1/1980 */
372                 dst->st_ex_btime.tv_nsec = 0;
373         }
374
375         dst->st_ex_calculated_birthtime = false;
376
377 #if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
378         dst->st_ex_btime = pst->st_birthtimespec;
379 #elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
380         dst->st_ex_btime.tv_sec = pst->st_birthtime;
381         dst->st_ex_btime.tv_nsec = pst->st_birthtimenspec;
382 #elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
383         dst->st_ex_btime.tv_sec = pst->st_birthtime;
384         dst->st_ex_btime.tv_nsec = 0;
385 #else
386         dst->st_ex_btime = calc_create_time_stat(pst);
387         dst->st_ex_calculated_birthtime = true;
388 #endif
389
390         /* Deal with systems that don't initialize birthtime correctly.
391          * Pointed out by SATOH Fumiyasu <fumiyas@osstech.jp>.
392          */
393         if (null_timespec(dst->st_ex_btime)) {
394                 dst->st_ex_btime = calc_create_time_stat(pst);
395                 dst->st_ex_calculated_birthtime = true;
396         }
397 }
398
399 /****************************************************************************
400  If we update a timestamp in a stat_ex struct we may have to recalculate
401  the birthtime. For now only implement this for write time, but we may
402  also need to do it for atime and ctime. JRA.
403 ****************************************************************************/
404
405 void update_stat_ex_mtime(struct stat_ex *dst,
406                                 struct timespec write_ts)
407 {
408         dst->st_ex_mtime = write_ts;
409
410         /* We may have to recalculate btime. */
411         if (dst->st_ex_calculated_birthtime) {
412                 dst->st_ex_btime = calc_create_time_stat_ex(dst);
413         }
414 }
415
416 void update_stat_ex_create_time(struct stat_ex *dst,
417                                 struct timespec create_time)
418 {
419         dst->st_ex_btime = create_time;
420         dst->st_ex_calculated_birthtime = false;
421 }
422
423 void init_stat_ex_from_stat (struct stat_ex *dst,
424                             const struct stat *src,
425                             bool fake_dir_create_times)
426 {
427         dst->st_ex_dev = src->st_dev;
428         dst->st_ex_ino = src->st_ino;
429         dst->st_ex_mode = src->st_mode;
430         dst->st_ex_nlink = src->st_nlink;
431         dst->st_ex_uid = src->st_uid;
432         dst->st_ex_gid = src->st_gid;
433         dst->st_ex_rdev = src->st_rdev;
434         dst->st_ex_size = src->st_size;
435         dst->st_ex_atime = get_atimespec(src);
436         dst->st_ex_mtime = get_mtimespec(src);
437         dst->st_ex_ctime = get_ctimespec(src);
438         make_create_timespec(src, dst, fake_dir_create_times);
439 #ifdef HAVE_STAT_ST_BLKSIZE
440         dst->st_ex_blksize = src->st_blksize;
441 #else
442         dst->st_ex_blksize = STAT_ST_BLOCKSIZE;
443 #endif
444
445 #ifdef HAVE_STAT_ST_BLOCKS
446         dst->st_ex_blocks = src->st_blocks;
447 #else
448         dst->st_ex_blocks = src->st_size / dst->st_ex_blksize + 1;
449 #endif
450
451 #ifdef HAVE_STAT_ST_FLAGS
452         dst->st_ex_flags = src->st_flags;
453 #else
454         dst->st_ex_flags = 0;
455 #endif
456 }
457
458 /*******************************************************************
459 A stat() wrapper.
460 ********************************************************************/
461
462 int sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf,
463              bool fake_dir_create_times)
464 {
465         int ret;
466         struct stat statbuf;
467         ret = stat(fname, &statbuf);
468         if (ret == 0) {
469                 /* we always want directories to appear zero size */
470                 if (S_ISDIR(statbuf.st_mode)) {
471                         statbuf.st_size = 0;
472                 }
473                 init_stat_ex_from_stat(sbuf, &statbuf, fake_dir_create_times);
474         }
475         return ret;
476 }
477
478 /*******************************************************************
479  An fstat() wrapper.
480 ********************************************************************/
481
482 int sys_fstat(int fd, SMB_STRUCT_STAT *sbuf, bool fake_dir_create_times)
483 {
484         int ret;
485         struct stat statbuf;
486         ret = fstat(fd, &statbuf);
487         if (ret == 0) {
488                 /* we always want directories to appear zero size */
489                 if (S_ISDIR(statbuf.st_mode)) {
490                         statbuf.st_size = 0;
491                 }
492                 init_stat_ex_from_stat(sbuf, &statbuf, fake_dir_create_times);
493         }
494         return ret;
495 }
496
497 /*******************************************************************
498  An lstat() wrapper.
499 ********************************************************************/
500
501 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf,
502               bool fake_dir_create_times)
503 {
504         int ret;
505         struct stat statbuf;
506         ret = lstat(fname, &statbuf);
507         if (ret == 0) {
508                 /* we always want directories to appear zero size */
509                 if (S_ISDIR(statbuf.st_mode)) {
510                         statbuf.st_size = 0;
511                 }
512                 init_stat_ex_from_stat(sbuf, &statbuf, fake_dir_create_times);
513         }
514         return ret;
515 }
516
517 /*******************************************************************
518  An posix_fallocate() wrapper.
519 ********************************************************************/
520 int sys_posix_fallocate(int fd, off_t offset, off_t len)
521 {
522 #if defined(HAVE_POSIX_FALLOCATE) && !defined(HAVE_BROKEN_POSIX_FALLOCATE)
523         return posix_fallocate(fd, offset, len);
524 #elif defined(F_RESVSP64)
525         /* this handles XFS on IRIX */
526         struct flock64 fl;
527         off_t new_len = offset + len;
528         int ret;
529         struct stat64 sbuf;
530
531         /* unlikely to get a too large file on a 64bit system but ... */
532         if (new_len < 0)
533                 return EFBIG;
534
535         fl.l_whence = SEEK_SET;
536         fl.l_start = offset;
537         fl.l_len = len;
538
539         ret=fcntl(fd, F_RESVSP64, &fl);
540
541         if (ret != 0)
542                 return errno;
543
544         /* Make sure the file gets enlarged after we allocated space: */
545         fstat64(fd, &sbuf);
546         if (new_len > sbuf.st_size)
547                 ftruncate64(fd, new_len);
548         return 0;
549 #else
550         return ENOSYS;
551 #endif
552 }
553
554 /*******************************************************************
555  An fallocate() function that matches the semantics of the Linux one.
556 ********************************************************************/
557
558 #ifdef HAVE_LINUX_FALLOC_H
559 #include <linux/falloc.h>
560 #endif
561
562 int sys_fallocate(int fd, enum vfs_fallocate_mode mode, off_t offset, off_t len)
563 {
564 #if defined(HAVE_LINUX_FALLOCATE64) || defined(HAVE_LINUX_FALLOCATE)
565         int lmode;
566         switch (mode) {
567         case VFS_FALLOCATE_EXTEND_SIZE:
568                 lmode = 0;
569                 break;
570         case VFS_FALLOCATE_KEEP_SIZE:
571                 lmode = FALLOC_FL_KEEP_SIZE;
572                 break;
573         default:
574                 errno = EINVAL;
575                 return -1;
576         }
577 #if defined(HAVE_LINUX_FALLOCATE)
578         return fallocate(fd, lmode, offset, len);
579 #endif
580 #else
581         /* TODO - plumb in fallocate from other filesysetms like VXFS etc. JRA. */
582         errno = ENOSYS;
583         return -1;
584 #endif
585 }
586
587 #if HAVE_KERNEL_SHARE_MODES
588 #ifndef LOCK_MAND
589 #define LOCK_MAND       32      /* This is a mandatory flock */
590 #define LOCK_READ       64      /* ... Which allows concurrent read operations */
591 #define LOCK_WRITE      128     /* ... Which allows concurrent write operations */
592 #define LOCK_RW         192     /* ... Which allows concurrent read & write ops */
593 #endif
594 #endif
595
596 /*******************************************************************
597  A flock() wrapper that will perform the kernel flock.
598 ********************************************************************/
599
600 void kernel_flock(int fd, uint32 share_mode, uint32 access_mask)
601 {
602 #if HAVE_KERNEL_SHARE_MODES
603         int kernel_mode = 0;
604         if (share_mode == FILE_SHARE_WRITE) {
605                 kernel_mode = LOCK_MAND|LOCK_WRITE;
606         } else if (share_mode == FILE_SHARE_READ) {
607                 kernel_mode = LOCK_MAND|LOCK_READ;
608         } else if (share_mode == FILE_SHARE_NONE) {
609                 kernel_mode = LOCK_MAND;
610         }
611         if (kernel_mode) {
612                 flock(fd, kernel_mode);
613         }
614 #endif
615         ;
616 }
617
618
619
620 /*******************************************************************
621  An fdopendir wrapper.
622  Ugly hack - we need dirfd for this to work correctly in the
623  calling code.. JRA.
624 ********************************************************************/
625
626 DIR *sys_fdopendir(int fd)
627 {
628 #if defined(HAVE_FDOPENDIR) && defined(HAVE_DIRFD)
629         return fdopendir(fd);
630 #else
631         errno = ENOSYS;
632         return NULL;
633 #endif
634 }
635
636 /*******************************************************************
637  An mknod() wrapper.
638 ********************************************************************/
639
640 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
641 {
642 #if defined(HAVE_MKNOD)
643         return mknod(path, mode, dev);
644 #else
645         /* No mknod system call. */
646         errno = ENOSYS;
647         return -1;
648 #endif
649 }
650
651 /*******************************************************************
652 The wait() calls vary between systems
653 ********************************************************************/
654
655 int sys_waitpid(pid_t pid,int *status,int options)
656 {
657 #ifdef HAVE_WAITPID
658         return waitpid(pid,status,options);
659 #else /* HAVE_WAITPID */
660         return wait4(pid, status, options, NULL);
661 #endif /* HAVE_WAITPID */
662 }
663
664 /*******************************************************************
665  System wrapper for getwd. Always returns MALLOC'ed memory, or NULL
666  on error (malloc fail usually).
667 ********************************************************************/
668
669 char *sys_getwd(void)
670 {
671 #ifdef GETCWD_TAKES_NULL
672         return getcwd(NULL, 0);
673 #elif HAVE_GETCWD
674         char *wd = NULL, *s = NULL;
675         size_t allocated = PATH_MAX;
676
677         while (1) {
678                 s = SMB_REALLOC_ARRAY(s, char, allocated);
679                 if (s == NULL) {
680                         return NULL;
681                 }
682                 wd = getcwd(s, allocated);
683                 if (wd) {
684                         break;
685                 }
686                 if (errno != ERANGE) {
687                         SAFE_FREE(s);
688                         break;
689                 }
690                 allocated *= 2;
691                 if (allocated < PATH_MAX) {
692                         SAFE_FREE(s);
693                         break;
694                 }
695         }
696         return wd;
697 #else
698         char *s = SMB_MALLOC_ARRAY(char, PATH_MAX);
699         if (s == NULL) {
700                 return NULL;
701         }
702         return getwd(s);
703 #endif
704 }
705
706 #if defined(HAVE_POSIX_CAPABILITIES)
707
708 /**************************************************************************
709  Try and abstract process capabilities (for systems that have them).
710 ****************************************************************************/
711
712 /* Set the POSIX capabilities needed for the given purpose into the effective
713  * capability set of the current process. Make sure they are always removed
714  * from the inheritable set, because there is no circumstance in which our
715  * children should inherit our elevated privileges.
716  */
717 static bool set_process_capability(enum smbd_capability capability,
718                                    bool enable)
719 {
720         cap_value_t cap_vals[2] = {0};
721         int num_cap_vals = 0;
722
723         cap_t cap;
724
725 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
726         /* On Linux, make sure that any capabilities we grab are sticky
727          * across UID changes. We expect that this would allow us to keep both
728          * the effective and permitted capability sets, but as of circa 2.6.16,
729          * only the permitted set is kept. It is a bug (which we work around)
730          * that the effective set is lost, but we still require the effective
731          * set to be kept.
732          */
733         if (!prctl(PR_GET_KEEPCAPS)) {
734                 prctl(PR_SET_KEEPCAPS, 1);
735         }
736 #endif
737
738         cap = cap_get_proc();
739         if (cap == NULL) {
740                 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
741                         strerror(errno)));
742                 return False;
743         }
744
745         switch (capability) {
746                 case KERNEL_OPLOCK_CAPABILITY:
747 #ifdef CAP_NETWORK_MGT
748                         /* IRIX has CAP_NETWORK_MGT for oplocks. */
749                         cap_vals[num_cap_vals++] = CAP_NETWORK_MGT;
750 #endif
751                         break;
752                 case DMAPI_ACCESS_CAPABILITY:
753 #ifdef CAP_DEVICE_MGT
754                         /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
755                         cap_vals[num_cap_vals++] = CAP_DEVICE_MGT;
756 #elif CAP_MKNOD
757                         /* Linux has CAP_MKNOD for DMAPI access. */
758                         cap_vals[num_cap_vals++] = CAP_MKNOD;
759 #endif
760                         break;
761                 case LEASE_CAPABILITY:
762 #ifdef CAP_LEASE
763                         cap_vals[num_cap_vals++] = CAP_LEASE;
764 #endif
765                         break;
766         }
767
768         SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals));
769
770         if (num_cap_vals == 0) {
771                 cap_free(cap);
772                 return True;
773         }
774
775         cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
776                 enable ? CAP_SET : CAP_CLEAR);
777
778         /* We never want to pass capabilities down to our children, so make
779          * sure they are not inherited.
780          */
781         cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
782
783         if (cap_set_proc(cap) == -1) {
784                 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
785                         strerror(errno)));
786                 cap_free(cap);
787                 return False;
788         }
789
790         cap_free(cap);
791         return True;
792 }
793
794 #endif /* HAVE_POSIX_CAPABILITIES */
795
796 /****************************************************************************
797  Gain the oplock capability from the kernel if possible.
798 ****************************************************************************/
799
800 void set_effective_capability(enum smbd_capability capability)
801 {
802 #if defined(HAVE_POSIX_CAPABILITIES)
803         set_process_capability(capability, True);
804 #endif /* HAVE_POSIX_CAPABILITIES */
805 }
806
807 void drop_effective_capability(enum smbd_capability capability)
808 {
809 #if defined(HAVE_POSIX_CAPABILITIES)
810         set_process_capability(capability, False);
811 #endif /* HAVE_POSIX_CAPABILITIES */
812 }
813
814 /**************************************************************************
815  Wrapper for random().
816 ****************************************************************************/
817
818 long sys_random(void)
819 {
820 #if defined(HAVE_RANDOM)
821         return (long)random();
822 #elif defined(HAVE_RAND)
823         return (long)rand();
824 #else
825         DEBUG(0,("Error - no random function available !\n"));
826         exit(1);
827 #endif
828 }
829
830 /**************************************************************************
831  Wrapper for srandom().
832 ****************************************************************************/
833
834 void sys_srandom(unsigned int seed)
835 {
836 #if defined(HAVE_SRANDOM)
837         srandom(seed);
838 #elif defined(HAVE_SRAND)
839         srand(seed);
840 #else
841         DEBUG(0,("Error - no srandom function available !\n"));
842         exit(1);
843 #endif
844 }
845
846 #ifndef NGROUPS_MAX
847 #define NGROUPS_MAX 32 /* Guess... */
848 #endif
849
850 /**************************************************************************
851  Returns equivalent to NGROUPS_MAX - using sysconf if needed.
852 ****************************************************************************/
853
854 int groups_max(void)
855 {
856 #if defined(SYSCONF_SC_NGROUPS_MAX)
857         int ret = sysconf(_SC_NGROUPS_MAX);
858         return (ret == -1) ? NGROUPS_MAX : ret;
859 #else
860         return NGROUPS_MAX;
861 #endif
862 }
863
864 /**************************************************************************
865  Wrap setgroups and getgroups for systems that declare getgroups() as
866  returning an array of gid_t, but actuall return an array of int.
867 ****************************************************************************/
868
869 #if defined(HAVE_BROKEN_GETGROUPS)
870
871 #ifdef HAVE_BROKEN_GETGROUPS
872 #define GID_T int
873 #else
874 #define GID_T gid_t
875 #endif
876
877 static int sys_broken_getgroups(int setlen, gid_t *gidset)
878 {
879         GID_T gid;
880         GID_T *group_list;
881         int i, ngroups;
882
883         if(setlen == 0) {
884                 return getgroups(setlen, &gid);
885         }
886
887         /*
888          * Broken case. We need to allocate a
889          * GID_T array of size setlen.
890          */
891
892         if(setlen < 0) {
893                 errno = EINVAL; 
894                 return -1;
895         } 
896
897         if (setlen == 0)
898                 setlen = groups_max();
899
900         if((group_list = SMB_MALLOC_ARRAY(GID_T, setlen)) == NULL) {
901                 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
902                 return -1;
903         }
904
905         if((ngroups = getgroups(setlen, group_list)) < 0) {
906                 int saved_errno = errno;
907                 SAFE_FREE(group_list);
908                 errno = saved_errno;
909                 return -1;
910         }
911
912         for(i = 0; i < ngroups; i++)
913                 gidset[i] = (gid_t)group_list[i];
914
915         SAFE_FREE(group_list);
916         return ngroups;
917 }
918
919 static int sys_broken_setgroups(int setlen, gid_t *gidset)
920 {
921         GID_T *group_list;
922         int i ; 
923
924         if (setlen == 0)
925                 return 0 ;
926
927         if (setlen < 0 || setlen > groups_max()) {
928                 errno = EINVAL; 
929                 return -1;   
930         }
931
932         /*
933          * Broken case. We need to allocate a
934          * GID_T array of size setlen.
935          */
936
937         if((group_list = SMB_MALLOC_ARRAY(GID_T, setlen)) == NULL) {
938                 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
939                 return -1;    
940         }
941
942         for(i = 0; i < setlen; i++) 
943                 group_list[i] = (GID_T) gidset[i]; 
944
945         if(setgroups(setlen, group_list) != 0) {
946                 int saved_errno = errno;
947                 SAFE_FREE(group_list);
948                 errno = saved_errno;
949                 return -1;
950         }
951
952         SAFE_FREE(group_list);
953         return 0 ;
954 }
955
956 #endif /* HAVE_BROKEN_GETGROUPS */
957
958 /* This is a list of systems that require the first GID passed to setgroups(2)
959  * to be the effective GID. If your system is one of these, add it here.
960  */
961 #if defined (FREEBSD) || defined (DARWINOS)
962 #define USE_BSD_SETGROUPS
963 #endif
964
965 #if defined(USE_BSD_SETGROUPS)
966 /* Depending on the particular BSD implementation, the first GID that is
967  * passed to setgroups(2) will either be ignored or will set the credential's
968  * effective GID. In either case, the right thing to do is to guarantee that
969  * gidset[0] is the effective GID.
970  */
971 static int sys_bsd_setgroups(gid_t primary_gid, int setlen, const gid_t *gidset)
972 {
973         gid_t *new_gidset = NULL;
974         int max;
975         int ret;
976
977         /* setgroups(2) will fail with EINVAL if we pass too many groups. */
978         max = groups_max();
979
980         /* No group list, just make sure we are setting the efective GID. */
981         if (setlen == 0) {
982                 return setgroups(1, &primary_gid);
983         }
984
985         /* If the primary gid is not the first array element, grow the array
986          * and insert it at the front.
987          */
988         if (gidset[0] != primary_gid) {
989                 new_gidset = SMB_MALLOC_ARRAY(gid_t, setlen + 1);
990                 if (new_gidset == NULL) {
991                         return -1;
992                 }
993
994                 memcpy(new_gidset + 1, gidset, (setlen * sizeof(gid_t)));
995                 new_gidset[0] = primary_gid;
996                 setlen++;
997         }
998
999         if (setlen > max) {
1000                 DEBUG(3, ("forced to truncate group list from %d to %d\n",
1001                         setlen, max));
1002                 setlen = max;
1003         }
1004
1005 #if defined(HAVE_BROKEN_GETGROUPS)
1006         ret = sys_broken_setgroups(setlen, new_gidset ? new_gidset : gidset);
1007 #else
1008         ret = setgroups(setlen, new_gidset ? new_gidset : gidset);
1009 #endif
1010
1011         if (new_gidset) {
1012                 int errsav = errno;
1013                 SAFE_FREE(new_gidset);
1014                 errno = errsav;
1015         }
1016
1017         return ret;
1018 }
1019
1020 #endif /* USE_BSD_SETGROUPS */
1021
1022 /**************************************************************************
1023  Wrapper for getgroups. Deals with broken (int) case.
1024 ****************************************************************************/
1025
1026 int sys_getgroups(int setlen, gid_t *gidset)
1027 {
1028 #if defined(HAVE_BROKEN_GETGROUPS)
1029         return sys_broken_getgroups(setlen, gidset);
1030 #else
1031         return getgroups(setlen, gidset);
1032 #endif
1033 }
1034
1035 /**************************************************************************
1036  Wrapper for setgroups. Deals with broken (int) case and BSD case.
1037 ****************************************************************************/
1038
1039 int sys_setgroups(gid_t UNUSED(primary_gid), int setlen, gid_t *gidset)
1040 {
1041 #if !defined(HAVE_SETGROUPS)
1042         errno = ENOSYS;
1043         return -1;
1044 #endif /* HAVE_SETGROUPS */
1045
1046 #if defined(USE_BSD_SETGROUPS)
1047         return sys_bsd_setgroups(primary_gid, setlen, gidset);
1048 #elif defined(HAVE_BROKEN_GETGROUPS)
1049         return sys_broken_setgroups(setlen, gidset);
1050 #else
1051         return setgroups(setlen, gidset);
1052 #endif
1053 }
1054
1055 /**************************************************************************
1056  Extract a command into an arg list.
1057 ****************************************************************************/
1058
1059 static char **extract_args(TALLOC_CTX *mem_ctx, const char *command)
1060 {
1061         char *trunc_cmd;
1062         char *saveptr;
1063         char *ptr;
1064         int argcl;
1065         char **argl = NULL;
1066         int i;
1067
1068         if (!(trunc_cmd = talloc_strdup(mem_ctx, command))) {
1069                 DEBUG(0, ("talloc failed\n"));
1070                 goto nomem;
1071         }
1072
1073         if(!(ptr = strtok_r(trunc_cmd, " \t", &saveptr))) {
1074                 TALLOC_FREE(trunc_cmd);
1075                 errno = EINVAL;
1076                 return NULL;
1077         }
1078
1079         /*
1080          * Count the args.
1081          */
1082
1083         for( argcl = 1; ptr; ptr = strtok_r(NULL, " \t", &saveptr))
1084                 argcl++;
1085
1086         TALLOC_FREE(trunc_cmd);
1087
1088         if (!(argl = talloc_array(mem_ctx, char *, argcl + 1))) {
1089                 goto nomem;
1090         }
1091
1092         /*
1093          * Now do the extraction.
1094          */
1095
1096         if (!(trunc_cmd = talloc_strdup(mem_ctx, command))) {
1097                 goto nomem;
1098         }
1099
1100         ptr = strtok_r(trunc_cmd, " \t", &saveptr);
1101         i = 0;
1102
1103         if (!(argl[i++] = talloc_strdup(argl, ptr))) {
1104                 goto nomem;
1105         }
1106
1107         while((ptr = strtok_r(NULL, " \t", &saveptr)) != NULL) {
1108
1109                 if (!(argl[i++] = talloc_strdup(argl, ptr))) {
1110                         goto nomem;
1111                 }
1112         }
1113
1114         argl[i++] = NULL;
1115         TALLOC_FREE(trunc_cmd);
1116         return argl;
1117
1118  nomem:
1119         DEBUG(0, ("talloc failed\n"));
1120         TALLOC_FREE(trunc_cmd);
1121         TALLOC_FREE(argl);
1122         errno = ENOMEM;
1123         return NULL;
1124 }
1125
1126 /**************************************************************************
1127  Wrapper for popen. Safer as it doesn't search a path.
1128  Modified from the glibc sources.
1129  modified by tridge to return a file descriptor. We must kick our FILE* habit
1130 ****************************************************************************/
1131
1132 typedef struct _popen_list
1133 {
1134         int fd;
1135         pid_t child_pid;
1136         struct _popen_list *next;
1137 } popen_list;
1138
1139 static popen_list *popen_chain;
1140
1141 int sys_popen(const char *command)
1142 {
1143         int parent_end, child_end;
1144         int pipe_fds[2];
1145         popen_list *entry = NULL;
1146         char **argl = NULL;
1147
1148         if (pipe(pipe_fds) < 0)
1149                 return -1;
1150
1151         parent_end = pipe_fds[0];
1152         child_end = pipe_fds[1];
1153
1154         if (!*command) {
1155                 errno = EINVAL;
1156                 goto err_exit;
1157         }
1158
1159         if((entry = SMB_MALLOC_P(popen_list)) == NULL)
1160                 goto err_exit;
1161
1162         ZERO_STRUCTP(entry);
1163
1164         /*
1165          * Extract the command and args into a NULL terminated array.
1166          */
1167
1168         if(!(argl = extract_args(NULL, command)))
1169                 goto err_exit;
1170
1171         entry->child_pid = fork();
1172
1173         if (entry->child_pid == -1) {
1174                 goto err_exit;
1175         }
1176
1177         if (entry->child_pid == 0) {
1178
1179                 /*
1180                  * Child !
1181                  */
1182
1183                 int child_std_end = STDOUT_FILENO;
1184                 popen_list *p;
1185
1186                 close(parent_end);
1187                 if (child_end != child_std_end) {
1188                         dup2 (child_end, child_std_end);
1189                         close (child_end);
1190                 }
1191
1192                 /*
1193                  * POSIX.2:  "popen() shall ensure that any streams from previous
1194                  * popen() calls that remain open in the parent process are closed
1195                  * in the new child process."
1196                  */
1197
1198                 for (p = popen_chain; p; p = p->next)
1199                         close(p->fd);
1200
1201                 execv(argl[0], argl);
1202                 _exit (127);
1203         }
1204
1205         /*
1206          * Parent.
1207          */
1208
1209         close (child_end);
1210         TALLOC_FREE(argl);
1211
1212         /* Link into popen_chain. */
1213         entry->next = popen_chain;
1214         popen_chain = entry;
1215         entry->fd = parent_end;
1216
1217         return entry->fd;
1218
1219 err_exit:
1220
1221         SAFE_FREE(entry);
1222         TALLOC_FREE(argl);
1223         close(pipe_fds[0]);
1224         close(pipe_fds[1]);
1225         return -1;
1226 }
1227
1228 /**************************************************************************
1229  Wrapper for pclose. Modified from the glibc sources.
1230 ****************************************************************************/
1231
1232 int sys_pclose(int fd)
1233 {
1234         int wstatus;
1235         popen_list **ptr = &popen_chain;
1236         popen_list *entry = NULL;
1237         pid_t wait_pid;
1238         int status = -1;
1239
1240         /* Unlink from popen_chain. */
1241         for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1242                 if ((*ptr)->fd == fd) {
1243                         entry = *ptr;
1244                         *ptr = (*ptr)->next;
1245                         status = 0;
1246                         break;
1247                 }
1248         }
1249
1250         if (status < 0 || close(entry->fd) < 0)
1251                 return -1;
1252
1253         /*
1254          * As Samba is catching and eating child process
1255          * exits we don't really care about the child exit
1256          * code, a -1 with errno = ECHILD will do fine for us.
1257          */
1258
1259         do {
1260                 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1261         } while (wait_pid == -1 && errno == EINTR);
1262
1263         SAFE_FREE(entry);
1264
1265         if (wait_pid == -1)
1266                 return -1;
1267         return wstatus;
1268 }
1269
1270 /**************************************************************************
1271  Wrapper for Admin Logs.
1272 ****************************************************************************/
1273
1274  void sys_adminlog(int priority, const char *format_str, ...) 
1275 {
1276         va_list ap;
1277         int ret;
1278         char *msgbuf = NULL;
1279
1280         va_start( ap, format_str );
1281         ret = vasprintf( &msgbuf, format_str, ap );
1282         va_end( ap );
1283
1284         if (ret == -1)
1285                 return;
1286
1287 #if defined(HAVE_SYSLOG)
1288         syslog( priority, "%s", msgbuf );
1289 #else
1290         DEBUG(0,("%s", msgbuf ));
1291 #endif
1292         SAFE_FREE(msgbuf);
1293 }
1294
1295 /****************************************************************************
1296  Return the major devicenumber for UNIX extensions.
1297 ****************************************************************************/
1298
1299 uint32 unix_dev_major(SMB_DEV_T dev)
1300 {
1301 #if defined(HAVE_DEVICE_MAJOR_FN)
1302         return (uint32)major(dev);
1303 #else
1304         return (uint32)(dev >> 8);
1305 #endif
1306 }
1307
1308 /****************************************************************************
1309  Return the minor devicenumber for UNIX extensions.
1310 ****************************************************************************/
1311
1312 uint32 unix_dev_minor(SMB_DEV_T dev)
1313 {
1314 #if defined(HAVE_DEVICE_MINOR_FN)
1315         return (uint32)minor(dev);
1316 #else
1317         return (uint32)(dev & 0xff);
1318 #endif
1319 }
1320
1321 #if 0
1322 /*******************************************************************
1323  Return the number of CPUs.
1324 ********************************************************************/
1325
1326 int sys_get_number_of_cores(void)
1327 {
1328         int ret = -1;
1329
1330 #if defined(HAVE_SYSCONF)
1331 #if defined(_SC_NPROCESSORS_ONLN)
1332         ret = (int)sysconf(_SC_NPROCESSORS_ONLN);
1333 #endif
1334 #if defined(_SC_NPROCESSORS_CONF)
1335         if (ret < 1) {
1336                 ret = (int)sysconf(_SC_NPROCESSORS_CONF);
1337         }
1338 #endif
1339 #elif defined(HAVE_SYSCTL) && defined(CTL_HW)
1340         int name[2];
1341         unsigned int len = sizeof(ret);
1342
1343         name[0] = CTL_HW;
1344 #if defined(HW_AVAILCPU)
1345         name[1] = HW_AVAILCPU;
1346
1347         if (sysctl(name, 2, &ret, &len, NULL, 0) == -1) {
1348                 ret = -1;
1349         }
1350 #endif
1351 #if defined(HW_NCPU)
1352         if(ret < 1) {
1353                 name[0] = CTL_HW;
1354                 name[1] = HW_NCPU;
1355                 if (sysctl(nm, 2, &count, &len, NULL, 0) == -1) {
1356                         ret = -1;
1357                 }
1358         }
1359 #endif
1360 #endif
1361         if (ret < 1) {
1362                 ret = 1;
1363         }
1364         return ret;
1365 }
1366 #endif
1367
1368 #if defined(HAVE_AIO)
1369
1370 /*******************************************************************
1371  An aio_read wrapper.
1372 ********************************************************************/
1373
1374 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
1375 {
1376 #if defined(HAVE_AIO_READ)
1377         return aio_read(aiocb);
1378 #else
1379         errno = ENOSYS;
1380         return -1;
1381 #endif
1382 }
1383
1384 /*******************************************************************
1385  An aio_write wrapper.
1386 ********************************************************************/
1387
1388 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
1389 {
1390 #if defined(HAVE_AIO_WRITE)
1391         return aio_write(aiocb);
1392 #else
1393         errno = ENOSYS;
1394         return -1;
1395 #endif
1396 }
1397
1398 /*******************************************************************
1399  An aio_return wrapper.
1400 ********************************************************************/
1401
1402 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
1403 {
1404 #if defined(HAVE_AIO_RETURN)
1405         return aio_return(aiocb);
1406 #else
1407         errno = ENOSYS;
1408         return -1;
1409 #endif
1410 }
1411
1412 /*******************************************************************
1413  An aio_cancel wrapper.
1414 ********************************************************************/
1415
1416 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
1417 {
1418 #if defined(HAVE_AIO_CANCEL)
1419         return aio_cancel(fd, aiocb);
1420 #else
1421         errno = ENOSYS;
1422         return -1;
1423 #endif
1424 }
1425
1426 /*******************************************************************
1427  An aio_error wrapper.
1428 ********************************************************************/
1429
1430 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
1431 {
1432 #if defined(HAVE_AIO_ERROR)
1433         return aio_error(aiocb);
1434 #else
1435         errno = ENOSYS;
1436         return -1;
1437 #endif
1438 }
1439
1440 /*******************************************************************
1441  An aio_fsync wrapper.
1442 ********************************************************************/
1443
1444 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
1445 {
1446 #if defined(HAVE_AIO_FSYNC)
1447         return aio_fsync(op, aiocb);
1448 #else
1449         errno = ENOSYS;
1450         return -1;
1451 #endif
1452 }
1453
1454 /*******************************************************************
1455  An aio_fsync wrapper.
1456 ********************************************************************/
1457
1458 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
1459 {
1460 #if defined(HAVE_AIO_FSYNC)
1461         return aio_suspend(cblist, n, timeout);
1462 #else
1463         errno = ENOSYS;
1464         return -1;
1465 #endif
1466 }
1467 #else /* !HAVE_AIO */
1468
1469 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
1470 {
1471         errno = ENOSYS;
1472         return -1;
1473 }
1474
1475 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
1476 {
1477         errno = ENOSYS;
1478         return -1;
1479 }
1480
1481 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
1482 {
1483         errno = ENOSYS;
1484         return -1;
1485 }
1486
1487 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
1488 {
1489         errno = ENOSYS;
1490         return -1;
1491 }
1492
1493 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
1494 {
1495         errno = ENOSYS;
1496         return -1;
1497 }
1498
1499 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
1500 {
1501         errno = ENOSYS;
1502         return -1;
1503 }
1504
1505 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
1506 {
1507         errno = ENOSYS;
1508         return -1;
1509 }
1510 #endif /* HAVE_AIO */