-static void append_username(char *p, const char *username,
- const char *defdomain)
-{
- for (strcpy(p, username); *p; p++)
- if (*p == '\'' || *p == '"' || *p == '\\' ||
- (int)(unsigned char)*p < ' ')
- *p=' '; /* No funny business */
- if (strchr(username, '@') == 0 && defdomain && *defdomain)
- strcat(strcpy(p, "@"), defdomain);
-}
-
-/* siefca@pld.org.pl */
-static struct var_data *get_variable (const char *begin, size_t len,
- struct var_data *vdt)
-{
-struct var_data *vdp;
-
- if (!begin || !vdt) /* should never happend */
- {
- err("authmysql: critical error while "
- "parsing substitution variable");
- return NULL;
- }
- if (len < 1)
- {
- err("authmysql: unknown empty substitution "
- "variable - aborting");
- return NULL;
- }
- if (len > MAX_SUBSTITUTION_LEN)
- {
- err("authmysql: variable name too long "
- "while parsing substitution. "
- "name begins with "
- SV_BEGIN_MARK
- "%.*s...", MAX_SUBSTITUTION_LEN, begin);
- return NULL;
- }
-
- for (vdp=vdt; vdp->name; vdp++)
- if (vdp->size == len+1 &&
- !strncmp(begin, vdp->name, len))
- {
- if (!vdp->value)
- vdp->value = "";
- if (!vdp->value_length) /* length cache */
- vdp->value_length = strlen (vdp->value);
- return vdp;
- }
-
- err("authmysql: unknown substitution variable "
- SV_BEGIN_MARK
- "%.*s"
- SV_END_MARK
- , (int)len, begin);
-
- return NULL;
-}
-
-/* siefca@pld.org.pl */
-static int ParsePlugin_counter (const char *p, size_t length, void *vp)
-{
- if (!p || !vp || length < 0)
- {
- err("authmysql: bad arguments while counting "
- "query string");
- return -1;
- }
-
- *((size_t *)vp) += length;
-
- return 0;
-}
-
-/* siefca@pld.org.pl */
-static int ParsePlugin_builder (const char *p, size_t length, void *vp)
-{
-char **strptr = (char **) vp;
-
- if (!p || !vp || length < 0)
- {
- err("authmysql: bad arguments while building "
- "query string");
- return -1;
- }
-
- if (!length) return 0;
- memcpy ((void *) *strptr, (void *) p, length);
- *strptr += length;
-
- return 0;
-}
-
-/* siefca@pld.org.pl */
-static int parse_core (const char *source, struct var_data *vdt,
- parsefunc outfn, void *result)
-{
-size_t v_size = 0,
- t_size = 0;
-const char *p, *q, *e,
- *v_begin, *v_end,
- *t_begin, *t_end;
-struct var_data *v_ptr;
-
- if (!source)
- source = "";
- if (!result)
- {
- err("authmysql: no memory allocated for result "
- "while parser core was invoked");
- return -1;
- }
- if (!vdt)
- {
- err("authmysql: no substitution table found "
- "while parser core was invoked");
- return -1;
- }
-
- q = source;
- while ( (p=strstr(q, SV_BEGIN_MARK)) )
- {
- e = strstr (p, SV_END_MARK);
- if (!e)
- {
- err("authmysql: syntax error in "
- "substitution "
- "- no closing symbol found! "
- "bad variable begins with:"
- "%.*s...", MAX_SUBSTITUTION_LEN, p);
- return -1;
- }
-
- /*
- **
- ** __________sometext$(variable_name)_________
- ** | | | |
- ** t_begin' t_end' `v_begin `v_end
- **
- */
-
- v_begin = p+SV_BEGIN_LEN; /* variable field ptr */
- v_end = e-SV_END_LEN; /* variable field last character */
- v_size = v_end-v_begin+1;/* variable field length */
-
- t_begin = q; /* text field ptr */
- t_end = p-1; /* text field last character */
- t_size = t_end-t_begin+1;/* text field length */
-
- /* work on text */
- if ( (outfn (t_begin, t_size, result)) == -1 )
- return -1;
-
- /* work on variable */
- v_ptr = get_variable (v_begin, v_size, vdt);
- if (!v_ptr) return -1;
-
- if ( (outfn (v_ptr->value, v_ptr->value_length, result)) == -1 )
- return -1;
-
- q = e + 1;
- }
-
- /* work on last part of text if any */
- if (*q != '\0')
- if ( (outfn (q, strlen(q), result)) == -1 )
- return -1;
-
- return 0;
-}
-
-/* siefca@pld.org.pl */
-static char *parse_string (const char *source, struct var_data *vdt)
-{
-struct var_data *vdp = NULL;
-char *output_buf = NULL,
- *pass_buf = NULL;
-size_t buf_size = 2;
-
- if (source == NULL || *source == '\0' ||
- vdt == NULL || vdt[0].name == NULL)
- {
- err("authmysql: source clause is empty "
- "- this is critical error");
- return NULL;
- }
-
- /* zero var_data length cache - important! */
- for (vdp=vdt; vdp->name; vdp++)
- vdp->value_length = 0;
-
-
- /* phase 1 - count and validate string */
- if ( (parse_core (source, vdt, &ParsePlugin_counter, &buf_size)) != 0)
- return NULL;
-
- /* phase 2 - allocate memory */
- output_buf = malloc (buf_size);
- if (!output_buf)
- {
- perror ("malloc");
- return NULL;
- }
- pass_buf = output_buf;
-
- /* phase 3 - build the output string */
- if ( (parse_core (source, vdt, &ParsePlugin_builder, &pass_buf)) != 0)
- {
- free (output_buf);
- return NULL;
- }
- *pass_buf = '\0';
-
- return output_buf;
-}
-
-/* siefca@pld.org.pl */
-static const char *get_localpart (const char *username)
-{
-size_t lbuf = 0;
-const char *l_end, *p;
-char *q;
-static char localpart_buf[130];
-
- if (!username || *username == '\0') return NULL;
-
- p = strchr(username,'@');
- if (p)
- {
- if ((p-username) > 128)
- return NULL;
- l_end = p;
- }
- else
- {
- if ((lbuf = strlen(username)) > 128)
- return NULL;
- l_end = username + lbuf;
- }
-
- p=username;
- q=localpart_buf;
-
- while (*p && p != l_end)
- if (*p == '\"' || *p == '\\' ||
- *p == '\'' || (int)(unsigned char)*p < ' ')
- p++;
- else
- *q++ = *p++;
-
- *q = '\0';
- return localpart_buf;
-}
-
-/* siefca@pld.org.pl */
-static const char *get_domain (const char *username, const char *defdomain)
-{
-static char domain_buf[260];
-const char *p;
-char *q;
-
- if (!username || *username == '\0') return NULL;
- p = strchr(username,'@');
-
- if (!p || *(p+1) == '\0')
- {
- if (defdomain && *defdomain)
- return defdomain;
- else
- return NULL;
- }
-
- p++;
- if ((strlen(p)) > 256)
- return NULL;
-
- q = domain_buf;
- while (*p)
- if (*p == '\"' || *p == '\\' ||
- *p == '\'' || (int)(unsigned char)*p < ' ')
- p++;
- else
- *q++ = *p++;
-
- *q = '\0';
- return domain_buf;
-}
-
-/* siefca@pld.org.pl */
-
-static const char *validateMyPassword (const char *password)
-{
-static char pass_buf[2][540]; /* Use two buffers, see parse_chpass_clause */
-static int next_pass=0;
-const char *p;
-char *q, *endq;
-
- if (!password || *password == '\0' || (strlen(password)) > 256)
- return NULL;
-
- next_pass= 1-next_pass;
-
- p = password;
- q = pass_buf[next_pass];
- endq = q + sizeof pass_buf[next_pass];
-
- while (*p && q < endq)
- {
- if (*p == '\"' || *p == '\\' || *p == '\'')
- *q++ = '\\';
- *q++ = *p++;
- }
-
- if (q >= endq)
- return NULL;
-
- *q = '\0';
- return pass_buf[next_pass];
-}
-
-/* siefca@pld.org.pl */
-static char *parse_select_clause (const char *clause, const char *username,
- const char *defdomain,
- const char *service)
-{
-static struct var_data vd[]={
- {"local_part", NULL, sizeof("local_part"), 0},
- {"domain", NULL, sizeof("domain"), 0},
- {"service", NULL, sizeof("service"), 0},
- {NULL, NULL, 0, 0}};
-
- if (clause == NULL || *clause == '\0' ||
- !username || *username == '\0')
- return NULL;
-
- vd[0].value = get_localpart (username);
- vd[1].value = get_domain (username, defdomain);
- if (!vd[0].value || !vd[1].value)
- return NULL;
- vd[2].value = service;
-
- return (parse_string (clause, vd));
-}
-
-/* siefca@pld.org.pl */
-static char *parse_chpass_clause (const char *clause, const char *username,
- const char *defdomain, const char *newpass,
- const char *newpass_crypt)
-{
-static struct var_data vd[]={
- {"local_part", NULL, sizeof("local_part"), 0},
- {"domain", NULL, sizeof("domain"), 0},
- {"newpass", NULL, sizeof("newpass"), 0},
- {"newpass_crypt", NULL, sizeof("newpass_crypt"), 0},
- {NULL, NULL, 0, 0}};
-
- if (clause == NULL || *clause == '\0' ||
- !username || *username == '\0' ||
- !newpass || *newpass == '\0' ||
- !newpass_crypt || *newpass_crypt == '\0') return NULL;
-
- vd[0].value = get_localpart (username);
- vd[1].value = get_domain (username, defdomain);
- vd[2].value = validateMyPassword (newpass);
- vd[3].value = validateMyPassword (newpass_crypt);
-
- if (!vd[0].value || !vd[1].value ||
- !vd[2].value || !vd[3].value) return NULL;
-
- return (parse_string (clause, vd));
-}
-