Пример #1
0
void free_lr_predict( lr_predict *lrp)
{
  if (lrp != NULL) {
    if (lrp->b   != NULL) free_dyv( lrp->b);
    AM_FREE( lrp, lr_predict);
  }
  return;
}
Пример #2
0
void free_dyv(dyv *d)
{
  d -> dyv_code = 7777;

  am_free_realnums(d->farr,d->array_size);
  AM_FREE(d,dyv);

  Dyvs_freed += 1;
}
Пример #3
0
void free_lr_train( lr_train *lrt)
{
  if (lrt != NULL) {
    if (lrt->lrs != NULL)      free_lr_state( lrt->lrs);
    if (lrt->y != NULL)        free_dyv( lrt->y);
    if (lrt->opts != NULL)     free_lr_options( lrt->opts);
    AM_FREE(lrt, lr_train);
  }
  return;
}
Пример #4
0
void free_minteg(minteg *mit)
{
  int i;
  for ( i = 0 ; i < mit->integ_array_size ; i++ )
  {
    if ( mit->integ_array[i] != NULL )
      free_integ(mit->integ_array[i]);
  }

  AM_FREE_ARRAY(mit->integ_array,integ_ptr,mit->integ_array_size);
  AM_FREE(mit,minteg);
}
Пример #5
0
void free_lr_state( lr_state *lrs)
{
  if (lrs != NULL) {
    if (lrs->b != NULL) free_dyv( lrs->b);
    if (lrs->n != NULL) free_dyv( lrs->n);
    if (lrs->u != NULL) free_dyv( lrs->u);
    if (lrs->w != NULL) free_dyv( lrs->w);
    if (lrs->z != NULL) free_dyv( lrs->z);
    AM_FREE( lrs, lr_state);
  }
  return;
}
Пример #6
0
void free_lr_statearr( lr_statearr *lrsarr)
{
  int i;
  if (lrsarr != NULL) {
    if (lrsarr->arr != NULL) {
      for (i=0; i < lrsarr->size; ++i) {
        if (lrsarr->arr[i] != NULL) free_lr_state( lrsarr->arr[i]);
      }
      AM_FREE_ARRAY( lrsarr->arr, lr_state *, lrsarr->size);
    }
    AM_FREE( lrsarr, lr_statearr);
  }
}
Пример #7
0
void free_string_array(string_array *sar)
{
  int i;
  sar -> string_array_code = 7777;

  for ( i = 0 ; i < sar->size ; i++ )
    if ( sar->sarr[i] != NULL )
      am_free_string(sar->sarr[i]);

  AM_FREE_ARRAY(sar->sarr,char_ptr,sar->sarr_size);
  AM_FREE(sar,string_array);

  String_Arrays_freed += 1;
}
Пример #8
0
void am_config_free(am_config_t **cp) {
    if (cp != NULL && *cp != NULL) {
        am_config_t *c = *cp;

        if (ISVALID(c->pass) && c->pass_sz > 0) {
            am_secure_zero_memory(c->pass, c->pass_sz);
        }
        if (ISVALID(c->cert_key_pass) && c->cert_key_pass_sz > 0) {
            am_secure_zero_memory(c->cert_key_pass, c->cert_key_pass_sz);
        }

        AM_FREE(c->token, c->config, c->pdp_dir, c->realm, c->user, c->pass,
                c->key, c->debug_file, c->audit_file, c->cert_key_file,
                c->cert_key_pass, c->cert_file, c->cert_ca_file, c->ciphers,
                c->tls_opts, c->valid_default_url, c->agenturi, c->cookie_name,
                c->notif_url, c->userid_param, c->userid_param_type, c->access_denied_url,
                c->fqdn_default, c->pdp_lb_cookie, c->cookie_prefix, c->logout_redirect_url,
                c->password_replay_key, c->url_redirect_param, c->client_ip_header,
                c->client_hostname_header, c->url_check_regex, c->multi_attr_separator,
                c->pdp_sess_mode, c->pdp_sess_value, c->pdp_uri_prefix, c->logout_url_regex,
                c->audit_file_remote, c->audit_file_disposition, c->unauthenticated_user);

        AM_CONF_FREE(c->naming_url_sz, c->naming_url);
        AM_CONF_FREE(c->hostmap_sz, c->hostmap);
        AM_CONF_MAP_FREE(c->login_url_sz, c->login_url);
        AM_CONF_MAP_FREE(c->profile_attr_map_sz, c->profile_attr_map);
        AM_CONF_MAP_FREE(c->session_attr_map_sz, c->session_attr_map);
        AM_CONF_MAP_FREE(c->response_attr_map_sz, c->response_attr_map);
        AM_CONF_MAP_FREE(c->fqdn_map_sz, c->fqdn_map);
        AM_CONF_MAP_FREE(c->cookie_reset_map_sz, c->cookie_reset_map);
        AM_CONF_MAP_FREE(c->not_enforced_map_sz, c->not_enforced_map);
        AM_CONF_MAP_FREE(c->not_enforced_ext_map_sz, c->not_enforced_ext_map);
        AM_CONF_MAP_FREE(c->not_enforced_ip_map_sz, c->not_enforced_ip_map);
        AM_CONF_MAP_FREE(c->cdsso_login_map_sz, c->cdsso_login_map);
        AM_CONF_MAP_FREE(c->cdsso_cookie_domain_map_sz, c->cdsso_cookie_domain_map);
        AM_CONF_MAP_FREE(c->logout_cookie_reset_map_sz, c->logout_cookie_reset_map);
        AM_CONF_MAP_FREE(c->logout_map_sz, c->logout_map);
        AM_CONF_MAP_FREE(c->openam_logout_map_sz, c->openam_logout_map);
        AM_CONF_MAP_FREE(c->cond_login_url_sz, c->cond_login_url);
        AM_CONF_MAP_FREE(c->json_url_map_sz, c->json_url_map);

        free(c);
        c = NULL;
    }
}
Пример #9
0
static void am_url_validator_tick(void *arg) {
    static const char *thisfunc = "am_url_validator_tick():";
    int i;
    struct url_validator_worker_data *list;

    list = (struct url_validator_worker_data *) calloc(1,
            sizeof (struct url_validator_worker_data) * AM_MAX_INSTANCES);
    if (list == NULL || get_valid_url_all(list) != AM_SUCCESS) {
        am_free(list);
        return;
    }

    for (i = 0; i < AM_MAX_INSTANCES; i++) {
        /* schedule a new url_validator_worker only when instance is registered and validator is not running already */
        if (list[i].instance_id > 0 && !list[i].running) {
            struct url_validator_worker_data *worker_data =
                    (struct url_validator_worker_data *) malloc(sizeof (struct url_validator_worker_data));
            if (worker_data != NULL) {
                worker_data->instance_id = list[i].instance_id;
                worker_data->url_index = list[i].url_index;
                worker_data->last = list[i].last;
                worker_data->config_path = strdup(list[i].config_path);
                if (am_worker_dispatch(url_validator_worker, worker_data) != AM_SUCCESS) {
                    AM_LOG_WARNING(list[i].instance_id, "%s failed to dispatch url validator worker", thisfunc);
                    AM_FREE(worker_data->config_path, worker_data);
                }
            } else {
                AM_LOG_ERROR(list[i].instance_id, "%s memory allocation error", thisfunc);
            }
        } else if (list[i].instance_id > 0 && list[i].running) {
            AM_LOG_WARNING(list[i].instance_id, "%s url validator worker already running", thisfunc);
        }
        am_free(list[i].config_path);
    }
    free(list);
}
Пример #10
0
int am_net_close(am_net_t *n) {
    if (n == NULL) {
        return AM_EINVAL;
    }

#ifdef _WIN32   
    WaitForSingleObject(n->pw, INFINITE);
    CloseHandle(n->pw);
    DeleteCriticalSection(&n->lk);
#else
    pthread_join(n->pw, NULL);
    pthread_mutex_destroy(&n->lk);
#endif

    /* close ssl/socket */
    am_net_diconnect(n);

    /* shut down connected/disconnected events */
    close_event(n->ce);
    close_exit_event(n->de);

    /* shut down response timeout handler */
    am_close_timer_event(n->tm);
    n->tm = NULL;

    if (n->ra != NULL) {
        freeaddrinfo(n->ra);
    }
    n->ra = NULL;

    AM_FREE(n->hs, n->hp, n->req_headers);
    n->hs = NULL;
    n->hp = NULL;
    n->req_headers = NULL;
    return AM_SUCCESS;
}
Пример #11
0
void list_iis_sites(int argc, char **argv) {
    IAppHostWritableAdminManager *admin_manager = NULL;
    IAppHostElement *he = NULL, *ce = NULL;
    IAppHostElementCollection *hec = NULL;
    DWORD num;
    UINT i;
    BSTR bstr_config_path = SysAllocString(AM_IIS_APPHOST);
    BSTR bstr_sites = SysAllocString(AM_IIS_SITES);
    BSTR bstr_name = SysAllocString(AM_IIS_ENAME);
    BSTR bstr_id = SysAllocString(AM_IIS_EID);
    VARIANT value;
    HRESULT hresult = S_OK;
    char *name, *id;

    fprintf(stdout, "\nIIS Server Site configuration:\n");

    do {
        hresult = CoInitializeEx(NULL, COINIT_MULTITHREADED);
        if (FAILED(hresult)) {
            break;
        }
        hresult = CoCreateInstance(&CLSID_AppHostWritableAdminManager, NULL,
                CLSCTX_INPROC_SERVER, &IID_IAppHostWritableAdminManager, (LPVOID*) & admin_manager);
        if (FAILED(hresult)) {
            break;
        }
        hresult = IAppHostWritableAdminManager_GetAdminSection(admin_manager, bstr_sites, bstr_config_path, &he);
        if (FAILED(hresult) || he == NULL) {
            break;
        }
        hresult = IAppHostElement_get_Collection(he, &hec);
        if (FAILED(hresult)) {
            break;
        }
        hresult = IAppHostElementCollection_get_Count(hec, &num);
        if (FAILED(hresult)) {
            break;
        }

        fprintf(stdout, "\nNumber of Sites: %d\n\n", num);

        for (i = 0; i < num; i++) {
            VARIANT index;
            index.vt = VT_UINT;
            index.uintVal = i;
            hresult = IAppHostElementCollection_get_Item(hec, index, &ce);
            if (SUCCEEDED(hresult)) {
                name = get_property_value_byname(ce, &value, &bstr_name, VT_BSTR);
                id = get_property_value_byname(ce, &value, &bstr_id, VT_UI4);
                if (name != NULL && id != NULL) {
                    char *p;
                    for (p = name; *p != '\0'; ++p) {
                        *p = toupper(*p);
                    }
                    fprintf(stdout, "id: %s\tname: \"%s\"\n", id, name);
                }
                AM_FREE(name, id);
                name = NULL;
                id = NULL;
            }
            if (ce != NULL) IAppHostElement_Release(ce);
        }

    } while (FALSE);

    if (he != NULL) IAppHostElement_Release(he);
    if (hec != NULL) IAppHostElementCollection_Release(hec);
    if (admin_manager != NULL) IAppHostWritableAdminManager_Release(admin_manager);
    SysFreeString(bstr_config_path);
    SysFreeString(bstr_sites);
    SysFreeString(bstr_name);
    SysFreeString(bstr_id);
    CoUninitialize();
}
Пример #12
0
void free_integ(integ *it)
{
  free_dyv(it->integral);
  AM_FREE(it,integ);
}
Пример #13
0
void free_lr_options( lr_options *opts)
{
  if (opts != NULL) AM_FREE( opts, lr_options);
  return;
}
Пример #14
0
static int send_login_request(am_net_t *conn, char **token, const char *user,
        const char *password) {
    static const char *thisfunc = "send_login_request():";
    size_t post_sz, post_data_sz, xml_esc_sz;
    char *post = NULL, *post_data = NULL;
    int status = AM_ERROR;
    struct request_data *req_data;
    char *user_xml_esc = NULL, *pass_xml_esc = NULL;

    if (conn == NULL || conn->data == NULL || token == NULL ||
            !ISVALID(*token) || !ISVALID(user)) return AM_EINVAL;

    /* do xml-escape */
    xml_esc_sz = strlen(user);
    user_xml_esc = malloc(xml_esc_sz * 6 + 1); /* worst case */
    if (user_xml_esc != NULL) {
        memcpy(user_xml_esc, user, xml_esc_sz);
        xml_entity_escape(user_xml_esc, xml_esc_sz);
    } else {
        return AM_ENOMEM;
    }

    if (ISVALID(password)) {
        xml_esc_sz = strlen(password);
        pass_xml_esc = malloc(xml_esc_sz * 6 + 1); /* worst case */
        if (pass_xml_esc != NULL) {
            memcpy(pass_xml_esc, password, xml_esc_sz);
            xml_entity_escape(pass_xml_esc, xml_esc_sz);
        } else {
            free(user_xml_esc);
            return AM_ENOMEM;
        }
    }

    req_data = (struct request_data *) conn->data;

    post_data_sz = am_asprintf(&post_data,
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
            "<RequestSet vers=\"1.0\" svcid=\"auth\" reqid=\"0\">"
            "<Request><![CDATA["
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?><AuthContext version=\"1.0\">"
            "<Request authIdentifier=\"%s\"><Login>"
            "<IndexTypeNamePair indexType=\"moduleInstance\"><IndexName>Application</IndexName>"
            "</IndexTypeNamePair></Login></Request></AuthContext>]]>"
            "</Request>"
            "<Request><![CDATA["
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?><AuthContext version=\"1.0\">"
            "<Request authIdentifier=\"%s\"><SubmitRequirements>"
            "<Callbacks length=\"2\"><NameCallback><Prompt>Enter application name.</Prompt>"
            "<Value>%s</Value>"
            "</NameCallback><PasswordCallback echoPassword=\"true\"><Prompt>Enter secret string.</Prompt>"
            "<Value>%s</Value>"
            "</PasswordCallback></Callbacks>"
            "</SubmitRequirements></Request></AuthContext>]]>"
            "</Request>"
            "</RequestSet>",
            *token, *token, user_xml_esc, NOTNULL(pass_xml_esc));

    AM_FREE(user_xml_esc, pass_xml_esc);
    if (post_data == NULL) {
        return AM_ENOMEM;
    }

    post_sz = am_asprintf(&post, "POST %s/authservice HTTP/1.1\r\n"
            "Host: %s:%d\r\n"
            "User-Agent: "MODINFO"\r\n"
            "Accept: text/xml\r\n"
            "Connection: Keep-Alive\r\n"
            "Content-Type: text/xml; charset=UTF-8\r\n"
            "%s"
            "Content-Length: %d\r\n\r\n"
            "%s", conn->uv.path, conn->uv.host, conn->uv.port,
            NOTNULL(conn->req_headers), post_data_sz, post_data);
    if (post == NULL) {
        free(post_data);
        return AM_ENOMEM;
    }

#ifdef DEBUG
    AM_LOG_DEBUG(conn->instance_id, "%s sending %d bytes:\n%s", thisfunc, post_sz, post);
#else
    AM_LOG_DEBUG(conn->instance_id, "%s sending %d bytes", thisfunc, post_sz);
#endif
    if (conn->log != NULL) {
#ifdef DEBUG
        conn->log("%s sending %d bytes:\n%s", thisfunc, post_sz, post);
#else
        conn->log("%s sending %d bytes", thisfunc, post_sz);
#endif                
    }

    status = am_net_write(conn, post, post_sz);
    free(post_data);
    free(post);
    free(*token); /* delete pre-login/authcontext token */
    *token = NULL;

    if (status == AM_SUCCESS) {
        wait_for_event(req_data->event, 0);
    }

    AM_LOG_DEBUG(conn->instance_id, "%s authenticate response status code: %d\n%s",
            thisfunc, conn->http_status, LOGEMPTY(req_data->data));
    if (conn->log != NULL) {
        conn->log("%s authenticate response status code: %d\n%s", thisfunc,
                conn->http_status, LOGEMPTY(req_data->data));
    }

    status = AM_ERROR;

    if (ISVALID(req_data->data)) {
        char *begin = strstr(req_data->data, "LoginStatus status=\"success\" ssoToken=\"");
        if (begin != NULL) {
            char *end = strstr(begin + 39, "\"");
            if (end != NULL) {
                *token = strndup(begin + 39, end - begin - 39);
                if (ISVALID(*token)) status = AM_SUCCESS;
            }
        }
    }

    AM_LOG_DEBUG(conn->instance_id, "%s status: %s", thisfunc, am_strerror(status));
    am_free(req_data->data);
    req_data->data = NULL;
    return status;
}
Пример #15
0
static int send_attribute_request(am_net_t *conn, char **token, char **pxml, size_t *pxsz,
        const char *user, const char *realm) {
    static const char *thisfunc = "send_attribute_request():";
    size_t post_sz;
    char *post = NULL;
    int status = AM_ERROR;
    struct request_data *req_data;
    char *token_enc;
    char *realm_enc = url_encode(realm);
    char *user_enc = url_encode(user);

    if (conn == NULL || conn->data == NULL || token == NULL ||
            !ISVALID(*token) || !ISVALID(realm) || !ISVALID(user)) return AM_EINVAL;

    token_enc = url_encode(*token);
    req_data = (struct request_data *) conn->data;

    post_sz = am_asprintf(&post, "GET %s/identity/xml/read?"
            "name=%s&attributes_names=realm&attributes_values_realm=%s&attributes_names=objecttype"
            "&attributes_values_objecttype=Agent&admin=%s HTTP/1.1\r\n"
            "Host: %s:%d\r\n"
            "User-Agent: "MODINFO"\r\n"
            "Accept: text/xml\r\n"
            "%s"
            "Connection: Keep-Alive\r\n\r\n",
            conn->uv.path,
            user_enc, realm_enc, token_enc,
            conn->uv.host, conn->uv.port, NOTNULL(conn->req_headers));
    if (post == NULL) {
        AM_FREE(realm_enc, user_enc, token_enc);
        return AM_ENOMEM;
    }

#ifdef DEBUG
    AM_LOG_DEBUG(conn->instance_id, "%s sending %d bytes:\n%s", thisfunc, post_sz, post);
#else
    AM_LOG_DEBUG(conn->instance_id, "%s sending %d bytes", thisfunc, post_sz);
#endif
    if (conn->log != NULL) {
#ifdef DEBUG
        conn->log("%s sending %d bytes:\n%s", thisfunc, post_sz, post);
#else
        conn->log("%s sending %d bytes", thisfunc, post_sz);
#endif                
    }

    status = am_net_write(conn, post, post_sz);
    free(post);

    if (status == AM_SUCCESS) {
        wait_for_event(req_data->event, 0);
    }

    AM_LOG_DEBUG(conn->instance_id, "%s response status code: %d\n%s",
            thisfunc, conn->http_status, LOGEMPTY(req_data->data));
    if (conn->log != NULL) {
        conn->log("%s response status code: %d\n%s", thisfunc,
                conn->http_status, LOGEMPTY(req_data->data));
    }

    if (status == AM_SUCCESS && conn->http_status == 200 && ISVALID(req_data->data)) {
        if (stristr(req_data->data, "exception") != NULL) {
            status = AM_ERROR;
        } else {
            if (pxml != NULL) {
                *pxml = malloc(req_data->data_size + 1);
                if (*pxml != NULL) {
                    memcpy(*pxml, req_data->data, req_data->data_size);
                    (*pxml)[req_data->data_size] = 0;
                } else {
                    status = AM_ENOMEM;
                }
            }
            if (pxsz != NULL) *pxsz = req_data->data_size;
        }
    }

    AM_LOG_DEBUG(conn->instance_id, "%s status: %s", thisfunc, am_strerror(status));
    AM_FREE(req_data->data, realm_enc, user_enc, token_enc);
    req_data->data = NULL;
    return status;
}
Пример #16
0
static int send_session_request(am_net_t *conn, char **token, const char *notifyurl,
        struct am_namevalue **session_list) {
    static const char *thisfunc = "send_session_request():";
    size_t post_sz, post_data_sz, token_sz;
    char *post = NULL, *post_data = NULL, *token_in = NULL, *token_b64;
    int status = AM_ERROR;
    struct request_data *req_data;

    if (conn == NULL || conn->data == NULL || token == NULL ||
            !ISVALID(*token)) return AM_EINVAL;

    token_sz = am_asprintf(&token_in, "token:%s", *token);
    token_b64 = base64_encode(token_in, &token_sz);

    req_data = (struct request_data *) conn->data;

    post_data_sz = am_asprintf(&post_data,
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
            "<RequestSet vers=\"1.0\" svcid=\"Session\" reqid=\"0\">"
            "<Request><![CDATA["
            "<SessionRequest vers=\"1.0\" reqid=\"1\" requester=\"%s\">"
            "<GetSession reset=\"true\">"
            "<SessionID>%s</SessionID>"
            "</GetSession>"
            "</SessionRequest>]]>"
            "</Request>"
            "<Request><![CDATA["
            "<SessionRequest vers=\"1.0\" reqid=\"2\" requester=\"%s\">"
            "<AddSessionListener>"
            "<URL>%s</URL>"
            "<SessionID>%s</SessionID>"
            "</AddSessionListener>"
            "</SessionRequest>]]>"
            "</Request>"
            "</RequestSet>",
            NOTNULL(token_b64), *token, NOTNULL(token_b64), notifyurl, *token);
    if (post_data == NULL) {
        AM_FREE(token_b64, token_in);
        return AM_ENOMEM;
    }

    post_sz = am_asprintf(&post, "POST %s/sessionservice HTTP/1.1\r\n"
            "Host: %s:%d\r\n"
            "User-Agent: "MODINFO"\r\n"
            "Accept: text/xml\r\n"
            "Connection: Keep-Alive\r\n"
            "Content-Type: text/xml; charset=UTF-8\r\n"
            "%s"
            "Content-Length: %d\r\n\r\n"
            "%s", conn->uv.path, conn->uv.host, conn->uv.port,
            NOTNULL(conn->req_headers), post_data_sz, post_data);
    if (post == NULL) {
        AM_FREE(post_data, token_b64, token_in);
        return AM_ENOMEM;
    }

#ifdef DEBUG
    AM_LOG_DEBUG(conn->instance_id, "%s sending %d bytes:\n%s", thisfunc, post_sz, post);
#else
    AM_LOG_DEBUG(conn->instance_id, "%s sending %d bytes", thisfunc, post_sz);
#endif
    if (conn->log != NULL) {
#ifdef DEBUG
        conn->log("%s sending %d bytes:\n%s", thisfunc, post_sz, post);
#else
        conn->log("%s sending %d bytes", thisfunc, post_sz);
#endif                
    }

    status = am_net_write(conn, post, post_sz);
    AM_FREE(post, post_data, token_b64, token_in);

    if (status == AM_SUCCESS) {
        wait_for_event(req_data->event, 0);
    }

    AM_LOG_DEBUG(conn->instance_id, "%s response status code: %d\n%s",
            thisfunc, conn->http_status, LOGEMPTY(req_data->data));
    if (conn->log != NULL) {
        conn->log("%s response status code: %d\n%s", thisfunc,
                conn->http_status, LOGEMPTY(req_data->data));
    }

    if (status == AM_SUCCESS && conn->http_status == 200 && ISVALID(req_data->data)) {
        if (session_list != NULL) {
            *session_list = am_parse_session_xml(conn->instance_id, req_data->data, req_data->data_size);
        }
    }

    AM_LOG_DEBUG(conn->instance_id, "%s status: %s", thisfunc, am_strerror(status));
    am_free(req_data->data);
    req_data->data = NULL;
    return status;
}
Пример #17
0
int am_agent_session_request(unsigned long instance_id, const char *openam,
        const char *token, const char *user_token, const char *notif_url) {
    char *post = NULL, *post_data = NULL;
    am_net_t n;
    size_t post_sz;
    int status = AM_ERROR;

    struct request_data ld;

    if (!ISVALID(token) || !ISVALID(user_token) ||
            !ISVALID(openam) || !ISVALID(notif_url)) return AM_EINVAL;

    memset(&ld, 0, sizeof(struct request_data));

    memset(&n, 0, sizeof(am_net_t));
    n.instance_id = instance_id;
    n.timeout = AM_NET_CONNECT_TIMEOUT;
    n.url = openam;

    ld.event = create_event();
    if (ld.event == NULL) return AM_ENOMEM;

    n.data = &ld;
    n.on_connected = on_connected_cb;
    n.on_close = on_close_cb;
    n.on_data = on_agent_request_data_cb;
    n.on_complete = on_complete_cb;

    if (am_net_connect(&n) == 0) {
        char *token_in = NULL;
        size_t token_sz = am_asprintf(&token_in, "token:%s", token);
        char *token_b64 = base64_encode(token_in, &token_sz);

        size_t post_data_sz = am_asprintf(&post_data,
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                "<RequestSet vers=\"1.0\" svcid=\"Session\" reqid=\"0\">"
                "<Request><![CDATA["
                "<SessionRequest vers=\"1.0\" reqid=\"1\" requester=\"%s\">"
                "<GetSession reset=\"true\">"
                "<SessionID>%s</SessionID>"
                "</GetSession>"
                "</SessionRequest>]]>"
                "</Request>"
                "<Request><![CDATA["
                "<SessionRequest vers=\"1.0\" reqid=\"2\" requester=\"%s\">"
                "<AddSessionListener>"
                "<URL>%s</URL>"
                "<SessionID>%s</SessionID>"
                "</AddSessionListener>"
                "</SessionRequest>]]>"
                "</Request>"
                "</RequestSet>",
                NOTNULL(token_b64), user_token, NOTNULL(token_b64), notif_url, user_token);

        AM_FREE(token_in, token_b64);

        if (post_data != NULL) {
            post_sz = am_asprintf(&post, "POST %s/sessionservice HTTP/1.1\r\n"
                    "Host: %s:%d\r\n"
                    "User-Agent: "MODINFO"\r\n"
                    "Accept: text/xml\r\n"
                    "Connection: close\r\n"
                    "Content-Type: text/xml; charset=UTF-8\r\n"
                    "Content-Length: %d\r\n\r\n"
                    "%s", n.uv.path, n.uv.host, n.uv.port, post_data_sz, post_data);
            if (post != NULL) {
                status = am_net_write(&n, post, post_sz);
                free(post);
                post = NULL;
            }
            free(post_data);
            post_data = NULL;
        }

    }

    if (status == AM_SUCCESS) {
        wait_for_event(ld.event, 0);
    } else {
        am_net_diconnect(&n);
    }

    am_net_close(&n);
    close_event(ld.event);

    am_free(ld.data);
    return status;
}
Пример #18
0
static char *get_site_name(const char *sid) {
    IAppHostWritableAdminManager *admin_manager = NULL;
    IAppHostElement *he = NULL, *ce = NULL;
    IAppHostElementCollection *hec = NULL;
    DWORD num;
    UINT i;
    BSTR bstr_config_path = SysAllocString(AM_IIS_APPHOST);
    BSTR bstr_sites = SysAllocString(AM_IIS_SITES);
    BSTR bstr_name = SysAllocString(AM_IIS_ENAME);
    BSTR bstr_id = SysAllocString(AM_IIS_EID);
    VARIANT value;
    HRESULT hresult = S_OK;
    char *name, *id, *ret = NULL;

    do {
        hresult = CoInitializeEx(NULL, COINIT_MULTITHREADED);
        if (FAILED(hresult)) {
            break;
        }
        hresult = CoCreateInstance(&CLSID_AppHostWritableAdminManager, NULL,
                CLSCTX_INPROC_SERVER, &IID_IAppHostWritableAdminManager, (LPVOID*) & admin_manager);
        if (FAILED(hresult)) {
            break;
        }
        hresult = IAppHostWritableAdminManager_GetAdminSection(admin_manager, bstr_sites, bstr_config_path, &he);
        if (FAILED(hresult) || he == NULL) {
            break;
        }
        hresult = IAppHostElement_get_Collection(he, &hec);
        if (FAILED(hresult)) {
            break;
        }
        hresult = IAppHostElementCollection_get_Count(hec, &num);
        if (FAILED(hresult)) {
            break;
        }

        for (i = 0; i < num; i++) {
            VARIANT index;
            index.vt = VT_UINT;
            index.uintVal = i;
            hresult = IAppHostElementCollection_get_Item(hec, index, &ce);
            if (SUCCEEDED(hresult)) {
                name = get_property_value_byname(ce, &value, &bstr_name, VT_BSTR);
                id = get_property_value_byname(ce, &value, &bstr_id, VT_UI4);
                if (strcmp(id, sid) == 0) {
                    if (name != NULL && id != NULL) {
                        char cpath[2048];
                        char *p;
                        for (p = name; *p != '\0'; ++p) {
                            *p = toupper(*p);
                        }
                        sprintf_s(cpath, sizeof (cpath), "MACHINE/WEBROOT/APPHOST/%s", name);
                        ret = strdup(cpath);
                        i = num;
                    }
                }
                AM_FREE(name, id);
                name = NULL;
                id = NULL;
            }
            if (ce != NULL) IAppHostElement_Release(ce);
        }

    } while (FALSE);

    if (he != NULL) IAppHostElement_Release(he);
    if (hec != NULL) IAppHostElementCollection_Release(hec);
    if (admin_manager != NULL) IAppHostWritableAdminManager_Release(admin_manager);
    SysFreeString(bstr_config_path);
    SysFreeString(bstr_sites);
    SysFreeString(bstr_name);
    SysFreeString(bstr_id);
    CoUninitialize();
    return ret;
}
Пример #19
0
static void *parse_value(const char *line, const char *name,
        int value_type, const char *mvsep) {
    char set = 0, map = 0, *token = NULL, *key = NULL, *key_val = NULL;
    void *value = NULL;
    size_t token_sz, name_sz = strlen(name);
    char *orig, *tn, *tmp = strdup(line);
    size_t line_sz;
    int *value_int;

    if (tmp == NULL) {
        return NULL;
    }
    orig = tmp;
    line_sz = strlen(tmp);

    tn = strchr(tmp, '=');
    if (tn != NULL && ((size_t) (tn - tmp)) < line_sz) {

        token = tn + 1; /* move past the '=' */
        *tn = 0; /* terminate token key and reset the pointer */
        tn = tmp;

        trim(tn, ' ');
        trim(token, ' ');

        /* check if the key is what we're looking for */
        if (strncmp(tn, name, name_sz) == 0) {
            map = 0;
            if ((token_sz = strlen(tn)) != name_sz) {
                /* get map value key */
                key = strstr(tn, "[");
                if (key != NULL) {
                    key++; /* move past the '[' */
                    if (*key != ']') {
                        tn[token_sz - 1] = 0;
                        key_val = strdup(key);
                        if (key_val != NULL) {
                            map = 1;
                        }
                    }
                }
            }
            set = 1;
        }

        if (set != 1 || !ISVALID(token)) {
            AM_FREE(key_val, orig);
            return NULL;
        }

        switch (value_type) {
            case CONF_NUMBER:
                value = malloc(sizeof (int));
                if (value == NULL) {
                    break;
                }
                value_int = (int *) value;
                if (strcasecmp(token, "on") == 0 || strcasecmp(token, "true") == 0 || strcasecmp(token, "local") == 0) {
                    *value_int = 1;
                    break;
                }
                if (strcasecmp(token, "off") == 0 || strcasecmp(token, "false") == 0 || strcasecmp(token, "centralized") == 0) {
                    *value_int = 0;
                    break;
                }
                *value_int = strtol(token, NULL, AM_BASE_TEN);
                break;
            case CONF_DEBUG_LEVEL:
                value = malloc(sizeof (int));
                if (value == NULL) {
                    break;
                }
                value_int = (int *) value;
                if (strncasecmp(token, "all", 3) == 0 || strcasecmp(token, "debug") == 0) {
                    *value_int = AM_LOG_LEVEL_DEBUG;
                    break;
                }
                if (strcasecmp(token, "error") == 0) {
                    *value_int = AM_LOG_LEVEL_ERROR;
                    break;
                }
                if (strcasecmp(token, "info") == 0) {
                    *value_int = AM_LOG_LEVEL_INFO;
                    break;
                }
                if (strcasecmp(token, "message") == 0) {
                    *value_int = AM_LOG_LEVEL_WARNING;
                    break;
                }
                if (strcasecmp(token, "warning") == 0) {
                    *value_int = AM_LOG_LEVEL_WARNING;
                    break;
                }
                *value_int = AM_LOG_LEVEL_NONE;
                break;
            case CONF_ATTR_MODE:
                value = malloc(sizeof (int));
                if (value == NULL) {
                    break;
                }
                value_int = (int *) value;
                if (strcasecmp(token, "HTTP_HEADER") == 0) {
                    *value_int = AM_SET_ATTRS_AS_HEADER;
                    break;
                }
                if (strcasecmp(token, "HTTP_COOKIE") == 0) {
                    *value_int = AM_SET_ATTRS_AS_COOKIE;
                    break;
                }
                *value_int = AM_SET_ATTRS_NONE;
                break;
            case CONF_AUDIT_LEVEL:
                value = calloc(1, sizeof (int));
                if (value == NULL) {
                    break;
                }
                value_int = (int *) value;
                if (strcasecmp(token, "LOG_ALLOW") == 0) {
                    *value_int |= AM_LOG_LEVEL_AUDIT_ALLOW;
                    break;
                }
                if (strcasecmp(token, "LOG_BOTH") == 0) {
                    *value_int |= AM_LOG_LEVEL_AUDIT_ALLOW;
                    *value_int |= AM_LOG_LEVEL_AUDIT_DENY;
                    break;
                }
                if (strcasecmp(token, "LOG_DENY") == 0) {
                    *value_int |= AM_LOG_LEVEL_AUDIT_DENY;
                    break;
                }
                break;
            case CONF_STRING:
            {
                if (map == 1) {
                    size_t val_sz = strlen(token);
                    size_t key_sz = strlen(key_val);
                    /* value is stored as:
                     * key\0value\0
                     */
                    value = malloc(val_sz + key_sz + 2);
                    if (value == NULL) {
                        break;
                    }
                    memcpy(value, key_val, key_sz);
                    ((char *) value)[key_sz] = 0;
                    memcpy((char *) value + key_sz + 1, token, val_sz);
                    ((char *) value)[val_sz + key_sz + 1] = 0;
                    free(key_val);
                    key_val = NULL;
                    break;
                }
                value = strdup(token);
            }
                break;
            case CONF_STRING_LIST:
            {
                struct val_string_list *ret = NULL;
                char *sl_token = NULL, *o, *sl_tmp = strdup(token);
                char **vl = NULL;
                int i = 0, vl_sz = 0;
                if (sl_tmp == NULL) {
                    break;
                }
                o = sl_tmp;
                while ((sl_token = am_strsep(&sl_tmp, mvsep)) != NULL) {
                    trim(sl_token, ' ');
                    if (!sl_token || sl_token[0] == '\0') {
                        continue;
                    }
                    vl_sz++;
                }
                free(o);
                if (vl_sz == 0) {
                    break;
                }
                sl_tmp = strdup(token);
                if (sl_tmp == NULL) {
                    break;
                }
                o = sl_tmp;
                vl = malloc(sizeof (char *) * vl_sz);
                if (vl == NULL) {
                    free(sl_tmp);
                    break;
                }
                while ((sl_token = am_strsep(&sl_tmp, mvsep)) != NULL) {
                    trim(sl_token, ' ');
                    if (!sl_token || sl_token[0] == '\0') {
                        continue;
                    }
                    vl[i] = strdup(sl_token);
                    if (vl[i] == NULL) {
                        break;
                    }
                    i++;
                }
                free(o);

                ret = malloc(sizeof (struct val_string_list));
                if (ret == NULL) {
                    for (i = 0; i < vl_sz; i++) {
                        am_free(vl[i]);
                    }
                    free(vl);
                    break;
                }
                ret->size = vl_sz;
                ret->list = vl;
                value = ret;
            }
                break;
            case CONF_NUMBER_LIST:
            {
                struct val_number_list *ret = NULL;
                char *sl_token = NULL, *o, *sl_tmp = strdup(token);
                int *vl = NULL;
                int i = 0, vl_sz = 0;
                if (sl_tmp == NULL) {
                    break;
                }
                o = sl_tmp;
                while ((sl_token = am_strsep(&sl_tmp, mvsep)) != NULL) {
                    trim(sl_token, ' ');
                    if (!sl_token || sl_token[0] == '\0') {
                        continue;
                    }
                    vl_sz++;
                }
                free(o);
                if (vl_sz == 0) {
                    break;
                }
                sl_tmp = strdup(token);
                if (sl_tmp == NULL) {
                    break;
                }
                o = sl_tmp;
                vl = malloc(sizeof (int) * vl_sz);
                if (vl == NULL) {
                    free(sl_tmp);
                    break;
                }
                while ((sl_token = am_strsep(&sl_tmp, mvsep)) != NULL) {
                    trim(sl_token, ' ');
                    if (!sl_token || sl_token[0] == '\0') {
                        continue;
                    }
                    vl[i] = strtol(sl_token, NULL, AM_BASE_TEN);
                    i++;
                }
                free(o);

                ret = malloc(sizeof (struct val_number_list));
                if (ret == NULL) {
                    free(vl);
                    break;
                }
                ret->size = vl_sz;
                ret->list = vl;
                value = ret;
            }
                break;
        }
        am_free(key_val);
    }
    am_free(orig);
    return value;
}
Пример #20
0
int am_agent_policy_request(unsigned long instance_id, const char *openam,
        const char *token, const char *user_token, const char *req_url,
        const char *notif_url, const char *scope, const char *cip, const char *pattr,
        const char *server_id, struct am_ssl_options *info,
        struct am_namevalue **session_list,
        struct am_policy_result **policy_list) {

    static const char *thisfunc = "am_agent_policy_request():";
    char *post = NULL, *post_data = NULL;
    am_net_t n;
    size_t post_sz;
    int status = AM_ERROR;
    int session_status = AM_SUCCESS;
    struct request_data req_data;

    if (!ISVALID(token) || !ISVALID(user_token) || !ISVALID(notif_url) || !ISVALID(scope) ||
            !ISVALID(req_url) || !ISVALID(openam) || !ISVALID(cip)) {
        return AM_EINVAL;
    }

    memset(&req_data, 0, sizeof(struct request_data));
    memset(&n, 0, sizeof(am_net_t));
    n.instance_id = instance_id;
    n.timeout = AM_NET_CONNECT_TIMEOUT;
    n.url = openam;
    if (info != NULL) {
        memcpy(&n.ssl.info, info, sizeof(struct am_ssl_options));
    }

    if (ISVALID(server_id)) {
        am_asprintf(&n.req_headers, "Cookie: amlbcookie=%s\r\n", server_id);
    }

    req_data.event = create_event();
    if (req_data.event == NULL) {
        return AM_ENOMEM;
    }

    n.data = &req_data;
    n.on_connected = on_connected_cb;
    n.on_close = on_close_cb;
    n.on_data = on_agent_request_data_cb;
    n.on_complete = on_complete_cb;

    if (am_net_connect(&n) == 0) {
        char *token_in = NULL;
        size_t token_sz = am_asprintf(&token_in, "token:%s", token);
        char *token_b64 = base64_encode(token_in, &token_sz);

        size_t post_data_sz = am_asprintf(&post_data,
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                "<RequestSet vers=\"1.0\" svcid=\"Session\" reqid=\"0\">"
                "<Request><![CDATA["
                "<SessionRequest vers=\"1.0\" reqid=\"1\" requester=\"%s\">"
                "<GetSession reset=\"true\">" /* reset the idle timeout */
                "<SessionID>%s</SessionID>"
                "</GetSession>"
                "</SessionRequest>]]>"
                "</Request>"
                "<Request><![CDATA["
                "<SessionRequest vers=\"1.0\" reqid=\"2\" requester=\"%s\">"
                "<AddSessionListener>"
                "<URL>%s</URL>"
                "<SessionID>%s</SessionID>"
                "</AddSessionListener>"
                "</SessionRequest>]]>"
                "</Request>"
                "</RequestSet>",
                NOTNULL(token_b64), user_token, NOTNULL(token_b64), notif_url, user_token);

        AM_FREE(token_in, token_b64);

        if (post_data != NULL) {
            post_sz = am_asprintf(&post, "POST %s/sessionservice HTTP/1.1\r\n"
                    "Host: %s:%d\r\n"
                    "User-Agent: "MODINFO"\r\n"
                    "Accept: text/xml\r\n"
                    "Connection: Keep-Alive\r\n"
                    "Content-Type: text/xml; charset=UTF-8\r\n"
                    "%s"
                    "Content-Length: %d\r\n\r\n"
                    "%s", n.uv.path, n.uv.host, n.uv.port,
                    NOTNULL(n.req_headers), post_data_sz, post_data);
            if (post != NULL) {
                AM_LOG_DEBUG(instance_id, "%s sending request:\n%s", thisfunc, post);
                status = am_net_write(&n, post, post_sz);
                free(post);
                post = NULL;
            }
            free(post_data);
            post_data = NULL;
        }

        if (status == AM_SUCCESS) {
            wait_for_event(req_data.event, 0);
        }

        AM_LOG_DEBUG(instance_id, "%s response status code: %d", thisfunc, n.http_status);

        if (status == AM_SUCCESS && n.http_status == 200 && ISVALID(req_data.data)) {
            size_t req_url_sz = strlen(req_url);
            char *req_url_escaped = malloc(req_url_sz * 6 + 1); /* worst case */
            if (req_url_escaped != NULL) {
                memcpy(req_url_escaped, req_url, req_url_sz);
                xml_entity_escape(req_url_escaped, req_url_sz);
            }

            AM_LOG_DEBUG(instance_id, "%s response:\n%s", thisfunc, req_data.data);

            if (strstr(req_data.data, "<Exception>") != NULL && strstr(req_data.data, "Invalid session ID") != NULL) {
                session_status = AM_INVALID_SESSION;
            }
            if (strstr(req_data.data, "<Exception>") != NULL && strstr(req_data.data, "Application token passed in") != NULL) {
                session_status = AM_INVALID_AGENT_SESSION;
            }
            if (session_status == AM_SUCCESS && session_list != NULL) {
                *session_list = am_parse_session_xml(instance_id, req_data.data, req_data.data_size);
            }

            req_data.data_size = 0;
            free(req_data.data);
            req_data.data = NULL;

            /* TODO:
             * <AttributeValuePair><Attribute name=\"requestDnsName\"/><Value>%s</Value></AttributeValuePair>
             */
            post_data_sz = am_asprintf(&post_data,
                    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                    "<RequestSet vers=\"1.0\" svcid=\"Policy\" reqid=\"3\">"
                    "<Request><![CDATA[<PolicyService version=\"1.0\">"
                    "<PolicyRequest requestId=\"4\" appSSOToken=\"%s\">"
                    "<GetResourceResults userSSOToken=\"%s\" serviceName=\"iPlanetAMWebAgentService\" resourceName=\"%s\" resourceScope=\"%s\">"
                    "<EnvParameters><AttributeValuePair><Attribute name=\"requestIp\"/><Value>%s</Value></AttributeValuePair></EnvParameters>"
                    "<GetResponseDecisions>"
                    "%s"
                    "</GetResponseDecisions>"
                    "</GetResourceResults>"
                    "</PolicyRequest>"
                    "</PolicyService>]]>"
                    "</Request>"
                    "</RequestSet>",
                    token, user_token, NOTNULL(req_url_escaped), scope,
                    cip, NOTNULL(pattr));

            am_free(req_url_escaped);

            post_sz = am_asprintf(&post, "POST %s/policyservice HTTP/1.1\r\n"
                    "Host: %s:%d\r\n"
                    "User-Agent: "MODINFO"\r\n"
                    "Accept: text/xml\r\n"
                    "Content-Type: text/xml; charset=UTF-8\r\n"
                    "Content-Length: %d\r\n"
                    "%s"
                    "Connection: close\r\n\r\n"
                    "%s", n.uv.path, n.uv.host, n.uv.port,
                    post_data_sz, NOTNULL(n.req_headers), post_data);

            if (post != NULL) {
                AM_LOG_DEBUG(instance_id, "%s sending request:\n%s", thisfunc, post);
                status = am_net_write(&n, post, post_sz);
                free(post);
            }
        } else {
            status = n.error != AM_SUCCESS ? n.error : AM_ERROR;
        }
    }

    if (status == AM_SUCCESS) {
        wait_for_event(req_data.event, 0);
    } else {
        AM_LOG_DEBUG(instance_id, "%s disconnecting", thisfunc);
        am_net_diconnect(&n);
    }

    AM_LOG_DEBUG(instance_id, "%s response status code: %d", thisfunc, n.http_status);

    if (status == AM_SUCCESS && n.http_status == 200 && ISVALID(req_data.data)) {
        AM_LOG_DEBUG(instance_id, "%s response:\n%s", thisfunc, req_data.data);

        if (strstr(req_data.data, "<Exception>") != NULL) {
            if (strstr(req_data.data, "SSO token is invalid") != NULL) {
                session_status = AM_INVALID_SESSION;
            } else if (strstr(req_data.data, "Application sso token is invalid") != NULL) {
                session_status = AM_INVALID_AGENT_SESSION;
            }
        }

        if (session_status == AM_SUCCESS && policy_list != NULL) {
            *policy_list = am_parse_policy_xml(instance_id, req_data.data, req_data.data_size,
                    am_scope_to_num(scope));
        }
    }

    am_net_close(&n);
    close_event(req_data.event);

    am_free(req_data.data);
    return session_status != AM_SUCCESS ? session_status : status;
}
Пример #21
0
int disable_module(const char *siteid, const char *modconf) {
    IAppHostWritableAdminManager *admin_manager = NULL;
    HRESULT hresult = S_OK;
    int rv = 0;
    wchar_t *config_path_w = NULL;
    wchar_t *modconf_w = NULL;
    char *config_path;

    if (siteid == NULL || modconf == NULL) {
        fprintf(stderr, "Invalid arguments.\n");
        return rv;
    }

    config_path = get_site_name(siteid);
    if (config_path != NULL) {
        config_path_w = utf8_decode(config_path, NULL);
        free(config_path);
    }

    modconf_w = utf8_decode(modconf, NULL);

    do {
        if (config_path_w == NULL || modconf_w == NULL) {
            fprintf(stderr, "Failed to allocate memory.\n");
            break;
        }

        hresult = CoInitializeEx(NULL, COINIT_MULTITHREADED);
        if (FAILED(hresult)) {
            fprintf(stderr, "Failed to initialize COM.\n");
            break;
        }
        hresult = CoCreateInstance(&CLSID_AppHostWritableAdminManager, NULL,
                CLSCTX_INPROC_SERVER, &IID_IAppHostWritableAdminManager, (LPVOID*) & admin_manager);
        if (FAILED(hresult)) {
            fprintf(stderr, "Failed to create AppHostWritableAdminManager.\n");
            break;
        }
        hresult = IAppHostWritableAdminManager_put_CommitPath(admin_manager, config_path_w);
        if (FAILED(hresult)) {
            fprintf(stderr, "Failed to put commit path.\n");
            break;
        }

        if (!remove_from_modules(admin_manager, config_path_w, AM_IIS_MODULES, FALSE)) {
            fprintf(stderr, "Failed to remove entry from modules.\n");
            break;
        } else {
            if (!update_module_site_config(admin_manager, config_path_w, modconf_w, FALSE)) {
                fprintf(stderr, "Failed to add module configuration entry.\n");
            } else {
                rv = 1;
            }
        }

        hresult = IAppHostWritableAdminManager_CommitChanges(admin_manager);
        if (FAILED(hresult)) {
            break;
        }
    } while (FALSE);

    AM_FREE(modconf_w, config_path_w);

    if (admin_manager != NULL) IAppHostWritableAdminManager_Release(admin_manager);
    CoUninitialize();
    return rv;
}
Пример #22
0
void url_validator_worker(void *arg) {
    static const char *thisfunc = "url_validator_worker():";
    struct url_validator_worker_data *w = (struct url_validator_worker_data *) arg;
    am_net_options_t *net_options;
    int i, validate_status;
    am_config_t *conf = NULL;
    time_t current_ts;
    struct url_valid_table *e, *t;
    int current_index, current_ok, current_fail, default_ok, next_ok;
    char **url_list;
    int url_list_sz = 0;
    int ping_diff;

    set_valid_url_instance_running(w->instance_id, AM_TRUE);

    conf = am_get_config_file(w->instance_id, w->config_path);
    if (conf == NULL) {
        AM_LOG_WARNING(w->instance_id, "%s failed to get agent configuration (%s)",
                thisfunc, LOGEMPTY(w->config_path));
        set_valid_url_instance_running(w->instance_id, AM_FALSE);
        AM_FREE(w->config_path, w);
        return;
    }

    ping_diff = MAX(MIN_URL_VALIDATOR_TICK, conf->valid_ping);
    current_ts = time(NULL);
    /* this index corresponds to the naming.url multi-value index */
    current_index = w->url_index;

    if (conf->valid_level > 1 || conf->naming_url_sz < 2 || conf->naming_url_sz != conf->valid_default_url_sz ||
            (current_ts - w->last) < ping_diff) {
        /* a) validation is disabled; b) there is nothing to validate;
         * c) naming.url list and default.url list sizes do not match or
         * d) its not time yet to do any validation
         */
        am_config_free(&conf);
        set_valid_url_instance_running(w->instance_id, AM_FALSE);
        AM_FREE(w->config_path, w);
        return;
    }

    if (current_index < 0 || current_index >= conf->naming_url_sz) {
        AM_LOG_WARNING(w->instance_id,
                "%s invalid current index value, defaulting to %s", thisfunc, conf->naming_url[0]);
        set_valid_url_index(w->instance_id, 0);
        am_config_free(&conf);
        set_valid_url_instance_running(w->instance_id, AM_FALSE);
        AM_FREE(w->config_path, w);
        return;
    }

#define URL_LIST_FREE(l, s) do { \
        int k; \
        if (l == NULL) break; \
        for (k = 0; k < s; k++) { \
            am_free(l[k]); \
        }\
        free(l); \
    } while (0)

    net_options = calloc(1, sizeof (am_net_options_t));
    if (net_options == NULL) {
        AM_LOG_ERROR(w->instance_id, "%s memory allocation error", thisfunc);
        am_config_free(&conf);
        set_valid_url_instance_running(w->instance_id, AM_FALSE);
        AM_FREE(w->config_path, w);
        return;
    }

    url_list = (char **) calloc(1, conf->naming_url_sz * sizeof (char *));
    if (url_list == NULL) {
        AM_LOG_ERROR(w->instance_id, "%s memory allocation error", thisfunc);
        am_config_free(&conf);
        set_valid_url_instance_running(w->instance_id, AM_FALSE);
        AM_FREE(net_options, w->config_path, w);
        return;
    }
    url_list_sz = conf->naming_url_sz;

    for (i = 0; i < url_list_sz; i++) {
        /* default.url.set contains fail-over order;
         * will keep internal value list index-ordered 
         **/
        int j = conf->valid_default_url[i];
        url_list[i] = strdup(conf->naming_url[j]);
        if (url_list[i] == NULL) {
            URL_LIST_FREE(url_list, url_list_sz);
            am_config_free(&conf);
            set_valid_url_instance_running(w->instance_id, AM_FALSE);
            AM_FREE(net_options, w->config_path, w);
            return;
        }
    }

    am_net_options_create(conf, net_options, NULL);
    net_options->keepalive = AM_FALSE;
    net_options->local = net_options->cert_trust = AM_TRUE;
    net_options->net_timeout = 2; /* fixed for url validator; in sec */

    /* do the actual url validation */

    for (i = 0; i < url_list_sz; i++) {
        const char *url = url_list[i];
        int ok = 0, fail = 0, httpcode = 0;

        get_validation_table_entry(w->instance_id, i, &ok, &fail, NULL);

        AM_LOG_DEBUG(w->instance_id, "%s validating %s", thisfunc, url);

        if (conf->valid_level == 1) {
            /* simple HEAD request */
            validate_status = am_url_validate(w->instance_id, url, net_options, &httpcode);
        } else {
            /* full scale agent login-logout request */
            char *agent_token = NULL;
            validate_status = am_agent_login(w->instance_id, url, conf->user, conf->pass, conf->realm,
                    net_options, &agent_token, NULL, NULL, NULL);
            if (agent_token != NULL) {
                am_agent_logout(0, url, agent_token, net_options);
                free(agent_token);
                httpcode = 200;
            }
        }

        if (validate_status == AM_SUCCESS && httpcode != 0) {
            if (ok++ > conf->valid_ping_ok) {
                ok = conf->valid_ping_ok;
            }
            fail = 0;
        } else {
            if (fail++ > conf->valid_ping_miss) {
                fail = conf->valid_ping_miss;
            }
            ok = 0;
        }

        set_validation_table_entry(w->instance_id, i, ok, fail);
    }

    /* map stored index value to our ordered list index */
    for (i = 0; i < conf->valid_default_url_sz; i++) {
        if (current_index == conf->valid_default_url[i]) {
            current_index = i;
            break;
        }
    }

    default_ok = current_ok = current_fail = 0;
    /* fetch validation table entry for the current_index 
     * (which now corresponds to the default.url.set value/index) */
    get_validation_table_entry(w->instance_id, current_index, &current_ok, &current_fail, &default_ok);

    /* do the fail-over logic */
    do {
        if (current_ok > 0) {
            if (current_index > 0 && default_ok >= conf->valid_ping_ok) {
                set_valid_url_index(w->instance_id, conf->valid_default_url[0]);
                AM_LOG_INFO(w->instance_id, "%s fail-back to %s", thisfunc, url_list[0]);
            } else {
                set_valid_url_index(w->instance_id, conf->valid_default_url[current_index]);
                AM_LOG_INFO(w->instance_id, "%s continue with %s", thisfunc, url_list[current_index]);
            }
            break;
        }

        /* current index is not valid; check ping.miss.count */
        if (current_ok == 0 && current_fail <= conf->valid_ping_miss) {
            set_valid_url_index(w->instance_id, conf->valid_default_url[current_index]);
            AM_LOG_INFO(w->instance_id, "%s still staying with %s", thisfunc, url_list[current_index]);
            break;
        }

        /* find next valid index value to fail-over to */
        next_ok = 0;
        AM_MUTEX_LOCK(&table_mutex);

        AM_LIST_FOR_EACH(table, e, t) {
            if (e->instance_id == w->instance_id && e->index == 0) {
                default_ok = e->ok;
            }
            if (e->instance_id == w->instance_id && e->ok > 0) {
                next_ok = e->ok;
                i = e->index;
                break;
            }
        }

        AM_MUTEX_UNLOCK(&table_mutex);

        if (next_ok == 0) {
            AM_LOG_WARNING(w->instance_id,
                    "%s none of the values are valid, defaulting to %s", thisfunc, url_list[0]);
            set_valid_url_index(w->instance_id, conf->valid_default_url[0]);
            break;
        }

        if (current_index > 0 && default_ok >= conf->valid_ping_ok) {
            AM_LOG_INFO(w->instance_id, "%s fail-back to %s", thisfunc, url_list[0]);
            set_valid_url_index(w->instance_id, conf->valid_default_url[0]);
            break;
        }

        AM_LOG_INFO(w->instance_id, "%s fail-over to %s", thisfunc, url_list[i]);
        set_valid_url_index(w->instance_id, conf->valid_default_url[i]);

    } while (0);

    am_net_options_delete(net_options);
    free(net_options);
    am_config_free(&conf);
    set_valid_url_instance_running(w->instance_id, AM_FALSE);
    AM_FREE(w->config_path, w);
    URL_LIST_FREE(url_list, url_list_sz);
}