mep.c 101 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2010 Red Hat, Inc.
  3. * All rights reserved.
  4. *
  5. * License: GPL (version 3 or any later version).
  6. * See LICENSE for details.
  7. * END COPYRIGHT BLOCK **/
  8. #ifdef HAVE_CONFIG_H
  9. #include <config.h>
  10. #endif
  11. /*
  12. * Managed Entries Plug-in
  13. */
  14. #include "mep.h"
  15. #include "slapi-private.h"
  16. /*
  17. * Plug-in globals
  18. */
  19. static PRCList *g_mep_config = NULL;
  20. static Slapi_RWLock *g_mep_config_lock;
  21. static void *_PluginID = NULL;
  22. static Slapi_DN *_PluginDN = NULL;
  23. static Slapi_DN *_ConfigAreaDN = NULL;
  24. static Slapi_PluginDesc pdesc = {MEP_FEATURE_DESC,
  25. VENDOR,
  26. DS_PACKAGE_VERSION,
  27. MEP_PLUGIN_DESC};
  28. /*
  29. * Plug-in management functions
  30. */
  31. int mep_init(Slapi_PBlock *pb);
  32. static int mep_start(Slapi_PBlock *pb);
  33. static int mep_close(Slapi_PBlock *pb);
  34. static int mep_postop_init(Slapi_PBlock *pb);
  35. static int mep_internal_postop_init(Slapi_PBlock *pb);
  36. /*
  37. * Operation callbacks (where the real work is done)
  38. */
  39. static int mep_mod_post_op(Slapi_PBlock *pb);
  40. static int mep_add_post_op(Slapi_PBlock *pb);
  41. static int mep_del_post_op(Slapi_PBlock *pb);
  42. static int mep_modrdn_post_op(Slapi_PBlock *pb);
  43. static int mep_pre_op(Slapi_PBlock *pb, int modop);
  44. static int mep_mod_pre_op(Slapi_PBlock *pb);
  45. static int mep_add_pre_op(Slapi_PBlock *pb);
  46. static int mep_del_pre_op(Slapi_PBlock *pb);
  47. static int mep_modrdn_pre_op(Slapi_PBlock *pb);
  48. /*
  49. * Config cache management functions
  50. */
  51. static int mep_load_config(void);
  52. static void mep_delete_config(void);
  53. static int mep_parse_config_entry(Slapi_Entry *e, int apply);
  54. static void mep_free_config_entry(struct configEntry **entry);
  55. /*
  56. * helpers
  57. */
  58. static Slapi_DN *mep_get_sdn(Slapi_PBlock *pb);
  59. static Slapi_DN *mep_get_config_area(void);
  60. static void mep_set_config_area(Slapi_DN *sdn);
  61. static int mep_dn_is_config(Slapi_DN *sdn);
  62. static int mep_dn_is_template(Slapi_DN *dn);
  63. static void mep_find_config(Slapi_Entry *e, struct configEntry **config);
  64. static void mep_find_config_by_template_dn(Slapi_DN *template_dn,
  65. struct configEntry **config);
  66. static int mep_oktodo(Slapi_PBlock *pb);
  67. static int mep_isrepl(Slapi_PBlock *pb);
  68. static Slapi_Entry *mep_create_managed_entry(struct configEntry *config,
  69. Slapi_Entry *origin);
  70. static int mep_add_managed_entry(struct configEntry *config,
  71. Slapi_Entry *origin);
  72. static int mep_rename_managed_entry(Slapi_Entry *origin,
  73. Slapi_DN *new_dn,
  74. Slapi_DN *old_dn);
  75. static Slapi_Mods *mep_get_mapped_mods(struct configEntry *config,
  76. Slapi_Entry *origin,
  77. char **mapped_dn);
  78. static int mep_parse_mapped_attr(char *mapping, Slapi_Entry *origin, char **type, char **value);
  79. static int mep_is_managed_entry(Slapi_Entry *e);
  80. static int mep_is_mapped_attr(Slapi_Entry *template, char *type);
  81. static int mep_has_tombstone_value(Slapi_Entry *e);
  82. static int mep_parse_mapped_origin_attr(char *mapping, char **origin_type);
  83. static int mep_is_mapped_origin_attr(char **vals, char *type);
  84. static char **mep_extract_origin_attrs(Slapi_Entry *entry);
  85. /*
  86. * Config cache locking functions
  87. */
  88. void
  89. mep_config_read_lock()
  90. {
  91. slapi_rwlock_rdlock(g_mep_config_lock);
  92. }
  93. void
  94. mep_config_write_lock()
  95. {
  96. slapi_rwlock_wrlock(g_mep_config_lock);
  97. }
  98. void
  99. mep_config_unlock()
  100. {
  101. slapi_rwlock_unlock(g_mep_config_lock);
  102. }
  103. /*
  104. * Plugin identity functions
  105. */
  106. void
  107. mep_set_plugin_id(void *pluginID)
  108. {
  109. _PluginID = pluginID;
  110. }
  111. void *
  112. mep_get_plugin_id()
  113. {
  114. return _PluginID;
  115. }
  116. void
  117. mep_set_plugin_sdn(Slapi_DN *pluginDN)
  118. {
  119. _PluginDN = pluginDN;
  120. }
  121. Slapi_DN *
  122. mep_get_plugin_sdn(void)
  123. {
  124. return _PluginDN;
  125. }
  126. static int plugin_is_betxn = 0;
  127. /*
  128. * Plug-in initialization functions
  129. */
  130. int
  131. mep_init(Slapi_PBlock *pb)
  132. {
  133. int status = 0;
  134. char *plugin_identity = NULL;
  135. Slapi_Entry *plugin_entry = NULL;
  136. char *plugin_type = NULL;
  137. int preadd = SLAPI_PLUGIN_PRE_ADD_FN;
  138. int premod = SLAPI_PLUGIN_PRE_MODIFY_FN;
  139. int predel = SLAPI_PLUGIN_PRE_DELETE_FN;
  140. int premdn = SLAPI_PLUGIN_PRE_MODRDN_FN;
  141. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  142. "--> mep_init\n");
  143. if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
  144. plugin_entry &&
  145. (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
  146. plugin_type && strstr(plugin_type, "betxn")) {
  147. plugin_is_betxn = 1;
  148. preadd = SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN;
  149. premod = SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN;
  150. predel = SLAPI_PLUGIN_BE_TXN_PRE_DELETE_FN;
  151. premdn = SLAPI_PLUGIN_BE_TXN_PRE_MODRDN_FN;
  152. }
  153. slapi_ch_free_string(&plugin_type);
  154. /* Store the plugin identity for later use.
  155. * Used for internal operations. */
  156. slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &plugin_identity);
  157. PR_ASSERT(plugin_identity);
  158. mep_set_plugin_id(plugin_identity);
  159. /* Register callbacks */
  160. if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
  161. SLAPI_PLUGIN_VERSION_01) != 0 ||
  162. slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
  163. (void *)mep_start) != 0 ||
  164. slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
  165. (void *)mep_close) != 0 ||
  166. slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
  167. (void *)&pdesc) != 0 ||
  168. slapi_pblock_set(pb, premod, (void *)mep_mod_pre_op) != 0 ||
  169. slapi_pblock_set(pb, preadd, (void *)mep_add_pre_op) != 0 ||
  170. slapi_pblock_set(pb, predel, (void *)mep_del_pre_op) != 0 ||
  171. slapi_pblock_set(pb, premdn, (void *)mep_modrdn_pre_op) != 0) {
  172. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  173. "mep_init - Failed to register plugin\n");
  174. status = -1;
  175. }
  176. if (!status && !plugin_is_betxn &&
  177. slapi_register_plugin("internalpostoperation", /* op type */
  178. 1, /* Enabled */
  179. "mep_init", /* this function desc */
  180. mep_internal_postop_init, /* init func */
  181. MEP_INT_POSTOP_DESC, /* plugin desc */
  182. NULL, /* ? */
  183. plugin_identity /* access control */
  184. )) {
  185. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  186. "mep_init - Failed to register internalpostoperation plugin\n");
  187. status = -1;
  188. }
  189. if (!status) {
  190. plugin_type = plugin_is_betxn ? "betxnpostoperation" : "postoperation";
  191. if (slapi_register_plugin(plugin_type, /* op type */
  192. 1, /* Enabled */
  193. "mep_init", /* this function desc */
  194. mep_postop_init, /* init func for post op */
  195. MEP_POSTOP_DESC, /* plugin desc */
  196. NULL, /* ? */
  197. plugin_identity /* access control */
  198. )) {
  199. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  200. "mep_init - Failed to register plugin\n");
  201. status = -1;
  202. }
  203. }
  204. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  205. "<-- mep_init\n");
  206. return status;
  207. }
  208. /* not used when using plugin as a betxn plugin - betxn plugins are called for both internal and external ops */
  209. static int
  210. mep_internal_postop_init(Slapi_PBlock *pb)
  211. {
  212. int status = 0;
  213. if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
  214. SLAPI_PLUGIN_VERSION_01) != 0 ||
  215. slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
  216. (void *)&pdesc) != 0 ||
  217. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN,
  218. (void *)mep_add_post_op) != 0 ||
  219. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN,
  220. (void *)mep_del_post_op) != 0 ||
  221. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN,
  222. (void *)mep_mod_post_op) != 0 ||
  223. slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN,
  224. (void *)mep_modrdn_post_op) != 0) {
  225. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  226. "mep_internal_postop_init - Failed to register plugin\n");
  227. status = -1;
  228. }
  229. return status;
  230. }
  231. static int
  232. mep_postop_init(Slapi_PBlock *pb)
  233. {
  234. int status = 0;
  235. int addfn = SLAPI_PLUGIN_POST_ADD_FN;
  236. int delfn = SLAPI_PLUGIN_POST_DELETE_FN;
  237. int modfn = SLAPI_PLUGIN_POST_MODIFY_FN;
  238. int mdnfn = SLAPI_PLUGIN_POST_MODRDN_FN;
  239. if (plugin_is_betxn) {
  240. addfn = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN;
  241. delfn = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
  242. modfn = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
  243. mdnfn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
  244. }
  245. if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
  246. SLAPI_PLUGIN_VERSION_01) != 0 ||
  247. slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
  248. (void *)&pdesc) != 0 ||
  249. slapi_pblock_set(pb, addfn, (void *)mep_add_post_op) != 0 ||
  250. slapi_pblock_set(pb, delfn, (void *)mep_del_post_op) != 0 ||
  251. slapi_pblock_set(pb, modfn, (void *)mep_mod_post_op) != 0 ||
  252. slapi_pblock_set(pb, mdnfn, (void *)mep_modrdn_post_op) != 0) {
  253. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  254. "mep_postop_init - Failed to register plugin\n");
  255. status = -1;
  256. }
  257. return status;
  258. }
  259. /*
  260. * mep_start()
  261. *
  262. * Creates config lock and loads config cache.
  263. */
  264. static int
  265. mep_start(Slapi_PBlock *pb)
  266. {
  267. Slapi_DN *plugindn = NULL;
  268. char *config_area = NULL;
  269. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  270. "--> mep_start\n");
  271. g_mep_config_lock = slapi_new_rwlock();
  272. if (!g_mep_config_lock) {
  273. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  274. "mep_start - Lock creation failed\n");
  275. return -1;
  276. }
  277. /*
  278. * Get the plug-in target dn from the system
  279. * and store it for future use. */
  280. slapi_pblock_get(pb, SLAPI_TARGET_SDN, &plugindn);
  281. if (NULL == plugindn || 0 == slapi_sdn_get_ndn_len(plugindn)) {
  282. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  283. "mep_start - Unable to retrieve plugin dn\n");
  284. return -1;
  285. }
  286. mep_set_plugin_sdn(slapi_sdn_dup(plugindn));
  287. /* Set the alternate config area if one is defined. */
  288. slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_AREA, &config_area);
  289. if (config_area) {
  290. mep_set_config_area(slapi_sdn_new_normdn_byval(config_area));
  291. }
  292. /*
  293. * Load the config cache
  294. */
  295. g_mep_config = (PRCList *)slapi_ch_calloc(1, sizeof(struct configEntry));
  296. PR_INIT_CLIST(g_mep_config);
  297. if (mep_load_config() != 0) {
  298. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  299. "mep_start - Unable to load plug-in configuration\n");
  300. return -1;
  301. }
  302. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  303. "mep_start - Ready for service\n");
  304. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  305. "<-- mep_start\n");
  306. return 0;
  307. }
  308. /*
  309. * mep_close()
  310. *
  311. * Cleans up the config cache.
  312. */
  313. static int
  314. mep_close(Slapi_PBlock *pb __attribute__((unused)))
  315. {
  316. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  317. "--> mep_close\n");
  318. mep_delete_config();
  319. slapi_destroy_rwlock(g_mep_config_lock);
  320. g_mep_config_lock = NULL;
  321. slapi_ch_free((void **)&g_mep_config);
  322. slapi_sdn_free(&_PluginDN);
  323. slapi_sdn_free(&_ConfigAreaDN);
  324. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  325. "<-- mep_close\n");
  326. return 0;
  327. }
  328. PRCList *
  329. mep_get_config()
  330. {
  331. return g_mep_config;
  332. }
  333. /*
  334. * config looks like this
  335. * - cn=Managed Entries,cn=plugins,cn=config
  336. * --- cn=user private groups,...
  337. * --- cn=etc,...
  338. */
  339. static int
  340. mep_load_config(void)
  341. {
  342. int status = 0;
  343. int result;
  344. int i;
  345. Slapi_PBlock *search_pb;
  346. Slapi_Entry **entries = NULL;
  347. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  348. "--> mep_load_config\n");
  349. /* Clear out any old config. */
  350. mep_config_write_lock();
  351. mep_delete_config();
  352. search_pb = slapi_pblock_new();
  353. /* If an alternate config area is configured, find
  354. * the config entries that are beneath it, otherwise
  355. * we load the entries beneath our top-level plug-in
  356. * config entry. */
  357. if (mep_get_config_area()) {
  358. /* Find the config entries beneath the alternate config area. */
  359. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  360. "mep_load_config - Looking for config entries "
  361. "beneath \"%s\".\n",
  362. slapi_sdn_get_ndn(mep_get_config_area()));
  363. slapi_search_internal_set_pb(search_pb, slapi_sdn_get_ndn(mep_get_config_area()),
  364. LDAP_SCOPE_SUBTREE, "objectclass=*",
  365. NULL, 0, NULL, NULL, mep_get_plugin_id(), 0);
  366. } else {
  367. /* Find the config entries beneath our plugin entry. */
  368. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  369. "mep_load_config - Looking for config entries "
  370. "beneath \"%s\".\n",
  371. slapi_sdn_get_ndn(mep_get_plugin_sdn()));
  372. slapi_search_internal_set_pb(search_pb,
  373. slapi_sdn_get_ndn(mep_get_plugin_sdn()),
  374. LDAP_SCOPE_SUBTREE, "objectclass=*",
  375. NULL, 0, NULL, NULL, mep_get_plugin_id(), 0);
  376. }
  377. slapi_search_internal_pb(search_pb);
  378. slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  379. if (LDAP_SUCCESS != result) {
  380. if (mep_get_config_area() && (result == LDAP_NO_SUCH_OBJECT)) {
  381. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  382. "mep_load_config - Config container \"%s\" does "
  383. "not exist.\n",
  384. slapi_sdn_get_ndn(mep_get_config_area()));
  385. goto cleanup;
  386. } else {
  387. status = -1;
  388. goto cleanup;
  389. }
  390. }
  391. slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
  392. &entries);
  393. /* Loop through all of the entries we found and parse them. */
  394. for (i = 0; entries && (entries[i] != NULL); i++) {
  395. /* We don't care about the status here because we may have
  396. * some invalid config entries, but we just want to continue
  397. * looking for valid ones. */
  398. mep_parse_config_entry(entries[i], 1);
  399. }
  400. cleanup:
  401. slapi_free_search_results_internal(search_pb);
  402. slapi_pblock_destroy(search_pb);
  403. mep_config_unlock();
  404. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  405. "<-- mep_load_config\n");
  406. return status;
  407. }
  408. /*
  409. * mep_parse_config_entry()
  410. *
  411. * Parses a single config entry. If apply is non-zero, then
  412. * we will load and start using the new config. You can simply
  413. * validate config without making any changes by setting apply
  414. * to 0.
  415. *
  416. * Returns 0 if the entry is valid and -1 if it is invalid.
  417. */
  418. static int
  419. mep_parse_config_entry(Slapi_Entry *e, int apply)
  420. {
  421. char *value;
  422. struct configEntry *entry = NULL;
  423. struct configEntry *config_entry;
  424. PRCList *list;
  425. int entry_added = 0;
  426. int ret = 0;
  427. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  428. "--> mep_parse_config_entry\n");
  429. /* If this is the main plug-in
  430. * config entry, just bail. */
  431. if ((slapi_sdn_compare(mep_get_plugin_sdn(), slapi_entry_get_sdn(e)) == 0) ||
  432. (mep_get_config_area() && (slapi_sdn_compare(mep_get_config_area(),
  433. slapi_entry_get_sdn(e)) == 0))) {
  434. ret = -1;
  435. goto bail;
  436. }
  437. entry = (struct configEntry *)slapi_ch_calloc(1, sizeof(struct configEntry));
  438. if (NULL == entry) {
  439. ret = -1;
  440. goto bail;
  441. }
  442. entry->sdn = slapi_sdn_dup(slapi_entry_get_sdn(e));
  443. if (entry->sdn == NULL) {
  444. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  445. "mep_parse_config_entry - Error "
  446. "reading dn from config entry\n");
  447. ret = -1;
  448. goto bail;
  449. }
  450. slapi_log_err(SLAPI_LOG_CONFIG, MEP_PLUGIN_SUBSYSTEM,
  451. "----------> dn [%s]\n", slapi_sdn_get_dn(entry->sdn));
  452. /* Load the origin scope */
  453. value = slapi_entry_attr_get_charptr(e, MEP_SCOPE_TYPE);
  454. if (value) {
  455. entry->origin_scope = value;
  456. } else {
  457. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  458. "mep_parse_config_entry - The %s config "
  459. "setting is required for config entry \"%s\".\n",
  460. MEP_SCOPE_TYPE, slapi_sdn_get_dn(entry->sdn));
  461. ret = -1;
  462. goto bail;
  463. }
  464. /* Load the origin filter */
  465. value = slapi_entry_attr_get_charptr(e, MEP_FILTER_TYPE);
  466. if (value) {
  467. /* Convert to a Slapi_Filter to improve performance. */
  468. if (NULL == (entry->origin_filter = slapi_str2filter(value))) {
  469. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  470. "mep_parse_config_entry - Invalid search filter in "
  471. "%s config setting for config entry \"%s\" "
  472. "(filter = \"%s\").\n",
  473. MEP_FILTER_TYPE, slapi_sdn_get_dn(entry->sdn), value);
  474. ret = -1;
  475. }
  476. slapi_ch_free_string(&value);
  477. if (ret != 0) {
  478. goto bail;
  479. }
  480. } else {
  481. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  482. "mep_parse_config_entry - The %s config "
  483. "setting is required for config entry \"%s\".\n",
  484. MEP_FILTER_TYPE, slapi_sdn_get_dn(entry->sdn));
  485. ret = -1;
  486. goto bail;
  487. }
  488. /* Load the managed base */
  489. value = slapi_entry_attr_get_charptr(e, MEP_MANAGED_BASE_TYPE);
  490. if (value) {
  491. entry->managed_base = value;
  492. } else {
  493. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  494. "mep_parse_config_entry - The %s config "
  495. "setting is required for config entry \"%s\".\n",
  496. MEP_MANAGED_BASE_TYPE, slapi_sdn_get_dn(entry->sdn));
  497. ret = -1;
  498. goto bail;
  499. }
  500. /* Load the managed template */
  501. value = slapi_entry_attr_get_charptr(e, MEP_MANAGED_TEMPLATE_TYPE);
  502. if (value) {
  503. Slapi_Entry *test_entry = NULL;
  504. entry->template_sdn = slapi_sdn_new_dn_passin(value);
  505. value = NULL; /* entry->template_sdn owns value now */
  506. /* Fetch the managed entry template */
  507. slapi_search_internal_get_entry(entry->template_sdn, 0,
  508. &entry->template_entry, mep_get_plugin_id());
  509. if (entry->template_entry == NULL) {
  510. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  511. "mep_parse_config_entry - The managed entry "
  512. "template \"%s\" does not exist. Please "
  513. "add it or correct the %s config setting for "
  514. "config entry \"%s\"\n",
  515. slapi_sdn_get_dn(entry->template_sdn),
  516. MEP_MANAGED_TEMPLATE_TYPE, slapi_sdn_get_dn(entry->sdn));
  517. ret = -1;
  518. goto bail;
  519. }
  520. /* Validate the template entry by creating a test managed
  521. * entry and running a schema check on it */
  522. test_entry = mep_create_managed_entry(entry, NULL);
  523. if (test_entry == NULL) {
  524. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  525. "mep_parse_config_entry - Unable to create "
  526. "a test managed entry from managed entry "
  527. "template \"%s\". Please check the template "
  528. "entry for errors.\n",
  529. slapi_sdn_get_dn(entry->template_sdn));
  530. ret = -1;
  531. goto bail;
  532. }
  533. /* Check the schema */
  534. if (slapi_entry_schema_check(NULL, test_entry) != 0) {
  535. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  536. "mep_parse_config_entry - Test managed "
  537. "entry created from managed entry template "
  538. "\"%s\" violates the schema. Please check "
  539. "the template entry for schema errors.\n",
  540. slapi_sdn_get_dn(entry->template_sdn));
  541. slapi_entry_free(test_entry);
  542. ret = -1;
  543. goto bail;
  544. }
  545. /*
  546. * Extract the origin attrs from the template entry
  547. */
  548. entry->origin_attrs = mep_extract_origin_attrs(entry->template_entry);
  549. /* Dispose of the test entry */
  550. slapi_entry_free(test_entry);
  551. } else {
  552. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  553. "mep_parse_config_entry - The %s config "
  554. "setting is required for config entry \"%s\".\n",
  555. MEP_MANAGED_TEMPLATE_TYPE, slapi_sdn_get_dn(entry->sdn));
  556. ret = -1;
  557. goto bail;
  558. }
  559. /* If we were only called to validate config, we can
  560. * just bail out before applying the config changes */
  561. if (apply == 0) {
  562. goto bail;
  563. }
  564. /* Add the config object to the list. We order by scope. */
  565. if (!PR_CLIST_IS_EMPTY(g_mep_config)) {
  566. list = PR_LIST_HEAD(g_mep_config);
  567. while (list != g_mep_config) {
  568. config_entry = (struct configEntry *)list;
  569. /* If the config entry we are adding has a scope that is
  570. * a child of the scope of the current list item, we insert
  571. * the entry before that list item. */
  572. if (slapi_dn_issuffix(entry->origin_scope, config_entry->origin_scope)) {
  573. PR_INSERT_BEFORE(&(entry->list), list);
  574. slapi_log_err(SLAPI_LOG_CONFIG, MEP_PLUGIN_SUBSYSTEM,
  575. "mep_parse_config_entry - store [%s] before [%s] \n", slapi_sdn_get_dn(entry->sdn),
  576. slapi_sdn_get_dn(config_entry->sdn));
  577. entry_added = 1;
  578. break;
  579. }
  580. list = PR_NEXT_LINK(list);
  581. /* If we hit the end of the list, add to the tail. */
  582. if (g_mep_config == list) {
  583. PR_INSERT_BEFORE(&(entry->list), list);
  584. slapi_log_err(SLAPI_LOG_CONFIG, MEP_PLUGIN_SUBSYSTEM,
  585. "mep_parse_config_entry - store [%s] at tail\n", slapi_sdn_get_dn(entry->sdn));
  586. entry_added = 1;
  587. break;
  588. }
  589. }
  590. } else {
  591. /* first entry */
  592. PR_INSERT_LINK(&(entry->list), g_mep_config);
  593. slapi_log_err(SLAPI_LOG_CONFIG, MEP_PLUGIN_SUBSYSTEM,
  594. "mep_parse_config_entry - store [%s] at head \n", slapi_sdn_get_dn(entry->sdn));
  595. entry_added = 1;
  596. }
  597. bail:
  598. if (0 == entry_added) {
  599. /* Don't log error if we weren't asked to apply config */
  600. if ((apply != 0) && (entry != NULL)) {
  601. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  602. "mep_parse_config_entry - Invalid config entry "
  603. "[%s] skipped\n",
  604. slapi_sdn_get_dn(entry->sdn));
  605. }
  606. mep_free_config_entry(&entry);
  607. } else {
  608. ret = 0;
  609. }
  610. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  611. "<-- mep_parse_config_entry\n");
  612. return ret;
  613. }
  614. static void
  615. mep_free_config_entry(struct configEntry **entry)
  616. {
  617. struct configEntry *e = *entry;
  618. if (e == NULL)
  619. return;
  620. if (e->sdn) {
  621. slapi_log_err(SLAPI_LOG_CONFIG, MEP_PLUGIN_SUBSYSTEM,
  622. "mep_free_config_entry - Freeing config entry [%s]\n", slapi_sdn_get_dn(e->sdn));
  623. slapi_sdn_free(&e->sdn);
  624. }
  625. if (e->origin_scope) {
  626. slapi_ch_free_string(&e->origin_scope);
  627. }
  628. if (e->origin_filter) {
  629. slapi_filter_free(e->origin_filter, 1);
  630. }
  631. if (e->managed_base) {
  632. slapi_ch_free_string(&e->managed_base);
  633. }
  634. if (e->template_sdn) {
  635. slapi_sdn_free(&e->template_sdn);
  636. }
  637. if (e->template_entry) {
  638. slapi_entry_free(e->template_entry);
  639. }
  640. if (e->origin_attrs) {
  641. slapi_ch_array_free(e->origin_attrs);
  642. }
  643. slapi_ch_free((void **)entry);
  644. }
  645. static void
  646. mep_delete_configEntry(PRCList *entry)
  647. {
  648. PR_REMOVE_LINK(entry);
  649. mep_free_config_entry((struct configEntry **)&entry);
  650. }
  651. static void
  652. mep_delete_config(void)
  653. {
  654. PRCList *list;
  655. /* Delete the config cache. */
  656. while (!PR_CLIST_IS_EMPTY(g_mep_config)) {
  657. list = PR_LIST_HEAD(g_mep_config);
  658. mep_delete_configEntry(list);
  659. }
  660. return;
  661. }
  662. /*
  663. * Helper functions
  664. */
  665. /*
  666. * mep_parse_mapped_origin_attr()
  667. *
  668. * Parses a mapped attribute setting from a template and
  669. * grabs the attribute name and places it in origin_type.
  670. *
  671. * This is used to determine if a modify operation needs
  672. * to update the managed entry.
  673. */
  674. static int
  675. mep_parse_mapped_origin_attr(char *mapping, char **origin_type)
  676. {
  677. int ret = 0;
  678. char *p = NULL;
  679. char *end = NULL;
  680. char *var_start = NULL;
  681. /* reset the pointer for origin_type as this func is usually in a loop */
  682. *origin_type = NULL;
  683. /* split out the type from the value (use the first ':') */
  684. if ((p = strchr(mapping, ':')) == NULL) {
  685. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  686. "mep_parse_mapped_origin_attr - Value for mapped attribute "
  687. "is not in the correct format. (value: \"%s\").\n",
  688. mapping);
  689. ret = 1;
  690. goto bail;
  691. }
  692. /* Ensure the type is not empty. */
  693. if (p == mapping) {
  694. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  695. "mep_parse_mapped_origin_attr - Value for mapped attribute "
  696. "is not in the correct format. The type is missing. "
  697. "(value: \"%s\").\n",
  698. mapping);
  699. ret = 1;
  700. goto bail;
  701. }
  702. /* Terminate the type so we can use it as a string. */
  703. *p = '\0';
  704. /* Advance p to point to the beginning of the value. */
  705. p++;
  706. while (*p == ' ') {
  707. p++;
  708. }
  709. /* Make end point to the last character that we want in the value. */
  710. end = p + strlen(p) - 1;
  711. /* Find the variable that we need to substitute. */
  712. for (; p <= end; p++) {
  713. if (*p == '$') {
  714. if (p == end) {
  715. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  716. "mep_parse_mapped_origin_attr - Invalid mapped "
  717. "attribute value for type \"%s\".\n",
  718. mapping);
  719. ret = 1;
  720. goto bail;
  721. }
  722. if (*(p + 1) == '$') {
  723. /* This is an escaped $. Eliminate the escape character
  724. * to prevent if from being a part of the value. */
  725. p++;
  726. memmove(p, p + 1, end - (p + 1) + 1);
  727. *end = '\0';
  728. end--;
  729. } else {
  730. int quoted = 0;
  731. /* We found a variable. Terminate the pre
  732. * string and process the variable. */
  733. *p = '\0';
  734. p++;
  735. /* Check if the variable name is quoted. If it is, we skip past
  736. * the quoting brace to avoid putting it in the mapped value. */
  737. if (*p == '{') {
  738. quoted = 1;
  739. if (p < end) {
  740. p++;
  741. } else {
  742. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  743. "mep_parse_mapped_origin_attr - Invalid mapped "
  744. "attribute value for type \"%s\".\n",
  745. mapping);
  746. ret = 1;
  747. goto bail;
  748. }
  749. }
  750. /* We should be pointing at the variable name now. */
  751. var_start = p;
  752. /* Move the pointer to the end of the variable name. We
  753. * stop at the first character that is not legal for use
  754. * in an attribute description. */
  755. while ((p < end) && IS_ATTRDESC_CHAR(*p)) {
  756. p++;
  757. }
  758. /* If the variable is quoted and this is not a closing
  759. * brace, there is a syntax error in the mapping rule. */
  760. if (quoted && (*p != '}')) {
  761. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  762. "mep_parse_mapped_origin_attr - Invalid mapped "
  763. "attribute value for type \"%s\".\n",
  764. mapping);
  765. ret = 1;
  766. goto bail;
  767. }
  768. /* Check for a missing variable name. */
  769. if (p == var_start) {
  770. break;
  771. }
  772. if (p == end) {
  773. /* Set the map type. In this case, p could be
  774. * pointing at either the last character of the
  775. * map type, or at the first character after the
  776. * map type. If the character is valid for use
  777. * in an attribute description, we consider it
  778. * to be a part of the map type. */
  779. if (IS_ATTRDESC_CHAR(*p)) {
  780. *origin_type = strndup(var_start, p - var_start + 1);
  781. /* There is no post string. */
  782. } else {
  783. *origin_type = strndup(var_start, p - var_start);
  784. }
  785. } else {
  786. /* Set the map type. In this case, p is pointing
  787. * at the first character after the map type. */
  788. *origin_type = strndup(var_start, p - var_start);
  789. }
  790. /* We only support a single variable, so we're done. */
  791. break;
  792. }
  793. }
  794. }
  795. bail:
  796. if (ret != 0) {
  797. slapi_ch_free_string(origin_type);
  798. }
  799. return ret;
  800. }
  801. /*
  802. * mep_extract_origin_attrs
  803. *
  804. * Extract the attributes from the template that reside on
  805. * the origin entry that trigger updates to the managed entry.
  806. */
  807. static char **
  808. mep_extract_origin_attrs(Slapi_Entry *template)
  809. {
  810. char **vals = NULL;
  811. char *origin_type = NULL;
  812. char **origin_attrs = NULL;
  813. int i;
  814. if (template) {
  815. vals = slapi_entry_attr_get_charray(template, MEP_MAPPED_ATTR_TYPE);
  816. for (i = 0; vals && vals[i]; ++i) {
  817. if (mep_parse_mapped_origin_attr(vals[i], &origin_type) == 0) {
  818. slapi_ch_array_add(&origin_attrs, origin_type);
  819. }
  820. }
  821. slapi_ch_array_free(vals);
  822. }
  823. return origin_attrs;
  824. }
  825. /*
  826. * mep_is_mapped_origin_attr()
  827. *
  828. * Checks if type is a mapped origin attribute.
  829. */
  830. static int
  831. mep_is_mapped_origin_attr(char **vals, char *type)
  832. {
  833. int ret = 0;
  834. int i;
  835. if (type) {
  836. for (i = 0; vals && vals[i]; ++i) {
  837. if (slapi_attr_type_cmp(vals[i], type, SLAPI_TYPE_CMP_EXACT) == 0) {
  838. /* Ok, we are modifying a attribute that affects the managed entry */
  839. ret = 1;
  840. break;
  841. }
  842. }
  843. }
  844. return ret;
  845. }
  846. static Slapi_DN *
  847. mep_get_sdn(Slapi_PBlock *pb)
  848. {
  849. Slapi_DN *sdn = 0;
  850. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  851. "--> mep_get_sdn\n");
  852. slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
  853. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  854. "<-- mep_get_sdn\n");
  855. return sdn;
  856. }
  857. static void
  858. mep_set_config_area(Slapi_DN *sdn)
  859. {
  860. _ConfigAreaDN = sdn;
  861. }
  862. static Slapi_DN *
  863. mep_get_config_area(void)
  864. {
  865. return _ConfigAreaDN;
  866. }
  867. /*
  868. * mep_dn_is_config()
  869. *
  870. * Checks if dn is a managed entries config entry.
  871. */
  872. static int
  873. mep_dn_is_config(Slapi_DN *sdn)
  874. {
  875. int ret = 0;
  876. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  877. "--> mep_dn_is_config\n");
  878. if (sdn == NULL) {
  879. goto bail;
  880. }
  881. /* If an alternate config area is configured, treat it's child
  882. * entries as config entries. If the alternate config area is
  883. * not configured, treat children of the top-level plug-in
  884. * config entry as our config entries. */
  885. if (mep_get_config_area()) {
  886. if (slapi_sdn_issuffix(sdn, mep_get_config_area()) &&
  887. slapi_sdn_compare(sdn, mep_get_config_area())) {
  888. ret = 1;
  889. }
  890. } else {
  891. if (slapi_sdn_issuffix(sdn, mep_get_plugin_sdn()) &&
  892. slapi_sdn_compare(sdn, mep_get_plugin_sdn())) {
  893. ret = 1;
  894. }
  895. }
  896. bail:
  897. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  898. "<-- mep_dn_is_config\n");
  899. return ret;
  900. }
  901. /*
  902. * mep_dn_is_template()
  903. *
  904. * Checks if dn is a managed entries template.
  905. */
  906. static int
  907. mep_dn_is_template(Slapi_DN *sdn)
  908. {
  909. int ret = 0;
  910. PRCList *list = NULL;
  911. Slapi_DN *config_sdn = NULL;
  912. if (!PR_CLIST_IS_EMPTY(g_mep_config)) {
  913. list = PR_LIST_HEAD(g_mep_config);
  914. while (list != g_mep_config) {
  915. config_sdn = ((struct configEntry *)list)->template_sdn;
  916. if (slapi_sdn_compare(config_sdn, sdn) == 0) {
  917. ret = 1;
  918. break;
  919. } else {
  920. list = PR_NEXT_LINK(list);
  921. }
  922. }
  923. }
  924. return ret;
  925. }
  926. /*
  927. * mep_find_config()
  928. *
  929. * Finds the appropriate config entry for a given entry
  930. * by checking if the entry meets the origin scope and
  931. * filter requirements of any config entry. A read lock
  932. * must be held on the config before calling this function.
  933. * The configEntry that is returned is a pointer to the
  934. * actual config entry in the config cache. It should not
  935. * be modified in any way. The read lock should not be
  936. * released until you are finished with the config entry
  937. * that is returned.
  938. *
  939. * Returns NULL if no applicable config entry is found.
  940. */
  941. static void
  942. mep_find_config(Slapi_Entry *e, struct configEntry **config)
  943. {
  944. PRCList *list = NULL;
  945. char *dn = NULL;
  946. *config = NULL;
  947. if (e && !PR_CLIST_IS_EMPTY(g_mep_config)) {
  948. dn = slapi_entry_get_dn(e);
  949. list = PR_LIST_HEAD(g_mep_config);
  950. while (list != g_mep_config) {
  951. /* See if the dn is within the scope of this config entry
  952. * in addition to matching the origin filter. */
  953. if (slapi_dn_issuffix(dn, ((struct configEntry *)list)->origin_scope) &&
  954. (slapi_filter_test_simple(e, ((struct configEntry *)list)->origin_filter) == 0)) {
  955. *config = (struct configEntry *)list;
  956. break;
  957. }
  958. list = PR_NEXT_LINK(list);
  959. }
  960. }
  961. }
  962. /*
  963. * mep_find_config_by_template_dn()
  964. *
  965. * Finds the config entry associated with a particular
  966. * template dn. A read lock must be held on the config
  967. * before calling this function. The configEntry that
  968. * us returned is a pointer to the actual config entry
  969. * in the config cache. It should not be modified in
  970. * any way. The read lock should not be released until
  971. * you are finished with the config entry that is returned.
  972. *
  973. * Returns NULL if no applicable config entry is found.
  974. */
  975. static void
  976. mep_find_config_by_template_dn(Slapi_DN *template_sdn,
  977. struct configEntry **config)
  978. {
  979. PRCList *list = NULL;
  980. Slapi_DN *config_sdn = NULL;
  981. *config = NULL;
  982. if (!PR_CLIST_IS_EMPTY(g_mep_config)) {
  983. list = PR_LIST_HEAD(g_mep_config);
  984. while (list != g_mep_config) {
  985. config_sdn = ((struct configEntry *)list)->template_sdn;
  986. if (slapi_sdn_compare(config_sdn, template_sdn) == 0) {
  987. *config = (struct configEntry *)list;
  988. break;
  989. } else {
  990. list = PR_NEXT_LINK(list);
  991. }
  992. }
  993. }
  994. }
  995. /*
  996. * mep_oktodo()
  997. *
  998. * Check if we want to process this operation. We need to be
  999. * sure that the operation succeeded.
  1000. */
  1001. static int
  1002. mep_oktodo(Slapi_PBlock *pb)
  1003. {
  1004. int ret = 1;
  1005. int oprc = 0;
  1006. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  1007. "--> mep_oktodo\n");
  1008. if (slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0) {
  1009. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1010. "mep_oktodo: Could not get parameters\n");
  1011. ret = -1;
  1012. }
  1013. /* This plugin should only execute if the operation succeeded. */
  1014. if (oprc != 0) {
  1015. ret = 0;
  1016. }
  1017. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  1018. "<-- mep_oktodo\n");
  1019. return ret;
  1020. }
  1021. /*
  1022. * mep_isrepl()
  1023. *
  1024. * Returns 1 if the operation associated with pb
  1025. * is a replicated op. Returns 0 otherwise.
  1026. */
  1027. static int
  1028. mep_isrepl(Slapi_PBlock *pb)
  1029. {
  1030. int is_repl = 0;
  1031. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  1032. "--> mep_isrepl\n");
  1033. slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &is_repl);
  1034. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  1035. "<-- mep_isrepl\n");
  1036. return is_repl;
  1037. }
  1038. /*
  1039. * mep_create_managed_entry()
  1040. *
  1041. * Creates a managed entry from a specified template and origin
  1042. * entry. If an origin entry is not passed in, the values of
  1043. * mapped attributes will not be filled in and the addition of
  1044. * a backlink to the origin is not added. This is useful for
  1045. * creating a test managed entry for template validation.
  1046. */
  1047. static Slapi_Entry *
  1048. mep_create_managed_entry(struct configEntry *config, Slapi_Entry *origin)
  1049. {
  1050. Slapi_Entry *managed_entry = NULL;
  1051. Slapi_Entry *template = NULL;
  1052. char *rdn_type = NULL;
  1053. char **vals = NULL;
  1054. char *type = NULL;
  1055. char *value = NULL;
  1056. Slapi_Value *sval = NULL;
  1057. int found_rdn_map = 0;
  1058. int i = 0;
  1059. int err = 0;
  1060. /* If no template was supplied, there's nothing we can do. */
  1061. if ((config == NULL) || (config->template_entry == NULL)) {
  1062. return NULL;
  1063. } else {
  1064. template = config->template_entry;
  1065. }
  1066. /* Ensure that a RDN type was specified in the template. */
  1067. if ((rdn_type = slapi_entry_attr_get_charptr(template, MEP_RDN_ATTR_TYPE)) == NULL) {
  1068. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1069. "mep_create_managed_entry - The %s config attribute "
  1070. "was not found in template \"%s\". This attribute "
  1071. "is required.\n",
  1072. MEP_RDN_ATTR_TYPE, slapi_sdn_get_dn(config->template_sdn));
  1073. err = 1;
  1074. goto done;
  1075. }
  1076. /* Create the entry to be returned. */
  1077. managed_entry = slapi_entry_alloc();
  1078. slapi_entry_init(managed_entry, NULL, NULL);
  1079. /* Add all of the static attributes from the template to the newly
  1080. * created managed entry. */
  1081. vals = slapi_entry_attr_get_charray(template, MEP_STATIC_ATTR_TYPE);
  1082. for (i = 0; vals && vals[i]; ++i) {
  1083. struct berval bvtype = {0, NULL}, bvvalue = {0, NULL};
  1084. int freeval = 0;
  1085. if (slapi_ldif_parse_line(vals[i], &bvtype, &bvvalue, &freeval) != 0) {
  1086. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1087. "mep_create_managed_entry - Value for %s config setting "
  1088. "is not in the correct format in template \"%s\". "
  1089. "(value: \"%s\")\n",
  1090. MEP_STATIC_ATTR_TYPE,
  1091. slapi_sdn_get_dn(config->template_sdn), vals[i]);
  1092. err = 1;
  1093. goto done;
  1094. } else {
  1095. /* Create a berval and add the value to the entry. */
  1096. sval = slapi_value_new_berval(&bvvalue);
  1097. slapi_entry_add_value(managed_entry, bvtype.bv_val, sval);
  1098. slapi_value_free(&sval);
  1099. /* Set type and value to NULL so they don't get
  1100. * free'd by mep_parse_mapped_attr(). */
  1101. if (freeval) {
  1102. slapi_ch_free_string(&bvvalue.bv_val);
  1103. }
  1104. type = NULL;
  1105. value = NULL;
  1106. }
  1107. }
  1108. /* Clear out vals so we can use them again */
  1109. slapi_ch_array_free(vals);
  1110. /* Add the mapped attributes to the newly created managed entry. */
  1111. vals = slapi_entry_attr_get_charray(template, MEP_MAPPED_ATTR_TYPE);
  1112. for (i = 0; vals && vals[i]; ++i) {
  1113. if (mep_parse_mapped_attr(vals[i], origin, &type, &value) == 0) {
  1114. /* Add the attribute to the managed entry. */
  1115. slapi_entry_add_string(managed_entry, type, value);
  1116. /* Check if this type is the RDN type. */
  1117. if (slapi_attr_type_cmp(type, rdn_type, SLAPI_TYPE_CMP_EXACT) == 0) {
  1118. found_rdn_map = 1;
  1119. }
  1120. slapi_ch_free_string(&type);
  1121. slapi_ch_free_string(&value);
  1122. } else {
  1123. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1124. "mep_create_managed_entry - Error parsing mapped attribute "
  1125. "in template \"%s\".\n",
  1126. slapi_sdn_get_dn(config->template_sdn));
  1127. err = 1;
  1128. goto done;
  1129. }
  1130. }
  1131. /* The RDN attribute must be a mapped attribute. If we didn't find it,
  1132. * we need to bail. */
  1133. if (!found_rdn_map) {
  1134. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1135. "mep_create_managed_entry - The RDN type \"%s\" "
  1136. "was not found as a mapped attribute in template "
  1137. "\"%s\". It must be a mapped attribute.\n",
  1138. rdn_type, slapi_sdn_get_dn(config->template_sdn));
  1139. err = 1;
  1140. goto done;
  1141. } else {
  1142. /* Build the DN and set it in the entry. */
  1143. char **rdn_vals = NULL;
  1144. char *rdn_val = NULL;
  1145. char *dn = NULL;
  1146. /* If an origin entry was supplied, the RDN value will be
  1147. * the mapped value. If no origin entry was supplied, the
  1148. * value will be the mapping rule from the template. */
  1149. if (origin) {
  1150. const char *origin_dn = slapi_entry_get_dn(origin);
  1151. rdn_vals = slapi_ldap_explode_dn(origin_dn, 1);
  1152. rdn_val = rdn_vals[0];
  1153. } else {
  1154. rdn_val = slapi_entry_attr_get_charptr(managed_entry, rdn_type);
  1155. }
  1156. /* Create the DN using the mapped RDN value
  1157. * and the base specified in the config. */
  1158. dn = slapi_ch_smprintf("%s=%s,%s", rdn_type, rdn_val, config->managed_base);
  1159. if (origin) {
  1160. slapi_ldap_value_free(rdn_vals);
  1161. } else {
  1162. slapi_ch_free_string(&rdn_val);
  1163. }
  1164. if (dn != NULL) {
  1165. slapi_sdn_set_dn_passin(slapi_entry_get_sdn(managed_entry), dn);
  1166. } else {
  1167. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1168. "mep_create_managed_entry - Error setting DN "
  1169. "in managed entry based off of template entry "
  1170. "\"%s\" (origin entry \"%s\").\n",
  1171. slapi_sdn_get_dn(config->template_sdn),
  1172. origin ? slapi_entry_get_dn(origin) : "NULL");
  1173. err = 1;
  1174. goto done;
  1175. }
  1176. }
  1177. /* If an origin entry was supplied, set a backpointer to the
  1178. * origin in the managed entry. */
  1179. if (origin) {
  1180. slapi_entry_add_string(managed_entry,
  1181. SLAPI_ATTR_OBJECTCLASS, MEP_MANAGED_OC);
  1182. slapi_entry_add_string(managed_entry, MEP_MANAGED_BY_TYPE,
  1183. slapi_entry_get_dn(origin));
  1184. }
  1185. done:
  1186. slapi_ch_array_free(vals);
  1187. slapi_ch_free_string(&rdn_type);
  1188. if (err != 0) {
  1189. slapi_entry_free(managed_entry);
  1190. managed_entry = NULL;
  1191. }
  1192. return managed_entry;
  1193. }
  1194. /*
  1195. * mep_add_managed_entry()
  1196. *
  1197. * Creates and adds a managed entry to the database. The
  1198. * origin entry will also be modified to add a link to the
  1199. * newly created managed entry.
  1200. */
  1201. static int
  1202. mep_add_managed_entry(struct configEntry *config,
  1203. Slapi_Entry *origin)
  1204. {
  1205. Slapi_Entry *managed_entry = NULL;
  1206. char *managed_dn = NULL;
  1207. Slapi_PBlock *mod_pb = slapi_pblock_new();
  1208. int result = LDAP_SUCCESS;
  1209. /* Create the managed entry */
  1210. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  1211. "mep_add_managed_entry - Creating a managed "
  1212. "entry from origin entry \"%s\" using "
  1213. "config \"%s\".\n",
  1214. slapi_entry_get_dn(origin),
  1215. slapi_sdn_get_dn(config->sdn));
  1216. managed_entry = mep_create_managed_entry(config, origin);
  1217. if (managed_entry == NULL) {
  1218. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1219. "mep_add_managed_entry - Unable to create a managed "
  1220. "entry from origin entry \"%s\" using config "
  1221. "\"%s\".\n",
  1222. slapi_entry_get_dn(origin), slapi_sdn_get_dn(config->sdn));
  1223. result = -1;
  1224. goto bail;
  1225. } else {
  1226. /* Copy the managed entry DN to use when
  1227. * creating the pointer attribute. */
  1228. managed_dn = slapi_ch_strdup(slapi_entry_get_dn(managed_entry));
  1229. /* Add managed entry to db. The entry will be consumed. */
  1230. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  1231. "mep_add_managed_entry - Adding managed entry \"%s\" for origin "
  1232. "entry \"%s\"\n.",
  1233. managed_dn, slapi_entry_get_dn(origin));
  1234. slapi_add_entry_internal_set_pb(mod_pb, managed_entry, NULL,
  1235. mep_get_plugin_id(), 0);
  1236. slapi_add_internal_pb(mod_pb);
  1237. slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  1238. if (result != LDAP_SUCCESS) {
  1239. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1240. "mep_add_managed_entry - Unable to add managed "
  1241. "entry \"%s\" for origin entry \"%s\" (%s).\n",
  1242. managed_dn, slapi_entry_get_dn(origin),
  1243. ldap_err2string(result));
  1244. goto bail;
  1245. } else {
  1246. /* Add forward link to origin entry. */
  1247. LDAPMod oc_mod;
  1248. LDAPMod pointer_mod;
  1249. LDAPMod *mods[2];
  1250. char *oc_vals[2];
  1251. char *pointer_vals[2];
  1252. /* Clear out the pblock for reuse. */
  1253. slapi_pblock_init(mod_pb);
  1254. /*
  1255. * Add the origin entry objectclass. A modrdn might result in
  1256. * an err 20 (type or value exists), in which case just ignore it.
  1257. */
  1258. oc_vals[0] = MEP_ORIGIN_OC;
  1259. oc_vals[1] = 0;
  1260. oc_mod.mod_op = LDAP_MOD_ADD;
  1261. oc_mod.mod_type = SLAPI_ATTR_OBJECTCLASS;
  1262. oc_mod.mod_values = oc_vals;
  1263. mods[0] = &oc_mod;
  1264. mods[1] = NULL;
  1265. /* add the objectclass */
  1266. slapi_modify_internal_set_pb_ext(mod_pb, slapi_entry_get_sdn(origin),
  1267. mods, 0, 0, mep_get_plugin_id(), 0);
  1268. slapi_modify_internal_pb(mod_pb);
  1269. slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  1270. if (result != LDAP_SUCCESS && result != LDAP_TYPE_OR_VALUE_EXISTS) {
  1271. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1272. "mep_add_managed_entry - Failed to add managed entry "
  1273. "objectclass in origin entry \"%s\", error (%s)\n",
  1274. slapi_entry_get_dn(origin), ldap_err2string(result));
  1275. goto bail;
  1276. }
  1277. slapi_pblock_init(mod_pb);
  1278. /*
  1279. * Now, add a pointer to the managed entry.
  1280. */
  1281. pointer_vals[0] = managed_dn;
  1282. pointer_vals[1] = 0;
  1283. pointer_mod.mod_op = LDAP_MOD_ADD;
  1284. pointer_mod.mod_type = MEP_MANAGED_ENTRY_TYPE;
  1285. pointer_mod.mod_values = pointer_vals;
  1286. mods[0] = &pointer_mod;
  1287. mods[1] = NULL;
  1288. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  1289. "mep_add_managed_entry - Adding %s pointer to \"%s\" in entry \"%s\"\n.",
  1290. MEP_MANAGED_ENTRY_TYPE, managed_dn, slapi_entry_get_dn(origin));
  1291. slapi_modify_internal_set_pb_ext(mod_pb, slapi_entry_get_sdn(origin),
  1292. mods, 0, 0, mep_get_plugin_id(), 0);
  1293. slapi_modify_internal_pb(mod_pb);
  1294. slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  1295. if (result != LDAP_SUCCESS) {
  1296. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1297. "mep_add_managed_entry - Unable to add pointer to "
  1298. "managed entry \"%s\" in origin entry \"%s\" "
  1299. "(%s).\n",
  1300. managed_dn, slapi_entry_get_dn(origin),
  1301. ldap_err2string(result));
  1302. }
  1303. }
  1304. }
  1305. bail:
  1306. slapi_ch_free_string(&managed_dn);
  1307. slapi_pblock_destroy(mod_pb);
  1308. return result;
  1309. }
  1310. /* mep_rename_managed_entry()
  1311. *
  1312. * Renames a managed entry and updates the pointer in the
  1313. * origin entry.
  1314. */
  1315. static int
  1316. mep_rename_managed_entry(Slapi_Entry *origin,
  1317. Slapi_DN *new_dn,
  1318. Slapi_DN *old_dn)
  1319. {
  1320. Slapi_RDN *srdn = slapi_rdn_new();
  1321. Slapi_PBlock *mep_pb = slapi_pblock_new();
  1322. LDAPMod mod;
  1323. LDAPMod *mods[2];
  1324. char *vals[2];
  1325. int result = LDAP_SUCCESS;
  1326. /* Just bail if any of our parameters are NULL. */
  1327. if (origin == NULL || new_dn == NULL || old_dn == NULL) {
  1328. goto bail;
  1329. }
  1330. /* Create new RDN */
  1331. slapi_rdn_set_dn(srdn, slapi_sdn_get_ndn(new_dn));
  1332. /* Rename the managed entry. */
  1333. slapi_rename_internal_set_pb_ext(mep_pb, old_dn,
  1334. slapi_rdn_get_rdn(srdn),
  1335. NULL, 1, NULL, NULL, mep_get_plugin_id(), 0);
  1336. slapi_modrdn_internal_pb(mep_pb);
  1337. slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  1338. if (result != LDAP_SUCCESS) {
  1339. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1340. "mep_rename_managed_entry - Unable to rename managed "
  1341. "entry \"%s\" to \"%s\" (%s).\n",
  1342. slapi_sdn_get_dn(old_dn),
  1343. slapi_sdn_get_dn(new_dn), ldap_err2string(result));
  1344. } else {
  1345. /* Clear out the pblock for reuse. */
  1346. slapi_pblock_init(mep_pb);
  1347. /* Update the link to the managed entry in the origin entry. */
  1348. vals[0] = (char *)slapi_sdn_get_dn(new_dn);
  1349. vals[1] = 0;
  1350. mod.mod_op = LDAP_MOD_REPLACE;
  1351. mod.mod_type = MEP_MANAGED_ENTRY_TYPE;
  1352. mod.mod_values = vals;
  1353. mods[0] = &mod;
  1354. mods[1] = 0;
  1355. /* Perform the modify operation. */
  1356. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  1357. "mep_rename_managed_entry - Updating %s pointer to "
  1358. "\"%s\" in entry \"%s\"\n.",
  1359. MEP_MANAGED_ENTRY_TYPE,
  1360. vals[0], slapi_entry_get_dn(origin));
  1361. slapi_modify_internal_set_pb_ext(mep_pb, slapi_entry_get_sdn(origin),
  1362. mods, 0, 0, mep_get_plugin_id(), 0);
  1363. slapi_modify_internal_pb(mep_pb);
  1364. slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  1365. if (result != LDAP_SUCCESS) {
  1366. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1367. "mep_rename_managed_entry - Unable to update %s "
  1368. "pointer in entry \"%s\" (%s).\n",
  1369. MEP_MANAGED_ENTRY_TYPE,
  1370. slapi_entry_get_dn(origin), ldap_err2string(result));
  1371. }
  1372. }
  1373. bail:
  1374. slapi_rdn_free(&srdn);
  1375. slapi_pblock_destroy(mep_pb);
  1376. return result;
  1377. }
  1378. /*
  1379. * mep_get_mapped_mods()
  1380. *
  1381. * Creates the modifications needed to update the mapped values
  1382. * in a managed entry. It is up to the caller to free the
  1383. * returned mods when it is finished using them.
  1384. */
  1385. static Slapi_Mods *
  1386. mep_get_mapped_mods(struct configEntry *config,
  1387. Slapi_Entry *origin,
  1388. char **mapped_dn)
  1389. {
  1390. Slapi_Mods *smods = NULL;
  1391. Slapi_Entry *template = NULL;
  1392. Slapi_Attr *attr = NULL;
  1393. char **vals = NULL;
  1394. char *type = NULL;
  1395. char *value = NULL;
  1396. char *rdn_type = NULL;
  1397. int i = 0;
  1398. /* If no template was supplied, there's nothing we can do. */
  1399. if (origin == NULL || config == NULL || config->template_entry == NULL) {
  1400. return NULL;
  1401. } else {
  1402. template = config->template_entry;
  1403. }
  1404. /* See how many mods we will have and initialize the smods. */
  1405. if (slapi_entry_attr_find(config->template_entry, MEP_MAPPED_ATTR_TYPE, &attr) == 0) {
  1406. int numvals = 0;
  1407. slapi_attr_get_numvalues(attr, &numvals);
  1408. smods = slapi_mods_new();
  1409. slapi_mods_init(smods, numvals);
  1410. }
  1411. /* Find the the RDN type for the managed entry. */
  1412. if ((rdn_type = slapi_entry_attr_get_charptr(template, MEP_RDN_ATTR_TYPE)) == NULL) {
  1413. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1414. "mep_get_mapped_mods - Error getting RDN type from tempate "
  1415. "\"%s\".\n",
  1416. slapi_sdn_get_dn(config->template_sdn));
  1417. slapi_mods_free(&smods);
  1418. goto bail;
  1419. }
  1420. /* Go through the template and find the mapped attrs. */
  1421. vals = slapi_entry_attr_get_charray(template, MEP_MAPPED_ATTR_TYPE);
  1422. for (i = 0; vals && vals[i]; ++i) {
  1423. if (mep_parse_mapped_attr(vals[i], origin, &type, &value) == 0) {
  1424. /* Don't attempt to modify the RDN type, but create
  1425. * the mapped DN if requested. It is up to the caller
  1426. * to free the returned DN. */
  1427. if (slapi_attr_type_cmp(type, rdn_type, SLAPI_TYPE_CMP_EXACT) == 0) {
  1428. if (mapped_dn) {
  1429. *mapped_dn = slapi_create_dn_string("%s=%s,%s", rdn_type,
  1430. value, config->managed_base);
  1431. }
  1432. } else {
  1433. /* Add a modify that replaces all values with the new value. */
  1434. slapi_mods_add_string(smods, LDAP_MOD_REPLACE, type, value);
  1435. }
  1436. slapi_ch_free_string(&type);
  1437. slapi_ch_free_string(&value);
  1438. } else {
  1439. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1440. "mep_get_mapped_mods - Error parsing mapped attribute "
  1441. "in template \"%s\".\n",
  1442. slapi_sdn_get_dn(config->template_sdn));
  1443. slapi_mods_free(&smods);
  1444. goto bail;
  1445. }
  1446. }
  1447. bail:
  1448. slapi_ch_free_string(&rdn_type);
  1449. slapi_ch_array_free(vals);
  1450. return smods;
  1451. }
  1452. /*
  1453. * mep_parse_mapped_attr()
  1454. *
  1455. * Parses a mapped attribute setting from a template and
  1456. * fills in the type and value based off of the origin
  1457. * entry. If an origin entry is not supplied, the value
  1458. * is simply the mapping rule.
  1459. */
  1460. static int
  1461. mep_parse_mapped_attr(char *mapping, Slapi_Entry *origin, char **type, char **value)
  1462. {
  1463. int ret = 0;
  1464. char *p = NULL;
  1465. char *pre_str = NULL;
  1466. char *post_str = NULL;
  1467. char *end = NULL;
  1468. char *var_start = NULL;
  1469. char *map_type = NULL;
  1470. /* Clear out any existing type or value. */
  1471. slapi_ch_free_string(type);
  1472. slapi_ch_free_string(value);
  1473. /* split out the type from the value (use the first ':') */
  1474. if ((p = strchr(mapping, ':')) == NULL) {
  1475. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1476. "mep_parse_mapped_attr - Value for mapped attribute "
  1477. "is not in the correct format. (value: \"%s\").\n",
  1478. mapping);
  1479. ret = 1;
  1480. goto bail;
  1481. }
  1482. /* Ensure the type is not empty. */
  1483. if (p == mapping) {
  1484. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1485. "mep_parse_mapped_attr - Value for mapped attribute "
  1486. "is not in the correct format. The type is missing. "
  1487. "(value: \"%s\").\n",
  1488. mapping);
  1489. ret = 1;
  1490. goto bail;
  1491. }
  1492. /* Terminate the type so we can use it as a string. */
  1493. *p = '\0';
  1494. /* Duplicate the type to be returned. */
  1495. *type = slapi_ch_strdup(mapping);
  1496. /* Advance p to point to the beginning of the value. */
  1497. p++;
  1498. while (*p == ' ') {
  1499. p++;
  1500. }
  1501. pre_str = p;
  1502. /* Make end point to the last character that we want in the value. */
  1503. end = p + strlen(p) - 1;
  1504. /* Find the variable that we need to substitute. */
  1505. for (; p <= end; p++) {
  1506. if (*p == '$') {
  1507. if (p == end) {
  1508. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1509. "mep_parse_mapped_attr - Invalid mapped "
  1510. "attribute value for type \"%s\".\n",
  1511. mapping);
  1512. ret = 1;
  1513. goto bail;
  1514. }
  1515. if (*(p + 1) == '$') {
  1516. /* This is an escaped $. Eliminate the escape character
  1517. * to prevent if from being a part of the value. */
  1518. p++;
  1519. memmove(p, p + 1, end - (p + 1) + 1);
  1520. *end = '\0';
  1521. end--;
  1522. } else {
  1523. int quoted = 0;
  1524. /* We found a variable. Terminate the pre
  1525. * string and process the variable. */
  1526. *p = '\0';
  1527. p++;
  1528. /* Check if the variable name is quoted. If it is, we skip past
  1529. * the quoting brace to avoid putting it in the mapped value. */
  1530. if (*p == '{') {
  1531. quoted = 1;
  1532. if (p < end) {
  1533. p++;
  1534. } else {
  1535. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1536. "mep_parse_mapped_attr - Invalid mapped "
  1537. "attribute value for type \"%s\".\n",
  1538. mapping);
  1539. ret = 1;
  1540. goto bail;
  1541. }
  1542. }
  1543. /* We should be pointing at the variable name now. */
  1544. var_start = p;
  1545. /* Move the pointer to the end of the variable name. We
  1546. * stop at the first character that is not legal for use
  1547. * in an attribute description. */
  1548. while ((p < end) && IS_ATTRDESC_CHAR(*p)) {
  1549. p++;
  1550. }
  1551. /* If the variable is quoted and this is not a closing
  1552. * brace, there is a syntax error in the mapping rule. */
  1553. if (quoted && (*p != '}')) {
  1554. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1555. "mep_parse_mapped_attr - Invalid mapped "
  1556. "attribute value for type \"%s\".\n",
  1557. mapping);
  1558. ret = 1;
  1559. goto bail;
  1560. }
  1561. /* Check for a missing variable name. */
  1562. if (p == var_start) {
  1563. break;
  1564. }
  1565. if (p == end) {
  1566. /* Set the map type. In this case, p could be
  1567. * pointing at either the last character of the
  1568. * map type, or at the first character after the
  1569. * map type. If the character is valid for use
  1570. * in an attribute description, we consider it
  1571. * to be a part of the map type. */
  1572. if (IS_ATTRDESC_CHAR(*p)) {
  1573. map_type = strndup(var_start, p - var_start + 1);
  1574. /* There is no post string. */
  1575. post_str = NULL;
  1576. } else {
  1577. map_type = strndup(var_start, p - var_start);
  1578. post_str = p;
  1579. }
  1580. } else {
  1581. /* Set the map type. In this case, p is pointing
  1582. * at the first character after the map type. */
  1583. map_type = strndup(var_start, p - var_start);
  1584. /* If the variable is quoted, don't include
  1585. * the closing brace in the post string. */
  1586. if (quoted) {
  1587. post_str = p + 1;
  1588. } else {
  1589. post_str = p;
  1590. }
  1591. }
  1592. /* Process the post string to remove any escapes. */
  1593. for (p = post_str; p && (p <= end); p++) {
  1594. if (*p == '$') {
  1595. if ((p == end) || (*(p + 1) != '$')) {
  1596. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1597. "mep_parse_mapped_attr - Invalid mapped "
  1598. "attribute value for type \"%s\".\n",
  1599. mapping);
  1600. ret = 1;
  1601. goto bail;
  1602. } else {
  1603. /* This is an escaped '$'. Remove the escape char. */
  1604. p++;
  1605. memmove(p, p + 1, end - (p + 1) + 1);
  1606. *end = '\0';
  1607. end--;
  1608. }
  1609. }
  1610. }
  1611. /* We only support a single variable, so we're done. */
  1612. break;
  1613. }
  1614. }
  1615. }
  1616. if (map_type) {
  1617. if (origin) {
  1618. char *map_val = NULL;
  1619. int freeit = 0;
  1620. /* If the map type is dn, fetch the origin dn. */
  1621. if (slapi_attr_type_cmp(map_type, "dn", SLAPI_TYPE_CMP_EXACT) == 0) {
  1622. map_val = slapi_entry_get_ndn(origin);
  1623. } else {
  1624. map_val = slapi_entry_attr_get_charptr(origin, map_type);
  1625. freeit = 1;
  1626. }
  1627. if (map_val) {
  1628. /* Create the new mapped value. */
  1629. *value = slapi_ch_smprintf("%s%s%s", pre_str,
  1630. map_val, post_str ? post_str : "");
  1631. if (freeit) {
  1632. slapi_ch_free_string(&map_val);
  1633. }
  1634. } else {
  1635. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1636. "mep_parse_mapped_attr - Mapped attribute \"%s\" "
  1637. "is not present in origin entry \"%s\". Please "
  1638. "correct template to only map attributes "
  1639. "required by the schema.\n",
  1640. map_type,
  1641. slapi_entry_get_dn(origin));
  1642. ret = 1;
  1643. goto bail;
  1644. }
  1645. } else {
  1646. /* Just use the mapping since we have no origin entry. */
  1647. *value = slapi_ch_smprintf("%s$%s%s", pre_str, map_type,
  1648. post_str);
  1649. }
  1650. } else {
  1651. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1652. "mep_parse_mapped_attr - No variable found in "
  1653. "mapped attribute value for type \"%s\".\n",
  1654. mapping);
  1655. ret = 1;
  1656. goto bail;
  1657. }
  1658. bail:
  1659. slapi_ch_free_string(&map_type);
  1660. if (ret != 0) {
  1661. slapi_ch_free_string(type);
  1662. slapi_ch_free_string(value);
  1663. }
  1664. return ret;
  1665. }
  1666. /*
  1667. * mep_is_managed_entry()
  1668. *
  1669. * Returns 1 if the entry is a managed entry, 0 otherwise.
  1670. * The check is performed by seeing if the managed entry
  1671. * objectclass is present.
  1672. */
  1673. static int
  1674. mep_is_managed_entry(Slapi_Entry *e)
  1675. {
  1676. int ret = 0;
  1677. Slapi_Attr *attr = NULL;
  1678. struct berval bv;
  1679. bv.bv_val = MEP_MANAGED_OC;
  1680. bv.bv_len = strlen(bv.bv_val);
  1681. if (e && (slapi_entry_attr_find(e, SLAPI_ATTR_OBJECTCLASS, &attr) == 0)) {
  1682. if (slapi_attr_value_find(attr, &bv) == 0) {
  1683. ret = 1;
  1684. }
  1685. }
  1686. return ret;
  1687. }
  1688. /*
  1689. * mep_is_mapped_attr()
  1690. *
  1691. * Checks if type is defined as a mapped attribute in template.
  1692. */
  1693. static int
  1694. mep_is_mapped_attr(Slapi_Entry *template, char *type)
  1695. {
  1696. int ret = 0;
  1697. int i = 0;
  1698. char **vals = NULL;
  1699. char *map_type = NULL;
  1700. char *value = NULL;
  1701. if (template && type) {
  1702. vals = slapi_entry_attr_get_charray(template, MEP_MAPPED_ATTR_TYPE);
  1703. for (i = 0; vals && vals[i]; ++i) {
  1704. if (mep_parse_mapped_attr(vals[i], NULL, &map_type, &value) == 0) {
  1705. if (slapi_attr_type_cmp(map_type, type, SLAPI_TYPE_CMP_EXACT) == 0) {
  1706. ret = 1;
  1707. }
  1708. slapi_ch_free_string(&map_type);
  1709. slapi_ch_free_string(&value);
  1710. /* If we found a match, we're done. */
  1711. if (ret == 1) {
  1712. break;
  1713. }
  1714. }
  1715. }
  1716. slapi_ch_array_free(vals);
  1717. }
  1718. return ret;
  1719. }
  1720. /*
  1721. * Operation callback functions
  1722. */
  1723. /*
  1724. * mep_pre_op()
  1725. *
  1726. * Checks if an operation is modifying the managed
  1727. * entries config and validates the config changes.
  1728. */
  1729. static int
  1730. mep_pre_op(Slapi_PBlock *pb, int modop)
  1731. {
  1732. Slapi_DN *sdn = NULL;
  1733. Slapi_Entry *e = 0;
  1734. Slapi_Mods *smods = 0;
  1735. LDAPMod **mods;
  1736. int free_entry = 0;
  1737. char *errstr = NULL;
  1738. struct configEntry *config = NULL;
  1739. void *caller_id = NULL;
  1740. int ret = SLAPI_PLUGIN_SUCCESS;
  1741. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  1742. "--> mep_pre_op\n");
  1743. /* See if we're calling ourselves. */
  1744. slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &caller_id);
  1745. if (0 == (sdn = mep_get_sdn(pb)))
  1746. goto bail;
  1747. if (mep_dn_is_config(sdn)) {
  1748. /* Validate config changes, but don't apply them.
  1749. * This allows us to reject invalid config changes
  1750. * here at the pre-op stage. Applying the config
  1751. * needs to be done at the post-op stage. */
  1752. if (LDAP_CHANGETYPE_ADD == modop) {
  1753. slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e);
  1754. } else if (LDAP_CHANGETYPE_MODIFY == modop) {
  1755. /* Fetch the entry being modified so we can
  1756. * create the resulting entry for validation. */
  1757. if (sdn) {
  1758. slapi_search_internal_get_entry(sdn, 0, &e, mep_get_plugin_id());
  1759. free_entry = 1;
  1760. }
  1761. /* If the entry doesn't exist, just bail and
  1762. * let the server handle it. */
  1763. if (e == NULL) {
  1764. goto bail;
  1765. }
  1766. /* Grab the mods. */
  1767. slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
  1768. smods = slapi_mods_new();
  1769. slapi_mods_init_byref(smods, mods);
  1770. /* Apply the mods to create the resulting entry. */
  1771. if (mods && (slapi_entry_apply_mods(e, mods) != LDAP_SUCCESS)) {
  1772. /* The mods don't apply cleanly, so we just let this op go
  1773. * to let the main server handle it. */
  1774. goto bailmod;
  1775. }
  1776. } else if (LDAP_CHANGETYPE_DELETE == modop) {
  1777. /* we allow for deletes, so goto bail to we can skip the config parsing */
  1778. goto bail;
  1779. } else {
  1780. /* Refuse other operations. */
  1781. ret = LDAP_UNWILLING_TO_PERFORM;
  1782. errstr = slapi_ch_smprintf("Not a valid operation.");
  1783. goto bail;
  1784. }
  1785. if (mep_parse_config_entry(e, 0) != 0) {
  1786. /* Refuse the operation if config parsing failed. */
  1787. ret = LDAP_UNWILLING_TO_PERFORM;
  1788. if (LDAP_CHANGETYPE_ADD == modop) {
  1789. errstr = slapi_ch_smprintf("Not a valid managed entries configuration entry.");
  1790. } else {
  1791. errstr = slapi_ch_smprintf("Changes result in an invalid "
  1792. "managed entries configuration.");
  1793. }
  1794. }
  1795. } else {
  1796. /* Check if an active template entry is being updated. If so, validate it. */
  1797. mep_config_read_lock();
  1798. /* Bail out if the plug-in close function was just called. */
  1799. if (!slapi_plugin_running(pb)) {
  1800. mep_config_unlock();
  1801. goto bail;
  1802. }
  1803. mep_find_config_by_template_dn(sdn, &config);
  1804. if (config) {
  1805. Slapi_Entry *test_entry = NULL;
  1806. struct configEntry *config_copy = NULL;
  1807. config_copy = (struct configEntry *)slapi_ch_calloc(1, sizeof(struct configEntry));
  1808. /* Make a temporary copy of the config to use for validation. */
  1809. config_copy->sdn = slapi_sdn_dup(config->sdn);
  1810. config_copy->managed_base = slapi_ch_strdup(config->managed_base);
  1811. config_copy->template_sdn = slapi_sdn_dup(config->template_sdn);
  1812. /* Reject attempts to delete or rename an active template.
  1813. * Validate changes to an active template. */
  1814. switch (modop) {
  1815. case LDAP_CHANGETYPE_DELETE:
  1816. errstr = slapi_ch_smprintf("Deleting an active managed "
  1817. "entries template is not allowed. "
  1818. "Delete the associated config "
  1819. "entry first.");
  1820. ret = LDAP_UNWILLING_TO_PERFORM;
  1821. break;
  1822. case LDAP_CHANGETYPE_MODDN:
  1823. errstr = slapi_ch_smprintf("Renaming an active managed "
  1824. "entries template is not allowed. "
  1825. "Create a new template and modify "
  1826. "the associated config entry instead.");
  1827. ret = LDAP_UNWILLING_TO_PERFORM;
  1828. break;
  1829. case LDAP_CHANGETYPE_MODIFY:
  1830. /* Fetch the existing template entry. */
  1831. if (sdn) {
  1832. slapi_search_internal_get_entry(sdn, 0, &e, mep_get_plugin_id());
  1833. free_entry = 1;
  1834. }
  1835. /* If the entry doesn't exist, we just skip
  1836. * validation and let the server handle it. */
  1837. if (e) {
  1838. /* Grab the mods. */
  1839. slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
  1840. smods = slapi_mods_new();
  1841. slapi_mods_init_byref(smods, mods);
  1842. /* Apply the mods to create the resulting entry. */
  1843. if (mods && (slapi_entry_apply_mods(e, mods) == LDAP_SUCCESS)) {
  1844. /* Set the resulting template in the config copy.
  1845. * The ownership of the resulting entry is handed
  1846. * over to the config copy. */
  1847. config_copy->template_entry = e;
  1848. e = NULL;
  1849. /* Validate the changed template. */
  1850. test_entry = mep_create_managed_entry(config_copy, NULL);
  1851. if (test_entry == NULL) {
  1852. errstr = slapi_ch_smprintf("Changes result in an invalid "
  1853. "managed entries template.");
  1854. ret = LDAP_UNWILLING_TO_PERFORM;
  1855. } else if (slapi_entry_schema_check(NULL, test_entry) != 0) {
  1856. errstr = slapi_ch_smprintf("Changes result in an invalid "
  1857. "managed entries template due "
  1858. "to a schema violation.");
  1859. ret = LDAP_UNWILLING_TO_PERFORM;
  1860. }
  1861. }
  1862. }
  1863. /* Dispose of the test entry */
  1864. slapi_entry_free(test_entry);
  1865. break;
  1866. }
  1867. /* Free the config copy */
  1868. mep_free_config_entry(&config_copy);
  1869. }
  1870. mep_config_unlock();
  1871. /* If replication, just bail. */
  1872. if (mep_isrepl(pb)) {
  1873. goto bailmod;
  1874. }
  1875. /* Check if a managed entry is being deleted or
  1876. * renamed and reject if it's not being done by
  1877. * this plugin. */
  1878. if (((modop == LDAP_CHANGETYPE_DELETE) || (modop == LDAP_CHANGETYPE_MODDN) ||
  1879. (modop == LDAP_CHANGETYPE_MODIFY)) &&
  1880. (caller_id != mep_get_plugin_id())) {
  1881. Slapi_Entry *origin_e = NULL;
  1882. Slapi_Mod *smod = NULL;
  1883. Slapi_Mod *next_mod = NULL;
  1884. char *origin_dn = NULL;
  1885. Slapi_DN *origin_sdn = NULL;
  1886. /* Fetch the target entry. */
  1887. if (sdn) {
  1888. /* Free any existing entry so we don't leak it. */
  1889. if (e && free_entry) {
  1890. slapi_entry_free(e);
  1891. }
  1892. slapi_search_internal_get_entry(sdn, 0, &e, mep_get_plugin_id());
  1893. free_entry = 1;
  1894. }
  1895. if (e && mep_is_managed_entry(e)) {
  1896. if (modop == LDAP_CHANGETYPE_MODIFY) {
  1897. /* Fetch the origin entry so we can locate the config template. */
  1898. origin_dn = slapi_entry_attr_get_charptr(e, MEP_MANAGED_BY_TYPE);
  1899. if (origin_dn) {
  1900. origin_sdn = slapi_sdn_new_normdn_byref(origin_dn);
  1901. slapi_search_internal_get_entry(origin_sdn, 0,
  1902. &origin_e, mep_get_plugin_id());
  1903. slapi_sdn_free(&origin_sdn);
  1904. }
  1905. if (origin_e) {
  1906. /* Fetch the config. */
  1907. mep_config_read_lock();
  1908. /* Bail out if the plug-in close function was just called. */
  1909. if (!slapi_plugin_running(pb)) {
  1910. mep_config_unlock();
  1911. goto bail;
  1912. }
  1913. mep_find_config(origin_e, &config);
  1914. if (config) {
  1915. /* Get the mods if we haven't already. */
  1916. if (smods == NULL) {
  1917. slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
  1918. smods = slapi_mods_new();
  1919. slapi_mods_init_byref(smods, mods);
  1920. }
  1921. next_mod = slapi_mod_new();
  1922. smod = slapi_mods_get_first_smod(smods, next_mod);
  1923. while (smod) {
  1924. char *type = (char *)slapi_mod_get_type(smod);
  1925. /* If this is a mapped attribute, reject the op. */
  1926. if (mep_is_mapped_attr(config->template_entry, type)) {
  1927. errstr = slapi_ch_smprintf("Modifying a mapped attribute "
  1928. " in a managed entry is not allowed. "
  1929. "The \"%s\" attribute is mapped for "
  1930. "this entry.",
  1931. type);
  1932. ret = LDAP_UNWILLING_TO_PERFORM;
  1933. break;
  1934. }
  1935. slapi_mod_done(next_mod);
  1936. smod = slapi_mods_get_next_smod(smods, next_mod);
  1937. }
  1938. slapi_mod_free(&next_mod);
  1939. } else {
  1940. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1941. "mep_pre_op - Unable to fetch config for "
  1942. "origin entry \"%s\".\n",
  1943. origin_dn);
  1944. }
  1945. slapi_entry_free(origin_e);
  1946. mep_config_unlock();
  1947. } else {
  1948. Slapi_Operation *op;
  1949. slapi_pblock_get(pb, SLAPI_OPERATION, &op);
  1950. if (operation_is_flag_set(op, OP_FLAG_INTERNAL)) {
  1951. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  1952. "mep_pre_op - (internal operation) Unable to fetch "
  1953. "origin entry \"%s\".\n",
  1954. origin_dn);
  1955. } else {
  1956. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  1957. "mep_pre_op - Unable to fetch origin entry "
  1958. "\"%s\".\n",
  1959. origin_dn);
  1960. }
  1961. }
  1962. slapi_ch_free_string(&origin_dn);
  1963. } else {
  1964. errstr = slapi_ch_smprintf("%s a managed entry is not allowed. "
  1965. "It needs to be manually unlinked first.",
  1966. modop == LDAP_CHANGETYPE_DELETE ? "Deleting"
  1967. : "Renaming");
  1968. ret = LDAP_UNWILLING_TO_PERFORM;
  1969. }
  1970. }
  1971. }
  1972. }
  1973. bailmod:
  1974. /* Clean up smods. */
  1975. if (LDAP_CHANGETYPE_MODIFY == modop) {
  1976. slapi_mods_free(&smods);
  1977. }
  1978. bail:
  1979. if (free_entry && e)
  1980. slapi_entry_free(e);
  1981. if (ret) {
  1982. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  1983. "mep_pre_op - Operation failure [%d]\n", ret);
  1984. slapi_send_ldap_result(pb, ret, NULL, errstr, 0, NULL);
  1985. slapi_ch_free((void **)&errstr);
  1986. slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret);
  1987. ret = SLAPI_PLUGIN_FAILURE;
  1988. }
  1989. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  1990. "<-- mep_pre_op\n");
  1991. return ret;
  1992. }
  1993. static int
  1994. mep_add_pre_op(Slapi_PBlock *pb)
  1995. {
  1996. return mep_pre_op(pb, LDAP_CHANGETYPE_ADD);
  1997. }
  1998. static int
  1999. mep_del_pre_op(Slapi_PBlock *pb)
  2000. {
  2001. return mep_pre_op(pb, LDAP_CHANGETYPE_DELETE);
  2002. }
  2003. static int
  2004. mep_mod_pre_op(Slapi_PBlock *pb)
  2005. {
  2006. return mep_pre_op(pb, LDAP_CHANGETYPE_MODIFY);
  2007. }
  2008. static int
  2009. mep_modrdn_pre_op(Slapi_PBlock *pb)
  2010. {
  2011. return mep_pre_op(pb, LDAP_CHANGETYPE_MODDN);
  2012. }
  2013. static int
  2014. mep_mod_post_op(Slapi_PBlock *pb)
  2015. {
  2016. Slapi_Mods *smods = NULL;
  2017. Slapi_PBlock *mep_pb = NULL;
  2018. Slapi_Entry *e = NULL;
  2019. Slapi_DN *sdn = NULL;
  2020. char *managed_dn = NULL;
  2021. Slapi_DN *managed_sdn = NULL;
  2022. char *mapped_dn = NULL;
  2023. Slapi_DN *mapped_sdn = NULL;
  2024. struct configEntry *config = NULL;
  2025. int result = SLAPI_PLUGIN_SUCCESS;
  2026. LDAPMod **mods = NULL;
  2027. int i, abort_mod = 1;
  2028. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  2029. "--> mep_mod_post_op\n");
  2030. if (mep_oktodo(pb) && (sdn = mep_get_sdn(pb))) {
  2031. /* First check if the config or a template is being modified. */
  2032. if (mep_dn_is_config(sdn) || mep_dn_is_template(sdn)) {
  2033. mep_load_config();
  2034. }
  2035. /* If replication, just bail. */
  2036. if (mep_isrepl(pb)) {
  2037. goto bail;
  2038. }
  2039. /* Fetch the modified entry. This will not be set for a chaining
  2040. * backend, so don't treat the message as fatal. */
  2041. slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
  2042. if (e == NULL) {
  2043. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  2044. "mep_mod_post_op - Unable to fetch postop entry.\n");
  2045. result = SLAPI_PLUGIN_FAILURE;
  2046. goto bail;
  2047. }
  2048. /* If the entry is a tombstone, just bail. */
  2049. if (mep_has_tombstone_value(e)) {
  2050. goto bail;
  2051. }
  2052. /* Check if we're an origin entry. Update the
  2053. * mapped attrs of it's managed entry if so. */
  2054. managed_dn = slapi_entry_attr_get_charptr(e, MEP_MANAGED_ENTRY_TYPE);
  2055. if (managed_dn) {
  2056. mep_config_read_lock();
  2057. /* Bail out if the plug-in close function was just called. */
  2058. if (!slapi_plugin_running(pb)) {
  2059. mep_config_unlock();
  2060. goto bail;
  2061. }
  2062. mep_find_config(e, &config);
  2063. if (config) {
  2064. /*
  2065. * Check to see if the applied mods are mapped origin attributes.
  2066. * If they are not, then we don't need to modify the mapped entry
  2067. * as it has not changed.
  2068. */
  2069. slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
  2070. for (i = 0; mods && mods[i]; i++) {
  2071. if (mep_is_mapped_origin_attr(config->origin_attrs, mods[i]->mod_type)) {
  2072. /*
  2073. * We are modifying a managed origin attr, so we can proceed with
  2074. * modifying the managed entry. Otherwise we would modify the
  2075. * managed entry for no reason.
  2076. */
  2077. abort_mod = 0;
  2078. break;
  2079. }
  2080. }
  2081. if (abort_mod) {
  2082. mep_config_unlock();
  2083. goto bail;
  2084. }
  2085. smods = mep_get_mapped_mods(config, e, &mapped_dn);
  2086. if (smods) {
  2087. /* Clear out the pblock for reuse. */
  2088. mep_pb = slapi_pblock_new();
  2089. /* Perform the modify operation. */
  2090. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2091. "mep_mod_post_op - Updating mapped attributes "
  2092. "in entry \"%s\"\n.",
  2093. managed_dn);
  2094. slapi_modify_internal_set_pb(mep_pb, managed_dn,
  2095. slapi_mods_get_ldapmods_byref(smods), 0, 0,
  2096. mep_get_plugin_id(), 0);
  2097. slapi_modify_internal_pb(mep_pb);
  2098. slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  2099. if (result != LDAP_SUCCESS) {
  2100. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  2101. "mep_mod_post_op - Unable to update mapped "
  2102. "attributes from origin entry \"%s\" in managed "
  2103. "entry \"%s\" (%s).\n",
  2104. slapi_sdn_get_dn(sdn), managed_dn,
  2105. ldap_err2string(result));
  2106. }
  2107. slapi_mods_free(&smods);
  2108. slapi_pblock_destroy(mep_pb);
  2109. }
  2110. /* Check if we need to rename the managed entry. */
  2111. if (result == SLAPI_PLUGIN_SUCCESS && mapped_dn) {
  2112. mapped_sdn = slapi_sdn_new_normdn_passin(mapped_dn);
  2113. managed_sdn = slapi_sdn_new_normdn_byref(managed_dn);
  2114. if (slapi_sdn_compare(managed_sdn, mapped_sdn) != 0) {
  2115. result = mep_rename_managed_entry(e, mapped_sdn, managed_sdn);
  2116. }
  2117. slapi_sdn_free(&mapped_sdn);
  2118. slapi_sdn_free(&managed_sdn);
  2119. }
  2120. } else {
  2121. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  2122. "mep_mod_post_op - Unable to find config for origin "
  2123. "entry \"%s\".\n",
  2124. slapi_sdn_get_dn(sdn));
  2125. }
  2126. mep_config_unlock();
  2127. }
  2128. }
  2129. bail:
  2130. if (result) {
  2131. slapi_pblock_set(pb, SLAPI_RESULT_CODE, &result);
  2132. result = SLAPI_PLUGIN_FAILURE;
  2133. }
  2134. slapi_ch_free_string(&managed_dn);
  2135. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  2136. "<-- mep_mod_post_op\n");
  2137. return result;
  2138. }
  2139. static int
  2140. mep_add_post_op(Slapi_PBlock *pb)
  2141. {
  2142. Slapi_Entry *e = NULL;
  2143. Slapi_DN *sdn = NULL;
  2144. struct configEntry *config = NULL;
  2145. int result = SLAPI_PLUGIN_SUCCESS;
  2146. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  2147. "--> mep_add_post_op\n");
  2148. /* Reload config if a config entry was added. */
  2149. if ((sdn = mep_get_sdn(pb))) {
  2150. if (mep_dn_is_config(sdn)) {
  2151. mep_load_config();
  2152. }
  2153. } else {
  2154. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2155. "mep_add_post_op - Error retrieving dn\n");
  2156. }
  2157. /* If replication, just bail. */
  2158. if (mep_isrepl(pb)) {
  2159. return SLAPI_PLUGIN_SUCCESS;
  2160. }
  2161. /* Get the newly added entry. */
  2162. slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
  2163. if (e) {
  2164. /* If the entry is a tombstone, just bail. */
  2165. if (mep_has_tombstone_value(e)) {
  2166. return SLAPI_PLUGIN_SUCCESS;
  2167. }
  2168. /* Check if a config entry applies
  2169. * to the entry being added. */
  2170. mep_config_read_lock();
  2171. /* Bail out if the plug-in close function was just called. */
  2172. if (!slapi_plugin_running(pb)) {
  2173. mep_config_unlock();
  2174. return SLAPI_PLUGIN_SUCCESS;
  2175. }
  2176. mep_find_config(e, &config);
  2177. if (config) {
  2178. if (mep_add_managed_entry(config, e)) {
  2179. char errtxt[SLAPI_DSE_RETURNTEXT_SIZE];
  2180. int rc = LDAP_UNWILLING_TO_PERFORM;
  2181. PR_snprintf(errtxt, SLAPI_DSE_RETURNTEXT_SIZE,
  2182. "Managed Entry Plugin rejected add operation (see errors log).\n");
  2183. slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, &errtxt);
  2184. slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
  2185. result = SLAPI_PLUGIN_FAILURE;
  2186. }
  2187. }
  2188. mep_config_unlock();
  2189. } else {
  2190. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2191. "mep_add_post_op - Error "
  2192. "retrieving post-op entry %s\n",
  2193. slapi_sdn_get_dn(sdn));
  2194. }
  2195. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  2196. "<-- mep_add_post_op\n");
  2197. return result;
  2198. }
  2199. static int
  2200. mep_del_post_op(Slapi_PBlock *pb)
  2201. {
  2202. Slapi_Entry *e = NULL;
  2203. Slapi_DN *sdn = NULL;
  2204. int result = SLAPI_PLUGIN_SUCCESS;
  2205. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  2206. "--> mep_del_post_op\n");
  2207. /* Reload config if a config entry was deleted. */
  2208. if ((sdn = mep_get_sdn(pb))) {
  2209. if (mep_dn_is_config(sdn))
  2210. mep_load_config();
  2211. } else {
  2212. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2213. "mep_del_post_op - Error retrieving dn\n");
  2214. }
  2215. /* If replication, just bail. */
  2216. if (mep_isrepl(pb)) {
  2217. return SLAPI_PLUGIN_SUCCESS;
  2218. }
  2219. /* Get deleted entry, then go through types to find config. */
  2220. slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e);
  2221. if (e) {
  2222. char *managed_dn = NULL;
  2223. /* If the entry is a tombstone, just bail. */
  2224. if (mep_has_tombstone_value(e)) {
  2225. return SLAPI_PLUGIN_SUCCESS;
  2226. }
  2227. /* See if we're an origin entry . */
  2228. managed_dn = slapi_entry_attr_get_charptr(e, MEP_MANAGED_ENTRY_TYPE);
  2229. if (managed_dn) {
  2230. Slapi_PBlock *mep_pb = slapi_pblock_new();
  2231. /* Delete the managed entry. */
  2232. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2233. "mep_del_post_op - Deleting managed entry "
  2234. "\"%s\" due to deletion of origin entry "
  2235. "\"%s\".\n ",
  2236. managed_dn, slapi_sdn_get_dn(sdn));
  2237. slapi_delete_internal_set_pb(mep_pb, managed_dn, NULL,
  2238. NULL, mep_get_plugin_id(), 0);
  2239. slapi_delete_internal_pb(mep_pb);
  2240. slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  2241. if (result) {
  2242. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  2243. "mep_del_post_op - Failed to delete managed entry "
  2244. "(%s) - error (%d)\n",
  2245. managed_dn, result);
  2246. }
  2247. slapi_ch_free_string(&managed_dn);
  2248. slapi_pblock_destroy(mep_pb);
  2249. }
  2250. } else {
  2251. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2252. "mep_del_post_op - Error "
  2253. "retrieving pre-op entry %s\n",
  2254. slapi_sdn_get_dn(sdn));
  2255. }
  2256. if (result) {
  2257. slapi_pblock_set(pb, SLAPI_RESULT_CODE, &result);
  2258. result = SLAPI_PLUGIN_FAILURE;
  2259. }
  2260. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  2261. "<-- mep_del_post_op\n");
  2262. return result;
  2263. }
  2264. static int
  2265. mep_modrdn_post_op(Slapi_PBlock *pb)
  2266. {
  2267. const char *new_dn = NULL;
  2268. Slapi_DN *old_sdn = NULL;
  2269. Slapi_DN *new_sdn = NULL;
  2270. Slapi_Entry *post_e = NULL;
  2271. char *managed_dn = NULL;
  2272. struct configEntry *config = NULL;
  2273. int result = SLAPI_PLUGIN_SUCCESS;
  2274. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  2275. "--> mep_modrdn_post_op\n");
  2276. /* Just bail if we aren't ready to service requests yet. */
  2277. if (!mep_oktodo(pb)) {
  2278. return SLAPI_PLUGIN_SUCCESS;
  2279. }
  2280. /* Reload config if an existing config entry was renamed,
  2281. * or if the new dn brings an entry into the scope of the
  2282. * config entries. */
  2283. slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &post_e);
  2284. if (post_e) {
  2285. new_sdn = slapi_entry_get_sdn(post_e);
  2286. new_dn = slapi_sdn_get_dn(new_sdn);
  2287. } else {
  2288. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  2289. "mep_modrdn_post_op -Error "
  2290. "retrieving post-op entry\n");
  2291. return SLAPI_PLUGIN_FAILURE;
  2292. }
  2293. if ((old_sdn = mep_get_sdn(pb))) {
  2294. if (mep_dn_is_config(old_sdn) || mep_dn_is_config(new_sdn))
  2295. mep_load_config();
  2296. } else {
  2297. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2298. "mep_modrdn_post_op - Error "
  2299. "retrieving dn\n");
  2300. }
  2301. /* If replication, just bail. */
  2302. if (mep_isrepl(pb)) {
  2303. return SLAPI_PLUGIN_SUCCESS;
  2304. }
  2305. /* If the entry is a tombstone, just bail. */
  2306. if (mep_has_tombstone_value(post_e)) {
  2307. return SLAPI_PLUGIN_SUCCESS;
  2308. }
  2309. /* See if we're an origin entry . */
  2310. managed_dn = slapi_entry_attr_get_charptr(post_e, MEP_MANAGED_ENTRY_TYPE);
  2311. if (managed_dn) {
  2312. LDAPMod mod;
  2313. LDAPMod *mods[3];
  2314. char *vals[2];
  2315. int result = LDAP_SUCCESS;
  2316. Slapi_PBlock *mep_pb = slapi_pblock_new();
  2317. Slapi_Entry *new_managed_entry = NULL;
  2318. Slapi_DN *managed_sdn = NULL;
  2319. Slapi_Mods *smods = NULL;
  2320. int free_managed_dn = 1;
  2321. mep_config_read_lock();
  2322. /* Bail out if the plug-in close function was just called. */
  2323. if (!slapi_plugin_running(pb)) {
  2324. mep_config_unlock();
  2325. slapi_ch_free_string(&managed_dn);
  2326. slapi_pblock_destroy(mep_pb);
  2327. return SLAPI_PLUGIN_SUCCESS;
  2328. }
  2329. mep_find_config(post_e, &config);
  2330. if (!config) {
  2331. LDAPMod mod2;
  2332. char *vals2[2];
  2333. /* Delete the associated managed entry. */
  2334. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2335. "mep_modrdn_post_op - Removing managed entry \"%s\" "
  2336. "since origin entry \"%s\" was moved out of scope.\n",
  2337. managed_dn, slapi_sdn_get_dn(old_sdn));
  2338. slapi_delete_internal_set_pb(mep_pb, managed_dn, NULL, NULL,
  2339. mep_get_plugin_id(), 0);
  2340. slapi_delete_internal_pb(mep_pb);
  2341. slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  2342. if (result) {
  2343. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  2344. "mep_modrdn_post_op - Failed to delete managed entry "
  2345. "(%s) - error (%d)\n",
  2346. managed_dn, result);
  2347. goto bailmod;
  2348. }
  2349. /* Clear out the pblock for reuse. */
  2350. slapi_pblock_init(mep_pb);
  2351. /* Remove the pointer from the origin entry. */
  2352. vals[0] = 0;
  2353. mod.mod_op = LDAP_MOD_DELETE;
  2354. mod.mod_type = MEP_MANAGED_ENTRY_TYPE;
  2355. mod.mod_values = vals;
  2356. /* Remove the origin objectclass. */
  2357. vals2[0] = MEP_ORIGIN_OC;
  2358. vals2[1] = 0;
  2359. mod2.mod_op = LDAP_MOD_DELETE;
  2360. mod2.mod_type = SLAPI_ATTR_OBJECTCLASS;
  2361. mod2.mod_values = vals2;
  2362. mods[0] = &mod;
  2363. mods[1] = &mod2;
  2364. mods[2] = 0;
  2365. /* Perform the modify operation. */
  2366. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2367. "mep_modrdn_post_op - Removing %s pointer and %s "
  2368. "objectclass from entry \"%s\".\n",
  2369. MEP_MANAGED_ENTRY_TYPE, MEP_ORIGIN_OC, new_dn);
  2370. slapi_modify_internal_set_pb_ext(mep_pb, new_sdn, mods, 0, 0,
  2371. mep_get_plugin_id(), 0);
  2372. slapi_modify_internal_pb(mep_pb);
  2373. slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  2374. if (result != LDAP_SUCCESS) {
  2375. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  2376. "mep_modrdn_post_op - Unable to remove %s "
  2377. "pointer and %s objectclass from entry "
  2378. "\"%s\".\n",
  2379. MEP_MANAGED_ENTRY_TYPE,
  2380. MEP_ORIGIN_OC, new_dn);
  2381. }
  2382. } else {
  2383. /* Update backlink to new origin DN in managed entry. */
  2384. vals[0] = (char *)new_dn;
  2385. vals[1] = 0;
  2386. mod.mod_op = LDAP_MOD_REPLACE;
  2387. mod.mod_type = MEP_MANAGED_BY_TYPE;
  2388. mod.mod_values = vals;
  2389. mods[0] = &mod;
  2390. mods[1] = 0;
  2391. /* Create a new managed entry to determine what changes
  2392. * we need to make to the existing managed entry. */
  2393. new_managed_entry = mep_create_managed_entry(config, post_e);
  2394. if (new_managed_entry == NULL) {
  2395. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  2396. "mep_modrdn_post_op - Unable to create in-memory "
  2397. "managed entry from origin entry \"%s\".\n",
  2398. new_dn);
  2399. result = SLAPI_PLUGIN_FAILURE;
  2400. goto bailmod;
  2401. }
  2402. /* Check if the managed entry exists. It is possible that
  2403. * it has already been renamed by another plug-in. If it
  2404. * has already been renamed, we need to use the new DN to
  2405. * perform our updates. */
  2406. managed_sdn = slapi_sdn_new_normdn_byref(managed_dn);
  2407. if (slapi_search_internal_get_entry(managed_sdn, 0,
  2408. NULL, mep_get_plugin_id()) == LDAP_NO_SUCH_OBJECT) {
  2409. slapi_ch_free_string(&managed_dn);
  2410. /* This DN is not a copy, so we don't want to free it later. */
  2411. managed_dn = slapi_entry_get_dn(new_managed_entry);
  2412. slapi_sdn_set_normdn_byref(managed_sdn, managed_dn);
  2413. free_managed_dn = 0;
  2414. }
  2415. /* Perform the modify operation. */
  2416. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2417. "mep_modrdn_post_op - Updating %s pointer to \"%s\" "
  2418. "in entry \"%s\".\n",
  2419. MEP_MANAGED_BY_TYPE, new_dn, managed_dn);
  2420. slapi_modify_internal_set_pb(mep_pb, managed_dn, mods, 0, 0,
  2421. mep_get_plugin_id(), 0);
  2422. slapi_modify_internal_pb(mep_pb);
  2423. slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  2424. if (result != LDAP_SUCCESS) {
  2425. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  2426. "mep_modrdn_post_op - Unable to update pointer to "
  2427. "origin entry \"%s\" in managed entry \"%s\" "
  2428. "(%s).\n",
  2429. new_dn, managed_dn, ldap_err2string(result));
  2430. } else {
  2431. /* See if we need to rename the managed entry. */
  2432. if (slapi_sdn_compare(slapi_entry_get_sdn(new_managed_entry), managed_sdn) != 0) {
  2433. /* Rename the managed entry. */
  2434. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2435. "mep_modrdn_post_op - Renaming managed entry "
  2436. "\"%s\" to \"%s\" due to rename of origin "
  2437. "entry \"%s\".\n ",
  2438. managed_dn,
  2439. slapi_entry_get_dn(new_managed_entry),
  2440. slapi_sdn_get_dn(old_sdn));
  2441. if ((result = mep_rename_managed_entry(post_e,
  2442. slapi_entry_get_sdn(new_managed_entry),
  2443. managed_sdn))) {
  2444. goto bailmod;
  2445. }
  2446. }
  2447. /* Update all of the mapped attributes
  2448. * to be sure they are up to date. */
  2449. smods = mep_get_mapped_mods(config, post_e, NULL);
  2450. if (smods) {
  2451. /* Clear out the pblock for reuse. */
  2452. slapi_pblock_init(mep_pb);
  2453. /* Perform the modify operation. */
  2454. slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
  2455. "mep_modrdn_post_op - Updating mapped attributes "
  2456. "in entry \"%s\"\n.",
  2457. managed_dn);
  2458. slapi_modify_internal_set_pb_ext(mep_pb,
  2459. slapi_entry_get_sdn(new_managed_entry),
  2460. slapi_mods_get_ldapmods_byref(smods), 0, 0,
  2461. mep_get_plugin_id(), 0);
  2462. slapi_modify_internal_pb(mep_pb);
  2463. slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  2464. if (result != LDAP_SUCCESS) {
  2465. slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM,
  2466. "mep_modrdn_post_op - Unable to update mapped "
  2467. "attributes from origin entry \"%s\" in managed "
  2468. "entry \"%s\" (%s).\n",
  2469. new_dn,
  2470. slapi_entry_get_dn(new_managed_entry),
  2471. ldap_err2string(result));
  2472. }
  2473. slapi_mods_free(&smods);
  2474. }
  2475. }
  2476. bailmod:
  2477. slapi_entry_free(new_managed_entry);
  2478. slapi_sdn_free(&managed_sdn);
  2479. }
  2480. slapi_pblock_destroy(mep_pb);
  2481. if (free_managed_dn) {
  2482. slapi_ch_free_string(&managed_dn);
  2483. }
  2484. mep_config_unlock();
  2485. } else {
  2486. /* Was this entry moved into scope of a config entry?
  2487. * If so, treat like an add and create the new managed
  2488. * entry and links. */
  2489. mep_config_read_lock();
  2490. /* Bail out if the plug-in close function was just called. */
  2491. if (!slapi_plugin_running(pb)) {
  2492. mep_config_unlock();
  2493. return result;
  2494. }
  2495. mep_find_config(post_e, &config);
  2496. if (config) {
  2497. if (mep_add_managed_entry(config, post_e)) {
  2498. char errtxt[SLAPI_DSE_RETURNTEXT_SIZE];
  2499. result = LDAP_UNWILLING_TO_PERFORM;
  2500. PR_snprintf(errtxt, SLAPI_DSE_RETURNTEXT_SIZE,
  2501. "Managed Entry Plugin rejected modrdn operation (see errors log).\n");
  2502. slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, &errtxt);
  2503. }
  2504. }
  2505. mep_config_unlock();
  2506. }
  2507. if (result) {
  2508. slapi_pblock_set(pb, SLAPI_RESULT_CODE, &result);
  2509. result = SLAPI_PLUGIN_FAILURE;
  2510. }
  2511. slapi_log_err(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
  2512. "<-- mep_modrdn_post_op\n");
  2513. return result;
  2514. }
  2515. static int
  2516. mep_has_tombstone_value(Slapi_Entry *e)
  2517. {
  2518. Slapi_Value *tombstone = slapi_value_new_string(SLAPI_ATTR_VALUE_TOMBSTONE);
  2519. int rc = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS,
  2520. tombstone);
  2521. slapi_value_free(&tombstone);
  2522. return rc;
  2523. }