~ubuntu-branches/debian/lenny/netatalk/lenny

« back to all changes in this revision

Viewing changes to etc/afpd/filedir.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: filedir.c,v 1.32.2.3 2003/06/09 14:53:15 srittau Exp $
 
3
 *
 
4
 * Copyright (c) 1990,1993 Regents of The University of Michigan.
 
5
 * All Rights Reserved.  See COPYRIGHT.
 
6
 */
 
7
 
 
8
#ifdef HAVE_CONFIG_H
 
9
#include "config.h"
 
10
#endif /* HAVE_CONFIG_H */
 
11
 
 
12
#include <errno.h>
 
13
#include <atalk/logger.h>
 
14
#include <sys/types.h>
 
15
#include <sys/stat.h>
 
16
#include <sys/param.h>
 
17
#include <netatalk/endian.h>
 
18
#include <atalk/adouble.h>
 
19
#include <atalk/afp.h>
 
20
#include <atalk/util.h>
 
21
#ifdef CNID_DB
 
22
#include <atalk/cnid.h>
 
23
#endif /* CNID_DB */
 
24
#include <stdio.h>
 
25
#include <stdlib.h>
 
26
#ifdef HAVE_FCNTL_H
 
27
#include <fcntl.h>
 
28
#endif /* HAVE_FCNTL_H */
 
29
#include <dirent.h>
 
30
 
 
31
/* STDC check */
 
32
#if STDC_HEADERS
 
33
#include <string.h>
 
34
#else /* STDC_HEADERS */
 
35
#ifndef HAVE_STRCHR
 
36
#define strchr index
 
37
#define strrchr index
 
38
#endif /* HAVE_STRCHR */
 
39
char *strchr (), *strrchr ();
 
40
#ifndef HAVE_MEMCPY
 
41
#define memcpy(d,s,n) bcopy ((s), (d), (n))
 
42
#define memmove(d,s,n) bcopy ((s), (d), (n))
 
43
#endif /* ! HAVE_MEMCPY */
 
44
#endif /* STDC_HEADERS */
 
45
 
 
46
#ifdef HAVE_UNISTD_H
 
47
#include <unistd.h>
 
48
#endif /* HAVE_UNISTD_H */
 
49
 
 
50
#include "directory.h"
 
51
#include "desktop.h"
 
52
#include "volume.h"
 
53
#include "fork.h"
 
54
#include "file.h"
 
55
#include "globals.h"
 
56
#include "filedir.h"
 
57
#include "unix.h"
 
58
 
 
59
int matchfile2dirperms(upath, vol, did)
 
60
/* Since it's kinda' big; I decided against an
 
61
inline function */
 
62
char    *upath;
 
63
struct vol  *vol;
 
64
int             did;
 
65
/* The below code changes the way file ownership is determined in the name of
 
66
fixing dropboxes.  It has known security problem.  See the netatalk FAQ for
 
67
more information */
 
