1 /*------------------------------------------------------------------------------
2  *
3  * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4  * The YADIFA TM software product is provided under the BSD 3-clause license:
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  *        * Redistributions of source code must retain the above copyright
11  *          notice, this list of conditions and the following disclaimer.
12  *        * Redistributions in binary form must reproduce the above copyright
13  *          notice, this list of conditions and the following disclaimer in the
14  *          documentation and/or other materials provided with the distribution.
15  *        * Neither the name of EURid nor the names of its contributors may be
16  *          used to endorse or promote products derived from this software
17  *          without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  *------------------------------------------------------------------------------
32  *
33  */
34 
35 /** @defgroup dnsdbzone Zone related functions
36  *  @ingroup dnsdb
37  *  @brief Functions used to manipulate a zone
38  *
39  *  Functions used to manipulate a zone
40  *
41  * @{
42  */
43 
44 #include "dnsdb/dnsdb-config.h"
45 #include <unistd.h>
46 #include <arpa/inet.h>
47 
48 #include <dnscore/mutex.h>
49 
50 #include <dnscore/dnscore.h>
51 
52 #include <dnscore/logger.h>
53 
54 #include "dnsdb/zdb.h"
55 
56 #include "dnsdb/zdb-zone-find.h"
57 #include "dnsdb/zdb_zone_label.h"
58 #include "dnsdb/zdb_rr_label.h"
59 #include "dnsdb/zdb_record.h"
60 
61 #include "dnsdb/zdb_utils.h"
62 #include "dnsdb/zdb_error.h"
63 
64 #include "dnsdb/dnsrdata.h"
65 
66 #if ZDB_HAS_NSEC_SUPPORT
67 #include "dnsdb/nsec.h"
68 #endif
69 #if ZDB_HAS_NSEC3_SUPPORT
70 #include "dnsdb/nsec3.h"
71 #endif
72 
73 #if DEBUG
74 #define ZONE_MUTEX_LOG 0    // set this to 0 to disable in DEBUG
75 #else
76 #define ZONE_MUTEX_LOG 0
77 #endif
78 
79 extern logger_handle* g_database_logger;
80 #define MODULE_MSG_HANDLE g_database_logger
81 
82 /**
83  * @brief Get the zone with the given name
84  *
85  * Get the zone with the given name
86  *
87  * No reference counting is done.  This is ultimately used to find existence.
88  *
89  * @param[in] db a pointer to the database
90  * @param[in] exact_match_origin the name of the zone
91  *
92  * @return a pointer to zone or NULL if the zone is not in the database
93  *
94  */
95 
96 static inline zdb_zone*
zdb_zone_find(zdb * db,dnsname_vector * exact_match_origin)97 zdb_zone_find(zdb *db, dnsname_vector *exact_match_origin) // INTERNAL mutex checked
98 {
99     /* Find label */
100 
101     yassert(group_mutex_islocked(&db->mutex));
102 
103     zdb_zone_label *zone_label = zdb_zone_label_find(db, exact_match_origin); // zdb_zone_find
104 
105     if(zone_label != NULL)
106     {
107         return zone_label->zone;
108     }
109     else
110     {
111         return NULL;
112     }
113 }
114 
zdb_zone_exists(zdb * db,dnsname_vector * exact_match_origin)115 bool zdb_zone_exists(zdb *db, dnsname_vector* exact_match_origin)
116 {
117     zdb_lock(db, ZDB_MUTEX_READER);
118     bool does_exist = (zdb_zone_find(db, exact_match_origin) != NULL); // INTERNAL
119     zdb_unlock(db, ZDB_MUTEX_READER);
120     return does_exist;
121 }
122 
123 /**
124  * @brief Get the zone with the given name
125  *
126  * Get the zone with the given name
127  *
128  * No reference counting is done.  This is ultimately used to find existence.
129  *
130  * @param[in] db a pointer to the database
131  * @param[in] name the name of the zone (dotted c-string)
132  *
133  * @return a pointer to zone or NULL if the zone is not in the database
134  *
135  */
136 
137 static inline zdb_zone *
zdb_zone_find_from_name(zdb * db,const char * name)138 zdb_zone_find_from_name(zdb* db, const char* name) // INTERNAL mutex checked
139 {
140     dnsname_vector origin;
141 
142     u8 dns_name[MAX_DOMAIN_LENGTH];
143 
144     if(ISOK(cstr_to_dnsname(dns_name, name)))
145     {
146         dnsname_to_dnsname_vector(dns_name, &origin);
147 
148         zdb_zone *zone = zdb_zone_find(db, &origin); // INTERNAL
149 
150         return zone;
151     }
152 
153     return NULL;
154 }
155 
zdb_zone_exists_from_name(zdb * db,const char * name)156 bool zdb_zone_exists_from_name(zdb *db, const char* name)
157 {
158     zdb_lock(db, ZDB_MUTEX_READER);
159     bool does_exist = (zdb_zone_find_from_name(db, name) != NULL); // INTERNAL
160     zdb_unlock(db, ZDB_MUTEX_READER);
161     return does_exist;
162 }
163 
164 /**
165  * @brief Get the zone with the given dns name
166  *
167  * Get the zone with the given dns name
168  *
169  * No reference counting is done.  This is ultimately used to find existence.
170  *
171  * @param[in] db a pointer to the database
172  * @param[in] name the name of the zone (dns name)
173  *
174  * @return a pointer to zone or NULL if the zone is not in the database
175  *
176  */
177 
178 static inline zdb_zone *
zdb_zone_find_from_dnsname(zdb * db,const u8 * dns_name)179 zdb_zone_find_from_dnsname(zdb* db, const u8 *dns_name) // INTERNAL mutex checked
180 {
181     dnsname_vector origin;
182 
183     yassert(group_mutex_islocked(&db->mutex));
184 
185     dnsname_to_dnsname_vector(dns_name, &origin);
186 
187     zdb_zone *zone = zdb_zone_find(db, &origin); // INTERNAL
188 
189     return zone;
190 }
191 
192 bool
zdb_zone_exists_from_dnsname(zdb * db,const u8 * dns_name)193 zdb_zone_exists_from_dnsname(zdb *db, const u8* dns_name)
194 {
195     zdb_lock(db, ZDB_MUTEX_READER);
196     bool does_exist = (zdb_zone_find_from_dnsname(db, dns_name) != NULL); // KEEP
197     zdb_unlock(db, ZDB_MUTEX_READER);
198     return does_exist;
199 }
200 
201 /** @} */
202