~ubuntu-branches/ubuntu/utopic/fakeroot/utopic

« back to all changes in this revision

Viewing changes to .pc/debian-changes-1.14.5-2/libfakeroot.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams
  • Date: 2011-03-28 11:10:45 UTC
  • mfrom: (10.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110328111045-aw7high2asyxltbg
Tags: 1.15-1
* Patch from Aurelien Jarno to add lchmod() support (for GNU/kFreeBSD).
  closes: #618782.
* Patch from Justin B. Rye to improve short and long package descriptions.
  closes: #615852.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
  Copyright Ⓒ 1997, 1998, 1999, 2000, 2001  joost witteveen
3
 
  Copyright Ⓒ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009  Clint Adams
4
 
 
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.
9
 
 
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.
14
 
 
15
 
*/
16
 
/* #define _POSIX_C_SOURCE 199309L whatever that may mean...*/
17
 
/* #define _BSD_SOURCE             I use strdup, S_IFDIR, etc */
18
 
 
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
22
 
   it
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
28
 
   fakeroot
29
 
   always bombs. Simple fix:
30
 
*/
31
 
#define _GNU_SOURCE
32
 
 
33
 
#define FAKEROOT_LIBFAKEROOT
34
 
 
35
 
#ifdef __APPLE__
36
 
/*
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'.
39
 
*/
40
 
#define _DARWIN_NO_64_BIT_INODE
41
 
 
42
 
#ifndef __LP64__
43
 
/*
44
 
   This file is for 32-bit symbols which do not have the "$UNIX2003" version.
45
 
*/
46
 
#define _NONSTD_SOURCE
47
 
#endif
48
 
#endif
49
 
 
50
 
#include "config.h"
51
 
#include "communicate.h"
52
 
 
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)
58
 
#else
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)
63
 
#endif
64
 
 
65
 
/*
66
 
   These INT_* (which stands for internal) macros should always be used when
67
 
   the fakeroot library owns the storage of the stat variable.
68
 
*/
69
 
#ifdef STAT64_SUPPORT
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)
76
 
#else
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)
83
 
#endif
84
 
 
85
 
#include <stdlib.h>
86
 
#include <sys/ipc.h>
87
 
#include <sys/msg.h>
88
 
#include <fcntl.h>
89
 
#include <string.h>
90
 
#include <stdio.h>
91
 
#include <stdarg.h>
92
 
#include <dlfcn.h>
93
 
#include <unistd.h>
94
 
#include <dirent.h>
95
 
#include <errno.h>
96
 
#include <sys/types.h>
97
 
#ifdef HAVE_SYS_ACL_H
98
 
#include <sys/acl.h>
99
 
#endif /* HAVE_SYS_ACL_H */
100
 
#if HAVE_FTS_H
101
 
#include <fts.h>
102
 
#endif /* HAVE_FTS_H */
103
 
 
104
 
#if !HAVE_DECL_SETENV
105
 
extern int setenv (const char *name, const char *value, int replace);
106
 
#endif
107
 
#if !HAVE_DECL_UNSETENV
108
 
extern int unsetenv (const char *name);
109
 
#endif
110
 
 
111
 
 
112
 
/*
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)
118
 
*/
119
 
 
120
 
 
121
 
/*
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
124
 
 
125
 
   Linux:
126
 
*/
127
 
 
128
 
/* OSF1 :*/
129
 
/*#define LIBCPATH "/usr/shlib/libc.so"*/
130
 
 
131
 
#undef __xstat
132
 
#undef __fxstat
133
 
#undef __lxstat
134
 
#undef __xstat64
135
 
#undef __fxstat64
136
 
#undef __lxstat64
137
 
#undef _FILE_OFFSET_BITS
138
 
 
139
 
/*
140
 
// next_wrap_st:
141
 
// this structure is used in next_wrap, which is defined in
142
 
// wrapstruct.h, included below
143
 
*/
144
 
 
145
 
struct next_wrap_st{
146
 
  void **doit;
147
 
  char *name;
148
 
};
149
 
 
150
 
void *get_libc(){
151
 
 
152
 
#ifndef RTLD_NEXT
153
 
 void *lib=0;
154
 
 if(!lib){
155
 
   lib= dlopen(LIBCPATH,RTLD_LAZY);
156
 
 }
157
 
 if (NULL==lib) {
158
 
   fprintf(stderr, "Couldn't find libc at: %s\n", LIBCPATH);
159
 
   abort();
160
 
 }
161
 
 return lib;
162
 
#else
163
 
  return RTLD_NEXT;
164
 
#endif
165
 
}
166
 
void load_library_symbols(void);
167
 
 
168
 
int fakeroot_disabled = 0;
169
 
#ifdef LIBFAKEROOT_DEBUGGING
170
 
int fakeroot_debug = 0;
171
 
#endif /* LIBFAKEROOT_DEBUGGING */
172
 
 
173
 
#ifdef __APPLE__
174
 
#include "patchattr.h"
175
 
#endif
176
 
#include "wrapped.h"
177
 
#include "wraptmpf.h"
178
 
#include "wrapdef.h"
179
 
#include "wrapstruct.h"
180
 
 
181
 
 
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
194
 
     things :) */
195
 
 
196
 
  int i;
197
 
  const char *msg;
198
 
 
199
 
#ifdef LIBFAKEROOT_DEBUGGING
200
 
  if (getenv("FAKEROOT_DEBUG")) {
201
 
    fakeroot_debug=1;
202
 
  }
203
 
  if (fakeroot_debug) {
204
 
    fprintf(stderr, "load_library_symbols\n");
205
 
  }
206
 
 
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);
212
 
/*    abort ();*/
213
 
    }
214
 
  }
215
 
}
216
 
 
217
 
 
218
 
/*
219
 
 * Fake implementations for the setuid family of functions.
220
 
 * The fake IDs are inherited by child processes via environment variables.
221
 
 *
222
 
 * Issues:
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.
228
 
 *   o Not thread-safe.
229
 
 */
230
 
 
231
 
 
232
 
/* Generic set/get ID functions */
233
 
 
234
 
static int env_get_id(const char *key) {
235
 
  char *str = getenv(key);
236
 
  if (str)
237
 
    return atoi(str);
238
 
  return 0;
239
 
}
240
 
 
241
 
static int env_set_id(const char *key, int id) {
242
 
  if (id == 0) {
243
 
    unsetenv(key);
244
 
    return 0;
245
 
  } else {
246
 
    char str[12];
247
 
    snprintf(str, sizeof (str), "%d", id);
248
 
    return setenv(key, str, 1);
249
 
  }
250
 
}
251
 
 
252
 
