#include "quipu/common.h"
#include "quipu/modify.h"
#define AS_SYNTAX(attrSeq) attrSeq->attr_type->oa_syntax
#define AS_STROID(attrSeq) attrSeq->attr_type->oa_ot.ot_stroid
#define FOREACH(a) for (eptr = a; eptr != NULLATTR; eptr=eptr->attr_link)
void char_map(), char_unmap();
static Attr_Sequence eptr
;
struct entrymod
* ems_append (a
,b
)
if ((ptr
= a
) == NULLMOD
)
for ( ; ptr
->em_next
!= NULLMOD
; ptr
= ptr
->em_next
)
dsErrorStruct
modify_entry(mods
)
struct ds_modifyentry_arg mod_arg
;
struct entrymod
*curr_mod
= 0, *entrymods
= 0;
AttributeType attr_type
= 0;
AttributeValue attr_val
= 0;
AV_Sequence attrVal_seq
= 0;
register modVals curr_val
;
char err_buf
[STRINGLEN
], attr_val_buf
[STRINGLEN
];
if (get_default_service(&mod_arg
.mea_common
) != 0) {
mod_error
.error
= serviceerror
;
mod_error
.err_mess
= strdup("Directory Service Error!\n");
mod_arg
.mea_common
.ca_servicecontrol
.svc_options
= SVC_OPT_PREFERCHAIN
;
mod_arg
.mea_object
= str2dn(mods
->entry_name
);
for (attrs
= mods
->attrs
; attrs
; attrs
= attrs
->next
) {
attr_type
= str2AttrT(attrs
->attr_name
);
for (curr_val
= attrs
->val_seq
;
curr_val
&& curr_val
->mod_flag
;
curr_val
= curr_val
->next
)
curr_mod
->em_next
= NULLMOD
;
curr_mod
->em_type
= EM_REMOVEATTRIBUTE
;
curr_mod
->em_what
= NULLATTR
;
curr_mod
->em_what
= as_comp_new(attr_type
, NULLAV
, NULLACL_INFO
);
entrymods
= ems_append(entrymods
, curr_mod
);
curr_mod
->em_next
= NULLMOD
;
curr_mod
->em_type
= EM_ADDATTRIBUTE
;
curr_mod
->em_what
= NULLATTR
;
for (curr_val
= attrs
->val_seq
; curr_val
; curr_val
= curr_val
->next
) {
char_unmap(attr_val_buf
, curr_val
->new_value
);
if (attr_val_buf
[0] != '\0') {
attr_val
= str2AttrV(attr_val_buf
, attr_type
->oa_syntax
);
attrVal_seq
= avs_merge(attrVal_seq
, avs_comp_new(attr_val
));
attrVal_seq
= avs_comp_new(attr_val
);
if (entrymods
) ems_free(entrymods
);
mod_error
.error
= attributerror
;
"Attribute Error!\nInvalid syntax for value %s type %s.",
curr_val
->new_value
, attrs
->attr_name
);
mod_error
.err_mess
= strdup(err_buf
);
curr_mod
->em_what
= as_comp_new(AttrT_cpy(attr_type
),
entrymods
= ems_append(entrymods
, curr_mod
);
for (curr_val
= attrs
->val_seq
;
curr_val
= curr_val
->next
) {
char_unmap(attr_val_buf
, curr_val
->value
);
if (curr_val
->mod_flag
&& attr_val_buf
[0] != '\0') {
attrVal_seq
= avs_comp_new(str2AttrV(attr_val_buf
,
curr_mod
->em_next
= NULLMOD
;
curr_mod
->em_type
= EM_REMOVEVALUES
;
curr_mod
->em_what
= as_comp_new(AttrT_cpy(attr_type
),
entrymods
= ems_append(entrymods
, curr_mod
);
for (curr_val
= attrs
->val_seq
;
curr_val
= curr_val
->next
) {
char_unmap(attr_val_buf
, curr_val
->new_value
);
if (curr_val
->mod_flag
&& attr_val_buf
[0] != '\0') {
attr_val
= str2AttrV(attr_val_buf
,
attrVal_seq
= avs_merge(attrVal_seq
,
attrVal_seq
= avs_comp_new(attr_val
);
if (entrymods
) ems_free(entrymods
);
mod_error
.error
= attributerror
;
"Attribute Error!\nInvalid syntax for value %s type %s.",
curr_val
->new_value
, attrs
->attr_name
);
mod_error
.err_mess
= strdup(err_buf
);
curr_mod
->em_next
= NULLMOD
;
curr_mod
->em_type
= EM_ADDVALUES
;
curr_mod
->em_what
= as_comp_new(AttrT_cpy(attr_type
),
entrymods
= ems_append(entrymods
, curr_mod
);
curr_mod
->em_next
= NULLMOD
;
curr_mod
->em_type
= EM_ADDATTRIBUTE
;
for (curr_val
= attrs
->val_seq
;
curr_val
= curr_val
->next
) {
char_unmap(attr_val_buf
, curr_val
->new_value
);
if (attr_val_buf
[0] != '\0') {
attr_val
= str2AttrV(attr_val_buf
,
attrVal_seq
= avs_merge(attrVal_seq
,
attrVal_seq
= avs_comp_new(attr_val
);
if (entrymods
) ems_free(entrymods
);
mod_error
.error
= attributerror
;
"Attribute Error!\nInvalid syntax for value %s type %s.",
curr_val
->new_value
, attrs
->attr_name
);
mod_error
.err_mess
= strdup(err_buf
);
curr_mod
->em_what
= as_comp_new(AttrT_cpy(attr_type
),
entrymods
= ems_append(entrymods
, curr_mod
);
mod_arg
.mea_changes
= entrymods
;
if (ds_modifyentry(&mod_arg
, &error
) != DS_OK
) {
mod_error
.err_mess
= modify_error(&error
);
switch (error
.dse_type
) {
mod_error
.error
= duaerror
;
if (!mod_error
.err_mess
) {
strdup("Internal Error, No modifications made. Sorry!");
mod_error
.error
= localdsaerror
;
mod_error
.error
= attributerror
;
if (!mod_error
.err_mess
) {
strdup("Attribute Error! No Modifications made.");
mod_error
.error
= remotedsaerror
;
if (!mod_error
.err_mess
) {
strdup("Referral Error! No Modifications made.");
mod_error
.error
= security
;
if (!mod_error
.err_mess
) {
mod_error
.err_mess
= strdup("Security Error! Check access rights.");
mod_error
.error
= namerror
;
if (!mod_error
.err_mess
) {
switch (error
.dse_un
.dse_un_name
.DSE_na_problem
) {
case DSE_NA_NOSUCHOBJECT
:
strdup("Name Error! No such object.");
case DSE_NA_ALIASPROBLEM
:
case DSE_NA_ALIASDEREFERENCE
:
mod_error
.err_mess
= strdup("Error! Alias problem.");
case DSE_NA_INVALIDATTRIBUTESYNTAX
:
strdup("Name Error! Invalid attribute syntax.");
mod_error
.error
= serviceerror
;
mod_error
.error
= updaterror
;
mod_error
.error
= localdsaerror
;
dn_free(mod_arg
.mea_object
);
delete_cache(mod_arg
.mea_object
);
mod_error
.error
= updaterror
;
mod_error
.err_mess
= strdup("No modifications to make!");
dn_free(mod_arg
.mea_object
);
for (attrs
= mods
->attrs
; attrs
; attrs
= attrs
->next
) {
if (attrs
->mod_flag
== TRUE
&& attrs
->in_flag
== FALSE
)
for (curr_val
= attrs
->val_seq
; curr_val
; curr_val
= curr_val
->next
) {
if (curr_val
->new_value
!= NULLCP
) {
if (curr_val
->value
!= NULLCP
) free(curr_val
->value
);
curr_val
->value
= curr_val
->new_value
;
curr_val
->new_value
= NULLCP
;
if (curr_val
->value
&& *curr_val
->value
!= '\0' && !curr_val
->mod_flag
)
curr_val
->mod_flag
= FALSE
;
if (attr_removed
) attrs
->in_flag
= FALSE
;
dn_free(mod_arg
.mea_object
);
void make_template(entry_name
, attrs
)
static char buffer
[RESBUF
];
extern AttributeType at_objectclass
;
struct ds_read_arg read_arg
;
struct ds_read_result result
;
Attr_Sequence as
, read_attrs
;
Attr_Sequence nas
= 0, tas
= 0, templ_as
, make_template_as();
if (*entry_name
== '\0') return;
if ((ps
= ps_alloc(str_open
)) == NULLPS
) return;
if (str_setup(ps
, buffer
, RESBUF
, 1) == NOTOK
) return;
if (get_default_service (&read_arg
.rda_common
) != 0) return;
read_arg
.rda_common
.ca_servicecontrol
.svc_options
= SVC_OPT_PREFERCHAIN
;
read_arg
.rda_eis
.eis_allattributes
= TRUE
;
read_arg
.rda_eis
.eis_infotypes
= EIS_ATTRIBUTESANDVALUES
;
read_arg
.rda_object
= str2dn(entry_name
);
if ((read_entry
= local_find_entry(read_arg
.rda_object
, FALSE
))
read_entry
->e_data
!= E_TYPE_CONSTRUCTOR
) {
read_attrs
= read_entry
->e_attributes
;
if (ds_read(&read_arg
, &error
, &result
) != DS_OK
) {
if (result
.rdr_entry
.ent_attr
== NULLATTR
) {
read_attrs
= result
.rdr_entry
.ent_attr
;
for (as
= read_attrs
; as
!= NULLATTR
; as
= as
->attr_link
)
if (as
->attr_type
== at_objectclass
)
templ_as
= make_template_as(as
->attr_value
);
if (!(AS_SYNTAX(as
) == str2syntax("schema") ||
AS_SYNTAX(as
) == str2syntax("objectclass") ||
AS_SYNTAX(as
) == str2syntax("acl") ||
AS_SYNTAX(as
) == str2syntax("edbinfo") ||
AS_SYNTAX(as
) == str2syntax("octetstring") ||
!strcmp(AS_STROID(as
), "0.9.2342.19200300.100.1.23") ||
!strcmp(AS_STROID(as
), "0.9.2342.19200300.100.1.24"))) {
nas
= as_comp_new(AttrT_cpy(as
->attr_type
),
if (tas
) tas
= as_merge(tas
, nas
);
for (; as
!= NULLATTR
; as
= as
->attr_link
)
if (!(AS_SYNTAX(as
) == str2syntax("schema") ||
AS_SYNTAX(as
) == str2syntax("objectclass") ||
AS_SYNTAX(as
) == str2syntax("acl") ||
AS_SYNTAX(as
) == str2syntax("edbinfo") ||
AS_SYNTAX(as
) == str2syntax("octetstring") ||
!strcmp(AS_STROID(as
), "0.9.2342.19200300.100.1.23") ||
!strcmp(AS_STROID(as
), "0.9.2342.19200300.100.1.24"))) {
nas
= as_comp_new(AttrT_cpy(as
->attr_type
), NULLAV
, NULLACL_INFO
);
if (templ_as
) templ_as
= as_merge(templ_as
, nas
);
as
= as_merge(tas
, templ_as
);
my_as_print(ps
, as
, READOUT
);
*--ps
->ps_ptr
= NULL
, ps
->ps_cnt
++;
make_attr_sequence(buffer
, attrs
);
make_attr_sequence(entry_string
, attrs
)
register char *str
, *sptr
;
char save
, buffer
[RESBUF
];
AttributeType curr_attr_type
;
str
= sptr
= entry_string
;
if (!str
|| str
== sptr
) return;
if (strcmp(curr_attr
->attr_name
, sptr
)) {
curr_attr
->next
= (dirAttrs
) malloc(sizeof(dir_attrs
));
curr_attr
= curr_attr
->next
;
curr_attr
->mod_flag
= FALSE
;
curr_attr
->in_flag
= TRUE
;
curr_attr
->attr_name
= strdup(sptr
);
curr_attr_type
= str2AttrT(curr_attr
->attr_name
);
if (!strcmp(curr_attr_type
->oa_ot
.ot_stroid
, "2.5.4.35"))
curr_attr
->hidden_flag
= TRUE
;
curr_attr
->hidden_flag
= FALSE
;
AttrT_free(curr_attr_type
);
curr_attr
= (dirAttrs
) malloc(sizeof(dir_attrs
));
curr_attr
->val_seq
= (modVals
) 0;
curr_attr
->mod_flag
= FALSE
;
curr_attr
->in_flag
= TRUE
;
curr_attr
->attr_name
= strdup(sptr
);
curr_attr_type
= str2AttrT(curr_attr
->attr_name
);
if (!strcmp(curr_attr_type
->oa_ot
.ot_stroid
, "2.5.4.35"))
curr_attr
->hidden_flag
= TRUE
;
curr_attr
->hidden_flag
= FALSE
;
AttrT_free(curr_attr_type
);
while ((isspace(*str
) || (*str
== '-')) && *str
!= '\n' && *str
!= '\0')
while (*str
!= '\n' && *str
!= '\0') {
if (*str
!= '\0' && *(str
+ 1) == '\t') {
while (isspace(*str
)) str
++;
curr_val
->next
= (modVals
) malloc(sizeof(struct mod_vals
));
curr_val
= curr_val
->next
;
curr_val
= (modVals
) malloc(sizeof(struct mod_vals
));
curr_attr
->val_seq
= curr_val
;
if (!count
) curr_attr
->in_flag
= FALSE
;
curr_val
->attr
= curr_attr
;
curr_val
->mod_flag
= FALSE
;
curr_val
->value
= strdup(buffer
);
char_map(buffer
, curr_val
->value
);
curr_val
->value
= strdup(buffer
);
if (*str
== '\0' || *++str
== '\0') return;
void char_map(buffer
, value
)
if (value
!= NULLCP
&& *value
!= '\0') {
if (*((char *) (value
+ 1)) == '4' &&
*((char *) (value
+ 2)) == '0') {
void char_unmap(buffer
, value
)
if (value
!= NULLCP
&& *value
!= '\0') {
Attr_Sequence
make_template_as(oc
)
Attr_Sequence as
= NULLATTR
;
for (avs
= oc
; avs
!= NULLAV
; avs
= avs
->avseq_next
) {
ocp
= (objectclass
*) avs
->avseq_av
.av_struct
;
for (optr
= ocp
->oc_must
; optr
!= NULLTABLE_SEQ
; optr
= optr
->ts_next
) {
newas
= as_comp_new(at
, NULLAV
, NULLACL_INFO
);
as
= as_merge(as
, newas
);
for (avs
= oc
; avs
!= NULLAV
; avs
= avs
->avseq_next
) {
ocp
= (objectclass
*) avs
->avseq_av
.av_struct
;
for (optr
= ocp
->oc_may
; optr
!= NULLTABLE_SEQ
; optr
= optr
->ts_next
) {
newas
= as_comp_new(at
, NULLAV
, NULLACL_INFO
);
as
= as_merge(as
, newas
);
char *modify_error(error
)
if ((ps
= ps_alloc(str_open
)) == NULLPS
) {
if (str_setup(ps
, buffer
, RESBUF
, 1) == NOTOK
) {
my_as_comp_print (ps
,as
,format
)
(void) sprintf(buffer
,"%s",attr2name (as
->attr_type
, 1));
(void) sprintf (buffer
,"%s",attr2name_aux (as
->attr_type
));
if ((as
->attr_value
== NULLAV
) && (format
!= READOUT
))
ps_printf (ps
, "%s=\n", buffer
);
if (as
->attr_value
== NULLAV
) {
ps_printf(ps
, "%-21s - \n", buffer
);
for (avs
= as
->attr_value
; avs
!= NULLAV
; avs
= avs
->avseq_next
) {
ps_printf (ps
, "%-21s - ", buffer
);
ps_printf (ps
, "%s= ", buffer
);
avs_comp_print (ps
, avs
, EDBOUT
);
ps_printf (ps
, "%-21s - ", buffer
);
ps_printf (ps
, "%s= ", buffer
);
avs_print (ps
, as
->attr_value
, format
);
my_as_print (ps
,as
,format
)
my_as_comp_print(ps
,eptr
,format
);
Attr_Sequence
as_sort(as
)
Attr_Sequence with_vals
= NULLATTR
, without_vals
= NULLATTR
, next_as
;
if (as
== NULLATTR
) return as
;
as
->attr_link
= NULLATTR
;
if (as
->attr_value
) with_vals
= as_merge(with_vals
, as
);
else without_vals
= as_merge(without_vals
, as
);
for (; as
->attr_link
!= NULLATTR
; as
= as
->attr_link
)
else return without_vals
;
as
->attr_link
= without_vals
;