1 /*
2  * ProFTPD - FTP server daemon
3  * Copyright (c) 2017-2020 The ProFTPD Project team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  *
19  * As a special exemption, The ProFTPD Project team and other respective
20  * copyright holders give permission to link this program with OpenSSL, and
21  * distribute the resulting executable, without including the source code for
22  * OpenSSL in the source distribution.
23  */
24 
25 /* Redis support */
26 
27 #ifndef PR_REDIS_H
28 #define PR_REDIS_H
29 
30 #include "conf.h"
31 
32 typedef struct redis_rec pr_redis_t;
33 
34 /* Core API for use by modules et al */
35 
36 /* This function returns the pr_redis_t for the current session; if one
37  * does not exist, it will be allocated.
38  */
39 pr_redis_t *pr_redis_conn_get(pool *p, unsigned long flags);
40 pr_redis_t *pr_redis_conn_new(pool *p, module *owner, unsigned long flags);
41 
42 /* These flags are used for tweaking connection behaviors. */
43 #define PR_REDIS_CONN_FL_NO_RECONNECT		0x0001
44 
45 int pr_redis_conn_close(pr_redis_t *redis);
46 int pr_redis_conn_destroy(pr_redis_t *redis);
47 
48 /* Set a namespace key prefix, to be used by this connection for all of the
49  * operations involving items.  In practice, the key prefix should always
50  * be a string which does contain any space characters.
51  *
52  * Different modules can use different namespace prefixes for their keys.
53  * Setting NULL for the namespace prefix clears it.
54  */
55 int pr_redis_conn_set_namespace(pr_redis_t *redis, module *m,
56   const void *prefix, size_t prefixsz);
57 
58 /* Redis server version. */
59 int pr_redis_conn_get_version(pr_redis_t *redis, unsigned int *major_version,
60   unsigned int *minor_version, unsigned int *patch_version);
61 
62 /* Authenticate to a password-protected Redis server. */
63 int pr_redis_auth(pr_redis_t *redis, const char *password);
64 int pr_redis_auth2(pr_redis_t *redis, const char *username,
65   const char *password);
66 
67 /* Select the database used by the Redis server. */
68 int pr_redis_select(pr_redis_t *redis, const char *db_idx);
69 
70 /* Issue a custom command to the Redis server; the reply type MUST match the
71  * one specified.  Mostly this is used for testing.
72  */
73 int pr_redis_command(pr_redis_t *redis, const array_header *args,
74   int reply_type);
75 #define PR_REDIS_REPLY_TYPE_STRING		1
76 #define PR_REDIS_REPLY_TYPE_INTEGER		2
77 #define PR_REDIS_REPLY_TYPE_NIL			3
78 #define PR_REDIS_REPLY_TYPE_ARRAY		4
79 #define PR_REDIS_REPLY_TYPE_STATUS		5
80 #define PR_REDIS_REPLY_TYPE_ERROR		6
81 
82 int pr_redis_add(pr_redis_t *redis, module *m, const char *key, void *value,
83   size_t valuesz, time_t expires);
84 int pr_redis_decr(pr_redis_t *redis, module *m, const char *key, uint32_t decr,
85   uint64_t *value);
86 void *pr_redis_get(pool *p, pr_redis_t *redis, module *m, const char *key,
87   size_t *valuesz);
88 char *pr_redis_get_str(pool *p, pr_redis_t *redis, module *m, const char *key);
89 int pr_redis_incr(pr_redis_t *redis, module *m, const char *key, uint32_t incr,
90   uint64_t *value);
91 int pr_redis_remove(pr_redis_t *redis, module *m, const char *key);
92 int pr_redis_rename(pr_redis_t *redis, module *m, const char *from,
93   const char *to);
94 int pr_redis_set(pr_redis_t *redis, module *m, const char *key, void *value,
95   size_t valuesz, time_t expires);
96 
97 /* Hash operations */
98 int pr_redis_hash_count(pr_redis_t *redis, module *m, const char *key,
99   uint64_t *count);
100 int pr_redis_hash_delete(pr_redis_t *redis, module *m, const char *key,
101   const char *field);
102 int pr_redis_hash_exists(pr_redis_t *redis, module *m, const char *key,
103   const char *field);
104 int pr_redis_hash_get(pool *p, pr_redis_t *redis, module *m, const char *key,
105   const char *field, void **value, size_t *valuesz);
106 int pr_redis_hash_getall(pool *p, pr_redis_t *redis, module *m,
107   const char *key, pr_table_t **hash);
108 int pr_redis_hash_incr(pr_redis_t *redis, module *m, const char *key,
109   const char *field, int32_t incr, int64_t *value);
110 int pr_redis_hash_keys(pool *p, pr_redis_t *redis, module *m, const char *key,
111   array_header **fields);
112 int pr_redis_hash_remove(pr_redis_t *redis, module *m, const char *key);
113 int pr_redis_hash_set(pr_redis_t *redis, module *m, const char *key,
114   const char *field, void *value, size_t valuesz);
115 int pr_redis_hash_setall(pr_redis_t *redis, module *m, const char *key,
116   pr_table_t *hash);
117 int pr_redis_hash_values(pool *p, pr_redis_t *redis, module *m,
118   const char *key, array_header **values);
119 
120 /* List operations */
121 int pr_redis_list_append(pr_redis_t *redis, module *m, const char *key,
122   void *value, size_t valuesz);
123 int pr_redis_list_count(pr_redis_t *redis, module *m, const char *key,
124   uint64_t *count);
125 int pr_redis_list_delete(pr_redis_t *redis, module *m, const char *key,
126   void *value, size_t valuesz);
127 int pr_redis_list_exists(pr_redis_t *redis, module *m, const char *key,
128   unsigned int idx);
129 int pr_redis_list_get(pool *p, pr_redis_t *redis, module *m, const char *key,
130   unsigned int idx, void **value, size_t *valuesz);
131 int pr_redis_list_getall(pool *p, pr_redis_t *redis, module *m,
132   const char *key, array_header **values, array_header **valueszs);
133 int pr_redis_list_pop(pool *p, pr_redis_t *redis, module *m, const char *key,
134   void **value, size_t *valuesz, int flags);
135 int pr_redis_list_push(pr_redis_t *redis, module *m, const char *key,
136   void *value, size_t valuesz, int flags);
137 int pr_redis_list_remove(pr_redis_t *redis, module *m, const char *key);
138 int pr_redis_list_rotate(pool *p, pr_redis_t *redis, module *m, const char *key,
139   void **value, size_t *valuesz);
140 int pr_redis_list_set(pr_redis_t *redis, module *m, const char *key,
141   unsigned int idx, void *value, size_t valuesz);
142 int pr_redis_list_setall(pr_redis_t *redis, module *m, const char *key,
143   array_header *values, array_header *valueszs);
144 
145 /* These flags are used for determining whether the list operation occurs
146  * to the LEFT or the RIGHT side of the list, e.g. LPUSH vs RPUSH.
147  */
148 #define PR_REDIS_LIST_FL_LEFT		1
149 #define PR_REDIS_LIST_FL_RIGHT		2
150 
151 /* Set operations */
152 int pr_redis_set_add(pr_redis_t *redis, module *m, const char *key,
153   void *value, size_t valuesz);
154 int pr_redis_set_count(pr_redis_t *redis, module *m, const char *key,
155   uint64_t *count);
156 int pr_redis_set_delete(pr_redis_t *redis, module *m, const char *key,
157   void *value, size_t valuesz);
158 int pr_redis_set_exists(pr_redis_t *redis, module *m, const char *key,
159   void *value, size_t valuesz);
160 int pr_redis_set_getall(pool *p, pr_redis_t *redis, module *m, const char *key,
161   array_header **values, array_header **valueszs);
162 int pr_redis_set_remove(pr_redis_t *redis, module *m, const char *key);
163 int pr_redis_set_setall(pr_redis_t *redis, module *m, const char *key,
164   array_header *values, array_header *valueszs);
165 
166 /* Sorted Set operations */
167 int pr_redis_sorted_set_add(pr_redis_t *redis, module *m, const char *key,
168   void *value, size_t valuesz, float score);
169 int pr_redis_sorted_set_count(pr_redis_t *redis, module *m, const char *key,
170   uint64_t *count);
171 int pr_redis_sorted_set_delete(pr_redis_t *redis, module *m, const char *key,
172   void *value, size_t valuesz);
173 int pr_redis_sorted_set_exists(pr_redis_t *redis, module *m, const char *key,
174   void *value, size_t valuesz);
175 int pr_redis_sorted_set_getn(pool *p, pr_redis_t *redis, module *m,
176   const char *key, unsigned int offset, unsigned int len,
177   array_header **values, array_header **valueszs, int flags);
178 
179 /* These flags are used for determining whether the sorted set items are
180  * obtained in ascending (ASC) or descending (DESC) order.
181  */
182 #define PR_REDIS_SORTED_SET_FL_ASC		1
183 #define PR_REDIS_SORTED_SET_FL_DESC		2
184 
185 int pr_redis_sorted_set_incr(pr_redis_t *redis, module *m, const char *key,
186   void *value, size_t valuesz, float incr, float *score);
187 int pr_redis_sorted_set_remove(pr_redis_t *redis, module *m, const char *key);
188 int pr_redis_sorted_set_score(pr_redis_t *redis, module *m, const char *key,
189   void *value, size_t valuesz, float *score);
190 int pr_redis_sorted_set_set(pr_redis_t *redis, module *m, const char *key,
191   void *value, size_t valuesz, float score);
192 int pr_redis_sorted_set_setall(pr_redis_t *redis, module *m, const char *key,
193   array_header *values, array_header *valueszs, array_header *scores);
194 
195 /* Variants of the above, where the key values are arbitrary bits rather than
196  * being assumed to be strings.
197  */
198 int pr_redis_kadd(pr_redis_t *redis, module *m, const char *key, size_t keysz,
199   void *value, size_t valuesz, time_t expires);
200 int pr_redis_kdecr(pr_redis_t *redis, module *m, const char *key, size_t keysz,
201   uint32_t decr, uint64_t *value);
202 void *pr_redis_kget(pool *p, pr_redis_t *redis, module *m, const char *key,
203   size_t keysz, size_t *valuesz);
204 char *pr_redis_kget_str(pool *p, pr_redis_t *redis, module *m, const char *key,
205   size_t keysz);
206 int pr_redis_kincr(pr_redis_t *redis, module *m, const char *key, size_t keysz,
207   uint32_t incr, uint64_t *value);
208 int pr_redis_kremove(pr_redis_t *redis, module *m, const char *key,
209   size_t keysz);
210 int pr_redis_krename(pr_redis_t *redis, module *m, const char *from,
211   size_t fromsz, const char *to, size_t tosz);
212 int pr_redis_kset(pr_redis_t *redis, module *m, const char *key, size_t keysz,
213   void *value, size_t valuesz, time_t expires);
214 
215 int pr_redis_hash_kcount(pr_redis_t *redis, module *m, const char *key,
216   size_t keysz, uint64_t *count);
217 int pr_redis_hash_kdelete(pr_redis_t *redis, module *m, const char *key,
218   size_t keysz, const char *field, size_t fieldsz);
219 int pr_redis_hash_kexists(pr_redis_t *redis, module *m, const char *key,
220   size_t keysz, const char *field, size_t fieldsz);
221 int pr_redis_hash_kget(pool *p, pr_redis_t *redis, module *m, const char *key,
222   size_t keysz, const char *field, size_t fieldsz, void **value,
223   size_t *valuesz);
224 int pr_redis_hash_kgetall(pool *p, pr_redis_t *redis, module *m,
225   const char *key, size_t keysz, pr_table_t **hash);
226 int pr_redis_hash_kincr(pr_redis_t *redis, module *m, const char *key,
227   size_t keysz, const char *field, size_t fieldsz, int32_t incr,
228   int64_t *value);
229 int pr_redis_hash_kkeys(pool *p, pr_redis_t *redis, module *m, const char *key,
230   size_t keysz, array_header **fields);
231 int pr_redis_hash_kremove(pr_redis_t *redis, module *m, const char *key,
232   size_t keysz);
233 int pr_redis_hash_kset(pr_redis_t *redis, module *m, const char *key,
234   size_t keysz, const char *field, size_t fieldsz, void *value, size_t valuesz);
235 int pr_redis_hash_ksetall(pr_redis_t *redis, module *m, const char *key,
236   size_t keysz, pr_table_t *hash);
237 int pr_redis_hash_kvalues(pool *p, pr_redis_t *redis, module *m,
238   const char *key, size_t keysz, array_header **values);
239 
240 int pr_redis_list_kappend(pr_redis_t *redis, module *m, const char *key,
241   size_t keysz, void *value, size_t valuesz);
242 int pr_redis_list_kcount(pr_redis_t *redis, module *m, const char *key,
243   size_t keysz, uint64_t *count);
244 int pr_redis_list_kdelete(pr_redis_t *redis, module *m, const char *key,
245   size_t keysz, void *value, size_t valuesz);
246 int pr_redis_list_kexists(pr_redis_t *redis, module *m, const char *key,
247   size_t keysz, unsigned int idx);
248 int pr_redis_list_kget(pool *p, pr_redis_t *redis, module *m, const char *key,
249   size_t keysz, unsigned int idx, void **value, size_t *valuesz);
250 int pr_redis_list_kgetall(pool *p, pr_redis_t *redis, module *m,
251   const char *key, size_t keysz, array_header **values,
252   array_header **valueszs);
253 int pr_redis_list_kpop(pool *p, pr_redis_t *redis, module *m,
254   const char *key, size_t keysz, void **value, size_t *valuesz, int flags);
255 int pr_redis_list_kpush(pr_redis_t *redis, module *m, const char *key,
256   size_t keysz, void *value, size_t valuesz, int flags);
257 int pr_redis_list_kremove(pr_redis_t *redis, module *m, const char *key,
258   size_t keysz);
259 int pr_redis_list_krotate(pool *p, pr_redis_t *redis, module *m,
260   const char *key, size_t keysz, void **value, size_t *valuesz);
261 int pr_redis_list_kset(pr_redis_t *redis, module *m, const char *key,
262   size_t keysz, unsigned int idx, void *value, size_t valuesz);
263 int pr_redis_list_ksetall(pr_redis_t *redis, module *m, const char *key,
264   size_t keysz, array_header *values, array_header *valueszs);
265 
266 int pr_redis_set_kadd(pr_redis_t *redis, module *m, const char *key,
267   size_t keysz, void *value, size_t valuesz);
268 int pr_redis_set_kcount(pr_redis_t *redis, module *m, const char *key,
269   size_t keysz, uint64_t *count);
270 int pr_redis_set_kdelete(pr_redis_t *redis, module *m, const char *key,
271   size_t keysz, void *value, size_t valuesz);
272 int pr_redis_set_kexists(pr_redis_t *redis, module *m, const char *key,
273   size_t keysz, void *value, size_t valuesz);
274 int pr_redis_set_kgetall(pool *p, pr_redis_t *redis, module *m, const char *key,
275   size_t keysz, array_header **values, array_header **valueszs);
276 int pr_redis_set_kremove(pr_redis_t *redis, module *m, const char *key,
277   size_t keysz);
278 int pr_redis_set_ksetall(pr_redis_t *redis, module *m, const char *key,
279   size_t keysz, array_header *values, array_header *valueszs);
280 
281 int pr_redis_sorted_set_kadd(pr_redis_t *redis, module *m, const char *key,
282   size_t keysz, void *value, size_t valuesz, float score);
283 int pr_redis_sorted_set_kcount(pr_redis_t *redis, module *m, const char *key,
284   size_t keysz, uint64_t *count);
285 int pr_redis_sorted_set_kdelete(pr_redis_t *redis, module *m, const char *key,
286   size_t keysz, void *value, size_t valuesz);
287 int pr_redis_sorted_set_kexists(pr_redis_t *redis, module *m, const char *key,
288   size_t keysz, void *value, size_t valuesz);
289 int pr_redis_sorted_set_kgetn(pool *p, pr_redis_t *redis, module *m,
290   const char *key, size_t keysz, unsigned int offset, unsigned int len,
291   array_header **values, array_header **valueszs, int flags);
292 int pr_redis_sorted_set_kincr(pr_redis_t *redis, module *m, const char *key,
293   size_t keysz, void *value, size_t valuesz, float incr, float *score);
294 int pr_redis_sorted_set_kremove(pr_redis_t *redis, module *m, const char *key,
295   size_t keysz);
296 int pr_redis_sorted_set_kscore(pr_redis_t *redis, module *m, const char *key,
297   size_t keysz, void *value, size_t valuesz, float *score);
298 int pr_redis_sorted_set_kset(pr_redis_t *redis, module *m, const char *key,
299   size_t keysz, void *value, size_t valuesz, float score);
300 int pr_redis_sorted_set_ksetall(pr_redis_t *redis, module *m, const char *key,
301   size_t keysz, array_header *values, array_header *valueszs,
302   array_header *scores);
303 
304 /* Sentinel operations */
305 int pr_redis_sentinel_get_master_addr(pool *p, pr_redis_t *redis,
306   const char *name, pr_netaddr_t **addr);
307 int pr_redis_sentinel_get_masters(pool *p, pr_redis_t *redis,
308   array_header **masters);
309 
310 /* For internal use only */
311 int redis_set_server(const char *server, int port, unsigned long flags,
312   const char *password, const char *db_idx);
313 int redis_set_server2(const char *server, int port, unsigned long flags,
314   const char *username, const char *password, const char *db_idx);
315 int redis_set_sentinels(array_header *sentinels, const char *name);
316 int redis_set_timeouts(unsigned long connect_millis, unsigned long io_millis);
317 
318 int redis_clear(void);
319 int redis_init(void);
320 
321 #endif /* PR_REDIS_H */
322