68
{
 
69
    struct stat st, sb;
 
70
    struct dir  *dir;
 
71
    char        *adpath;
 
72
    int         uid;
 
73
    int         ret = AFP_OK;
 
74
#ifdef DEBUG
 
75
    LOG(log_info, logtype_afpd, "begin matchfile2dirperms:");
 
76
#endif /* DEBUG */
 
77
 
 
78
    if (stat(upath, &st ) < 0) {
 
79
        LOG(log_error, logtype_afpd, "Could not stat %s: %s", upath, strerror(errno));
 
80
        return AFPERR_NOOBJ ;
 
81
    }
 
82
 
 
83
    adpath = ad_path( upath, ADFLAGS_HF );
 
84
    /* FIXME dirsearch doesn't move cwd to did ! */
 
85
    if (( dir = dirlookup( vol, did )) == NULL ) {
 
86
        LOG(log_error, logtype_afpd, "matchfile2dirperms: Unable to get directory info.");
 
87
        ret = AFPERR_NOOBJ;
 
88
    }
 
89
    else if (stat(".", &sb) < 0) {
 
90
        LOG(log_error, logtype_afpd,
 
91
            "matchfile2dirperms: Error checking directory \"%s\": %s",
 
92
            dir->d_name, strerror(errno));
 
93
        ret = AFPERR_NOOBJ;
 
94
    }
 
95
    else {
 
96
        uid=geteuid();
 
97
        if ( uid != sb.st_uid )
 
98
        {
 
99
            seteuid(0);
 
100
            if (lchown(upath, sb.st_uid, sb.st_gid) < 0)
 
101
            {
 
102
                LOG(log_error, logtype_afpd,
 
103
                    "matchfile2dirperms: Error changing owner/gid of %s: %s",
 
104
                    upath, strerror(errno));
 
105
                ret = AFPERR_ACCESS;
 
106
            }
 
107
            else if (chmod(upath,(st.st_mode&~default_options.umask)| S_IRGRP| S_IROTH) < 0)
 
108
            {
 
109
                LOG(log_error, logtype_afpd,
 
110
                    "matchfile2dirperms:  Error adding file read permissions: %s",
 
111
                    strerror(errno));
 
112
                ret = AFPERR_ACCESS;
 
113
            }
 
114
            else if (lchown(adpath, sb.st_uid, sb.st_gid) < 0)
 
115
            {
 
116
                LOG(log_error, logtype_afpd,
 
117
                    "matchfile2dirperms: Error changing AppleDouble owner/gid %s: %s",
 
118
                    adpath, strerror(errno));
 
119
                ret = AFPERR_ACCESS;
 
120
            }
 
121
            else if (chmod(adpath, (st.st_mode&~default_options.umask)| S_IRGRP| S_IROTH) < 0)
 
122
            {
 
123
                LOG(log_error, logtype_afpd,
 
124
                    "matchfile2dirperms:  Error adding AD file read permissions: %s",
 
125
                    strerror(errno));
 
126
                ret = AFPERR_ACCESS;
 
127
            }
 
128
            seteuid(uid); 
 
129
        }
 
130
    } /* end else if stat success */
 
131
 
 
132
#ifdef DEBUG
 
133
    LOG(log_info, logtype_afpd, "end matchfile2dirperms:");
 
134
#endif /* DEBUG */
 
135
    return ret;
 
136
}
 
137
 
 
138
 
 
139
int afp_getfildirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
 
140
AFPObj      *obj;
 
141
char    *ibuf, *rbuf;
 
142
int             ibuflen, *rbuflen;
 
