2 * ITKACL control library.
4 * (C) 2004-2013 Steinar H. Gunderson
16 struct itkacl_config {
20 #define CONFIG_FILENAME "/etc/itkacl.conf"
22 static int itkacl_read_config(const char * const filename,
23 struct itkacl_config *config,
24 char *errmsg, size_t errmsg_size)
29 strcpy(config->nszone, "");
31 fp = fopen(CONFIG_FILENAME, "r");
34 snprintf(errmsg, errmsg_size, "%s: %s",
35 CONFIG_FILENAME, strerror(errno));
40 char line[256], arg[256], *ptr;
42 if (fgets(line, sizeof(line), fp) == NULL) {
47 /* Remove trailing newlines and then comments. */
48 ptr = strchr(line, '\n');
52 ptr = strchr(line, '\r');
56 ptr = strchr(line, '#');
60 /* Remove trailing whitespace, if any. */
61 ptr = line + strlen(line) - 1;
62 while (ptr >= line && isspace(*ptr))
65 /* Skip lines that now ended up blank. */
69 if (sscanf(line, "zone %255s", arg) == 1) {
70 strcpy(config->nszone, arg);
75 snprintf(errmsg, errmsg_size, "%s: Could not parse line %d",
76 CONFIG_FILENAME, lineno);
81 if (strlen(config->nszone) == 0) {
83 snprintf(errmsg, errmsg_size, "%s: Missing 'zone' directive",
93 int itkacl_check(const char * const realm, const char * const user,
94 char *errmsg, size_t errmsg_size)
96 struct itkacl_config config;
102 struct ub_result* result;
104 if (itkacl_read_config(CONFIG_FILENAME, &config, errmsg, errmsg_size) != 0) {
108 if (realm[0] != '/') {
110 snprintf(errmsg, errmsg_size, "Invalid realm '%s' (missing leading /)",
114 if (strlen(user) > 64) {
116 snprintf(errmsg, errmsg_size, "Invalid user '%s' (above 64 characters)",
120 if (strlen(realm) > 64) {
122 snprintf(errmsg, errmsg_size, "Invalid realm '%s' (above 64 characters)",
127 /* check that the user name is valid */
130 /* only allow [a-z0-9-] */
131 if (!((*ptr >= 'a' && *ptr <= 'z') ||
132 (*ptr >= '0' && *ptr <= '9') ||
135 snprintf(errmsg, errmsg_size, "Invalid realm '%s' (illegal characters)",
143 /* traverse the realm entry by entry from the root,
144 * creating a DNS zone name as we go */
145 strcpy(nszone, config.nszone);
148 /* copy all characters to next / or end of string */
154 while (*ptr && *ptr != '/') {
155 /* only allow [a-z0-9-] */
156 if (!((*ptr >= 'a' && *ptr <= 'z') ||
157 (*ptr >= '0' && *ptr <= '9') ||
160 snprintf(errmsg, errmsg_size, "Invalid realm '%s' (illegal characters)",
165 this_part[i++] = *ptr++;
169 strcpy(temp, nszone);
170 snprintf(nszone, 256, "%s.%s", this_part, temp);
173 /* finally, prepend the username */
174 strcpy(temp, nszone);
175 sprintf(nszone, "%s.%s", user, temp);
177 /* Create the DNS resolver context. */
178 ctx = ub_ctx_create();
181 snprintf(errmsg, errmsg_size, "Host name lookup failure: Could not create DNS context");
185 ret = ub_ctx_resolvconf(ctx, "/etc/resolv.conf");
188 snprintf(errmsg, errmsg_size,
189 "Host name lookup failure: Could not read /etc/resolv.conf "
190 "(resolver error: %s) (system error: %s)",
191 ub_strerror(ret), strerror(errno));
196 ret = ub_ctx_hosts(ctx, "/etc/hosts");
199 snprintf(errmsg, errmsg_size,
200 "Host name lookup failure: Could not read /etc/hosts "
201 "(resolver error: %s) (system error: %s)",
202 ub_strerror(ret), strerror(errno));
207 /* Do the actual DNS lookup (TYPE A, CLASS IN). */
208 ret = ub_resolve(ctx, nszone, 1, 1, &result);
211 snprintf(errmsg, errmsg_size, "Host name lookup failure: %s",
217 nxdomain = result->nxdomain;
219 ub_resolve_free(result);