|
|
1.1 ! root 1: /* ds_modify.c - */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_modify.c,v 7.2 90/07/09 14:45:45 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/quipu/RCS/ds_modify.c,v 7.2 90/07/09 14:45:45 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: ds_modify.c,v $ ! 12: * Revision 7.2 90/07/09 14:45:45 mrose ! 13: * sync ! 14: * ! 15: * Revision 7.1 89/12/19 16:20:16 mrose ! 16: * sync ! 17: * ! 18: * Revision 7.0 89/11/23 22:17:10 mrose ! 19: * Release 6.0 ! 20: * ! 21: */ ! 22: ! 23: /* ! 24: * NOTICE ! 25: * ! 26: * Acquisition, use, and distribution of this module and related ! 27: * materials are subject to the restrictions of a license agreement. ! 28: * Consult the Preface in the User's Manual for the full terms of ! 29: * this agreement. ! 30: * ! 31: */ ! 32: ! 33: ! 34: #include "quipu/config.h" ! 35: #include "quipu/util.h" ! 36: #include "quipu/entry.h" ! 37: #include "quipu/modify.h" ! 38: #include "quipu/malloc.h" ! 39: #include "config.h" ! 40: ! 41: static check_remove_values (); ! 42: static check_remove_type (); ! 43: extern Entry database_root; ! 44: extern LLog * log_dsap; ! 45: extern int encode_DAS_ModifyEntryArgumentData(); ! 46: ! 47: struct acl *acl_list; ! 48: int updateerror; ! 49: ! 50: do_ds_modifyentry (arg, error, binddn, target, di_p, dsp) ! 51: struct ds_modifyentry_arg *arg; ! 52: struct DSError *error; ! 53: DN binddn; ! 54: DN target; ! 55: struct di_block **di_p; ! 56: char dsp; ! 57: { ! 58: Entry entryptr; ! 59: Entry real_entry; ! 60: struct entrymod *eptr; ! 61: Entry entry_cpy (); ! 62: int remove = NOTOK; ! 63: int retval; ! 64: extern AttributeType at_control; ! 65: extern AttributeType at_acl; ! 66: extern int read_only; ! 67: char * new_version (); ! 68: Attr_Sequence as; ! 69: ! 70: DLOG (log_dsap,LLOG_TRACE,("ds_modifyentry")); ! 71: ! 72: if (!dsp) ! 73: target = arg->mea_object; ! 74: ! 75: /* stop aliases being dereferenced */ ! 76: arg->mea_common.ca_servicecontrol.svc_options |= SVC_OPT_DONTDEREFERENCEALIAS; ! 77: ! 78: /* check for control sequence */ ! 79: if (!dsp && arg->mea_changes ! 80: && (arg->mea_changes->em_type == EM_ADDATTRIBUTE)) { ! 81: if ( AttrT_cmp (arg->mea_changes->em_what->attr_type,at_control) == 0) { ! 82: int res; ! 83: res = dsa_control (arg->mea_changes->em_what,error,binddn); ! 84: return (res); ! 85: } ! 86: } ! 87: ! 88: if (target == NULLDN) { ! 89: error->dse_type = DSE_NAMEERROR; ! 90: error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT; ! 91: error->ERR_NAME.DSE_na_matched = NULLDN; ! 92: return (DS_ERROR_REMOTE); ! 93: } ! 94: ! 95: switch(find_entry(target,&(arg->mea_common),binddn,NULLDNSEQ,TRUE,&(real_entry), error, di_p)) ! 96: { ! 97: case DS_OK: ! 98: /* Filled out entryptr - carry on */ ! 99: break; ! 100: case DS_CONTINUE: ! 101: /* Filled out di_p - what do we do with it ?? */ ! 102: return(DS_CONTINUE); ! 103: ! 104: case DS_X500_ERROR: ! 105: /* Filled out error - what do we do with it ?? */ ! 106: return(DS_X500_ERROR); ! 107: default: ! 108: /* SCREAM */ ! 109: LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_modify() - find_entry failed")); ! 110: return(DS_ERROR_LOCAL); ! 111: } ! 112: ! 113: /* Strong authentication */ ! 114: if ((retval = check_security_parms((caddr_t) arg, ! 115: encode_DAS_ModifyEntryArgumentData, ! 116: arg->mea_common.ca_security, ! 117: arg->mea_common.ca_sig, &binddn)) != 0) ! 118: { ! 119: error->dse_type = DSE_SECURITYERROR; ! 120: error->ERR_SECURITY.DSE_sc_problem = retval; ! 121: return (DS_ERROR_REMOTE); ! 122: } ! 123: ! 124: if (read_only || real_entry->e_parent->e_lock) { ! 125: error->dse_type = DSE_SERVICEERROR; ! 126: error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNAVAILABLE; ! 127: return (DS_ERROR_REMOTE); ! 128: } ! 129: ! 130: /* not prepared to accept operation over DSP */ ! 131: if (dsp) { ! 132: error->dse_type = DSE_SECURITYERROR; ! 133: error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION; ! 134: return (DS_ERROR_REMOTE); ! 135: } ! 136: ! 137: DATABASE_HEAP; ! 138: entryptr = entry_cpy (real_entry); ! 139: acl_list = real_entry->e_acl; ! 140: GENERAL_HEAP; ! 141: ! 142: if (check_acl (binddn, ACL_ADD, acl_list->ac_entry,target) == NOTOK) { ! 143: error->dse_type = DSE_SECURITYERROR; ! 144: error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; ! 145: entry_free (entryptr); ! 146: return (DS_ERROR_REMOTE); ! 147: } ! 148: ! 149: if (check_acl (binddn, ACL_WRITE, acl_list->ac_entry,target) == OK) ! 150: remove = OK; ! 151: ! 152: for (eptr = arg->mea_changes; eptr!=NULLMOD; eptr=eptr->em_next) { ! 153: switch (eptr->em_type) { ! 154: case EM_ADDVALUES: ! 155: if (mod_add_value (entryptr,eptr->em_what,error,binddn,target,real_entry) != OK) { ! 156: entry_free (entryptr); ! 157: return (DS_ERROR_REMOTE); ! 158: } ! 159: break; ! 160: case EM_ADDATTRIBUTE: ! 161: if (add_attribute (entryptr,eptr->em_what,error,binddn,target) != OK) { ! 162: entry_free (entryptr); ! 163: return (DS_ERROR_REMOTE); ! 164: } ! 165: break; ! 166: case EM_REMOVEATTRIBUTE: ! 167: /* must not do this if attribute is rdn */ ! 168: if (check_remove_type (entryptr->e_name,eptr->em_what->attr_type) == NOTOK) { ! 169: error->dse_type = DSE_UPDATEERROR; ! 170: error->ERR_UPDATE.DSE_up_problem = updateerror;; ! 171: ! 172: entry_free (entryptr); ! 173: return (DS_ERROR_REMOTE); ! 174: } ! 175: if (remove == OK) { ! 176: if (remove_attribute (entryptr,eptr->em_what->attr_type,error,binddn,target,real_entry) != OK) { ! 177: entry_free (entryptr); ! 178: return (DS_ERROR_REMOTE); ! 179: } ! 180: } else { ! 181: error->dse_type = DSE_SECURITYERROR; ! 182: error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; ! 183: entry_free (entryptr); ! 184: return (DS_ERROR_REMOTE); ! 185: } ! 186: break; ! 187: case EM_REMOVEVALUES: ! 188: if (check_remove_values (entryptr->e_name, eptr->em_what) == NOTOK) { ! 189: error->dse_type = DSE_UPDATEERROR; ! 190: error->ERR_UPDATE.DSE_up_problem = updateerror;; ! 191: ! 192: entry_free (entryptr); ! 193: return (DS_ERROR_REMOTE); ! 194: } ! 195: if (remove == OK) { ! 196: if (remove_value (entryptr,eptr->em_what,error,binddn,target,real_entry) != OK) { ! 197: entry_free (entryptr); ! 198: return (DS_ERROR_REMOTE); ! 199: } ! 200: } else { ! 201: error->dse_type = DSE_SECURITYERROR; ! 202: error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; ! 203: entry_free (entryptr); ! 204: return (DS_ERROR_REMOTE); ! 205: } ! 206: break; ! 207: } ! 208: } ! 209: ! 210: /* check the last value of an attribute has not been removed */ ! 211: for (as = entryptr->e_attributes; as!=NULLATTR; as=as->attr_link) ! 212: if (as->attr_value == NULLAV) { ! 213: error->dse_type = DSE_ATTRIBUTEERROR; ! 214: error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (entryptr); ! 215: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_CONSTRAINTVIOLATION; ! 216: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (as->attr_type); ! 217: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; ! 218: error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; ! 219: entry_free (entryptr); ! 220: return (DS_ERROR_REMOTE); ! 221: } ! 222: ! 223: DATABASE_HEAP; ! 224: modify_attr (entryptr,binddn); ! 225: if (unravel_attribute (entryptr,error) != OK) { ! 226: GENERAL_HEAP; ! 227: entry_free (entryptr); ! 228: return (DS_ERROR_REMOTE); ! 229: } else if (check_schema (entryptr,NULLATTR,error) == OK) { ! 230: GENERAL_HEAP; ! 231: ! 232: /* Check user has not prevented further modification by themselves ! */ ! 233: if ((acl_list != entryptr->e_acl) ! 234: && (acl_cmp (acl_list,entryptr->e_acl) != 0)) { ! 235: as = as_find_type (entryptr->e_attributes,at_acl); ! 236: if ((check_acl (binddn, ACL_WRITE, as->attr_acl,target) == NOTOK) || ! 237: (check_acl (binddn, ACL_WRITE, entryptr->e_acl->ac_entry,target) == NOTOK)) { ! 238: entry_free (entryptr); ! 239: LLOG(log_dsap,LLOG_NOTICE,("Not modifying due to future access problem")); ! 240: error->dse_type = DSE_SERVICEERROR; ! 241: error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; ! 242: return (DS_ERROR_REMOTE); ! 243: } ! 244: } ! 245: ! 246: /* changes made OK, so add new entry into tree */ ! 247: if (entryptr->e_parent == NULLENTRY) { ! 248: database_root = entryptr; ! 249: entry_free (real_entry); ! 250: } else { ! 251: entryptr->e_parent->e_child = entryptr; ! 252: entry_free (real_entry); ! 253: /* now alter all parent pointers */ ! 254: for (real_entry = entryptr->e_child; real_entry!=NULLENTRY; real_entry=real_entry->e_sibling) ! 255: real_entry->e_parent = entryptr; ! 256: } ! 257: ! 258: if (entryptr->e_parent != NULLENTRY) { ! 259: if (entryptr->e_parent->e_edbversion) ! 260: free (entryptr->e_parent->e_edbversion); ! 261: entryptr->e_parent->e_edbversion = new_version(); ! 262: } ! 263: #ifdef TURBO_DISK ! 264: if (turbo_write(entryptr) != OK) ! 265: fatal (-33,"modify rewrite failed - check database"); ! 266: #else ! 267: if (journal (entryptr) != OK) ! 268: fatal (-33,"modify rewrite failed - check database"); ! 269: #endif ! 270: ! 271: return (DS_OK); ! 272: } else { ! 273: entry_free (entryptr); ! 274: return (DS_ERROR_REMOTE); ! 275: } ! 276: } ! 277: ! 278: remove_attribute (eptr,at,error,requestor,dn,real_entry) ! 279: Entry eptr,real_entry; ! 280: AttributeType at; ! 281: struct DSError *error; ! 282: DN requestor,dn; ! 283: { ! 284: register Attr_Sequence as, trail= NULLATTR, real_as; ! 285: extern oid_table_attr * tab_acl; ! 286: ! 287: DLOG (log_dsap,LLOG_DEBUG,("remove attribute")); ! 288: ! 289: for (as=eptr->e_attributes; as!=NULLATTR; as=as->attr_link) { ! 290: if ((AttrT_cmp (as->attr_type,at)) == 0) ! 291: break; ! 292: trail = as; ! 293: } ! 294: if (as == NULLATTR) { ! 295: error->dse_type = DSE_ATTRIBUTEERROR; ! 296: error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (eptr); ! 297: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE; ! 298: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (at); ! 299: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; ! 300: error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; ! 301: return (DS_ERROR_REMOTE); ! 302: } ! 303: ! 304: if ( (real_as = as_find_type (real_entry->e_attributes,at)) == NULLATTR) { ! 305: error->dse_type = DSE_ATTRIBUTEERROR; ! 306: error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (eptr); ! 307: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE; ! 308: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (at); ! 309: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; ! 310: error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; ! 311: return (DS_ERROR_REMOTE); ! 312: } ! 313: ! 314: if (check_acl(requestor,ACL_WRITE,real_as->attr_acl,dn) == NOTOK) { ! 315: error->dse_type = DSE_SECURITYERROR; ! 316: error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; ! 317: return (DS_ERROR_REMOTE); ! 318: } ! 319: ! 320: if (trail == NULLATTR) { ! 321: /* first in sequence */ ! 322: eptr->e_attributes = as->attr_link; ! 323: as_comp_free (as); ! 324: } else ! 325: as_delnext (trail); ! 326: ! 327: return (OK); ! 328: } ! 329: ! 330: ! 331: static check_remove_type (rdn,at) ! 332: register RDN rdn; ! 333: register AttributeType at; ! 334: { ! 335: extern AttributeType at_objectclass; ! 336: ! 337: if ( AttrT_cmp (at,at_objectclass) == 0) { ! 338: updateerror = DSE_UP_NOOBJECTCLASSMODS; ! 339: return (NOTOK); ! 340: } ! 341: ! 342: /* check attribute type is not distinguished */ ! 343: ! 344: for (; rdn!=NULLRDN; rdn=rdn->rdn_next) ! 345: if (AttrT_cmp (rdn->rdn_at,at) == 0) { ! 346: updateerror = DSE_UP_NOTONRDN; ! 347: return (NOTOK); ! 348: } ! 349: return (OK); ! 350: } ! 351: ! 352: static check_remove_values (rdn,as) ! 353: register RDN rdn; ! 354: register Attr_Sequence as; ! 355: { ! 356: register AV_Sequence as_avs; ! 357: extern AttributeType at_objectclass; ! 358: ! 359: /* check that the value trying to remove is not distinguished */ ! 360: for (; rdn!=NULLRDN; rdn=rdn->rdn_next) ! 361: if (AttrT_cmp (rdn->rdn_at,as->attr_type) == 0) ! 362: for (as_avs=as->attr_value; as_avs!=NULLAV; as_avs=as_avs->avseq_next) ! 363: if (AttrV_cmp (&rdn->rdn_av,&as_avs->avseq_av) == 0) { ! 364: updateerror = DSE_UP_NOTONRDN; ! 365: return (NOTOK); ! 366: } ! 367: return (OK); ! 368: } ! 369: ! 370: ! 371: ! 372: remove_value (eptr,rmas,error,requestor,dn,real_entry) ! 373: Entry eptr, real_entry; ! 374: Attr_Sequence rmas; ! 375: struct DSError *error; ! 376: DN requestor,dn; ! 377: { ! 378: register Attr_Sequence as,real_as; ! 379: register AV_Sequence rmavs,avs,trail = NULLAV; ! 380: int i; ! 381: ! 382: ! 383: DLOG (log_dsap,LLOG_DEBUG,("remove attribute value")); ! 384: ! 385: for (as=eptr->e_attributes; as!=NULLATTR; as=as->attr_link) { ! 386: if ((AttrT_cmp (as->attr_type,rmas->attr_type)) == 0) ! 387: break; ! 388: } ! 389: if (as == NULLATTR) { ! 390: error->dse_type = DSE_ATTRIBUTEERROR; ! 391: error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (eptr); ! 392: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE; ! 393: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (rmas->attr_type); ! 394: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; ! 395: error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; ! 396: return (DS_ERROR_REMOTE); ! 397: } ! 398: ! 399: if ( (real_as = as_find_type (real_entry->e_attributes,as->attr_type)) == NULLATTR) { ! 400: error->dse_type = DSE_ATTRIBUTEERROR; ! 401: error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (eptr); ! 402: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE; ! 403: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (rmas->attr_type); ! 404: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; ! 405: error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; ! 406: return (DS_ERROR_REMOTE); ! 407: } ! 408: ! 409: if (check_acl(requestor,ACL_WRITE,real_as->attr_acl,dn) == NOTOK) { ! 410: error->dse_type = DSE_SECURITYERROR; ! 411: error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; ! 412: return (NOTOK); ! 413: } ! 414: ! 415: for (rmavs=rmas->attr_value; rmavs != NULLAV; rmavs = rmavs->avseq_next) { ! 416: ! 417: for (avs=as->attr_value; avs!=NULLAV; avs=avs->avseq_next) { ! 418: if ((i = AttrV_cmp(&avs->avseq_av,&rmas->attr_value->avseq_av)) == 0) ! 419: break; ! 420: if (i == -2) { ! 421: error->dse_type = DSE_ATTRIBUTEERROR; ! 422: error->ERR_ATTRIBUTE.DSE_at_name = NULLDN; ! 423: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what = DSE_AT_INAPPROPRIATEMATCHING; ! 424: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (as->attr_type); ! 425: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = AttrV_cpy(&rmas->attr_value->avseq_av); ! 426: error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; ! 427: return (DS_ERROR_REMOTE); ! 428: } ! 429: trail = avs; ! 430: } ! 431: ! 432: if (avs == NULLAV) { ! 433: error->dse_type = DSE_ATTRIBUTEERROR; ! 434: error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (eptr); ! 435: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE; ! 436: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (rmas->attr_type); ! 437: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = AttrV_cpy (&rmas->attr_value->avseq_av); ! 438: error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; ! 439: return (DS_ERROR_REMOTE); ! 440: } ! 441: if (trail == NULLAV) { ! 442: /* first in sequence */ ! 443: as->attr_value = avs->avseq_next; ! 444: avs_comp_free (avs); ! 445: } else ! 446: avs_delnext (trail); ! 447: } ! 448: ! 449: return (OK); ! 450: } ! 451: ! 452: add_attribute (eptr,newas,error,requestor,dn) ! 453: Entry eptr; ! 454: Attr_Sequence newas; ! 455: struct DSError *error; ! 456: DN requestor,dn; ! 457: { ! 458: struct acl_attr * aa; ! 459: struct acl_info * ai = NULLACL_INFO; ! 460: struct oid_seq * oidptr; ! 461: ! 462: DLOG (log_dsap,LLOG_DEBUG,("add attribute")); ! 463: ! 464: if (as_find_type (eptr->e_attributes,newas->attr_type) != NULLATTR) { ! 465: error->dse_type = DSE_ATTRIBUTEERROR; ! 466: error->ERR_ATTRIBUTE.DSE_at_name = dn_cpy (dn); ! 467: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what = DSE_AT_TYPEORVALUEEXISTS; ! 468: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (newas->attr_type); ! 469: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; ! 470: error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; ! 471: DLOG (log_dsap,LLOG_DEBUG,("add exists error")); ! 472: return (NOTOK); ! 473: } ! 474: ! 475: for ( aa = acl_list->ac_attributes; aa!=NULLACL_ATTR; aa=aa->aa_next) { ! 476: for ( oidptr=aa->aa_types;oidptr != NULLOIDSEQ; oidptr=oidptr->oid_next) { ! 477: if (oid_cmp (oidptr->oid_oid,grab_oid(newas->attr_type)) == 0) { ! 478: ai = aa->aa_acl; ! 479: break; ! 480: } ! 481: } ! 482: if (ai != NULLACL_INFO) ! 483: break; ! 484: } ! 485: if (ai == NULLACL_INFO) ! 486: ai = acl_list->ac_default; ! 487: ! 488: if (check_acl(requestor,ACL_WRITE,ai,dn) == NOTOK) { ! 489: error->dse_type = DSE_SECURITYERROR; ! 490: error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; ! 491: DLOG (log_dsap,LLOG_DEBUG,("add acl failed")); ! 492: return (NOTOK); ! 493: } ! 494: ! 495: DATABASE_HEAP; ! 496: eptr->e_attributes = as_merge (as_cpy(newas),eptr->e_attributes); ! 497: GENERAL_HEAP; ! 498: ! 499: return (OK); ! 500: } ! 501: ! 502: ! 503: mod_add_value (eptr,newas,error,requestor,dn,real_entry) ! 504: Entry eptr,real_entry; ! 505: Attr_Sequence newas; ! 506: struct DSError *error; ! 507: DN requestor,dn; ! 508: { ! 509: register Attr_Sequence as; ! 510: AV_Sequence avs; ! 511: ! 512: DLOG (log_dsap,LLOG_DEBUG,("add value")); ! 513: ! 514: if ( (as = as_find_type (real_entry->e_attributes,newas->attr_type)) == NULLATTR) { ! 515: error->dse_type = DSE_ATTRIBUTEERROR; ! 516: error->ERR_ATTRIBUTE.DSE_at_name = dn_cpy (dn); ! 517: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what = DSE_AT_NOSUCHATTRIBUTE; ! 518: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (newas->attr_type); ! 519: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; ! 520: error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; ! 521: return (NOTOK); ! 522: } ! 523: ! 524: if (check_acl(requestor,ACL_WRITE,as->attr_acl,dn) == NOTOK) { ! 525: error->dse_type = DSE_SECURITYERROR; ! 526: error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; ! 527: DLOG (log_dsap,LLOG_DEBUG,("add acl failed")); ! 528: return (NOTOK); ! 529: } ! 530: ! 531: for (avs=as->attr_value; avs != NULLAV; avs=avs->avseq_next) ! 532: if (AttrV_cmp(&avs->avseq_av,&newas->attr_value->avseq_av) == 0) { ! 533: error->dse_type = DSE_ATTRIBUTEERROR; ! 534: error->ERR_ATTRIBUTE.DSE_at_name = dn_cpy (dn); ! 535: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what = DSE_AT_TYPEORVALUEEXISTS; ! 536: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (newas->attr_type); ! 537: error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = AttrV_cpy (&newas->attr_value->avseq_av); ! 538: error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; ! 539: DLOG (log_dsap,LLOG_DEBUG,("add value exists error")); ! 540: return (NOTOK); ! 541: } ! 542: ! 543: DATABASE_HEAP; ! 544: eptr->e_attributes = as_merge (as_cpy(newas),eptr->e_attributes); ! 545: GENERAL_HEAP; ! 546: ! 547: return (OK); ! 548: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.