static void read_id(unsigned int *id, const char *key) {
253
 
  if (*id == (unsigned int)-1)
254
 
    *id = env_get_id(key);
255
 
}
256
 
 
257
 
static int write_id(const char *key, int id) {
258
 
  if (env_get_id(key) != id)
259
 
    return env_set_id(key, id);
260
 
  return 0;
261
 
}
262
 
 
263
 
/* Fake ID storage */
264
 
 
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;
273
 
 
274
 
/* Read user ID */
275
 
 
276
 
static void read_real_uid() {
277
 
  read_id(&faked_real_uid, FAKEROOTUID_ENV);
278
 
}
279
 
 
280
 
static void read_effective_uid() {
281
 
  read_id(&faked_effective_uid, FAKEROOTEUID_ENV);
282
 
}
283
 
 
284
 
static void read_saved_uid() {
285
 
  read_id(&faked_saved_uid, FAKEROOTSUID_ENV);
286
 
}
287
 
 
288
 
static void read_fs_uid() {
289
 
  read_id(&faked_fs_uid, FAKEROOTFUID_ENV);
290
 
}
291
 
 
292
 
static void read_uids() {
293
 
  read_real_uid();
294
 
  read_effective_uid();
295
 
  read_saved_uid();
296
 
  read_fs_uid();
297
 
}
298
 
 
299
 
/* Read group ID */
300
 
 
301
 
static void read_real_gid() {
302
 
  read_id(&faked_real_gid, FAKEROOTGID_ENV);
303
 
}
304
 
 
305
 
static void read_effective_gid() {
306
 
  read_id(&faked_effective_gid, FAKEROOTEGID_ENV);
307
 
}
308
 
 
309
 
static void read_saved_gid() {
310
 
  read_id(&faked_saved_gid, FAKEROOTSGID_ENV);
311
 
}
312
 
 
313
 
static void read_fs_gid() {
314
 
  read_id(&faked_fs_gid, FAKEROOTFGID_ENV);
315
 
}
316
 
 
317
 
static void read_gids() {
318
 
  read_real_gid();
319
 
  read_effective_gid();
320
 
  read_saved_gid();
321
 
  read_fs_gid();
322
 
}
323
 
 
324
 
/* Write user ID */
325
 
 
326
 
static int write_real_uid() {
327
 
  return write_id(FAKEROOTUID_ENV, faked_real_uid);
328
 
}
329
 
 
330
 
static int write_effective_uid() {
331
 
  return write_id(FAKEROOTEUID_ENV, faked_effective_uid);
332
 
}
333
 
 
334
 
static int write_saved_uid() {
335
 
  return write_id(FAKEROOTSUID_ENV, faked_saved_uid);
336
 
}
337
 
 
338
 
static int write_fs_uid() {
339
 
  return write_id(FAKEROOTFUID_ENV, faked_fs_uid);
340
 
}
341
 
 
342
 
static int write_uids() {
343
 
  if (write_real_uid() < 0)
344
 
    return -1;
345
 
  if (write_effective_uid() < 0)
346
 
    return -1;
347
 
  if (write_saved_uid() < 0)
348
 
    return -1;
349
 
  if (write_fs_uid() < 0)
350
 
    return -1;
351
 
  return 0;
352
 
}
353
 
 
354
 
/* Write group ID */
355
 
 
356
 
static int write_real_gid() {
357
 
  return write_id(FAKEROOTGID_ENV, faked_real_gid);
358
 
}
359
 
 
360
 
static int write_effective_gid() {
361
 
  return write_id(FAKEROOTEGID_ENV, faked_effective_gid);
362
 
}
363
 
 
364
 
static int write_saved_gid() {
365
 
  return write_id(FAKEROOTSGID_ENV, faked_saved_gid);
366
 
}
367
 
 
368
 
static int write_fs_gid() {
369
 
  return write_id(FAKEROOTFGID_ENV, faked_fs_gid);
370
 
}
371
 
 
372
 
static int write_gids() {
373
 
  if (write_real_gid() < 0)
374
 
    return -1;
375
 
  if (write_effective_gid() < 0)
376
 
    return -1;
377
 
  if (write_saved_gid() < 0)
378
 
    return -1;
379
 
  if (write_fs_gid() < 0)
380
 
    return -1;
381
 
  return 0;
382
 
}
383
 
 
384
 
/* Faked get functions */
385
 
 
386
 
static uid_t get_faked_uid() {
387
 
  read_real_uid();
388
 
  return faked_real_uid;
389
 
}
390
 
 
391
 
static gid_t get_faked_gid() {
392
 
  read_real_gid();
393
 
  return faked_real_gid;
394
 
}
395
 
 
396
 
static uid_t get_faked_euid() {
397
 
  read_effective_uid();
398
 
  return faked_effective_uid;
399
 
}
400
 
 
401
 
static gid_t get_faked_egid() {
402
 
  read_effective_gid();
403
 
  return faked_effective_gid;
404
 
}
405
 
 
406
 
static uid_t get_faked_suid() {
407
 
  read_saved_uid();
408
 
  return faked_saved_uid;
409
 
}
410
 
 
411
 
static gid_t get_faked_sgid() {
412
 
  read_saved_gid();
413
 
  return faked_saved_gid;
414
 
}
415
 
 
416
 
static uid_t get_faked_fsuid() {
417
 
  read_fs_uid();
418
 
  return faked_fs_uid;
419
 
}
420
 
 
421
 
static gid_t get_faked_fsgid() {
422
 
  read_fs_gid();
423
 
  return faked_fs_gid;
424
 
}
425
 
 
426
 
/* Faked set functions */
427
 
 
428
 
static int set_faked_uid(uid_t uid) {
429
 
  read_uids();
430
 
  if (faked_effective_uid == 0) {
431
 
    faked_real_uid = uid;
432
 
    faked_effective_uid = uid;
433
 
    faked_saved_uid = uid;
434
 
  } else {
435
 
    faked_effective_uid = uid;
436
 
  }
437
 
  faked_fs_uid = uid;
438
 
  return write_uids();
439
 
}
440
 
 
441
 
static int set_faked_gid(gid_t gid) {
442
 
  read_gids();
443
 
  if (faked_effective_gid == 0) {
444
 
    faked_real_gid = gid;
445
 
    faked_effective_gid = gid;
446
 
    faked_saved_gid = gid;
447
 
  } else {
448
 
    faked_effective_gid = gid;
449
 
  }
450
 
  faked_fs_gid = gid;
451
 
  return write_gids();
452
 
}
453
 
 
454
 
