56
/* find group_mask for selected gropus. The function returns 1 if OK or nothing to do,
57
* 0 if case of unresolved groupname.
58
* WARING: the function destroys the list (strtok), so it can only be used once.
62
auth_resolve_groups(struct userlist *l, char *groups)
66
unsigned int g, group_mask = 0;
68
if (!groups || !*groups)
71
while ((group = strtok(group?NULL:groups," "))) {
72
for (g = 0; g < l->grpcnt; g++)
73
if (!strcmp(l->groups[g], group))
77
Alert("No such group '%s' in userlist '%s'.\n",
82
group_mask |= (1 << g);
89
parse_auth_cond(const char **args, const char *file, int linenum, struct proxy *proxy)
91
struct req_acl_rule *req_acl;
94
req_acl = (struct req_acl_rule*)calloc(1, sizeof(struct req_acl_rule));
96
Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
101
goto req_error_parsing;
102
} else if (!strcmp(args[0], "allow")) {
103
req_acl->action = PR_REQ_ACL_ACT_ALLOW;
105
} else if (!strcmp(args[0], "deny")) {
106
req_acl->action = PR_REQ_ACL_ACT_DENY;
108
} else if (!strcmp(args[0], "auth")) {
109
req_acl->action = PR_REQ_ACL_ACT_HTTP_AUTH;
112
while(*args[cur_arg]) {
113
if (!strcmp(args[cur_arg], "realm")) {
114
req_acl->http_auth.realm = strdup(args[cur_arg + 1]);
122
Alert("parsing [%s:%d]: %s '%s', expects 'allow', 'deny', 'auth'.\n",
123
file, linenum, *args[1]?"unknown parameter":"missing keyword in", args[*args[1]?1:0]);
127
if (strcmp(args[cur_arg], "if") == 0 || strcmp(args[cur_arg], "unless") == 0) {
128
struct acl_cond *cond;
130
if ((cond = build_acl_cond(file, linenum, proxy, args+cur_arg)) == NULL) {
131
Alert("parsing [%s:%d] : error detected while parsing an 'http-request %s' condition.\n",
132
file, linenum, args[0]);
135
req_acl->cond = cond;
137
else if (*args[cur_arg]) {
138
Alert("parsing [%s:%d]: 'http-request %s' expects 'realm' for 'auth' or"
139
" either 'if' or 'unless' followed by a condition but found '%s'.\n",
140
file, linenum, args[0], args[cur_arg]);
58
int check_group(struct userlist *ul, char *name)
60
struct auth_groups *ag;
62
for (ag = ul->groups; ag; ag = ag->next)
63
if (strcmp(name, ag->name) == 0)
167
for (i = 0; i < tul->grpcnt; i++)
168
free(tul->groups[i]);
176
req_acl_free(struct list *r) {
177
struct req_acl_rule *tr, *pr;
179
list_for_each_entry_safe(pr, tr, r, list) {
181
if (pr->action == PR_REQ_ACL_ACT_HTTP_AUTH)
182
free(pr->http_auth.realm);
111
int userlist_postinit()
113
struct userlist *curuserlist = NULL;
115
/* Resolve usernames and groupnames. */
116
for (curuserlist = userlist; curuserlist; curuserlist = curuserlist->next) {
117
struct auth_groups *ag;
118
struct auth_users *curuser;
119
struct auth_groups_list *grl;
121
for (curuser = curuserlist->users; curuser; curuser = curuser->next) {
123
struct auth_groups_list *groups = NULL;
125
if (!curuser->u.groups_names)
128
while ((group = strtok(group?NULL:curuser->u.groups_names, ","))) {
129
for (ag = curuserlist->groups; ag; ag = ag->next) {
130
if (!strcmp(ag->name, group))
135
Alert("userlist '%s': no such group '%s' specified in user '%s'\n",
136
curuserlist->name, group, curuser->user);
138
return ERR_ALERT | ERR_FATAL;
141
/* Add this group at the group userlist. */
142
grl = calloc(1, sizeof(*grl));
144
Alert("userlist '%s': no more memory when trying to allocate the user groups.\n",
147
return ERR_ALERT | ERR_FATAL;
155
free(curuser->u.groups);
156
curuser->u.groups = groups;
159
for (ag = curuserlist->groups; ag; ag = ag->next) {
165
while ((user = strtok(user?NULL:ag->groupusers, ","))) {
166
for (curuser = curuserlist->users; curuser; curuser = curuser->next) {
167
if (!strcmp(curuser->user, user))
172
Alert("userlist '%s': no such user '%s' specified in group '%s'\n",
173
curuserlist->name, user, ag->name);
174
return ERR_ALERT | ERR_FATAL;
177
/* Add this group at the group userlist. */
178
grl = calloc(1, sizeof(*grl));
180
Alert("userlist '%s': no more memory when trying to allocate the user groups.\n",
182
return ERR_ALERT | ERR_FATAL;
186
grl->next = curuser->u.groups;
187
curuser->u.groups = grl;
190
free(ag->groupusers);
191
ag->groupusers = NULL;
195
for (ag = curuserlist->groups; ag; ag = ag->next) {
196
struct auth_groups_list *agl;
198
fprintf(stderr, "group %s, id %p, users:", ag->name, ag);
199
for (curuser = curuserlist->users; curuser; curuser = curuser->next) {
200
for (agl = curuser->u.groups; agl; agl = agl->next) {
201
if (agl->group == ag)
202
fprintf(stderr, " %s", curuser->user);
205
fprintf(stderr, "\n");
189
214
* Authenticate and authorize user; return 1 if OK, 0 if case of error.
192
check_user(struct userlist *ul, unsigned int group_mask, const char *user, const char *pass)
217
check_user(struct userlist *ul, const char *user, const char *pass)
195
220
struct auth_users *u;
198
223
#ifdef DEBUG_AUTH
199
fprintf(stderr, "req: userlist=%s, user=%s, pass=%s, group_mask=%u\n",
200
ul->name, user, pass, group_mask);
224
fprintf(stderr, "req: userlist=%s, user=%s, pass=%s, group=%s\n",
225
ul->name, user, pass, group);
203
228
for (u = ul->users; u; u = u->next)
210
235
#ifdef DEBUG_AUTH
211
fprintf(stderr, "cfg: user=%s, pass=%s, group_mask=%u, flags=%X",
212
u->user, u->pass, u->group_mask, u->flags);
236
fprintf(stderr, "cfg: user=%s, pass=%s, flags=%X, groups=",
237
u->user, u->pass, u->flags);
238
for (agl = u->u.groups; agl; agl = agl->next)
239
fprintf(stderr, " %s", agl->group->name);
216
* if user matches but group does not,
217
* it makes no sens to check passwords
219
if (group_mask && !(group_mask & u->u.group_mask))
222
242
if (!(u->flags & AU_O_INSECURE)) {
223
243
#ifdef CONFIG_HAP_CRYPT
224
244
ep = crypt(pass, u->pass);
242
acl_match_auth(struct acl_test *test, struct acl_pattern *pattern)
262
pat_match_auth(struct sample *smp, struct pattern_expr *expr, int fill)
245
struct userlist *ul = test->ctx.a[0];
246
char *user = test->ctx.a[1];
247
char *pass = test->ctx.a[2];
248
unsigned int group_mask;
251
group_mask = pattern->val.group_mask;
255
if (check_user(ul, group_mask, user, pass))
264
struct userlist *ul = smp->ctx.a[0];
265
struct pattern_list *lst;
266
struct auth_users *u;
267
struct auth_groups_list *agl;
268
struct pattern *pattern;
270
/* Check if the userlist is present in the context data. */
274
/* Browse the userlist for searching user. */
275
for (u = ul->users; u; u = u->next) {
276
if (strcmp(smp->data.str.str, u->user) == 0)
282
/* Browse each pattern. */
283
list_for_each_entry(lst, &expr->patterns, list) {
286
/* Browse each group for searching group name that match the pattern. */
287
for (agl = u->u.groups; agl; agl = agl->next) {
288
if (strcmp(agl->group->name, pattern->ptr.str) == 0)