X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fcnid%2Fcnid.c;h=7cf3af1618d19a6de2e0cecada09936aeab90508;hb=6821c9c1b67181b020f375bab7ac8061b0dcbec2;hp=58aa780c452623ea9487db8902de620b86dab3de;hpb=6d36dfa12919387d2822025297deb24cb96403af;p=netatalk.git diff --git a/libatalk/cnid/cnid.c b/libatalk/cnid/cnid.c index 58aa780c..7cf3af16 100644 --- a/libatalk/cnid/cnid.c +++ b/libatalk/cnid/cnid.c @@ -1,6 +1,4 @@ /* - * $Id: cnid.c,v 1.8 2009-11-24 11:40:11 didg Exp $ - * * Copyright (c) 2003 the Netatalk Team * Copyright (c) 2003 Rafal Lewczuk * @@ -31,6 +29,7 @@ #include #include #include +#include /* List of all registered modules. */ static struct list_head modules = ATALK_LIST_HEAD_INIT(modules); @@ -92,14 +91,15 @@ static int cnid_dir(const char *dir, mode_t mask) } /* Opens CNID database using particular back-end */ -struct _cnid_db *cnid_open(const char *volpath, mode_t mask, char *type, int flags) +struct _cnid_db *cnid_open(const char *volpath, mode_t mask, char *type, int flags, + const char *cnidsrv, const char *cnidport) { struct _cnid_db *db; cnid_module *mod = NULL; struct list_head *ptr; uid_t uid = -1; gid_t gid = -1; - + list_for_each(ptr, &modules) { if (0 == strcmp(list_entry(ptr, cnid_module, db_list)->name, type)) { mod = list_entry(ptr, cnid_module, db_list); @@ -112,7 +112,7 @@ struct _cnid_db *cnid_open(const char *volpath, mode_t mask, char *type, int fla return NULL; } - if ((mod->flags & CNID_FLAG_SETUID)) { + if ((mod->flags & CNID_FLAG_SETUID) && !(flags & CNID_FLAG_MEMORY)) { uid = geteuid(); gid = getegid(); if (seteuid(0)) { @@ -128,9 +128,10 @@ struct _cnid_db *cnid_open(const char *volpath, mode_t mask, char *type, int fla } } - db = mod->cnid_open(volpath, mask); + struct cnid_open_args args = {volpath, mask, flags, cnidsrv, cnidport}; + db = mod->cnid_open(&args); - if ((mod->flags & CNID_FLAG_SETUID)) { + if ((mod->flags & CNID_FLAG_SETUID) && !(flags & CNID_FLAG_MEMORY)) { seteuid(0); if ( setegid(gid) < 0 || seteuid(uid) < 0) { LOG(log_error, logtype_afpd, "can't seteuid back %s", strerror(errno)); @@ -161,25 +162,45 @@ struct _cnid_db *cnid_open(const char *volpath, mode_t mask, char *type, int fla } /* ------------------- */ -static void block_signal( u_int32_t flags) +static void block_signal(uint32_t flags) { if ((flags & CNID_FLAG_BLOCK)) { - sigprocmask(SIG_BLOCK, &sigblockset, NULL); + pthread_sigmask(SIG_BLOCK, &sigblockset, NULL); } } /* ------------------- */ -static void unblock_signal(u_int32_t flags) +static void unblock_signal(uint32_t flags) { if ((flags & CNID_FLAG_BLOCK)) { - sigprocmask(SIG_UNBLOCK, &sigblockset, NULL); + pthread_sigmask(SIG_UNBLOCK, &sigblockset, NULL); + } +} + +/* ------------------- + protect against bogus value from the DB. + adddir really doesn't like 2 +*/ +static cnid_t valide(cnid_t id) +{ + if (id == CNID_INVALID) + return id; + + if (id < CNID_START) { + static int err = 0; + if (!err) { + err = 1; + LOG(log_error, logtype_afpd, "Error: Invalid cnid, corrupted DB?"); } + return CNID_INVALID; + } + return id; } /* Closes CNID database. Currently it's just a wrapper around db->cnid_close(). */ void cnid_close(struct _cnid_db *db) { -u_int32_t flags; + uint32_t flags; if (NULL == db) { LOG(log_error, logtype_afpd, "Error: cnid_close called with NULL argument !"); @@ -194,12 +215,15 @@ u_int32_t flags; /* --------------- */ cnid_t cnid_add(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, - char *name, const size_t len, cnid_t hint) + const char *name, const size_t len, cnid_t hint) { -cnid_t ret; + cnid_t ret; + + if (len == 0) + return CNID_INVALID; block_signal(cdb->flags); - ret = cdb->cnid_add(cdb, st, did, name, len, hint); + ret = valide(cdb->cnid_add(cdb, st, did, name, len, hint)); unblock_signal(cdb->flags); return ret; } @@ -222,7 +246,7 @@ cnid_t cnid_get(struct _cnid_db *cdb, const cnid_t did, char *name,const size_t cnid_t ret; block_signal(cdb->flags); - ret = cdb->cnid_get(cdb, did, name, len); + ret = valide(cdb->cnid_get(cdb, did, name, len)); unblock_signal(cdb->flags); return ret; } @@ -250,12 +274,28 @@ time_t t; /* --------------- */ cnid_t cnid_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, - char *name, const size_t len) + char *name, const size_t len) { -cnid_t ret; + cnid_t ret; + + block_signal(cdb->flags); + ret = valide(cdb->cnid_lookup(cdb, st, did, name, len)); + unblock_signal(cdb->flags); + return ret; +} + +/* --------------- */ +int cnid_find(struct _cnid_db *cdb, const char *name, size_t namelen, void *buffer, size_t buflen) +{ + int ret; + + if (cdb->cnid_find == NULL) { + LOG(log_error, logtype_cnid, "cnid_find not supported by CNID backend"); + return -1; + } block_signal(cdb->flags); - ret = cdb->cnid_lookup(cdb, st, did, name, len); + ret = cdb->cnid_find(cdb, name, namelen, buffer, buflen); unblock_signal(cdb->flags); return ret; } @@ -298,3 +338,15 @@ cnid_t ret; unblock_signal(cdb->flags); return ret; } + +/* --------------- */ +int cnid_wipe(struct _cnid_db *cdb) +{ + int ret = 0; + + block_signal(cdb->flags); + if (cdb->cnid_wipe) + ret = cdb->cnid_wipe(cdb); + unblock_signal(cdb->flags); + return ret; +}