static int set_faked_euid(uid_t euid) {
455
 
  read_effective_uid();
456
 
  faked_effective_uid = euid;
457
 
  read_fs_uid();
458
 
  faked_fs_uid = euid;
459
 
  if (write_effective_uid() < 0)
460
 
    return -1;
461
 
  if (write_fs_uid() < 0)
462
 
    return -1;
463
 
  return 0;
464
 
}
465
 
 
466
 
static int set_faked_egid(gid_t egid) {
467
 
  read_effective_gid();
468
 
  faked_effective_gid = egid;
469
 
  read_fs_gid();
470
 
  faked_fs_gid = egid;
471
 
  if (write_effective_gid() < 0)
472
 
    return -1;
473
 
  if (write_fs_gid() < 0)
474
 
    return -1;
475
 
  return 0;
476
 
}
477
 
 
478
 
static int set_faked_reuid(uid_t ruid, uid_t euid) {
479
 
  read_uids();
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;
487
 
  return write_uids();
488
 
}
489
 
 
490
 
static int set_faked_regid(gid_t rgid, gid_t egid) {
491
 
  read_gids();
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;
499
 
  return write_gids();
500
 
}
501
 
 
502
 
#ifdef HAVE_SETRESUID
503
 
static int set_faked_resuid(uid_t ruid, uid_t euid, uid_t suid) {
504
 
  read_uids();
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;
512
 
  return write_uids();
513
 
}
514
 
#endif
515
 
 
516
 
#ifdef HAVE_SETRESGID
517
 
static int set_faked_resgid(gid_t rgid, gid_t egid, gid_t sgid) {
518
 
  read_gids();
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;
526
 
  return write_gids();
527
 
}
528
 
#endif
529
 
 
530
 
#ifdef HAVE_SETFSUID
531
 
static uid_t set_faked_fsuid(uid_t fsuid) {
532
 
  uid_t prev_fsuid = get_faked_fsuid();
533
 
  faked_fs_uid = fsuid;
534
 
  return prev_fsuid;
535
 
}
536
 
#endif
537
 
 
538
 
#ifdef HAVE_SETFSGID
539
 
static gid_t set_faked_fsgid(gid_t fsgid) {
540
 
  gid_t prev_fsgid = get_faked_fsgid();
541
 
  faked_fs_gid = fsgid;
542
 
  return prev_fsgid;
543
 
}
544
 
#endif
545
 
 
546
 
 
547
 
static int dont_try_chown(){
548
 
  static int inited=0;
549
 
  static int donttry;
550
 
 
551
 
  if(!inited){
552
 
    donttry=(env_var_set(FAKEROOTDONTTRYCHOWN_ENV)!=NULL);
553
 
    inited=1;
554
 
  }
555
 
  return donttry;
556
 
}
557
 
 
558
 
 
559
 
/* The wrapped functions */
560
 
 
561
 
 
562
 
int WRAP_LSTAT LSTAT_ARG(int ver,
563
 
                       const char *file_name,
564
 
                       struct stat *statbuf){
565
 
 
566
 
  int r;
567
 
 
568
 
#ifdef LIBFAKEROOT_DEBUGGING
569
 
  if (fakeroot_debug) {
570
 
    fprintf(stderr, "lstat file_name %s\n", file_name);
571
 
  }
572
 
#endif /* LIBFAKEROOT_DEBUGGING */
573
 
  r=NEXT_LSTAT(ver, file_name, statbuf);
574
 
  if(r)
575
 
    return -1;
576
 
  SEND_GET_STAT(statbuf, ver);
577
 
  return 0;
578
 
}
579
 
 
580
 
 
581
 
int WRAP_STAT STAT_ARG(int ver,
582
 
                       const char *file_name,
583
 
                       struct stat *st){
584
 
  int r;
585
 
 
586
 
#ifdef LIBFAKEROOT_DEBUGGING
587
 
  if (fakeroot_debug) {
588
 
    fprintf(stderr, "stat file_name %s\n", file_name);
589
 
  }
590
 
#endif /* LIBFAKEROOT_DEBUGGING */
591
 
  r=NEXT_STAT(ver, file_name, st);
592
 
  if(r)
593
 
    return -1;
594
 
  SEND_GET_STAT(st,ver);
595
 
  return 0;
596
 
}
597
 
 
598
 
 
599
 
int WRAP_FSTAT FSTAT_ARG(int ver,
600
 
                        int fd,
601
 
                        struct stat *st){
602
 
 
603
 
 
604
 
  int r;
605
 
 
606
 
#ifdef LIBFAKEROOT_DEBUGGING
607
 
  if (fakeroot_debug) {
608
 
    fprintf(stderr, "fstat fd %d\n", fd);
609
 
  }
610
 
#endif /* LIBFAKEROOT_DEBUGGING */
611
 
  r=NEXT_FSTAT(ver, fd, st);
612
 
  if(r)
613
 
    return -1;
614
 
  SEND_GET_STAT(st,ver);
615
 
  return 0;
616
 
}
617
 
 
618
 
#ifdef HAVE_FSTATAT
619
 
int WRAP_FSTATAT FSTATAT_ARG(int ver,
620
 
                             int dir_fd,
621
 
                             const char *path,
622
 
                             struct stat *st,
623
 
                             int flags){
624
 
 
625
 
 
626
 
  int r;
627
 
 
628
 
  r=NEXT_FSTATAT(ver, dir_fd, path, st, flags);
629
 
  if(r)
630
 
    return -1;
631
 
  SEND_GET_STAT(st,ver);
632
 
  return 0;
633
 
}
634
 
#endif /* HAVE_FSTATAT */
635
 
 
636
 
#ifdef STAT64_SUPPORT
637
 
 
638
 
int WRAP_LSTAT64 LSTAT64_ARG (int ver,
639
 
                           const char *file_name,
640
 
                           struct stat64 *st){
641
 
 
642
 
  int r;
643
 
 
644
 
#ifdef LIBFAKEROOT_DEBUGGING
645
 
  if (fakeroot_debug) {
646
 
    fprintf(stderr, "lstat64 file_name %s\n", file_name);
647
 
  }
648
 
#endif /* LIBFAKEROOT_DEBUGGING */
649
 
  r=NEXT_LSTAT64(ver, file_name, st);
650
 
 
651
 
  if(r)
652
 
    return -1;
653
 
 
654
 
  SEND_GET_STAT64(st,ver);
655
 
  return 0;
656
 
}
657
 
 
658
 
 
659
 
