1 /*
2  * UNIX SOCK_STREAM protocol layer (uxst)
3  *
4  * Copyright 2000-2010 Willy Tarreau <w@1wt.eu>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  *
11  */
12 
13 #include <ctype.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <pwd.h>
17 #include <grp.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <syslog.h>
22 #include <time.h>
23 
24 #include <sys/socket.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <sys/un.h>
28 
29 #include <common/compat.h>
30 #include <common/config.h>
31 #include <common/debug.h>
32 #include <common/errors.h>
33 #include <common/mini-clist.h>
34 #include <common/standard.h>
35 #include <common/time.h>
36 #include <common/version.h>
37 
38 #include <types/global.h>
39 
40 #include <proto/connection.h>
41 #include <proto/fd.h>
42 #include <proto/listener.h>
43 #include <proto/log.h>
44 #include <proto/protocol.h>
45 #include <proto/proto_uxst.h>
46 #include <proto/task.h>
47 
48 static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen);
49 static int uxst_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
50 static int uxst_unbind_listeners(struct protocol *proto);
51 static int uxst_connect_server(struct connection *conn, int data, int delack);
52 
53 /* Note: must not be declared <const> as its list will be overwritten */
54 static struct protocol proto_unix = {
55 	.name = "unix_stream",
56 	.sock_domain = PF_UNIX,
57 	.sock_type = SOCK_STREAM,
58 	.sock_prot = 0,
59 	.sock_family = AF_UNIX,
60 	.sock_addrlen = sizeof(struct sockaddr_un),
61 	.l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path),/* path len */
62 	.accept = &listener_accept,
63 	.connect = &uxst_connect_server,
64 	.bind = uxst_bind_listener,
65 	.bind_all = uxst_bind_listeners,
66 	.unbind_all = uxst_unbind_listeners,
67 	.enable_all = enable_all_listeners,
68 	.disable_all = disable_all_listeners,
69 	.get_src = uxst_get_src,
70 	.get_dst = uxst_get_dst,
71 	.pause = uxst_pause_listener,
72 	.listeners = LIST_HEAD_INIT(proto_unix.listeners),
73 	.nb_listeners = 0,
74 };
75 
76 /********************************
77  * 1) low-level socket functions
78  ********************************/
79 
80 /*
81  * Retrieves the source address for the socket <fd>, with <dir> indicating
82  * if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
83  * success, -1 in case of error. The socket's source address is stored in
84  * <sa> for <salen> bytes.
85  */
uxst_get_src(int fd,struct sockaddr * sa,socklen_t salen,int dir)86 int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
87 {
88 	if (dir)
89 		return getsockname(fd, sa, &salen);
90 	else
91 		return getpeername(fd, sa, &salen);
92 }
93 
94 
95 /*
96  * Retrieves the original destination address for the socket <fd>, with <dir>
97  * indicating if we're a listener (=0) or an initiator (!=0). It returns 0 in
98  * case of success, -1 in case of error. The socket's source address is stored
99  * in <sa> for <salen> bytes.
100  */
uxst_get_dst(int fd,struct sockaddr * sa,socklen_t salen,int dir)101 int uxst_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
102 {
103 	if (dir)
104 		return getpeername(fd, sa, &salen);
105 	else
106 		return getsockname(fd, sa, &salen);
107 }
108 
109 
110 /********************************
111  * 2) listener-oriented functions
112  ********************************/
113 
114 
115 /* This function creates a UNIX socket associated to the listener. It changes
116  * the state from ASSIGNED to LISTEN. The socket is NOT enabled for polling.
117  * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL. It
118  * may return a warning or an error message in <errmsg> if the message is at
119  * most <errlen> bytes long (including '\0'). Note that <errmsg> may be NULL if
120  * <errlen> is also zero.
121  */
uxst_bind_listener(struct listener * listener,char * errmsg,int errlen)122 static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen)
123 {
124 	int fd;
125 	char tempname[MAXPATHLEN];
126 	char backname[MAXPATHLEN];
127 	struct sockaddr_un addr;
128 	const char *msg = NULL;
129 	const char *path;
130 	int maxpathlen;
131 	int ext, ready;
132 	socklen_t ready_len;
133 	int err;
134 	int ret;
135 
136 	err = ERR_NONE;
137 
138 	/* ensure we never return garbage */
139 	if (errlen)
140 		*errmsg = 0;
141 
142 	if (listener->state != LI_ASSIGNED)
143 		return ERR_NONE; /* already bound */
144 
145 	path = ((struct sockaddr_un *)&listener->addr)->sun_path;
146 
147 	maxpathlen = MIN(MAXPATHLEN, sizeof(addr.sun_path));
148 
149 	/* if the listener already has an fd assigned, then we were offered the
150 	 * fd by an external process (most likely the parent), and we don't want
151 	 * to create a new socket. However we still want to set a few flags on
152 	 * the socket.
153 	 */
154 	fd = listener->fd;
155 	ext = (fd >= 0);
156 	if (ext)
157 		goto fd_ready;
158 
159 	if (path[0]) {
160 		ret = snprintf(tempname, maxpathlen, "%s.%d.tmp", path, pid);
161 		if (ret < 0 || ret >= maxpathlen) {
162 			err |= ERR_FATAL | ERR_ALERT;
163 			msg = "name too long for UNIX socket (limit usually 97)";
164 			goto err_return;
165 		}
166 
167 		ret = snprintf(backname, maxpathlen, "%s.%d.bak", path, pid);
168 		if (ret < 0 || ret >= maxpathlen) {
169 			err |= ERR_FATAL | ERR_ALERT;
170 			msg = "name too long for UNIX socket (limit usually 97)";
171 			goto err_return;
172 		}
173 
174 		/* 2. clean existing orphaned entries */
175 		if (unlink(tempname) < 0 && errno != ENOENT) {
176 			err |= ERR_FATAL | ERR_ALERT;
177 			msg = "error when trying to unlink previous UNIX socket";
178 			goto err_return;
179 		}
180 
181 		if (unlink(backname) < 0 && errno != ENOENT) {
182 			err |= ERR_FATAL | ERR_ALERT;
183 			msg = "error when trying to unlink previous UNIX socket";
184 			goto err_return;
185 		}
186 
187 		/* 3. backup existing socket */
188 		if (link(path, backname) < 0 && errno != ENOENT) {
189 			err |= ERR_FATAL | ERR_ALERT;
190 			msg = "error when trying to preserve previous UNIX socket";
191 			goto err_return;
192 		}
193 
194 		strncpy(addr.sun_path, tempname, sizeof(addr.sun_path));
195 		addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
196 	}
197 	else {
198 		/* first char is zero, it's an abstract socket whose address
199 		 * is defined by all the bytes past this zero.
200 		 */
201 		memcpy(addr.sun_path, path, sizeof(addr.sun_path));
202 	}
203 	addr.sun_family = AF_UNIX;
204 
205 	fd = socket(PF_UNIX, SOCK_STREAM, 0);
206 	if (fd < 0) {
207 		err |= ERR_FATAL | ERR_ALERT;
208 		msg = "cannot create UNIX socket";
209 		goto err_unlink_back;
210 	}
211 
212  fd_ready:
213 	if (fd >= global.maxsock) {
214 		err |= ERR_FATAL | ERR_ALERT;
215 		msg = "socket(): not enough free sockets, raise -n argument";
216 		goto err_unlink_temp;
217 	}
218 
219 	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
220 		err |= ERR_FATAL | ERR_ALERT;
221 		msg = "cannot make UNIX socket non-blocking";
222 		goto err_unlink_temp;
223 	}
224 
225 	if (!ext && bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
226 		/* note that bind() creates the socket <tempname> on the file system */
227 		if (errno == EADDRINUSE) {
228 			/* the old process might still own it, let's retry */
229 			err |= ERR_RETRYABLE | ERR_ALERT;
230 			msg = "cannot listen to socket";
231 		}
232 		else {
233 			err |= ERR_FATAL | ERR_ALERT;
234 			msg = "cannot bind UNIX socket";
235 		}
236 		goto err_unlink_temp;
237 	}
238 
239 	/* <uid> and <gid> different of -1 will be used to change the socket owner.
240 	 * If <mode> is not 0, it will be used to restrict access to the socket.
241 	 * While it is known not to be portable on every OS, it's still useful
242 	 * where it works. We also don't change permissions on abstract sockets.
243 	 */
244 	if (!ext && path[0] &&
245 	    (((listener->bind_conf->ux.uid != -1 || listener->bind_conf->ux.gid != -1) &&
246 	      (chown(tempname, listener->bind_conf->ux.uid, listener->bind_conf->ux.gid) == -1)) ||
247 	     (listener->bind_conf->ux.mode != 0 && chmod(tempname, listener->bind_conf->ux.mode) == -1))) {
248 		err |= ERR_FATAL | ERR_ALERT;
249 		msg = "cannot change UNIX socket ownership";
250 		goto err_unlink_temp;
251 	}
252 
253 	ready = 0;
254 	ready_len = sizeof(ready);
255 	if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &ready, &ready_len) == -1)
256 		ready = 0;
257 
258 	if (!(ext && ready) && /* only listen if not already done by external process */
259 	    listen(fd, listener->backlog ? listener->backlog : listener->maxconn) < 0) {
260 		err |= ERR_FATAL | ERR_ALERT;
261 		msg = "cannot listen to UNIX socket";
262 		goto err_unlink_temp;
263 	}
264 
265 	/* Point of no return: we are ready, we'll switch the sockets. We don't
266 	 * fear loosing the socket <path> because we have a copy of it in
267 	 * backname. Abstract sockets are not renamed.
268 	 */
269 	if (!ext && path[0] && rename(tempname, path) < 0) {
270 		err |= ERR_FATAL | ERR_ALERT;
271 		msg = "cannot switch final and temporary UNIX sockets";
272 		goto err_rename;
273 	}
274 
275 	/* Cleanup: only unlink if we didn't inherit the fd from the parent */
276 	if (!ext && path[0])
277 		unlink(backname);
278 
279 	/* the socket is now listening */
280 	listener->fd = fd;
281 	listener->state = LI_LISTEN;
282 
283 	/* the function for the accept() event */
284 	fd_insert(fd);
285 	fdtab[fd].iocb = listener->proto->accept;
286 	fdtab[fd].owner = listener; /* reference the listener instead of a task */
287 	return err;
288 
289  err_rename:
290 	ret = rename(backname, path);
291 	if (ret < 0 && errno == ENOENT)
292 		unlink(path);
293  err_unlink_temp:
294 	if (!ext && path[0])
295 		unlink(tempname);
296 	close(fd);
297  err_unlink_back:
298 	if (!ext && path[0])
299 		unlink(backname);
300  err_return:
301 	if (msg && errlen) {
302 		if (!ext)
303 			snprintf(errmsg, errlen, "%s [%s]", msg, path);
304 		else
305 			snprintf(errmsg, errlen, "%s [fd %d]", msg, fd);
306 	}
307 	return err;
308 }
309 
310 /* This function closes the UNIX sockets for the specified listener.
311  * The listener enters the LI_ASSIGNED state. It always returns ERR_NONE.
312  */
uxst_unbind_listener(struct listener * listener)313 static int uxst_unbind_listener(struct listener *listener)
314 {
315 	if (listener->state > LI_ASSIGNED) {
316 		unbind_listener(listener);
317 	}
318 	return ERR_NONE;
319 }
320 
321 /* Add a listener to the list of unix stream listeners. The listener's state
322  * is automatically updated from LI_INIT to LI_ASSIGNED. The number of
323  * listeners is updated. This is the function to use to add a new listener.
324  */
uxst_add_listener(struct listener * listener)325 void uxst_add_listener(struct listener *listener)
326 {
327 	if (listener->state != LI_INIT)
328 		return;
329 	listener->state = LI_ASSIGNED;
330 	listener->proto = &proto_unix;
331 	LIST_ADDQ(&proto_unix.listeners, &listener->proto_list);
332 	proto_unix.nb_listeners++;
333 }
334 
335 /* Pause a listener. Returns < 0 in case of failure, 0 if the listener
336  * was totally stopped, or > 0 if correctly paused. Nothing is done for
337  * plain unix sockets since currently it's the new process which handles
338  * the renaming. Abstract sockets are completely unbound.
339  */
uxst_pause_listener(struct listener * l)340 int uxst_pause_listener(struct listener *l)
341 {
342 	if (((struct sockaddr_un *)&l->addr)->sun_path[0])
343 		return 1;
344 
345 	unbind_listener(l);
346 	return 0;
347 }
348 
349 
350 /*
351  * This function initiates a UNIX connection establishment to the target assigned
352  * to connection <conn> using (si->{target,addr.to}). The source address is ignored
353  * and will be selected by the system. conn->target may point either to a valid
354  * server or to a backend, depending on conn->target. Only OBJ_TYPE_PROXY and
355  * OBJ_TYPE_SERVER are supported. The <data> parameter is a boolean indicating
356  * whether there are data waiting for being sent or not, in order to adjust data
357  * write polling and on some platforms. The <delack> argument is ignored.
358  *
359  * Note that a pending send_proxy message accounts for data.
360  *
361  * It can return one of :
362  *  - SF_ERR_NONE if everything's OK
363  *  - SF_ERR_SRVTO if there are no more servers
364  *  - SF_ERR_SRVCL if the connection was refused by the server
365  *  - SF_ERR_PRXCOND if the connection has been limited by the proxy (maxconn)
366  *  - SF_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...)
367  *  - SF_ERR_INTERNAL for any other purely internal errors
368  * Additionally, in the case of SF_ERR_RESOURCE, an emergency log will be emitted.
369  *
370  * The connection's fd is inserted only when SF_ERR_NONE is returned, otherwise
371  * it's invalid and the caller has nothing to do.
372  */
uxst_connect_server(struct connection * conn,int data,int delack)373 int uxst_connect_server(struct connection *conn, int data, int delack)
374 {
375 	int fd;
376 	struct server *srv;
377 	struct proxy *be;
378 
379 	conn->flags = 0;
380 
381 	switch (obj_type(conn->target)) {
382 	case OBJ_TYPE_PROXY:
383 		be = objt_proxy(conn->target);
384 		srv = NULL;
385 		break;
386 	case OBJ_TYPE_SERVER:
387 		srv = objt_server(conn->target);
388 		be = srv->proxy;
389 		break;
390 	default:
391 		conn->flags |= CO_FL_ERROR;
392 		return SF_ERR_INTERNAL;
393 	}
394 
395 	if ((fd = conn->t.sock.fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
396 		qfprintf(stderr, "Cannot get a server socket.\n");
397 
398 		if (errno == ENFILE) {
399 			conn->err_code = CO_ER_SYS_FDLIM;
400 			send_log(be, LOG_EMERG,
401 				 "Proxy %s reached system FD limit at %d. Please check system tunables.\n",
402 				 be->id, maxfd);
403 		}
404 		else if (errno == EMFILE) {
405 			conn->err_code = CO_ER_PROC_FDLIM;
406 			send_log(be, LOG_EMERG,
407 				 "Proxy %s reached process FD limit at %d. Please check 'ulimit-n' and restart.\n",
408 				 be->id, maxfd);
409 		}
410 		else if (errno == ENOBUFS || errno == ENOMEM) {
411 			conn->err_code = CO_ER_SYS_MEMLIM;
412 			send_log(be, LOG_EMERG,
413 				 "Proxy %s reached system memory limit at %d sockets. Please check system tunables.\n",
414 				 be->id, maxfd);
415 		}
416 		else if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
417 			conn->err_code = CO_ER_NOPROTO;
418 		}
419 		else
420 			conn->err_code = CO_ER_SOCK_ERR;
421 
422 		/* this is a resource error */
423 		conn->flags |= CO_FL_ERROR;
424 		return SF_ERR_RESOURCE;
425 	}
426 
427 	if (fd >= global.maxsock) {
428 		/* do not log anything there, it's a normal condition when this option
429 		 * is used to serialize connections to a server !
430 		 */
431 		Alert("socket(): not enough free sockets. Raise -n argument. Giving up.\n");
432 		close(fd);
433 		conn->err_code = CO_ER_CONF_FDLIM;
434 		conn->flags |= CO_FL_ERROR;
435 		return SF_ERR_PRXCOND; /* it is a configuration limit */
436 	}
437 
438 	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
439 		qfprintf(stderr,"Cannot set client socket to non blocking mode.\n");
440 		close(fd);
441 		conn->err_code = CO_ER_SOCK_ERR;
442 		conn->flags |= CO_FL_ERROR;
443 		return SF_ERR_INTERNAL;
444 	}
445 
446 	/* if a send_proxy is there, there are data */
447 	data |= conn->send_proxy_ofs;
448 
449 	if (global.tune.server_sndbuf)
450                 setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &global.tune.server_sndbuf, sizeof(global.tune.server_sndbuf));
451 
452 	if (global.tune.server_rcvbuf)
453                 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &global.tune.server_rcvbuf, sizeof(global.tune.server_rcvbuf));
454 
455 	if (connect(fd, (struct sockaddr *)&conn->addr.to, get_addr_len(&conn->addr.to)) == -1) {
456 		if (errno == EINPROGRESS || errno == EALREADY) {
457 			conn->flags |= CO_FL_WAIT_L4_CONN;
458 		}
459 		else if (errno == EISCONN) {
460 			conn->flags &= ~CO_FL_WAIT_L4_CONN;
461 		}
462 		else if (errno == EAGAIN || errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
463 			char *msg;
464 			if (errno == EAGAIN || errno == EADDRNOTAVAIL) {
465 				msg = "can't connect to destination unix socket, check backlog size on the server";
466 				conn->err_code = CO_ER_FREE_PORTS;
467 			}
468 			else {
469 				msg = "local address already in use";
470 				conn->err_code = CO_ER_ADDR_INUSE;
471 			}
472 
473 			qfprintf(stderr,"Connect() failed for backend %s: %s.\n", be->id, msg);
474 			close(fd);
475 			send_log(be, LOG_ERR, "Connect() failed for backend %s: %s.\n", be->id, msg);
476 			conn->flags |= CO_FL_ERROR;
477 			return SF_ERR_RESOURCE;
478 		}
479 		else if (errno == ETIMEDOUT) {
480 			close(fd);
481 			conn->err_code = CO_ER_SOCK_ERR;
482 			conn->flags |= CO_FL_ERROR;
483 			return SF_ERR_SRVTO;
484 		}
485 		else {	// (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EACCES || errno == EPERM)
486 			close(fd);
487 			conn->err_code = CO_ER_SOCK_ERR;
488 			conn->flags |= CO_FL_ERROR;
489 			return SF_ERR_SRVCL;
490 		}
491 	}
492 	else {
493 		/* connect() already succeeded, which is quite usual for unix
494 		 * sockets. Let's avoid a second connect() probe to complete it.
495 		 */
496 		conn->flags &= ~CO_FL_WAIT_L4_CONN;
497 	}
498 
499 	conn->flags |= CO_FL_ADDR_TO_SET;
500 
501 	/* Prepare to send a few handshakes related to the on-wire protocol. */
502 	if (conn->send_proxy_ofs)
503 		conn->flags |= CO_FL_SEND_PROXY;
504 
505 	conn_ctrl_init(conn);       /* registers the FD */
506 	fdtab[fd].linger_risk = 0;  /* no need to disable lingering */
507 
508 	if (conn_xprt_init(conn) < 0) {
509 		conn_force_close(conn);
510 		conn->flags |= CO_FL_ERROR;
511 		return SF_ERR_RESOURCE;
512 	}
513 
514 	if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_WAIT_L4_CONN)) {
515 		conn_sock_want_send(conn);  /* for connect status, proxy protocol or SSL */
516 	}
517 	else {
518 		/* If there's no more handshake, we need to notify the data
519 		 * layer when the connection is already OK otherwise we'll have
520 		 * no other opportunity to do it later (eg: health checks).
521 		 */
522 		data = 1;
523 	}
524 
525 	if (data)
526 		conn_data_want_send(conn);  /* prepare to send data if any */
527 
528 	return SF_ERR_NONE;  /* connection is OK */
529 }
530 
531 
532 /********************************
533  * 3) protocol-oriented functions
534  ********************************/
535 
536 
537 /* This function creates all UNIX sockets bound to the protocol entry <proto>.
538  * It is intended to be used as the protocol's bind_all() function.
539  * The sockets will be registered but not added to any fd_set, in order not to
540  * loose them across the fork(). A call to uxst_enable_listeners() is needed
541  * to complete initialization.
542  *
543  * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
544  */
uxst_bind_listeners(struct protocol * proto,char * errmsg,int errlen)545 static int uxst_bind_listeners(struct protocol *proto, char *errmsg, int errlen)
546 {
547 	struct listener *listener;
548 	int err = ERR_NONE;
549 
550 	list_for_each_entry(listener, &proto->listeners, proto_list) {
551 		err |= uxst_bind_listener(listener, errmsg, errlen);
552 		if (err & ERR_ABORT)
553 			break;
554 	}
555 	return err;
556 }
557 
558 
559 /* This function stops all listening UNIX sockets bound to the protocol
560  * <proto>. It does not detaches them from the protocol.
561  * It always returns ERR_NONE.
562  */
uxst_unbind_listeners(struct protocol * proto)563 static int uxst_unbind_listeners(struct protocol *proto)
564 {
565 	struct listener *listener;
566 
567 	list_for_each_entry(listener, &proto->listeners, proto_list)
568 		uxst_unbind_listener(listener);
569 	return ERR_NONE;
570 }
571 
572 /* parse the "mode" bind keyword */
bind_parse_mode(char ** args,int cur_arg,struct proxy * px,struct bind_conf * conf,char ** err)573 static int bind_parse_mode(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
574 {
575 	if (!*args[cur_arg + 1]) {
576 		memprintf(err, "'%s' : missing mode (octal integer expected)", args[cur_arg]);
577 		return ERR_ALERT | ERR_FATAL;
578 	}
579 
580 	conf->ux.mode = strtol(args[cur_arg + 1], NULL, 8);
581 	return 0;
582 }
583 
584 /* parse the "gid" bind keyword */
bind_parse_gid(char ** args,int cur_arg,struct proxy * px,struct bind_conf * conf,char ** err)585 static int bind_parse_gid(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
586 {
587 	if (!*args[cur_arg + 1]) {
588 		memprintf(err, "'%s' : missing value", args[cur_arg]);
589 		return ERR_ALERT | ERR_FATAL;
590 	}
591 
592 	conf->ux.gid = atol(args[cur_arg + 1]);
593 	return 0;
594 }
595 
596 /* parse the "group" bind keyword */
bind_parse_group(char ** args,int cur_arg,struct proxy * px,struct bind_conf * conf,char ** err)597 static int bind_parse_group(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
598 {
599 	struct group *group;
600 
601 	if (!*args[cur_arg + 1]) {
602 		memprintf(err, "'%s' : missing group name", args[cur_arg]);
603 		return ERR_ALERT | ERR_FATAL;
604 	}
605 
606 	group = getgrnam(args[cur_arg + 1]);
607 	if (!group) {
608 		memprintf(err, "'%s' : unknown group name '%s'", args[cur_arg], args[cur_arg + 1]);
609 		return ERR_ALERT | ERR_FATAL;
610 	}
611 
612 	conf->ux.gid = group->gr_gid;
613 	return 0;
614 }
615 
616 /* parse the "uid" bind keyword */
bind_parse_uid(char ** args,int cur_arg,struct proxy * px,struct bind_conf * conf,char ** err)617 static int bind_parse_uid(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
618 {
619 	if (!*args[cur_arg + 1]) {
620 		memprintf(err, "'%s' : missing value", args[cur_arg]);
621 		return ERR_ALERT | ERR_FATAL;
622 	}
623 
624 	conf->ux.uid = atol(args[cur_arg + 1]);
625 	return 0;
626 }
627 
628 /* parse the "user" bind keyword */
bind_parse_user(char ** args,int cur_arg,struct proxy * px,struct bind_conf * conf,char ** err)629 static int bind_parse_user(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
630 {
631 	struct passwd *user;
632 
633 	if (!*args[cur_arg + 1]) {
634 		memprintf(err, "'%s' : missing user name", args[cur_arg]);
635 		return ERR_ALERT | ERR_FATAL;
636 	}
637 
638 	user = getpwnam(args[cur_arg + 1]);
639 	if (!user) {
640 		memprintf(err, "'%s' : unknown user name '%s'", args[cur_arg], args[cur_arg + 1]);
641 		return ERR_ALERT | ERR_FATAL;
642 	}
643 
644 	conf->ux.uid = user->pw_uid;
645 	return 0;
646 }
647 
648 /* Note: must not be declared <const> as its list will be overwritten.
649  * Please take care of keeping this list alphabetically sorted, doing so helps
650  * all code contributors.
651  * Optional keywords are also declared with a NULL ->parse() function so that
652  * the config parser can report an appropriate error when a known keyword was
653  * not enabled.
654  */
655 static struct bind_kw_list bind_kws = { "UNIX", { }, {
656 	{ "gid",   bind_parse_gid,   1 },      /* set the socket's gid */
657 	{ "group", bind_parse_group, 1 },      /* set the socket's gid from the group name */
658 	{ "mode",  bind_parse_mode,  1 },      /* set the socket's mode (eg: 0644)*/
659 	{ "uid",   bind_parse_uid,   1 },      /* set the socket's uid */
660 	{ "user",  bind_parse_user,  1 },      /* set the socket's uid from the user name */
661 	{ NULL, NULL, 0 },
662 }};
663 
664 /********************************
665  * 4) high-level functions
666  ********************************/
667 
668 __attribute__((constructor))
__uxst_protocol_init(void)669 static void __uxst_protocol_init(void)
670 {
671 	protocol_register(&proto_unix);
672 	bind_register_keywords(&bind_kws);
673 }
674 
675 
676 /*
677  * Local variables:
678  *  c-indent-level: 8
679  *  c-basic-offset: 8
680  * End:
681  */
682