X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fextattrs.c;h=40298b50737ccfa62000ac1469c2e4749a4ef511;hb=465246e257d9aff9855e3e35d8fd5983db932b45;hp=b198f7718d4a7050a4a179378129188f78bd4505;hpb=27fe60215c4e666efec784af8f57e10956e996fd;p=netatalk.git diff --git a/etc/afpd/extattrs.c b/etc/afpd/extattrs.c index b198f771..40298b50 100644 --- a/etc/afpd/extattrs.c +++ b/etc/afpd/extattrs.c @@ -1,5 +1,5 @@ /* - $Id: extattrs.c,v 1.15 2009-10-28 01:52:49 didg Exp $ + $Id: extattrs.c,v 1.29 2010-01-05 12:06:33 franklahm Exp $ Copyright (c) 2009 Frank Lahm This program is free software; you can redistribute it and/or modify @@ -21,16 +21,15 @@ #include #include #include -#include -#include #include +#include #include #include #include #include +#include -#include "globals.h" #include "volume.h" #include "desktop.h" #include "directory.h" @@ -72,7 +71,7 @@ static void hexdump(void *m, size_t l) { EA names, secondly it wants these names. In order to avoid scanning EAs twice we cache them in a static buffer. */ -int afp_listextattr(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) +int afp_listextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { int ret, oflag = 0, adflags = 0; uint16_t vid, bitmap, uint16; @@ -80,9 +79,8 @@ int afp_listextattr(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, siz struct vol *vol; struct dir *dir; struct path *s_path; - struct stat st; + struct stat *st; struct adouble ad, *adp = NULL; - struct ofork *of; char *uname, *FinderInfo; char emptyFinderInfo[32] = { 0 }; @@ -92,7 +90,10 @@ int afp_listextattr(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, siz *rbuflen = 0; ibuf += 2; - /* Get MaxReplySize first */ + /* Get Bitmap and MaxReplySize first */ + memcpy( &bitmap, ibuf +6, sizeof(bitmap)); + bitmap = ntohs( bitmap ); + memcpy( &maxreply, ibuf + 14, sizeof (maxreply)); maxreply = ntohl( maxreply ); @@ -107,54 +108,54 @@ int afp_listextattr(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, siz memcpy( &vid, ibuf, sizeof(vid)); ibuf += sizeof(vid); if (NULL == ( vol = getvolbyvid( vid )) ) { - LOG(log_error, logtype_afpd, "afp_listextattr: getvolbyvid error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_listextattr: getvolbyvid error: %s", strerror(errno)); return AFPERR_ACCESS; } memcpy( &did, ibuf, sizeof(did)); ibuf += sizeof(did); if (NULL == ( dir = dirlookup( vol, did )) ) { - LOG(log_error, logtype_afpd, "afp_listextattr: dirlookup error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_listextattr: dirlookup error: %s", strerror(errno)); return afp_errno; } - memcpy( &bitmap, ibuf, sizeof(bitmap)); - bitmap = ntohs( bitmap ); - ibuf += sizeof(bitmap); - -#ifdef HAVE_SOLARIS_EAS if (bitmap & kXAttrNoFollow) oflag = O_NOFOLLOW; -#endif - /* Skip ReqCount, StartIndex and maxreply*/ - ibuf += 10; + /* Skip Bitmap, ReqCount, StartIndex and maxreply*/ + ibuf += 12; /* get name */ if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) { - LOG(log_error, logtype_afpd, "afp_listextattr: cname error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_listextattr: cname error: %s", strerror(errno)); return AFPERR_NOOBJ; } - uname = s_path->u_name; + st = &s_path->st; + if (!s_path->st_valid) { + /* it's a dir in our cache, we didn't stat it, do it now */ + of_statdir(vol, s_path); + } + if ( s_path->st_errno != 0 ) { + return( AFPERR_NOOBJ ); + } + + adp = of_ad(vol, s_path, &ad); + uname = s_path->u_name; /* We have to check the FinderInfo for the file, because if they aren't all 0 we must return the synthetic attribute "com.apple.FinderInfo". Note: the client will never (never seen in traces) request that attribute via FPGetExtAttr ! */ - if ((of = of_findname(s_path))) { - adp = of->of_ad; - } else { - ad_init(&ad, vol->v_adouble, vol->v_ad_options); - adp = &ad; - } - stat(uname, &st); - if (S_ISDIR(st.st_mode)) + if (S_ISDIR(st->st_mode)) adflags = ADFLAGS_DIR; if ( ad_metadata( uname, adflags, adp) < 0 ) { switch (errno) { + case ENOENT: + adp = NULL; + break; case EACCES: LOG(log_error, logtype_afpd, "afp_listextattr(%s): %s: check resource fork permission?", uname, strerror(errno)); @@ -165,35 +166,38 @@ int afp_listextattr(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, siz } } - FinderInfo = ad_entry(adp, ADEID_FINDERI); + if (adp) { + FinderInfo = ad_entry(adp, ADEID_FINDERI); #ifdef DEBUG - LOG(log_maxdebug, logtype_afpd, "afp_listextattr(%s): FinderInfo:", uname); - hexdump( FinderInfo, 32); + LOG(log_maxdebug, logtype_afpd, "afp_listextattr(%s): FinderInfo:", uname); + hexdump( FinderInfo, 32); #endif - if ((adflags & ADFLAGS_DIR)) { - /* set default view */ - uint16 = htons(FINDERINFO_CLOSEDVIEW); - memcpy(emptyFinderInfo + FINDERINFO_FRVIEWOFF, &uint16, 2); - } + if ((adflags & ADFLAGS_DIR)) { + /* set default view */ + uint16 = htons(FINDERINFO_CLOSEDVIEW); + memcpy(emptyFinderInfo + FINDERINFO_FRVIEWOFF, &uint16, 2); + } - /* Check if FinderInfo equals default and empty FinderInfo*/ - if ((memcmp(FinderInfo, emptyFinderInfo, 32)) != 0) { - /* FinderInfo contains some non 0 bytes -> include "com.apple.FinderInfo" */ - strcpy(attrnamebuf, ea_finderinfo); - attrbuflen += strlen(ea_finderinfo) + 1; - LOG(log_debug7, logtype_afpd, "afp_listextattr(%s): sending com.apple.FinderInfo", uname); - } + /* Check if FinderInfo equals default and empty FinderInfo*/ + if (memcmp(FinderInfo, emptyFinderInfo, 32) != 0) { + /* FinderInfo contains some non 0 bytes -> include "com.apple.FinderInfo" */ + strcpy(attrnamebuf, ea_finderinfo); + attrbuflen += strlen(ea_finderinfo) + 1; + LOG(log_debug7, logtype_afpd, "afp_listextattr(%s): sending com.apple.FinderInfo", uname); + } - /* Now check for Ressource fork and add virtual EA "com.apple.ResourceFork" if size > 0 */ - LOG(log_debug7, logtype_afpd, "afp_listextattr(%s): Ressourcefork size: %u", uname, adp->ad_eid[ADEID_RFORK].ade_len); - if (adp->ad_eid[ADEID_RFORK].ade_len > 0) { - LOG(log_debug7, logtype_afpd, "afp_listextattr(%s): sending com.apple.RessourceFork.", uname); - strcpy(attrnamebuf + attrbuflen, ea_resourcefork); - attrbuflen += strlen(ea_resourcefork) + 1; - } + /* Now check for Ressource fork and add virtual EA "com.apple.ResourceFork" if size > 0 */ + LOG(log_debug7, logtype_afpd, "afp_listextattr(%s): Ressourcefork size: %llu", uname, adp->ad_rlen); + if (adp->ad_rlen > 0) { + LOG(log_debug7, logtype_afpd, "afp_listextattr(%s): sending com.apple.RessourceFork.", uname); + strcpy(attrnamebuf + attrbuflen, ea_resourcefork); + attrbuflen += strlen(ea_resourcefork) + 1; + } + } + ret = vol->vfs->vfs_ea_list(vol, attrnamebuf, &attrbuflen, uname, oflag); switch (ret) { @@ -242,12 +246,25 @@ exit: return ret; } +static char *to_stringz(char *ibuf, uint16_t len) +{ +static char attrmname[256]; + + if (len > 255) + /* dont fool with us */ + len = 255; + + /* we must copy the name as its not 0-terminated and I DONT WANT TO WRITE to ibuf */ + strlcpy(attrmname, ibuf, len + 1); + return attrmname; +} + int afp_getextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { int ret, oflag = 0; uint16_t vid, bitmap, attrnamelen; uint32_t did, maxreply; - char attrmname[256], attruname[256]; + char attruname[256]; struct vol *vol; struct dir *dir; struct path *s_path; @@ -259,14 +276,14 @@ int afp_getextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, memcpy( &vid, ibuf, sizeof(vid)); ibuf += sizeof(vid); if (NULL == ( vol = getvolbyvid( vid )) ) { - LOG(log_error, logtype_afpd, "afp_getextattr: getvolbyvid error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_getextattr: getvolbyvid error: %s", strerror(errno)); return AFPERR_ACCESS; } memcpy( &did, ibuf, sizeof(did)); ibuf += sizeof(did); if (NULL == ( dir = dirlookup( vol, did )) ) { - LOG(log_error, logtype_afpd, "afp_getextattr: dirlookup error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_getextattr: dirlookup error: %s", strerror(errno)); return afp_errno; } @@ -274,10 +291,8 @@ int afp_getextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, bitmap = ntohs( bitmap ); ibuf += sizeof(bitmap); -#ifdef HAVE_SOLARIS_EAS if (bitmap & kXAttrNoFollow) oflag = O_NOFOLLOW; -#endif /* Skip Offset and ReqCount */ ibuf += 16; @@ -289,7 +304,7 @@ int afp_getextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, /* get name */ if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) { - LOG(log_error, logtype_afpd, "afp_getextattr: cname error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_getextattr: cname error: %s", strerror(errno)); return AFPERR_NOOBJ; } @@ -300,24 +315,13 @@ int afp_getextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, memcpy(&attrnamelen, ibuf, sizeof(attrnamelen)); attrnamelen = ntohs(attrnamelen); ibuf += sizeof(attrnamelen); - if (attrnamelen > 255) - /* dont fool with us */ - attrnamelen = 255; - /* we must copy the name as its not 0-terminated and I DONT WANT TO WRITE to ibuf */ - strncpy(attrmname, ibuf, attrnamelen); - attrmname[attrnamelen] = 0; - - LOG(log_debug, logtype_afpd, "afp_getextattr(%s): EA: %s", s_path->u_name, attrmname); + LOG(log_debug, logtype_afpd, "afp_getextattr(%s): EA: %s", s_path->u_name, to_stringz(ibuf, attrnamelen)); /* Convert EA name in utf8 to unix charset */ - if ( 0 >= ( attrnamelen = convert_string(CH_UTF8_MAC, obj->options.unixcharset,attrmname, attrnamelen, attruname, 255)) ) + if ( 0 >= convert_string(CH_UTF8_MAC, obj->options.unixcharset, ibuf, attrnamelen, attruname, 256) ) return AFPERR_MISC; - if (attrnamelen == 255) - /* convert_string didn't 0-terminate */ - attruname[255] = 0; - /* write bitmap now */ bitmap = htons(bitmap); memcpy(rbuf, &bitmap, sizeof(bitmap)); @@ -337,12 +341,13 @@ int afp_getextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, return ret; } -int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) +int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { - int oflag = O_CREAT | O_WRONLY, ret; + int oflag = 0, ret; uint16_t vid, bitmap, attrnamelen; uint32_t did, attrsize; - char attrmname[256], attruname[256]; + char attruname[256]; + char *attrmname; struct vol *vol; struct dir *dir; struct path *s_path; @@ -353,14 +358,14 @@ int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, memcpy( &vid, ibuf, sizeof(vid)); ibuf += sizeof(vid); if (NULL == ( vol = getvolbyvid( vid )) ) { - LOG(log_error, logtype_afpd, "afp_setextattr: getvolbyvid error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_setextattr: getvolbyvid error: %s", strerror(errno)); return AFPERR_ACCESS; } memcpy( &did, ibuf, sizeof(did)); ibuf += sizeof(did); if (NULL == ( dir = dirlookup( vol, did )) ) { - LOG(log_error, logtype_afpd, "afp_setextattr: dirlookup error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_setextattr: dirlookup error: %s", strerror(errno)); return afp_errno; } @@ -368,13 +373,11 @@ int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, bitmap = ntohs( bitmap ); ibuf += sizeof(bitmap); -#ifdef HAVE_SOLARIS_EAS if (bitmap & kXAttrNoFollow) - oflag |= AT_SYMLINK_NOFOLLOW; -#endif + oflag |= O_NOFOLLOW; if (bitmap & kXAttrCreate) - oflag |= O_EXCL; + oflag |= O_CREAT; else if (bitmap & kXAttrReplace) oflag |= O_TRUNC; @@ -383,7 +386,7 @@ int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, /* get name */ if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) { - LOG(log_error, logtype_afpd, "afp_setextattr: cname error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_setextattr: cname error: %s", strerror(errno)); return AFPERR_NOOBJ; } @@ -397,19 +400,12 @@ int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, if (attrnamelen > 255) return AFPERR_PARAM; - /* we must copy the name as its not 0-terminated and we cant write to ibuf */ - strncpy(attrmname, ibuf, attrnamelen); - attrmname[attrnamelen] = 0; - ibuf += attrnamelen; - + attrmname = ibuf; /* Convert EA name in utf8 to unix charset */ - if ( 0 >= ( attrnamelen = convert_string(CH_UTF8_MAC, obj->options.unixcharset,attrmname, attrnamelen, attruname, 255)) ) + if ( 0 >= convert_string(CH_UTF8_MAC, obj->options.unixcharset, attrmname, attrnamelen, attruname, 256)) return AFPERR_MISC; - if (attrnamelen == 255) - /* convert_string didn't 0-terminate */ - attruname[255] = 0; - + ibuf += attrnamelen; /* get EA size */ memcpy(&attrsize, ibuf, sizeof(attrsize)); attrsize = ntohl(attrsize); @@ -418,19 +414,19 @@ int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, /* we arbitrarily make this fatal */ return AFPERR_PARAM; - LOG(log_debug, logtype_afpd, "afp_setextattr(%s): EA: %s, size: %u", s_path->u_name, attrmname, attrsize); + LOG(log_debug, logtype_afpd, "afp_setextattr(%s): EA: %s, size: %u", s_path->u_name, to_stringz(attrmname, attrnamelen), attrsize); ret = vol->vfs->vfs_ea_set(vol, s_path->u_name, attruname, ibuf, attrsize, oflag); return ret; } -int afp_remextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) +int afp_remextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { - int oflag = O_RDONLY, ret; + int oflag = 0, ret; uint16_t vid, bitmap, attrnamelen; uint32_t did; - char attrmname[256], attruname[256]; + char attruname[256]; struct vol *vol; struct dir *dir; struct path *s_path; @@ -441,14 +437,14 @@ int afp_remextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, memcpy( &vid, ibuf, sizeof(vid)); ibuf += sizeof(vid); if (NULL == ( vol = getvolbyvid( vid )) ) { - LOG(log_error, logtype_afpd, "afp_remextattr: getvolbyvid error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_remextattr: getvolbyvid error: %s", strerror(errno)); return AFPERR_ACCESS; } memcpy( &did, ibuf, sizeof(did)); ibuf += sizeof(did); if (NULL == ( dir = dirlookup( vol, did )) ) { - LOG(log_error, logtype_afpd, "afp_remextattr: dirlookup error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_remextattr: dirlookup error: %s", strerror(errno)); return afp_errno; } @@ -456,14 +452,12 @@ int afp_remextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, bitmap = ntohs( bitmap ); ibuf += sizeof(bitmap); -#ifdef HAVE_SOLARIS_EAS if (bitmap & kXAttrNoFollow) - oflag |= AT_SYMLINK_NOFOLLOW; -#endif + oflag |= O_NOFOLLOW; /* get name */ if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) { - LOG(log_error, logtype_afpd, "afp_setextattr: cname error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "afp_setextattr: cname error: %s", strerror(errno)); return AFPERR_NOOBJ; } @@ -477,20 +471,11 @@ int afp_remextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, if (attrnamelen > 255) return AFPERR_PARAM; - /* we must copy the name as its not 0-terminated and we cant write to ibuf */ - strncpy(attrmname, ibuf, attrnamelen); - attrmname[attrnamelen] = 0; - ibuf += attrnamelen; - /* Convert EA name in utf8 to unix charset */ - if ( 0 >= ( attrnamelen = convert_string(CH_UTF8_MAC, obj->options.unixcharset,attrmname, attrnamelen, attruname, 255)) ) + if ( 0 >= (convert_string(CH_UTF8_MAC, obj->options.unixcharset,ibuf, attrnamelen, attruname, 256)) ) return AFPERR_MISC; - if (attrnamelen == 255) - /* convert_string didn't 0-terminate */ - attruname[255] = 0; - - LOG(log_debug, logtype_afpd, "afp_remextattr(%s): EA: %s", s_path->u_name, attrmname); + LOG(log_debug, logtype_afpd, "afp_remextattr(%s): EA: %s", s_path->u_name, to_stringz(ibuf, attrnamelen)); ret = vol->vfs->vfs_ea_remove(vol, s_path->u_name, attruname, oflag);