int WRAP_STAT64 STAT64_ARG(int ver,
660
 
                           const char *file_name,
661
 
                           struct stat64 *st){
662
 
  int r;
663
 
 
664
 
#ifdef LIBFAKEROOT_DEBUGGING
665
 
  if (fakeroot_debug) {
666
 
    fprintf(stderr, "stat64 file_name %s\n", file_name);
667
 
  }
668
 
#endif /* LIBFAKEROOT_DEBUGGING */
669
 
  r=NEXT_STAT64(ver,file_name,st);
670
 
  if(r)
671
 
    return -1;
672
 
  SEND_GET_STAT64(st,ver);
673
 
  return 0;
674
 
}
675
 
 
676
 
 
677
 
int WRAP_FSTAT64 FSTAT64_ARG(int ver,
678
 
                             int fd,
679
 
                             struct stat64 *st){
680
 
  int r;
681
 
 
682
 
#ifdef LIBFAKEROOT_DEBUGGING
683
 
  if (fakeroot_debug) {
684
 
    fprintf(stderr, "fstat64 fd %d\n", fd);
685
 
  }
686
 
#endif /* LIBFAKEROOT_DEBUGGING */
687
 
  r=NEXT_FSTAT64(ver, fd, st);
688
 
  if(r)
689
 
    return -1;
690
 
  SEND_GET_STAT64(st,ver);
691
 
 
692
 
  return 0;
693
 
}
694
 
 
695
 
#ifdef HAVE_FSTATAT
696
 
int WRAP_FSTATAT64 FSTATAT64_ARG(int ver,
697
 
                                 int dir_fd,
698
 
                                 const char *path,
699
 
                                 struct stat64 *st,
700
 
                                 int flags){
701
 
 
702
 
 
703
 
  int r;
704
 
 
705
 
  r=NEXT_FSTATAT64(ver, dir_fd, path, st, flags);
706
 
  if(r)
707
 
    return -1;
708
 
  SEND_GET_STAT64(st,ver);
709
 
  return 0;
710
 
}
711
 
#endif /* HAVE_FSTATAT */
712
 
 
713
 
#endif /* STAT64_SUPPORT */
714
 
 
715
 
/*************************************************************/
716
 
/*
717
 
  Wrapped functions general info:
718
 
 
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.
730
 
 
731
 
*/
732
 
/*************************************************************/
733
 
 
734
 
 
735
 
 
736
 
/* chown, lchown, fchown, chmod, fchmod, mknod functions
737
 
 
738
 
   quite general. See the `Wrapped functions general info:' above
739
 
   for more info.
740
 
 */
741
 
 
742
 
int chown(const char *path, uid_t owner, gid_t group){
743
 
  INT_STRUCT_STAT st;
744
 
  int r=0;
745
 
 
746
 
 
747
 
#ifdef LIBFAKEROOT_DEBUGGING
748
 
  if (fakeroot_debug) {
749
 
    fprintf(stderr, "chown path %s owner %d group %d\n", path, owner, group);
750
 
  }
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);
756
 
#else
757
 
  /*chown(sym-link) works on the symlink itself, use lstat: */
758
 
  r=INT_NEXT_LSTAT(path, &st);
759
 
#endif
760
 
 
761
 
  if(r)
762
 
    return r;
763
 
  st.st_uid=owner;
764
 
  st.st_gid=group;
765
 
  INT_SEND_STAT(&st,chown_func);
766
 
  if(!dont_try_chown())
767
 
    r=next_lchown(path,owner,group);
768
 
  else
769
 
    r=0;
770
 
  if(r&&(errno==EPERM))
771
 
    r=0;
772
 
 
773
 
  return r;
774
 
}
775
 
 
776
 
 
777
 
#ifdef LCHOWN_SUPPORT
778
 
int lchown(const char *path, uid_t owner, gid_t group){
779
 
  INT_STRUCT_STAT st;
780
 
  int r=0;
781
 
 
782
 
#ifdef LIBFAKEROOT_DEBUGGING
783
 
  if (fakeroot_debug) {
784
 
    fprintf(stderr, "lchown path %s owner %d group %d\n", path, owner, group);
785
 
  }
786
 
#endif /* LIBFAKEROOT_DEBUGGING */
787
 
  r=INT_NEXT_LSTAT(path, &st);
788
 
  if(r)
789
 
    return r;
790
 
  st.st_uid=owner;
791
 
  st.st_gid=group;
792
 
  INT_SEND_STAT(&st,chown_func);
793
 
  if(!dont_try_chown())
794
 
    r=next_lchown(path,owner,group);
795
 
  else
796
 
    r=0;
797
 
  if(r&&(errno==EPERM))
798
 
    r=0;
799
 
 
800
 
  return r;
801
 
}
802
 
#endif
803
 
 
804
 
int fchown(int fd, uid_t owner, gid_t group){
805
 
  INT_STRUCT_STAT st;
806
 
  int r;
807
 
 
808
 
  r=INT_NEXT_FSTAT(fd, &st);
809
 
  if(r)
810
 
    return r;
811
 
 
812
 
  st.st_uid=owner;
813
 
  st.st_gid=group;
814
 
  INT_SEND_STAT(&st, chown_func);
815
 
 
816
 
  if(!dont_try_chown())
817
 
    r=next_fchown(fd,owner,group);
818
 
  else
819
 
    r=0;
820
 
 
821
 
  if(r&&(errno==EPERM))
822
 
    r=0;
823
 
 
824
 
  return r;
825
 
}
826
 
 
827
 
#ifdef HAVE_FSTATAT
828
 
#ifdef HAVE_FCHOWNAT
829
 
int fchownat(int dir_fd, const char *path, uid_t owner, gid_t group, int flags) {
830
 
  int r;
831
 
  /* If AT_SYMLINK_NOFOLLOW is set in the fchownat call it should
832
 
     be when we stat it. */
833
 
  INT_STRUCT_STAT st;
834
 
  r=INT_NEXT_FSTATAT(dir_fd, path, &st, (flags & AT_SYMLINK_NOFOLLOW));
835
 
 
836
 
  if(r)
837
 
    return(r);
838
 
 
839
 
  st.st_uid=owner;
840
 
  st.st_gid=group;
841
 
  INT_SEND_STAT(&st,chown_func);
842
 
 
843
 
  if(!dont_try_chown())
844
 
    r=next_fchownat(dir_fd,path,owner,group,flags);
845
 
  else
846
 
    r=0;
847
 
 
848
 
  if(r&&(errno==EPERM))
849
 
    r=0;
850
 
 
851
 
  return r;
852
 
}
853
 
