Commit | Line | Data |
---|---|---|
9e8e5516 C |
1 | /* ds_remove.c - */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_remove.c,v 7.2 91/02/22 09:38:57 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/quipu/RCS/ds_remove.c,v 7.2 91/02/22 09:38:57 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: ds_remove.c,v $ | |
12 | * Revision 7.2 91/02/22 09:38:57 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.1 90/10/17 11:53:52 mrose | |
16 | * sync | |
17 | * | |
18 | * Revision 7.0 89/11/23 22:17:15 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/util.h" | |
35 | #include "quipu/entry.h" | |
36 | #include "quipu/remove.h" | |
37 | #include "pepsy.h" | |
38 | #include "quipu/DAS_pre_defs.h" | |
39 | ||
40 | extern LLog * log_dsap; | |
41 | extern int local_master_size; | |
42 | #ifdef TURBO_AVL | |
43 | extern int entry_cmp(); | |
44 | #endif | |
45 | ||
46 | do_ds_removeentry (arg, error, binddn, target, di_p, dsp) | |
47 | struct ds_removeentry_arg *arg; | |
48 | struct DSError *error; | |
49 | DN binddn; | |
50 | DN target; | |
51 | struct di_block **di_p; | |
52 | char dsp; | |
53 | { | |
54 | Entry entryptr, delent = NULLENTRY; | |
55 | char * new_version (); | |
56 | int retval; | |
57 | extern int read_only; | |
58 | ||
59 | DLOG (log_dsap,LLOG_TRACE,("ds remove entry")); | |
60 | ||
61 | if (!dsp) | |
62 | target = arg->rma_object; | |
63 | ||
64 | /* stop aliases being dereferenced */ | |
65 | arg->rma_common.ca_servicecontrol.svc_options |= SVC_OPT_DONTDEREFERENCEALIAS; | |
66 | ||
67 | if (target == NULLDN) { | |
68 | error->dse_type = DSE_NAMEERROR; | |
69 | error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT; | |
70 | error->ERR_NAME.DSE_na_matched = NULLDN; | |
71 | return (DS_ERROR_REMOTE); | |
72 | } | |
73 | ||
74 | switch(find_entry(target,&(arg->rma_common),binddn,NULLDNSEQ,TRUE,&(entryptr), error, di_p, OP_REMOVEENTRY)) | |
75 | { | |
76 | case DS_OK: | |
77 | /* Filled out entryptr - carry on */ | |
78 | break; | |
79 | case DS_CONTINUE: | |
80 | /* Filled out di_p - what do we do with it ?? */ | |
81 | return(DS_CONTINUE); | |
82 | ||
83 | case DS_X500_ERROR: | |
84 | /* Filled out error - what do we do with it ?? */ | |
85 | return(DS_X500_ERROR); | |
86 | default: | |
87 | /* SCREAM */ | |
88 | LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_remove() - find_entry failed")); | |
89 | return(DS_ERROR_LOCAL); | |
90 | } | |
91 | ||
92 | /* entry found, so remove it */ | |
93 | ||
94 | /* Strong authentication */ | |
95 | if ((retval = check_security_parms((caddr_t) arg, | |
96 | _ZRemoveEntryArgumentDataDAS, | |
97 | &_ZDAS_mod, | |
98 | arg->rma_common.ca_security, | |
99 | arg->rma_common.ca_sig, &binddn)) != 0) | |
100 | { | |
101 | error->dse_type = DSE_SECURITYERROR; | |
102 | error->ERR_SECURITY.DSE_sc_problem = retval; | |
103 | return (DS_ERROR_REMOTE); | |
104 | } | |
105 | ||
106 | if (read_only || entryptr->e_parent->e_lock) { | |
107 | error->dse_type = DSE_SERVICEERROR; | |
108 | error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNAVAILABLE; | |
109 | return (DS_ERROR_REMOTE); | |
110 | } | |
111 | ||
112 | /* not prepared to accept operation over DSP */ | |
113 | if (dsp) { | |
114 | error->dse_type = DSE_SECURITYERROR; | |
115 | error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION; | |
116 | return (DS_ERROR_REMOTE); | |
117 | } | |
118 | ||
119 | if ( ! (isleaf(entryptr))) { | |
120 | error->dse_type = DSE_UPDATEERROR; | |
121 | error->ERR_UPDATE.DSE_up_problem = DSE_UP_NOTONNONLEAF; | |
122 | return (DS_ERROR_REMOTE); | |
123 | } | |
124 | ||
125 | if ( ((entryptr->e_parent->e_data == E_TYPE_CONSTRUCTOR) && (check_acl (binddn,ACL_WRITE,entryptr->e_acl->ac_entry, target) == NOTOK)) | |
126 | || (check_acl (binddn, ACL_WRITE, entryptr->e_parent->e_acl->ac_child, target) == NOTOK)) { | |
127 | error->dse_type = DSE_SECURITYERROR; | |
128 | error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; | |
129 | return (DS_ERROR_REMOTE); | |
130 | } | |
131 | ||
132 | ||
133 | #ifdef TURBO_AVL | |
134 | if (avl_onenode(entryptr->e_parent->e_children)) { | |
135 | #else | |
136 | if (entryptr->e_sibling == NULLENTRY) { | |
137 | #endif | |
138 | #ifdef NOTANYMORE | |
139 | ||
140 | /* | |
141 | We have been asked to remove the last node at one level, | |
142 | This means the parent has become a leaf. The parent however may be | |
143 | held in another DSA - which will need updating. | |
144 | Also the edbinfo attribute will need modifing. | |
145 | Leave till later... | |
146 | */ | |
147 | if (entryptr->e_parent->e_data != E_DATA_MASTER) { | |
148 | error->dse_type = DSE_UPDATEERROR; | |
149 | error->ERR_UPDATE.DSE_up_problem = DSE_UP_AFFECTSMULTIPLEDSAS; | |
150 | } else { | |
151 | error->dse_type = DSE_SERVICEERROR; | |
152 | error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; | |
153 | } | |
154 | return (DS_ERROR_REMOTE); | |
155 | #endif | |
156 | ||
157 | #ifdef TURBO_AVL | |
158 | #ifdef TURBO_INDEX | |
159 | /* delete index references to this node */ | |
160 | turbo_index_delete(entryptr); | |
161 | #endif | |
162 | /* removed node in core */ | |
163 | (void) avl_delete(&entryptr->e_parent->e_children,(caddr_t) entryptr,entry_cmp); | |
164 | #else | |
165 | entryptr->e_parent->e_child = NULLENTRY ; | |
166 | #endif /* TURBO_AVL */ | |
167 | entryptr->e_parent->e_allchildrenpresent = 2 ; | |
168 | ||
169 | if (entryptr->e_parent->e_edbversion) | |
170 | free (entryptr->e_parent->e_edbversion); | |
171 | entryptr->e_parent->e_edbversion = new_version(); | |
172 | ||
173 | #ifdef TURBO_DISK | |
174 | /* remove node on disk */ | |
175 | if (turbo_delete(entryptr) != OK) | |
176 | fatal(-35, "turbo delete failed - check database"); | |
177 | #else | |
178 | { | |
179 | DN save_dn ; | |
180 | char *filename ; | |
181 | Entry empty_entry = get_default_entry (NULLENTRY) ; | |
182 | char *dn2edbfile() ; | |
183 | ||
184 | empty_entry->e_data = E_DATA_MASTER ; | |
185 | ||
186 | save_dn = get_copy_dn(entryptr->e_parent) ; | |
187 | ||
188 | if ((filename = dn2edbfile(save_dn)) == NULLCP) | |
189 | { | |
190 | fatal(-33, "SPT: ds_modify: 1 creating new NLN out failed.\n") ; | |
191 | } | |
192 | if (write_edb(empty_entry, filename) != OK) | |
193 | { | |
194 | (void) unlink (filename); | |
195 | fatal(-33, "SPT: ds_modify: 2 writing new NLN out failed.\n") ; | |
196 | } | |
197 | ||
198 | dn_free (save_dn); | |
199 | } | |
200 | #endif /* TURBO_DISK */ | |
201 | entry_free (entryptr); | |
202 | local_master_size--; | |
203 | return (DS_OK); | |
204 | ||
205 | } | |
206 | else | |
207 | { | |
208 | /* removed node node in core */ | |
209 | #ifdef TURBO_AVL | |
210 | #ifdef TURBO_INDEX | |
211 | /* delete index references to this node */ | |
212 | turbo_index_delete(entryptr); | |
213 | #endif | |
214 | (void) avl_delete(&entryptr->e_parent->e_children,(caddr_t) entryptr,entry_cmp); | |
215 | #else | |
216 | entryptr->e_parent->e_child = entryptr->e_sibling; | |
217 | #ifndef TURBO_DISK | |
218 | delent = entryptr; | |
219 | entryptr = entryptr->e_sibling; | |
220 | #endif | |
221 | #endif | |
222 | } | |
223 | ||
224 | if (entryptr->e_parent->e_edbversion) | |
225 | free (entryptr->e_parent->e_edbversion); | |
226 | entryptr->e_parent->e_edbversion = new_version(); | |
227 | ||
228 | /* remove node on disk */ | |
229 | #ifdef TURBO_DISK | |
230 | if (turbo_delete(entryptr) != OK) | |
231 | fatal (-35,"turbo remove failed - check database"); | |
232 | #else | |
233 | if (journal (entryptr) != OK) | |
234 | fatal (-35,"remove rewrite fail - check database"); | |
235 | #endif | |
236 | ||
237 | if (delent) | |
238 | entry_free (delent); | |
239 | else | |
240 | entry_free (entryptr); | |
241 | local_master_size--; | |
242 | return (DS_OK); | |
243 | ||
244 | } |