|
|
BSD 4.3reno
/* add_alias.c - a mutilated add.c*/
#ifndef lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/others/quipu/uips/manage/add_alias.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $";
#endif
/*
* $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/others/quipu/uips/manage/add_alias.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $
*
*
* $Log: add_alias.c,v $
* Revision 1.1.1.1 2018/04/24 16:12:56 root
* BSD 4.3reno
*
* Revision 7.1 90/07/27 08:47:16 mrose
* update
*
* Revision 7.0 90/06/26 14:52:31 mrose
* *** empty log message ***
*
*/
/*
* NOTICE
*
* 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
* this agreement.
*
*/
#include "quipu/util.h"
#include "quipu/dua.h"
#include "quipu/add.h"
#include "quipu/entry.h"
#include "quipu/compare.h"
#include "quipu/modify.h"
#define ORG_PERSON "thornPerson & quipuObject"
/* this should probably go elsewhere !!! */
extern DN dn;
#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps)
#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt)
extern char frompipe;
extern PS opt;
extern PS rps;
extern Entry current_entry;
static char new_draft;
call_add_alias (argc, argv)
int argc;
char **argv;
{
DN oj_dn, aoj_dn ;
DN save_dn, dnptr, trail ;
DN moddn;
extern DN str2dn_aux() ;
extern DN sequence_dn() ;
Entry entry_ptr;
FILE *fd;
PS tmp ;
PS str_ps;
char str_buffer[1000];
char fname[128];
char alias = FALSE ;
struct ds_addentry_arg add_arg;
struct DSError error;
struct DSError compare_error;
struct ds_compare_result compare_result;
struct ds_compare_arg compare_arg;
struct ds_modifyentry_arg mod_arg;
struct DSError mod_error;
struct entrymod *emnew ;
AV_Sequence objClassAVS ;
AV_Sequence treeStrAVS ;
Attr_Sequence get_attributes();
extern int parse_status;
int draft_flag = 0;
char *home;
char objectname[80] ;
char aliasobjectname[160] ;
char *contact_compare[6] ;
char *contact_showentry[6] ;
char *contact_modify[1] ;
contact_compare[0] = "compare" ;
contact_compare[1] = "";
contact_compare[2] = "-attribute";
contact_compare[4] = "-noprint";
contact_compare[5] = "-dontdereferencealias" ;
contact_showentry[0] = "showentry";
contact_showentry[1] = "-noshow" ;
contact_showentry[2] = "-all" ;
contact_showentry[3] = "-nokey" ;
contact_showentry[4] = "-dontdereferencealias";
contact_modify[0] = "modify" ;
emnew = em_alloc() ;
contact_showentry[5] = (char *) malloc ((unsigned)strlen(argv[2])) ;
(void)strcpy(contact_showentry[5], argv[2]) ;
contact_compare[3] = (char *) malloc ((unsigned)strlen("objectClass=alias.")) ;
(void)strcpy(contact_compare[3], "objectClass=alias") ;
if (service_control (OPT, 6, contact_compare, &compare_arg.cma_common) == -1)
{
ps_print(OPT, "Problems with compare service control flags.\n") ;
return ;
}
if (home = getenv ("HOME"))
(void) sprintf (fname, "%s/.dishdraft", home);
else
(void) strcpy (fname, "./.dishdraft");
new_draft = FALSE;
if ((argc = service_control (OPT, argc, argv, &add_arg.ada_common)) == -1)
return ;
if (argc < 3)
{
ps_printf(OPT, "Not enough arguments.\n") ;
Usage (argv[0]) ;
return ;
}
(void)strcpy(objectname, argv[1]) ;
(void)strcpy(aliasobjectname, argv[2]) ;
/* Turn a sequence number back into a DN */
if (*aliasobjectname >= '0' && *aliasobjectname <= '9')
{
/* First convert the number into a dn */
aoj_dn = dn_cpy(sequence_dn(atoi(aliasobjectname))) ;
}
else
{
if (*aliasobjectname == '.')
{
ps_print(OPT, "..@ gives me a headache. Ambiguous. Abort... \n") ;
return ;
}
if (*aliasobjectname == '@')
{
aoj_dn = dn_cpy(str2dn(aliasobjectname + 1)) ;
}
else
{
/*aoj_dn = dn_cpy(dn) ;
*dn_append(aoj_dn, dn_cpy(str2dn(aliasobjectname))) ;
*/
save_dn = str2dn_aux(aliasobjectname,&alias) ;
if (save_dn != NULLDN)
{
if (alias)
{
aoj_dn = dn_cpy(save_dn);
}
else
{
if (dn == NULLDN)
{
aoj_dn = dn_cpy(save_dn) ;
}
else
{
aoj_dn = dn_cpy(dn) ;
dn_append (aoj_dn,save_dn);
}
}
}
dn_free(save_dn) ;
}
}
if (*objectname >= '0' && *objectname <= '9')
{
/* First convert the number into a dn */
oj_dn = dn_cpy(sequence_dn(atoi(objectname))) ;
}
else
{
if (*objectname == '.')
{
ps_print(OPT, "..@ gives me a headache. Ambiguous. Abort... \n") ;
return ;
}
if (*objectname == '@')
{
oj_dn = dn_cpy(str2dn(objectname + 1)) ;
}
else
{
oj_dn = dn_cpy(dn) ;
dn_append(oj_dn, dn_cpy(str2dn(objectname))) ;
}
}
save_dn = dn_cpy(dn) ;
dn_free(dn) ;
dn = dn_cpy(aoj_dn) ;
if (!test_move_dn())
{
ps_print(OPT, "Can't move to ") ;
dn_print(OPT, dn, EDBOUT) ;
ps_print(OPT, ".\nAborting.\n") ;
return ;
}
compare_arg.cma_object = aoj_dn;
if (get_ava (&compare_arg.cma_purported, "objectClass", "alias") != OK)
{
ps_print(OPT, "Oops, 'objectClass=alias' is a bad attribute!\n") ;
ps_print(OPT, "This is very bad...\n") ;
return ;
}
if (rebind () != OK)
return ;
while (ds_compare (&compare_arg, &compare_error, &compare_result) != DS_OK)
{
if (dish_error (OPT, &compare_error) == 0)
{
return ;
}
compare_arg.cma_object = compare_error.ERR_REFERRAL.DSE_ref_candidates->cr_name;
}
if ( compare_result.cmr_matched == 1 ) /* if <AOJ> is an alias, abort. */
{
ps_printf(OPT, "Sorry, %s is an alias.\nAliasing to aliases is illegal.\n", aliasobjectname) ;
return ;
}
/* Now we want to discover the objectClass of our object, and make
* sure that this will be OK when we add in the alias. (ie fitting
* in with the treeStructure.)
*/
/* stick the aliasobjectname into the cache so we can read
* bits of information from it.
*/
call_showentry(6, contact_showentry) ;
contact_showentry[5] = (char *) malloc ((unsigned)strlen(argv[2])) ;
(void)strcpy(contact_showentry[5], argv[2]) ;
if (current_entry == NULLENTRY)
{
ps_print(OPT, "Can't read ") ;
dn_print(OPT, dn, EDBOUT) ;
ps_print(OPT, " for objectClass attribute. Aborting.\n") ;
return ;
}
else
{
/* Find the objectClass attribute to compare with the tree
* structure of the node we are going to dangle the alias
* from.
* While we are at it, find out how many seeAlso attributes
* are present, so we can decide whether we need to add
* the entire attribute or just another value.
*/
Attr_Sequence eptr ;
AttributeType a_t = AttrT_new("objectClass") ;
AttributeType a_t2 = AttrT_new("seeAlso") ;
emnew->em_type = EM_ADDATTRIBUTE ;
for (eptr = current_entry->e_attributes; eptr != NULLATTR; eptr = eptr->attr_link)
{
if ( AttrT_cmp (eptr->attr_type, a_t) == 0 )
{
objClassAVS = avs_cpy(eptr->attr_value);
}
if ( AttrT_cmp (eptr->attr_type, a_t2) == 0 )
{
emnew->em_type = EM_ADDVALUES ;
}
}
}
if (objClassAVS == NULLAV)
{
ps_print(OPT, "We can't find Object Class.... Aborting.\n") ;
return ;
}
/* We should have got the ObjectClass now, so return to where we were
* and move up a level to grab the tree structure */
dn_free(dn) ;
dn = dn_cpy(oj_dn) ;
for (dnptr = dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent)
trail = dnptr;
dn_comp_free (dnptr);
trail->dn_parent = NULLDN;
contact_showentry[1] = ( char *) malloc ((unsigned)strlen("-noshow") + 1) ;
(void)strcpy(contact_showentry[1], "-noshow") ;
contact_showentry[2] = ( char *) malloc ((unsigned)strlen("-all") + 1) ;
(void)strcpy(contact_showentry[2], "-all") ;
contact_showentry[3] = ( char *) malloc ((unsigned)strlen("-nokey") + 1) ;
(void)strcpy(contact_showentry[3], "-nokey") ;
contact_showentry[4] = ( char *) malloc ((unsigned)strlen("-dontdereferencealias") + 1) ;
(void)strcpy(contact_showentry[4], "-dontdereferencealias") ;
call_showentry(5, contact_showentry) ;
if (current_entry == NULLENTRY)
{
ps_print(OPT, "Can't read ") ;
dn_print(OPT, dn, EDBOUT) ;
ps_print(OPT, " for the treeStructure. Aborting.\n") ;
return ;
}
else
{
Attr_Sequence eptr ;
AttributeType a_t = AttrT_new("treeStructure") ;
for (eptr = current_entry->e_attributes; eptr != NULLATTR; eptr = eptr->attr_link)
{
if ( AttrT_cmp (eptr->attr_type, a_t) == 0 )
{
treeStrAVS = avs_cpy (eptr->attr_value) ;
}
}
}
if (treeStrAVS == NULLAV)
{
ps_print(OPT, "Tree Structure Missing in ") ;
dn_print(OPT, dn, EDBOUT) ;
ps_print(OPT, ".\nAssuming that the add will be valid.\n") ;
}
else
{
if (test_schema(treeStrAVS, objClassAVS) != OK)
{
ps_print(OPT, "Not allowed to add this alias here.\n") ;
ps_print(OPT, "It would break the directory schema to add this alias here.\n") ;
return ;
}
}
/* This is where we have to start being rather careful, previously
* we have just being reading and checking, but now we start to add
* things in, changing in several places. Mistakes => inconsistencies
* ie BAD...
*/
/* If we reach here, we should have the appropriate arguments,
* one is the new object,
* the other is an existing non-alias-entry object.
* We now write the information to a draft file, and 'whongo'
* the alias into the database.
*/
/* open the draft file for writing... */
if ((fd = fopen (fname, "w")) == (FILE *) NULL)
{
ps_printf (OPT, "Can't open draft entry %s\n", fname);
return ;
}
(void)fprintf(fd, "aliasedObjectName= ") ;
if ( ((tmp = ps_alloc (std_open)) != NULLPS) &&
(std_setup (tmp, fd) != NOTOK) )
{
dn_print(tmp, aoj_dn, EDBOUT) ;
}
else
{
ps_print(OPT, "Unable to open appropriate ps. Aborting..\n") ;
return ;
}
(void)fprintf(fd, "\nobjectClass= quipuObject & alias & top\n") ;
(void) fclose(fd) ;
if (move (objectname) != OK)
{
ps_printf (OPT,"Unknown option %s\n",objectname);
return ;
}
/* now parse the files */
if ((fd = fopen (fname, "r")) == (FILE *) NULL) {
ps_printf (OPT, "Can't open draft entry %s\n", fname);
return ;
}
entry_ptr = get_default_entry (NULLENTRY);
entry_ptr->e_attributes = get_attributes (fd);
(void) fclose (fd);
if (parse_status != 0)
return ;
add_arg.ada_object = dn;
for (moddn = dn ; moddn->dn_parent != NULLDN; moddn=moddn->dn_parent)
;
entry_ptr->e_name = rdn_cpy (moddn->dn_rdn);
add_arg.ada_entry = entry_ptr->e_attributes;
if (rebind () != OK) {
entry_free (entry_ptr);
return ;
}
while (ds_addentry (&add_arg, &error) != DS_OK) {
if (dish_error (OPT, &error) == 0) {
entry_free (entry_ptr);
return ;
}
add_arg.ada_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name;
}
ps_print (RPS, "Added ");
dn_print (RPS, dn, EDBOUT);
ps_print (RPS, "\n");
entry_free (entry_ptr);
make_old (fname,draft_flag);
/* Now we have to add a "seeAlso=<DN>" attribute to the <AOJ> */
if (service_control(OPT, 1, contact_modify, &mod_arg.mea_common) == -1)
{
ps_printf(OPT, "Add_alias: Badly wrong. Service controls for modify in error...\n") ;
return ;
}
dn_free(dn) ;
dn = dn_cpy(save_dn) ;
{
AV_Sequence new_avs = avs_comp_alloc() ;
AttributeValue new_AV = AttrV_alloc() ;
if ((str_ps = ps_alloc(str_open)) == NULLPS)
{
ps_printf(OPT, "Ps alloc for your string failed.\n") ;
return ;
}
if (str_setup (str_ps, str_buffer, 998, 1) == NOTOK)
{
ps_printf (OPT, "str_setup: %s", ps_error (str_ps -> ps_errno));
ps_free (str_ps);
return ;
}
dn_print(str_ps, oj_dn, EDBOUT) ;
*str_ps->ps_ptr = 0 ;
ps_free(str_ps) ;
new_AV = AttrV_cpy(str2AttrV(str_buffer, str2syntax("DN"))) ;
new_avs = avs_comp_new(AttrV_cpy(new_AV)) ;
emnew->em_what = as_comp_new(AttrT_new("seeAlso"), new_avs, NULLACL_INFO) ;
}
emnew->em_next = NULLMOD ;
mod_arg.mea_object = aoj_dn;
mod_arg.mea_changes = emnew ;
if (rebind () != OK)
return ;
/*
* If this operation is time-stamped, it may have expired while the user
* was editing the entry. Re-calculate the time-stamp. Modify is the only
* dish command where this needs to be done.
*/
if ((mod_arg.mea_common.ca_security != (struct security_parms *) 0)
&& (mod_arg.mea_common.ca_security->sp_time != NULLCP))
{
char *new_version();
free(mod_arg.mea_common.ca_security->sp_time);
mod_arg.mea_common.ca_security->sp_time = new_version();
}
/* If security parameters are present, take this to mean that strong
* authentication is required. This disallows 'parms + no signature'
* (pointless) and 'signature + no parms' (security risk).
*/
if (mod_arg.mea_common.ca_security != (struct security_parms *) 0)
{
int encode_DAS_ModifyEntryArgumentData();
struct signature *sign_operation();
mod_arg.mea_common.ca_sig =
sign_operation((caddr_t)&mod_arg,
encode_DAS_ModifyEntryArgumentData);
}
while (ds_modifyentry (&mod_arg, &mod_error) != DS_OK)
{
if (dish_error (OPT, &mod_error) == 0)
{
ps_print(OPT, "Unable to modify ") ;
dn_print(OPT, aoj_dn, EDBOUT) ;
ps_print(OPT, "\n") ;
return ;
}
mod_arg.mea_object = mod_error.ERR_REFERRAL.DSE_ref_candidates->cr_name;
}
ps_print (RPS, "Modified ");
dn_print (RPS, aoj_dn, EDBOUT);
ps_print (RPS, "\n");
delete_cache (aoj_dn); /* re-cache when next read */
dn_free(dn) ;
dn = dn_cpy(save_dn) ;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.