143
{
 
144
    struct stat         st;
 
145
    struct vol          *vol;
 
146
    struct dir          *dir;
 
147
    u_int32_t           did;
 
148
    int                 buflen, ret;
 
149
    char                *path;
 
150
    u_int16_t           fbitmap, dbitmap, vid;
 
151
 
 
152
#ifdef DEBUG
 
153
    LOG(log_info, logtype_afpd, "begin afp_getfildirparams:");
 
154
#endif /* DEBUG */
 
155
 
 
156
    *rbuflen = 0;
 
157
    ibuf += 2;
 
158
 
 
159
    memcpy( &vid, ibuf, sizeof( vid ));
 
160
    ibuf += sizeof( vid );
 
161
    if (( vol = getvolbyvid( vid )) == NULL ) {
 
162
        return( AFPERR_PARAM );
 
163
    }
 
164
 
 
165
    memcpy( &did, ibuf, sizeof( did ));
 
166
    ibuf += sizeof( did );
 
167
 
 
168
    if (( dir = dirlookup( vol, did )) == NULL ) {
 
169
        /* FIXME: EACCES */
 
170
        return( AFPERR_NOOBJ );
 
171
    }
 
172
 
 
173
    memcpy( &fbitmap, ibuf, sizeof( fbitmap ));
 
174
    fbitmap = ntohs( fbitmap );
 
175
    ibuf += sizeof( fbitmap );
 
176
    memcpy( &dbitmap, ibuf, sizeof( dbitmap ));
 
177
    dbitmap = ntohs( dbitmap );
 
178
    ibuf += sizeof( dbitmap );
 
179
 
 
180
    if (( path = cname( vol, dir, &ibuf )) == NULL || 
 
181
          stat( mtoupath(vol, path ), &st ) < 0 ) {
 
182
        switch (errno) {
 
183
        case EACCES:
 
184
        case EPERM:
 
185
            return AFPERR_ACCESS;
 
186
        default:
 
187
            return AFPERR_NOOBJ;
 
188
        }
 
189
    }
 
190
 
 
191
    buflen = 0;
 
192
    if (S_ISDIR(st.st_mode)) {
 
193
        if (dbitmap) {
 
194
            if (*path != '\0') {
 
195
                /* the dir wasn't in the cache and we weren't able to chdir in it.
 
196
                */
 
197
                return AFPERR_ACCESS;
 
198
            }
 
199
            ret = getdirparams(vol, dbitmap, ".", curdir,
 
200
                               &st, rbuf + 3 * sizeof( u_int16_t ), &buflen );
 
201
            if (ret != AFP_OK )
 
202
                return( ret );
 
203
        }
 
204
        /* this is a directory */
 
205
        *(rbuf + 2 * sizeof( u_int16_t )) = (char) FILDIRBIT_ISDIR;
 
206
    } else {
 
207
        if (fbitmap && ( ret = getfilparams(vol, fbitmap, path, curdir, &st,
 
208
                                            rbuf + 3 * sizeof( u_int16_t ), &buflen )) != AFP_OK ) {
 
209
            return( ret );
 
210
        }
 
211
        /* this is a file */
 
212
        *(rbuf + 2 * sizeof( u_int16_t )) = FILDIRBIT_ISFILE;
 
213
    }
 
214
    *rbuflen = buflen + 3 * sizeof( u_int16_t );
 
215
    fbitmap = htons( fbitmap );
 
216
    memcpy( rbuf, &fbitmap, sizeof( fbitmap ));
 
217
    rbuf += sizeof( fbitmap );
 
218
    dbitmap = htons( dbitmap );
 
219
    memcpy( rbuf, &dbitmap, sizeof( dbitmap ));
 
220
    rbuf += sizeof( dbitmap ) + sizeof( u_char );
 
221
    *rbuf = 0;
 
222
 
 
223
#ifdef DEBUG
 
224
    LOG(log_info, logtype_afpd, "end afp_getfildirparams:");
 
225
#endif /* DEBUG */
 
226
 
 
227
    return( AFP_OK );
 
228
}
 
229
 
 
230
/*
 
231
 * We can't use unix file's perm to support Apple's inherited protection modes.
 
232
 * If we aren't the file's owner we can't change its perms when moving it and smb
 
233
 * nfs,... don't even try.
 
234
*/
 
235
#define AFP_CHECK_ACCESS 
 
236
 
 
237
int check_access(char *path, int mode)
 
238
{
 
239
#ifdef AFP_CHECK_ACCESS
 
240
struct maccess ma;
 
241
char *p;
 
242
 
 
243
    p = ad_dir(path);
 
244
    if (!p)
 
245
       return -1;
 
246
 
 
247
    accessmode(p, &ma, curdir, NULL);
 
248
    if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE))
 
249
        return -1;
 
250
    if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD))
 
251
        return -1;
 
252
#endif
 
253
    return 0;
 
254
}
 
255
 
 
256
int afp_setfildirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
 
257
AFPObj      *obj;
 
258
char    *ibuf, *rbuf;
 
259
int             ibuflen, *rbuflen;
 
