X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fvfs%2Fea_ad.c;h=5b99a5c321b2052866307aa161615188ca61b59d;hb=76b379ad71f4b129fade5611356b103b7ca6d39a;hp=032c045d3973a7eb9b358a33416eeb595f0a1261;hpb=caad56fb97ea14d8b64df8879f68fe82175aa54f;p=netatalk.git diff --git a/libatalk/vfs/ea_ad.c b/libatalk/vfs/ea_ad.c index 032c045d..5b99a5c3 100644 --- a/libatalk/vfs/ea_ad.c +++ b/libatalk/vfs/ea_ad.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include /* * Store Extended Attributes inside .AppleDouble folders as follows: @@ -77,7 +79,7 @@ static char *mtoupath(const struct vol *vol, const char *mpath) char *u; size_t inplen; size_t outlen; - uint16_t flags = CONV_ESCAPEHEX | CONV_ALLOW_COLON; + uint16_t flags = CONV_ESCAPEHEX; if (!mpath) return NULL; @@ -122,26 +124,30 @@ static int unpack_header(struct ea * restrict ea) { int ret = 0; unsigned int count = 0; + uint16_t uint16; uint32_t uint32; char *buf; /* Check magic and version */ buf = ea->ea_data; - if (*(uint32_t *)buf != htonl(EA_MAGIC)) { - LOG(log_error, logtype_afpd, "unpack_header: wrong magic 0x%08x", *(uint32_t *)buf); + memcpy(&uint32, buf, sizeof(uint32_t)); + if (uint32 != htonl(EA_MAGIC)) { + LOG(log_error, logtype_afpd, "unpack_header: wrong magic 0x%08x", uint32); ret = -1; goto exit; } buf += 4; - if (*(uint16_t *)buf != htons(EA_VERSION)) { - LOG(log_error, logtype_afpd, "unpack_header: wrong version 0x%04x", *(uint16_t *)buf); + memcpy(&uint16, buf, sizeof(uint16_t)); + if (uint16 != htons(EA_VERSION)) { + LOG(log_error, logtype_afpd, "unpack_header: wrong version 0x%04x", uint16); ret = -1; goto exit; } buf += 2; /* Get EA count */ - ea->ea_count = ntohs(*(uint16_t *)buf); + memcpy(&uint16, buf, sizeof(uint16_t)); + ea->ea_count = ntohs(uint16); LOG(log_debug, logtype_afpd, "unpack_header: number of EAs: %u", ea->ea_count); buf += 2; @@ -389,6 +395,8 @@ static int create_ea_header(const char * restrict uname, { int fd = -1, err = 0; char *ptr; + uint16_t uint16; + uint32_t uint32; if ((fd = open(uname, O_RDWR | O_CREAT | O_EXCL, 0666 & ~ea->vol->v_umask)) == -1) { LOG(log_error, logtype_afpd, "ea_create: open race condition with ea header for file: %s", uname); @@ -404,11 +412,15 @@ static int create_ea_header(const char * restrict uname, /* Now init it */ ptr = ea->ea_data; - *(uint32_t *)ptr = htonl(EA_MAGIC); + uint32 = htonl(EA_MAGIC); + memcpy(ptr, &uint32, sizeof(uint32_t)); ptr += EA_MAGIC_LEN; - *(uint16_t *)ptr = htons(EA_VERSION); + + uint16 = htons(EA_VERSION); + memcpy(ptr, &uint16, sizeof(uint16_t)); ptr += EA_VERSION_LEN; - *(uint16_t *)ptr = 0; /* count */ + + memset(ptr, 0, 2); /* count */ ea->ea_size = EA_HEADER_SIZE; ea->ea_inited = EA_INITED; @@ -514,13 +526,15 @@ static int ea_delentry(struct ea * restrict ea, const char * restrict attruname) unsigned int count = 0; if (ea->ea_count == 0) { - LOG(log_error, logtype_afpd, "ea_delentry('%s'): illegal ea_count of 0 on deletion"); + LOG(log_error, logtype_afpd, "ea_delentry('%s'): illegal ea_count of 0 on deletion", + attruname); return -1; } while (count < ea->ea_count) { /* search matching EA */ - if (strcmp(attruname, (*ea->ea_entries)[count].ea_name) == 0) { + if ((*ea->ea_entries)[count].ea_name && + strcmp(attruname, (*ea->ea_entries)[count].ea_name) == 0) { free((*ea->ea_entries)[count].ea_name); (*ea->ea_entries)[count].ea_name = NULL; @@ -892,7 +906,7 @@ int ea_close(struct ea * restrict ea) if (ea->ea_count == 0) { /* Check if EA header exists and remove it */ eaname = ea_path(ea, NULL, 0); - if ((lstatat(ea->dirfd, eaname, &st)) == 0) { + if ((statat(ea->dirfd, eaname, &st)) == 0) { if ((netatalk_unlinkat(ea->dirfd, eaname)) != 0) { LOG(log_error, logtype_afpd, "ea_close('%s'): unlink: %s", eaname, strerror(errno)); @@ -1051,7 +1065,7 @@ int get_easize(VFS_FUNC_ARGS_EA_GETSIZE) */ int get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT) { - int ret = AFPERR_MISC, fd = -1; + int ret = AFPERR_MISC; unsigned int count = 0; uint32_t uint32; size_t toread; @@ -1393,8 +1407,8 @@ int ea_renamefile(VFS_FUNC_ARGS_RENAMEFILE) if ((ea_open(vol, dst, EA_RDWR | EA_CREATE, &dstea)) != 0) { if (errno == ENOENT) { /* Possibly the .AppleDouble folder didn't exist, we create it and try again */ - ad_init(&ad, vol->v_adouble, vol->v_ad_options); - if ((ad_open(&ad, dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666)) != 0) { + ad_init(&ad, vol); + if ((ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666)) != 0) { LOG(log_error, logtype_afpd, "ea_renamefile('%s/%s'): ad_open error: '%s'", src, dst, dst); ret = AFPERR_MISC; goto exit; @@ -1490,8 +1504,8 @@ int ea_copyfile(VFS_FUNC_ARGS_COPYFILE) if ((ea_open(vol, dst, EA_RDWR | EA_CREATE, &dstea)) != 0) { if (errno == ENOENT) { /* Possibly the .AppleDouble folder didn't exist, we create it and try again */ - ad_init(&ad, vol->v_adouble, vol->v_ad_options); - if ((ad_open(&ad, dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666)) != 0) { + ad_init(&ad, vol); + if ((ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666)) != 0) { LOG(log_error, logtype_afpd, "ea_copyfile('%s/%s'): ad_open error: '%s'", src, dst, dst); ret = AFPERR_MISC; goto exit; @@ -1569,7 +1583,7 @@ int ea_chown(VFS_FUNC_ARGS_CHOWN) } } - if ((lchown(ea_path(&ea, NULL, 0), uid, gid)) != 0) { + if ((ochown(ea_path(&ea, NULL, 0), uid, gid, vol_syml_opt(vol))) != 0) { switch (errno) { case EPERM: case EACCES: @@ -1586,7 +1600,7 @@ int ea_chown(VFS_FUNC_ARGS_CHOWN) ret = AFPERR_MISC; goto exit; } - if ((lchown(eaname, uid, gid)) != 0) { + if ((ochown(eaname, uid, gid, vol_syml_opt(vol))) != 0) { switch (errno) { case EPERM: case EACCES: @@ -1630,7 +1644,7 @@ int ea_chmod_file(VFS_FUNC_ARGS_SETFILEMODE) } /* Set mode on EA header file */ - if ((setfilmode(ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL, vol->v_umask)) != 0) { + if ((setfilmode(vol, ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL)) != 0) { LOG(log_error, logtype_afpd, "ea_chmod_file('%s'): %s", ea_path(&ea, NULL, 0), strerror(errno)); switch (errno) { case EPERM: @@ -1649,7 +1663,7 @@ int ea_chmod_file(VFS_FUNC_ARGS_SETFILEMODE) ret = AFPERR_MISC; goto exit; } - if ((setfilmode(eaname, ea_mode(mode), NULL, vol->v_umask)) != 0) { + if ((setfilmode(vol, eaname, ea_mode(mode), NULL)) != 0) { LOG(log_error, logtype_afpd, "ea_chmod_file('%s'): %s", eaname, strerror(errno)); switch (errno) { case EPERM: @@ -1680,33 +1694,25 @@ int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE) int ret = AFP_OK; unsigned int count = 0; - uid_t uid; const char *eaname; const char *eaname_safe = NULL; struct ea ea; LOG(log_debug, logtype_afpd, "ea_chmod_dir('%s')", name); /* .AppleDouble already might be inaccesible, so we must run as id 0 */ - uid = geteuid(); - if (seteuid(0)) { - LOG(log_error, logtype_afpd, "ea_chmod_dir('%s'): seteuid: %s", name, strerror(errno)); - return AFPERR_MISC; - } + become_root(); /* Open EA stuff */ if ((ea_open(vol, name, EA_RDWR, &ea)) != 0) { /* ENOENT --> no EA files, nothing to do */ if (errno != ENOENT) ret = AFPERR_MISC; - if (seteuid(uid) < 0) { - LOG(log_error, logtype_afpd, "can't seteuid back: %s", strerror(errno)); - exit(EXITERR_SYS); - } + unbecome_root(); return ret; } /* Set mode on EA header */ - if ((setfilmode(ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL, vol->v_umask)) != 0) { + if ((setfilmode(vol, ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL)) != 0) { LOG(log_error, logtype_afpd, "ea_chmod_dir('%s'): %s", ea_path(&ea, NULL, 0), strerror(errno)); switch (errno) { case EPERM: @@ -1736,7 +1742,7 @@ int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE) ret = AFPERR_MISC; goto exit; } - if ((setfilmode(eaname, ea_mode(mode), NULL, vol->v_umask)) != 0) { + if ((setfilmode(vol, eaname, ea_mode(mode), NULL)) != 0) { LOG(log_error, logtype_afpd, "ea_chmod_dir('%s'): %s", eaname, strerror(errno)); switch (errno) { case EPERM: @@ -1754,10 +1760,7 @@ int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE) } exit: - if (seteuid(uid) < 0) { - LOG(log_error, logtype_afpd, "can't seteuid back: %s", strerror(errno)); - exit(EXITERR_SYS); - } + unbecome_root(); if ((ea_close(&ea)) != 0) { LOG(log_error, logtype_afpd, "ea_chmod_dir('%s'): error closing ea handle", name);