/* alias_chk.c - checks aliases from position provided downwards. */
/* A management tool - probably best to run this as a manager. */
static char *rcsid
= "$Header: /f/osi/others/quipu/uips/manage/RCS/alias_chk.c,v 7.1 91/02/22 09:32:02 mrose Interim $";
* $Header: /f/osi/others/quipu/uips/manage/RCS/alias_chk.c,v 7.1 90/07/27 08:4
* Revision 7.1 91/02/22 09:32:02 mrose
* Revision 7.0 91/01/24 14:43:41 mrose
* *** empty log message ***
* Revision 7.1 90/07/27 08:47:16 mrose
* Revision 7.0 90/06/26 14:52:31 mrose
* *** empty log message ***
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
#include "quipu/compare.h"
#include "quipu/ds_search.h"
#define ORG_PERSON "thornPerson & quipuObject"
/* this should probably go elsewhere !!! */
#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps)
#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt)
extern Entry current_entry
;
extern Filter
get_filter();
char **NULLARGV
= (char **) 0;
call_alias_chk(argc
, argv
)
struct ds_search_arg search_arg
;
struct DSError search_error
;
struct ds_search_result search_result
;
DN save_dn
, tmp_dn
= NULLDN
;
ps_print(OPT
, "Error, too many arguments..\n") ;
/* Convert arg 2 to a DN for future use. */
/* Turn a sequence number back into a DN */
if (*argv
[1] >= '0' && *argv
[1] <= '9')
/* First convert the number into a dn */
tmp_dn
= dn_cpy(sequence_dn(atoi(argv
[1]))) ;
ps_print(OPT
, "..@ gives me a headache. Ambiguous. Aborting.\n") ;
tmp_dn
= dn_cpy(str2dn(argv
[1] + 1)) ;
save_dn
= dn_cpy(str2dn_aux(argv
[1], &alias
)) ;
tmp_dn
= dn_cpy(save_dn
);
tmp_dn
= dn_cpy(save_dn
) ;
dn_append(tmp_dn
, dn_cpy(save_dn
));
/* We now have the start location in tmp_dn */
save_dn
= dn_cpy(dn
) ; /* save start location for later restore */
/* dn should be set to a: either current location, or
b: 2nd arg if specified. */
/* Is dn a leaf or a non_leaf? */
struct ds_compare_arg compare_arg
;
struct DSError compare_error
;
struct ds_compare_result compare_result
;
if ((argc
= service_control (OPT
, argc
, argv
, &compare_arg
.cma_common
)) == -1)
compare_arg
.cma_common
.ca_servicecontrol
.svc_options
|= SVC_OPT_DONTDEREFERENCEALIAS
;
compare_arg
.cma_object
= dn
;
if (get_ava (&compare_arg
.cma_purported
, "objectClass", "quipuNonLeafObject") != OK
)
ps_print(OPT
, "Oops, 'objectClass=quipuNonLeafObject' is a bad attribute!\n") ;
ps_print(OPT
, "This is very bad...\n") ;
if (compare_arg
.cma_common
.ca_security
!= (struct security_parms
*) 0)
struct signature
*sign_operation();
int encode_DAS_CompareArgumentData();
compare_arg
.cma_common
.ca_sig
=
sign_operation((caddr_t
)&compare_arg
, encode_DAS_CompareArgumentData
) ;
while (ds_compare (&compare_arg
, &compare_error
, &compare_result
) != DS_OK
)
if (dish_error (OPT
, &compare_error
) == 0)
compare_arg
.cma_object
= compare_error
.ERR_REFERRAL
.DSE_ref_candidates
->cr_name
;
/* If the object is a leaf then check it out and exit... */
if ( compare_result
.cmr_matched
== FALSE
)
struct DSError read_error
;
struct ds_read_result read_result
;
struct ds_read_arg read_arg
;
read_arg
.rda_eis
.eis_allattributes
= TRUE
;
read_arg
.rda_eis
.eis_select
= NULLATTR
;
read_arg
.rda_eis
.eis_infotypes
= TRUE
;
if (service_control (OPT
, argc
, argv
, &read_arg
.rda_common
) == -1)
read_arg
.rda_common
.ca_servicecontrol
.svc_options
|= SVC_OPT_DONTDEREFERENCEALIAS
;
read_arg
.rda_object
= dn
;
/* Strong authentication */
if (read_arg
.rda_common
.ca_security
!=
(struct security_parms
*) 0)
struct signature
*sign_operation();
int encode_DAS_ReadArgumentData();
read_arg
.rda_common
.ca_sig
=
sign_operation((caddr_t
)&read_arg
,
encode_DAS_ReadArgumentData
);
while (ds_read (&read_arg
, &read_error
, &read_result
) != DS_OK
) {
if (dish_error (OPT
, &read_error
) == 0)
read_arg
.rda_object
= read_error
.ERR_REFERRAL
.DSE_ref_candidates
->cr_name
;
if ( verify_alias(&read_result
.rdr_entry
) != OK
)
ps_print(OPT
, "Bad Alias.\n") ;
/* Else search the subtree below this current
* position for ALL aliases, and check each one. */
/* Sort out the search filter for this. */
search_arg
.sra_baseobject
= dn
;
search_arg
.sra_subset
= SRA_WHOLESUBTREE
;
search_arg
.sra_common
.ca_servicecontrol
.svc_sizelimit
= SVC_NOSIZELIMIT
;
search_arg
.sra_searchaliases
= FALSE
;
search_arg
.sra_filter
= NULLFILTER
;
if ((argc
= service_control (OPT
, argc
, argv
, &search_arg
.sra_common
)) == -1)
if ((search_arg
.sra_filter
= get_filter("objectClass=alias")) == NULLFILTER
)
ps_printf (OPT
,"Very bad... Filter wrong. Aborting...\n");
ps_print(OPT
, "Searching... please wait...\n") ;
/* Strong authentication */
if (search_arg
.sra_common
.ca_security
!= (struct security_parms
*) 0)
struct signature
*sign_operation();
int encode_DAS_SearchArgumentData();
search_arg
.sra_common
.ca_sig
= sign_operation((caddr_t
)&search_arg
, encode_DAS_SearchArgumentData
);
while (ds_search (&search_arg
, &search_error
, &search_result
) != DS_OK
)
if (dish_error (OPT
, &search_error
) == 0)
search_arg
.sra_baseobject
= search_error
.ERR_REFERRAL
.DSE_ref_candidates
->cr_name
;
correlate_search_results (&search_result
);
if (search_result
.CSR_entries
== NULLENTRYINFO
)
ps_printf(OPT
, "No aliases found...\n");
for (ptr
= search_result
.CSR_entries
; ptr
!= NULLENTRYINFO
; ptr
= ptr
->ent_next
)
/* decode it immediately so we only have to do it once. */
cache_entry (ptr
, TRUE
, TRUE
) ;
if ( verify_alias(ptr
) != OK
)
ps_print(OPT
, "Bad Alias.\n") ;
handle_problems (RPS
, search_result
.CSR_cr
,search_result
.CSR_limitproblem
, TRUE
);
filter_free (search_arg
.sra_filter
);
verify_alias(alias_entry
)
static char *nvec
[2] = {"search"};
struct DSError read_error
;
struct ds_read_result read_result
;
struct ds_read_arg read_arg
;
struct attrcomp
*tmp_ent_attr
;
AV_Sequence object_class_of_object
;
AV_Sequence tree_strAVS
= NULLAV
;
DN dn_above_alias
, trail
, dnptr
;
char Name
=FALSE
, Acl
=FALSE
, ObjClass
=FALSE
, AlObjNam
=FALSE
;
char BackReference
=FALSE
;
at_ojc
= AttrT_new("objectClass") ; /* objectClass */
at_aoj
= AttrT_new("aliasedObjectName") ;
at_acl
= AttrT_new("acl") ;
at_sa
= AttrT_new("seeAlso") ;
at_lmt
= AttrT_new("lastModifiedTime") ;
at_lmb
= AttrT_new("lastModifiedBy") ;
at_trs
= AttrT_new("treeStructure") ;
at_c
= AttrT_new("countryName") ;
at_o
= AttrT_new("organizationName") ;
at_ou
= AttrT_new("organizationalUnitName") ;
at_cn
= AttrT_new("commonName") ;
read_arg
.rda_object
= NULLDN
;
ps_print(OPT
, "\nFound alias:") ;
dn_print(OPT
, alias_entry
->ent_dn
, EDBOUT
) ;
/* We now have ourselves an entrystruct which is an alias, and we
* have to check various features!!
* 1: only the allowed objects.
* 2: the seeAlso attribute is correct (ie points to a real entry).
* 3: The objectClass of the real entry fits under where the alias
/* Does the alias have the allowed objects and only the allowed? */
for (tmp_ent_attr
= alias_entry
->ent_attr
; tmp_ent_attr
!= NULL
; tmp_ent_attr
= tmp_ent_attr
->attr_link
)
if (AttrT_cmp(tmp_ent_attr
->attr_type
, at_ojc
) == 0)
if (AttrT_cmp(tmp_ent_attr
->attr_type
, at_aoj
) == 0)
read_arg
.rda_object
= dn_cpy ((DN
) tmp_ent_attr
->attr_value
->avseq_av
.av_struct
);
if (AttrT_cmp(tmp_ent_attr
->attr_type
, at_acl
) == 0)
if (AttrT_cmp(tmp_ent_attr
->attr_type
, at_lmt
) == 0)
if (AttrT_cmp(tmp_ent_attr
->attr_type
, at_lmb
) == 0)
if (AttrT_cmp(tmp_ent_attr
->attr_type
, at_c
) == 0 ||
AttrT_cmp(tmp_ent_attr
->attr_type
, at_o
) == 0 ||
AttrT_cmp(tmp_ent_attr
->attr_type
, at_ou
) == 0 ||
AttrT_cmp(tmp_ent_attr
->attr_type
, at_cn
) == 0)
ps_print(OPT
, "Illegal attribute type: ") ;
AttrT_print (OPT
, tmp_ent_attr
->attr_type
, EDBOUT
) ;
if (read_arg
.rda_object
== NULLDN
)
ps_print(OPT
, "Malformed alias. No alias object name present!\n" ) ;
ps_print(OPT
, "Object Class missing.\n") ;
ps_print(OPT
, "Alias Object name missing.\n") ;
ps_print(OPT
, "ACL missing.\n") ;
ps_print(OPT
, "Name of alias is missing.\n") ;
GoodAlias
= ((ObjClass
&& AlObjNam
&& Acl
&& Name
) ? OK
: NOTOK
) ;
/* Read the entry that the alias points to.... */
read_arg
.rda_eis
.eis_allattributes
= TRUE
;
read_arg
.rda_eis
.eis_select
= NULLATTR
;
read_arg
.rda_eis
.eis_infotypes
= TRUE
;
if (service_control (OPT
, 0, NULLARGV
, &read_arg
.rda_common
) == -1)
read_arg
.rda_common
.ca_servicecontrol
.svc_options
|= SVC_OPT_DONTDEREFERENCEALIAS
;
/* Strong authentication */
if (read_arg
.rda_common
.ca_security
!=
(struct security_parms
*) 0)
struct signature
*sign_operation();
int encode_DAS_ReadArgumentData();
read_arg
.rda_common
.ca_sig
=
sign_operation((caddr_t
)&read_arg
,
encode_DAS_ReadArgumentData
);
while (ds_read (&read_arg
, &read_error
, &read_result
) != DS_OK
) {
if (dish_error (OPT
, &read_error
) == 0)
ps_print(OPT
, "Can't read ") ;
dn_print(OPT
, read_arg
.rda_object
, EDBOUT
) ;
read_arg
.rda_object
= read_error
.ERR_REFERRAL
.DSE_ref_candidates
->cr_name
;
/* and see if it points back to this alias.
* It should do, but doesn't have to. While we are at it,
* collect the objectClass of this entry.
for (tmp_ent_attr
= read_result
.rdr_entry
.ent_attr
; tmp_ent_attr
!= NULL
;
tmp_ent_attr
= tmp_ent_attr
->attr_link
)
if (AttrT_cmp(tmp_ent_attr
->attr_type
, at_sa
) == 0)
AV_Sequence tmp_avs
= tmp_ent_attr
->attr_value
;
for (; tmp_avs
!= NULL
; tmp_avs
= tmp_avs
->avseq_next
)
if (dn_cmp((DN
) tmp_avs
->avseq_av
.av_struct
, alias_entry
->ent_dn
))
ps_print(OPT
, "Alias object correctly points back to alias itself.\n") ;
if (AttrT_cmp(tmp_ent_attr
->attr_type
, at_ojc
) == 0)
object_class_of_object
= avs_cpy(tmp_ent_attr
->attr_value
) ;
if (BackReference
== FALSE
)
ps_print(OPT
, "Alias object should point back to alias.\n") ;
if (object_class_of_object
== NULLAV
)
ps_print(OPT
, "Can't find object class of aliased object\n. Assuming OK\n") ;
/* Move above the alias in order to find the treeStructure. */
dn_above_alias
= dn_cpy(alias_entry
->ent_dn
) ;
for (dnptr
= dn_above_alias
; dnptr
->dn_parent
!= NULLDN
; dnptr
= dnptr
->dn_parent
)
trail
->dn_parent
= NULLDN
;
read_arg
.rda_object
= dn_cpy(dn_above_alias
) ;
/* Strong authentication */
if (read_arg
.rda_common
.ca_security
!=
(struct security_parms
*) 0)
struct signature
*sign_operation();
int encode_DAS_ReadArgumentData();
read_arg
.rda_common
.ca_sig
=
sign_operation((caddr_t
)&read_arg
,
encode_DAS_ReadArgumentData
);
while (ds_read (&read_arg
, &read_error
, &read_result
) != DS_OK
) {
if (dish_error (OPT
, &read_error
) == 0)
read_arg
.rda_object
= read_error
.ERR_REFERRAL
.DSE_ref_candidates
->cr_name
;
for (tmp_ent_attr
= read_result
.rdr_entry
.ent_attr
; tmp_ent_attr
!= NULL
;
tmp_ent_attr
= tmp_ent_attr
->attr_link
)
if (AttrT_cmp(tmp_ent_attr
->attr_type
, at_trs
) == 0)
tree_strAVS
= avs_cpy(tmp_ent_attr
->attr_value
) ;
if (tree_strAVS
== NULLAV
)
ps_print(OPT
, "Tree structure missing - assuming validity.\n") ;
if (test_schema(tree_strAVS
, object_class_of_object
) != OK
)
ps_print(OPT
, "Tree structure bad...\n") ;