260
{
 
261
    struct stat st;
 
262
    struct vol  *vol;
 
263
    struct dir  *dir;
 
264
    char        *path;
 
265
    u_int16_t   vid, bitmap;
 
266
    int         did, rc;
 
267
 
 
268
#ifdef DEBUG
 
269
    LOG(log_info, logtype_afpd, "begin afp_setfildirparams:");
 
270
#endif /* DEBUG */
 
271
 
 
272
    *rbuflen = 0;
 
273
    ibuf += 2;
 
274
    memcpy( &vid, ibuf, sizeof(vid));
 
275
    ibuf += sizeof( vid );
 
276
 
 
277
    if (( vol = getvolbyvid( vid )) == NULL ) {
 
278
        return( AFPERR_PARAM );
 
279
    }
 
280
 
 
281
    if (vol->v_flags & AFPVOL_RO)
 
282
        return AFPERR_VLOCK;
 
283
 
 
284
    memcpy( &did, ibuf, sizeof( did));
 
285
    ibuf += sizeof( did);
 
286
 
 
287
    if (( dir = dirlookup( vol, did )) == NULL ) {
 
288
        return( AFPERR_NOOBJ );
 
289
    }
 
290
 
 
291
    memcpy( &bitmap, ibuf, sizeof( bitmap ));
 
292
    bitmap = ntohs( bitmap );
 
293
    ibuf += sizeof( bitmap );
 
294
 
 
295
    if (( path = cname( vol, dir, &ibuf )) == NULL ) {
 
296
        return( AFPERR_NOOBJ );
 
297
    }
 
298
 
 
299
    if ( stat( mtoupath(vol, path ), &st ) < 0 ) {
 
300
        return( AFPERR_NOOBJ );
 
301
    }
 
302
 
 
303
    /*
 
304
     * If ibuf is odd, make it even.
 
305
     */
 
306
    if ((u_long)ibuf & 1 ) {
 
307
        ibuf++;
 
308
    }
 
309
 
 
310
    if (S_ISDIR(st.st_mode)) {
 
311
        rc = setdirparams(vol, path, bitmap, ibuf );
 
312
    } else {
 
313
        rc = setfilparams(vol, path, bitmap, ibuf );
 
314
    }
 
315
    if ( rc == AFP_OK ) {
 
316
        setvoltime(obj, vol );
 
317
    }
 
318
 
 
319
#ifdef DEBUG
 
320
    LOG(log_info, logtype_afpd, "end afp_setfildirparams:");
 
321
#endif /* DEBUG */
 
322
 
 
323
    return( rc );
 
324
}
 
325
 
 
326
/* -------------------------------------------- 
 
327
   Factorise some check on a pathname
 
328
*/
 
329
int check_name(const struct vol *vol, char *name)
 
330
{
 
331
    /* check for illegal characters in the unix filename */
 
332
    if (!wincheck(vol, name))
 
333
        return AFPERR_PARAM;
 
334
 
 
335
    if ((vol->v_flags & AFPVOL_NOHEX) && strchr(name, '/'))
 
336
        return AFPERR_PARAM;
 
337
 
 
338
    if (!validupath(vol, name))
 
339
        return AFPERR_EXIST;
 
340
 
 
341
    /* check for vetoed filenames */
 
342
    if (veto_file(vol->v_veto, name))
 
343
        return AFPERR_EXIST;
 
344
    return 0;
 
345
}
 
346
 
 
347
/* ------------------------- 
 
348
    move and rename sdir:oldname to curdir:newname in volume vol
 
349
   
 
350
    special care is needed for lock   
 
351
*/
 
352
static int moveandrename(vol, sdir, oldname, newname, isdir)
 
353
const struct vol        *vol;
 
354
struct dir      *sdir;
 
355
char        *oldname;
 
356
char        *newname;
 
357
int         isdir;
 