#endif /* HAVE_FCHOWNAT */
854
 
#endif /* HAVE_FSTATAT */
855
 
 
856
 
int chmod(const char *path, mode_t mode){
857
 
  INT_STRUCT_STAT st;
858
 
  int r;
859
 
 
860
 
#ifdef LIBFAKEROOT_DEBUGGING
861
 
  if (fakeroot_debug) {
862
 
    fprintf(stderr, "chmod path %s\n", path);
863
 
  }
864
 
#endif /* LIBFAKEROOT_DEBUGGING */
865
 
  r=INT_NEXT_STAT(path, &st);
866
 
  if(r)
867
 
    return r;
868
 
 
869
 
  st.st_mode=(mode&ALLPERMS)|(st.st_mode&~ALLPERMS);
870
 
 
871
 
  INT_SEND_STAT(&st, chmod_func);
872
 
 
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.
880
 
  */
881
 
  mode |= 0600;
882
 
  if(S_ISDIR(st.st_mode))
883
 
    mode |= 0100;
884
 
 
885
 
  r=next_chmod(path, mode);
886
 
  if(r&&(errno==EPERM))
887
 
    r=0;
888
 
#ifdef EFTYPE           /* available under FreeBSD kernel */
889
 
  if(r&&(errno==EFTYPE))
890
 
    r=0;
891
 
#endif
892
 
  return r;
893
 
}
894
 
 
895
 
int fchmod(int fd, mode_t mode){
896
 
  int r;
897
 
  INT_STRUCT_STAT st;
898
 
 
899
 
 
900
 
#ifdef LIBFAKEROOT_DEBUGGING
901
 
  if (fakeroot_debug) {
902
 
    fprintf(stderr, "fchmod fd %d\n", fd);
903
 
  }
904
 
#endif /* LIBFAKEROOT_DEBUGGING */
905
 
  r=INT_NEXT_FSTAT(fd, &st);
906
 
 
907
 
  if(r)
908
 
    return(r);
909
 
 
910
 
  st.st_mode=(mode&ALLPERMS)|(st.st_mode&~ALLPERMS);
911
 
  INT_SEND_STAT(&st,chmod_func);
912
 
 
913
 
  /* see chmod() for comment */
914
 
  mode |= 0600;
915
 
  if(S_ISDIR(st.st_mode))
916
 
    mode |= 0100;
917
 
 
918
 
  r=next_fchmod(fd, mode);
919
 
  if(r&&(errno==EPERM))
920
 
    r=0;
921
 
#ifdef EFTYPE           /* available under FreeBSD kernel */
922
 
  if(r&&(errno==EFTYPE))
923
 
    r=0;
924
 
#endif
925
 
  return r;
926
 
}
927
 
 
928
 
#ifdef HAVE_FSTATAT
929
 
#ifdef HAVE_FCHMODAT
930
 
int fchmodat(int dir_fd, const char *path, mode_t mode, int flags) {
931
 
/*   (int fd, mode_t mode){*/
932
 
  int r;
933
 
  INT_STRUCT_STAT st;
934
 
 
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);
938
 
 
939
 
  if(r)
940
 
    return(r);
941
 
 
942
 
  st.st_mode=(mode&ALLPERMS)|(st.st_mode&~ALLPERMS);
943
 
  INT_SEND_STAT(&st,chmod_func);
944
 
 
945
 
  /* see chmod() for comment */
946
 
  mode |= 0600;
947
 
  if(S_ISDIR(st.st_mode))
948
 
    mode |= 0100;
949
 
 
950
 
  r=next_fchmodat(dir_fd, path, mode, flags);
951
 
  if(r&&(errno==EPERM))
952
 
    r=0;
953
 
#ifdef EFTYPE           /* available under FreeBSD kernel */
954
 
  if(r&&(errno==EFTYPE))
955
 
    r=0;
956
 
#endif
957
 
  return r;
958
 
}
959
 
#endif /* HAVE_FCHMODAT */
960
 
#endif /* HAVE_FSTATAT */
961
 
 
962
 
int WRAP_MKNOD MKNOD_ARG(int ver UNUSED,
963
 
                         const char *pathname,
964
 
                         mode_t mode, dev_t XMKNOD_FRTH_ARG dev)
965
 
{
966
 
  INT_STRUCT_STAT st;
967
 
  mode_t old_mask=umask(022);
968
 
  int fd,r;
969
 
 
970
 
  umask(old_mask);
971
 
 
972
 
  /*Don't bother to mknod the file, that probably doesn't work.
973
 
    just create it as normal file, and leave the premissions
974
 
    to the fakemode.*/
975
 
 
976
 
  fd=open(pathname, O_WRONLY|O_CREAT|O_TRUNC, 00644);
977
 
 
978
 
  if(fd==-1)
979
 
    return -1;
980
 
 
981
 
  close(fd);
982
 
  /* get the inode, to communicate with faked */
983
 
 
984
 
  r=INT_NEXT_LSTAT(pathname, &st);
985
 
 
986
 
  if(r)
987
 
    return -1;
988
 
 
989
 
  st.st_mode= mode & ~old_mask;
990
 
  st.st_rdev= XMKNOD_FRTH_ARG dev;
991
 
 
992
 
  INT_SEND_STAT(&st,mknod_func);
993
 
 
994
 
  return 0;
995
 
}
996
 
 
997
 
#ifdef HAVE_FSTATAT
998
 
#ifdef HAVE_MKNODAT
999
 
int WRAP_MKNODAT MKNODAT_ARG(int ver UNUSED,
1000
 
                             int dir_fd,
1001
 
                             const char *pathname,
1002
 
                             mode_t mode, dev_t XMKNODAT_FIFTH_ARG dev)
1003
 
{
1004
 
  INT_STRUCT_STAT st;
1005
 
  mode_t old_mask=umask(022);
1006
 
  int fd,r;
1007
 
 
1008
 
  umask(old_mask);
1009
 
 
1010
 
  /*Don't bother to mknod the file, that probably doesn't work.
1011
 
    just create it as normal file, and leave the permissions
1012
 
    to the fakemode.*/
1013
 
 
1014
 
  fd=openat(dir_fd, pathname, O_WRONLY|O_CREAT|O_TRUNC, 00644);
1015
 
 
1016
 
  if(fd==-1)
1017
 
    return -1;
1018
 
 
1019
 
  close(fd);
1020
 
  /* get the inode, to communicate with faked */
1021
 
 
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);
1025
 
 
1026
 
  if(r)
