Apache HTTPD
md_store_fs.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <assert.h>
18#include <stddef.h>
19#include <stdio.h>
20#include <stdlib.h>
21
22#include <apr_lib.h>
23#include <apr_file_info.h>
24#include <apr_file_io.h>
25#include <apr_fnmatch.h>
26#include <apr_hash.h>
27#include <apr_strings.h>
28
29#include "md.h"
30#include "md_crypt.h"
31#include "md_json.h"
32#include "md_log.h"
33#include "md_store.h"
34#include "md_store_fs.h"
35#include "md_util.h"
36#include "md_version.h"
37
38/**************************************************************************************************/
39/* file system based implementation of md_store_t */
40
41#define MD_STORE_VERSION 3
42#define MD_FS_LOCK_NAME "store.lock"
43
48
67
68#define FS_STORE(store) (md_store_fs_t*)(((char*)store)-offsetof(md_store_fs_t, s))
69#define FS_STORE_JSON "md_store.json"
70#define FS_STORE_KLEN 48
71
73 const char *name, const char *aspect,
74 md_store_vtype_t vtype, void **pvalue, apr_pool_t *p);
76 const char *name, const char *aspect,
77 md_store_vtype_t vtype, void *value, int create);
79 const char *name, const char *aspect,
80 apr_pool_t *p, int force);
82 md_store_group_t group, const char *name);
84 apr_time_t modified, md_store_group_t group,
85 const char *name, const char *aspect);
88 const char *name, int archive);
90 md_store_group_t group, const char *from, const char *to);
91static apr_status_t fs_iterate(md_store_inspect *inspect, void *baton, md_store_t *store,
92 apr_pool_t *p, md_store_group_t group, const char *pattern,
93 const char *aspect, md_store_vtype_t vtype);
94static apr_status_t fs_iterate_names(md_store_inspect *inspect, void *baton, md_store_t *store,
95 apr_pool_t *p, md_store_group_t group, const char *pattern);
96
97static apr_status_t fs_get_fname(const char **pfname,
98 md_store_t *store, md_store_group_t group,
99 const char *name, const char *aspect,
100 apr_pool_t *p);
102 const char *name, const char *aspect, apr_pool_t *p);
103
105 const char *name, const char *aspect, apr_pool_t *p);
106
108static void fs_unlock_global(md_store_t *store, apr_pool_t *p);
109
111 apr_pool_t *p, apr_pool_t *ptemp)
112{
113 md_json_t *json = md_json_create(p);
114 const char *key64;
115 apr_status_t rv;
116
118
120 if (APR_SUCCESS != (rv = md_rand_bytes((unsigned char*)s_fs->key.data, s_fs->key.len, p))) {
121 return rv;
122 }
123
124 key64 = md_util_base64url_encode(&s_fs->key, ptemp);
127 memset((char*)key64, 0, strlen(key64));
128
129 return rv;
130}
131
133 const char *dir, const char *name,
134 apr_filetype_e ftype)
135{
136 const char *from, *to;
138
139 (void)baton;
140 (void)ftype;
141 if ( MD_OK(md_util_path_merge(&from, ptemp, dir, name, NULL))
143 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, p, "renaming %s/%s to %s",
145 return apr_file_rename(from, to, ptemp);
146 }
147 return rv;
148}
149
151 const char *dir, const char *name,
152 apr_filetype_e ftype)
153{
156 const char *fname, *fpubcert;
158
159 (void)baton;
160 (void)ftype;
161 (void)p;
164 && MD_OK(md_util_path_merge(&fname, ptemp, dir, name, NULL))
165 && MD_OK(md_cert_fload(&cert, ptemp, fname))
166 && MD_OK(md_util_path_merge(&fname, ptemp, dir, "chain.pem", NULL))) {
167
168 rv = md_chain_fload(&chain, ptemp, fname);
169 if (APR_STATUS_IS_ENOENT(rv)) {
170 chain = apr_array_make(ptemp, 1, sizeof(md_cert_t*));
171 rv = APR_SUCCESS;
172 }
173 if (APR_SUCCESS == rv) {
174 pubcert = apr_array_make(ptemp, chain->nelts + 1, sizeof(md_cert_t*));
176 apr_array_cat(pubcert, chain);
178 }
179 }
180 return rv;
181}
182
184{
187
188 (void)ptemp;
189 /* Migrate pkey.pem -> privkey.pem */
190 for (g = MD_SG_NONE; g < MD_SG_COUNT && APR_SUCCESS == rv; ++g) {
191 rv = md_util_files_do(rename_pkey, s_fs, p, s_fs->base,
192 md_store_group_name(g), "*", "pkey.pem", NULL);
193 }
194 /* Generate fullcert.pem from cert.pem and chain.pem where missing */
195 rv = md_util_files_do(mk_pubcert, s_fs, p, s_fs->base,
197 rv = md_util_files_do(mk_pubcert, s_fs, p, s_fs->base,
199
200 return rv;
201}
202
204 apr_pool_t *p, apr_pool_t *ptemp)
205{
206 md_json_t *json;
207 const char *key64;
208 apr_status_t rv;
209 double store_version;
210
211 if (MD_OK(md_json_readf(&json, p, fname))) {
213 if (store_version <= 0.0) {
214 /* ok, an old one, compatible to 1.0 */
215 store_version = 1.0;
216 }
218 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "version too new: %f", store_version);
219 return APR_EINVAL;
220 }
221
223 if (!key64) {
224 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "missing key: %s", MD_KEY_KEY);
225 return APR_EINVAL;
226 }
227
229 if (s_fs->key.len != FS_STORE_KLEN) {
230 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "key length unexpected: %" APR_SIZE_T_FMT,
231 s_fs->key.len);
232 return APR_EINVAL;
233 }
234
235 /* Need to migrate format? */
237 if (store_version <= 1.0) {
238 md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "migrating store v1 -> v2");
239 rv = upgrade_from_1_0(s_fs, p, ptemp);
240 }
241 if (store_version <= 2.0) {
242 md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "migrating store v2 -> v3");
244 }
245
246 if (APR_SUCCESS == rv) {
249 }
250 md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, p, "migrated store");
251 }
252 }
253 return rv;
254}
255
257{
258 md_store_fs_t *s_fs = baton;
259 const char *fname;
260 apr_status_t rv;
261
262 (void)ap;
263 s_fs->plain_pkey[MD_SG_DOMAINS] = 1;
264 /* Added: the encryption of tls-alpn-01 certificate keys is not a security issue
265 * for these self-signed, short-lived certificates. Having them unencrypted let's
266 * use pass around the files insteak of an *SSL implementation dependent PKEY_something.
267 */
268 s_fs->plain_pkey[MD_SG_CHALLENGES] = 1;
269 s_fs->plain_pkey[MD_SG_TMP] = 1;
270
271 if (!MD_OK(md_util_path_merge(&fname, ptemp, s_fs->base, FS_STORE_JSON, NULL))) {
272 return rv;
273 }
274
275read:
276 if (MD_OK(md_util_is_file(fname, ptemp))) {
277 rv = read_store_file(s_fs, fname, p, ptemp);
278 }
279 else if (APR_STATUS_IS_ENOENT(rv)
280 && APR_STATUS_IS_EEXIST(rv = init_store_file(s_fs, fname, p, ptemp))) {
281 goto read;
282 }
283 return rv;
284}
285
287{
288 md_store_fs_t *s_fs;
290
291 s_fs = apr_pcalloc(p, sizeof(*s_fs));
292
293 s_fs->s.load = fs_load;
294 s_fs->s.save = fs_save;
295 s_fs->s.remove = fs_remove;
296 s_fs->s.move = fs_move;
297 s_fs->s.rename = fs_rename;
298 s_fs->s.purge = fs_purge;
299 s_fs->s.iterate = fs_iterate;
301 s_fs->s.get_fname = fs_get_fname;
302 s_fs->s.is_newer = fs_is_newer;
304 s_fs->s.remove_nms = fs_remove_nms;
307
308 /* by default, everything is only readable by the current user */
311
312 /* Account information needs to be accessible to httpd child processes.
313 * private keys are, similar to staging, encrypted. */
318 /* challenges dir and files are readable by all, no secrets involved */
321 /* OCSP data is readable by all, no secrets involved */
324
325 s_fs->base = apr_pstrdup(p, path);
326
327 rv = md_util_is_dir(s_fs->base, p);
328 if (APR_STATUS_IS_ENOENT(rv)) {
330 "store directory does not exist, creating %s", s_fs->base);
331 rv = apr_dir_make_recursive(s_fs->base, s_fs->def_perms.dir, p);
332 if (APR_SUCCESS != rv) goto cleanup;
334 if (APR_STATUS_IS_ENOTIMPL(rv)) {
335 rv = APR_SUCCESS;
336 }
337 if (APR_SUCCESS != rv) goto cleanup;
338 }
339 else if (APR_SUCCESS != rv) {
341 "not a plain directory, maybe a symlink? %s", s_fs->base);
342 }
343
345 if (APR_SUCCESS != rv) {
346 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "init fs store at %s", s_fs->base);
347 }
348cleanup:
349 *pstore = (rv == APR_SUCCESS)? &(s_fs->s) : NULL;
350 return rv;
351}
352
363
367{
368 md_store_fs_t *s_fs = FS_STORE(store);
369
370 if (group >= (sizeof(s_fs->group_perms)/sizeof(s_fs->group_perms[0]))) {
371 return APR_ENOTIMPL;
372 }
373 s_fs->group_perms[group].file = file_perms;
374 s_fs->group_perms[group].dir = dir_perms;
375 return APR_SUCCESS;
376}
377
379{
380 md_store_fs_t *s_fs = FS_STORE(store);
381
382 s_fs->event_cb = cb;
383 s_fs->event_baton = baton;
384 return APR_SUCCESS;
385}
386
387static const perms_t *gperms(md_store_fs_t *s_fs, md_store_group_t group)
388{
389 if (group >= (sizeof(s_fs->group_perms)/sizeof(s_fs->group_perms[0]))
390 || !s_fs->group_perms[group].dir) {
391 return &s_fs->def_perms;
392 }
393 return &s_fs->group_perms[group];
394}
395
396static apr_status_t fs_get_fname(const char **pfname,
397 md_store_t *store, md_store_group_t group,
398 const char *name, const char *aspect,
399 apr_pool_t *p)
400{
401 md_store_fs_t *s_fs = FS_STORE(store);
402 if (group == MD_SG_NONE) {
403 return md_util_path_merge(pfname, p, s_fs->base, aspect, NULL);
404 }
405 return md_util_path_merge(pfname, p,
406 s_fs->base, md_store_group_name(group), name, aspect, NULL);
407}
408
409static apr_status_t fs_get_dname(const char **pdname,
410 md_store_t *store, md_store_group_t group,
411 const char *name, apr_pool_t *p)
412{
413 md_store_fs_t *s_fs = FS_STORE(store);
414 if (group == MD_SG_NONE) {
415 *pdname = s_fs->base;
416 return APR_SUCCESS;
417 }
418 return md_util_path_merge(pdname, p, s_fs->base, md_store_group_name(group), name, NULL);
419}
420
421static void get_pass(const char **ppass, apr_size_t *plen,
422 md_store_fs_t *s_fs, md_store_group_t group)
423{
424 if (s_fs->plain_pkey[group]) {
425 *ppass = NULL;
426 *plen = 0;
427 }
428 else {
429 *ppass = (const char *)s_fs->key.data;
430 *plen = s_fs->key.len;
431 }
432}
433
434static apr_status_t fs_fload(void **pvalue, md_store_fs_t *s_fs, const char *fpath,
436 apr_pool_t *p, apr_pool_t *ptemp)
437{
438 apr_status_t rv;
439 const char *pass;
440 apr_size_t pass_len;
441
442 if (pvalue != NULL) {
443 switch (vtype) {
444 case MD_SV_TEXT:
445 rv = md_text_fread8k((const char **)pvalue, p, fpath);
446 break;
447 case MD_SV_JSON:
449 break;
450 case MD_SV_CERT:
452 break;
453 case MD_SV_PKEY:
454 get_pass(&pass, &pass_len, s_fs, group);
455 rv = md_pkey_fload((md_pkey_t **)pvalue, p, pass, pass_len, fpath);
456 break;
457 case MD_SV_CHAIN:
459 break;
460 default:
461 rv = APR_ENOTIMPL;
462 break;
463 }
465 "loading type %d from %s", vtype, fpath);
466 }
467 else { /* check for existence only */
468 rv = md_util_is_file(fpath, p);
469 }
470 return rv;
471}
472
474{
475 md_store_fs_t *s_fs = baton;
476 const char *fpath, *name, *aspect;
477 md_store_vtype_t vtype;
478 md_store_group_t group;
479 void **pvalue;
480 apr_status_t rv;
481
482 group = (md_store_group_t)va_arg(ap, int);
483 name = va_arg(ap, const char *);
484 aspect = va_arg(ap, const char *);
485 vtype = (md_store_vtype_t)va_arg(ap, int);
486 pvalue= va_arg(ap, void **);
487
488 if (MD_OK(fs_get_fname(&fpath, &s_fs->s, group, name, aspect, ptemp))) {
489 rv = fs_fload(pvalue, s_fs, fpath, group, vtype, p, ptemp);
490 }
491 return rv;
492}
493
494static apr_status_t dispatch(md_store_fs_t *s_fs, md_store_fs_ev_t ev, unsigned int group,
495 const char *fname, apr_filetype_e ftype, apr_pool_t *p)
496{
497 (void)ev;
498 if (s_fs->event_cb) {
499 return s_fs->event_cb(s_fs->event_baton, &s_fs->s, MD_S_FS_EV_CREATED,
500 group, fname, ftype, p);
501 }
502 return APR_SUCCESS;
503}
504
505static apr_status_t mk_group_dir(const char **pdir, md_store_fs_t *s_fs,
506 md_store_group_t group, const char *name,
507 apr_pool_t *p)
508{
509 const perms_t *perms;
510 apr_status_t rv;
511
512 perms = gperms(s_fs, group);
513
514 *pdir = NULL;
515 rv = fs_get_dname(pdir, &s_fs->s, group, name, p);
516 if ((APR_SUCCESS != rv) || (MD_SG_NONE == group)) goto cleanup;
517
518 rv = md_util_is_dir(*pdir, p);
519 if (APR_STATUS_IS_ENOENT(rv)) {
520 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, p, "not a directory, creating %s", *pdir);
521 rv = apr_dir_make_recursive(*pdir, perms->dir, p);
522 if (APR_SUCCESS != rv) goto cleanup;
523 dispatch(s_fs, MD_S_FS_EV_CREATED, group, *pdir, APR_DIR, p);
524 }
525
526 rv = apr_file_perms_set(*pdir, perms->dir);
527 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, rv, p, "mk_group_dir %s perm set", *pdir);
528 if (APR_STATUS_IS_ENOTIMPL(rv)) {
529 rv = APR_SUCCESS;
530 }
531cleanup:
532 if (APR_SUCCESS != rv) {
533 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "mk_group_dir %d %s",
534 group, (*pdir? *pdir : (name? name : "(null)")));
535 }
536 return rv;
537}
538
540{
541 md_store_fs_t *s_fs = baton;
542 const char *fname1, *fname2, *name, *aspect;
545 int *pnewer;
546 apr_status_t rv;
547
548 (void)p;
551 name = va_arg(ap, const char*);
552 aspect = va_arg(ap, const char*);
553 pnewer = va_arg(ap, int*);
554
555 *pnewer = 0;
556 if ( MD_OK(fs_get_fname(&fname1, &s_fs->s, group1, name, aspect, ptemp))
557 && MD_OK(fs_get_fname(&fname2, &s_fs->s, group2, name, aspect, ptemp))
559 && MD_OK(apr_stat(&inf2, fname2, APR_FINFO_MTIME, ptemp))) {
560 *pnewer = inf1.mtime > inf2.mtime;
561 }
562
563 return rv;
564}
565
567 const char *name, const char *aspect, apr_pool_t *p)
568{
569 md_store_fs_t *s_fs = FS_STORE(store);
570 int newer = 0;
571 apr_status_t rv;
572
573 rv = md_util_pool_vdo(pfs_is_newer, s_fs, p, group1, group2, name, aspect, &newer, NULL);
574 if (APR_SUCCESS == rv) {
575 return newer;
576 }
577 return 0;
578}
579
581{
582 md_store_fs_t *s_fs = baton;
583 const char *fname, *name, *aspect;
584 md_store_group_t group;
587 apr_status_t rv;
588
589 (void)p;
590 group = (md_store_group_t)va_arg(ap, int);
591 name = va_arg(ap, const char*);
592 aspect = va_arg(ap, const char*);
594
595 *pmtime = 0;
596 if ( MD_OK(fs_get_fname(&fname, &s_fs->s, group, name, aspect, ptemp))
597 && MD_OK(apr_stat(&inf, fname, APR_FINFO_MTIME, ptemp))) {
598 *pmtime = inf.mtime;
599 }
600
601 return rv;
602}
603
605 const char *name, const char *aspect, apr_pool_t *p)
606{
607 md_store_fs_t *s_fs = FS_STORE(store);
609 apr_status_t rv;
610
611 rv = md_util_pool_vdo(pfs_get_modified, s_fs, p, group, name, aspect, &mtime, NULL);
612 if (APR_SUCCESS == rv) {
613 return mtime;
614 }
615 return 0;
616}
617
619{
620 md_store_fs_t *s_fs = baton;
621 const char *gdir, *dir, *fpath, *name, *aspect;
622 md_store_vtype_t vtype;
623 md_store_group_t group;
624 void *value;
625 int create;
626 apr_status_t rv;
627 const perms_t *perms;
628 const char *pass;
629 apr_size_t pass_len;
630
631 group = (md_store_group_t)va_arg(ap, int);
632 name = va_arg(ap, const char*);
633 aspect = va_arg(ap, const char*);
634 vtype = (md_store_vtype_t)va_arg(ap, int);
635 value = va_arg(ap, void *);
636 create = va_arg(ap, int);
637
638 perms = gperms(s_fs, group);
639
640 if ( MD_OK(mk_group_dir(&gdir, s_fs, group, NULL, p))
641 && MD_OK(mk_group_dir(&dir, s_fs, group, name, p))
642 && MD_OK(md_util_path_merge(&fpath, ptemp, dir, aspect, NULL))) {
643
644 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, ptemp, "storing in %s", fpath);
645 switch (vtype) {
646 case MD_SV_TEXT:
647 rv = (create? md_text_fcreatex(fpath, perms->file, p, value)
648 : md_text_freplace(fpath, perms->file, p, value));
649 break;
650 case MD_SV_JSON:
652 fpath, perms->file)
654 fpath, perms->file));
655 break;
656 case MD_SV_CERT:
657 rv = md_cert_fsave((md_cert_t *)value, ptemp, fpath, perms->file);
658 break;
659 case MD_SV_PKEY:
660 /* Take care that we write private key with access only to the user,
661 * unless we write the key encrypted */
662 get_pass(&pass, &pass_len, s_fs, group);
663 rv = md_pkey_fsave((md_pkey_t *)value, ptemp, pass, pass_len,
664 fpath, (pass && pass_len)? perms->file : MD_FPROT_F_UONLY);
665 break;
666 case MD_SV_CHAIN:
667 rv = md_chain_fsave((apr_array_header_t*)value, ptemp, fpath, perms->file);
668 break;
669 default:
670 return APR_ENOTIMPL;
671 }
672 if (APR_SUCCESS == rv) {
673 rv = dispatch(s_fs, MD_S_FS_EV_CREATED, group, fpath, APR_REG, p);
674 }
675 }
676 return rv;
677}
678
680{
681 md_store_fs_t *s_fs = baton;
682 const char *dir, *name, *fpath, *groupname, *aspect;
683 apr_status_t rv;
684 int force;
686 md_store_group_t group;
687
688 (void)p;
689 group = (md_store_group_t)va_arg(ap, int);
690 name = va_arg(ap, const char*);
691 aspect = va_arg(ap, const char *);
692 force = va_arg(ap, int);
693
695
696 if ( MD_OK(md_util_path_merge(&dir, ptemp, s_fs->base, groupname, name, NULL))
697 && MD_OK(md_util_path_merge(&fpath, ptemp, dir, aspect, NULL))) {
698 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "start remove of md %s/%s/%s",
699 groupname, name, aspect);
700
701 if (!MD_OK(apr_stat(&info, dir, APR_FINFO_TYPE, ptemp))) {
702 if (APR_ENOENT == rv && force) {
703 return APR_SUCCESS;
704 }
705 return rv;
706 }
707
708 rv = apr_file_remove(fpath, ptemp);
709 if (APR_ENOENT == rv && force) {
710 rv = APR_SUCCESS;
711 }
712 }
713 return rv;
714}
715
717 const char *name, const char *aspect,
718 md_store_vtype_t vtype, void **pvalue, apr_pool_t *p)
719{
720 md_store_fs_t *s_fs = FS_STORE(store);
721 return md_util_pool_vdo(pfs_load, s_fs, p, group, name, aspect, vtype, pvalue, NULL);
722}
723
725 const char *name, const char *aspect,
726 md_store_vtype_t vtype, void *value, int create)
727{
728 md_store_fs_t *s_fs = FS_STORE(store);
729 return md_util_pool_vdo(pfs_save, s_fs, p, group, name, aspect,
730 vtype, value, create, NULL);
731}
732
734 const char *name, const char *aspect,
735 apr_pool_t *p, int force)
736{
737 md_store_fs_t *s_fs = FS_STORE(store);
738 return md_util_pool_vdo(pfs_remove, s_fs, p, group, name, aspect, force, NULL);
739}
740
742{
743 md_store_fs_t *s_fs = baton;
744 const char *dir, *name, *groupname;
745 md_store_group_t group;
746 apr_status_t rv;
747
748 (void)p;
749 group = (md_store_group_t)va_arg(ap, int);
750 name = va_arg(ap, const char*);
751
753
754 if (MD_OK(md_util_path_merge(&dir, ptemp, s_fs->base, groupname, name, NULL))) {
755 /* Remove all files in dir, there should be no sub-dirs */
756 rv = md_util_rm_recursive(dir, ptemp, 1);
757 }
758 if (!APR_STATUS_IS_ENOENT(rv)) {
759 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, ptemp, "purge %s/%s (%s)", groupname, name, dir);
760 }
761 return APR_SUCCESS;
762}
763
765 md_store_group_t group, const char *name)
766{
767 md_store_fs_t *s_fs = FS_STORE(store);
768 return md_util_pool_vdo(pfs_purge, s_fs, p, group, name, NULL);
769}
770
771/**************************************************************************************************/
772/* iteration */
773
785
787 const char *dir, const char *name, apr_filetype_e ftype)
788{
790 apr_status_t rv;
791 void *value;
792 const char *fpath;
793
794 (void)ftype;
795 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting value at: %s/%s", dir, name);
796 if (APR_SUCCESS == (rv = md_util_path_merge(&fpath, ptemp, dir, name, NULL))) {
797 rv = fs_fload(&value, ctx->s_fs, fpath, ctx->group, ctx->vtype, p, ptemp);
798 if (APR_SUCCESS == rv
799 && !ctx->inspect(ctx->baton, ctx->dirname, name, ctx->vtype, value, p)) {
800 return APR_EOF;
801 }
802 else if (APR_STATUS_IS_ENOENT(rv)) {
803 rv = APR_SUCCESS;
804 }
805 }
806 return rv;
807}
808
810 const char *dir, const char *name, apr_filetype_e ftype)
811{
813 apr_status_t rv;
814 const char *fpath;
815
816 (void)ftype;
817 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting dir at: %s/%s", dir, name);
819 ctx->dirname = name;
820 rv = md_util_files_do(insp, ctx, p, fpath, ctx->aspect, NULL);
821 if (APR_STATUS_IS_ENOENT(rv)) {
822 rv = APR_SUCCESS;
823 }
824 }
825 return rv;
826}
827
829 apr_pool_t *p, md_store_group_t group, const char *pattern,
830 const char *aspect, md_store_vtype_t vtype)
831{
832 const char *groupname;
833 apr_status_t rv;
835
836 ctx.s_fs = FS_STORE(store);
837 ctx.group = group;
838 ctx.pattern = pattern;
839 ctx.aspect = aspect;
840 ctx.vtype = vtype;
841 ctx.inspect = inspect;
842 ctx.baton = baton;
844
845 rv = md_util_files_do(insp_dir, &ctx, p, ctx.s_fs->base, groupname, pattern, NULL);
846
847 return rv;
848}
849
851 const char *dir, const char *name, apr_filetype_e ftype)
852{
854
855 (void)ftype;
856 (void)p;
857 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting name at: %s/%s", dir, name);
858 return ctx->inspect(ctx->baton, dir, name, 0, NULL, ptemp);
859}
860
862 apr_pool_t *p, md_store_group_t group, const char *pattern)
863{
864 const char *groupname;
865 apr_status_t rv;
867
868 ctx.s_fs = FS_STORE(store);
869 ctx.group = group;
870 ctx.pattern = pattern;
871 ctx.inspect = inspect;
872 ctx.baton = baton;
874
875 rv = md_util_files_do(insp_name, &ctx, p, ctx.s_fs->base, groupname, pattern, NULL);
876
877 return rv;
878}
879
881 const char *dir, const char *name, apr_filetype_e ftype)
882{
884 const char *fname;
887
888 (void)p;
889 if (APR_DIR == ftype) goto leave;
890 if (APR_SUCCESS != (rv = md_util_path_merge(&fname, ptemp, dir, name, NULL))) goto leave;
891 if (APR_SUCCESS != (rv = apr_stat(&inf, fname, APR_FINFO_MTIME, ptemp))) goto leave;
892 if (inf.mtime >= ctx->ts) goto leave;
893
894 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "remove_nms file: %s/%s", dir, name);
895 rv = apr_file_remove(fname, ptemp);
896
897leave:
898 return rv;
899}
900
902 const char *dir, const char *name, apr_filetype_e ftype)
903{
905 apr_status_t rv;
906 const char *fpath;
907
908 (void)ftype;
909 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "remove_nms dir at: %s/%s", dir, name);
911 ctx->dirname = name;
913 if (APR_STATUS_IS_ENOENT(rv)) {
914 rv = APR_SUCCESS;
915 }
916 }
917 return rv;
918}
919
921 apr_time_t modified, md_store_group_t group,
922 const char *name, const char *aspect)
923{
924 const char *groupname;
925 apr_status_t rv;
927
928 ctx.s_fs = FS_STORE(store);
929 ctx.group = group;
930 ctx.pattern = name;
931 ctx.aspect = aspect;
932 ctx.ts = modified;
934
935 rv = md_util_files_do(remove_nms_dir, &ctx, p, ctx.s_fs->base, groupname, name, NULL);
936
937 return rv;
938}
939
940/**************************************************************************************************/
941/* moving */
942
944{
945 md_store_fs_t *s_fs = baton;
946 const char *name, *from_group, *to_group, *from_dir, *to_dir, *arch_dir, *dir;
947 md_store_group_t from, to;
948 int archive;
949 apr_status_t rv;
950
951 (void)p;
952 from = (md_store_group_t)va_arg(ap, int);
953 to = (md_store_group_t)va_arg(ap, int);
954 name = va_arg(ap, const char*);
955 archive = va_arg(ap, int);
956
959 if (!strcmp(from_group, to_group)) {
960 return APR_EINVAL;
961 }
962
963 if ( !MD_OK(md_util_path_merge(&from_dir, ptemp, s_fs->base, from_group, name, NULL))
964 || !MD_OK(md_util_path_merge(&to_dir, ptemp, s_fs->base, to_group, name, NULL))) {
965 goto out;
966 }
967
968 if (!MD_OK(md_util_is_dir(from_dir, ptemp))) {
969 md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "source is no dir: %s", from_dir);
970 goto out;
971 }
972
973 if (MD_OK(archive? md_util_is_dir(to_dir, ptemp) : APR_ENOENT)) {
974 int n = 1;
975 const char *narch_dir;
976
977 if ( !MD_OK(md_util_path_merge(&dir, ptemp, s_fs->base,
980 || !MD_OK(md_util_path_merge(&arch_dir, ptemp, dir, name, NULL))) {
981 goto out;
982 }
983
984#ifdef WIN32
985 /* WIN32 and handling of files/dirs. What can one say? */
986
987 while (n < 1000) {
988 narch_dir = apr_psprintf(ptemp, "%s.%d", arch_dir, n);
989 rv = md_util_is_dir(narch_dir, ptemp);
990 if (APR_STATUS_IS_ENOENT(rv)) {
991 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, ptemp, "using archive dir: %s",
992 narch_dir);
993 break;
994 }
995 else {
996 ++n;
997 narch_dir = NULL;
998 }
999 }
1000
1001#else /* ifdef WIN32 */
1002
1003 while (n < 1000) {
1004 narch_dir = apr_psprintf(ptemp, "%s.%d", arch_dir, n);
1006 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, ptemp, "using archive dir: %s",
1007 narch_dir);
1008 break;
1009 }
1010 else if (APR_EEXIST == rv) {
1011 ++n;
1012 narch_dir = NULL;
1013 }
1014 else {
1015 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "creating archive dir: %s",
1016 narch_dir);
1017 goto out;
1018 }
1019 }
1020
1021#endif /* ifdef WIN32 (else part) */
1022
1023 if (!narch_dir) {
1024 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "ran out of numbers less than 1000 "
1025 "while looking for an available one in %s to archive the data "
1026 "from %s. Either something is generally wrong or you need to "
1027 "clean up some of those directories.", arch_dir, from_dir);
1028 rv = APR_EGENERAL;
1029 goto out;
1030 }
1031
1032 if (!MD_OK(apr_file_rename(to_dir, narch_dir, ptemp))) {
1033 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "rename from %s to %s",
1034 to_dir, narch_dir);
1035 goto out;
1036 }
1037 if (!MD_OK(apr_file_rename(from_dir, to_dir, ptemp))) {
1038 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "rename from %s to %s",
1039 from_dir, to_dir);
1041 goto out;
1042 }
1043 if (MD_OK(dispatch(s_fs, MD_S_FS_EV_MOVED, to, to_dir, APR_DIR, ptemp))) {
1045 }
1046 }
1047 else if (APR_STATUS_IS_ENOENT(rv)) {
1048 if (APR_SUCCESS != (rv = apr_file_rename(from_dir, to_dir, ptemp))) {
1049 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "rename from %s to %s",
1050 from_dir, to_dir);
1051 goto out;
1052 }
1053 }
1054 else {
1055 md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "target is no dir: %s", to_dir);
1056 goto out;
1057 }
1058
1059out:
1060 return rv;
1061}
1062
1065 const char *name, int archive)
1066{
1067 md_store_fs_t *s_fs = FS_STORE(store);
1068 return md_util_pool_vdo(pfs_move, s_fs, p, from, to, name, archive, NULL);
1069}
1070
1072{
1073 md_store_fs_t *s_fs = baton;
1074 const char *group_name, *from_dir, *to_dir;
1075 md_store_group_t group;
1076 const char *from, *to;
1077 apr_status_t rv;
1078
1079 (void)p;
1080 group = (md_store_group_t)va_arg(ap, int);
1081 from = va_arg(ap, const char*);
1082 to = va_arg(ap, const char*);
1083
1085 if ( !MD_OK(md_util_path_merge(&from_dir, ptemp, s_fs->base, group_name, from, NULL))
1086 || !MD_OK(md_util_path_merge(&to_dir, ptemp, s_fs->base, group_name, to, NULL))) {
1087 goto out;
1088 }
1089
1090 if (APR_SUCCESS != (rv = apr_file_rename(from_dir, to_dir, ptemp))
1091 && !APR_STATUS_IS_ENOENT(rv)) {
1092 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, ptemp, "rename from %s to %s",
1093 from_dir, to_dir);
1094 goto out;
1095 }
1096out:
1097 return rv;
1098}
1099
1101 md_store_group_t group, const char *from, const char *to)
1102{
1103 md_store_fs_t *s_fs = FS_STORE(store);
1104 return md_util_pool_vdo(pfs_rename, s_fs, p, group, from, to, NULL);
1105}
1106
1108{
1109 md_store_fs_t *s_fs = FS_STORE(store);
1110 apr_status_t rv;
1111 const char *lpath;
1113
1114 if (s_fs->global_lock) {
1115 rv = APR_EEXIST;
1116 md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "already locked globally");
1117 goto cleanup;
1118 }
1119
1121 if (APR_SUCCESS != rv) goto cleanup;
1123
1125 "acquire global lock: %s", lpath);
1126 while (apr_time_now() < end) {
1127 rv = apr_file_open(&s_fs->global_lock, lpath,
1130 if (APR_SUCCESS != rv) {
1132 "unable to create/open lock file: %s",
1133 lpath);
1134 goto next_try;
1135 }
1136 rv = apr_file_lock(s_fs->global_lock,
1138 if (APR_SUCCESS == rv) {
1139 goto cleanup;
1140 }
1142 "unable to obtain lock on: %s",
1143 lpath);
1144
1145 next_try:
1146 if (s_fs->global_lock) {
1148 s_fs->global_lock = NULL;
1149 }
1151 }
1152 rv = APR_EGENERAL;
1154 "acquire global lock: %s", lpath);
1155
1156cleanup:
1157 return rv;
1158}
1159
1161{
1162 md_store_fs_t *s_fs = FS_STORE(store);
1163
1164 (void)p;
1165 if (s_fs->global_lock) {
1167 s_fs->global_lock = NULL;
1168 }
1169}
int n
Definition ap_regex.h:278
const char * pattern
Definition ap_regex.h:243
APR File Information.
APR File I/O Handling.
APR FNMatch Functions.
APR Hash Tables.
APR general purpose library routines.
APR Strings library.
apr_status_t apr_dir_make_recursive(const char *path, apr_fileperms_t perm, apr_pool_t *pool)
request_rec int int apr_table_t const char * path
ap_vhost_iterate_conn_cb void * baton
Definition http_vhost.h:87
#define APR_EGENERAL
Definition apr_errno.h:313
#define APR_EOF
Definition apr_errno.h:461
#define APR_ENOTIMPL
Definition apr_errno.h:476
#define APR_ENOENT
Definition apr_errno.h:662
#define APR_EINVAL
Definition apr_errno.h:711
#define APR_EEXIST
Definition apr_errno.h:648
#define APR_STATUS_IS_EEXIST(s)
Definition apr_errno.h:1233
#define APR_STATUS_IS_ENOTIMPL(s)
Definition apr_errno.h:615
#define APR_STATUS_IS_ENOENT(s)
Definition apr_errno.h:1246
apr_brigade_flush void * ctx
apr_datum_t apr_datum_t * pvalue
Definition apr_dbm.h:128
apr_size_t size
const char * value
Definition apr_env.h:51
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
apr_int32_t apr_fileperms_t
apr_filetype_e
@ APR_REG
@ APR_DIR
const char apr_fileperms_t perms
void const char apr_status_t(* cleanup)(void *))
apr_time_t mtime
#define APR_FLOCK_NONBLOCK
#define APR_FLOCK_EXCLUSIVE
#define APR_FOPEN_WRITE
Definition apr_file_io.h:55
#define APR_FOPEN_CREATE
Definition apr_file_io.h:56
const char * fname
#define APR_FINFO_MTIME
#define APR_FINFO_TYPE
apr_vformatter_buff_t const char va_list ap
Definition apr_lib.h:176
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
apr_dir_t * dir
int to
const char char ** end
#define APR_ARRAY_PUSH(ary, type)
Definition apr_tables.h:150
const char * groupname
#define apr_time_from_msec(msec)
Definition apr_time.h:75
apr_int64_t apr_time_t
Definition apr_time.h:45
#define MD_OK(c)
Definition md.h:328
#define MD_KEY_VERSION
Definition md.h:213
#define MD_KEY_STORE
Definition md.h:197
#define MD_KEY_KEY
Definition md.h:157
apr_status_t md_chain_fload(apr_array_header_t **pcerts, apr_pool_t *p, const char *fname)
Definition md_crypt.c:1645
apr_status_t md_rand_bytes(unsigned char *buf, apr_size_t len, apr_pool_t *p)
Definition md_crypt.c:162
apr_status_t md_cert_fload(md_cert_t **pcert, apr_pool_t *p, const char *fname)
Definition md_crypt.c:1353
apr_status_t md_chain_fsave(apr_array_header_t *certs, apr_pool_t *p, const char *fname, apr_fileperms_t perms)
Definition md_crypt.c:1656
apr_status_t md_pkey_fsave(md_pkey_t *pkey, apr_pool_t *p, const char *pass_phrase, apr_size_t pass_len, const char *fname, apr_fileperms_t perms)
Definition md_crypt.c:691
apr_status_t md_cert_fsave(md_cert_t *cert, apr_pool_t *p, const char *fname, apr_fileperms_t perms)
Definition md_crypt.c:1403
apr_status_t md_pkey_fload(md_pkey_t **ppkey, apr_pool_t *p, const char *key, apr_size_t key_len, const char *fname)
Definition md_crypt.c:600
apr_pool_t * p
Definition md_event.c:32
md_json_t * md_json_create(apr_pool_t *pool)
Definition md_json.c:92
double md_json_getn(const md_json_t *json,...)
Definition md_json.c:356
apr_status_t md_json_sets(const char *value, md_json_t *json,...)
Definition md_json.c:430
apr_status_t md_json_setn(double value, md_json_t *json,...)
Definition md_json.c:367
apr_status_t md_json_freplace(const md_json_t *json, apr_pool_t *p, md_json_fmt_t fmt, const char *fpath, apr_fileperms_t perms)
Definition md_json.c:1058
apr_status_t md_json_readf(md_json_t **pjson, apr_pool_t *p, const char *fpath)
Definition md_json.c:1156
apr_status_t md_json_fcreatex(const md_json_t *json, apr_pool_t *p, md_json_fmt_t fmt, const char *fpath, apr_fileperms_t perms)
Definition md_json.c:1034
apr_status_t md_json_del(md_json_t *json,...)
Definition md_json.c:618
const char * md_json_dups(apr_pool_t *p, const md_json_t *json,...)
Definition md_json.c:418
@ MD_JSON_FMT_INDENT
Definition md_json.h:44
void md_log_perror(const char *file, int line, md_log_level_t level, apr_status_t rv, apr_pool_t *p, const char *fmt,...)
Definition md_log.c:68
#define MD_LOG_MARK
Definition md_log.h:39
@ MD_LOG_TRACE2
Definition md_log.h:30
@ MD_LOG_TRACE1
Definition md_log.h:29
@ MD_LOG_ERR
Definition md_log.h:24
@ MD_LOG_TRACE3
Definition md_log.h:31
@ MD_LOG_DEBUG
Definition md_log.h:28
@ MD_LOG_INFO
Definition md_log.h:27
const char * md_store_group_name(unsigned int group)
Definition md_store.c:62
#define MD_FN_PUBCERT
Definition md_store.h:87
md_store_group_t
Definition md_store.h:62
@ MD_SG_ACCOUNTS
Definition md_store.h:64
@ MD_SG_STAGING
Definition md_store.h:67
@ MD_SG_OCSP
Definition md_store.h:70
@ MD_SG_NONE
Definition md_store.h:63
@ MD_SG_COUNT
Definition md_store.h:71
@ MD_SG_ARCHIVE
Definition md_store.h:68
@ MD_SG_TMP
Definition md_store.h:69
@ MD_SG_CHALLENGES
Definition md_store.h:65
@ MD_SG_DOMAINS
Definition md_store.h:66
md_store_vtype_t
Definition md_store.h:52
@ MD_SV_PKEY
Definition md_store.h:56
@ MD_SV_CERT
Definition md_store.h:55
@ MD_SV_JSON
Definition md_store.h:54
@ MD_SV_TEXT
Definition md_store.h:53
@ MD_SV_CHAIN
Definition md_store.h:57
int md_store_inspect(void *baton, const char *name, const char *aspect, md_store_vtype_t vtype, void *value, apr_pool_t *ptemp)
Definition md_store.h:152
#define MD_FN_CERT
Definition md_store.h:88
#define MD_FN_PRIVKEY
Definition md_store.h:86
static apr_status_t insp_name(void *baton, apr_pool_t *p, apr_pool_t *ptemp, const char *dir, const char *name, apr_filetype_e ftype)
static apr_time_t fs_get_modified(md_store_t *store, md_store_group_t group, const char *name, const char *aspect, apr_pool_t *p)
static apr_status_t mk_pubcert(void *baton, apr_pool_t *p, apr_pool_t *ptemp, const char *dir, const char *name, apr_filetype_e ftype)
static apr_status_t pfs_purge(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
static apr_status_t fs_move(md_store_t *store, apr_pool_t *p, md_store_group_t from, md_store_group_t to, const char *name, int archive)
static apr_status_t fs_remove_nms(md_store_t *store, apr_pool_t *p, apr_time_t modified, md_store_group_t group, const char *name, const char *aspect)
static apr_status_t fs_iterate(md_store_inspect *inspect, void *baton, md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *pattern, const char *aspect, md_store_vtype_t vtype)
static apr_status_t fs_get_fname(const char **pfname, md_store_t *store, md_store_group_t group, const char *name, const char *aspect, apr_pool_t *p)
static apr_status_t remove_nms_file(void *baton, apr_pool_t *p, apr_pool_t *ptemp, const char *dir, const char *name, apr_filetype_e ftype)
static void get_pass(const char **ppass, apr_size_t *plen, md_store_fs_t *s_fs, md_store_group_t group)
static apr_status_t remove_nms_dir(void *baton, apr_pool_t *p, apr_pool_t *ptemp, const char *dir, const char *name, apr_filetype_e ftype)
#define MD_FS_LOCK_NAME
Definition md_store_fs.c:42
static apr_status_t pfs_load(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
static apr_status_t pfs_get_modified(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
static apr_status_t upgrade_from_1_0(md_store_fs_t *s_fs, apr_pool_t *p, apr_pool_t *ptemp)
static int fs_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2, const char *name, const char *aspect, apr_pool_t *p)
static apr_status_t pfs_move(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
static apr_status_t fs_lock_global(md_store_t *store, apr_pool_t *p, apr_time_t max_wait)
static apr_status_t dispatch(md_store_fs_t *s_fs, md_store_fs_ev_t ev, unsigned int group, const char *fname, apr_filetype_e ftype, apr_pool_t *p)
static apr_status_t init_store_file(md_store_fs_t *s_fs, const char *fname, apr_pool_t *p, apr_pool_t *ptemp)
static apr_status_t pfs_save(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
#define FS_STORE(store)
Definition md_store_fs.c:68
static apr_status_t setup_store_file(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
#define FS_STORE_KLEN
Definition md_store_fs.c:70
static apr_status_t pfs_rename(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
apr_status_t md_store_fs_default_perms_set(md_store_t *store, apr_fileperms_t file_perms, apr_fileperms_t dir_perms)
static apr_status_t read_store_file(md_store_fs_t *s_fs, const char *fname, apr_pool_t *p, apr_pool_t *ptemp)
static const perms_t * gperms(md_store_fs_t *s_fs, md_store_group_t group)
apr_status_t md_store_fs_init(md_store_t **pstore, apr_pool_t *p, const char *path)
static apr_status_t fs_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *name, const char *aspect, md_store_vtype_t vtype, void *value, int create)
apr_status_t md_store_fs_group_perms_set(md_store_t *store, md_store_group_t group, apr_fileperms_t file_perms, apr_fileperms_t dir_perms)
static apr_status_t rename_pkey(void *baton, apr_pool_t *p, apr_pool_t *ptemp, const char *dir, const char *name, apr_filetype_e ftype)
static apr_status_t fs_purge(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *name)
static apr_status_t fs_iterate_names(md_store_inspect *inspect, void *baton, md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *pattern)
static apr_status_t fs_rename(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *from, const char *to)
static apr_status_t fs_remove(md_store_t *store, md_store_group_t group, const char *name, const char *aspect, apr_pool_t *p, int force)
static apr_status_t insp(void *baton, apr_pool_t *p, apr_pool_t *ptemp, const char *dir, const char *name, apr_filetype_e ftype)
static apr_status_t fs_fload(void **pvalue, md_store_fs_t *s_fs, const char *fpath, md_store_group_t group, md_store_vtype_t vtype, apr_pool_t *p, apr_pool_t *ptemp)
#define FS_STORE_JSON
Definition md_store_fs.c:69
static apr_status_t insp_dir(void *baton, apr_pool_t *p, apr_pool_t *ptemp, const char *dir, const char *name, apr_filetype_e ftype)
static apr_status_t fs_get_dname(const char **pdname, md_store_t *store, md_store_group_t group, const char *name, apr_pool_t *p)
static apr_status_t pfs_remove(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
static void fs_unlock_global(md_store_t *store, apr_pool_t *p)
static apr_status_t mk_group_dir(const char **pdir, md_store_fs_t *s_fs, md_store_group_t group, const char *name, apr_pool_t *p)
static apr_status_t pfs_is_newer(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
#define MD_STORE_VERSION
Definition md_store_fs.c:41
apr_status_t md_store_fs_set_event_cb(struct md_store_t *store, md_store_fs_cb *cb, void *baton)
static apr_status_t fs_load(md_store_t *store, md_store_group_t group, const char *name, const char *aspect, md_store_vtype_t vtype, void **pvalue, apr_pool_t *p)
#define MD_FPROT_F_UONLY
Definition md_store_fs.h:26
apr_status_t md_store_fs_cb(void *baton, struct md_store_t *store, md_store_fs_ev_t ev, unsigned int group, const char *fname, apr_filetype_e ftype, apr_pool_t *p)
Definition md_store_fs.h:58
#define MD_FPROT_F_UALL_WREAD
Definition md_store_fs.h:38
md_store_fs_ev_t
Definition md_store_fs.h:53
@ MD_S_FS_EV_MOVED
Definition md_store_fs.h:55
@ MD_S_FS_EV_CREATED
Definition md_store_fs.h:54
#define MD_FPROT_D_UONLY
Definition md_store_fs.h:27
#define MD_FPROT_D_UALL_WREAD
Definition md_store_fs.h:39
#define MD_FPROT_F_UALL_GREAD
Definition md_store_fs.h:32
apr_status_t md_util_rm_recursive(const char *fpath, apr_pool_t *p, int max_level)
Definition md_util.c:586
apr_size_t md_util_base64url_decode(md_data_t *decoded, const char *encoded, apr_pool_t *pool)
Definition md_util.c:1157
apr_status_t md_util_pool_vdo(md_util_vaction *cb, void *baton, apr_pool_t *p,...)
Definition md_util.c:65
apr_status_t md_util_is_dir(const char *path, apr_pool_t *pool)
Definition md_util.c:381
apr_status_t md_util_files_do(md_util_fdo_cb *cb, void *baton, apr_pool_t *p, const char *path,...)
Definition md_util.c:668
void md_data_pinit(md_data_t *d, apr_size_t len, apr_pool_t *p)
Definition md_util.c:79
apr_status_t md_text_freplace(const char *fpath, apr_fileperms_t perms, apr_pool_t *p, const char *text)
Definition md_util.c:521
apr_status_t md_util_path_merge(const char **ppath, apr_pool_t *p,...)
Definition md_util.c:416
apr_status_t md_text_fread8k(const char **ptext, apr_pool_t *p, const char *fpath)
Definition md_util.c:472
apr_status_t md_util_is_file(const char *path, apr_pool_t *pool)
Definition md_util.c:391
const char * md_util_base64url_encode(const md_data_t *data, apr_pool_t *pool)
Definition md_util.c:1207
apr_status_t md_text_fcreatex(const char *fpath, apr_fileperms_t perms, apr_pool_t *p, const char *text)
Definition md_util.c:500
static apr_file_t * out
Definition mod_info.c:85
return NULL
Definition mod_so.c:359
apr_status_t apr_file_lock(apr_file_t *thefile, int type)
Definition flock.c:21
char * name
const char * dirname
md_store_inspect * inspect
md_store_fs_t * s_fs
apr_time_t ts
const char * aspect
const char * pattern
md_store_group_t group
md_store_vtype_t vtype
const char * data
Definition md_util.h:42
apr_size_t len
Definition md_util.h:43
md_store_t s
Definition md_store_fs.c:51
const char * base
Definition md_store_fs.c:53
int plain_pkey[MD_SG_COUNT]
Definition md_store_fs.c:60
void * event_baton
Definition md_store_fs.c:57
perms_t def_perms
Definition md_store_fs.c:54
apr_file_t * global_lock
Definition md_store_fs.c:65
perms_t group_perms[MD_SG_COUNT]
Definition md_store_fs.c:55
md_data_t key
Definition md_store_fs.c:59
md_store_fs_cb * event_cb
Definition md_store_fs.c:56
md_store_unlock_global_cb * unlock_global
Definition md_store.h:339
md_store_rename_cb * rename
Definition md_store.h:330
md_store_iter_cb * iterate
Definition md_store.h:331
md_store_get_fname_cb * get_fname
Definition md_store.h:334
md_store_save_cb * save
Definition md_store.h:326
md_store_get_modified_cb * get_modified
Definition md_store.h:336
md_store_names_iter_cb * iterate_names
Definition md_store.h:332
md_store_remove_nms_cb * remove_nms
Definition md_store.h:337
md_store_remove_cb * remove
Definition md_store.h:328
md_store_load_cb * load
Definition md_store.h:327
md_store_move_cb * move
Definition md_store.h:329
md_store_lock_global_cb * lock_global
Definition md_store.h:338
md_store_is_newer_cb * is_newer
Definition md_store.h:335
md_store_purge_cb * purge
Definition md_store.h:333
apr_fileperms_t file
Definition md_store_fs.c:46
apr_fileperms_t dir
Definition md_store_fs.c:45
apr_status_t apr_dir_make(const char *path, apr_fileperms_t perm, apr_pool_t *pool)
Definition dir.c:297
INT info