358
{
 
359
    char            *p;
 
360
    char            *upath;
 
361
    int             rc;
 
362
    struct stat     st;
 
363
    int             adflags;
 
364
    struct adouble      ad;
 
365
    struct adouble      *adp;
 
366
    struct ofork        *opened;
 
367
 
 
368
#ifdef CNID_DB
 
369
    cnid_t      id;
 
370
#endif /* CNID_DB */
 
371
 
 
372
    memset(&ad, 0, sizeof(ad));
 
373
    adp = &ad;
 
374
    adflags = 0;
 
375
    
 
376
    if (!isdir) {
 
377
#ifdef CNID_DB
 
378
        p = mtoupath(vol, oldname);
 
379
        id = cnid_get(vol->v_db, sdir->d_did, p, strlen(p));
 
380
#endif /* CNID_DB */
 
381
        p = ctoupath( vol, sdir, oldname );
 
382
        if ((opened = of_findname(p, NULL))) {
 
383
            /* reuse struct adouble so it won't break locks */
 
384
            adp = opened->of_ad;
 
385
        }
 
386
    }
 
387
    else {
 
388
#ifdef CNID_DB
 
389
        id = sdir->d_did; /* we already have the CNID */
 
390
#endif /* CNID_DB */
 
391
        p = ctoupath( vol, sdir->d_parent, oldname );
 
392
        adflags = ADFLAGS_DIR;
 
393
    }
 
394
    /*
 
395
     * p now points to the full pathname of the source fs object.
 
396
     * 
 
397
     * we are in the dest folder so we need to use p for ad_open
 
398
    */
 
399
    
 
400
    if (!ad_open(p, ADFLAGS_HF |adflags, O_RDONLY, 0666, adp)) {
 
401
    u_int16_t bshort;
 
402
 
 
403
        ad_getattr(adp, &bshort);
 
404
        ad_close( adp, ADFLAGS_HF );
 
405
        if ((bshort & htons(ATTRBIT_NORENAME))) 
 
406
            return(AFPERR_OLOCK);
 
407
    }
 
408
 
 
409
    upath = mtoupath(vol, newname);
 
410
    if (0 != (rc = check_name(vol, upath))) {
 
411
            return  rc;
 
412
    }
 
413
 
 
414
    /* source == destination. we just silently accept this. */
 
415
    if (curdir == sdir) {
 
416
        if (strcmp(oldname, newname) == 0)
 
417
            return AFP_OK;
 
418
 
 
419
        /* deal with case insensitive, case-preserving filesystems. */
 
420
        if ((stat(upath, &st) == 0) && strdiacasecmp(oldname, newname))
 
421
            return AFPERR_EXIST;
 
422
 
 
423
    } else if (stat(upath, &st ) == 0)
 
424
        return AFPERR_EXIST;
 
425
 
 
426
    if ( !isdir ) {
 
427
        if (of_findname(upath, &st)) {
 
428
            rc = AFPERR_EXIST; /* was AFPERR_BUSY; */
 
429
        } else {
 
430
            rc = renamefile( p, upath, newname,vol_noadouble(vol), adp );
 
431
            if (rc == AFP_OK)
 
432
                of_rename(vol, opened, sdir, oldname, curdir, newname);
 
433
        }
 
434
    } else {
 
435
        rc = renamedir(p, upath, sdir, curdir, newname, vol_noadouble(vol));
 
436
    }
 
437
    if ( rc == AFP_OK ) {
 
438
#ifdef CNID_DB
 
439
        /* renaming may have moved the file/dir across a filesystem */
 
440
        if (stat(upath, &st) < 0)
 
441
            return AFPERR_MISC;
 
442
 
 
443
        /* fix up the catalog entry */
 
444
        cnid_update(vol->v_db, id, &st, curdir->d_did, upath, strlen(upath));
 
445
#endif /* CNID_DB */
 
446
    }
 
447
 
 
448
    return rc;
 
449
}
 
450
 
 
451
/* -------------------------------------------- */
 
452
int afp_rename(obj, ibuf, ibuflen, rbuf, rbuflen )
 
453
AFPObj      *obj;
 
454
char    *ibuf, *rbuf;
 
455
int             ibuflen, *rbuflen;
 
