home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Chans / lists / dl_x500.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  16.7 KB  |  756 lines

  1. /* dl_x500.c: */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Chans/lists/RCS/dl_x500.c,v 6.0 1991/12/18 20:10:43 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Chans/lists/RCS/dl_x500.c,v 6.0 1991/12/18 20:10:43 jpo Rel $
  9.  *
  10.  * $Log: dl_x500.c,v $
  11.  * Revision 6.0  1991/12/18  20:10:43  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "dlist.h"
  19. #include <isode/quipu/dua.h>
  20. #include <isode/quipu/read.h>
  21. #include <isode/quipu/modify.h>
  22. #include <isode/quipu/add.h>
  23. #include <isode/quipu/entry.h>
  24. #include <isode/quipu/ds_search.h>
  25. #include <isode/quipu/connection.h>    /* ds_search uses di_block - include this for lint !!! */
  26. #include <isode/quipu/bind.h>
  27.  
  28. extern AttributeType at_Member;
  29. extern AttributeType at_RoleOccupant;
  30. extern AttributeType at_CommonName;
  31. extern AttributeType at_Owner;
  32. extern AttributeType at_Permit;
  33. extern AttributeType at_Policy;
  34. extern AttributeType at_ORAddress;
  35. extern AttributeType at_RFC822;
  36. extern AttributeType at_GroupMember;
  37. extern AttributeType at_ObjectClass;
  38. extern OID role_oc;
  39. extern char * local_dit;
  40.  
  41. extern LLog * log_dsap;
  42.  
  43. extern Filter strfilter(), ocfilter(), joinfilter();
  44. extern Attr_Sequence as_combine();
  45. extern DN dn_append();
  46. extern char * dn2str();
  47.  
  48. static Attr_Sequence mailas = NULLATTR;
  49.  
  50. extern int str2dl ();
  51.  
  52. static int isPermanentError (error)
  53. struct DSError    *error;
  54. {
  55. /* DONE == temporary, NOTOK == permanent */
  56.  
  57.     switch (error -> dse_type) {
  58.         case DSE_REMOTEERROR:
  59.         case DSE_REFERRAL:
  60.         case DSE_ABANDONED:
  61.         return DONE;
  62.         case DSE_SERVICEERROR:
  63.         switch (error -> ERR_SERVICE.DSE_sv_problem) {
  64.             case DSE_SV_BUSY:
  65.             case DSE_SV_TIMELIMITEXCEEDED:
  66.             case DSE_SV_ADMINLIMITEXCEEDED:
  67.             return DONE;
  68.             default:
  69.             return NOTOK;
  70.         }
  71.         default:
  72.         return NOTOK;
  73.     }
  74. }
  75.  
  76. static int ds_cache_read (dn,as, pres) 
  77. DN dn;
  78. Attr_Sequence as;
  79. Attr_Sequence *pres;
  80. {
  81. struct ds_read_arg read_arg;
  82. struct ds_read_result result;
  83. struct DSError  error;
  84. static CommonArgs ca = default_common_args;
  85. Entry ptr;
  86.  
  87.     if ((ptr = local_find_entry (dn,TRUE)) != NULLENTRY) {
  88.         if (ptr->e_complete) {
  89.             *pres = ptr->e_attributes;
  90.             return OK;
  91.         }
  92.         if (as != NULLATTR) {
  93.             Attr_Sequence tmp;
  94.             for (tmp = as; tmp!= NULLATTR; tmp = tmp->attr_link) 
  95.                 if (as_find_type(ptr->e_attributes,tmp->attr_type) == NULLATTR) 
  96.                     goto do_read;
  97.             *pres = ptr->e_attributes;
  98.             return OK;
  99.         }
  100.     }
  101.  
  102. do_read:;
  103.  
  104.     read_arg.rda_common = ca; /* struct copy */
  105.  
  106.     read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
  107.     read_arg.rda_eis.eis_allattributes = FALSE;
  108.     read_arg.rda_eis.eis_select = as;
  109.     read_arg.rda_object = dn;
  110.     
  111.     if (ds_read (&read_arg, &error, &result) != DS_OK) {
  112.         int    resultint = isPermanentError(&error);
  113.         log_ds_error (&error);
  114.         ds_error_free (&error);
  115.         *pres = NULLATTR;
  116.         return resultint;
  117.     }
  118.  
  119.     result.rdr_entry.ent_attr = as_merge (result.rdr_entry.ent_attr,as_cpy(as));
  120.  
  121.     cache_entry (&result.rdr_entry,FALSE,TRUE);
  122.         *pres = result.rdr_entry.ent_attr;
  123.     return OK;
  124. }
  125.  
  126.  
  127. int dn2addr (dn, pres) 
  128. DN dn;
  129. Attr_Sequence    *pres;
  130. {
  131. Attr_Sequence found;
  132. int    result;
  133.  
  134.     if (mailas == NULLATTR) {
  135.         Attr_Sequence as;
  136.         mailas = as_comp_new (at_ORAddress,  NULLAV, NULLACL_INFO);
  137.         as = as_comp_new (at_RFC822,  NULLAV, NULLACL_INFO);
  138.         mailas = as_merge (mailas,as);
  139.         as = as_comp_new (at_ObjectClass,  NULLAV, NULLACL_INFO);
  140.         mailas = as_merge (mailas,as);
  141.         as = as_comp_new (at_RoleOccupant,  NULLAV, NULLACL_INFO);
  142.         mailas = as_merge (mailas,as);
  143.     }
  144.  
  145.     if ((result = ds_cache_read (dn,mailas, pres)) != OK)
  146.         return result;
  147.  
  148.     /* Have we got an address ? */
  149.     if ((found = as_find_type (*pres,at_ORAddress)) != NULLATTR) 
  150.         return OK;
  151.  
  152.     if ((found = as_find_type (*pres,at_RFC822)) != NULLATTR) 
  153.         return OK;
  154.  
  155.     /* NO address, is it a role ? */
  156.     if ((found = as_find_type (*pres,at_ObjectClass)) == NULLATTR) 
  157.         return NOTOK;
  158.  
  159.     if (check_in_oc(role_oc,found->attr_value)) {
  160.         /* Its a role :- follow member... */
  161.         if ((found = as_find_type (*pres,at_RoleOccupant)) == NULLATTR) 
  162.             return NOTOK;
  163.  
  164.         return dn2addr ((DN)&found->attr_value->avseq_av, pres);
  165.     }
  166.  
  167.     return OK;
  168.     
  169. }
  170.  
  171.  
  172. int dir_getdl_aux (dn, pres)
  173. DN dn;
  174. Attr_Sequence    *pres;
  175. {
  176. static Attr_Sequence astop = NULLATTR;
  177. int    result;
  178.  
  179.     if (astop == NULLATTR) {
  180.         Attr_Sequence as;
  181.         astop = as_comp_new (at_Member,  NULLAV, NULLACL_INFO);
  182.         as = as_comp_new (at_Owner,  NULLAV, NULLACL_INFO);
  183.         astop = as_merge (astop,as);
  184.         as = as_comp_new (at_Permit,  NULLAV, NULLACL_INFO);
  185.         astop = as_merge (astop,as);
  186.         as = as_comp_new (at_Policy,  NULLAV, NULLACL_INFO);
  187.         astop = as_merge (astop,as);
  188. /*
  189.         as = as_comp_new (acl_at,  NULLAV, NULLACL_INFO);
  190.         astop = as_merge (astop,as);
  191. */
  192.     }
  193.     result = ds_cache_read (dn,astop,pres);
  194.     return result;
  195. }
  196.  
  197. int dir_getdl (list, pas)
  198. char * list;
  199. Attr_Sequence *pas;
  200. {
  201.     DN dn;
  202.     int    result;
  203.     static  DN localdn = NULLDN;
  204.  
  205.     if ((localdn == NULLDN) && local_dit)
  206.         localdn = str2dn (local_dit);
  207.  
  208.     if ((result = str2dl(list,localdn,&dn)) != OK) 
  209.         return result;
  210.  
  211.     result = dir_getdl_aux (dn, pas);
  212.     dn_free (dn);
  213.  
  214.     return result;
  215.  
  216. int read_group_entry (dn, pres)
  217. DN dn;
  218. Attr_Sequence    *pres;
  219. {
  220. static Attr_Sequence astop = NULLATTR;
  221.  
  222.     if (astop == NULLATTR) 
  223.         astop = as_comp_new (at_GroupMember,  NULLAV, NULLACL_INFO);
  224.  
  225.     return (ds_cache_read (dn,astop, pres));
  226. }
  227.  
  228.  
  229. or_modify (ps,old,newname,at,dn) 
  230. PS ps;
  231. ORName * old;
  232. OR_ptr newname;
  233. AttributeType at;
  234. DN dn;
  235. {
  236. struct ds_modifyentry_arg mod_arg;
  237. struct DSError  error;
  238. static CommonArgs ca = default_common_args;
  239. struct entrymod *emnew;
  240. AttributeValue av;
  241. AV_Sequence avs;
  242. ORName * newor;
  243. ORName * orName_cpy();
  244. OR_ptr or_cpy();
  245.  
  246.     mod_arg.mea_common = ca;
  247.     mod_arg.mea_object = dn;
  248.  
  249.     emnew = em_alloc ();
  250.     emnew->em_type = EM_ADDVALUES;
  251.     av = AttrV_alloc();
  252.     av->av_syntax = str2syntax("ORName");
  253.     newor = orName_cpy (old);
  254.     if (newor->on_or != NULLOR)
  255.         or_free (newor->on_or);
  256.     newor->on_or = or_cpy(newname);
  257.     av->av_struct = (caddr_t) newor;
  258.     avs = avs_comp_new(av);
  259.     emnew->em_what = as_comp_new (AttrT_cpy(at),avs,NULLACL_INFO);
  260.  
  261.     mod_arg.mea_changes = emnew;
  262.  
  263.      emnew = em_alloc ();
  264.     emnew->em_type = EM_REMOVEVALUES;
  265.     av = AttrV_alloc();
  266.     av->av_syntax = str2syntax("ORName");
  267.     av->av_struct = (caddr_t) orName_cpy(old);
  268.     avs = avs_comp_new(av);
  269.     emnew->em_what = as_comp_new (AttrT_cpy(at),avs,NULLACL_INFO);
  270.     emnew->em_next = NULLMOD;
  271.  
  272.     mod_arg.mea_changes->em_next = emnew;
  273.  
  274.     if (ds_modifyentry (&mod_arg, &error) != DS_OK) {
  275.         ds_error (ps, &error);
  276.         return FALSE;
  277.     }
  278.     delete_cache (old->on_dn);
  279.  
  280.     ems_free (mod_arg.mea_changes);
  281.  
  282.     return TRUE;
  283. }
  284.  
  285. dl_modify (ps,name,dn,delete) 
  286. PS ps;
  287. ORName * name;
  288. DN dn;
  289. char delete;
  290. {
  291. struct ds_modifyentry_arg mod_arg;
  292. struct DSError  error;
  293. static CommonArgs ca = default_common_args;
  294. struct entrymod *emnew;
  295. AttributeValue av;
  296. AV_Sequence avs;
  297.  
  298.     mod_arg.mea_common = ca;
  299.     mod_arg.mea_object = dn;
  300.  
  301.     emnew = em_alloc ();
  302.     if (delete)
  303.         emnew->em_type = EM_REMOVEVALUES;
  304.     else
  305.         emnew->em_type = EM_ADDVALUES;
  306.     av = AttrV_alloc();
  307.     av->av_syntax = str2syntax("ORName");
  308.     av->av_struct = (caddr_t) name;
  309.     avs = avs_comp_new(av);
  310.     emnew->em_what = as_comp_new (AttrT_cpy(at_Member),avs,NULLACL_INFO);
  311.     emnew->em_next = NULLMOD;
  312.  
  313.     mod_arg.mea_changes = emnew;
  314.  
  315.     if (ds_modifyentry (&mod_arg, &error) != DS_OK) {
  316.         ds_error (ps, &error);
  317.         return FALSE;
  318.     }
  319.     delete_cache (dn);
  320.     ems_free (mod_arg.mea_changes);
  321.  
  322.     return TRUE;
  323. }
  324.  
  325. dl_modify_attr (ps,oldas,newas,dl,quiet) 
  326. PS ps;
  327. Attr_Sequence oldas,newas;
  328. DN dl;
  329. char quiet;
  330. {
  331. struct ds_modifyentry_arg mod_arg;
  332. struct DSError  error;
  333. static CommonArgs ca = default_common_args;
  334. struct entrymod *emnew;
  335.  
  336.     mod_arg.mea_common = ca;
  337.     mod_arg.mea_object = dl;
  338.  
  339.     if ((! oldas) || (oldas->attr_value == NULLAV)) {
  340.         emnew = em_alloc ();
  341.         emnew->em_type = EM_ADDATTRIBUTE;
  342.         emnew->em_what = as_comp_cpy (newas);
  343.            } else {
  344.         emnew = em_alloc ();
  345.         emnew->em_type = EM_REMOVEATTRIBUTE;
  346.         emnew->em_what = as_comp_cpy (oldas);
  347.         emnew->em_next = em_alloc();
  348.         emnew->em_next->em_type = EM_ADDATTRIBUTE;
  349.         emnew->em_next->em_what = as_comp_cpy (newas);
  350.            }
  351.  
  352.     emnew->em_next->em_next = NULLMOD;
  353.  
  354.     mod_arg.mea_changes = emnew;
  355.  
  356.     if (!quiet) {
  357.         ps_print (ps, "modifying...");
  358.         ps_flush (ps);
  359.     }
  360.  
  361.     if (ds_modifyentry (&mod_arg, &error) != DS_OK) {
  362.         ds_error (ps, &error);
  363.         return FALSE;
  364.     }
  365.  
  366.     if (!quiet) {
  367.         ps_print (ps, "OK\n");
  368.         ps_flush (ps);
  369.     }
  370.  
  371.     delete_cache (dl);
  372.     ems_free (mod_arg.mea_changes);
  373.  
  374.     return TRUE;
  375. }
  376.  
  377. dl_modify_owner (ps,olddn,newdn,dl,quiet) 
  378. PS ps;
  379. DN olddn,newdn;
  380. DN dl;
  381. char quiet;
  382. {
  383. struct ds_modifyentry_arg mod_arg;
  384. struct DSError  error;
  385. static CommonArgs ca = default_common_args;
  386. struct entrymod *emnew;
  387. AttributeValue av;
  388. AV_Sequence avs;
  389.  
  390.     mod_arg.mea_common = ca;
  391.     mod_arg.mea_object = dl;
  392.  
  393.     emnew = em_alloc ();
  394.     emnew->em_type = EM_REMOVEATTRIBUTE;
  395.     av = AttrV_alloc();
  396.     av->av_syntax = str2syntax("DN");
  397.     av->av_struct = (caddr_t) dn_cpy(olddn);
  398.     avs = avs_comp_new(av);
  399.     emnew->em_what = as_comp_new (AttrT_cpy(at_Owner),avs,NULLACL_INFO);
  400.  
  401.     emnew->em_next = em_alloc();
  402.     emnew->em_next->em_type = EM_ADDATTRIBUTE;
  403.     av = AttrV_alloc();
  404.     av->av_syntax = str2syntax("DN");
  405.     av->av_struct = (caddr_t) dn_cpy(newdn);
  406.     avs = avs_comp_new(av);
  407.     emnew->em_next->em_what = as_comp_new (AttrT_cpy(at_Owner),avs,NULLACL_INFO);
  408.     emnew->em_next->em_next = NULLMOD;
  409.  
  410.     mod_arg.mea_changes = emnew;
  411.  
  412.     if (!quiet) {
  413.         ps_print (ps, "modifying...");
  414.         ps_flush (ps);
  415.     }
  416.  
  417.     if (ds_modifyentry (&mod_arg, &error) != DS_OK) {
  418.         ds_error (ps, &error);
  419.         return FALSE;
  420.     }
  421.  
  422.     if (!quiet) {
  423.         ps_print (ps, "OK\n");
  424.         ps_flush (ps);
  425.     }
  426.  
  427.     delete_cache (dl);
  428.     ems_free (mod_arg.mea_changes);
  429.  
  430.     return TRUE;
  431. }
  432.  
  433. dl_bind (name,passwd)
  434. DN name;
  435. char * passwd;
  436. {
  437.   struct ds_bind_arg bindarg;
  438.   struct ds_bind_arg bindresult;
  439.   struct ds_bind_error binderr;
  440.  
  441.   bindarg.dba_version = DBA_VERSION_V1988;
  442.  
  443.   bindarg.dba_passwd_len = 0;
  444.   bindarg.dba_passwd [0] = '\0';
  445.  
  446.   if ((bindarg.dba_dn = name) != NULLDN) {
  447.     if (passwd) {
  448.         bindarg.dba_passwd_len = strlen (passwd);
  449.         (void) strcpy (bindarg.dba_passwd,passwd);
  450.         }
  451.   }
  452.  
  453.   if (ds_bind (&bindarg,&binderr,&bindresult) != DS_OK)
  454.         return NOTOK;
  455.   else
  456.     return OK;
  457. }
  458.  
  459.  
  460. dl_unbind ()
  461. {
  462.     (void) ds_unbind ();
  463. }
  464.  
  465.  
  466. str2dl (str,localdn,res)
  467. char * str;
  468. DN localdn;
  469. DN * res;
  470. {
  471. extern int print_parse_errors;
  472. int old;
  473. struct ds_search_arg search_arg;
  474. static struct ds_search_result result;
  475. struct DSError err;
  476. static CommonArgs ca = default_common_args;
  477. Filter filtcn, filtoc, filtand;
  478.  
  479.     old = print_parse_errors;
  480.     print_parse_errors = FALSE;
  481.     *res = str2dn (str);
  482.     print_parse_errors = old;
  483.  
  484.     if (*res != NULLDN)
  485.         return OK;
  486.  
  487.     filtcn = strfilter (at_CommonName,str,FILTERITEM_EQUALITY);
  488.     if ((filtoc = ocfilter ("ppDistributionList")) == NULLFILTER)
  489.         return NOTOK;
  490.  
  491.     filtoc->flt_next = filtcn;
  492.     filtand = joinfilter (filtoc,FILTER_AND);
  493.  
  494.     search_arg.sra_baseobject = localdn;
  495.     search_arg.sra_filter = filtand;
  496.     search_arg.sra_subset = SRA_ONELEVEL;
  497.     search_arg.sra_searchaliases = FALSE;
  498.     search_arg.sra_common = ca; /* struct copy */
  499.     search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
  500.     search_arg.sra_eis.eis_allattributes = FALSE;
  501.     search_arg.sra_eis.eis_select = NULLATTR;
  502.  
  503.     if (ds_search (&search_arg, &err, &result) != DS_OK) {
  504.         int    resultint = isPermanentError(&err);
  505.         filter_free (filtoc);
  506.         log_ds_error (&err);
  507.         ds_error_free (&err);
  508.         return resultint;
  509.     }
  510.     filter_free (filtoc);
  511.  
  512.     if (result.CSR_entries) {
  513.         if (*res = result.CSR_entries->ent_dn) /* assign */
  514.             return OK;
  515.     } 
  516.  
  517.     return NOTOK;
  518.     
  519. }
  520.  
  521.  
  522. DN search_postmaster (localdn)
  523. DN localdn;
  524. {
  525. struct ds_search_arg search_arg;
  526. static struct ds_search_result result;
  527. struct DSError err;
  528. static CommonArgs ca = default_common_args;
  529. Filter filtcn;
  530.  
  531.     if (mailas == NULLATTR) {
  532.         Attr_Sequence as;
  533.         mailas = as_comp_new (at_ORAddress,  NULLAV, NULLACL_INFO);
  534.         as = as_comp_new (at_RFC822,  NULLAV, NULLACL_INFO);
  535.         mailas = as_merge (mailas,as);
  536.         as = as_comp_new (at_ObjectClass,  NULLAV, NULLACL_INFO);
  537.         mailas = as_merge (mailas,as);
  538.         as = as_comp_new (at_RoleOccupant,  NULLAV, NULLACL_INFO);
  539.         mailas = as_merge (mailas,as);
  540.     }
  541.  
  542.     filtcn = strfilter (at_CommonName,"PostMaster",FILTERITEM_EQUALITY);
  543.  
  544.     search_arg.sra_baseobject = localdn;
  545.     search_arg.sra_filter = filtcn;
  546.     search_arg.sra_subset = SRA_ONELEVEL;
  547.     search_arg.sra_searchaliases = TRUE;
  548.     search_arg.sra_common = ca; /* struct copy */
  549.     search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
  550.     search_arg.sra_eis.eis_allattributes = FALSE;
  551.     search_arg.sra_eis.eis_select = mailas;
  552.  
  553.     if (ds_search (&search_arg, &err, &result) != DS_OK) {
  554.         filter_free (filtcn);
  555.         log_ds_error (&err);
  556.         ds_error_free (&err);
  557.         return NULLDN;
  558.     }
  559.     filter_free (filtcn);
  560.  
  561.     if (result.CSR_entries) {
  562.         cache_entry (result.CSR_entries,FALSE,TRUE);
  563.         return (result.CSR_entries->ent_dn);
  564.     } 
  565.  
  566.     return NULLDN;
  567. }
  568.     
  569. dl_showentry(ps,dn)
  570. PS ps;
  571. DN dn;
  572. {
  573. struct ds_read_arg read_arg;
  574. struct ds_read_result result;
  575. struct DSError  error;
  576. static CommonArgs ca = default_common_args;
  577. Entry ptr;
  578.  
  579.     if ((ptr = local_find_entry (dn,TRUE)) != NULLENTRY) 
  580.         if (ptr->e_complete) {
  581.             as_print (ps,ptr->e_attributes,READOUT);
  582.             return;
  583.         }
  584.  
  585.     read_arg.rda_common = ca; /* struct copy */
  586.  
  587.     read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
  588.     read_arg.rda_eis.eis_allattributes = TRUE;
  589.     read_arg.rda_eis.eis_select = NULLATTR;
  590.     read_arg.rda_object = dn;
  591.     
  592.     if (ds_read (&read_arg, &error, &result) != DS_OK) 
  593.         ds_error(ps,&error);
  594.  
  595.     cache_entry (&result.rdr_entry,FALSE,TRUE);
  596.  
  597.     as_print (ps,result.rdr_entry.ent_attr,READOUT);
  598. }
  599.  
  600. add_list_request (ps,where, listname, owner)
  601. PS ps;
  602. DN where;
  603. char * listname;
  604. DN owner;
  605. {
  606. struct ds_addentry_arg add_arg;
  607. struct DSError  error;
  608. Attr_Sequence as,nas;
  609. char buffer [LINESIZE];
  610. DN obj;
  611. DN dnc;
  612. static CommonArgs ca = default_common_args;
  613.  
  614.     add_arg.ada_common = ca; /* struct copy */
  615.  
  616.     (void) sprintf (buffer, "cn=%s-request",listname);
  617.     if ((as = str2as (buffer)) == NULLATTR)
  618.         return FALSE;
  619.     if ((dnc = str2dn (buffer)) == NULLDN)
  620.         return FALSE;
  621.  
  622.     (void) sprintf (buffer, "ObjectClass=ppRole&quipuobject");
  623.     if ((nas = str2as (buffer)) == NULLATTR)
  624.         return FALSE;
  625.     as = as_merge (as,nas);
  626.  
  627.     (void) sprintf (buffer, "roleOccupant=%s",dn2str(owner));
  628.     if ((nas = str2as (buffer)) == NULLATTR)
  629.         return FALSE;
  630.     as = as_merge (as,nas);
  631.  
  632.     (void) sprintf (buffer, "mhsORAddresses=%s-request",listname);
  633.     if ((nas = str2as (buffer)) == NULLATTR)
  634.         return FALSE;
  635.     as = as_merge (as,nas);
  636.  
  637.     (void) sprintf (buffer, 
  638.          "acl=others # read # entry & others # read # default & group #");
  639.     strcat (buffer, dn2str(owner));
  640.     strcat (buffer, "# write # entry & group #");
  641.     strcat (buffer, dn2str(owner));
  642.     strcat (buffer, "# write # default");
  643.     if ((nas = str2as (buffer)) == NULLATTR)
  644.         return FALSE;
  645.     as = as_merge (as,nas);
  646.  
  647.     obj = dn_cpy (where);
  648.     dn_append (obj,dn_cpy(dnc));
  649.     add_arg.ada_object = obj;
  650.     add_arg.ada_entry = as;
  651.  
  652.     if (ds_addentry (&add_arg, &error) != DS_OK) {
  653.         ds_error (ps,&error);
  654.         dn_free (obj);
  655.         as_free (as);
  656.         return FALSE;
  657.     }
  658.  
  659.     dn_free (obj);
  660.     as_free (as);
  661.  
  662.     return TRUE;
  663. }
  664.  
  665. add_new_list (ps, where,listname, owner, description,members)
  666. PS ps;
  667. DN where;
  668. char * listname;
  669. DN owner;
  670. char *description;
  671. Attr_Sequence members;
  672. {
  673. struct ds_addentry_arg add_arg;
  674. struct DSError  error;
  675. Attr_Sequence as,nas;
  676. char buffer [LINESIZE];
  677. DN obj;
  678. DN dnc;
  679. static CommonArgs ca = default_common_args;
  680.  
  681.     add_arg.ada_common = ca; /* struct copy */
  682.  
  683.     (void) sprintf (buffer, "cn=%s",listname);
  684.     if ((as = str2as (buffer)) == NULLATTR)
  685.         return FALSE;
  686.     if ((dnc = str2dn (buffer)) == NULLDN)
  687.         return FALSE;
  688.  
  689.     (void) sprintf (buffer, "ObjectClass=ppDistributionList&quipuobject");
  690.     if ((nas = str2as (buffer)) == NULLATTR)
  691.         return FALSE;
  692.     as = as_merge (as,nas);
  693.  
  694.     (void) sprintf (buffer, "owner=%s@cn=%s-request",dn2str(where),listname);
  695.     if ((nas = str2as (buffer)) == NULLATTR)
  696.         return FALSE;
  697.     as = as_merge (as,nas);
  698.  
  699.     if (members) 
  700.         as = as_merge (as,members);
  701.     else {
  702.         (void) sprintf (buffer, "mhsDLmembers=%s",dn2str(owner));
  703.         if ((nas = str2as (buffer)) == NULLATTR)
  704.             return FALSE;
  705.         as = as_merge (as,nas);
  706.         }
  707.  
  708.     if (description && *description != 0) {
  709.         (void) sprintf (buffer, "description=%s",description);
  710.         if ((nas = str2as (buffer)) == NULLATTR)
  711.             return FALSE;
  712.         as = as_merge (as,nas);
  713.     }
  714.  
  715.     (void) sprintf (buffer, "mhsDLSubmitPermissions=ALL");
  716.     if ((nas = str2as (buffer)) == NULLATTR)
  717.         return FALSE;
  718.     as = as_merge (as,nas);
  719.  
  720.     (void) sprintf (buffer, 
  721.          "acl=others # read # entry & others # read # default & group #");
  722.     strcat (buffer, dn2str(owner));
  723.     strcat (buffer, "# write # entry & group #");
  724.     strcat (buffer, dn2str(owner));
  725.     strcat (buffer, "# write # default");
  726.     if ((nas = str2as (buffer)) == NULLATTR)
  727.         return FALSE;
  728.     as = as_merge (as,nas);
  729.  
  730.     (void) sprintf (buffer, "mhsORAddresses=%s",listname);
  731.     if ((nas = str2as (buffer)) == NULLATTR)
  732.         return FALSE;
  733.     as = as_merge (as,nas);
  734.  
  735.     obj = dn_cpy (where);
  736.     dn_append (obj,dn_cpy(dnc));
  737.     add_arg.ada_object = obj;
  738.     add_arg.ada_entry = as;
  739.  
  740.     if (ds_addentry (&add_arg, &error) != DS_OK) {
  741.         ds_error (ps,&error);
  742.         dn_free (obj);
  743.         as_free (as);
  744.         return FALSE;
  745.     }
  746.  
  747.     dn_free (obj);
  748.     as_free (as);
  749.  
  750.     return TRUE;
  751. }
  752.  
  753.  
  754.  
  755.