#include <string.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <grp.h>
#include <pwd.h>
#include <sys/param.h>
cnid = htonl(2);
dir = vol->v_root;
+ LOG(log_debug, logtype_afpd, "dirlookup_bypath(\"%s\")", path);
+
+ if (strcmp(vol->v_path, path) == 0)
+ return dir;
+
EC_NULL(rpath = rel_path_in_vol(path, vol->v_path)); /* 1. */
+
+ LOG(log_debug, logtype_afpd, "dirlookup_bypath: rpath: \"%s\"", cfrombstr(rpath));
+
EC_NULL(statpath = bfromcstr(vol->v_path)); /* 2. */
l = bsplit(rpath, '/');
did = cnid;
EC_ZERO(bcatcstr(statpath, "/"));
EC_ZERO(bconcat(statpath, l->entry[i]));
+
+ LOG(log_debug, logtype_afpd, "dirlookup_bypath: statpath: \"%s\"", cfrombstr(statpath));
+
EC_ZERO_LOGSTR(lstat(cfrombstr(statpath), &st),
"lstat(rpath: %s, elem: %s): %s: %s",
cfrombstr(rpath), cfrombstr(l->entry[i]),
dir,
cfrombstr(l->entry[i]),
blength(l->entry[i]))) == NULL) {
+
if ((cnid = cnid_add(vol->v_cdb, /* 6. */
&st,
did,
cfrombstr(l->entry[i]),
blength(l->entry[i]),
- 0)) == CNID_INVALID) {
+ 0)) == CNID_INVALID)
EC_FAIL;
- }
if ((dir = dirlookup(vol, cnid)) == NULL) /* 7. */
EC_FAIL;
if (ret != 0)
return NULL;
+ LOG(log_debug, logtype_afpd, "dirlookup_bypath: result: \"%s\"",
+ cfrombstr(dir->d_fullpath));
+
return dir;
}
DIR *dp;
struct dirent *de;
int ret;
- static u_int32_t did = 0;
+ static uint32_t did = 0;
static char cname[MAXPATHLEN];
static char lname[MAXPATHLEN];
ucs2_t u2_path[MAXPATHLEN];
}
/* get_id needs adp for reading CNID from adouble file */
- ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if ((ad_open_metadata(path->u_name, ADFLAGS_DIR, 0, &ad)) == 0) /* 1 */
+ ad_init(&ad, vol);
+ if ((ad_open(&ad, path->u_name, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDONLY)) == 0) /* 1 */
adp = &ad;
/* Get CNID */
}
if (adp)
- ad_close_metadata(adp);
+ ad_close(adp, ADFLAGS_HF);
/* Get macname from unixname */
if (path->m_name == NULL) {
cfrombstr(dir->d_u_name), path->u_name, err);
if (adp)
- ad_close_metadata(adp);
+ ad_close(adp, ADFLAGS_HF);
if (!cdir && fullpath)
bdestroy(fullpath);
if (cdir)
struct dir *cdir;
char *data, *p;
int len;
- u_int32_t hint;
- u_int16_t len16;
+ uint32_t hint;
+ uint16_t len16;
int size = 0;
int toUTF8 = 0;
if (!p)
return -1;
- accessmode(p, &ma, curdir, NULL);
+ accessmode(current_vol, p, &ma, curdir, NULL);
if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE))
return -1;
if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD))
{
struct maccess ma;
- accessmode(path->u_name, &ma, curdir, &path->st);
+ accessmode(current_vol, path->u_name, &ma, curdir, &path->st);
LOG(log_debug, logtype_afpd, "file_access(\"%s\"): mapped user mode: 0x%02x",
path->u_name, ma.ma_user);
}
/* --------------------- */
-void setdiroffcnt(struct dir *dir, struct stat *st, u_int32_t count)
+void setdiroffcnt(struct dir *dir, struct stat *st, uint32_t count)
{
dir->d_offcnt = count;
dir->d_ctime = st->st_ctime;
*/
int getdirparams(const struct vol *vol,
- u_int16_t bitmap, struct path *s_path,
+ uint16_t bitmap, struct path *s_path,
struct dir *dir,
char *buf, size_t *buflen )
{
struct adouble ad;
char *data, *l_nameoff = NULL, *utf_nameoff = NULL;
int bit = 0, isad = 0;
- u_int32_t aint;
- u_int16_t ashort;
+ uint32_t aint;
+ uint16_t ashort;
int ret;
- u_int32_t utf8 = 0;
+ uint32_t utf8 = 0;
cnid_t pdid;
struct stat *st = &s_path->st;
char *upath = s_path->u_name;
(1 << DIRPBIT_BDATE) |
(1 << DIRPBIT_FINFO)))) {
- ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if ( !ad_metadata( upath, ADFLAGS_CREATE|ADFLAGS_DIR, &ad) ) {
+ ad_init(&ad, vol);
+ if ( !ad_metadata( upath, ADFLAGS_DIR, &ad) ) {
isad = 1;
- if (ad.ad_md->adf_flags & O_CREAT) {
+ if (ad.ad_mdp->adf_flags & O_CREAT) {
/* We just created it */
if (s_path->m_name == NULL) {
if ((s_path->m_name = utompath(vol,
ashort = htons(ATTRBIT_INVISIBLE);
} else
ashort = 0;
- ashort |= htons(ATTRBIT_SHARED);
memcpy( data, &ashort, sizeof( ashort ));
data += sizeof( ashort );
break;
if (dir->d_m_name) /* root of parent can have a null name */
l_nameoff = data;
else
- memset(data, 0, sizeof(u_int16_t));
- data += sizeof( u_int16_t );
+ memset(data, 0, sizeof(uint16_t));
+ data += sizeof( uint16_t );
break;
case DIRPBIT_SNAME :
- memset(data, 0, sizeof(u_int16_t));
- data += sizeof( u_int16_t );
+ memset(data, 0, sizeof(uint16_t));
+ data += sizeof( uint16_t );
break;
case DIRPBIT_DID :
break;
case DIRPBIT_ACCESS :
- accessmode( upath, &ma, dir , st);
+ accessmode(vol, upath, &ma, dir , st);
*data++ = ma.ma_user;
*data++ = ma.ma_world;
if (dir->d_m_name) /* root of parent can have a null name */
utf_nameoff = data;
else
- memset(data, 0, sizeof(u_int16_t));
- data += sizeof( u_int16_t );
+ memset(data, 0, sizeof(uint16_t));
+ data += sizeof( uint16_t );
aint = 0;
memcpy(data, &aint, sizeof( aint ));
data += sizeof( aint );
break;
case DIRPBIT_UNIXPR :
+ /* accessmode may change st_mode with ACLs */
+ accessmode(vol, upath, &ma, dir, st);
+
aint = htonl(st->st_uid);
memcpy( data, &aint, sizeof( aint ));
data += sizeof( aint );
memcpy( data, &aint, sizeof( aint ));
data += sizeof( aint );
- accessmode( upath, &ma, dir , st);
-
*data++ = ma.ma_user;
*data++ = ma.ma_world;
*data++ = ma.ma_group;
default :
if ( isad ) {
- ad_close_metadata( &ad );
+ ad_close(&ad, ADFLAGS_HF);
}
return( AFPERR_BITMAP );
}
data = set_name(vol, data, pdid, cfrombstr(dir->d_m_name), dir->d_did, utf8);
}
if ( isad ) {
- ad_close_metadata( &ad );
+ ad_close(&ad, ADFLAGS_HF);
}
*buflen = data - buf;
return( AFP_OK );
struct vol *vol;
struct dir *dir;
struct path *path;
- u_int16_t vid, bitmap;
- u_int32_t did;
+ uint16_t vid, bitmap;
+ uint32_t did;
int rc;
*rbuflen = 0;
}
/*
- * cf AFP3.0.pdf page 244 for change_mdate and change_parent_mdate logic
- *
* assume path == '\0' eg. it's a directory in canonical form
*/
-int setdirparams(struct vol *vol, struct path *path, u_int16_t d_bitmap, char *buf )
+int setdirparams(struct vol *vol, struct path *path, uint16_t d_bitmap, char *buf )
{
struct maccess ma;
struct adouble ad;
int bit, isad = 1;
int cdate, bdate;
int owner, group;
- u_int16_t ashort, bshort, oshort;
+ uint16_t ashort, bshort, oshort;
int err = AFP_OK;
int change_mdate = 0;
int change_parent_mdate = 0;
int newdate = 0;
- u_int16_t bitmap = d_bitmap;
+ uint16_t bitmap = d_bitmap;
u_char finder_buf[32];
- u_int32_t upriv;
+ uint32_t upriv;
mode_t mpriv = 0;
- u_int16_t upriv_bit = 0;
+ bool set_upriv = false, set_maccess = false;
+
+ LOG(log_debug, logtype_afpd, "setdirparams(%s)", path->u_name);
bit = 0;
upath = path->u_name;
buf += 32;
break;
case DIRPBIT_UID : /* What kind of loser mounts as root? */
- change_parent_mdate = 1;
memcpy( &owner, buf, sizeof(owner));
buf += sizeof( owner );
break;
case DIRPBIT_GID :
- change_parent_mdate = 1;
memcpy( &group, buf, sizeof( group ));
buf += sizeof( group );
break;
case DIRPBIT_ACCESS :
+ set_maccess = true;
change_mdate = 1;
- change_parent_mdate = 1;
ma.ma_user = *buf++;
ma.ma_world = *buf++;
ma.ma_group = *buf++;
ma.ma_owner = *buf++;
mpriv = mtoumode( &ma ) | vol->v_dperm;
- if (dir_rx_set(mpriv) && setdirmode( vol, upath, mpriv) < 0 ) {
- err = set_dir_errors(path, "setdirmode", errno);
- bitmap = 0;
- }
break;
/* Ignore what the client thinks we should do to the
ProDOS information block. Skip over the data and
break;
case DIRPBIT_UNIXPR :
if (vol_unix_priv(vol)) {
+ set_upriv = true;
memcpy( &owner, buf, sizeof(owner)); /* FIXME need to change owner too? */
buf += sizeof( owner );
memcpy( &group, buf, sizeof( group ));
buf += sizeof( group );
change_mdate = 1;
- change_parent_mdate = 1;
memcpy( &upriv, buf, sizeof( upriv ));
buf += sizeof( upriv );
upriv = ntohl (upriv) | vol->v_dperm;
- if (dir_rx_set(upriv)) {
- /* maybe we are trying to set perms back */
- if ( setdirunixmode(vol, upath, upriv) < 0 ) {
- bitmap = 0;
- err = set_dir_errors(path, "setdirunixmode", errno);
- }
- }
- else {
- /* do it later */
- upriv_bit = 1;
- }
break;
}
/* fall through */
bitmap = bitmap>>1;
bit++;
}
- ad_init(&ad, vol->v_adouble, vol->v_ad_options);
+ ad_init(&ad, vol);
- if (ad_open_metadata( upath, ADFLAGS_DIR, O_CREAT, &ad) < 0) {
+ if (ad_open(&ad, upath, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_CREATE | ADFLAGS_RDWR, 0777) != 0) {
/*
* Check to see what we're trying to set. If it's anything
* but ACCESS, UID, or GID, give an error. If it's any of those
* note: we also don't need to worry about mdate. also, be quiet
* if we're using the noadouble option.
*/
+
if (!vol_noadouble(vol) && (d_bitmap &
~((1<<DIRPBIT_ACCESS)|(1<<DIRPBIT_UNIXPR)|
(1<<DIRPBIT_UID)|(1<<DIRPBIT_GID)|
* Check to see if a create was necessary. If it was, we'll want
* to set our name, etc.
*/
- if ( (ad_get_HF_flags( &ad ) & O_CREAT)) {
+ if ( (ad_get_MD_flags( &ad ) & O_CREAT)) {
ad_setname(&ad, cfrombstr(curdir->d_m_name));
}
}
case DIRPBIT_FINFO :
if (isad) {
/* Fixes #2802236 */
- u_int16_t *fflags = (u_int16_t *)(finder_buf + FINDERINFO_FRFLAGOFF);
+ uint16_t *fflags = (uint16_t *)(finder_buf + FINDERINFO_FRFLAGOFF);
*fflags &= htons(~FINDERINFO_ISHARED);
/* #2802236 end */
if ( dir->d_did == DIRDID_ROOT ) {
}
break;
case DIRPBIT_ACCESS :
- if (dir->d_did == DIRDID_ROOT) {
- setdeskmode(mpriv);
- if (!dir_rx_set(mpriv)) {
- /* we can't remove read and search for owner on volume root */
- err = AFPERR_ACCESS;
- goto setdirparam_done;
- }
- }
-
- if (!dir_rx_set(mpriv) && setdirmode( vol, upath, mpriv) < 0 ) {
- err = set_dir_errors(path, "setdirmode", errno);
- goto setdirparam_done;
- }
break;
case DIRPBIT_PDINFO :
if (afp_version >= 30) {
}
break;
case DIRPBIT_UNIXPR :
- if (vol_unix_priv(vol)) {
- if (dir->d_did == DIRDID_ROOT) {
- if (!dir_rx_set(upriv)) {
- /* we can't remove read and search for owner on volume root */
- err = AFPERR_ACCESS;
- goto setdirparam_done;
- }
- setdeskowner( -1, ntohl(group) );
- setdeskmode( upriv );
- }
- if ( setdirowner(vol, upath, -1, ntohl(group) ) < 0 ) {
- err = set_dir_errors(path, "setdirowner", errno);
- goto setdirparam_done;
- }
-
- if ( upriv_bit && setdirunixmode(vol, upath, upriv) < 0 ) {
- err = set_dir_errors(path, "setdirunixmode", errno);
- goto setdirparam_done;
- }
- }
- else {
+ if (!vol_unix_priv(vol)) {
err = AFPERR_BITMAP;
goto setdirparam_done;
}
ad_setid(&ad, st->st_dev, st->st_ino, dir->d_did, dir->d_pdid, vol->v_stamp);
}
}
- ad_flush( &ad);
- ad_close_metadata( &ad);
+ if (ad_flush(&ad) != 0) {
+ switch (errno) {
+ case EACCES:
+ err = AFPERR_ACCESS;
+ break;
+ default:
+ err = AFPERR_MISC;
+ break;
+ }
+ }
+ ad_close(&ad, ADFLAGS_HF);
}
+ if (err == AFP_OK) {
+ if (set_maccess == true) {
+ if (dir->d_did == DIRDID_ROOT) {
+ setdeskmode(mpriv);
+ if (!dir_rx_set(mpriv)) {
+ /* we can't remove read and search for owner on volume root */
+ err = AFPERR_ACCESS;
+ goto setprivdone;
+ }
+ }
+ if (setdirmode(vol, upath, mpriv) < 0)
+ err = set_dir_errors(path, "setdirmode", errno);
+ }
+ if ((set_upriv == true) && vol_unix_priv(vol)) {
+ if (dir->d_did == DIRDID_ROOT) {
+ if (!dir_rx_set(upriv)) {
+ /* we can't remove read and search for owner on volume root */
+ err = AFPERR_ACCESS;
+ goto setprivdone;
+ }
+ setdeskowner(-1, ntohl(group));
+ setdeskmode(upriv);
+ }
+
+ if (setdirowner(vol, upath, -1, ntohl(group)) < 0) {
+ err = set_dir_errors(path, "setdirowner", errno);
+ goto setprivdone;
+ }
+
+
+ if (setdirunixmode(vol, upath, upriv) < 0)
+ err = set_dir_errors(path, "setdirunixmode", errno);
+ }
+ }
+
+setprivdone:
if (change_parent_mdate && dir->d_did != DIRDID_ROOT
&& gettimeofday(&tv, NULL) == 0) {
if (movecwd(vol, dirlookup(vol, dir->d_pdid)) == 0) {
/* should we reset curdir ?*/
}
}
-
return err;
}
int dfd;
struct vol *vol;
struct dir *dir;
- u_int32_t did;
- u_int16_t vid;
+ uint32_t did;
+ uint16_t vid;
*rbuflen = 0;
ibuf += 2;
struct dir *dir;
char *upath;
struct path *s_path;
- u_int32_t did;
- u_int16_t vid;
+ uint32_t did;
+ uint16_t vid;
int err;
*rbuflen = 0;
return( AFPERR_PARAM );
}
- ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if (ad_open_metadata( ".", ADFLAGS_DIR, O_CREAT, &ad ) < 0) {
+ ad_init(&ad, vol);
+ if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_CREATE | ADFLAGS_RDWR, 0777) < 0) {
if (vol_noadouble(vol))
goto createdir_done;
return( AFPERR_ACCESS );
fce_register_new_dir(s_path);
- ad_flush( &ad);
- ad_close_metadata( &ad);
+ ad_flush(&ad);
+ ad_close(&ad, ADFLAGS_HF);
createdir_done:
- memcpy( rbuf, &dir->d_did, sizeof( u_int32_t ));
- *rbuflen = sizeof( u_int32_t );
+ memcpy( rbuf, &dir->d_did, sizeof( uint32_t ));
+ *rbuflen = sizeof( uint32_t );
setvoltime(obj, vol );
return( AFP_OK );
}
vol->vfs->vfs_renamedir(vol, dirfd, src, dst);
- ad_init(&ad, vol->v_adouble, vol->v_ad_options);
+ ad_init(&ad, vol);
- if (!ad_open_metadata( dst, ADFLAGS_DIR, 0, &ad)) {
+ if (ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR) == 0) {
ad_setname(&ad, newname);
- ad_flush( &ad);
- ad_close_metadata( &ad);
+ ad_flush(&ad);
+ ad_close(&ad, ADFLAGS_HF);
}
return( AFP_OK );
struct dir *fdir, *pdir;
DIR *dp;
struct adouble ad;
- u_int16_t ashort;
+ uint16_t ashort;
int err;
if ((pdir = dirlookup(vol, curdir->d_pdid)) == NULL) {
fdir = curdir;
- ad_init(&ad, vol->v_adouble, vol->v_ad_options);
+ ad_init(&ad, vol);
/* we never want to create a resource fork here, we are going to delete it */
if ( ad_metadata( ".", ADFLAGS_DIR, &ad) == 0 ) {
ad_getattr(&ad, &ashort);
- ad_close_metadata(&ad);
+ ad_close(&ad, ADFLAGS_HF);
if ((ashort & htons(ATTRBIT_NODELETE))) {
return AFPERR_OLOCK;
}
dir_remove( vol, fdir );
} else {
LOG(log_error, logtype_afpd, "deletecurdir(\"%s\"): netatalk_rmdir_all_errors error",
- curdir->d_fullpath);
+ cfrombstr(curdir->d_fullpath));
}
delete_done:
struct passwd *pw;
struct group *gr;
char *name;
- u_int32_t id;
+ uint32_t id;
int len, sfunc;
int utf8 = 0;
len = strlen( name );
if (utf8) {
- u_int16_t tp = htons(len);
+ uint16_t tp = htons(len);
memcpy(rbuf, &tp, sizeof(tp));
rbuf += sizeof(tp);
*rbuflen += 2;
struct passwd *pw;
struct group *gr;
int len, sfunc;
- u_int32_t id;
- u_int16_t ulen;
+ uint32_t id;
+ uint16_t ulen;
ibuf++;
sfunc = (unsigned char) *ibuf++;
#if 0
struct vol *vol;
struct dir *dir;
- u_int16_t vid;
- u_int32_t did;
+ uint16_t vid;
+ uint32_t did;
#endif /* 0 */
*rbuflen = 0;
struct vol *vol;
struct dir *parentdir;
struct path *path;
- u_int32_t did;
- u_int16_t vid;
+ uint32_t did;
+ uint16_t vid;
*rbuflen = 0;
ibuf += 2;