456
{
 
457
    struct vol  *vol;
 
458
    struct dir  *sdir;
 
459
    char                *path, *oldname, *newname;
 
460
    u_int32_t   did;
 
461
    int                 plen;
 
462
    u_int16_t   vid;
 
463
    int         isdir = 0;
 
464
    int         rc;
 
465
#ifdef DEBUG
 
466
    LOG(log_info, logtype_afpd, "begin afp_rename:");
 
467
#endif /* DEBUG */
 
468
 
 
469
    *rbuflen = 0;
 
470
    ibuf += 2;
 
471
 
 
472
    memcpy( &vid, ibuf, sizeof( vid ));
 
473
    ibuf += sizeof( vid );
 
474
    if (( vol = getvolbyvid( vid )) == NULL ) {
 
475
        return( AFPERR_PARAM );
 
476
    }
 
477
 
 
478
    if (vol->v_flags & AFPVOL_RO)
 
479
        return AFPERR_VLOCK;
 
480
 
 
481
    memcpy( &did, ibuf, sizeof( did ));
 
482
    ibuf += sizeof( did );
 
483
    if (( sdir = dirlookup( vol, did )) == NULL ) {
 
484
        return( AFPERR_NOOBJ );
 
485
    }
 
486
 
 
487
    /* source pathname */
 
488
    if (( path = cname( vol, sdir, &ibuf )) == NULL ) {
 
489
        return( AFPERR_NOOBJ );
 
490
    }
 
491
 
 
492
    sdir = curdir;
 
493
    newname = obj->newtmp;
 
494
    oldname = obj->oldtmp;
 
495
    if ( *path != '\0' ) {
 
496
        strcpy(oldname, path); /* an extra copy for of_rename */
 
497
    }
 
498
    else {
 
499
        if ( sdir->d_parent == NULL ) { /* root directory */
 
500
            return( AFPERR_NORENAME );
 
501
        }
 
502
        /* move to destination dir */
 
503
        if ( movecwd( vol, sdir->d_parent ) < 0 ) {
 
504
            return( AFPERR_NOOBJ );
 
505
        }
 
506
        isdir = 1;
 
507
        strcpy(oldname, sdir->d_name);
 
508
    }
 
509
 
 
510
    /* another place where we know about the path type */
 
511
    if ( *ibuf++ != 2 ) {
 
512
        return( AFPERR_PARAM );
 
513
    }
 
514
 
 
515
    if (( plen = (unsigned char)*ibuf++ ) != 0 ) {
 
516
        strncpy( newname, ibuf, plen );
 
517
        newname[ plen ] = '\0';
 
518
        if (strlen(newname) != plen) {
 
519
            return( AFPERR_PARAM );
 
520
        }
 
521
    }
 
522
    else {
 
523
        return AFP_OK; /* newname == oldname same dir */
 
524
    }
 
525
    
 
526
    rc = moveandrename(vol, sdir, oldname, newname, isdir);
 
527
 
 
528
    if ( rc == AFP_OK ) {
 
529
        setvoltime(obj, vol );
 
530
    }
 
531
 
 
532
#ifdef DEBUG
 
533
    LOG(log_info, logtype_afpd, "end afp_rename:");
 
534
#endif /* DEBUG */
 
535
 
 
536
    return( rc );
 
537
}
 
538
 
 
539
/* ------------------------------- */
 
540
int afp_delete(obj, ibuf, ibuflen, rbuf, rbuflen )
 
541
AFPObj      *obj;
 
542
char    *ibuf, *rbuf;
 
543
int             ibuflen, *rbuflen;
 
544
{
 
545
    struct vol          *vol;
 
546
    struct dir          *dir;
 
547
    char                *path, *upath;
 
548
    int                 did, rc;
 
549
    u_int16_t           vid;
 
550
 
 
551
#ifdef DEBUG
 
552
    LOG(log_info, logtype_afpd, "begin afp_delete:");
 
553
#endif /* DEBUG */ 
 
554
 
 
555
    *rbuflen = 0;
 
556
    ibuf += 2;
 
557
 
 
558
    memcpy( &vid, ibuf, sizeof( vid ));
 
559
    ibuf += sizeof( vid );
 
560
    if (( vol = getvolbyvid( vid )) == NULL ) {
 
561
        return( AFPERR_PARAM );
 
562
    }
 
563
 
 
564
    if (vol->v_flags & AFPVOL_RO)
 
565
        return AFPERR_VLOCK;
 
566
 
 
567
    memcpy( &did, ibuf, sizeof( did ));
 
568
    ibuf += sizeof( int );
 
569
    if (( dir = dirlookup( vol, did )) == NULL ) {
 
570
        return( AFPERR_NOOBJ );
 
571
    }
 
572
 
 
573
    if (( path = cname( vol, dir, &ibuf )) == NULL ) {
 
574
        return( AFPERR_NOOBJ );
 
575
    }
 
576
 
 
577
    upath = mtoupath(vol, path );
 
578
    if ( *path == '\0' ) {
 
579
        rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
 
580
    } else if (of_findname(upath, NULL)) {
 
581
        rc = AFPERR_BUSY;
 
582
    } else if ((rc = deletefile( upath, 1)) == AFP_OK) {
 
583
#ifdef CNID_DB /* get rid of entry */
 
584
        cnid_t id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
 
585
        cnid_delete(vol->v_db, id);
 
586
#endif /* CNID_DB */
 
587
    }
 
588
    if ( rc == AFP_OK ) {
 
589
        setvoltime(obj, vol );
 
590
    }
 
591
 
 
592
#ifdef DEBUG
 
593
    LOG(log_info, logtype_afpd, "end afp_delete:");
 
594
#endif /* DEBUG */
 
595
 
 
596
    return( rc );
 
597
}
 
