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