1027
 
    return -1;
1028
 
 
1029
 
  st.st_mode= mode & ~old_mask;
1030
 
  st.st_rdev= XMKNODAT_FIFTH_ARG dev;
1031
 
 
1032
 
  INT_SEND_STAT(&st,mknod_func);
1033
 
 
1034
 
  return 0;
1035
 
}
1036
 
#endif /* HAVE_MKNODAT */
1037
 
#endif /* HAVE_FSTATAT */
1038
 
 
1039
 
int mkdir(const char *path, mode_t mode){
1040
 
  INT_STRUCT_STAT st;
1041
 
  int r;
1042
 
  mode_t old_mask=umask(022);
1043
 
 
1044
 
  umask(old_mask);
1045
 
 
1046
 
 
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) */
1050
 
 
1051
 
#ifdef LIBFAKEROOT_DEBUGGING
1052
 
  if (fakeroot_debug) {
1053
 
    fprintf(stderr, "mkdir path %s\n", path);
1054
 
  }
1055
 
#endif /* LIBFAKEROOT_DEBUGGING */
1056
 
  r=next_mkdir(path, mode|0700);
1057
 
  /* mode|0700: see comment in the chown() function above */
1058
 
  if(r)
1059
 
    return -1;
1060
 
  r=INT_NEXT_STAT(path, &st);
1061
 
 
1062
 
  if(r)
1063
 
    return -1;
1064
 
 
1065
 
  st.st_mode=(mode&~old_mask&ALLPERMS)|(st.st_mode&~ALLPERMS)|S_IFDIR;
1066
 
 
1067
 
  INT_SEND_STAT(&st, chmod_func);
1068
 
 
1069
 
  return 0;
1070
 
}
1071
 
 
1072
 
#ifdef HAVE_FSTATAT
1073
 
#ifdef HAVE_MKDIRAT
1074
 
int mkdirat(int dir_fd, const char *path, mode_t mode){
1075
 
  INT_STRUCT_STAT st;
1076
 
  int r;
1077
 
  mode_t old_mask=umask(022);
1078
 
 
1079
 
  umask(old_mask);
1080
 
 
1081
 
 
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) */
1085
 
 
1086
 
  r=next_mkdirat(dir_fd, path, mode|0700);
1087
 
  /* mode|0700: see comment in the chown() function above */
1088
 
  if(r)
1089
 
    return -1;
1090
 
  r=INT_NEXT_FSTATAT(dir_fd, path, &st, 0);
1091
 
 
1092
 
  if(r)
1093
 
    return -1;
1094
 
 
1095
 
  st.st_mode=(mode&~old_mask&ALLPERMS)|(st.st_mode&~ALLPERMS)|S_IFDIR;
1096
 
 
1097
 
  INT_SEND_STAT(&st, chmod_func);
1098
 
 
1099
 
  return 0;
1100
 
}
1101
 
#endif /* HAVE_MKDIRAT */
1102
 
#endif /* HAVE_FSTATAT */
1103
 
 
1104
 
/*
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
1108
 
   of the following:
1109
 
    # rm -f file
1110
 
    # touch file
1111
 
    # chown admin file
1112
 
    # rm file
1113
 
    # touch file
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.
1117
 
*/
1118
 
 
1119
 
int unlink(const char *pathname){
1120
 
  int r;
1121
 
  INT_STRUCT_STAT st;
1122
 
 
1123
 
 
1124
 
  r=INT_NEXT_LSTAT(pathname, &st);
1125
 
  if(r)
1126
 
    return -1;
1127
 
 
1128
 
  r=next_unlink(pathname);
1129
 
 
1130
 
  if(r)
1131
 
    return -1;
1132
 
 
1133
 
  INT_SEND_STAT(&st, unlink_func);
1134
 
 
1135
 
  return 0;
1136
 
}
1137
 
 
1138
 
#ifdef HAVE_FSTATAT
1139
 
#ifdef HAVE_UNLINKAT
1140
 
int unlinkat(int dir_fd, const char *pathname, int flags){
1141
 
  int r;
1142
 
  INT_STRUCT_STAT st;
1143
 
  r=INT_NEXT_FSTATAT(dir_fd, pathname, &st, (flags&~AT_REMOVEDIR) | AT_SYMLINK_NOFOLLOW);
1144
 
  if(r)
1145
 
    return -1;
1146
 
 
1147
 
  r=next_unlinkat(dir_fd, pathname, flags);
1148
 
 
1149
 
  if(r)
1150
 
    return -1;
1151
 
 
1152
 
  INT_SEND_STAT(&st, unlink_func);
1153
 
 
1154
 
  return 0;
1155
 
}
1156
 
#endif /* HAVE_UNLINKAT */
1157
 
#endif /* HAVE_FSTATAT */
1158
 
 
1159
 
/*
1160
 
  See the `remove funtions:' comments above for more info on
1161
 
  these remove function wrappers.
1162
 
*/
1163
 
int rmdir(const char *pathname){
1164
 
  int r;
1165
 
  INT_STRUCT_STAT st;
1166
 
 
1167
 
  r=INT_NEXT_LSTAT(pathname, &st);
1168
 
  if(r)
1169
 
    return -1;
1170
 
  r=next_rmdir(pathname);
1171
 
  if(r)
1172
 
    return -1;
1173
 
 
1174
 
  INT_SEND_STAT(&st,unlink_func);
1175
 
 
1176
 
  return 0;
1177
 
}
1178
 
 
1179
 
/*
1180
 
  See the `remove funtions:' comments above for more info on
1181
 
  these remove function wrappers.
1182
 
*/
1183
 
int remove(const char *pathname){
1184
 
  int r;
1185
 
  INT_STRUCT_STAT st;
1186
 
 
1187
 
  r=INT_NEXT_LSTAT(pathname, &st);
1188
 
  if(r)
1189
 
    return -1;
1190
 
  r=next_remove(pathname);
1191
 
  if(r)
1192
 
    return -1;
1193
 
  INT_SEND_STAT(&st,unlink_func);
1194
 
 
1195
 
  return r;
1196
 
}
1197
 
 
1198
 
/*
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'.
1202
 
 
1203
 
  See the `remove funtions:' comments above for more info on
1204
 
  these remove function wrappers.
1205
 
*/
1206
 
 
1207
 
