1 #ifndef __ldapdns_h
2 #define __ldapdns_h
3 
4 #include <lber.h>
5 #include <ldap.h>
6 #include <netdb.h>
7 
8 #include <pthread.h>
9 
10 #include <sys/time.h>
11 #include <time.h>
12 
13 #include "list.h"
14 #include "str.h"
15 #include "bin.h"
16 #include "ht.h"
17 
18 #include "ip.h"
19 
20 typedef struct dns_ctx_s dns_ctx;
21 typedef struct ldap_ctx_s ldap_ctx;
22 
23 struct ldap_ctx_s {
24 	int n;
25 	int	protocol_version;	/* 2 or 3 */
26 	pthread_t id;
27 	LDAP	*ldap_con;
28 
29 	int load;
30 	pthread_mutex_t load_lock;
31 
32 	pthread_mutex_t lock;
33 
34 	volatile int message_wait;
35 	volatile int message_sent;
36 	pthread_cond_t active;
37 };
38 
39 struct dns_ctx_s {
40 	int		n;
41 	ldap_ctx	*c;	/* current handler */
42 
43 	int		phase;
44 	time_t		lastt;
45 /* here are the following phases
46  */
47 #define PHASE_IDLE		0
48 #define PHASE_ZONESEARCH	1
49 #define PHASE_ATTRSEARCH	2
50 #define PHASE_AXFRFIRST		3
51 #define PHASE_AXFRSEARCH	4
52 #define PHASE_NSUPDATE		5
53 #define PHASE_SIMPLESEARCH	6
54 	/* set if we're a subrequest */
55 	int		subreq;
56 	int		subreq_valid;
57 	list_t		subreq_tries;
58 	list_t		subreq_done;
59 	char		*subreq_in;
60 	char		*subreq_in_alloc;
61 	char		*subreq_in_zone;
62 	int		answers;
63 	int		soahack;
64 
65 	/* protocol */
66 	char		dns_message_id[2];
67 	int		protnum;
68 #define PROT_DNS		0
69 #define PROT_NETBIOS		1
70 
71 	/* locking constraint */
72 	pthread_mutex_t lock;
73 
74 	/* where the request comes from */
75 	int		sock;
76 	unsigned char		ip[IP_LEN];
77 	int		port;
78 
79 	/* reassembled from TCP */
80 	unsigned short	tcplen, tcppos;
81 
82 	/* original request name */
83 	char		*request_name_zone;
84 	char		*request_name_alloc;
85 	char		*request_name;
86 	char		*request_attr;
87 	char		request_record[2];
88 
89 	/* maximum size of udp request; we don't support big tcp reqs either */
90 	char		request_buf[513];
91 	int		request_len;
92 	int		request_pos;
93 
94 	/* in message-waiting block */
95 	int		message_id;
96 	LDAPMessage	*message;
97 	//LDAPMessage	*message_entry;
98 
99 	/* static for the connection */
100 	int		wantdie;
101 	list_t		NS;
102 	unsigned long	serial, refresh, retry, expire, minimum;
103 	unsigned long	ttl;
104 
105 	/* used per-round */
106 	list_t		DNSRecord;
107 	list_t		A,CNAME,ADM,MX,SRV,TXT,PTR,Generic;
108 	int		adlen;
109 	char 		*search_base;
110 
111 
112 	/* helper for restarting phase-2 queries */
113 	int		attr_wild;
114 
115 	/* update helper */
116 	char		*update;
117 	list_t		sec_prereq;
118 	list_t		sec_update;
119 
120 	/* used in zone transfers */
121 	char		*axfr_base;
122 	int		axfr;
123 	list_t		ns;
124 	int		still_using_message;
125 
126 	list_t saved_NS;
127 	unsigned long saved_soa[6];
128 	int saved_wantdie;
129 	int saved_adlen;
130 
131 	/* and response */
132 	bin_t		response;
133 	int		response_tc;
134 	int		response_dpos;
135 	ht		response_names;
136 	int		response_ls;
137 
138 	/* this is the switch mechanism */
139 	char		*swm;
140 
141 	/* this implements a doubly-linked list */
142 	dns_ctx	*next, *prev;
143 };
144 
145 extern dns_ctx *handler;
146 
147 void inline ldapdns_list_unique(list_t *p);
148 
149 #define name_to_dns(a,b) name_to_dns_fix(a,b,0)
150 void name_to_dns_fix(str_t retbuf, char *name, int splithow);
151 void dns_to_name(str_t retbuf, char *dns, int joinhow);
152 
153 void name_to_ldap(str_t retbuf, char *name);
154 void ldap_to_name(str_t retbuf, char *dn);
155 
156 void join_name_parts(str_t retbuf, list_t p);
157 void join_dns_parts(str_t retbuf, list_t p);
158 list_t ldap_into_parts(char *dn);
join_ldap_parts(str_t retbuf,list_t p)159 static void inline join_ldap_parts(str_t retbuf, list_t p)
160 {
161 	str_t tmp;
162 
163 	str_init(tmp);
164 	join_name_parts(tmp, p);
165 	name_to_ldap(retbuf, str(tmp));
166 	free(tmp->buf);
167 	free(tmp);
168 }
169 
170 list_t split_name_parts(char *name);
171 list_t split_dns_parts(char *dns);
split_ldap_parts(char * dn)172 static list_t inline split_ldap_parts(char *dn) {
173 	str_t tmp;
174 	list_t p;
175 
176 	ldap_to_name(tmp, dn);
177 	p = split_name_parts(str(tmp));
178 	free(tmp->buf);
179 	free(tmp);
180 
181 	return p;
182 }
183 
184 int response_query(dns_ctx *, char *dnsenc, char rr[2], char cc[2]);
185 int response_notify(dns_ctx *, char *dnsenc, char rr[2], char cc[2]);
186 int response_rstart(dns_ctx *, char *dnsenc, char rr[2], unsigned int ttl);
187 
188 int response_addname(dns_ctx *, char *dnsenc);
189 int response_addbytes(dns_ctx *, unsigned char *, int);
190 
191 int response_addulong(dns_ctx *, unsigned long);
192 int response_addushort(dns_ctx *, unsigned short);
193 int response_addnameptr(dns_ctx *c, unsigned int u);
194 
195 void response_id(dns_ctx *, const char id[2]);
196 void response_tc(dns_ctx *);
197 void response_aa(dns_ctx *, int setting);
198 void response_rcode(dns_ctx *, int code);
199 void response_nxdomain(dns_ctx *);
200 void response_servfail(dns_ctx *);
201 void response_refuse(dns_ctx *);
202 
203 void response_axfr(dns_ctx *c);
204 int response_axstart(dns_ctx *c, int soa, char *q, char qt[2], char qc[2], unsigned int ttl);
205 void response_axfinish(dns_ctx *c);
206 
207 int response_rfinish(dns_ctx *, int section);
208 
209 unsigned int dns_packet_copy(dns_ctx *c, char *out,unsigned int outlen);
210 unsigned int dns_packet_skipname(dns_ctx *c);
211 unsigned int dns_packet_getname(dns_ctx *c, char **d);
212 unsigned int dns_domain_length(const char *dn);
213 int dns_domain_copy(char **out,char *in);
214 void dns_domain_lower(char *q);
215 
216 int inline ldap_load_dns_attributes(dns_ctx *c, char **dn, int zonef);
217 
218 
219 /* user-level */
220 void tp_initialize(void);
221 void inline tp_housekeeping(long *);
222 int inline tp_write(dns_ctx *c);
223 int inline tp_read(dns_ctx *c);
224 void tp_close(dns_ctx *c);
225 
226 #endif
227