2
Copyright Ⓒ 1997, 1998, 1999, 2000, 2001 joost witteveen
3
Copyright Ⓒ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Clint Adams
5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
16
/* #define _POSIX_C_SOURCE 199309L whatever that may mean...*/
17
/* #define _BSD_SOURCE I use strdup, S_IFDIR, etc */
19
/* Roderich Schupp writes (bug #79100):
20
/usr/include/dlfcn.h from libc6 2.2-5 defines RTLD_NEXT only
21
when compiled with _GNU_SOURCE defined. Hence libfakeroot.c doesn't pick
23
up and does a dlopen("/lib/libc.so.6",...) in get_libc().
24
This works most of the time, but explodes if you have an arch-optimized
25
libc installed: the program now has two versions of libc.so
26
(/lib/libc.so.6 and, say, /lib/i586/libc.so.6) mapped. Again for
27
some programs you might get away with this, but running bash under
29
always bombs. Simple fix:
33
#define FAKEROOT_LIBFAKEROOT
37
In this file, we want 'struct stat' to have a 32-bit 'ino_t'.
38
We use 'struct stat64' when we need a 64-bit 'ino_t'.
40
#define _DARWIN_NO_64_BIT_INODE
44
This file is for 32-bit symbols which do not have the "$UNIX2003" version.
46
#define _NONSTD_SOURCE
51
#include "communicate.h"
53
#ifdef STUPID_ALPHA_HACK
54
#define SEND_STAT(a,b,c) send_stat(a,b,c)
55
#define SEND_STAT64(a,b,c) send_stat64(a,b,c)
56
#define SEND_GET_STAT(a,b) send_get_stat(a,b)
57
#define SEND_GET_STAT64(a,b) send_get_stat64(a,b)
59
#define SEND_STAT(a,b,c) send_stat(a,b)
60
#define SEND_STAT64(a,b,c) send_stat64(a,b)
61
#define SEND_GET_STAT(a,b) send_get_stat(a)
62
#define SEND_GET_STAT64(a,b) send_get_stat64(a)
66
These INT_* (which stands for internal) macros should always be used when
67
the fakeroot library owns the storage of the stat variable.
70
#define INT_STRUCT_STAT struct stat64
71
#define INT_NEXT_STAT(a,b) NEXT_STAT64(_STAT_VER,a,b)
72
#define INT_NEXT_LSTAT(a,b) NEXT_LSTAT64(_STAT_VER,a,b)
73
#define INT_NEXT_FSTAT(a,b) NEXT_FSTAT64(_STAT_VER,a,b)
74
#define INT_NEXT_FSTATAT(a,b,c,d) NEXT_FSTATAT64(_STAT_VER,a,b,c,d)
75
#define INT_SEND_STAT(a,b) SEND_STAT64(a,b,_STAT_VER)
77
#define INT_STRUCT_STAT struct stat
78
#define INT_NEXT_STAT(a,b) NEXT_STAT(_STAT_VER,a,b)
79
#define INT_NEXT_LSTAT(a,b) NEXT_LSTAT(_STAT_VER,a,b)
80
#define INT_NEXT_FSTAT(a,b) NEXT_FSTAT(_STAT_VER,a,b)
81
#define INT_NEXT_FSTATAT(a,b,c,d) NEXT_FSTATAT(_STAT_VER,a,b,c,d)
82
#define INT_SEND_STAT(a,b) SEND_STAT(a,b,_STAT_VER)
96
#include <sys/types.h>
99
#endif /* HAVE_SYS_ACL_H */
102
#endif /* HAVE_FTS_H */
104
#if !HAVE_DECL_SETENV
105
extern int setenv (const char *name, const char *value, int replace);
107
#if !HAVE_DECL_UNSETENV
108
extern int unsetenv (const char *name);
113
Where are those shared libraries?
114
If I knew of a configure/libtool way to find that out, I'd use it. Or
115
any other way other than the method I'm using below. Does anybody know
116
how I can get that location? (BTW, symply linking a programme, and running
117
`ldd' on it isn't the option, as Digital Unix doesn't have ldd)
122
Note that LIBCPATH isn't actually used on Linux or Solaris, as RTLD_NEXT
123
is defined and we use that to get the `next_*' functions
129
/*#define LIBCPATH "/usr/shlib/libc.so"*/
137
#undef _FILE_OFFSET_BITS
141
// this structure is used in next_wrap, which is defined in
142
// wrapstruct.h, included below
155
lib= dlopen(LIBCPATH,RTLD_LAZY);
158
fprintf(stderr, "Couldn't find libc at: %s\n", LIBCPATH);
166
void load_library_symbols(void);
168
int fakeroot_disabled = 0;
169
#ifdef LIBFAKEROOT_DEBUGGING
170
int fakeroot_debug = 0;
171
#endif /* LIBFAKEROOT_DEBUGGING */
174
#include "patchattr.h"
177
#include "wraptmpf.h"
179
#include "wrapstruct.h"
182
void load_library_symbols(void){
183
/* this function loads all original functions from the C library.
184
This function is only called once.
185
I ran into problems when each function individually
186
loaded it's original counterpart, as RTLD_NEXT seems to have
187
a different meaning in files with different names than libtricks.c
188
(I.E, dlsym(RTLD_NEXT, ...) called in vsearch.c returned funtions
189
defined in libtricks */
190
/* The calling of this function itself is somewhat tricky:
191
the awk script wrapawk generates several .h files. In wraptmpf.h
192
there are temporary definitions for tmp_*, that do the call
193
to this function. The other generated .h files do even more tricky
199
#ifdef LIBFAKEROOT_DEBUGGING
200
if (getenv("FAKEROOT_DEBUG")) {
203
if (fakeroot_debug) {
204
fprintf(stderr, "load_library_symbols\n");
207
#endif /* LIBFAKEROOT_DEBUGGING */
208
for(i=0; next_wrap[i].doit; i++){
209
*(next_wrap[i].doit)=dlsym(get_libc(), next_wrap[i].name);
210
if ( (msg = dlerror()) != NULL){
211
fprintf (stderr, "dlsym(%s): %s\n", next_wrap[i].name, msg);
219
* Fake implementations for the setuid family of functions.
220
* The fake IDs are inherited by child processes via environment variables.
223
* o Privileges are not checked, which results in incorrect behaviour.
224
* Example: process changes its (real, effective and saved) uid to 1000
225
* and then tries to regain root privileges. This should normally result
226
* in an EPERM, but our implementation doesn't care...
227
* o If one of the setenv calls fails, the state may get corrupted.
232
/* Generic set/get ID functions */
234
static int env_get_id(const char *key) {
235
char *str = getenv(key);
241
static int env_set_id(const char *key, int id) {
247
snprintf(str, sizeof (str), "%d", id);
248
return setenv(key, str, 1);
252
static void read_id(unsigned int *id, const char *key) {
253
if (*id == (unsigned int)-1)
254
*id = env_get_id(key);
257
static int write_id(const char *key, int id) {
258
if (env_get_id(key) != id)
259
return env_set_id(key, id);
263
/* Fake ID storage */
265
static uid_t faked_real_uid = (uid_t)-1;
266
static gid_t faked_real_gid = (gid_t)-1;
267
static uid_t faked_effective_uid = (uid_t)-1;
268
static gid_t faked_effective_gid = (gid_t)-1;
269
static uid_t faked_saved_uid = (uid_t)-1;
270
static gid_t faked_saved_gid = (gid_t)-1;
271
static uid_t faked_fs_uid = (uid_t)-1;
272
static gid_t faked_fs_gid = (gid_t)-1;
276
static void read_real_uid() {
277
read_id(&faked_real_uid, FAKEROOTUID_ENV);
280
static void read_effective_uid() {
281
read_id(&faked_effective_uid, FAKEROOTEUID_ENV);
284
static void read_saved_uid() {
285
read_id(&faked_saved_uid, FAKEROOTSUID_ENV);
288
static void read_fs_uid() {
289
read_id(&faked_fs_uid, FAKEROOTFUID_ENV);
292
static void read_uids() {
294
read_effective_uid();
301
static void read_real_gid() {
302
read_id(&faked_real_gid, FAKEROOTGID_ENV);
305
static void read_effective_gid() {
306
read_id(&faked_effective_gid, FAKEROOTEGID_ENV);
309
static void read_saved_gid() {
310
read_id(&faked_saved_gid, FAKEROOTSGID_ENV);
313
static void read_fs_gid() {
314
read_id(&faked_fs_gid, FAKEROOTFGID_ENV);
317
static void read_gids() {
319
read_effective_gid();
326
static int write_real_uid() {
327
return write_id(FAKEROOTUID_ENV, faked_real_uid);
330
static int write_effective_uid() {
331
return write_id(FAKEROOTEUID_ENV, faked_effective_uid);
334
static int write_saved_uid() {
335
return write_id(FAKEROOTSUID_ENV, faked_saved_uid);
338
static int write_fs_uid() {
339
return write_id(FAKEROOTFUID_ENV, faked_fs_uid);
342
static int write_uids() {
343
if (write_real_uid() < 0)
345
if (write_effective_uid() < 0)
347
if (write_saved_uid() < 0)
349
if (write_fs_uid() < 0)
356
static int write_real_gid() {
357
return write_id(FAKEROOTGID_ENV, faked_real_gid);
360
static int write_effective_gid() {
361
return write_id(FAKEROOTEGID_ENV, faked_effective_gid);
364
static int write_saved_gid() {
365
return write_id(FAKEROOTSGID_ENV, faked_saved_gid);
368
static int write_fs_gid() {
369
return write_id(FAKEROOTFGID_ENV, faked_fs_gid);
372
static int write_gids() {
373
if (write_real_gid() < 0)
375
if (write_effective_gid() < 0)
377
if (write_saved_gid() < 0)
379
if (write_fs_gid() < 0)
384
/* Faked get functions */
386
static uid_t get_faked_uid() {
388
return faked_real_uid;
391
static gid_t get_faked_gid() {
393
return faked_real_gid;
396
static uid_t get_faked_euid() {
397
read_effective_uid();
398
return faked_effective_uid;
401
static gid_t get_faked_egid() {
402
read_effective_gid();
403
return faked_effective_gid;
406
static uid_t get_faked_suid() {
408
return faked_saved_uid;
411
static gid_t get_faked_sgid() {
413
return faked_saved_gid;
416
static uid_t get_faked_fsuid() {
421
static gid_t get_faked_fsgid() {
426
/* Faked set functions */
428
static int set_faked_uid(uid_t uid) {
430
if (faked_effective_uid == 0) {
431
faked_real_uid = uid;
432
faked_effective_uid = uid;
433
faked_saved_uid = uid;
435
faked_effective_uid = uid;
441
static int set_faked_gid(gid_t gid) {
443
if (faked_effective_gid == 0) {
444
faked_real_gid = gid;
445
faked_effective_gid = gid;
446
faked_saved_gid = gid;
448
faked_effective_gid = gid;
454
static int set_faked_euid(uid_t euid) {
455
read_effective_uid();
456
faked_effective_uid = euid;
459
if (write_effective_uid() < 0)
461
if (write_fs_uid() < 0)
466
static int set_faked_egid(gid_t egid) {
467
read_effective_gid();
468
faked_effective_gid = egid;
471
if (write_effective_gid() < 0)
473
if (write_fs_gid() < 0)
478
static int set_faked_reuid(uid_t ruid, uid_t euid) {
480
if (ruid != (uid_t)-1 || euid != (uid_t)-1)
481
faked_saved_uid = faked_effective_uid;
482
if (ruid != (uid_t)-1)
483
faked_real_uid = ruid;
484
if (euid != (uid_t)-1)
485
faked_effective_uid = euid;
486
faked_fs_uid = faked_effective_uid;
490
static int set_faked_regid(gid_t rgid, gid_t egid) {
492
if (rgid != (gid_t)-1 || egid != (gid_t)-1)
493
faked_saved_gid = faked_effective_gid;
494
if (rgid != (gid_t)-1)
495
faked_real_gid = rgid;
496
if (egid != (gid_t)-1)
497
faked_effective_gid = egid;
498
faked_fs_gid = faked_effective_gid;
502
#ifdef HAVE_SETRESUID
503
static int set_faked_resuid(uid_t ruid, uid_t euid, uid_t suid) {
505
if (ruid != (uid_t)-1)
506
faked_real_uid = ruid;
507
if (euid != (uid_t)-1)
508
faked_effective_uid = euid;
509
if (suid != (uid_t)-1)
510
faked_saved_uid = suid;
511
faked_fs_uid = faked_effective_uid;
516
#ifdef HAVE_SETRESGID
517
static int set_faked_resgid(gid_t rgid, gid_t egid, gid_t sgid) {
519
if (rgid != (gid_t)-1)
520
faked_real_gid = rgid;
521
if (egid != (gid_t)-1)
522
faked_effective_gid = egid;
523
if (sgid != (gid_t)-1)
524
faked_saved_gid = sgid;
525
faked_fs_gid = faked_effective_gid;
531
static uid_t set_faked_fsuid(uid_t fsuid) {
532
uid_t prev_fsuid = get_faked_fsuid();
533
faked_fs_uid = fsuid;
539
static gid_t set_faked_fsgid(gid_t fsgid) {
540
gid_t prev_fsgid = get_faked_fsgid();
541
faked_fs_gid = fsgid;
547
static int dont_try_chown(){
552
donttry=(env_var_set(FAKEROOTDONTTRYCHOWN_ENV)!=NULL);
559
/* The wrapped functions */
562
int WRAP_LSTAT LSTAT_ARG(int ver,
563
const char *file_name,
564
struct stat *statbuf){
568
#ifdef LIBFAKEROOT_DEBUGGING
569
if (fakeroot_debug) {
570
fprintf(stderr, "lstat file_name %s\n", file_name);
572
#endif /* LIBFAKEROOT_DEBUGGING */
573
r=NEXT_LSTAT(ver, file_name, statbuf);
576
SEND_GET_STAT(statbuf, ver);
581
int WRAP_STAT STAT_ARG(int ver,
582
const char *file_name,
586
#ifdef LIBFAKEROOT_DEBUGGING
587
if (fakeroot_debug) {
588
fprintf(stderr, "stat file_name %s\n", file_name);
590
#endif /* LIBFAKEROOT_DEBUGGING */
591
r=NEXT_STAT(ver, file_name, st);
594
SEND_GET_STAT(st,ver);
599
int WRAP_FSTAT FSTAT_ARG(int ver,
606
#ifdef LIBFAKEROOT_DEBUGGING
607
if (fakeroot_debug) {
608
fprintf(stderr, "fstat fd %d\n", fd);
610
#endif /* LIBFAKEROOT_DEBUGGING */
611
r=NEXT_FSTAT(ver, fd, st);
614
SEND_GET_STAT(st,ver);
619
int WRAP_FSTATAT FSTATAT_ARG(int ver,
628
r=NEXT_FSTATAT(ver, dir_fd, path, st, flags);
631
SEND_GET_STAT(st,ver);
634
#endif /* HAVE_FSTATAT */
636
#ifdef STAT64_SUPPORT
638
int WRAP_LSTAT64 LSTAT64_ARG (int ver,
639
const char *file_name,
644
#ifdef LIBFAKEROOT_DEBUGGING
645
if (fakeroot_debug) {
646
fprintf(stderr, "lstat64 file_name %s\n", file_name);
648
#endif /* LIBFAKEROOT_DEBUGGING */
649
r=NEXT_LSTAT64(ver, file_name, st);
654
SEND_GET_STAT64(st,ver);
659
int WRAP_STAT64 STAT64_ARG(int ver,
660
const char *file_name,
664
#ifdef LIBFAKEROOT_DEBUGGING
665
if (fakeroot_debug) {
666
fprintf(stderr, "stat64 file_name %s\n", file_name);
668
#endif /* LIBFAKEROOT_DEBUGGING */
669
r=NEXT_STAT64(ver,file_name,st);
672
SEND_GET_STAT64(st,ver);
677
int WRAP_FSTAT64 FSTAT64_ARG(int ver,
682
#ifdef LIBFAKEROOT_DEBUGGING
683
if (fakeroot_debug) {
684
fprintf(stderr, "fstat64 fd %d\n", fd);
686
#endif /* LIBFAKEROOT_DEBUGGING */
687
r=NEXT_FSTAT64(ver, fd, st);
690
SEND_GET_STAT64(st,ver);
696
int WRAP_FSTATAT64 FSTATAT64_ARG(int ver,
705
r=NEXT_FSTATAT64(ver, dir_fd, path, st, flags);
708
SEND_GET_STAT64(st,ver);
711
#endif /* HAVE_FSTATAT */
713
#endif /* STAT64_SUPPORT */
715
/*************************************************************/
717
Wrapped functions general info:
719
In general, the structure is as follows:
720
- Then, if the function does things that (possibly) fail by
721
other users than root, allow for `fake' root privileges.
722
Do this by obtaining the inode the function works on, and then
723
informing faked (the deamon that remembers all `fake' file
724
permissions e.d.) about the intentions of the user.
725
Faked maintains a list of inodes and their respective
726
`fake' ownerships/filemodes.
727
- Or, if the function requests information that we should
728
fake, again get the inode of the file, and ask faked about the
729
ownership/filemode data it maintains for that inode.
732
/*************************************************************/
736
/* chown, lchown, fchown, chmod, fchmod, mknod functions
738
quite general. See the `Wrapped functions general info:' above
742
int chown(const char *path, uid_t owner, gid_t group){
747
#ifdef LIBFAKEROOT_DEBUGGING
748
if (fakeroot_debug) {
749
fprintf(stderr, "chown path %s owner %d group %d\n", path, owner, group);
751
#endif /* LIBFAKEROOT_DEBUGGING */
752
#ifdef LCHOWN_SUPPORT
753
/*chown(sym-link) works on the target of the symlink if lchown is
754
present and enabled.*/
755
r=INT_NEXT_STAT(path, &st);
757
/*chown(sym-link) works on the symlink itself, use lstat: */
758
r=INT_NEXT_LSTAT(path, &st);
765
INT_SEND_STAT(&st,chown_func);
766
if(!dont_try_chown())
767
r=next_lchown(path,owner,group);
770
if(r&&(errno==EPERM))
777
#ifdef LCHOWN_SUPPORT
778
int lchown(const char *path, uid_t owner, gid_t group){
782
#ifdef LIBFAKEROOT_DEBUGGING
783
if (fakeroot_debug) {
784
fprintf(stderr, "lchown path %s owner %d group %d\n", path, owner, group);
786
#endif /* LIBFAKEROOT_DEBUGGING */
787
r=INT_NEXT_LSTAT(path, &st);
792
INT_SEND_STAT(&st,chown_func);
793
if(!dont_try_chown())
794
r=next_lchown(path,owner,group);
797
if(r&&(errno==EPERM))
804
int fchown(int fd, uid_t owner, gid_t group){
808
r=INT_NEXT_FSTAT(fd, &st);
814
INT_SEND_STAT(&st, chown_func);
816
if(!dont_try_chown())
817
r=next_fchown(fd,owner,group);
821
if(r&&(errno==EPERM))
829
int fchownat(int dir_fd, const char *path, uid_t owner, gid_t group, int flags) {
831
/* If AT_SYMLINK_NOFOLLOW is set in the fchownat call it should
832
be when we stat it. */
834
r=INT_NEXT_FSTATAT(dir_fd, path, &st, (flags & AT_SYMLINK_NOFOLLOW));
841
INT_SEND_STAT(&st,chown_func);
843
if(!dont_try_chown())
844
r=next_fchownat(dir_fd,path,owner,group,flags);
848
if(r&&(errno==EPERM))
853
#endif /* HAVE_FCHOWNAT */
854
#endif /* HAVE_FSTATAT */
856
int chmod(const char *path, mode_t mode){
860
#ifdef LIBFAKEROOT_DEBUGGING
861
if (fakeroot_debug) {
862
fprintf(stderr, "chmod path %s\n", path);
864
#endif /* LIBFAKEROOT_DEBUGGING */
865
r=INT_NEXT_STAT(path, &st);
869
st.st_mode=(mode&ALLPERMS)|(st.st_mode&~ALLPERMS);
871
INT_SEND_STAT(&st, chmod_func);
873
/* if a file is unwritable, then root can still write to it
874
(no matter who owns the file). If we are fakeroot, the only
875
way to fake this is to always make the file writable, readable
876
etc for the real user (who started fakeroot). Also holds for
877
the exec bit of directories.
878
Yes, packages requering that are broken. But we have lintian
879
to get rid of broken packages, not fakeroot.
882
if(S_ISDIR(st.st_mode))
885
r=next_chmod(path, mode);
886
if(r&&(errno==EPERM))
888
#ifdef EFTYPE /* available under FreeBSD kernel */
889
if(r&&(errno==EFTYPE))
895
int fchmod(int fd, mode_t mode){
900
#ifdef LIBFAKEROOT_DEBUGGING
901
if (fakeroot_debug) {
902
fprintf(stderr, "fchmod fd %d\n", fd);
904
#endif /* LIBFAKEROOT_DEBUGGING */
905
r=INT_NEXT_FSTAT(fd, &st);
910
st.st_mode=(mode&ALLPERMS)|(st.st_mode&~ALLPERMS);
911
INT_SEND_STAT(&st,chmod_func);
913
/* see chmod() for comment */
915
if(S_ISDIR(st.st_mode))
918
r=next_fchmod(fd, mode);
919
if(r&&(errno==EPERM))
921
#ifdef EFTYPE /* available under FreeBSD kernel */
922
if(r&&(errno==EFTYPE))
930
int fchmodat(int dir_fd, const char *path, mode_t mode, int flags) {
931
/* (int fd, mode_t mode){*/
935
/* If AT_SYMLINK_NOFOLLOW is set in the fchownat call it should
936
be when we stat it. */
937
r=INT_NEXT_FSTATAT(dir_fd, path, &st, flags & AT_SYMLINK_NOFOLLOW);
942
st.st_mode=(mode&ALLPERMS)|(st.st_mode&~ALLPERMS);
943
INT_SEND_STAT(&st,chmod_func);
945
/* see chmod() for comment */
947
if(S_ISDIR(st.st_mode))
950
r=next_fchmodat(dir_fd, path, mode, flags);
951
if(r&&(errno==EPERM))
953
#ifdef EFTYPE /* available under FreeBSD kernel */
954
if(r&&(errno==EFTYPE))
959
#endif /* HAVE_FCHMODAT */
960
#endif /* HAVE_FSTATAT */
962
int WRAP_MKNOD MKNOD_ARG(int ver UNUSED,
963
const char *pathname,
964
mode_t mode, dev_t XMKNOD_FRTH_ARG dev)
967
mode_t old_mask=umask(022);
972
/*Don't bother to mknod the file, that probably doesn't work.
973
just create it as normal file, and leave the premissions
976
fd=open(pathname, O_WRONLY|O_CREAT|O_TRUNC, 00644);
982
/* get the inode, to communicate with faked */
984
r=INT_NEXT_LSTAT(pathname, &st);
989
st.st_mode= mode & ~old_mask;
990
st.st_rdev= XMKNOD_FRTH_ARG dev;
992
INT_SEND_STAT(&st,mknod_func);
999
int WRAP_MKNODAT MKNODAT_ARG(int ver UNUSED,
1001
const char *pathname,
1002
mode_t mode, dev_t XMKNODAT_FIFTH_ARG dev)
1005
mode_t old_mask=umask(022);
1010
/*Don't bother to mknod the file, that probably doesn't work.
1011
just create it as normal file, and leave the permissions
1014
fd=openat(dir_fd, pathname, O_WRONLY|O_CREAT|O_TRUNC, 00644);
1020
/* get the inode, to communicate with faked */
1022
/* The only known flag is AT_SYMLINK_NOFOLLOW and
1023
we don't want that here. */
1024
r=INT_NEXT_FSTATAT(dir_fd, pathname, &st, 0);
1029
st.st_mode= mode & ~old_mask;
1030
st.st_rdev= XMKNODAT_FIFTH_ARG dev;
1032
INT_SEND_STAT(&st,mknod_func);
1036
#endif /* HAVE_MKNODAT */
1037
#endif /* HAVE_FSTATAT */
1039
int mkdir(const char *path, mode_t mode){
1042
mode_t old_mask=umask(022);
1047
/* we need to tell the fake deamon the real mode. In order
1048
to communicate with faked we need a struct stat, so we now
1049
do a stat of the new directory (just for the inode/dev) */
1051
#ifdef LIBFAKEROOT_DEBUGGING
1052
if (fakeroot_debug) {
1053
fprintf(stderr, "mkdir path %s\n", path);
1055
#endif /* LIBFAKEROOT_DEBUGGING */
1056
r=next_mkdir(path, mode|0700);
1057
/* mode|0700: see comment in the chown() function above */
1060
r=INT_NEXT_STAT(path, &st);
1065
st.st_mode=(mode&~old_mask&ALLPERMS)|(st.st_mode&~ALLPERMS)|S_IFDIR;
1067
INT_SEND_STAT(&st, chmod_func);
1074
int mkdirat(int dir_fd, const char *path, mode_t mode){
1077
mode_t old_mask=umask(022);
1082
/* we need to tell the fake deamon the real mode. In order
1083
to communicate with faked we need a struct stat, so we now
1084
do a stat of the new directory (just for the inode/dev) */
1086
r=next_mkdirat(dir_fd, path, mode|0700);
1087
/* mode|0700: see comment in the chown() function above */
1090
r=INT_NEXT_FSTATAT(dir_fd, path, &st, 0);
1095
st.st_mode=(mode&~old_mask&ALLPERMS)|(st.st_mode&~ALLPERMS)|S_IFDIR;
1097
INT_SEND_STAT(&st, chmod_func);
1101
#endif /* HAVE_MKDIRAT */
1102
#endif /* HAVE_FSTATAT */
1105
The remove funtions: unlink, rmdir, rename.
1106
These functions can all remove inodes from the system.
1107
I need to inform faked about the removal of these inodes because
1114
In the above example, assuming that for both touch-es, the same
1115
inode is generated, faked will still report the owner of `file'
1116
as `admin', unless it's informed about the removal of the inode.
1119
int unlink(const char *pathname){
1124
r=INT_NEXT_LSTAT(pathname, &st);
1128
r=next_unlink(pathname);
1133
INT_SEND_STAT(&st, unlink_func);
1139
#ifdef HAVE_UNLINKAT
1140
int unlinkat(int dir_fd, const char *pathname, int flags){
1143
r=INT_NEXT_FSTATAT(dir_fd, pathname, &st, (flags&~AT_REMOVEDIR) | AT_SYMLINK_NOFOLLOW);
1147
r=next_unlinkat(dir_fd, pathname, flags);
1152
INT_SEND_STAT(&st, unlink_func);
1156
#endif /* HAVE_UNLINKAT */
1157
#endif /* HAVE_FSTATAT */
1160
See the `remove funtions:' comments above for more info on
1161
these remove function wrappers.
1163
int rmdir(const char *pathname){
1167
r=INT_NEXT_LSTAT(pathname, &st);
1170
r=next_rmdir(pathname);
1174
INT_SEND_STAT(&st,unlink_func);
1180
See the `remove funtions:' comments above for more info on
1181
these remove function wrappers.
1183
int remove(const char *pathname){
1187
r=INT_NEXT_LSTAT(pathname, &st);
1190
r=next_remove(pathname);
1193
INT_SEND_STAT(&st,unlink_func);
1199
if the second argument to the rename() call points to an
1200
existing file, then that file will be removed. So, we have
1201
to treat this function as one of the `remove functions'.
1203
See the `remove funtions:' comments above for more info on
1204
these remove function wrappers.
1207
int rename(const char *oldpath, const char *newpath){
1211
/* If newpath points to an existing file, that file will be
1212
unlinked. Make sure we tell the faked daemon about this! */
1214
/* we need the st_new struct in order to inform faked about the
1215
(possible) unlink of the file */
1217
r=INT_NEXT_LSTAT(newpath, &st);
1219
s=next_rename(oldpath, newpath);
1223
INT_SEND_STAT(&st,unlink_func);
1229
#ifdef HAVE_RENAMEAT
1230
int renameat(int olddir_fd, const char *oldpath,
1231
int newdir_fd, const char *newpath){
1235
/* If newpath points to an existing file, that file will be
1236
unlinked. Make sure we tell the faked daemon about this! */
1238
/* we need the st_new struct in order to inform faked about the
1239
(possible) unlink of the file */
1241
r=INT_NEXT_FSTATAT(newdir_fd, newpath, &st, AT_SYMLINK_NOFOLLOW);
1243
s=next_renameat(olddir_fd, oldpath, newdir_fd, newpath);
1247
INT_SEND_STAT(&st,unlink_func);
1251
#endif /* HAVE_RENAMEAT */
1252
#endif /* HAVE_FSTATAT */
1255
#ifdef FAKEROOT_FAKENET
1263
/* No need to lock in the child process. */
1265
next_close(comm_sd);
1275
/* We can't wrap vfork(2) without breaking everything... */
1279
/* Return an error when trying to close the comm_sd file descriptor
1280
(pretend that it's closed). */
1287
if (comm_sd >= 0 && comm_sd == fd) {
1291
retval = next_close(fd);
1301
int dup2(int oldfd, int newfd)
1307
if (comm_sd >= 0 && comm_sd == newfd) {
1308
/* If dup fails, comm_sd gets set to -1, which is fine. */
1309
comm_sd = dup(newfd);
1313
retval = next_dup2(oldfd, newfd);
1321
#endif /* FAKEROOT_FAKENET */
1324
if (fakeroot_disabled)
1325
return next_getuid();
1326
return get_faked_uid();
1329
uid_t geteuid(void){
1330
if (fakeroot_disabled)
1331
return next_geteuid();
1332
return get_faked_euid();
1335
#ifdef HAVE_GETRESUID
1336
int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid){
1337
if (fakeroot_disabled)
1338
return next_getresuid(ruid, euid, suid);
1339
*ruid = get_faked_uid();
1340
*euid = get_faked_euid();
1341
*suid = get_faked_suid();
1344
#endif /* HAVE_GETRESUID */
1347
if (fakeroot_disabled)
1348
return next_getgid();
1349
return get_faked_gid();
1352
uid_t getegid(void){
1353
if (fakeroot_disabled)
1354
return next_getegid();
1355
return get_faked_egid();
1358
#ifdef HAVE_GETRESGID
1359
int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid){
1360
if (fakeroot_disabled)
1361
return next_getresgid(rgid, egid, sgid);
1362
*rgid = get_faked_gid();
1363
*egid = get_faked_egid();
1364
*sgid = get_faked_sgid();
1367
#endif /* HAVE_GETRESGID */
1369
int setuid(uid_t id){
1370
if (fakeroot_disabled)
1371
return next_setuid(id);
1372
return set_faked_uid(id);
1375
int setgid(uid_t id){
1376
if (fakeroot_disabled)
1377
return next_setgid(id);
1378
return set_faked_gid(id);
1381
int seteuid(uid_t id){
1382
if (fakeroot_disabled)
1383
return next_seteuid(id);
1384
return set_faked_euid(id);
1387
int setegid(uid_t id){
1388
if (fakeroot_disabled)
1389
return next_setegid(id);
1390
return set_faked_egid(id);
1393
int setreuid(SETREUID_ARG ruid, SETREUID_ARG euid){
1394
#ifdef LIBFAKEROOT_DEBUGGING
1395
if (fakeroot_debug) {
1396
fprintf(stderr, "setreuid\n");
1398
#endif /* LIBFAKEROOT_DEBUGGING */
1399
if (fakeroot_disabled)
1400
return next_setreuid(ruid, euid);
1401
return set_faked_reuid(ruid, euid);
1404
int setregid(SETREGID_ARG rgid, SETREGID_ARG egid){
1405
#ifdef LIBFAKEROOT_DEBUGGING
1406
if (fakeroot_debug) {
1407
fprintf(stderr, "setregid\n");
1409
#endif /* LIBFAKEROOT_DEBUGGING */
1410
if (fakeroot_disabled)
1411
return next_setregid(rgid, egid);
1412
return set_faked_regid(rgid, egid);
1415
#ifdef HAVE_SETRESUID
1416
int setresuid(uid_t ruid, uid_t euid, uid_t suid){
1417
if (fakeroot_disabled)
1418
return next_setresuid(ruid, euid, suid);
1419
return set_faked_resuid(ruid, euid, suid);
1421
#endif /* HAVE_SETRESUID */
1423
#ifdef HAVE_SETRESGID
1424
int setresgid(gid_t rgid, gid_t egid, gid_t sgid){
1425
if (fakeroot_disabled)
1426
return next_setresgid(rgid, egid, sgid);
1427
return set_faked_resgid(rgid, egid, sgid);
1429
#endif /* HAVE_SETRESGID */
1431
#ifdef HAVE_SETFSUID
1432
uid_t setfsuid(uid_t fsuid){
1433
if (fakeroot_disabled)
1434
return next_setfsuid(fsuid);
1435
return set_faked_fsuid(fsuid);
1437
#endif /* HAVE_SETFSUID */
1439
#ifdef HAVE_SETFSGID
1440
gid_t setfsgid(gid_t fsgid){
1441
if (fakeroot_disabled)
1442
return next_setfsgid(fsgid);
1443
return set_faked_fsgid(fsgid);
1445
#endif /* HAVE_SETFSGID */
1447
int initgroups(const char* user, INITGROUPS_SECOND_ARG group){
1448
if (fakeroot_disabled)
1449
return next_initgroups(user, group);
1454
int setgroups(SETGROUPS_SIZE_TYPE size, const gid_t *list){
1455
if (fakeroot_disabled)
1456
return next_setgroups(size, list);
1461
int fakeroot_disable(int new)
1463
int old = fakeroot_disabled;
1464
fakeroot_disabled = new ? 1 : 0;
1468
int fakeroot_isdisabled(void)
1470
return fakeroot_disabled;
1473
#ifdef HAVE_SYS_ACL_H
1474
int acl_set_fd(int fd, acl_t acl) {
1479
int acl_set_file(const char *path_p, acl_type_t type, acl_t acl) {
1483
#endif /* HAVE_SYS_ACL_H */
1485
#ifdef HAVE_FTS_READ
1486
FTSENT *fts_read(FTS *ftsp) {
1489
#ifdef LIBFAKEROOT_DEBUGGING
1490
if (fakeroot_debug) {
1491
fprintf(stderr, "fts_read\n");
1493
#endif /* LIBFAKEROOT_DEBUGGING */
1494
r=next_fts_read(ftsp);
1495
if(r && r->fts_statp) { /* Should we bother checking fts_info here? */
1496
# if defined(STAT64_SUPPORT) && !defined(__APPLE__)
1497
SEND_GET_STAT64(r->fts_statp, _STAT_VER);
1499
SEND_GET_STAT(r->fts_statp, _STAT_VER);
1505
#endif /* HAVE_FTS_READ */
1507
#ifdef HAVE_FTS_CHILDREN
1508
FTSENT *fts_children(FTS *ftsp, int options) {
1511
#ifdef LIBFAKEROOT_DEBUGGING
1512
if (fakeroot_debug) {
1513
fprintf(stderr, "fts_children\n");
1515
#endif /* LIBFAKEROOT_DEBUGGING */
1516
first=next_fts_children(ftsp, options);
1517
for(r = first; r; r = r->fts_link) {
1518
if(r && r->fts_statp) { /* Should we bother checking fts_info here? */
1519
# if defined(STAT64_SUPPORT) && !defined(__APPLE__)
1520
SEND_GET_STAT64(r->fts_statp, _STAT_VER);
1522
SEND_GET_STAT(r->fts_statp, _STAT_VER);
1529
#endif /* HAVE_FTS_CHILDREN */
1534
getattrlist(const char *path, void *attrList, void *attrBuf,
1535
size_t attrBufSize, unsigned int options)
1538
getattrlist(const char *path, void *attrList, void *attrBuf,
1539
size_t attrBufSize, unsigned long options)
1545
#ifdef LIBFAKEROOT_DEBUGGING
1546
if (fakeroot_debug) {
1547
fprintf(stderr, "getattrlist path %s\n", path);
1549
#endif /* LIBFAKEROOT_DEBUGGING */
1550
r=next_getattrlist(path, attrList, attrBuf, attrBufSize, options);
1554
if (options & FSOPT_NOFOLLOW) {
1562
patchattr(attrList, attrBuf, st.st_uid, st.st_gid);
1569
fgetattrlist(int fd, void *attrList, void *attrBuf,
1570
size_t attrBufSize, unsigned int options)
1573
fgetattrlist(int fd, void *attrList, void *attrBuf,
1574
size_t attrBufSize, unsigned long options)
1580
#ifdef LIBFAKEROOT_DEBUGGING
1581
if (fakeroot_debug) {
1582
fprintf(stderr, "fgetattrlist fd %d\n", fd);
1584
#endif /* LIBFAKEROOT_DEBUGGING */
1585
r=next_fgetattrlist(fd, attrList, attrBuf, attrBufSize, options);
1593
patchattr(attrList, attrBuf, st.st_uid, st.st_gid);
1597
#endif /* ifdef __APPLE__ */