1 /*
2  * wzdftpd - a modular and cool ftp server
3  * Copyright (C) 2002-2004  Pierre Chifflier
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * As a special exemption, Pierre Chifflier
20  * and other respective copyright holders give permission to link this program
21  * with OpenSSL, and distribute the resulting executable, without including
22  * the source code for OpenSSL in the source distribution.
23  */
24 
25 #ifndef __WZD_BACKEND__
26 #define __WZD_BACKEND__
27 
28 #include <stdarg.h>
29 
30 #include "wzd_structs.h"
31 
32 /*
33  * 101 backend_id
34  */
35 #define STRUCT_BACKEND_VERSION  101
36 
37 /** \brief Initialization for backends */
38 struct wzd_backend_t {
39   unsigned int struct_version; /* used to know which fields are
40                                   present in the struct .. */
41   char * name;
42   unsigned int version;
43 
44   int (*backend_init)(const char * param);
45 
46   uid_t (*backend_validate_login)(const char *, wzd_user_t *);
47   uid_t (*backend_validate_pass) (const char *, const char *, wzd_user_t *);
48   wzd_user_t * (*backend_get_user)(uid_t uid);
49   wzd_group_t * (*backend_get_group)(gid_t gid);
50   uid_t (*backend_find_user) (const char *, wzd_user_t *);
51   gid_t (*backend_find_group) (const char *, wzd_group_t *);
52   int (*backend_chpass) (const char *, const char *);
53   int (*backend_mod_user) (uid_t, wzd_user_t *, unsigned long);
54   int (*backend_mod_group) (gid_t, wzd_group_t *, unsigned long);
55   int (*backend_commit_changes) (void);
56 
57   int (*backend_exit)(void);
58 
59   u16_t backend_id;
60 };
61 
62 
63 /* used to know what was modified in update functions */
64 #define	_USER_NOTHING		0
65 #define	_USER_USERNAME		1<<0
66 #define	_USER_USERPASS		1<<1
67 #define	_USER_ROOTPATH		1<<2
68 #define	_USER_TAGLINE		1<<3
69 #define	_USER_UID		1<<4
70 #define	_USER_GROUPNUM		1<<5
71 #define	_USER_GROUP		1<<6
72 #define	_USER_IDLE		1<<7
73 #define	_USER_PERMS		1<<8
74 #define	_USER_FLAGS		1<<9
75 #define	_USER_MAX_ULS		1<<10
76 #define	_USER_MAX_DLS		1<<11
77 #define	_USER_IP		1<<12
78 #define	_USER_BYTESUL		1<<13
79 #define	_USER_BYTESDL		1<<14
80 #define	_USER_CREDITS		1<<15
81 #define	_USER_NUMLOGINS		1<<16
82 #define	_USER_USERSLOTS		1<<17
83 #define	_USER_LEECHSLOTS	1<<18
84 #define	_USER_RATIO		1<<19
85 #define _USER_ALL               0x0000ffff
86 #define _USER_CREATE            0x01000000
87 
88 #define _GROUP_NOTHING		0
89 #define	_GROUP_GROUPNAME	1<<0
90 #define	_GROUP_GROUPPERMS	1<<1
91 #define	_GROUP_IDLE		1<<2
92 #define	_GROUP_MAX_ULS		1<<3
93 #define	_GROUP_MAX_DLS		1<<4
94 #define	_GROUP_RATIO		1<<5
95 #define	_GROUP_IP		1<<6
96 #define	_GROUP_DEFAULTPATH	1<<7
97 #define	_GROUP_NUMLOGINS	1<<8
98 #define	_GROUP_TAGLINE		1<<9
99 #define	_GROUP_GID		1<<10
100 #define _GROUP_ALL              0x0000ffff
101 #define _GROUP_CREATE           0x01000000
102 
103 
104 /** \brief Get backend version
105  */
106 char *backend_get_version(wzd_backend_def_t *backend);
107 
108 /** \brief Get backend name
109  *
110  * \note This is generally the short name of the backend (for ex, pgsql), and
111  * is different from the name defined in the config (the shared library name).
112  */
113 char *backend_get_name(wzd_backend_def_t *backend);
114 
115 /** \brief Validate backend by checking needed functions, and if a specific version is required
116  *
117  * \param backend The shared library file name
118  * \param pred A predicate (for ex, >=)
119  * \param version The version to be compared, by the predicate, to the backend version
120  *
121  * \return
122  * - a newly allocated structure for the backend, or
123  * - NULL if some functions are missing (check logs for details)
124  *
125  * \note Actually, \a pred and \a version are ignored
126  */
127 wzd_backend_def_t * backend_validate(const char *backend, const char *pred, const char *version);
128 
129 /** \brief Register backend
130  * Use \a filename for dynamic modules (shared libraries)
131  * \a fcn for static modules.
132  * When loading a static module, \a filename is used as a comment
133  */
134 struct wzd_backend_def_t * backend_register(const char * filename, backend_init_function_t fcn);
135 
136 /**
137  * \brief Initialize backend
138  * \param backend The backend name
139  */
140 int backend_init(wzd_backend_def_t * backend);
141 
142 /** \brief Close backend and associated resources
143  *
144  * Call backend exit function (if defined), mark backend as closed, and
145  * unloads shared library if present.
146  *
147  * \note The backend structure must still be removed from list
148  *
149  * \return
150  * - 0 if ok
151  * - 1 if an error occurred
152  */
153 int backend_close(const char *backend);
154 
155 /** \brief Reload backend
156  *
157  * \param backend The backend (short) name
158  *
159  * \return
160  * - 0 if ok
161  * - 1 if an error occurred (the backend may be in inconsistant state)
162  */
163 int backend_reload(const char *backend);
164 
165 enum { INVALID_USER = (uid_t)-1, GET_USER_LIST = (uid_t)-2 };
166 
167 /**
168  * \brief Get user informations
169  * \param userid The user id, or the special value (uid_t)-2
170  *
171  * Search backend for user with the corresponding uid and return the corresponding struct.
172  *
173  * If the argument is -2, this function returns an array of uid (ended with -1) containing
174  * the list of all known users (you have to cast the return to a (uid_t *) to use it). You must
175  * free the returned array using wzd_free().
176  */
177 wzd_user_t * backend_get_user(uid_t userid);
178 
179 enum { INVALID_GROUP = (gid_t)-1, GET_GROUP_LIST = (gid_t)-2 };
180 
181 /**
182  * \brief Get group informations
183  * \param groupid The group id, or the special value (gid_t)-2
184  *
185  * Search backend for group with the corresponding gid and return the corresponding struct.
186  *
187  * If the argument is -2, this function returns an array of gid (ended with -1) containing
188  * the list of all known groups (you have to cast the return to a (gid_t *) to use it). You must
189  * free the returned array using wzd_free().
190  */
191 wzd_group_t * backend_get_group(gid_t groupid);
192 
193 /** \brief Search for user with name \a name in backends
194  *
195  * If an user is found, its uid is stored in \a userid. If \a user is not NULL,
196  * the structure is copied (and should be freed using free() )
197  */
198 int backend_find_user(const char *name, wzd_user_t * user, int * userid);
199 
200 /** \brief Search for group with name \a name in backends
201  *
202  * If a group is found, its gid is stored in \a groupid. If \a group is not NULL,
203  * the structure is copied (and should be freed using free() )
204  */
205 int backend_find_group(const char *name, wzd_group_t * group, int * groupid);
206 
207 /** \brief Check if \a name is a defined in backend, and retrieve the associated structure
208  */
209 int backend_validate_login(const char *name, wzd_user_t * user, uid_t * userid);
210 
211 /** \brief Check user and password, and retrieve associated structure
212  */
213 int backend_validate_pass(const char *name, const char *pass, wzd_user_t *user, uid_t * userid);
214 
215 /** \brief Send user modifications to backend
216  *
217  * The modified user is identified by the backend and the \a uid.
218  * \a mod_type is used to determine which values are changed, and the new values
219  * are taken from the structure \a user.
220  *
221  * If the user does not exist, the backend will add it. If \a user is NULL, the user
222  * is deleted.
223  */
224 int backend_mod_user(const char *backend, uid_t uid, wzd_user_t * user, unsigned long mod_type);
225 
226 /** \brief Send group modifications to backend
227  *
228  * The modified group is identified by the backend and the \a gid.
229  * \a mod_type is used to determine which values are changed, and the new values
230  * are taken from the structure \a group.
231  *
232  * If the group. does not exist, the backend will add it. If \a group. is NULL, the group.
233  * is deleted.
234  */
235 int backend_mod_group(const char *backend, gid_t gid, wzd_group_t * group, unsigned long mod_type);
236 
237 /** \brief Commit changes to backend
238  */
239 int backend_commit_changes(const char *backend);
240 
241 /** \brief Check if a backend is currently used
242  * \return The number of users connected currently using this backend
243  */
244 int backend_inuse(const char *backend);
245 
246 #ifndef STRINGIFY
247 # define STRINGIFY(v) STRINGIFY1(v)
248 # define STRINGIFY1(v) #v
249 #endif
250 
251 #define BACKEND_NAME(n)    const char * wzd_backend_name = STRINGIFY(n)
252 #define BACKEND_VERSION(v) const char * wzd_backend_version = STRINGIFY(v)
253 
254 
255 /** \brief Get user identified by \a id from backend
256  *
257  * \param id The uid of the user
258  *
259  * \return A wzd_user_t structure, or NULL if not found
260  */
261 wzd_user_t * GetUserByID(uid_t id);
262 
263 /** \brief Get user identified by \a name from backend
264  *
265  * \param name The name of the user
266  *
267  * \return A wzd_user_t structure, or NULL if not found
268  */
269 wzd_user_t * GetUserByName(const char *name);
270 
271 /** \brief Get group identified by \a id from backend
272  *
273  * \param id The gid of the group
274  *
275  * \return A wzd_group_t structure, or NULL if not found
276  */
277 wzd_group_t * GetGroupByID(gid_t id);
278 
279 /** \brief Get group identified by \a name from backend
280  *
281  * \param name The name of the group
282  *
283  * \return A wzd_group_t structure, or NULL if not found
284  */
285 wzd_group_t * GetGroupByName(const char *name);
286 
287 /** \brief Get user ID identified by \a name from backend
288  *
289  * \param name The name of the user
290  *
291  * \return The unique identifier of the user, or -1 if not found
292  */
293 uid_t GetUserIDByName(const char *name);
294 
295 /** \brief Get group ID identified by \a name from backend
296  *
297  * \param name The name of the group
298  *
299  * \return The unique identifier of the group, or -1 if not found
300  */
301 gid_t GetGroupIDByName(const char *name);
302 
303 
304 #endif /* __WZD_BACKEND__ */
305