|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T q
Length: 18155 (0x46eb)
Types: TextFile
Names: »quipurc.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/others/quipu/uips/dish/quipurc.c«
/* A 'C' version of the shellscript dishinit
* By Steve Titcombe
*
* Most of this has fixed calls to other functions, and will require going
* through again to strip out all unnecessary error trapping, etc.
* (Utterly Horrible Hack.)
*/
#ifndef lint
static char *rcsid = "$Header: /f/osi/others/quipu/uips/dish/RCS/quipurc.c,v 7.1 89/12/19 16:21:22 mrose Exp $";
#endif
/*
* 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 <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <pwd.h>
#include "quipu/read.h"
#include "quipu/sequence.h"
#include "quipu/name.h"
#include "quipu/bind.h"
#include "quipu/dsp.h"
#include "quipu/ds_error.h"
#include "tailor.h"
#include "quipu/util.h"
#include "quipu/dua.h"
#include "quipu/ds_search.h"
#include "quipu/list.h"
#include "quipu/entry.h"
#include "quipu/modify.h"
#define ORG_PERSON "thornPerson & quipuObject"
/* this should probably go elsewhere !!! */
LLog *log_dua;
DN sequence_dn() ;
DN dn, moddn ;
DN fixed_pos = NULLDN ;
PS opt;
PS rps;
PS fileps ;
FILE *fp_quipurc ;
FILE *fp_draft ;
FILE *fp_tailor ;
Filter get_filter ();
struct entrymod *ems_append() ;
struct entrymod *modify_avs() ;
static struct ds_bind_arg bindarg ;
static struct ds_bind_arg bindresult ;
static struct ds_bind_error binderr ;
struct ds_read_arg read_arg;
struct DSError read_error;
struct ds_read_result read_result;
struct ds_modifyentry_arg mod_arg ;
struct DSError mod_error ;
struct DSError search_error;
struct ds_search_result search_result;
static struct ds_search_arg search_arg =
{
default_common_args,
NULLDN,
SRA_ONELEVEL,
NULLFILTER, /* filter */
FALSE,
{ /* eis */
FALSE,
NULLATTR,
EIS_ATTRIBUTESANDVALUES
}
};
static struct dua_sequence *current_sequence = NULL_DS;
struct entrymod *emnew ;
AV_Sequence avst = NULLAV ;
Attr_Sequence as_flag = NULLATTR ;
Attr_Sequence trail = NULLATTR ;
Attr_Sequence eptr ;
Attr_Sequence temp ;
Attr_Sequence as ;
AttributeType at;
extern Attr_Sequence get_attributes() ;
extern char *TidyString() ;
Entry current_entry ;
Entry entry_ptr ;
char Manager[LINESIZE] ;
char Password[LINESIZE] ;
char Local[LINESIZE] ;
char filterstring[LINESIZE] ;
main()
{
struct passwd *pw_entry ;
struct passwd *getpwuid() ;
struct stat buf ;
int i = 1 ;
int uid ;
int um ;
char pass1[LINESIZE] ;
char pass2[LINESIZE] ;
char Read_in_Stuff[LINESIZE] ;
char **vecptr ;
char *tmpdraft ;
char home_dir[LINESIZE] ;
char *p, *part1, *part2 ;
char quipurc_file[100] ;
char tailor_file[100] ;
char user_name[9] ;
char *localptr = Local ;
char print_format = EDBOUT ;
EntryInfo *ptr ;
static CommonArgs ca = default_common_args;
vecptr = (char **) malloc(100) ;
vecptr[0] = malloc (LINESIZE) ;
(void) strcpy(vecptr[0], "showentry") ;
(void) strcpy(pass1, "x") ;
(void) strcpy(pass2, "y") ;
tmpdraft = malloc (LINESIZE) ;
(void) strcpy(tmpdraft, "/tmp/dish-") ;
if ((opt = ps_alloc (std_open)) == NULLPS)
fatal (-62, "ps_alloc failed");
if (std_setup (opt, stderr) == NOTOK)
fatal (-63, "std_setup failed");
if ((rps = ps_alloc (std_open)) == NULLPS)
fatal (-64, "ps_alloc 2 failed");
if (std_setup (rps, stdout) == NOTOK)
fatal (-65, "std_setup 2 failed");
(void) strcpy(filterstring, "userid=") ;
/* Sort out files, userids etc. */
uid=getuid() ;
if ((pw_entry=getpwuid(uid)) == 0)
{
ps_printf(rps, "Who are you? (no name for your uid number)\n") ;
exit(1) ;
}
(void) strcpy(user_name, pw_entry->pw_name) ;
(void) strcat(tmpdraft, user_name) ;
if (getenv("HOME") == 0)
{
ps_printf(rps, "No home directory?!!") ;
(void) strcpy(home_dir, pw_entry->pw_dir) ;
}
else
{
(void) strcpy(home_dir, getenv("HOME")) ;
}
(void) strcpy(quipurc_file, home_dir) ;
(void) strcat(quipurc_file, "/.quipurc") ;
(void) strcpy(tailor_file, isodefile ("dishinit", 1));
(void) stat(tailor_file, &buf) ;
(void) seteuid(buf.st_uid) ; /* set effective to enable */
/* us to read protected file */
if ((fp_tailor = fopen(tailor_file, "r")) == 0)
{
ps_print(rps, "Can't open Tailor File. Abort.\n") ;
exit(1) ;
}
while (fgets (Read_in_Stuff, LINESIZE, fp_tailor) != 0)
{
if (!strcmp(Read_in_Stuff, "##Anything after this line is copied into the users ~/.quipurc file\n"))
{
break ;
}
p = SkipSpace (Read_in_Stuff);
if (( *p == '#') || (*p == '\0'))
continue; /* ignore comments and blanks */
part1 = p;
if ((part2 = index (p,':')) == NULLCP) {
ps_printf (opt,"Seperator missing '%s'. Ignoring..\n",p);
}
*part2++ = '\0';
part2 = TidyString (part2);
if (lexequ(part1, "manager") == 0)
{
(void) strcpy(Manager, part2) ;
}
else
if (lexequ(part1, "password") == 0)
{
(void) strcpy(Password, part2) ;
}
else
if (lexequ(part1, "local") == 0)
{
(void) strcpy(Local, part2) ;
}
else
{
ps_printf(rps, "Error in tailor. What's a %s?\n", part1) ;
}
}
(void) setuid(uid) ; /* Restore Userid to original user. */
/* create ~/.quipurc file. NB this does eradicate anything in there.
* (Theoretically nothing.)
*/
um = umask(0177) ;
if ((fp_quipurc = fopen(quipurc_file, "w")) == 0)
{
ps_printf(rps, "Can't open ~/.quipurc. Aborting..\n") ;
exit(1) ;
}
(void) umask(um) ;
if ((fileps = ps_alloc(std_open)) == NULLPS)
{
fatal (-66, "ps_alloc 2 failed");
}
if (std_setup (fileps, fp_quipurc) == NOTOK)
{
fatal (-67, "std_setup 2 failed");
}
/* Sorting out the bind section */
quipu_syntaxes() ; /* set up the needed function pointers */
dsap_init(&i, &vecptr) ;
(void) strcpy(bindarg.dba_passwd, Password) ;
bindarg.dba_version = DBA_VERSION_V1988;
bindarg.dba_passwd_len = strlen(bindarg.dba_passwd) ;
if ((bindarg.dba_dn = str2dn (Manager)) == NULLDN)
{
ps_printf (opt,"Invalid Manager name %s (???!)\n",Manager) ;
exit(1) ;
}
if (ds_bind (&bindarg, &binderr, &bindresult) != OK)
{
ps_printf(rps, "Can't bind as the manager.\n") ;
exit(1);
}
/* Hopefully, should be successfully bound */
/*
* We now call the search stuff with the right bits, to see if we can get a
* match of uid='user_name'. Once there, we echo lots of information from
* their entry out to the .quipurc file.
* Hopefully there should only be one match. This assumes that ALL dir info
* up to date, and that SG do not allow multiple users with the same login.
*/
/* set up the appropriate structures and defaults. */
search_arg.sra_common = ca; /* struct copy */
search_arg.sra_common.ca_servicecontrol.svc_sizelimit = 2 ;
search_arg.sra_eis.eis_allattributes = FALSE ;
search_arg.sra_searchaliases = FALSE;
search_arg.sra_subset = SRA_ONELEVEL;
search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES ;
search_arg.sra_eis.eis_select = NULLATTR ;
search_arg.sra_eis.eis_allattributes = TRUE ;
search_arg.sra_filter = filter_alloc() ;
/* Default filter. */
search_arg.sra_filter->flt_next = NULLFILTER;
search_arg.sra_filter->flt_type = FILTER_ITEM;
search_arg.sra_filter->FUFILT = NULLFILTER;
if (*localptr == '@')
{
localptr++;
}
if ((search_arg.sra_baseobject = str2dn(localptr)) == NULLDN)
{
ps_printf (opt,"Invalid sequence in username %s.\n", localptr);
exit(1) ;
}
(void) strcat(filterstring, user_name) ;
search_arg.sra_filter->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY ;
if ((search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = AttrT_new ("userid")) == NULLAttrT)
{
ps_printf(rps, "Oops, userid is not a valid attr type. ABORT!!\n") ;
exit(1) ;
}
if ((search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = str2AttrV (user_name, search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type->at_table->oa_syntax)) == NULLAttrV)
{
ps_printf(rps, "%s is not a valid attribute value.\n", user_name) ;
}
/* call search */
/* We now ought to be in the right place, and with the search stuff set,
* ready to call search, and receive one (or no) entry back, which then
* gets processed accordingly.
*/
if (ds_search (&search_arg, &search_error, &search_result) != DS_OK)
{
ps_printf(rps, "Search failed...\n") ;
exit (1) ;
/* This is not the same as coming back with */
/* message "search failed to find anything. */
}
/* If the user does not exist in the DIT, print out the limited .quipurc
* and the warning message, and allow the user to play DISH.
*/
if (search_result.CSR_entries == NULLENTRYINFO)
{
ps_printf(opt, "Unfortunately, you seem to have no entry in\n") ;
ps_printf(opt, "the directory. Contact '%s' who should be able to help.\n", Manager) ;
ps_printf(opt, "In the mean time, you can read, but not write.\n") ;
}
else
{
ptr = search_result.CSR_entries ;
(void) as_decode(ptr->ent_attr) ;
(void) dn_decode(ptr->ent_dn) ;
dn = dn_cpy(ptr->ent_dn) ; /* Essence of move user_name. */
/* collect the info and put it into current_entry */
/* Set up the desired attribute type to be read*/
/* from read.c */
if ((at = AttrT_new ("userPassword")) != NULLAttrT)
{
as_flag = as_merge (as_flag, as_comp_new (AttrT_cpy (at), NULLAV, NULLACL_INFO));
}
else
{
ps_printf(rps, "Oops, Serious error. unknown attribute type 'userPassword'.\n") ;
exit(1) ;
}
if ((current_entry = local_find_entry (dn, FALSE)) == NULLENTRY)
{
read_arg.rda_common = ca; /* struct copy */
read_arg.rda_object = dn;
read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
read_arg.rda_eis.eis_allattributes = TRUE ;
read_arg.rda_eis.eis_select = NULLATTR ;
if (ds_read (&read_arg, &read_error, &read_result) != DS_OK)
{
ps_printf(rps, "We even seem to be having problems reading\n" ) ;
ps_printf(rps, "an entry we searched and found!! HELP!!\n") ;
exit(1) ;
}
if (read_result.rdr_entry.ent_attr == NULLATTR)
{
ps_printf(rps, "No attributes present. Even though\n") ;
ps_printf(rps, "we found you by userid attribute!!! HELP!!\n") ;
exit (1) ;
}
cache_entry (&(read_result.rdr_entry), read_arg.rda_eis.eis_allattributes, TRUE) ;
}
if ((current_entry = local_find_entry (dn, FALSE)) == NULLENTRY)
{
ps_printf(rps, "We still have nothing.Even after reading? Abort.\n") ;
exit(1) ;
}
ps_printf(fileps, "username: ") ;
dn_print(fileps, dn, EDBOUT) ;
ps_printf(fileps, "\n") ;
ps_printf(fileps, "me: ") ;
dn_print(fileps, dn, EDBOUT) ;
ps_printf(fileps, "\n") ;
/* now showattribute -nokey to display it. */
ps_printf(fileps, "password: ") ;
for (eptr = current_entry->e_attributes; eptr != NULLATTR;
eptr = eptr->attr_link)
{
/* Tiptoe through the list of types until one matches, and then print value. */
if (AttrT_cmp (&eptr->attr_type, at) == 0)
{
avs_print (fileps, eptr->attr_value,print_format);
break;
}
}
if (eptr == NULLATTR)
{
while( strcmp(pass1, pass2))
{
ps_printf(opt, "You need a password...\n") ;
(void) strcpy(pass1, getpassword("Enter Password: ")) ;
(void) strcpy(pass2, getpassword("Re-enter password: ")) ;
if (strcmp(pass1, pass2))
{
ps_printf(opt, "\nMismatch - Try again.\n") ;
}
}
ps_printf(fileps, "%s\n", pass1) ;
um = umask(0177) ;
if ((fp_draft = fopen(tmpdraft, "w")) == 0)
{
ps_print(rps, "Can't open draft file... Abort.\n") ;
exit(1) ;
}
(void) umask(um) ;
(void) fprintf(fp_draft, "UserPassword = %s\n", pass1) ;
(void) fprintf(fp_draft, "acl = self # write # attributes # acl $ userPassword\n") ;
(void) fprintf(fp_draft, "acl = others # compare # attributes # acl $ userPassword\n\n") ;
(void) fclose(fp_draft) ;
if ((fp_draft = fopen (tmpdraft, "r")) == NULL) {
ps_printf (opt, "Can't open draft entry %s\n", tmpdraft);
exit(1) ;
}
entry_ptr = get_default_entry (NULLENTRY);
entry_ptr->e_attributes = get_attributes (fp_draft);
(void) fclose (fp_draft);
mod_arg.mea_common = ca; /* struct copy */
mod_arg.mea_object = dn;
for (moddn = dn ; moddn->dn_parent != NULLDN; moddn=moddn->dn_parent)
;
entry_ptr->e_name = rdn_cpy (moddn->dn_rdn);
/* add rdn as attribute */
avst = avs_comp_new (AttrV_cpy (&entry_ptr->e_name->rdn_av));
temp = as_comp_new (AttrT_cpy (&entry_ptr->e_name->rdn_at), avst, NULLACL_INFO);
entry_ptr->e_attributes = as_merge (entry_ptr->e_attributes, temp);
for (as = entry_ptr->e_attributes; as != NULLATTR; as = as->attr_link)
{
emnew = NULLMOD;
trail = as->attr_link;
as->attr_link = NULLATTR;
temp = current_entry->e_attributes;
for (; temp != NULLATTR; temp = temp->attr_link)
if (AttrT_cmp (&as->attr_type, &temp->attr_type) == 0)
{
/* found it - does it need changing ? */
if (avs_cmp (as->attr_value, temp->attr_value) != 0)
emnew = modify_avs (as->attr_value, temp->attr_value,&as->attr_type);
break;
}
if (temp == NULLATTR)
{
emnew = em_alloc ();
emnew->em_type = EM_ADDATTRIBUTE;
emnew->em_what = as_cpy(as);
emnew->em_next = NULLMOD;
}
if (emnew != NULLMOD)
{
mod_arg.mea_changes = ems_append (mod_arg.mea_changes,emnew);
}
as->attr_link = trail;
}
while (ds_modifyentry (&mod_arg, &mod_error) != DS_OK)
{
if (dish_error (opt, &mod_error) == 0)
{
ps_printf(rps,"We have a dish error. Bye.\n") ;
entry_free (entry_ptr);
exit(1) ;
}
mod_arg.mea_object = mod_error.ERR_REFERRAL.DSE_ref_candidates->cr_name;
}
ps_print (rps, "Modified ");
dn_print (rps, dn, EDBOUT);
ps_print (rps, "\n");
delete_cache (dn); /* re-cache when next read */
entry_free (entry_ptr);
ems_part_free (mod_arg.mea_changes);
}
}
while(fgets(Read_in_Stuff, LINESIZE, fp_tailor) != 0)
{
fputs(Read_in_Stuff, fp_quipurc) ;
}
(void) fclose(fp_quipurc) ;
(void) fclose(fp_tailor) ;
/* (void) fprintf(fp_quipurc, "dsap: local_dit \"%s\"\n", Local) ;
(void) fprintf(fp_quipurc, "notype: acl\n") ;
(void) fprintf(fp_quipurc, "notype: treestructure\n") ;
(void) fprintf(fp_quipurc, "notype: masterdsa\n") ;
(void) fprintf(fp_quipurc, "notype: slavedsa\n") ;
(void) fprintf(fp_quipurc, "notype: objectclass\n") ;
(void) fprintf(fp_quipurc, "cache_time: 30\n") ;
(void) fprintf(fp_quipurc, "connect_time: 2\n") ;
*/
(void) ds_unbind() ;
(void) unlink(tmpdraft) ;
}
void
advise()
{
}
void
set_sequence()
{
}
void
unset_sequence()
{
}
dish_error (ps,error)
PS ps;
struct DSError * error;
{
char neverefer = TRUE ;
extern int chase_flag;
if (error->dse_type == DSE_ABANDONED) {
ps_printf (ps,"(DAP call interrupted - abandon successful)\n");
return (0);
}
if (error->dse_type == DSE_ABANDON_FAILED) {
ps_printf (ps,"(DAP call interrupted - abandon unsuccessful)\n");
return (0);
}
if (error->dse_type == DSE_INTRERROR) {
ps_printf (ps,"(DAP call interrupted)\n");
return (0);
}
if ((error->dse_type != DSE_REFERRAL)
|| ((chase_flag == 0) && neverefer)
|| (chase_flag == 1)) {
ds_error (ps,error);
return (0);
}
if (error->ERR_REFERRAL.DSE_ref_candidates == NULLCONTINUATIONREF) {
ps_printf (ps,"*** Referral error (but no reference !!!) ***\n");
return (0);
}
/*
for (ap = error->ERR_REFERRAL.DSE_ref_candidates->cr_accesspoints;
ap != NULLACCESSPOINT; ap=ap->ap_next) {
if (chase_flag != 2) {
ps_printf (ps,"Referral to ");
(void) dn_decode (ap->ap_name);
dn_print (ps,ap->ap_name,EDBOUT);
if (yesno (". Chase ? ") == FALSE)
continue;
}
if (referral_bind (ap->ap_address) != 0)
return (1);
ps_printf (ps,"Referral connection failed\n");
if (chase_flag == 2)
break;
/* only try first - otherwise possible looping
}
*/
return (0);
}
DN sequence_dn(y)
int y;
{
struct dua_seq_entry * ptr;
register int x = 1;
if (current_sequence == NULL_DS)
return (NULLDN);
for (ptr=current_sequence->ds_data;
(ptr != NULL_DE) && (x<y);
ptr=ptr->de_next,x++)
;
if (ptr == NULL_DE)
return (NULLDN);
if ( x == y )
return (ptr->de_name);
return (NULLDN);
}
struct entrymod * ems_append (a,b)
struct entrymod *a;
struct entrymod *b;
{
struct entrymod *ptr;
if ((ptr = a) == NULLMOD)
return b;
for ( ; ptr->em_next != NULLMOD; ptr = ptr->em_next)
;
ptr->em_next = b;
return a;
}
struct entrymod * modify_avs (a,b,ent_mod_at)
AV_Sequence a;
AV_Sequence b;
AttributeType ent_mod_at;
{
AV_Sequence x;
AV_Sequence y;
struct entrymod *em = NULLMOD, *em_new;
int removed_all = TRUE;
for (x=b; x != NULLAV; x=x->avseq_next) {
em_new = NULLMOD;
for (y=a; y != NULLAV; y=y->avseq_next)
if (AttrV_cmp (&x->avseq_av,&y->avseq_av) == 0)
break;
if (y == NULLAV) {
em_new = em_alloc ();
em_new->em_type = EM_REMOVEVALUES;
em_new->em_what = as_comp_new (ent_mod_at,avs_comp_new(&x->avseq_av),NULLACL_INFO);
em_new->em_next = NULLMOD;
} else
removed_all = FALSE;
if (em_new != NULLMOD)
em = ems_append (em,em_new);
}
if (removed_all) {
ems_part_free (em);
em_new = em_alloc ();
em_new->em_type = EM_REMOVEATTRIBUTE;
em_new->em_what = as_comp_new (ent_mod_at,b,NULLACL_INFO);
em_new->em_next = em_alloc();
em_new->em_next->em_type = EM_ADDATTRIBUTE;
em_new->em_next->em_what = as_comp_new (ent_mod_at,avs_cpy(a),NULLACL_INFO);
em_new->em_next->em_next = NULLMOD;
return (em_new);
}
for (x=a; x != NULLAV; x=x->avseq_next) {
em_new = NULLMOD;
for (y=b; y != NULLAV; y=y->avseq_next)
if (AttrV_cmp (&x->avseq_av,&y->avseq_av) == 0)
break;
if (y == NULLAV) {
em_new = em_alloc ();
em_new->em_type = EM_ADDVALUES;
em_new->em_what = as_comp_new (ent_mod_at,avs_comp_new(&x->avseq_av),NULLACL_INFO);
em_new->em_next = NULLMOD;
}
if (em_new != NULLMOD)
em = ems_append (em,em_new);
}
return (em);
}
ems_part_free(emp)
struct entrymod *emp;
{
if(emp == NULLMOD)
return;
ems_part_free(emp->em_next);
free((char *)emp);
}