598
 
 
599
char *ctoupath( vol, dir, name )
 
600
const struct vol        *vol;
 
601
struct dir      *dir;
 
602
char    *name;
 
603
{
 
604
    struct dir  *d;
 
605
    static char path[ MAXPATHLEN + 1];
 
606
    char        *p, *u;
 
607
    int         len;
 
608
 
 
609
    p = path + sizeof( path ) - 1;
 
610
    *p = '\0';
 
611
    u = mtoupath(vol, name );
 
612
    len = strlen( u );
 
613
    p -= len;
 
614
    strncpy( p, u, len );
 
615
    for ( d = dir; d->d_parent; d = d->d_parent ) {
 
616
        *--p = '/';
 
617
        u = mtoupath(vol, d->d_name );
 
618
        len = strlen( u );
 
619
        p -= len;
 
620
        strncpy( p, u, len );
 
621
    }
 
622
    *--p = '/';
 
623
    len = strlen( vol->v_path );
 
624
    p -= len;
 
625
    strncpy( p, vol->v_path, len );
 
626
 
 
627
    return( p );
 
628
}
 
629
 
 
630
/* ------------------------- */
 
631
int afp_moveandrename(obj, ibuf, ibuflen, rbuf, rbuflen )
 
632
AFPObj      *obj;
 
633
char    *ibuf, *rbuf;
 
634
int             ibuflen, *rbuflen;
 
