X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fextattrs.c;h=649cc6a30f3044b96533412751f850acee8a10be;hb=4054f4b3c85ecab060dafd46c0d3632cadbb5803;hp=b9d26c0439b228b91c6e97e472409e2670f4fa14;hpb=0cd78d0d2991bf3d843173d81538f03b15c3f9d8;p=netatalk.git diff --git a/etc/afpd/extattrs.c b/etc/afpd/extattrs.c index b9d26c04..649cc6a3 100644 --- a/etc/afpd/extattrs.c +++ b/etc/afpd/extattrs.c @@ -1,5 +1,5 @@ /* - $Id: extattrs.c,v 1.18 2009-10-29 10:34:15 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 @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -80,7 +81,6 @@ int afp_listextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, struct path *s_path; struct stat *st; struct adouble ad, *adp = NULL; - struct ofork *of; char *uname, *FinderInfo; char emptyFinderInfo[32] = { 0 }; @@ -90,7 +90,10 @@ int afp_listextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, *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 ); @@ -105,31 +108,25 @@ int afp_listextattr(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_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; } @@ -142,24 +139,23 @@ int afp_listextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, return( AFPERR_NOOBJ ); } - uname = s_path->u_name; /* + 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; - } 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)); @@ -170,35 +166,38 @@ int afp_listextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, } } - 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) { @@ -247,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; @@ -264,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; } @@ -279,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; @@ -294,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; } @@ -305,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)); @@ -344,10 +343,11 @@ int afp_getextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, 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; @@ -358,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; } @@ -373,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; @@ -388,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; } @@ -402,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); @@ -423,7 +414,7 @@ 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); @@ -432,10 +423,10 @@ int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _ 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; @@ -446,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; } @@ -461,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; } @@ -482,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);