s3: RPC: Don't crash on trying to talloc_free(-1) if smb_iconv_open_ex() fails.
[Samba.git] / source3 / rpc_server / rpc_sock_helper.c
blob069d0959534d383caf0e75e3b247cc553a15520b
1 /*
2 * Unix SMB/CIFS implementation.
4 * RPC Socket Helper
6 * Copyright (c) 2011 Andreas Schneider <asn@samba.org>
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.
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.
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/>.
22 #include "includes.h"
23 #include "ntdomain.h"
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 #include "lib/server_prefork.h"
31 #undef DBGC_CLASS
32 #define DBGC_CLASS DBGC_RPC_SRV
34 NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets(
35 const struct ndr_interface_table *iface,
36 struct dcerpc_binding_vector *bvec,
37 uint16_t port,
38 struct pf_listen_fd *listen_fd,
39 int *listen_fd_size)
41 uint32_t num_ifs = iface_count();
42 uint32_t i;
43 uint16_t p = port;
44 TALLOC_CTX *tmp_ctx;
45 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
46 int rc;
48 tmp_ctx = talloc_stackframe();
49 if (tmp_ctx == NULL) {
50 return NT_STATUS_NO_MEMORY;
53 if (lp_interfaces() && lp_bind_interfaces_only()) {
55 * We have been given an interfaces line, and been told to only
56 * bind to those interfaces. Create a socket per interface and
57 * bind to only these.
60 /* Now open a listen socket for each of the interfaces. */
61 for (i = 0; i < num_ifs; i++) {
62 const struct sockaddr_storage *ifss =
63 iface_n_sockaddr_storage(i);
64 struct tsocket_address *bind_addr;
65 const char *addr;
66 int fd;
68 status = dcesrv_create_ncacn_ip_tcp_socket(ifss,
69 &p,
70 &fd);
71 if (!NT_STATUS_IS_OK(status)) {
72 goto done;
74 listen_fd[*listen_fd_size].fd = fd;
75 listen_fd[*listen_fd_size].fd_data = NULL;
76 (*listen_fd_size)++;
78 if (bvec != NULL) {
79 rc = tsocket_address_bsd_from_sockaddr(tmp_ctx,
80 (const struct sockaddr *)ifss,
81 sizeof(struct sockaddr_storage),
82 &bind_addr);
83 if (rc < 0) {
84 close(fd);
85 status = NT_STATUS_NO_MEMORY;
86 goto done;
89 addr = tsocket_address_inet_addr_string(bind_addr,
90 tmp_ctx);
91 if (addr == NULL) {
92 close(fd);
93 status = NT_STATUS_NO_MEMORY;
94 goto done;
97 status = dcerpc_binding_vector_add_port(iface,
98 bvec,
99 addr,
101 if (!NT_STATUS_IS_OK(status)) {
102 close(fd);
103 goto done;
107 } else {
108 const char *sock_addr;
109 const char *sock_ptr;
110 char *sock_tok;
112 #ifdef HAVE_IPV6
113 sock_addr = "::,0.0.0.0";
114 #else
115 sock_addr = "0.0.0.0";
116 #endif
118 for (sock_ptr = sock_addr;
119 next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
121 struct sockaddr_storage ss;
122 int fd;
124 /* open an incoming socket */
125 if (!interpret_string_addr(&ss,
126 sock_tok,
127 AI_NUMERICHOST|AI_PASSIVE)) {
128 continue;
131 status = dcesrv_create_ncacn_ip_tcp_socket(&ss,
133 &fd);
134 if (!NT_STATUS_IS_OK(status)) {
135 goto done;
137 listen_fd[*listen_fd_size].fd = fd;
138 listen_fd[*listen_fd_size].fd_data = NULL;
139 (*listen_fd_size)++;
141 if (bvec != NULL) {
142 status = dcerpc_binding_vector_add_port(iface,
143 bvec,
144 sock_tok,
146 if (!NT_STATUS_IS_OK(status)) {
147 close(fd);
148 goto done;
154 status = NT_STATUS_OK;
155 done:
156 talloc_free(tmp_ctx);
157 return status;
160 NTSTATUS dcesrv_setup_ncacn_ip_tcp_sockets(struct tevent_context *ev_ctx,
161 struct messaging_context *msg_ctx,
162 const struct ndr_interface_table *iface,
163 struct dcerpc_binding_vector *bvec,
164 uint16_t port)
166 uint32_t num_ifs = iface_count();
167 uint32_t i;
168 uint16_t p = port;
169 TALLOC_CTX *tmp_ctx;
170 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
171 int rc;
173 tmp_ctx = talloc_stackframe();
174 if (tmp_ctx == NULL) {
175 return NT_STATUS_NO_MEMORY;
178 if (lp_interfaces() && lp_bind_interfaces_only()) {
180 * We have been given an interfaces line, and been told to only
181 * bind to those interfaces. Create a socket per interface and
182 * bind to only these.
185 /* Now open a listen socket for each of the interfaces. */
186 for (i = 0; i < num_ifs; i++) {
187 const struct sockaddr_storage *ifss =
188 iface_n_sockaddr_storage(i);
189 struct tsocket_address *bind_addr;
190 const char *addr;
192 status = dcesrv_setup_ncacn_ip_tcp_socket(ev_ctx,
193 msg_ctx,
194 ifss,
195 &p);
196 if (!NT_STATUS_IS_OK(status)) {
197 goto done;
200 if (bvec != NULL) {
201 rc = tsocket_address_bsd_from_sockaddr(tmp_ctx,
202 (const struct sockaddr*)ifss,
203 sizeof(struct sockaddr_storage),
204 &bind_addr);
205 if (rc < 0) {
206 status = NT_STATUS_NO_MEMORY;
207 goto done;
210 addr = tsocket_address_inet_addr_string(bind_addr,
211 tmp_ctx);
212 if (addr == NULL) {
213 status = NT_STATUS_NO_MEMORY;
214 goto done;
217 status = dcerpc_binding_vector_add_port(iface,
218 bvec,
219 addr,
221 if (!NT_STATUS_IS_OK(status)) {
222 goto done;
226 } else {
227 const char *sock_addr;
228 const char *sock_ptr;
229 char *sock_tok;
231 #ifdef HAVE_IPV6
232 sock_addr = "::,0.0.0.0";
233 #else
234 sock_addr = "0.0.0.0";
235 #endif
237 for (sock_ptr = sock_addr;
238 next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
240 struct sockaddr_storage ss;
242 /* open an incoming socket */
243 if (!interpret_string_addr(&ss,
244 sock_tok,
245 AI_NUMERICHOST|AI_PASSIVE)) {
246 continue;
249 status = dcesrv_setup_ncacn_ip_tcp_socket(ev_ctx,
250 msg_ctx,
251 &ss,
252 &p);
253 if (!NT_STATUS_IS_OK(status)) {
254 goto done;
257 if (bvec != NULL) {
258 status = dcerpc_binding_vector_add_port(iface,
259 bvec,
260 sock_tok,
262 if (!NT_STATUS_IS_OK(status)) {
263 goto done;
269 status = NT_STATUS_OK;
270 done:
271 talloc_free(tmp_ctx);
272 return status;
275 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */