ufname.c
来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 1,847 行 · 第 1/3 页
C
1,847 行
#ifndef lintstatic char *rcsid = "$Header: /xtel/isode/isode/others/quipu/uips/doog/query/RCS/ufname.c,v 9.0 1992/06/16 12:45:27 isode Rel $";#endif/* $Header: /xtel/isode/isode/others/quipu/uips/doog/query/RCS/ufname.c,v 9.0 1992/06/16 12:45:27 isode Rel $ *//* * $Log: ufname.c,v $ * Revision 9.0 1992/06/16 12:45:27 isode * Release 8.0 * *//***************************************************************************** ufname.c -*****************************************************************************/#include <ctype.h>#include "types.h"#include "ufname.h"#include "request.h"#include "error.h"#include "util.h"#include "ds_tasks.h"#include "ds_util.h"#include "quipu/ds_search.h"#include "quipu/dap2.h"#include "quipu/name.h"extern int dsap_ad;extern int next_task_id;#ifndef NO_STATSextern LLog *log_stat;#endifstatic QE_error_code process_ufn_search();static QE_error_code directory_search();static QBool follow_path();searchPath ufnpaths = NULLSearchPath;/* * - get_ufn_status() - * * */ufnStatus get_ufn_status(request_id) QCardinal request_id;{ (void) _get_request_of_id(request_id); return NULLUfnStatus; } /* get_ufn_status *//* * - get_ufn_results() - * Copy and return results for the identified ufn request, then delete all * records for that request. * */ufnResults get_ufn_results(id) QCardinal id;{ requestRec ufn_request = _get_request_of_id(id); ufnameRec ufnrec; ufnResults results; ufnrec = ufn_request->UFNAME_REC; results = ufnrec->results; results->tasks_sent = ufnrec->tasks_sent; results->tasks_failed = ufnrec->tasks_failed; ufnrec->results = NULLUfnResults; return results;} /* get_ufn_results *//* * - do_ufn_resolve() - * Initiate a UFN search. * */QE_error_code do_ufn_resolve(baseobjects, ufname, is_leaf, id_ptr) entryList baseobjects; namePart ufname; known is_leaf; QCardinal *id_ptr;{ ufnameRec new_request; namePart root_part, tmp_part; entryList path; requestRec request; int name_part_count; /* Record request invocation */ (void) _request_invoked(UFNAME, id_ptr); request = _get_request_of_id(*id_ptr); new_request = request->UFNAME_REC; new_request->name_parts = ufname; new_request->tasks_sent = new_request->tasks_failed = 0; for (tmp_part = ufname, name_part_count = 1; tmp_part->next != NULLNamePart; tmp_part = tmp_part->next, name_part_count++) ; tmp_part->is_bottom_level = is_leaf; if (baseobjects != NULLEntryList) { QCardinal base_object_num; root_part = name_part_alloc(); root_part->next = ufname; root_part->good_matches = root_part->poor_matches = NULLEntryList; root_part->good_match_num = root_part->exact_match_num = 0; root_part->part_name = NULLCP; root_part->is_resolved = TRUE; root_part->is_bottom_level = no; root_part->exact_matches = baseobjects; for (base_object_num = 0; baseobjects != NULLEntryList; baseobjects = baseobjects->next, base_object_num++) ; root_part->exact_match_num = base_object_num; new_request->name_parts = root_part; } else { path = new_request->path = get_ufn_path(name_part_count); root_part = name_part_alloc(); root_part->next = ufname; root_part->good_matches = root_part->poor_matches = root_part->exact_matches = NULLEntryList; root_part->good_match_num = 0; root_part->part_name = NULLCP; root_part->is_resolved = TRUE; root_part->is_bottom_level = no; (void) dn_list_add(path == NULLEntryList? "" : path->string_dn, &root_part->exact_matches, NULLAttrT); new_request->path = new_request->path->next; root_part->exact_match_num = 1; new_request->name_parts = root_part; } new_request->request_id = *id_ptr; new_request->results = NULLUfnResults; return process_ufn_search(new_request);} /* do_ufn_resolve *//* * - process_ufn_search() - * Do/continue a UFN search. Uses requestRec to determine the stage that * the search has reached, and then proceeds accordingly. * * If search not yet started do an appropriate ds_search against the given base * object. * * If the given name is only partially resolved, search against the list * of partial names resolved thus far. * */static QE_error_code process_ufn_search(ufnrec) ufnameRec ufnrec;{ namePart name_comp, prev_comp; entryList resolved_names; QE_error_code search_status; requestRec request; /* If ds searches outstanding, then do nothing. */ if (ufnrec->exact_task_count > 0 || ufnrec->approx_task_count > 0) return QERR_ok; /* Find out how far the search has gone. */ for (name_comp = ufnrec->name_parts, prev_comp = NULLNamePart; name_comp != NULLNamePart && name_comp->is_resolved == TRUE; prev_comp = name_comp, name_comp = name_comp->next) ; request = _get_request_of_id(ufnrec->request_id); if (prev_comp == NULLNamePart) { /* If no name part_names yet resolved search against root object. */ if ((search_status = directory_search(NULLCP, name_comp, ufnrec)) != QERR_ok) { add_error_to_request_rec(request, NULLCP, search_status, (struct DSError *) NULL); return search_status; } } else { /* Else search against all resolved names. If no exact matches, use good matches. If no good matches use poor matches. Return partial matches if match number exceeds limit */ if (prev_comp->exact_match_num > 0) resolved_names = prev_comp->exact_matches; else if (prev_comp->good_match_num > 0) resolved_names = prev_comp->good_matches; else if (prev_comp->poor_match_num > 0) resolved_names = prev_comp->poor_matches; else return QERR_nothing_found; while (resolved_names != NULLEntryList) { if ((search_status = directory_search(resolved_names->string_dn, name_comp, ufnrec)) != QERR_ok) return search_status; resolved_names = resolved_names->next; } } return QERR_ok;} /* process_ufn_search *//* * * * */request_state continue_ufn_search(good_matches, request_id) entryList good_matches; QCardinal request_id;{ namePart last_part, first_real_part; ufnameRec ufnrec; requestRec request; ufnResults results; QCardinal good_match_num; entryList curr_match; request = _get_request_of_id(request_id); ufnrec = request->UFNAME_REC; for (last_part = ufnrec->name_parts->next; last_part->poor_matches != NULLEntryList && last_part->good_matches == NULLEntryList && last_part->exact_matches == NULLEntryList && last_part != NULLNamePart; last_part = last_part->next) ; if (last_part == NULLNamePart) return RQ_error_returned; else { for (good_match_num = 0, curr_match = good_matches; curr_match != NULLEntryList; curr_match = curr_match->next, good_match_num++) ; if (good_match_num == 0) { first_real_part = ufnrec->name_parts->next; if (first_real_part->is_resolved != TRUE) { if (ufnrec->path != NULLEntryList) if (follow_path(ufnrec) == TRUE) { ufnrec->results = NULLUfnResults; return RQ_processing; } results = ufnrec->results = ufn_res_alloc(); results->match_status = Failed; results->tried_intermediate = TRUE; results->resolved_part = results->unresolved_part = NULLCP; results->tasks_sent = ufnrec->tasks_sent; results->tasks_failed = ufnrec->tasks_failed; results->match_num = 0; results->matches = NULLEntryList; results->errors = request->errors; request->errors = NULLError; } else { ufnrec->results = NULLUfnResults; return RQ_processing; } } last_part->good_match_num = good_match_num; last_part->good_matches = good_matches; last_part->is_resolved = TRUE; if (process_ufn_search(ufnrec) != QERR_ok) return RQ_error_returned; else return RQ_processing; }} /* continue_ufn_search *//* * - directory_search() - * Compose and invoke a X500 search. * */static QE_error_code directory_search(base_name, purp_name_comp, ufnrec) char *base_name; namePart purp_name_comp; ufnameRec ufnrec;{ struct ds_search_arg search_arg; struct DAPindication di; DN base_dn; AttributeType attr_type; QBool is_attr_cmp = FALSE; char *str_oid, *start, *end, *search_value; QCardinal level_count; QBool has_org = FALSE, has_loc = FALSE, has_org_unit = FALSE; Filter exact_filter, approx_filter; Attr_Sequence get_attrs = (Attr_Sequence) NULL; int task_id, count; char *TidyString(); if (purp_name_comp->next == NULLNamePart && purp_name_comp->is_bottom_level == no) return QERR_nothing_found; if (purp_name_comp->is_bottom_level == might_not) purp_name_comp->is_bottom_level = no; /* Make a DN struct from given string object name. If not valid then return an error. */ if (base_name == NULLCP || isnull(*base_name)) base_dn = NULLDN; else if ((base_dn = str2dn(base_name)) == NULLDN) return QERR_bad_name; /* `Analyse' the string dn. */ start = end = base_name; level_count = 0; if (base_dn != NULLDN) while (1) { end = index(start, '='); *end = '\0'; if ((attr_type = AttrT_new(start)) == NULLAttrT) return QERR_bad_name; *end = '='; /* Need the string oid of the base type. */ str_oid = attr_type->oa_ot.ot_stroid; if (lexequ(str_oid, "2.5.4.7") == 0) has_loc = TRUE; else if (lexequ(str_oid, "2.5.4.11") == 0) has_org_unit = TRUE; else if (lexequ(str_oid, "2.5.4.10") == 0) has_org = TRUE; level_count++; if ((start = index(end, '@')) == NULLCP) break; end = ++start; } /* Implace search parameters. */ (void) get_default_service(&search_arg.sra_common); search_arg.sra_common.ca_servicecontrol.svc_options = search_arg.sra_common.ca_servicecontrol.svc_options | SVC_OPT_PREFERCHAIN; search_arg.sra_common.ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT; search_arg.sra_common.ca_servicecontrol.svc_sizelimit = 10; search_arg.sra_baseobject = base_dn; /* Don't want any attributes back. */ search_arg.sra_eis.eis_allattributes = FALSE; /* Approx search will ask for some attributes back */ search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; search_arg.sra_eis.eis_select = NULL; /* Search dereferences alias entries. */ search_arg.sra_searchaliases = TRUE; if (level_count >= 2 && has_org == TRUE) search_arg.sra_subset = SRA_WHOLESUBTREE; else search_arg.sra_subset = SRA_ONELEVEL; /* Make search filters for exact and approx matches. */ search_value = TidyString(purp_name_comp->part_name); /* If a type is given, make appropriate filters. */ if (index(search_value, '=') != NULLCP) { is_attr_cmp = TRUE; if (make_typed_filter_items(search_value, &exact_filter, &approx_filter) != QERR_ok) return QERR_bad_value_syntax; } /* * If base object == root, can only search for a country. */ else if (base_dn == NULLDN) { if ((int)strlen(search_value) > 2) { attr_type = AttrT_new("0.9.2342.19200300.99.1.8"); get_attrs = as_comp_new(attr_type, NULLAV, NULLACL_INFO); if (make_filter_items(attr_type, search_value, &exact_filter, &approx_filter) != QERR_ok) return QERR_bad_value_syntax; } else { exact_filter = filter_alloc(); approx_filter = filter_alloc(); approx_filter->flt_next = exact_filter->flt_next = NULLFILTER; exact_filter->flt_type = approx_filter->flt_type = FILTER_OR; attr_type = AttrT_new("2.5.4.6"); get_attrs = as_comp_new(attr_type, NULLAV, NULLACL_INFO); if (make_filter_items(attr_type, search_value, &exact_filter->FUFILT, &approx_filter->FUFILT) != QERR_ok) { filter_free(exact_filter); filter_free(approx_filter); attr_type = AttrT_new("0.9.2342.19200300.99.1.8"); get_attrs = as_merge(get_attrs, as_comp_new(attr_type, NULLAV, NULLACL_INFO)); if (make_filter_items(attr_type, search_value, &exact_filter, &approx_filter) != QERR_ok) { return QERR_bad_value_syntax; } } else { attr_type = AttrT_new("0.9.2342.19200300.99.1.8"); get_attrs = as_merge(get_attrs, as_comp_new(attr_type, NULLAV, NULLACL_INFO)); if (make_filter_items(attr_type, search_value, &exact_filter->FUFILT->flt_next, &approx_filter->FUFILT->flt_next) != QERR_ok) { filter_free(exact_filter); filter_free(approx_filter); return QERR_bad_value_syntax; } } } } /* * Check for `bottom level' case first so search * against `cn', `sn' and `uid'. Get the `cn' and `uid' attrs back. */ else if (purp_name_comp->is_bottom_level == unknown && level_count >= 2 && has_org == TRUE) { search_arg.sra_common.ca_servicecontrol.svc_sizelimit = 20; exact_filter = filter_alloc(); approx_filter = filter_alloc(); approx_filter->flt_next = exact_filter->flt_next = NULLFILTER; exact_filter->flt_type = approx_filter->flt_type = FILTER_OR; /* `cn' filter item. */ attr_type = AttrT_new("2.5.4.3"); get_attrs = as_comp_new(attr_type, NULLAV, NULLACL_INFO); if (make_filter_items(attr_type, search_value, &exact_filter->FUFILT, &approx_filter->FUFILT) != QERR_ok) { filter_free(exact_filter); filter_free(approx_filter); return QERR_bad_value_syntax; } /* `sn' filter item. */ attr_type = AttrT_new("2.5.4.4"); if (make_filter_items(attr_type, search_value, &exact_filter->FUFILT->flt_next, &approx_filter->FUFILT->flt_next) != QERR_ok) { filter_free(exact_filter); filter_free(approx_filter); return QERR_bad_value_syntax; } exact_filter->FUFILT->flt_next->flt_next = NULLFILTER; approx_filter->FUFILT->flt_next->flt_next = NULLFILTER; } /* * Otherwise do an intermediate search. */ else { /* * If `organizationalUnit' in base object name filter on `ou'. */ search_arg.sra_subset = SRA_ONELEVEL; if (has_org_unit) { attr_type = AttrT_new("2.5.4.11"); /* Get back the 'ou' attrs */ get_attrs = as_comp_new(attr_type, NULLAV, NULLACL_INFO); if (make_filter_items(attr_type, search_value, &exact_filter, &approx_filter) != QERR_ok) { return QERR_bad_value_syntax; } } /* * If no `locality' or `organization' in base object name search * filter on `locality' or `organization'. */ else if (!has_loc && !has_org) { exact_filter = filter_alloc(); approx_filter = filter_alloc(); approx_filter->flt_next = exact_filter->flt_next = NULLFILTER; exact_filter->flt_type = approx_filter->flt_type = FILTER_OR; exact_filter->FUFILT = filter_alloc(); approx_filter->FUFILT = filter_alloc(); exact_filter->FUFILT->flt_next = filter_alloc(); approx_filter->FUFILT->flt_next = filter_alloc(); approx_filter->FUFILT->flt_next->flt_next = exact_filter->FUFILT->flt_next->flt_next = approx_filter->flt_next = exact_filter->flt_next = NULLFILTER; exact_filter->FUFILT->flt_type = approx_filter->FUFILT->flt_type = exact_filter->FUFILT->flt_next->flt_type = approx_filter->FUFILT->flt_next->flt_type = FILTER_AND; /* `localityName' filter. */ attr_type = AttrT_new("2.5.4.7"); get_attrs = as_comp_new(attr_type, NULLAV, NULLACL_INFO); if (make_filter_items(attr_type, search_value, &exact_filter->FUFILT->FUFILT, &approx_filter->FUFILT->FUFILT) != QERR_ok) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?