int rename(const char *oldpath, const char *newpath){
1208
 
  int r,s;
1209
 
  INT_STRUCT_STAT st;
1210
 
 
1211
 
  /* If newpath points to an existing file, that file will be
1212
 
     unlinked.   Make sure we tell the faked daemon about this! */
1213
 
 
1214
 
  /* we need the st_new struct in order to inform faked about the
1215
 
     (possible) unlink of the file */
1216
 
 
1217
 
  r=INT_NEXT_LSTAT(newpath, &st);
1218
 
 
1219
 
  s=next_rename(oldpath, newpath);
1220
 
  if(s)
1221
 
    return -1;
1222
 
  if(!r)
1223
 
    INT_SEND_STAT(&st,unlink_func);
1224
 
 
1225
 
  return 0;
1226
 
}
1227
 
 
1228
 
#ifdef HAVE_FSTATAT
1229
 
#ifdef HAVE_RENAMEAT
1230
 
int renameat(int olddir_fd, const char *oldpath,
1231
 
             int newdir_fd, const char *newpath){
1232
 
  int r,s;
1233
 
  INT_STRUCT_STAT st;
1234
 
 
1235
 
  /* If newpath points to an existing file, that file will be
1236
 
     unlinked.   Make sure we tell the faked daemon about this! */
1237
 
 
1238
 
  /* we need the st_new struct in order to inform faked about the
1239
 
     (possible) unlink of the file */
1240
 
 
1241
 
  r=INT_NEXT_FSTATAT(newdir_fd, newpath, &st, AT_SYMLINK_NOFOLLOW);
1242
 
 
1243
 
  s=next_renameat(olddir_fd, oldpath, newdir_fd, newpath);
1244
 
  if(s)
1245
 
    return -1;
1246
 
  if(!r)
1247
 
    INT_SEND_STAT(&st,unlink_func);
1248
 
 
1249
 
  return 0;
1250
 
}
1251
 
#endif /* HAVE_RENAMEAT */
1252
 
#endif /* HAVE_FSTATAT */
1253
 
 
1254
 
 
1255
 
#ifdef FAKEROOT_FAKENET
1256
 
pid_t fork(void)
1257
 
{
1258
 
  pid_t pid;
1259
 
 
1260
 
  pid = next_fork();
1261
 
 
1262
 
  if (pid == 0) {
1263
 
    /* No need to lock in the child process. */
1264
 
    if (comm_sd >= 0) {
1265
 
      next_close(comm_sd);
1266
 
      comm_sd = -1;
1267
 
    }
1268
 
  }
1269
 
 
1270
 
  return pid;
1271
 
}
1272
 
 
1273
 
pid_t vfork(void)
1274
 
{
1275
 
  /* We can't wrap vfork(2) without breaking everything... */
1276
 
  return fork();
1277
 
}
1278
 
 
1279
 
/* Return an error when trying to close the comm_sd file descriptor
1280
 
   (pretend that it's closed). */
1281
 
int close(int fd)
1282
 
{
1283
 
  int retval, reterr;
1284
 
 
1285
 
  lock_comm_sd();
1286
 
 
1287
 
  if (comm_sd >= 0 && comm_sd == fd) {
1288
 
    retval = -1;
1289
 
    reterr = EBADF;
1290
 
  } else {
1291
 
    retval = next_close(fd);
1292
 
    reterr = errno;
1293
 
  }
1294
 
 
1295
 
  unlock_comm_sd();
1296
 
 
1297
 
  errno = reterr;
1298
 
  return retval;
1299
 
}
1300
 
 
1301
 
int dup2(int oldfd, int newfd)
1302
 
{
1303
 
  int retval, reterr;
1304
 
 
1305
 
  lock_comm_sd();
1306
 
 
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);
1310
 
    next_close(newfd);
1311
 
  }
1312
 
 
1313
 
  retval = next_dup2(oldfd, newfd);
1314
 
  reterr = errno;
1315
 
 
1316
 
  unlock_comm_sd();
1317
 
 
1318
 
  errno = reterr;
1319
 
  return retval;
1320
 
}
1321
 
#endif /* FAKEROOT_FAKENET */
1322
 
 
1323
 
uid_t getuid(void){
1324
 
  if (fakeroot_disabled)
1325
 
    return next_getuid();
1326
 
  return get_faked_uid();
1327
 
}
1328
 
 
1329
 
uid_t geteuid(void){
1330
 
  if (fakeroot_disabled)
1331
 
    return next_geteuid();
1332
 
  return get_faked_euid();
1333
 
}
1334
 
 
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();
1342
 
  return 0;
1343
 
}
1344
 
#endif /* HAVE_GETRESUID */
1345
 
 
1346
 
uid_t getgid(void){
1347
 
  if (fakeroot_disabled)
1348
 
    return next_getgid();
1349
 
  return get_faked_gid();
1350
 
}
1351
 
 
1352
 
uid_t getegid(void){
1353
 
  if (fakeroot_disabled)
1354
 
    return next_getegid();
1355
 
  return get_faked_egid();
1356
 
}
1357
 
 
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();
1365
 
  return 0;
1366
 
}
1367
 
#endif /* HAVE_GETRESGID */
1368
 
 
1369
 
int setuid(uid_t id){
1370
 
  if (fakeroot_disabled)
1371
 
    return next_setuid(id);
1372
 
  return set_faked_uid(id);
1373
 
}
1374
 
 
1375
 
int setgid(uid_t id){
1376
 
  if (fakeroot_disabled)
1377
 
    return next_setgid(id);
1378
 
  return set_faked_gid(id);
1379
 
}
1380
 
 
1381
 
int seteuid(uid_t id){
1382
 
  if (fakeroot_disabled)
1383
 
    return next_seteuid(id);
1384
 
  return set_faked_euid(id);
1385
 
}
1386
 
 
1387
 
int setegid(uid_t id){
1388
 
  if (fakeroot_disabled)
1389
 
    return next_setegid(id);
1390
 
  return set_faked_egid(id);
1391
 
}
1392
 
 
1393
 
int setreuid(SETREUID_ARG ruid, SETREUID_ARG euid){
1394
 
#ifdef LIBFAKEROOT_DEBUGGING
1395
 
  if (fakeroot_debug) {
1396
 
    fprintf(stderr, "setreuid\n");
1397
 
  }
1398
 
#endif /* LIBFAKEROOT_DEBUGGING */
1399
 
  if (fakeroot_disabled)
1400
 
    return next_setreuid(ruid, euid);
1401
 
  return set_faked_reuid(ruid, euid);
1402
 
}
1403
 
 
1404
 
