|
|
1.1 root 1: /* ds_add.c - */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_add.c,v 7.2 90/07/09 14:45:37 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/quipu/RCS/ds_add.c,v 7.2 90/07/09 14:45:37 mrose Exp $
9: *
10: *
11: * $Log: ds_add.c,v $
12: * Revision 7.2 90/07/09 14:45:37 mrose
13: * sync
14: *
15: * Revision 7.1 90/01/11 18:37:19 mrose
16: * real-sync
17: *
18: * Revision 7.0 89/11/23 22:17:03 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/add.h"
38: #include "quipu/malloc.h"
39:
40: extern Entry database_root;
41: extern LLog * log_dsap;
42: extern int local_master_size;
43: extern int encode_DAS_AddEntryArgumentData();
44:
45: do_ds_addentry (arg, error, binddn,target,di_p,dsp)
46: struct ds_addentry_arg *arg;
47: struct DSError *error;
48: DN binddn;
49: DN target;
50: struct di_block **di_p;
51: char dsp;
52: {
53: Entry entryptr,ptr;
54: register DN dntop, dn = NULLDN;
55: DN trail = NULLDN;
56: extern Entry database_root;
57: ContinuationRef cont_ref_parent ();
58: char * new_version ();
59: int retval;
60: extern int read_only;
61:
62: DLOG (log_dsap,LLOG_TRACE,("ds_add"));
63:
64: if (!dsp)
65: target = arg->ada_object;
66:
67: /* stop aliases being dereferenced */
68: arg->ada_common.ca_servicecontrol.svc_options |= SVC_OPT_DONTDEREFERENCEALIAS;
69:
70: error ->dse_type = DSE_NOERROR;
71: /* first of all see if entry exists */
72:
73: if (target == NULLDN) {
74: error->dse_type = DSE_NAMEERROR;
75: error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT;
76: error->ERR_NAME.DSE_na_matched = NULLDN;
77: return (DS_ERROR_REMOTE);
78: }
79:
80: switch (find_entry (target,&(arg->ada_common),binddn,NULLDNSEQ,FALSE,&entryptr, error, di_p))
81: {
82: case DS_OK:
83: error->dse_type = DSE_UPDATEERROR;
84: error->ERR_UPDATE.DSE_up_problem = DSE_UP_ALREADYEXISTS;
85: return(DS_ERROR_REMOTE);
86: case DS_CONTINUE:
87: /* Filled out di_p - what do we do with it ?? */
88: return(DS_CONTINUE);
89: case DS_X500_ERROR:
90: /* Filled out error - what do we do with it ?? */
91: if ((error->dse_type != DSE_NAMEERROR) || (error->ERR_NAME.DSE_na_problem != DSE_NA_NOSUCHOBJECT)) {
92: return(DS_X500_ERROR);
93: }
94: ds_error_free (error); /* not interested - know it does not exist */
95: break;
96: default:
97: /* SCREAM */
98: LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_read() - find_entry failed"));
99: return(DS_ERROR_LOCAL);
100: }
101:
102: /* object does not exist, so create it */
103:
104: /* Strong authentication */
105: if ((retval = check_security_parms((caddr_t) arg,
106: encode_DAS_AddEntryArgumentData,
107: arg->ada_common.ca_security,
108: arg->ada_common.ca_sig, &binddn)) != 0)
109: {
110: error->dse_type = DSE_SECURITYERROR;
111: error->ERR_SECURITY.DSE_sc_problem = retval;
112: return (DS_ERROR_REMOTE);
113: }
114:
115: DLOG (log_dsap,LLOG_TRACE,("add - find parent"));
116:
117: if ((dntop = dn_cpy(target)) != NULLDN)
118: for (dn=dntop; dn->dn_parent != NULLDN; dn=dn->dn_parent)
119: trail = dn;
120:
121: if (trail == NULLDN) {
122: dntop = NULLDN;
123: entryptr = database_root;
124: if (entryptr->e_data != E_DATA_MASTER) {
125: error->dse_type = DSE_REFERRAL;
126: error->ERR_REFERRAL.DSE_ref_prefix = NULLDN;
127: if ((error->ERR_REFERRAL.DSE_ref_candidates = cont_ref_parent (NULLDN)) == NULLCONTINUATIONREF) {
128: error->dse_type = DSE_SERVICEERROR;
129: error->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
130: }
131: return (DS_ERROR_CONNECT);
132: }
133: } else {
134: trail->dn_parent = NULLDN;
135: switch(find_child_entry(dntop,&(arg->ada_common),binddn,NULLDNSEQ,TRUE,&(entryptr), error, di_p))
136: {
137: case DS_OK:
138: /* Filled out entryptr - carry on */
139: break;
140: case DS_CONTINUE:
141: /* Filled out di_p - what do we do with it ?? */
142: /* When add returns DS_CONTINUE the target must be changed */
143: return(DS_CONTINUE);
144:
145: case DS_X500_ERROR:
146: /* Filled out error - what do we do with it ?? */
147: return(DS_X500_ERROR);
148: default:
149: /* SCREAM */
150: LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_add() - find_child_entry failed"));
151: return(DS_ERROR_LOCAL);
152: }
153: }
154:
155: if ( read_only || ((entryptr->e_parent != NULLENTRY) && (entryptr->e_parent->e_lock))) {
156: error->dse_type = DSE_SERVICEERROR;
157: error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM;
158: dn_free (dntop);
159: dn_free (dn);
160: return (DS_ERROR_REMOTE);
161: }
162:
163: /* not prepared to accept operation over DSP */
164: if (dsp) {
165: error->dse_type = DSE_SECURITYERROR;
166: error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION;
167: dn_free (dntop);
168: dn_free (dn);
169: return (DS_ERROR_REMOTE);
170: }
171:
172: DLOG (log_dsap,LLOG_TRACE,("add - acl"));
173: if (check_acl (binddn,ACL_ADD,entryptr->e_acl->ac_child,dntop) == NOTOK) {
174: error->dse_type = DSE_SECURITYERROR;
175: error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS;
176: dn_free (dntop);
177: dn_free (dn);
178: return (DS_ERROR_REMOTE);
179: }
180:
181: DLOG (log_dsap,LLOG_TRACE,("add - default"));
182:
183: DATABASE_HEAP;
184:
185: ptr = get_default_entry (entryptr);
186: ptr->e_name = rdn_cpy (dn->dn_rdn);
187: ptr->e_attributes = as_cpy (arg->ada_entry);
188:
189: modify_attr (ptr,binddn);
190:
191: DLOG (log_dsap,LLOG_TRACE,("add - unravel"));
192: if (unravel_attribute (ptr,error) != OK) {
193: dn_free (dntop);
194: dn_free (dn);
195: entry_free (ptr);
196: GENERAL_HEAP;
197: return (DS_ERROR_REMOTE);
198: }
199:
200: DLOG (log_dsap,LLOG_TRACE,("add - schema"));
201: if (check_schema (ptr,NULLATTR,error) != OK) {
202: dn_free (dntop);
203: dn_free (dn);
204: entry_free (ptr);
205: GENERAL_HEAP;
206: return (DS_ERROR_REMOTE);
207: }
208:
209: GENERAL_HEAP;
210:
211: dn_free (dn);
212: dn_free (dntop);
213:
214: if ( entryptr->e_leaf) {
215: Attr_Sequence newas;
216: AttributeType newat;
217:
218: entryptr->e_child = ptr;
219: /* add master and slave attributes */
220:
221: DATABASE_HEAP;
222:
223: if ((entryptr->e_parent->e_slave == NULLAV) && (entryptr->e_parent->e_master == NULLAV)) {
224: extern char * mydsaname;
225: newat = AttrT_new (MASTERDSA_OID);
226: entryptr->e_master = str2avs (mydsaname,newat);
227: newas = as_comp_new (newat,entryptr->e_master,NULLACL_INFO);
228: entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);
229: } else {
230: if ((entryptr->e_master = avs_cpy(entryptr->e_parent->e_master)) != NULLAV) {
231: newat = AttrT_new (MASTERDSA_OID);
232: newas = as_comp_new (newat,entryptr->e_master,NULLACL_INFO);
233: entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);
234: }
235: if ((entryptr->e_slave = avs_cpy (entryptr->e_parent->e_slave)) != NULLAV) {
236: newat = AttrT_new (SLAVEDSA_OID);
237: newas = as_comp_new (newat,entryptr->e_slave,NULLACL_INFO);
238: entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);
239: }
240: }
241: /* add new QuipuNonLeaf objectclass */
242: newat = AttrT_new (OBJECTCLASS_OID);
243: newas = as_comp_new (newat,str2avs(NONLEAFOBJECT,newat),NULLACL_INFO);
244: entryptr->e_attributes = as_merge (entryptr->e_attributes,newas);
245:
246: if (entryptr->e_parent != NULLENTRY) {
247: if (entryptr->e_parent->e_edbversion)
248: free (entryptr->e_parent->e_edbversion);
249: entryptr->e_parent->e_edbversion = new_version();
250: }
251: if (entryptr->e_edbversion)
252: free (entryptr->e_edbversion);
253: entryptr->e_edbversion = new_version();
254: ptr->e_edbversion = new_version();
255: entryptr->e_allchildrenpresent = TRUE;
256:
257: modify_attr (entryptr,binddn);
258: if (unravel_attribute (entryptr,error) != OK)
259: fatal (-31,"serious schema error");
260:
261: #ifdef TURBO_DISK
262: if (turbo_write(ptr) == NOTOK)
263: fatal(-32,"add turbo_write(2) failure - check database");
264: #else
265: if (journal (ptr) == NOTOK)
266: fatal (-32,"add journal (2) failure - check database");
267: #endif
268:
269: entryptr->e_leaf = FALSE;
270: /* rewrite the parent as well */
271: #ifdef TURBO_DISK
272: if (turbo_write(ptr) == NOTOK)
273: fatal(-31,"add parent turbo_write failed - check database");
274: #else
275: if (journal (entryptr) != OK)
276: fatal (-31,"add parent journal failed - check database");
277: #endif
278:
279: GENERAL_HEAP;
280:
281: local_master_size++;
282: return (OK);
283:
284: } else {
285: ptr->e_sibling = entryptr->e_child;
286: entryptr->e_child = ptr;
287: }
288:
289: if (ptr->e_parent != NULLENTRY) {
290: if (ptr->e_parent->e_edbversion)
291: free (ptr->e_parent->e_edbversion);
292: ptr->e_parent->e_edbversion = new_version();
293: }
294: #ifdef TURBO_DISK
295: if (turbo_write(ptr) == NOTOK)
296: fatal(-32,"add turbo_write failure - check database");
297: #else
298: if (journal (ptr) == NOTOK)
299: fatal (-32,"add journal failure - check database");
300: #endif
301:
302: local_master_size++;
303: return (DS_OK);
304: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.