s3-rpc: Decrypt with the proper session key in CreateTrustedDomainEx2.
[kai/samba.git] / source3 / rpc_server / rpc_sock_helper.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *
4  *  RPC Socket Helper
5  *
6  *  Copyright (c) 2011      Andreas Schneider <asn@samba.org>
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "includes.h"
23 #include "ntdomain.h"
24
25 #include "../lib/tsocket/tsocket.h"
26 #include "librpc/rpc/dcerpc_ep.h"
27 #include "rpc_server/rpc_server.h"
28 #include "rpc_server/rpc_sock_helper.h"
29
30 NTSTATUS rpc_create_tcpip_sockets(const struct ndr_interface_table *iface,
31                                   struct dcerpc_binding_vector *bvec,
32                                   uint16_t port,
33                                   int *listen_fd,
34                                   int *listen_fd_size)
35 {
36         uint32_t num_ifs = iface_count();
37         uint32_t i;
38         uint16_t p = port;
39         TALLOC_CTX *tmp_ctx;
40         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
41         int rc;
42
43         tmp_ctx = talloc_stackframe();
44         if (tmp_ctx == NULL) {
45                 return NT_STATUS_NO_MEMORY;
46         }
47
48         if (lp_interfaces() && lp_bind_interfaces_only()) {
49                 /*
50                  * We have been given an interfaces line, and been told to only
51                  * bind to those interfaces. Create a socket per interface and
52                  * bind to only these.
53                  */
54
55                 /* Now open a listen socket for each of the interfaces. */
56                 for (i = 0; i < num_ifs; i++) {
57                         const struct sockaddr_storage *ifss =
58                                         iface_n_sockaddr_storage(i);
59                         struct tsocket_address *bind_addr;
60                         const char *addr;
61                         int fd;
62
63                         fd = create_tcpip_socket(ifss, &p);
64                         if (fd < 0 || p == 0) {
65                                 status = NT_STATUS_UNSUCCESSFUL;
66                                 goto done;
67                         }
68                         listen_fd[*listen_fd_size] = fd;
69                         (*listen_fd_size)++;
70
71                         if (bvec != NULL) {
72                                 rc = tsocket_address_bsd_from_sockaddr(tmp_ctx,
73                                                                        (struct sockaddr *)ifss,
74                                                                        sizeof(struct sockaddr_storage),
75                                                                        &bind_addr);
76                                 if (rc < 0) {
77                                         close(fd);
78                                         status = NT_STATUS_NO_MEMORY;
79                                         goto done;
80                                 }
81
82                                 addr = tsocket_address_inet_addr_string(bind_addr,
83                                                                         tmp_ctx);
84                                 if (addr == NULL) {
85                                         close(fd);
86                                         status = NT_STATUS_NO_MEMORY;
87                                         goto done;
88                                 }
89
90                                 status = dcerpc_binding_vector_add_port(iface,
91                                                                         bvec,
92                                                                         addr,
93                                                                         p);
94                                 if (!NT_STATUS_IS_OK(status)) {
95                                         close(fd);
96                                         goto done;
97                                 }
98                         }
99                 }
100         } else {
101                 const char *sock_addr = lp_socket_address();
102                 const char *sock_ptr;
103                 char *sock_tok;
104
105                 if (strequal(sock_addr, "0.0.0.0") ||
106                     strequal(sock_addr, "::")) {
107 #if HAVE_IPV6
108                         sock_addr = "::,0.0.0.0";
109 #else
110                         sock_addr = "0.0.0.0";
111 #endif
112                 }
113
114                 for (sock_ptr = sock_addr;
115                      next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
116                     ) {
117                         struct sockaddr_storage ss;
118                         int fd;
119
120                         /* open an incoming socket */
121                         if (!interpret_string_addr(&ss,
122                                                    sock_tok,
123                                                    AI_NUMERICHOST|AI_PASSIVE)) {
124                                 continue;
125                         }
126
127                         fd = create_tcpip_socket(&ss, &p);
128                         if (fd < 0 || p == 0) {
129                                 status = NT_STATUS_UNSUCCESSFUL;
130                                 goto done;
131                         }
132                         listen_fd[*listen_fd_size] = fd;
133                         (*listen_fd_size)++;
134
135                         if (bvec != NULL) {
136                                 status = dcerpc_binding_vector_add_port(iface,
137                                                                         bvec,
138                                                                         sock_ptr,
139                                                                         p);
140                                 if (!NT_STATUS_IS_OK(status)) {
141                                         close(fd);
142                                         return status;
143                                 }
144                         }
145                 }
146         }
147
148         status = NT_STATUS_OK;
149 done:
150         talloc_free(tmp_ctx);
151         return status;
152 }
153
154 NTSTATUS rpc_setup_tcpip_sockets(struct tevent_context *ev_ctx,
155                                  struct messaging_context *msg_ctx,
156                                  const struct ndr_interface_table *iface,
157                                  struct dcerpc_binding_vector *bvec,
158                                  uint16_t port)
159 {
160         uint32_t num_ifs = iface_count();
161         uint32_t i;
162         uint16_t p = 0;
163         TALLOC_CTX *tmp_ctx;
164         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
165         int rc;
166
167         tmp_ctx = talloc_stackframe();
168         if (tmp_ctx == NULL) {
169                 return NT_STATUS_NO_MEMORY;
170         }
171
172         if (lp_interfaces() && lp_bind_interfaces_only()) {
173                 /*
174                  * We have been given an interfaces line, and been told to only
175                  * bind to those interfaces. Create a socket per interface and
176                  * bind to only these.
177                  */
178
179                 /* Now open a listen socket for each of the interfaces. */
180                 for (i = 0; i < num_ifs; i++) {
181                         const struct sockaddr_storage *ifss =
182                                         iface_n_sockaddr_storage(i);
183                         struct tsocket_address *bind_addr;
184                         const char *addr;
185
186                         p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
187                                                             msg_ctx,
188                                                             ifss,
189                                                             port);
190                         if (p == 0) {
191                                 status = NT_STATUS_UNSUCCESSFUL;
192                                 goto done;
193                         }
194
195                         if (bvec != NULL) {
196                                 rc = tsocket_address_bsd_from_sockaddr(tmp_ctx,
197                                                                        (struct sockaddr*)ifss,
198                                                                        sizeof(struct sockaddr_storage),
199                                                                        &bind_addr);
200                                 if (rc < 0) {
201                                         return NT_STATUS_NO_MEMORY;
202                                 }
203
204                                 addr = tsocket_address_inet_addr_string(bind_addr,
205                                                                         tmp_ctx);
206                                 if (addr == NULL) {
207                                         return NT_STATUS_NO_MEMORY;
208                                 }
209
210                                 status = dcerpc_binding_vector_add_port(iface,
211                                                                         bvec,
212                                                                         addr,
213                                                                         p);
214                                 if (!NT_STATUS_IS_OK(status)) {
215                                         return status;
216                                 }
217                         }
218                 }
219         } else {
220                 const char *sock_addr = lp_socket_address();
221                 const char *sock_ptr;
222                 char *sock_tok;
223
224                 if (strequal(sock_addr, "0.0.0.0") ||
225                     strequal(sock_addr, "::")) {
226 #if HAVE_IPV6
227                         sock_addr = "::,0.0.0.0";
228 #else
229                         sock_addr = "0.0.0.0";
230 #endif
231                 }
232
233                 for (sock_ptr = sock_addr;
234                      next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
235                     ) {
236                         struct sockaddr_storage ss;
237
238                         /* open an incoming socket */
239                         if (!interpret_string_addr(&ss,
240                                                    sock_tok,
241                                                    AI_NUMERICHOST|AI_PASSIVE)) {
242                                 continue;
243                         }
244
245                         p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
246                                                             msg_ctx,
247                                                             &ss,
248                                                             port);
249                         if (p == 0) {
250                                 return NT_STATUS_UNSUCCESSFUL;
251                         }
252
253                         if (bvec != NULL) {
254                                 status = dcerpc_binding_vector_add_port(iface,
255                                                                         bvec,
256                                                                         sock_tok,
257                                                                         p);
258                                 if (!NT_STATUS_IS_OK(status)) {
259                                         return status;
260                                 }
261                         }
262                 }
263         }
264
265         status = NT_STATUS_OK;
266 done:
267         talloc_free(tmp_ctx);
268         return status;
269 }
270
271 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */