+++ /dev/null
-/*
- * itkacl control library, version 0.1
- *
- * (C) 2004-2009 Steinar H. Gunderson
- * GPL, v2.
- */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <netdb.h>
-
-#define BASE_ZONE "itkacl.samfundet.no"
-
-int itkacl_check(const char * const realm, const char * const user,
- char *errmsg, size_t errmsg_size)
-{
- struct hostent he, *he_ptr;
- int ret, host_errno;
- const char *ptr;
- char nszone[256] = BASE_ZONE;
- char temp[256], ns_temp[1024];
-
- if (realm[0] != '/') {
- if (errmsg)
- snprintf(errmsg, errmsg_size, "Invalid realm '%s' (missing leading /)",
- realm);
- return -1;
- }
- if (strlen(user) > 64) {
- if (errmsg)
- snprintf(errmsg, errmsg_size, "Invalid user '%s' (above 64 characters)",
- user);
- return -1;
- }
- if (strlen(realm) > 64) {
- if (errmsg)
- snprintf(errmsg, errmsg_size, "Invalid realm '%s' (above 64 characters)",
- realm);
- return -1;
- }
-
- /* check that the user name is valid */
- ptr = user;
- while (*ptr) {
- /* only allow [a-z0-9-] */
- if (!((*ptr >= 'a' && *ptr <= 'z') ||
- (*ptr >= '0' && *ptr <= '9') ||
- *ptr == '-')) {
- if (errmsg) {
- snprintf(errmsg, errmsg_size, "Invalid realm '%s' (illegal characters)",
- realm);
- }
- return -1;
- }
- ++ptr;
- }
-
- /* traverse the realm entry by entry from the root,
- * creating a DNS zone name as we go */
- ptr = realm;
- while (*ptr) {
- /* copy all characters to next / or end of string */
- char this_part[64];
- int i = 0;
- this_part[0] = 0;
-
- ++ptr;
- while (*ptr && *ptr != '/') {
- /* only allow [a-z0-9-] */
- if (!((*ptr >= 'a' && *ptr <= 'z') ||
- (*ptr >= '0' && *ptr <= '9') ||
- *ptr == '-')) {
- if (errmsg) {
- snprintf(errmsg, errmsg_size, "Invalid realm '%s' (illegal characters)",
- realm);
- }
- return -1;
- }
- this_part[i++] = *ptr++;
- }
- this_part[i] = 0;
-
- strcpy(temp, nszone);
- snprintf(nszone, 256, "%s.%s", this_part, temp);
- }
-
- /* finally, prepend the username */
- strcpy(temp, nszone);
- sprintf(nszone, "%s.%s", user, temp);
-
- ret = gethostbyname_r(nszone, &he, ns_temp, 1024, &he_ptr, &host_errno);
-
- /*
- * The man page for gethostbyname_r() specifies ret != 0 on failure, but
- * that seemingly does not include HOST_NOT_FOUND failure.
- */
- if (he_ptr == NULL) {
- // Not found => no access, but no error either.
- if (host_errno == HOST_NOT_FOUND) {
- return 1;
- }
-
- switch (host_errno) {
- case TRY_AGAIN:
- snprintf(errmsg, errmsg_size, "Host name lookup failure");
- break;
- case NO_RECOVERY:
- snprintf(errmsg, errmsg_size, "Unknown server error");
- break;
- case NO_ADDRESS:
- snprintf(errmsg, errmsg_size, "No address associated with name");
- break;
- default:
- snprintf(errmsg, errmsg_size, "Unknown DNS error %d", host_errno);
- }
- return -1;
- }
-
- // The lookup succeeded, so we're good.
- return 0;
-}