int setregid(SETREGID_ARG rgid, SETREGID_ARG egid){
1405
 
#ifdef LIBFAKEROOT_DEBUGGING
1406
 
  if (fakeroot_debug) {
1407
 
    fprintf(stderr, "setregid\n");
1408
 
  }
1409
 
#endif /* LIBFAKEROOT_DEBUGGING */
1410
 
  if (fakeroot_disabled)
1411
 
    return next_setregid(rgid, egid);
1412
 
  return set_faked_regid(rgid, egid);
1413
 
}
1414
 
 
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);
1420
 
}
1421
 
#endif /* HAVE_SETRESUID */
1422
 
 
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);
1428
 
}
1429
 
#endif /* HAVE_SETRESGID */
1430
 
 
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);
1436
 
}
1437
 
#endif /* HAVE_SETFSUID */
1438
 
 
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);
1444
 
}
1445
 
#endif /* HAVE_SETFSGID */
1446
 
 
1447
 
int initgroups(const char* user, INITGROUPS_SECOND_ARG group){
1448
 
  if (fakeroot_disabled)
1449
 
    return next_initgroups(user, group);
1450
 
  else
1451
 
    return 0;
1452
 
}
1453
 
 
1454
 
int setgroups(SETGROUPS_SIZE_TYPE size, const gid_t *list){
1455
 
  if (fakeroot_disabled)
1456
 
    return next_setgroups(size, list);
1457
 
  else
1458
 
    return 0;
1459
 
}
1460
 
 
1461
 
int fakeroot_disable(int new)
1462
 
{
1463
 
  int old = fakeroot_disabled;
1464
 
  fakeroot_disabled = new ? 1 : 0;
1465
 
  return old;
1466
 
}
1467
 
 
1468
 
int fakeroot_isdisabled(void)
1469
 
{
1470
 
  return fakeroot_disabled;
1471
 
}
1472
 
 
1473
 
#ifdef HAVE_SYS_ACL_H
1474
 
int acl_set_fd(int fd, acl_t acl) {
1475
 
  errno = ENOTSUP;
1476
 
  return -1;
1477
 
}
1478
 
 
1479
 
int acl_set_file(const char *path_p, acl_type_t type, acl_t acl) {
1480
 
  errno = ENOTSUP;
1481
 
  return -1;
1482
 
}
1483
 
#endif /* HAVE_SYS_ACL_H */
1484
 
 
1485
 
#ifdef HAVE_FTS_READ
1486
 
FTSENT *fts_read(FTS *ftsp) {
1487
 
  FTSENT *r;
1488
 
 
1489
 
#ifdef LIBFAKEROOT_DEBUGGING
1490
 
  if (fakeroot_debug) {
1491
 
    fprintf(stderr, "fts_read\n");
1492
 
  }
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);
1498
 
# else
1499
 
    SEND_GET_STAT(r->fts_statp, _STAT_VER);
1500
 
# endif
1501
 
  }
1502
 
 
1503
 
  return r;
1504
 
}
1505
 
#endif /* HAVE_FTS_READ */
1506
 
 
1507
 
#ifdef HAVE_FTS_CHILDREN
1508
 
FTSENT *fts_children(FTS *ftsp, int options) {
1509
 
  FTSENT *first, *r;
1510
 
 
1511
 
#ifdef LIBFAKEROOT_DEBUGGING
1512
 
  if (fakeroot_debug) {
1513
 
    fprintf(stderr, "fts_children\n");
1514
 
  }
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);
1521
 
# else
1522
 
      SEND_GET_STAT(r->fts_statp, _STAT_VER);
1523
 
# endif
1524
 
    }
1525
 
  }
1526
 
 
1527
 
  return first;
1528
 
}
1529
 
#endif /* HAVE_FTS_CHILDREN */
1530
 
 
1531
 
#ifdef __APPLE__
1532
 
#ifdef __LP64__
1533
 
int
1534
 
getattrlist(const char *path, void *attrList, void *attrBuf,
1535
 
            size_t attrBufSize, unsigned int options)
1536
 
#else
1537
 
int
1538
 
getattrlist(const char *path, void *attrList, void *attrBuf,
1539
 
            size_t attrBufSize, unsigned long options)
1540
 
#endif
1541
 
{
1542
 
  int r;
1543
 
  struct stat st;
1544
 
 
1545
 
#ifdef LIBFAKEROOT_DEBUGGING
1546
 
  if (fakeroot_debug) {
1547
 
    fprintf(stderr, "getattrlist path %s\n", path);
1548
 
  }
1549
 
#endif /* LIBFAKEROOT_DEBUGGING */
1550
 
  r=next_getattrlist(path, attrList, attrBuf, attrBufSize, options);
1551
 
  if (r) {
1552
 
    return r;
1553
 
  }
1554
 
  if (options & FSOPT_NOFOLLOW) {
1555
 
    r=lstat(path, &st);
1556
 
  } else {
1557
 
    r=stat(path, &st);
1558
 
  }
1559
 
  if (r) {
1560
 
    return r;
1561
 
  }
1562
 
  patchattr(attrList, attrBuf, st.st_uid, st.st_gid);
1563
 
 
1564
 
  return 0;
1565
 
}
1566
 
 
1567
 
#ifdef __LP64__
1568
 
int
1569
 
fgetattrlist(int fd, void *attrList, void *attrBuf,
1570
 
             size_t attrBufSize, unsigned int options)
1571
 
#else
1572
 
int
1573
 
fgetattrlist(int fd, void *attrList, void *attrBuf,
1574
 
             size_t attrBufSize, unsigned long options)
1575
 
#endif
1576
 
{
1577
 
  int r;
1578
 
  struct stat st;
1579
 
 
1580
 
#ifdef LIBFAKEROOT_DEBUGGING
1581
 
  if (fakeroot_debug) {
1582
 
    fprintf(stderr, "fgetattrlist fd %d\n", fd);
1583
 
  }
1584
 
#endif /* LIBFAKEROOT_DEBUGGING */
1585
 
  r=next_fgetattrlist(fd, attrList, attrBuf, attrBufSize, options);
1586
 
  if (r) {
1587
 
    return r;
1588
 
  }
1589
 
  r=fstat(fd, &st);
1590
 
  if (r) {
1591
 
    return r;
1592
 
  }
1593
 
  patchattr(attrList, attrBuf, st.st_uid, st.st_gid);
1594
 
 
1595
 
  return 0;
1596
 
}
1597
 
#endif /* ifdef __APPLE__ */