Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu" -*- */
      2 /* dbus-sysdeps.h Wrappers around system/libc features (internal to D-Bus implementation)
      3  *
      4  * Copyright (C) 2002, 2003  Red Hat, Inc.
      5  * Copyright (C) 2003 CodeFactory AB
      6  *
      7  * Licensed under the Academic Free License version 2.1
      8  *
      9  * This program is free software; you can redistribute it and/or modify
     10  * it under the terms of the GNU General Public License as published by
     11  * the Free Software Foundation; either version 2 of the License, or
     12  * (at your option) any later version.
     13  *
     14  * This program is distributed in the hope that it will be useful,
     15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  * GNU General Public License for more details.
     18  *
     19  * You should have received a copy of the GNU General Public License
     20  * along with this program; if not, write to the Free Software
     21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     22  *
     23  */
     24 
     25 #ifndef DBUS_SYSDEPS_H
     26 #define DBUS_SYSDEPS_H
     27 
     28 #include <config.h>
     29 
     30 #include <dbus/dbus-errors.h>
     31 
     32 /* this is perhaps bogus, but strcmp() etc. are faster if we use the
     33  * stuff straight out of string.h, so have this here for now.
     34  */
     35 #include <string.h>
     36 
     37 /* and it would just be annoying to abstract this */
     38 #include <errno.h>
     39 
     40 #include <stdarg.h>
     41 
     42 DBUS_BEGIN_DECLS
     43 
     44 /* Forward declarations */
     45 
     46 /** An opaque string type */
     47 typedef struct DBusString DBusString;
     48 
     49 /** An opaque list type */
     50 typedef struct DBusList DBusList;
     51 
     52 /**
     53  * @addtogroup DBusSysdeps
     54  *
     55  * @{
     56  */
     57 
     58 /* The idea of this file is to encapsulate everywhere that we're
     59  * relying on external libc features, for ease of security
     60  * auditing. The idea is from vsftpd. This also gives us a chance to
     61  * make things more convenient to use, e.g.  by reading into a
     62  * DBusString. Operating system headers aren't intended to be used
     63  * outside of this file and a limited number of others (such as
     64  * dbus-memory.c)
     65  */
     66 
     67 #if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
     68 #define _DBUS_GNUC_PRINTF( format_idx, arg_idx )    \
     69   __attribute__((__format__ (__printf__, format_idx, arg_idx)))
     70 #define _DBUS_GNUC_NORETURN                         \
     71   __attribute__((__noreturn__))
     72 #else   /* !__GNUC__ */
     73 #define _DBUS_GNUC_PRINTF( format_idx, arg_idx )
     74 #define _DBUS_GNUC_NORETURN
     75 #endif  /* !__GNUC__ */
     76 
     77 /** @def _DBUS_GNUC_PRINTF
     78  * used to tell gcc about printf format strings
     79  */
     80 /** @def _DBUS_GNUC_NORETURN
     81  * used to tell gcc about functions that never return, such as _dbus_abort()
     82  */
     83 
     84 void _dbus_abort (void) _DBUS_GNUC_NORETURN;
     85 
     86 const char* _dbus_getenv (const char *varname);
     87 dbus_bool_t _dbus_setenv (const char *varname,
     88 			  const char *value);
     89 
     90 /** A process ID */
     91 typedef unsigned long dbus_pid_t;
     92 /** A user ID */
     93 typedef unsigned long dbus_uid_t;
     94 /** A group ID */
     95 typedef unsigned long dbus_gid_t;
     96 
     97 /** an invalid PID used to represent an uninitialized dbus_pid_t field */
     98 #define DBUS_PID_UNSET ((dbus_pid_t) -1)
     99 /** an invalid UID used to represent an uninitialized dbus_uid_t field */
    100 #define DBUS_UID_UNSET ((dbus_uid_t) -1)
    101 /** an invalid GID used to represent an uninitialized dbus_gid_t field */
    102 #define DBUS_GID_UNSET ((dbus_gid_t) -1)
    103 
    104 /** an appropriate printf format for dbus_pid_t */
    105 #define DBUS_PID_FORMAT "%lu"
    106 /** an appropriate printf format for dbus_uid_t */
    107 #define DBUS_UID_FORMAT "%lu"
    108 /** an appropriate printf format for dbus_gid_t */
    109 #define DBUS_GID_FORMAT "%lu"
    110 
    111 
    112 /**
    113  * Socket interface
    114  *
    115  *  @todo Use for the file descriptors a struct
    116  *           - struct DBusSocket{ int d; }; -
    117  *        instead of int to get type-safety which
    118  *        will be checked by the compiler.
    119  *
    120  */
    121 
    122 dbus_bool_t _dbus_open_tcp_socket  (int              *fd,
    123                                     DBusError        *error);
    124 dbus_bool_t _dbus_close_socket     (int               fd,
    125                                     DBusError        *error);
    126 int         _dbus_read_socket      (int               fd,
    127                                     DBusString       *buffer,
    128                                     int               count);
    129 int         _dbus_write_socket     (int               fd,
    130                                     const DBusString *buffer,
    131                                     int               start,
    132                                     int               len);
    133 int         _dbus_write_socket_two (int               fd,
    134                                     const DBusString *buffer1,
    135                                     int               start1,
    136                                     int               len1,
    137                                     const DBusString *buffer2,
    138                                     int               start2,
    139                                     int               len2);
    140 int _dbus_connect_tcp_socket  (const char     *host,
    141                                dbus_uint32_t   port,
    142                                DBusError      *error);
    143 int _dbus_listen_tcp_socket   (const char     *host,
    144                                dbus_uint32_t   port,
    145                                DBusError      *error);
    146 int _dbus_accept              (int             listen_fd);
    147 
    148 /**
    149  * Struct representing socket credentials
    150  */
    151 typedef struct
    152 {
    153   dbus_pid_t pid; /**< process ID or DBUS_PID_UNSET */
    154   dbus_uid_t uid; /**< user ID or DBUS_UID_UNSET */
    155   dbus_gid_t gid; /**< group ID or DBUS_GID_UNSET */
    156 } DBusCredentials;
    157 
    158 /* FIXME these read/send credentials should get moved to sysdeps-unix.h,
    159  * or renamed to reflect what they mean cross-platform
    160  */
    161 dbus_bool_t _dbus_read_credentials_unix_socket (int              client_fd,
    162                                                 DBusCredentials *credentials,
    163                                                 DBusError       *error);
    164 dbus_bool_t _dbus_send_credentials_unix_socket (int              server_fd,
    165                                                 DBusError       *error);
    166 
    167 
    168 void        _dbus_credentials_clear                (DBusCredentials       *credentials);
    169 void        _dbus_credentials_from_current_process (DBusCredentials       *credentials);
    170 dbus_bool_t _dbus_credentials_match                (const DBusCredentials *expected_credentials,
    171                                                     const DBusCredentials *provided_credentials);
    172 
    173 
    174 /** Information about a UNIX user */
    175 typedef struct DBusUserInfo  DBusUserInfo;
    176 /** Information about a UNIX group */
    177 typedef struct DBusGroupInfo DBusGroupInfo;
    178 
    179 /**
    180  * Information about a UNIX user
    181  */
    182 struct DBusUserInfo
    183 {
    184   dbus_uid_t  uid;            /**< UID */
    185   dbus_gid_t  primary_gid;    /**< GID */
    186   dbus_gid_t *group_ids;      /**< Groups IDs, *including* above primary group */
    187   int         n_group_ids;    /**< Size of group IDs array */
    188   char       *username;       /**< Username */
    189   char       *homedir;        /**< Home directory */
    190 };
    191 
    192 /**
    193  * Information about a UNIX group
    194  */
    195 struct DBusGroupInfo
    196 {
    197   dbus_gid_t  gid;            /**< GID */
    198   char       *groupname;      /**< Group name */
    199 };
    200 
    201 dbus_bool_t _dbus_user_info_fill     (DBusUserInfo     *info,
    202                                       const DBusString *username,
    203                                       DBusError        *error);
    204 dbus_bool_t _dbus_user_info_fill_uid (DBusUserInfo     *info,
    205                                       dbus_uid_t        uid,
    206                                       DBusError        *error);
    207 void        _dbus_user_info_free     (DBusUserInfo     *info);
    208 
    209 dbus_bool_t _dbus_group_info_fill     (DBusGroupInfo    *info,
    210                                        const DBusString *groupname,
    211                                        DBusError        *error);
    212 dbus_bool_t _dbus_group_info_fill_gid (DBusGroupInfo    *info,
    213                                        dbus_gid_t        gid,
    214                                        DBusError        *error);
    215 void        _dbus_group_info_free     (DBusGroupInfo    *info);
    216 
    217 
    218 unsigned long _dbus_getpid (void);
    219 dbus_uid_t    _dbus_getuid (void);
    220 dbus_gid_t    _dbus_getgid (void);
    221 
    222 /** Opaque type representing an atomically-modifiable integer
    223  * that can be used from multiple threads.
    224  */
    225 typedef struct DBusAtomic DBusAtomic;
    226 
    227 /**
    228  * An atomic integer safe to increment or decrement from multiple threads.
    229  */
    230 struct DBusAtomic
    231 {
    232   volatile dbus_int32_t value; /**< Value of the atomic integer. */
    233 };
    234 
    235 dbus_int32_t _dbus_atomic_inc (DBusAtomic *atomic);
    236 dbus_int32_t _dbus_atomic_dec (DBusAtomic *atomic);
    237 
    238 /** There is data to read */
    239 #define _DBUS_POLLIN      0x0001
    240 /** There is urgent data to read */
    241 #define _DBUS_POLLPRI     0x0002
    242 /** Writing now will not block */
    243 #define _DBUS_POLLOUT     0x0004
    244 /** Error condition */
    245 #define _DBUS_POLLERR     0x0008
    246 /** Hung up */
    247 #define _DBUS_POLLHUP     0x0010
    248 /** Invalid request: fd not open */
    249 #define _DBUS_POLLNVAL    0x0020
    250 
    251 /**
    252  * A portable struct pollfd wrapper.
    253  */
    254 typedef struct
    255 {
    256   int fd;            /**< File descriptor */
    257   short events;      /**< Events to poll for */
    258   short revents;     /**< Events that occurred */
    259 } DBusPollFD;
    260 
    261 int _dbus_poll (DBusPollFD *fds,
    262                 int         n_fds,
    263                 int         timeout_milliseconds);
    264 
    265 void _dbus_sleep_milliseconds (int milliseconds);
    266 
    267 void _dbus_get_current_time (long *tv_sec,
    268                              long *tv_usec);
    269 
    270 /**
    271  * File/directory interface
    272  */
    273 dbus_bool_t _dbus_file_exists         (const char       *file);
    274 dbus_bool_t _dbus_file_get_contents   (DBusString       *str,
    275                                        const DBusString *filename,
    276                                        DBusError        *error);
    277 dbus_bool_t _dbus_string_save_to_file (const DBusString *str,
    278                                        const DBusString *filename,
    279                                        DBusError        *error);
    280 
    281 dbus_bool_t _dbus_make_file_world_readable   (const DBusString *filename,
    282                                               DBusError *error);
    283 
    284 dbus_bool_t    _dbus_create_file_exclusively (const DBusString *filename,
    285                                               DBusError        *error);
    286 dbus_bool_t    _dbus_delete_file             (const DBusString *filename,
    287                                               DBusError        *error);
    288 dbus_bool_t    _dbus_create_directory        (const DBusString *filename,
    289                                               DBusError        *error);
    290 dbus_bool_t    _dbus_delete_directory        (const DBusString *filename,
    291 					      DBusError        *error);
    292 
    293 dbus_bool_t _dbus_concat_dir_and_file (DBusString       *dir,
    294                                        const DBusString *next_component);
    295 dbus_bool_t _dbus_string_get_dirname  (const DBusString *filename,
    296                                        DBusString       *dirname);
    297 dbus_bool_t _dbus_path_is_absolute    (const DBusString *filename);
    298 
    299 dbus_bool_t _dbus_get_standard_session_servicedirs (DBusList **dirs);
    300 
    301 /** Opaque type for reading a directory listing */
    302 typedef struct DBusDirIter DBusDirIter;
    303 
    304 DBusDirIter* _dbus_directory_open          (const DBusString *filename,
    305                                             DBusError        *error);
    306 dbus_bool_t  _dbus_directory_get_next_file (DBusDirIter      *iter,
    307                                             DBusString       *filename,
    308                                             DBusError        *error);
    309 void         _dbus_directory_close         (DBusDirIter      *iter);
    310 
    311 dbus_bool_t  _dbus_check_dir_is_private_to_user    (DBusString *dir,
    312                                                     DBusError *error);
    313 
    314 void _dbus_fd_set_close_on_exec (int fd);
    315 
    316 const char* _dbus_get_tmpdir      (void);
    317 
    318 /**
    319  * Random numbers
    320  */
    321 void        _dbus_generate_pseudorandom_bytes_buffer (char *buffer,
    322                                                       int   n_bytes);
    323 void        _dbus_generate_random_bytes_buffer (char       *buffer,
    324                                                 int         n_bytes);
    325 dbus_bool_t _dbus_generate_random_bytes        (DBusString *str,
    326                                                 int         n_bytes);
    327 dbus_bool_t _dbus_generate_random_ascii        (DBusString *str,
    328                                                 int         n_bytes);
    329 
    330 const char* _dbus_error_from_errno (int error_number);
    331 
    332 void _dbus_disable_sigpipe (void);
    333 
    334 
    335 void _dbus_exit (int code) _DBUS_GNUC_NORETURN;
    336 
    337 int _dbus_printf_string_upper_bound (const char *format,
    338                                      va_list args);
    339 
    340 
    341 /**
    342  * Portable struct with stat() results
    343  */
    344 typedef struct
    345 {
    346   unsigned long mode;  /**< File mode */
    347   unsigned long nlink; /**< Number of hard links */
    348   dbus_uid_t    uid;   /**< User owning file */
    349   dbus_gid_t    gid;   /**< Group owning file */
    350   unsigned long size;  /**< Size of file */
    351   unsigned long atime; /**< Access time */
    352   unsigned long mtime; /**< Modify time */
    353   unsigned long ctime; /**< Creation time */
    354 } DBusStat;
    355 
    356 dbus_bool_t _dbus_stat             (const DBusString *filename,
    357                                     DBusStat         *statbuf,
    358                                     DBusError        *error);
    359 dbus_bool_t _dbus_full_duplex_pipe (int              *fd1,
    360                                     int              *fd2,
    361                                     dbus_bool_t       blocking,
    362                                     DBusError        *error);
    363 
    364 void        _dbus_print_backtrace  (void);
    365 
    366 dbus_bool_t _dbus_become_daemon   (const DBusString *pidfile,
    367 				   int               print_pid_fd,
    368                                    DBusError        *error);
    369 dbus_bool_t _dbus_write_pid_file  (const DBusString *filename,
    370                                    unsigned long     pid,
    371                                    DBusError        *error);
    372 dbus_bool_t _dbus_change_identity (unsigned long     uid,
    373                                    unsigned long     gid,
    374                                    DBusError        *error);
    375 
    376 /** A UNIX signal handler */
    377 typedef void (* DBusSignalHandler) (int sig);
    378 
    379 void _dbus_set_signal_handler (int               sig,
    380                                DBusSignalHandler handler);
    381 
    382 dbus_bool_t _dbus_user_at_console (const char *username,
    383                                    DBusError  *error);
    384 
    385 /* Define DBUS_VA_COPY() to do the right thing for copying va_list variables.
    386  * config.h may have already defined DBUS_VA_COPY as va_copy or __va_copy.
    387  */
    388 #if !defined (DBUS_VA_COPY)
    389 #  if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
    390 #    define DBUS_VA_COPY(ap1, ap2)   (*(ap1) = *(ap2))
    391 #  elif defined (DBUS_VA_COPY_AS_ARRAY)
    392 #    define DBUS_VA_COPY(ap1, ap2)   memcpy ((ap1), (ap2), sizeof (va_list))
    393 #  else /* va_list is a pointer */
    394 #    define DBUS_VA_COPY(ap1, ap2)   ((ap1) = (ap2))
    395 #  endif /* va_list is a pointer */
    396 #endif /* !DBUS_VA_COPY */
    397 
    398 
    399 /**
    400  * Casts a primitive C type to a byte array and then indexes
    401  * a particular byte of the array.
    402  */
    403 #define _DBUS_BYTE_OF_PRIMITIVE(p, i) \
    404     (((const char*)&(p))[(i)])
    405 /** On x86 there is an 80-bit FPU, and if you do "a == b" it may have a
    406  * or b in an 80-bit register, thus failing to compare the two 64-bit
    407  * doubles for bitwise equality. So this macro compares the two doubles
    408  * bitwise.
    409  */
    410 #define _DBUS_DOUBLES_BITWISE_EQUAL(a, b)                                       \
    411      (_DBUS_BYTE_OF_PRIMITIVE (a, 0) == _DBUS_BYTE_OF_PRIMITIVE (b, 0) &&       \
    412       _DBUS_BYTE_OF_PRIMITIVE (a, 1) == _DBUS_BYTE_OF_PRIMITIVE (b, 1) &&       \
    413       _DBUS_BYTE_OF_PRIMITIVE (a, 2) == _DBUS_BYTE_OF_PRIMITIVE (b, 2) &&       \
    414       _DBUS_BYTE_OF_PRIMITIVE (a, 3) == _DBUS_BYTE_OF_PRIMITIVE (b, 3) &&       \
    415       _DBUS_BYTE_OF_PRIMITIVE (a, 4) == _DBUS_BYTE_OF_PRIMITIVE (b, 4) &&       \
    416       _DBUS_BYTE_OF_PRIMITIVE (a, 5) == _DBUS_BYTE_OF_PRIMITIVE (b, 5) &&       \
    417       _DBUS_BYTE_OF_PRIMITIVE (a, 6) == _DBUS_BYTE_OF_PRIMITIVE (b, 6) &&       \
    418       _DBUS_BYTE_OF_PRIMITIVE (a, 7) == _DBUS_BYTE_OF_PRIMITIVE (b, 7))
    419 
    420 dbus_bool_t _dbus_parse_uid (const DBusString  *uid_str,
    421                              dbus_uid_t        *uid);
    422 
    423 dbus_bool_t _dbus_get_autolaunch_address (DBusString *address,
    424 					  DBusError *error);
    425 
    426 /** Type representing a universally unique ID
    427  * @todo rename to UUID instead of GUID
    428  */
    429 typedef union DBusGUID DBusGUID;
    430 
    431 dbus_bool_t _dbus_read_local_machine_uuid   (DBusGUID         *machine_id,
    432                                              dbus_bool_t       create_if_not_found,
    433                                              DBusError        *error);
    434 
    435 /**
    436  * Initialize threads as in dbus_threads_init_default(), appropriately
    437  * for the platform.
    438  * @returns #FALSE if no memory
    439  */
    440 dbus_bool_t _dbus_threads_init_platform_specific (void);
    441 
    442 /** @} */
    443 
    444 DBUS_END_DECLS
    445 
    446 #endif /* DBUS_SYSDEPS_H */
    447