blob: b1fb1e2804416f3b39e3b7cfdf0d95b8e35100ea [file] [log] [blame]
Willy Tarreau13180342020-08-28 11:54:59 +02001/*
2 * Configuration parsing for UNIX sockets (bind and server keywords)
3 *
4 * Copyright 2000-2020 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>
Willy Tarreau13180342020-08-28 11:54:59 +020015#include <grp.h>
16#include <pwd.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <time.h>
21
22#include <sys/param.h>
23#include <sys/socket.h>
24#include <sys/types.h>
25#include <sys/un.h>
26
27#include <netinet/tcp.h>
28#include <netinet/in.h>
29
30#include <haproxy/api.h>
31#include <haproxy/arg.h>
32#include <haproxy/errors.h>
33#include <haproxy/list.h>
34#include <haproxy/listener.h>
35#include <haproxy/namespace.h>
36#include <haproxy/proxy-t.h>
37#include <haproxy/server.h>
38#include <haproxy/tools.h>
39
40/* parse the "mode" bind keyword */
41static int bind_parse_mode(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
42{
43 char *endptr;
44
Willy Tarreau6e459d72020-09-03 07:09:09 +020045 conf->settings.ux.mode = strtol(args[cur_arg + 1], &endptr, 8);
Willy Tarreau13180342020-08-28 11:54:59 +020046
47 if (!*args[cur_arg + 1] || *endptr) {
48 memprintf(err, "'%s' : missing or invalid mode '%s' (octal integer expected)", args[cur_arg], args[cur_arg + 1]);
49 return ERR_ALERT | ERR_FATAL;
50 }
51
52 return 0;
53}
54
55/* parse the "gid" bind keyword */
56static int bind_parse_gid(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
57{
58 if (!*args[cur_arg + 1]) {
59 memprintf(err, "'%s' : missing value", args[cur_arg]);
60 return ERR_ALERT | ERR_FATAL;
61 }
62
Willy Tarreau6e459d72020-09-03 07:09:09 +020063 conf->settings.ux.gid = atol(args[cur_arg + 1]);
Willy Tarreau13180342020-08-28 11:54:59 +020064 return 0;
65}
66
67/* parse the "group" bind keyword */
68static int bind_parse_group(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
69{
70 struct group *group;
71
72 if (!*args[cur_arg + 1]) {
73 memprintf(err, "'%s' : missing group name", args[cur_arg]);
74 return ERR_ALERT | ERR_FATAL;
75 }
76
77 group = getgrnam(args[cur_arg + 1]);
78 if (!group) {
79 memprintf(err, "'%s' : unknown group name '%s'", args[cur_arg], args[cur_arg + 1]);
80 return ERR_ALERT | ERR_FATAL;
81 }
82
Willy Tarreau6e459d72020-09-03 07:09:09 +020083 conf->settings.ux.gid = group->gr_gid;
Willy Tarreau13180342020-08-28 11:54:59 +020084 return 0;
85}
86
87/* parse the "uid" bind keyword */
88static int bind_parse_uid(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
89{
90 if (!*args[cur_arg + 1]) {
91 memprintf(err, "'%s' : missing value", args[cur_arg]);
92 return ERR_ALERT | ERR_FATAL;
93 }
94
Willy Tarreau6e459d72020-09-03 07:09:09 +020095 conf->settings.ux.uid = atol(args[cur_arg + 1]);
Willy Tarreau13180342020-08-28 11:54:59 +020096 return 0;
97}
98
99/* parse the "user" bind keyword */
100static int bind_parse_user(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
101{
102 struct passwd *user;
103
104 if (!*args[cur_arg + 1]) {
105 memprintf(err, "'%s' : missing user name", args[cur_arg]);
106 return ERR_ALERT | ERR_FATAL;
107 }
108
109 user = getpwnam(args[cur_arg + 1]);
110 if (!user) {
111 memprintf(err, "'%s' : unknown user name '%s'", args[cur_arg], args[cur_arg + 1]);
112 return ERR_ALERT | ERR_FATAL;
113 }
114
Willy Tarreau6e459d72020-09-03 07:09:09 +0200115 conf->settings.ux.uid = user->pw_uid;
Willy Tarreau13180342020-08-28 11:54:59 +0200116 return 0;
117}
118
119/* Note: must not be declared <const> as its list will be overwritten.
120 * Please take care of keeping this list alphabetically sorted, doing so helps
121 * all code contributors.
122 * Optional keywords are also declared with a NULL ->parse() function so that
123 * the config parser can report an appropriate error when a known keyword was
124 * not enabled.
125 */
126static struct bind_kw_list bind_kws = { "UNIX", { }, {
127 { "gid", bind_parse_gid, 1 }, /* set the socket's gid */
128 { "group", bind_parse_group, 1 }, /* set the socket's gid from the group name */
129 { "mode", bind_parse_mode, 1 }, /* set the socket's mode (eg: 0644)*/
130 { "uid", bind_parse_uid, 1 }, /* set the socket's uid */
131 { "user", bind_parse_user, 1 }, /* set the socket's uid from the user name */
132 { NULL, NULL, 0 },
133}};
134
135INITCALL1(STG_REGISTER, bind_register_keywords, &bind_kws);