635
{
 
636
    struct vol  *vol;
 
637
    struct dir  *sdir, *ddir;
 
638
    int         isdir = 0;
 
639
    char            *oldname, *newname;
 
640
    char        *path;
 
641
    int         did;
 
642
    int         plen;
 
643
    u_int16_t   vid;
 
644
    int         rc;
 
645
#ifdef DROPKLUDGE
 
646
    int         retvalue;
 
647
#endif /* DROPKLUDGE */
 
648
 
 
649
#ifdef DEBUG
 
650
    LOG(log_info, logtype_afpd, "begin afp_moveandrename:");
 
651
#endif /* DEBUG */
 
652
 
 
653
    *rbuflen = 0;
 
654
    ibuf += 2;
 
655
 
 
656
    memcpy( &vid, ibuf, sizeof( vid ));
 
657
    ibuf += sizeof( vid );
 
658
    if (( vol = getvolbyvid( vid )) == NULL ) {
 
659
        return( AFPERR_PARAM );
 
660
    }
 
661
 
 
662
    if (vol->v_flags & AFPVOL_RO)
 
663
        return AFPERR_VLOCK;
 
664
 
 
665
    /* source did followed by dest did */
 
666
    memcpy( &did, ibuf, sizeof( did ));
 
667
    ibuf += sizeof( int );
 
668
    if (( sdir = dirlookup( vol, did )) == NULL ) {
 
669
        return( AFPERR_PARAM );
 
670
    }
 
671
 
 
672
    memcpy( &did, ibuf, sizeof( did ));
 
673
    ibuf += sizeof( int );
 
674
 
 
675
    /* source pathname */
 
676
    if (( path = cname( vol, sdir, &ibuf )) == NULL ) {
 
677
        return( AFPERR_NOOBJ );
 
678
    }
 
679
 
 
680
    sdir = curdir;
 
681
    newname = obj->newtmp;
 
682
    oldname = obj->oldtmp;
 
683
    if ( *path != '\0' ) {
 
684
        /* not a directory */
 
685
        strcpy(oldname, path); /* an extra copy for of_rename */
 
686
    } else {
 
687
        isdir = 1;
 
688
        strcpy(oldname, sdir->d_name);
 
689
    }
 
690
 
 
691
    /* get the destination directory */
 
692
    if (( ddir = dirlookup( vol, did )) == NULL ) {
 
693
        return( AFPERR_PARAM );
 
694
    }
 
695
    if (( path = cname( vol, ddir, &ibuf )) == NULL ) {
 
696
        return( AFPERR_NOOBJ );
 
697
    }
 
698
    if ( *path != '\0' ) {
 
699
        return( AFPERR_BADTYPE );
 
700
    }
 
701
 
 
702
    /* one more place where we know about path type */
 
703
    if ( *ibuf++ != 2 ) {
 
704
        return( AFPERR_PARAM );
 
705
    }
 
706
 
 
707
    if (( plen = (unsigned char)*ibuf++ ) != 0 ) {
 
708
        strncpy( newname, ibuf, plen );
 
709
        newname[ plen ] = '\0';
 
710
        if (strlen(newname) != plen) {
 
711
            return( AFPERR_PARAM );
 
712
        }
 
713
    }
 
714
    else {
 
715
        strcpy(newname, oldname);
 
716
    }
 
717
    
 
718
    rc = moveandrename(vol, sdir, oldname, newname, isdir);
 
719
 
 
720
    if ( rc == AFP_OK ) {
 
721
        char *upath = mtoupath(vol, newname);
 
722
#ifdef DROPKLUDGE
 
723
        if (vol->v_flags & AFPVOL_DROPBOX) {
 
724
            if (retvalue=matchfile2dirperms (upath, vol, did) != AFP_OK) {
 
725
                return retvalue;
 
726
            }
 
727
        }
 
728
        else
 
729
#endif /* DROPKLUDGE */
 
730
            if (!isdir) {
 
731
                int  admode = ad_mode("", 0777);
 
732
 
 
733
                setfilmode(upath, admode, NULL);
 
734
                setfilmode(ad_path( upath, ADFLAGS_HF ), ad_hf_mode(admode), NULL);
 
735
            }
 
736
        setvoltime(obj, vol );
 
737
    }
 
738
 
 
739
#ifdef DEBUG
 
740
    LOG(log_info, logtype_afpd, "end afp_moveandrename:");
 
741
#endif /* DEBUG */
 
742
 
 
743
    return( rc );
 
744
}
 
745
 
 
746
int veto_file(const char*veto_str, const char*path)
 
747
/* given a veto_str like "abc/zxc/" and path "abc", return 1
 
748
 * veto_str should be '/' delimited
 
749
 * if path matches any one of the veto_str elements exactly, then 1 is returned
 
750
 * otherwise, 0 is returned.
 
751
 */
 
752
{
 
753
    int i;      /* index to veto_str */
 
754
    int j;      /* index to path */
 
755
 
 
756
    if ((veto_str == NULL) || (path == NULL))
 
757
        return 0;
 
758
    /*
 
759
    #ifdef DEBUG
 
760
        LOG(log_debug, logtype_afpd, "veto_file \"%s\", \"%s\"", veto_str, path);
 
761
    #endif
 
762
    */
 
763
    for(i=0, j=0; veto_str[i] != '\0'; i++) {
 
764
        if (veto_str[i] == '/') {
 
765
            if ((j>0) && (path[j] == '\0'))
 
766
                return 1;
 
767
            j = 0;
 
768
        } else {
 
769
            if (veto_str[i] != path[j]) {
 
770
                while ((veto_str[i] != '/')
 
771
                        && (veto_str[i] != '\0'))
 
772
                    i++;
 
773
                j = 0;
 
774
                continue;
 
775
            }
 
776
            j++;
 
777
        }
 
778
    }
 
779
    return 0;
 
780
}
 
781