/** * Copyright (c) Members of the EGEE Collaboration. 2010. * See http://www.eu-egee.org/partners/ for details on the copyright * holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Authors: Oscar Koeroo, Mischa Sall\'e, Aram Verstegen * NIKHEF Amsterdam, the Netherlands * */ #ifndef _FILEUTIL_H_ #define _FILEUTIL_H_ #include /* Needed for definition of uid_t and gid_t */ #include /* Needed for FILE definition */ #define LCK_NOLOCK 1<<0 /* Make special flag, then we can specify it as lock_type */ #define LCK_FCNTL 1<<1 #define LCK_FLOCK 1<<2 #define LCK_READ 1<<0 #define LCK_WRITE 1<<1 #define LCK_UNLOCK 1<<2 /** * Does given lock action on file given by filedescriptor fd using mechanism * defined by lock_type. lock_type can be a multiple types in which case they * will be all used. LCK_NOLOCK is a special lock type which just does nothing * and will not be combined with others. Valid lock types: * LCK_NOLOCK - no locking * LCK_FCNTL - fcntl() locking * LCK_FLOCK - flock() locking * Valid actions are: * LCK_READ - set shared read lock * LCK_WRITE - set exclusive write lock * LCK_UNLOCK - unset lock * Locks are exclusive for writing and shared for reading: multiple processes * can read simultaneously, but writing is exclusive, both for reading and * writing. * Returns -1 on error, 0 on success. */ int cgul_filelock(int fd, int lock_type, int action); /** * Reads proxy from *path using given lock_type (see cgul_filelock). It tries to * drop privilege to real-uid/real-gid when euid==0 and uid!=0. * Space needed will be malloc-ed. * Upon successful completion config contains the contents of path. * Return values: * 0: success * -1: I/O error * -2: privilege-drop error * -3: permissions error * -4: memory error * -5: too many retries needed during reading * -6: locking failed */ int cgul_read_proxy(const char *path, int lock_type, char **proxy); /** * Used to read in a config file, the path is checked to be trusted (and * possible confidential) using safe_is_path_trusted_r() from the safefile * library of J. Kupsch. * Upon successful completion config contains the contents of the file at path. * * The config file (is trusted) when each of its pathcomponents is writeable * only by user root or user trusted_uid (which may also be 0). * In case userswitching is possible and the macro DEMAND_CONFIG_IS_CONFIDENTIAL * is defined, then an additional check for 'confidentiality' is done. The file * is confidential when it is only readable by the trusted users (root and * trust_uid) and/or the groupids trust_gid (only when !=-1, hence the type int * instead gid_t) or effective gid (when different from real gid, i.e. in setgid * mode). * * In case userswitching is possible privilege is dropped to account * trust_uid/trust_gid. If trust_uid==0 then real uid is used, if trust_gid==-1 * then effective gid is used. * * Return values: * 0: succes * -1: I/O error, including when file changed during reading in any way other * than access time. * -2: privilege-drop error * -3: permission error (untrusted path) * -4: memory error * -5: unknown or safefile error * -10: confidentiality error */ int cgul_read_config(const char *path, char **config, uid_t trust_uid, int trust_gid); /** * Writes proxy from *proxy to *path using given lock_type (see cgul_filelock). * When (e)uid==0 it tries to drop privilege to given write_uid, write_gid. When * either of these is -1, the real uid/gid is used instead, if one of those is * root, the corresponding effective uid/gid is used instead. * Return values: * 0: success * -1: I/O error * -2: privilege-drop error * -3: permissions error, including file directly in / or not absolute * -4: memory error * -6: locking failed */ int cgul_write_proxy(const char *path, int lock_type, const char *proxy, int write_uid, int write_gid); /** * Writes proxy to unique filename created from path_template using mkstemp(). * path_template will be overridden with the actual filename. * When (e)uid==0 it tries to drop privilege to given write_uid, write_gid. When * either of these is -1, the real uid/gid is used instead, if one of those is * root, the corresponding effective uid/gid is used instead. * Any directory in path_template will be attempted to be created if it doesn't * exist, with mode 0600. * Return values: * 0: success * -1: I/O error, this includes a failure of mkstemp which can be due to a * wrong template. It MUST contain 6 consecutive X's. * -2: privilege-drop error * -3: illegal path_template: in / or not absolute. * -4: memory error * -5: invalid template: it MUST end with 6 X's */ int cgul_write_uniq_proxy(char *path_template, const char *proxy, int write_uid, int write_gid); /** * Behaviour as mkdir -p: create parents where needed. * Return values: * 0: success * -1: result is not a directory * -3: absolutedir is not absolute (does not start with '/') * -4: out of memory */ int cgul_mkdir_with_parents(const char *absolutedir, mode_t mode); /** * Safely opens a root-owned logfile with given set of file- and directory * permissions, using J. Kupsch safe_path_is_trusted_r() routine. The file will * be opened with O_WRONLY | O_APPEND | O_CREAT and will have set in addition * the flag FD_CLOEXEC (automatically close upon exec() calls, see fcntl() ). * log_file absolute filename of the logfile * filemask mode_t of the file, if file doesn't exists, it gets this set, * otherwise, it may not be 'more open' than this. * dirmask mode_t of directories that will be created. * file FILE handle of opened file, only changed when succesfully * opened. * force_trusted Treat wrong trust level as an error instead of a warning. * Even when not forced, return code will still be -3. * Return values: * 0 - success * -1 - mkdir error * -2 - I/O error * -3 - permission failed (path or file) * -4 - out-of-memory * -5 - filename not absolute * -6 - stat before/after differs * -7 - given name exists but is not a regular file. * -8 - unknown error */ int cgul_open_logfile(const char *log_file, const mode_t filemask, const mode_t dirmask, FILE **file, int force_trusted); #endif /* _FILEUTIL_H_ */