2 * itkacl control library, version 0.1
4 * (C) 2004-2009 Steinar H. Gunderson
14 #define BASE_ZONE "itkacl.samfundet.no"
16 int itkacl_check(const char * const realm, const char * const user,
17 char *errmsg, size_t errmsg_size)
19 struct hostent he, *he_ptr;
22 char nszone[256] = BASE_ZONE;
23 char temp[256], ns_temp[1024];
25 if (realm[0] != '/') {
27 snprintf(errmsg, errmsg_size, "Invalid realm '%s' (missing leading /)",
31 if (strlen(user) > 64) {
33 snprintf(errmsg, errmsg_size, "Invalid user '%s' (above 64 characters)",
37 if (strlen(realm) > 64) {
39 snprintf(errmsg, errmsg_size, "Invalid realm '%s' (above 64 characters)",
44 /* check that the user name is valid */
47 /* only allow [a-z0-9-] */
48 if (!((*ptr >= 'a' && *ptr <= 'z') ||
49 (*ptr >= '0' && *ptr <= '9') ||
52 snprintf(errmsg, errmsg_size, "Invalid realm '%s' (illegal characters)",
60 /* traverse the realm entry by entry from the root,
61 * creating a DNS zone name as we go */
64 /* copy all characters to next / or end of string */
70 while (*ptr && *ptr != '/') {
71 /* only allow [a-z0-9-] */
72 if (!((*ptr >= 'a' && *ptr <= 'z') ||
73 (*ptr >= '0' && *ptr <= '9') ||
76 snprintf(errmsg, errmsg_size, "Invalid realm '%s' (illegal characters)",
81 this_part[i++] = *ptr++;
86 snprintf(nszone, 256, "%s.%s", this_part, temp);
89 /* finally, prepend the username */
91 sprintf(nszone, "%s.%s", user, temp);
93 ret = gethostbyname_r(nszone, &he, ns_temp, 1024, &he_ptr, &host_errno);
96 * The man page for gethostbyname_r() specifies ret != 0 on failure, but
97 * that seemingly does not include HOST_NOT_FOUND failure.
100 // Not found => no access, but no error either.
101 if (host_errno == HOST_NOT_FOUND) {
105 switch (host_errno) {
107 snprintf(errmsg, errmsg_size, "Host name lookup failure");
110 snprintf(errmsg, errmsg_size, "Unknown server error");
113 snprintf(errmsg, errmsg_size, "No address associated with name");
116 snprintf(errmsg, errmsg_size, "Unknown DNS error %d", host_errno);
121 // The lookup succeeded, so we're good.