daemon.c 104 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. #include <string.h>
  13. #include <sys/types.h>
  14. #include <unistd.h>
  15. #include <sys/socket.h>
  16. #include <errno.h>
  17. #include <netinet/in.h>
  18. #include <arpa/inet.h>
  19. #include <sys/types.h>
  20. #include <netinet/tcp.h>
  21. #include <netdb.h>
  22. #include <sys/time.h>
  23. #include <sys/wait.h>
  24. #include <pthread.h>
  25. #if defined(HAVE_MNTENT_H)
  26. #include <mntent.h>
  27. #endif
  28. #include <time.h>
  29. #include <signal.h>
  30. #include <fcntl.h>
  31. #define TCPLEN_T int
  32. #ifdef NEED_FILIO
  33. #include <sys/filio.h>
  34. #else /* NEED_FILIO */
  35. #include <sys/ioctl.h>
  36. #endif /* NEED_FILIO */
  37. /* for some reason, linux tty stuff defines CTIME */
  38. #include <stdio.h>
  39. #ifdef LINUX
  40. #undef CTIME
  41. #include <sys/statfs.h>
  42. #else
  43. #include <sys/statvfs.h>
  44. #include <sys/mnttab.h>
  45. #endif
  46. #include "slap.h"
  47. #include "slapi-plugin.h"
  48. #include "snmp_collator.h"
  49. #include <private/pprio.h>
  50. #include <ssl.h>
  51. #include "fe.h"
  52. #if defined(ENABLE_LDAPI)
  53. #include "getsocketpeer.h"
  54. #endif /* ENABLE_LDAPI */
  55. #if defined (LDAP_IOCP)
  56. #define SLAPD_WAKEUP_TIMER 250
  57. #else
  58. #define SLAPD_WAKEUP_TIMER 250
  59. #endif
  60. int slapd_wakeup_timer = SLAPD_WAKEUP_TIMER; /* time in ms to wakeup */
  61. #ifdef notdef /* GGOODREPL */
  62. /*
  63. * time in secs to do housekeeping:
  64. * this must be greater than slapd_wakeup_timer
  65. */
  66. short slapd_housekeeping_timer = 10;
  67. #endif /* notdef GGOODREPL */
  68. PRFileDesc* signalpipe[2];
  69. static int writesignalpipe = SLAPD_INVALID_SOCKET;
  70. static int readsignalpipe = SLAPD_INVALID_SOCKET;
  71. #define FDS_SIGNAL_PIPE 0
  72. static PRThread *disk_thread_p = NULL;
  73. static PRCondVar *diskmon_cvar = NULL;
  74. static PRLock *diskmon_mutex = NULL;
  75. void disk_monitoring_stop();
  76. typedef struct listener_info {
  77. #ifdef ENABLE_NUNC_STANS
  78. PRStackElem stackelem; /* must be first in struct for PRStack to work */
  79. #endif
  80. int idx; /* index of this listener in the ct->fd array */
  81. PRFileDesc *listenfd; /* the listener fd */
  82. int secure;
  83. int local;
  84. #ifdef ENABLE_NUNC_STANS
  85. Connection_Table *ct; /* for listen job callback */
  86. struct ns_job_t *ns_job; /* the ns accept job */
  87. #endif
  88. } listener_info;
  89. static int listeners = 0; /* number of listener sockets */
  90. static listener_info *listener_idxs = NULL; /* array of indexes of listener sockets in the ct->fd array */
  91. static int enable_nunc_stans = 0; /* if nunc-stans is set to enabled, set to 1 in slapd_daemon */
  92. #define SLAPD_POLL_LISTEN_READY(xxflagsxx) (xxflagsxx & PR_POLL_READ)
  93. static int get_configured_connection_table_size();
  94. #ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS
  95. static void get_loopback_by_addr( void );
  96. #endif
  97. static PRFileDesc **createprlistensockets(unsigned short port,
  98. PRNetAddr **listenaddr, int secure, int local);
  99. static const char *netaddr2string(const PRNetAddr *addr, char *addrbuf,
  100. size_t addrbuflen);
  101. static void set_shutdown (int);
  102. #ifdef ENABLE_NUNC_STANS
  103. struct ns_job_t *ns_signal_job[3];
  104. static void ns_set_shutdown (struct ns_job_t *job);
  105. #endif
  106. static void setup_pr_read_pds(Connection_Table *ct, PRFileDesc **n_tcps, PRFileDesc **s_tcps, PRFileDesc **i_unix, PRIntn *num_to_read);
  107. #ifdef HPUX10
  108. static void* catch_signals();
  109. #endif
  110. static int createsignalpipe( void );
  111. static char *
  112. get_pid_file()
  113. {
  114. return(pid_file);
  115. }
  116. static int
  117. accept_and_configure(int s, PRFileDesc *pr_acceptfd, PRNetAddr *pr_netaddr,
  118. int addrlen, int secure, int local, PRFileDesc **pr_clonefd)
  119. {
  120. int ns = 0;
  121. PRIntervalTime pr_timeout = PR_MillisecondsToInterval(slapd_wakeup_timer);
  122. (*pr_clonefd) = PR_Accept(pr_acceptfd, pr_netaddr, pr_timeout);
  123. if( !(*pr_clonefd) ) {
  124. PRErrorCode prerr = PR_GetError();
  125. LDAPDebug( LDAP_DEBUG_ANY, "PR_Accept() failed, "
  126. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  127. prerr, slapd_pr_strerror(prerr), 0 );
  128. return(SLAPD_INVALID_SOCKET);
  129. }
  130. ns = configure_pr_socket( pr_clonefd, secure, local );
  131. return ns;
  132. }
  133. /*
  134. * This is the shiny new re-born daemon function, without all the hair
  135. */
  136. /* GGOODREPL static void handle_timeout( void ); */
  137. static int handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, int secure, int local, Connection **newconn );
  138. #ifdef ENABLE_NUNC_STANS
  139. static void ns_handle_new_connection(struct ns_job_t *job);
  140. #endif
  141. static void handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll);
  142. static int clear_signal(struct POLL_STRUCT *fds);
  143. static void unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, PRFileDesc **n_tcps, PRFileDesc **s_tcps, PRFileDesc **i_unix);
  144. static int write_pid_file();
  145. static int init_shutdown_detect();
  146. /* Globals which are used to store the sockets between
  147. * calls to daemon_pre_setuid_init() and the daemon thread
  148. * creation. */
  149. int daemon_pre_setuid_init(daemon_ports_t *ports)
  150. {
  151. int rc = 0;
  152. if (0 != ports->n_port) {
  153. ports->n_socket = createprlistensockets(ports->n_port,
  154. ports->n_listenaddr, 0, 0);
  155. }
  156. if ( config_get_security() && (0 != ports->s_port) ) {
  157. ports->s_socket = createprlistensockets((unsigned short)ports->s_port,
  158. ports->s_listenaddr, 1, 0);
  159. } else {
  160. ports->s_socket = SLAPD_INVALID_SOCKET;
  161. }
  162. #if defined(ENABLE_LDAPI)
  163. /* ldapi */
  164. if(0 != ports->i_port) {
  165. ports->i_socket = createprlistensockets(1, ports->i_listenaddr, 0, 1);
  166. }
  167. #endif /* ENABLE_LDAPI */
  168. return( rc );
  169. }
  170. /*
  171. * The time_shutdown static variable is used to signal the time thread
  172. * to shutdown. We used to shut down the time thread when g_get_shutdown()
  173. * returned a non-zero value, but that caused the clock to stop, so to speak,
  174. * and all error log entries to have the same timestamp once the shutdown
  175. * process began.
  176. */
  177. static int time_shutdown = 0;
  178. void *
  179. time_thread(void *nothing)
  180. {
  181. PRIntervalTime interval;
  182. interval = PR_SecondsToInterval(1);
  183. while(!time_shutdown) {
  184. poll_current_time();
  185. csngen_update_time ();
  186. DS_Sleep(interval);
  187. }
  188. /*NOTREACHED*/
  189. return(NULL);
  190. }
  191. /*
  192. * Return a copy of the mount point for the specified directory
  193. */
  194. #ifdef SOLARIS
  195. char *
  196. disk_mon_get_mount_point(char *dir)
  197. {
  198. struct mnttab mnt;
  199. struct stat s;
  200. dev_t dev_id;
  201. FILE *fp;
  202. fp = fopen("/etc/mnttab", "r");
  203. if (fp == NULL || stat(dir, &s) != 0) {
  204. return NULL;
  205. }
  206. dev_id = s.st_dev;
  207. while((0 == getmntent(fp, &mnt))){
  208. if (stat(mnt.mnt_mountp, &s) != 0) {
  209. continue;
  210. }
  211. if (s.st_dev == dev_id) {
  212. return (slapi_ch_strdup(mnt.mnt_mountp));
  213. }
  214. }
  215. return NULL;
  216. }
  217. #elif HPUX
  218. char *
  219. disk_mon_get_mount_point(char *dir)
  220. {
  221. struct mntent *mnt;
  222. struct stat s;
  223. dev_t dev_id;
  224. FILE *fp;
  225. if ((fp = setmntent("/etc/mnttab", "r")) == NULL) {
  226. return NULL;
  227. }
  228. if (stat(dir, &s) != 0) {
  229. return NULL;
  230. }
  231. dev_id = s.st_dev;
  232. while((mnt = getmntent(fp))){
  233. if (stat(mnt->mnt_dir, &s) != 0) {
  234. continue;
  235. }
  236. if (s.st_dev == dev_id) {
  237. endmntent(fp);
  238. return (slapi_ch_strdup(mnt->mnt_dir));
  239. }
  240. }
  241. endmntent(fp);
  242. return NULL;
  243. }
  244. #else /* Linux */
  245. char *
  246. disk_mon_get_mount_point(char *dir)
  247. {
  248. struct mntent *mnt;
  249. struct stat s;
  250. dev_t dev_id;
  251. FILE *fp;
  252. if (stat(dir, &s) != 0) {
  253. return NULL;
  254. }
  255. dev_id = s.st_dev;
  256. if ((fp = setmntent("/proc/mounts", "r")) == NULL) {
  257. return NULL;
  258. }
  259. while((mnt = getmntent(fp))){
  260. if (stat(mnt->mnt_dir, &s) != 0) {
  261. continue;
  262. }
  263. if (s.st_dev == dev_id) {
  264. endmntent(fp);
  265. return (slapi_ch_strdup(mnt->mnt_dir));
  266. }
  267. }
  268. endmntent(fp);
  269. return NULL;
  270. }
  271. #endif
  272. /*
  273. * Get the mount point of the directory, and add it to the
  274. * list. Skip duplicate mount points.
  275. */
  276. void
  277. disk_mon_add_dir(char ***list, char *directory)
  278. {
  279. char *dir = disk_mon_get_mount_point(directory);
  280. if(dir == NULL)
  281. return;
  282. if(!charray_inlist(*list,dir)){
  283. slapi_ch_array_add(list, dir);
  284. } else {
  285. slapi_ch_free((void **)&dir);
  286. }
  287. }
  288. /*
  289. * We gather all the log, txn log, config, and db directories
  290. */
  291. void
  292. disk_mon_get_dirs(char ***list, int logs_critical){
  293. slapdFrontendConfig_t *config = getFrontendConfig();
  294. Slapi_Backend *be = NULL;
  295. char *cookie = NULL;
  296. char *dir = NULL;
  297. /* Add /var just to be safe */
  298. #ifdef LOCALSTATEDIR
  299. disk_mon_add_dir(list, LOCALSTATEDIR);
  300. #else
  301. disk_mon_add_dir(list, "/var");
  302. #endif
  303. /* config and backend directories */
  304. CFG_LOCK_READ(config);
  305. disk_mon_add_dir(list, config->configdir);
  306. disk_mon_add_dir(list, config->accesslog);
  307. disk_mon_add_dir(list, config->errorlog);
  308. disk_mon_add_dir(list, config->auditlog);
  309. disk_mon_add_dir(list, config->auditfaillog);
  310. CFG_UNLOCK_READ(config);
  311. be = slapi_get_first_backend (&cookie);
  312. while (be) {
  313. if(slapi_back_get_info(be, BACK_INFO_DIRECTORY, (void **)&dir) == LDAP_SUCCESS){ /* db directory */
  314. disk_mon_add_dir(list, dir);
  315. }
  316. if(slapi_back_get_info(be, BACK_INFO_LOG_DIRECTORY, (void **)&dir) == LDAP_SUCCESS){ /* txn log dir */
  317. disk_mon_add_dir(list, dir);
  318. }
  319. be = (backend *)slapi_get_next_backend (cookie);
  320. }
  321. slapi_ch_free((void **)&cookie);
  322. }
  323. /*
  324. * This function checks the list of directories to see if any are below the
  325. * threshold. We return the the directory/free disk space of the most critical
  326. * directory.
  327. */
  328. char *
  329. disk_mon_check_diskspace(char **dirs, PRUint64 threshold, PRUint64 *disk_space)
  330. {
  331. #ifdef LINUX
  332. struct statfs buf;
  333. #else
  334. struct statvfs buf;
  335. #endif
  336. PRUint64 worst_disk_space = threshold;
  337. PRUint64 freeBytes = 0;
  338. PRUint64 blockSize = 0;
  339. char *worst_dir = NULL;
  340. int hit_threshold = 0;
  341. int i = 0;
  342. for(i = 0; dirs && dirs[i]; i++){
  343. #ifndef LINUX
  344. if (statvfs(dirs[i], &buf) != -1)
  345. #else
  346. if (statfs(dirs[i], &buf) != -1)
  347. #endif
  348. {
  349. LL_UI2L(freeBytes, buf.f_bavail);
  350. LL_UI2L(blockSize, buf.f_bsize);
  351. LL_MUL(freeBytes, freeBytes, blockSize);
  352. if(LL_UCMP(freeBytes, <, threshold)){
  353. hit_threshold = 1;
  354. if(LL_UCMP(freeBytes, <, worst_disk_space)){
  355. worst_disk_space = freeBytes;
  356. worst_dir = dirs[i];
  357. }
  358. }
  359. }
  360. }
  361. if(hit_threshold){
  362. *disk_space = worst_disk_space;
  363. return worst_dir;
  364. } else {
  365. *disk_space = 0;
  366. return NULL;
  367. }
  368. }
  369. #define LOGGING_OFF 0
  370. #define LOGGING_ON 1
  371. /*
  372. * Disk Space Monitoring Thread
  373. *
  374. * We need to monitor the free disk space of critical disks.
  375. *
  376. * If we get below the free disk space threshold, start taking measures
  377. * to avoid additional disk space consumption by stopping verbose logging,
  378. * access/audit logging, and deleting rotated logs.
  379. *
  380. * If this is not enough, then we need to shut slapd down to avoid
  381. * possibly corrupting the db.
  382. *
  383. * Future - it would be nice to be able to email an alert.
  384. */
  385. void
  386. disk_monitoring_thread(void *nothing)
  387. {
  388. char errorbuf[BUFSIZ];
  389. char **dirs = NULL;
  390. char *dirstr = NULL;
  391. PRUint64 previous_mark = 0;
  392. PRUint64 disk_space = 0;
  393. PRInt64 threshold = 0;
  394. PRUint64 halfway = 0;
  395. time_t start = 0;
  396. time_t now = 0;
  397. int deleted_rotated_logs = 0;
  398. int logging_critical = 0;
  399. int passed_threshold = 0;
  400. int verbose_logging = 0;
  401. int using_accesslog = 0;
  402. int using_auditlog = 0;
  403. int using_auditfaillog = 0;
  404. int logs_disabled = 0;
  405. int grace_period = 0;
  406. int first_pass = 1;
  407. int ok_now = 0;
  408. while(!g_get_shutdown()) {
  409. if(!first_pass){
  410. PR_Lock(diskmon_mutex);
  411. PR_WaitCondVar(diskmon_cvar, PR_SecondsToInterval(10));
  412. PR_Unlock(diskmon_mutex);
  413. /*
  414. * We need to subtract from disk_space to account for the
  415. * logging we just did, it doesn't hurt if we subtract a
  416. * little more than necessary.
  417. */
  418. previous_mark = disk_space - 512;
  419. ok_now = 0;
  420. } else {
  421. first_pass = 0;
  422. }
  423. /*
  424. * Get the config settings, as they could have changed
  425. */
  426. logging_critical = config_get_disk_logging_critical();
  427. grace_period = 60 * config_get_disk_grace_period(); /* convert it to seconds */
  428. verbose_logging = config_get_errorlog_level();
  429. threshold = config_get_disk_threshold();
  430. halfway = threshold / 2;
  431. if(config_get_auditlog_logging_enabled()){
  432. using_auditlog = 1;
  433. }
  434. if(config_get_auditfaillog_logging_enabled()){
  435. using_auditfaillog = 1;
  436. }
  437. if(config_get_accesslog_logging_enabled()){
  438. using_accesslog = 1;
  439. }
  440. /*
  441. * Check the disk space. Always refresh the list, as backends can be added
  442. */
  443. slapi_ch_array_free(dirs);
  444. dirs = NULL;
  445. disk_mon_get_dirs(&dirs, logging_critical);
  446. dirstr = disk_mon_check_diskspace(dirs, threshold, &disk_space);
  447. if(dirstr == NULL){
  448. /*
  449. * Good, none of our disks are within the threshold,
  450. * reset the logging if we turned it off
  451. */
  452. if(passed_threshold){
  453. if(logs_disabled){
  454. LDAPDebug(LDAP_DEBUG_ANY, "Disk space is now within acceptable levels. "
  455. "Restoring the log settings.\n",0,0,0);
  456. if(using_accesslog){
  457. config_set_accesslog_enabled(LOGGING_ON);
  458. }
  459. if(using_auditlog){
  460. config_set_auditlog_enabled(LOGGING_ON);
  461. }
  462. if(using_auditfaillog){
  463. config_set_auditfaillog_enabled(LOGGING_ON);
  464. }
  465. } else {
  466. LDAPDebug(LDAP_DEBUG_ANY, "Disk space is now within acceptable levels.\n",0,0,0);
  467. }
  468. deleted_rotated_logs = 0;
  469. passed_threshold = 0;
  470. previous_mark = 0;
  471. logs_disabled = 0;
  472. }
  473. continue;
  474. } else {
  475. passed_threshold = 1;
  476. }
  477. /*
  478. * Check if we are already critical
  479. */
  480. if(disk_space < 4096){ /* 4 k */
  481. LDAPDebug(LDAP_DEBUG_ANY, "Disk space is critically low on disk (%s), remaining space: %" NSPRIu64 " Kb. "
  482. "Signaling slapd for shutdown...\n", dirstr , (disk_space / 1024), 0);
  483. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  484. return;
  485. }
  486. /*
  487. * If we are low, see if we are using verbose error logging, and turn it off
  488. * if logging is not critical
  489. */
  490. if(verbose_logging != 0 && verbose_logging != LDAP_DEBUG_ANY){
  491. LDAPDebug(LDAP_DEBUG_ANY, "Disk space is low on disk (%s), remaining space: %" NSPRIu64 " Kb, "
  492. "temporarily setting error loglevel to the default level(%d).\n", dirstr,
  493. (disk_space / 1024), SLAPD_DEFAULT_ERRORLOG_LEVEL);
  494. /* Setting the log level back to zero, actually sets the value to LDAP_DEBUG_ANY */
  495. config_set_errorlog_level(CONFIG_LOGLEVEL_ATTRIBUTE,
  496. STRINGIFYDEFINE(SLAPD_DEFAULT_ERRORLOG_LEVEL),
  497. errorbuf, CONFIG_APPLY);
  498. continue;
  499. }
  500. /*
  501. * If we are low, there's no verbose logging, logs are not critical, then disable the
  502. * access/audit logs, log another error, and continue.
  503. */
  504. if(!logs_disabled && !logging_critical){
  505. LDAPDebug(LDAP_DEBUG_ANY, "Disk space is too low on disk (%s), remaining space: %" NSPRIu64 " Kb, "
  506. "disabling access and audit logging.\n", dirstr, (disk_space / 1024), 0);
  507. config_set_accesslog_enabled(LOGGING_OFF);
  508. config_set_auditlog_enabled(LOGGING_OFF);
  509. config_set_auditfaillog_enabled(LOGGING_OFF);
  510. logs_disabled = 1;
  511. continue;
  512. }
  513. /*
  514. * If we are low, we turned off verbose logging, logs are not critical, and we disabled
  515. * access/audit logging, then delete the rotated logs, log another error, and continue.
  516. */
  517. if(!deleted_rotated_logs && !logging_critical){
  518. LDAPDebug(LDAP_DEBUG_ANY, "Disk space is too low on disk (%s), remaining space: %" NSPRIu64 " Kb, "
  519. "deleting rotated logs.\n", dirstr, (disk_space / 1024), 0);
  520. log__delete_rotated_logs();
  521. deleted_rotated_logs = 1;
  522. continue;
  523. }
  524. /*
  525. * Ok, we've done what we can, log a message if we continue to lose available disk space
  526. */
  527. if(disk_space < previous_mark){
  528. LDAPDebug(LDAP_DEBUG_ANY, "Disk space is too low on disk (%s), remaining space: %" NSPRIu64 " Kb\n",
  529. dirstr, (disk_space / 1024), 0);
  530. }
  531. /*
  532. *
  533. * If we are below the halfway mark, and we did everything else,
  534. * go into shutdown mode. If the disk space doesn't get critical,
  535. * wait for the grace period before shutting down. This gives an
  536. * admin the chance to clean things up.
  537. *
  538. */
  539. if(disk_space < halfway){
  540. LDAPDebug(LDAP_DEBUG_ANY, "Disk space on (%s) is too far below the threshold(%" NSPRIu64 " bytes). "
  541. "Waiting %d minutes for disk space to be cleaned up before shutting slapd down...\n",
  542. dirstr, threshold, (grace_period / 60));
  543. time(&start);
  544. now = start;
  545. while( (now - start) < grace_period ){
  546. if(g_get_shutdown()){
  547. return;
  548. }
  549. /*
  550. * Sleep for a little bit, but we don't want to run out of disk space
  551. * while sleeping for the entire grace period
  552. */
  553. DS_Sleep(PR_SecondsToInterval(1));
  554. /*
  555. * Now check disk space again in hopes some space was freed up
  556. */
  557. dirstr = disk_mon_check_diskspace(dirs, threshold, &disk_space);
  558. if(!dirstr){
  559. /*
  560. * Excellent, we are back to acceptable levels, reset everything...
  561. */
  562. LDAPDebug(LDAP_DEBUG_ANY, "Available disk space is now acceptable (%" NSPRIu64 " bytes). Aborting"
  563. " shutdown, and restoring the log settings.\n",disk_space,0,0);
  564. if(logs_disabled && using_accesslog){
  565. config_set_accesslog_enabled(LOGGING_ON);
  566. }
  567. if(logs_disabled && using_auditlog){
  568. config_set_auditlog_enabled(LOGGING_ON);
  569. }
  570. if(logs_disabled && using_auditfaillog){
  571. config_set_auditfaillog_enabled(LOGGING_ON);
  572. }
  573. deleted_rotated_logs = 0;
  574. passed_threshold = 0;
  575. logs_disabled = 0;
  576. previous_mark = 0;
  577. ok_now = 1;
  578. start = 0;
  579. now = 0;
  580. break;
  581. } else if(disk_space < 4096){ /* 4 k */
  582. /*
  583. * Disk space is critical, log an error, and shut it down now!
  584. */
  585. LDAPDebug(LDAP_DEBUG_ANY, "Disk space is critically low on disk (%s), remaining space: %" NSPRIu64 " Kb."
  586. " Signaling slapd for shutdown...\n", dirstr, (disk_space / 1024), 0);
  587. g_set_shutdown( SLAPI_SHUTDOWN_DISKFULL );
  588. return;
  589. }
  590. time(&now);
  591. }
  592. if(ok_now){
  593. /*
  594. * Disk space is acceptable, resume normal processing
  595. */
  596. continue;
  597. }
  598. /*
  599. * If disk space was freed up we would of detected in the above while loop. So shut it down.
  600. */
  601. LDAPDebug(LDAP_DEBUG_ANY, "Disk space is still too low (%" NSPRIu64 " Kb). Signaling slapd for shutdown...\n",
  602. (disk_space / 1024), 0, 0);
  603. g_set_shutdown( SLAPI_SHUTDOWN_DISKFULL );
  604. return;
  605. }
  606. }
  607. }
  608. static void
  609. handle_listeners(Connection_Table *ct)
  610. {
  611. int idx;
  612. for (idx = 0; idx < listeners; ++idx) {
  613. int fdidx = listener_idxs[idx].idx;
  614. PRFileDesc *listenfd = listener_idxs[idx].listenfd;
  615. int secure = listener_idxs[idx].secure;
  616. int local = listener_idxs[idx].local;
  617. if (fdidx && listenfd) {
  618. if (SLAPD_POLL_LISTEN_READY(ct->fd[fdidx].out_flags)) {
  619. /* accept() the new connection, put it on the active list for handle_pr_read_ready */
  620. int rc = handle_new_connection(ct, SLAPD_INVALID_SOCKET, listenfd, secure, local, NULL);
  621. if (rc) {
  622. LDAPDebug1Arg(LDAP_DEBUG_CONNS, "Error accepting new connection listenfd=%d\n",
  623. PR_FileDesc2NativeHandle(listenfd));
  624. continue;
  625. }
  626. }
  627. }
  628. }
  629. return;
  630. }
  631. /*
  632. * Convert any pre-existing DES passwords to AES.
  633. *
  634. * Grab the "password" attributes and search all the backends for
  635. * these attributes and convert them to AES if they are DES encoded.
  636. */
  637. static void
  638. convert_pbe_des_to_aes()
  639. {
  640. Slapi_PBlock *pb = NULL;
  641. Slapi_Entry **entries = NULL;
  642. struct slapdplugin *plugin = NULL;
  643. char **attrs = NULL;
  644. char **backends = NULL;
  645. char *val = NULL;
  646. int converted_des = 0;
  647. int result = -1;
  648. int have_aes = 0;
  649. int have_des = 0;
  650. int i = 0, ii = 0, be_idx = 0;
  651. /*
  652. * Check that AES plugin is enabled, and grab all the unique
  653. * password attributes.
  654. */
  655. for ( plugin = get_plugin_list(PLUGIN_LIST_REVER_PWD_STORAGE_SCHEME);
  656. plugin != NULL;
  657. plugin = plugin->plg_next )
  658. {
  659. char *arg = NULL;
  660. if(plugin->plg_started && strcasecmp(plugin->plg_name, "AES") == 0){
  661. /* We have the AES plugin, and its enabled */
  662. have_aes = 1;
  663. }
  664. if(plugin->plg_started && strcasecmp(plugin->plg_name, "DES") == 0){
  665. /* We have the DES plugin, and its enabled */
  666. have_des = 1;
  667. }
  668. /* Gather all the unique password attributes from all the PBE plugins */
  669. for ( i = 0, arg = plugin->plg_argv[i];
  670. i < plugin->plg_argc;
  671. arg = plugin->plg_argv[++i] )
  672. {
  673. if(charray_inlist(attrs, arg)){
  674. continue;
  675. }
  676. charray_add(&attrs, slapi_ch_strdup(arg));
  677. }
  678. }
  679. if(have_aes && have_des){
  680. /*
  681. * Build a list of all the backend dn's
  682. */
  683. Slapi_Backend *be = NULL;
  684. struct suffixlist *list;
  685. char *cookie = NULL;
  686. LDAPDebug(LDAP_DEBUG_ANY, "convert_pbe_des_to_aes: "
  687. "Converting DES passwords to AES...\n",0,0,0);
  688. be = slapi_get_first_backend(&cookie);
  689. while (be){
  690. int suffix_idx = 0;
  691. int count = slapi_counter_get_value(be->be_suffixcounter);
  692. list = be->be_suffixlist;
  693. for (suffix_idx = 0; list && suffix_idx < count; suffix_idx++) {
  694. char *suffix = (char *)slapi_sdn_get_ndn(list->be_suffix);
  695. if(charray_inlist(backends, suffix) || strlen(suffix) == 0){
  696. list = list->next;
  697. continue;
  698. }
  699. charray_add(&backends, slapi_ch_strdup(suffix));
  700. list = list->next;
  701. }
  702. be = slapi_get_next_backend (cookie);
  703. }
  704. slapi_ch_free ((void **)&cookie);
  705. /*
  706. * Search for the password attributes
  707. */
  708. for (i = 0; attrs && attrs[i]; i++){
  709. char *filter = PR_smprintf("%s=*", attrs[i]);
  710. /*
  711. * Loop over all the backends looking for the password attribute
  712. */
  713. for(be_idx = 0; backends && backends[be_idx]; be_idx++){
  714. pb = slapi_pblock_new();
  715. slapi_search_internal_set_pb(pb, backends[be_idx],
  716. LDAP_SCOPE_SUBTREE, filter, NULL, 0, NULL, NULL,
  717. (void *)plugin_get_default_component_id(),
  718. SLAPI_OP_FLAG_IGNORE_UNINDEXED);
  719. slapi_search_internal_pb(pb);
  720. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  721. if (LDAP_SUCCESS != result) {
  722. LDAPDebug(LDAP_DEBUG_ANY,"convert_pbe_des_to_aes: "
  723. "failed to search for password on (%s) error (%d)\n",
  724. backends[be_idx], result, 0);
  725. goto done;
  726. }
  727. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  728. for (ii = 0; entries && entries[ii]; ii++){
  729. if((val = slapi_entry_attr_get_charptr(entries[ii], attrs[i]))){
  730. if(strlen(val) >= 5 && strncmp(val,"{DES}", 5) == 0){
  731. /*
  732. * We have a DES encoded password, convert it AES
  733. */
  734. Slapi_PBlock *mod_pb = NULL;
  735. Slapi_Value *sval = NULL;
  736. LDAPMod mod_replace;
  737. LDAPMod *mods[2];
  738. char *replace_val[2];
  739. char *passwd = NULL;
  740. /* decode the DES password */
  741. if(pw_rever_decode(val, &passwd, attrs[i]) == -1){
  742. LDAPDebug(LDAP_DEBUG_ANY,"convert_pbe_des_to_aes: "
  743. "failed to decode existing DES password for (%s)\n",
  744. slapi_entry_get_dn(entries[ii]), 0, 0);
  745. converted_des = 0;
  746. goto done;
  747. }
  748. /* encode the password */
  749. sval = slapi_value_new_string(passwd);
  750. if(pw_rever_encode(&sval, attrs[i]) == -1){
  751. LDAPDebug(LDAP_DEBUG_ANY,"convert_pbe_des_to_aes: "
  752. "failed to encode AES password for (%s)\n",
  753. slapi_entry_get_dn(entries[ii]), 0, 0);
  754. slapi_ch_free_string(&passwd);
  755. slapi_value_free(&sval);
  756. converted_des = 0;
  757. goto done;
  758. }
  759. /* replace the attribute in the entry */
  760. replace_val[0] = (char *)slapi_value_get_string(sval);
  761. replace_val[1] = NULL;
  762. mod_replace.mod_op = LDAP_MOD_REPLACE;
  763. mod_replace.mod_type = attrs[i];
  764. mod_replace.mod_values = replace_val;
  765. mods[0] = &mod_replace;
  766. mods[1] = 0;
  767. mod_pb = slapi_pblock_new();
  768. slapi_modify_internal_set_pb(mod_pb, slapi_entry_get_dn(entries[ii]),
  769. mods, 0, 0, (void *)plugin_get_default_component_id(), 0);
  770. slapi_modify_internal_pb(mod_pb);
  771. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  772. if (LDAP_SUCCESS != result) {
  773. LDAPDebug(LDAP_DEBUG_ANY,"convert_pbe_des_to_aes: "
  774. "failed to convert password for (%s) error (%d)\n",
  775. slapi_entry_get_dn(entries[ii]), result, 0);
  776. converted_des = -1;
  777. } else {
  778. LDAPDebug(LDAP_DEBUG_ANY,"convert_pbe_des_to_aes: "
  779. "successfully converted password for (%s)\n",
  780. slapi_entry_get_dn(entries[ii]), result, 0);
  781. converted_des = 1;
  782. }
  783. slapi_ch_free_string(&passwd);
  784. slapi_value_free(&sval);
  785. slapi_pblock_destroy(mod_pb);
  786. if(result){
  787. goto done;
  788. }
  789. }
  790. slapi_ch_free_string(&val);
  791. }
  792. }
  793. slapi_free_search_results_internal(pb);
  794. slapi_pblock_destroy(pb);
  795. pb = NULL;
  796. }
  797. slapi_ch_free_string(&filter);
  798. }
  799. }
  800. done:
  801. charray_free(attrs);
  802. charray_free(backends);
  803. slapi_free_search_results_internal(pb);
  804. slapi_pblock_destroy(pb);
  805. if (have_aes && have_des){
  806. /*
  807. * If a conversion attempt did not fail, disable DES plugin
  808. */
  809. if(converted_des != -1){
  810. /*
  811. * Disable the DES plugin - this also prevents potentially expensive
  812. * searches at every server startup.
  813. */
  814. LDAPMod mod_replace;
  815. LDAPMod *mods[2];
  816. char *replace_val[2];
  817. char *des_dn = "cn=DES,cn=Password Storage Schemes,cn=plugins,cn=config";
  818. replace_val[0] = "off";
  819. replace_val[1] = NULL;
  820. mod_replace.mod_op = LDAP_MOD_REPLACE;
  821. mod_replace.mod_type = "nsslapd-pluginEnabled";
  822. mod_replace.mod_values = replace_val;
  823. mods[0] = &mod_replace;
  824. mods[1] = 0;
  825. pb = slapi_pblock_new();
  826. slapi_modify_internal_set_pb(pb, des_dn, mods, 0, 0,
  827. (void *)plugin_get_default_component_id(), 0);
  828. slapi_modify_internal_pb(pb);
  829. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
  830. if (LDAP_SUCCESS != result) {
  831. LDAPDebug(LDAP_DEBUG_ANY,"convert_pbe_des_to_aes: "
  832. "Failed to disable DES plugin (%s), error (%d)\n",
  833. des_dn, result, 0);
  834. } else {
  835. LDAPDebug(LDAP_DEBUG_ANY,"convert_pbe_des_to_aes: "
  836. "Successfully disabled DES plugin (%s)\n",
  837. des_dn, 0, 0);
  838. }
  839. slapi_pblock_destroy(pb);
  840. }
  841. if(converted_des == 1){
  842. LDAPDebug(LDAP_DEBUG_ANY,"convert_pbe_des_to_aes: "
  843. "Finished - all DES passwords have been converted to AES.\n",
  844. 0, 0, 0);
  845. } else if (converted_des == 0){
  846. LDAPDebug(LDAP_DEBUG_ANY, "convert_pbe_des_to_aes: "
  847. "Finished - no DES passwords to convert.\n",0,0,0);
  848. }
  849. }
  850. }
  851. #ifdef ENABLE_NUNC_STANS
  852. static ns_job_type_t ns_listen_job_flags = NS_JOB_ACCEPT|NS_JOB_PERSIST|NS_JOB_PRESERVE_FD;
  853. static PRStack *ns_disabled_listeners; /* holds the disabled listeners, if any */
  854. static PRInt32 num_disabled_listeners;
  855. #endif
  856. #ifdef ENABLE_NUNC_STANS
  857. static void
  858. ns_disable_listener(listener_info *listener)
  859. {
  860. /* tell the event framework not to listen for new connections on this listener */
  861. ns_job_modify(listener->ns_job, NS_JOB_DISABLE_ONLY|NS_JOB_PRESERVE_FD);
  862. /* add the listener to our list of disabled listeners */
  863. PR_StackPush(ns_disabled_listeners, (PRStackElem *)listener);
  864. PR_AtomicIncrement(&num_disabled_listeners);
  865. LDAPDebug2Args(LDAP_DEBUG_ANY, "ns_disable_listener: "
  866. "disabling listener for fd [%d]: [%d] now disabled\n",
  867. PR_FileDesc2NativeHandle(listener->listenfd),
  868. num_disabled_listeners);
  869. }
  870. #endif
  871. void
  872. ns_enable_listeners()
  873. {
  874. #ifdef ENABLE_NUNC_STANS
  875. if (!enable_nunc_stans) {
  876. return;
  877. }
  878. int num_enabled = 0;
  879. listener_info *listener;
  880. while ((listener = (listener_info *)PR_StackPop(ns_disabled_listeners))) {
  881. /* there was a disabled listener - re-enable it to listen for new connections */
  882. ns_job_modify(listener->ns_job, ns_listen_job_flags);
  883. PR_AtomicDecrement(&num_disabled_listeners);
  884. num_enabled++;
  885. }
  886. if (num_enabled) {
  887. LDAPDebug1Arg(LDAP_DEBUG_ANY, "ns_enable_listeners: "
  888. "enabled [%d] listeners\n", num_enabled);
  889. }
  890. #endif
  891. }
  892. #ifdef ENABLE_NUNC_STANS
  893. /*
  894. * Nunc stans logging function.
  895. */
  896. static void
  897. nunc_stans_logging(int priority, const char *format, va_list varg)
  898. {
  899. va_list varg_copy;
  900. int severity = SLAPI_LOG_FATAL;
  901. if (priority == LOG_DEBUG){
  902. severity = SLAPI_LOG_NUNCSTANS;
  903. } else if(priority == LOG_INFO){
  904. severity = SLAPI_LOG_CONNS;
  905. }
  906. va_copy(varg_copy, varg);
  907. slapi_log_error_ext(severity, "nunc-stans", (char *)format, varg, varg_copy);
  908. va_end(varg_copy);
  909. }
  910. static void*
  911. nunc_stans_malloc(size_t size)
  912. {
  913. return (void*)slapi_ch_malloc((unsigned long)size);
  914. }
  915. static void*
  916. nunc_stans_calloc(size_t count, size_t size)
  917. {
  918. return (void*)slapi_ch_calloc((unsigned long)count, (unsigned long)size);
  919. }
  920. static void*
  921. nunc_stans_realloc(void *block, size_t size)
  922. {
  923. return (void*)slapi_ch_realloc((char *)block, (unsigned long)size);
  924. }
  925. static void
  926. nunc_stans_free(void *ptr)
  927. {
  928. slapi_ch_free((void **)&ptr);
  929. }
  930. #endif /* ENABLE_NUNC_STANS */
  931. void slapd_daemon( daemon_ports_t *ports )
  932. {
  933. /* We are passed some ports---one for regular connections, one
  934. * for SSL connections, one for ldapi connections.
  935. */
  936. /* Previously there was a ton of code #defined on NET_SSL.
  937. * This looked horrible, so now I'm doing it this way:
  938. * If you want me to do SSL, pass me something in the ssl port number.
  939. * If you don't, pass me zero.
  940. */
  941. PRFileDesc **n_tcps = NULL;
  942. PRFileDesc **s_tcps = NULL;
  943. PRFileDesc **i_unix = NULL;
  944. PRFileDesc **fdesp = NULL;
  945. PRIntn num_poll = 0;
  946. PRIntervalTime pr_timeout = PR_MillisecondsToInterval(slapd_wakeup_timer);
  947. PRThread *time_thread_p;
  948. int threads;
  949. int in_referral_mode = config_check_referral_mode();
  950. #ifdef ENABLE_NUNC_STANS
  951. ns_thrpool_t *tp = NULL;
  952. struct ns_thrpool_config tp_config;
  953. #endif
  954. int connection_table_size = get_configured_connection_table_size();
  955. the_connection_table= connection_table_new(connection_table_size);
  956. #ifdef ENABLE_NUNC_STANS
  957. enable_nunc_stans = config_get_enable_nunc_stans();
  958. #endif
  959. #ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS
  960. /*
  961. * Some DNS resolver implementations, such as the one built into
  962. * Solaris <= 8, need to use one or more low numbered file
  963. * descriptors internally (probably because they use a deficient
  964. * implementation of stdio). So we make a call now that uses the
  965. * resolver so it has an opportunity to grab whatever low file
  966. * descriptors it needs (before we use up all of the low numbered
  967. * ones for incoming client connections and so on).
  968. */
  969. get_loopback_by_addr();
  970. #endif
  971. /* Retrieve the sockets from their hiding place */
  972. n_tcps = ports->n_socket;
  973. s_tcps = ports->s_socket;
  974. #if defined(ENABLE_LDAPI)
  975. i_unix = ports->i_socket;
  976. #endif /* ENABLE_LDAPI */
  977. if (!enable_nunc_stans) {
  978. createsignalpipe();
  979. }
  980. init_shutdown_detect();
  981. if (
  982. (n_tcps == NULL) &&
  983. #if defined(ENABLE_LDAPI)
  984. (i_unix == NULL) &&
  985. #endif /* ENABLE_LDAPI */
  986. (s_tcps == NULL) ) { /* nothing to do */
  987. LDAPDebug( LDAP_DEBUG_ANY,
  988. "no port to listen on\n", 0, 0, 0 );
  989. exit( 1 );
  990. }
  991. init_op_threads ();
  992. /* Start the time thread */
  993. time_thread_p = PR_CreateThread(PR_SYSTEM_THREAD,
  994. (VFP) (void *) time_thread, NULL,
  995. PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
  996. PR_JOINABLE_THREAD,
  997. SLAPD_DEFAULT_THREAD_STACKSIZE);
  998. if ( NULL == time_thread_p ) {
  999. PRErrorCode errorCode = PR_GetError();
  1000. LDAPDebug(LDAP_DEBUG_ANY, "Unable to create time thread - Shutting Down ("
  1001. SLAPI_COMPONENT_NAME_NSPR " error %d - %s)\n",
  1002. errorCode, slapd_pr_strerror(errorCode), 0);
  1003. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  1004. }
  1005. /*
  1006. * If we are monitoring disk space, then create the mutex, the cvar,
  1007. * and the monitoring thread.
  1008. */
  1009. if( config_get_disk_monitoring() ){
  1010. if ( ( diskmon_mutex = PR_NewLock() ) == NULL ) {
  1011. slapi_log_error(SLAPI_LOG_FATAL, NULL,
  1012. "Cannot create new lock for disk space monitoring. "
  1013. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1014. PR_GetError(), slapd_pr_strerror( PR_GetError() ));
  1015. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  1016. }
  1017. if ( diskmon_mutex ){
  1018. if(( diskmon_cvar = PR_NewCondVar( diskmon_mutex )) == NULL ) {
  1019. slapi_log_error(SLAPI_LOG_FATAL, NULL,
  1020. "Cannot create new condition variable for disk space monitoring. "
  1021. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1022. PR_GetError(), slapd_pr_strerror( PR_GetError() ));
  1023. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  1024. }
  1025. }
  1026. if( diskmon_mutex && diskmon_cvar ){
  1027. disk_thread_p = PR_CreateThread(PR_SYSTEM_THREAD,
  1028. (VFP) (void *) disk_monitoring_thread, NULL,
  1029. PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
  1030. PR_JOINABLE_THREAD,
  1031. SLAPD_DEFAULT_THREAD_STACKSIZE);
  1032. if ( NULL == disk_thread_p ) {
  1033. PRErrorCode errorCode = PR_GetError();
  1034. LDAPDebug(LDAP_DEBUG_ANY, "Unable to create disk monitoring thread - Shutting Down ("
  1035. SLAPI_COMPONENT_NAME_NSPR " error %d - %s)\n",
  1036. errorCode, slapd_pr_strerror(errorCode), 0);
  1037. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  1038. }
  1039. }
  1040. }
  1041. /* We are now ready to accept incoming connections */
  1042. if ( n_tcps != NULL ) {
  1043. PRFileDesc **fdesp;
  1044. PRNetAddr **nap = ports->n_listenaddr;
  1045. for (fdesp = n_tcps; fdesp && *fdesp; fdesp++, nap++) {
  1046. if ( PR_Listen( *fdesp, config_get_listen_backlog_size() ) == PR_FAILURE ) {
  1047. PRErrorCode prerr = PR_GetError();
  1048. char addrbuf[ 256 ];
  1049. slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
  1050. "PR_Listen() on %s port %d failed: %s error %d (%s)\n",
  1051. netaddr2string(*nap, addrbuf, sizeof(addrbuf)),
  1052. ports->n_port, SLAPI_COMPONENT_NAME_NSPR, prerr,
  1053. slapd_pr_strerror( prerr ));
  1054. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  1055. }
  1056. listeners++;
  1057. }
  1058. }
  1059. if ( s_tcps != NULL ) {
  1060. PRFileDesc **fdesp;
  1061. PRNetAddr **sap = ports->s_listenaddr;
  1062. for (fdesp = s_tcps; fdesp && *fdesp; fdesp++, sap++) {
  1063. if ( PR_Listen( *fdesp, config_get_listen_backlog_size() ) == PR_FAILURE ) {
  1064. PRErrorCode prerr = PR_GetError();
  1065. char addrbuf[ 256 ];
  1066. slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
  1067. "PR_Listen() on %s port %d failed: %s error %d (%s)\n",
  1068. netaddr2string(*sap, addrbuf, sizeof(addrbuf)),
  1069. ports->s_port, SLAPI_COMPONENT_NAME_NSPR, prerr,
  1070. slapd_pr_strerror( prerr ));
  1071. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  1072. }
  1073. listeners++;
  1074. }
  1075. }
  1076. #if defined(ENABLE_LDAPI)
  1077. if( i_unix != NULL ) {
  1078. PRFileDesc **fdesp;
  1079. PRNetAddr **iap = ports->i_listenaddr;
  1080. for (fdesp = i_unix; fdesp && *fdesp; fdesp++, iap++) {
  1081. if ( PR_Listen(*fdesp, config_get_listen_backlog_size()) == PR_FAILURE) {
  1082. PRErrorCode prerr = PR_GetError();
  1083. slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
  1084. "listen() on %s failed: error %d (%s)\n",
  1085. (*iap)->local.path,
  1086. prerr,
  1087. slapd_pr_strerror( prerr ));
  1088. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  1089. }
  1090. listeners++;
  1091. }
  1092. }
  1093. #endif /* ENABLE_LDAPI */
  1094. listener_idxs = (listener_info *)slapi_ch_calloc(listeners, sizeof(*listener_idxs));
  1095. #ifdef ENABLE_NUNC_STANS
  1096. if (enable_nunc_stans) {
  1097. ns_disabled_listeners = PR_CreateStack("disabled_listeners");
  1098. }
  1099. #endif
  1100. /*
  1101. * Convert old DES encoded passwords to AES
  1102. */
  1103. convert_pbe_des_to_aes();
  1104. #ifdef ENABLE_NUNC_STANS
  1105. if (enable_nunc_stans && !g_get_shutdown()) {
  1106. int ii;
  1107. PRInt32 maxthreads = (PRInt32)config_get_threadnumber();
  1108. /* Set the nunc-stans thread pool config */
  1109. ns_thrpool_config_init(&tp_config);
  1110. tp_config.initial_threads = maxthreads;
  1111. tp_config.max_threads = maxthreads;
  1112. tp_config.stacksize = 0;
  1113. tp_config.event_queue_size = config_get_maxdescriptors();
  1114. tp_config.work_queue_size = config_get_maxdescriptors();
  1115. tp_config.log_fct = nunc_stans_logging;
  1116. tp_config.log_start_fct = NULL;
  1117. tp_config.log_close_fct = NULL;
  1118. tp_config.malloc_fct = nunc_stans_malloc;
  1119. tp_config.calloc_fct = nunc_stans_calloc;
  1120. tp_config.realloc_fct = nunc_stans_realloc;
  1121. tp_config.free_fct = nunc_stans_free;
  1122. tp = ns_thrpool_new(&tp_config);
  1123. ns_add_signal_job(tp, SIGINT, NS_JOB_SIGNAL, ns_set_shutdown, NULL, &ns_signal_job[0]);
  1124. ns_add_signal_job(tp, SIGTERM, NS_JOB_SIGNAL, ns_set_shutdown, NULL, &ns_signal_job[1]);
  1125. ns_add_signal_job(tp, SIGHUP, NS_JOB_SIGNAL, ns_set_shutdown, NULL, &ns_signal_job[2]);
  1126. setup_pr_read_pds(the_connection_table,n_tcps,s_tcps,i_unix,&num_poll);
  1127. for (ii = 0; ii < listeners; ++ii) {
  1128. listener_idxs[ii].ct = the_connection_table; /* to pass to handle_new_connection */
  1129. ns_add_io_job(tp, listener_idxs[ii].listenfd, ns_listen_job_flags,
  1130. ns_handle_new_connection, &listener_idxs[ii], &listener_idxs[ii].ns_job);
  1131. }
  1132. }
  1133. #endif /* ENABLE_NUNC_STANS */
  1134. /* Now we write the pid file, indicating that the server is finally and listening for connections */
  1135. write_pid_file();
  1136. /* The server is ready and listening for connections. Logging "slapd started" message. */
  1137. unfurl_banners(the_connection_table,ports,n_tcps,s_tcps,i_unix);
  1138. #ifdef WITH_SYSTEMD
  1139. sd_notifyf(0, "READY=1\n"
  1140. "STATUS=slapd started: Ready to process requests\n"
  1141. "MAINPID=%lu",
  1142. (unsigned long) getpid()
  1143. );
  1144. #endif
  1145. #ifdef ENABLE_NUNC_STANS
  1146. if (enable_nunc_stans && ns_thrpool_wait(tp)) {
  1147. LDAPDebug( LDAP_DEBUG_ANY,
  1148. "ns_thrpool_wait failed errno %d (%s)\n", errno,
  1149. slapd_system_strerror(errno), 0 );
  1150. }
  1151. #endif
  1152. /* The meat of the operation is in a loop on a call to select */
  1153. while(!enable_nunc_stans && !g_get_shutdown())
  1154. {
  1155. int select_return = 0;
  1156. PRErrorCode prerr;
  1157. setup_pr_read_pds(the_connection_table,n_tcps,s_tcps,i_unix,&num_poll);
  1158. select_return = POLL_FN(the_connection_table->fd, num_poll, pr_timeout);
  1159. switch (select_return) {
  1160. case 0: /* Timeout */
  1161. /* GGOODREPL handle_timeout(); */
  1162. break;
  1163. case -1: /* Error */
  1164. prerr = PR_GetError();
  1165. LDAPDebug( LDAP_DEBUG_TRACE, "PR_Poll() failed, "
  1166. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1167. prerr, slapd_system_strerror(prerr), 0 );
  1168. break;
  1169. default: /* either a new connection or some new data ready */
  1170. /* handle new connections from the listeners */
  1171. handle_listeners(the_connection_table);
  1172. /* handle new data ready */
  1173. handle_pr_read_ready(the_connection_table, connection_table_size);
  1174. clear_signal(the_connection_table->fd);
  1175. break;
  1176. }
  1177. }
  1178. /* We get here when the server is shutting down */
  1179. /* Do what we have to do before death */
  1180. #ifdef WITH_SYSTEMD
  1181. sd_notify(0, "STOPPING=1");
  1182. #endif
  1183. connection_table_abandon_all_operations(the_connection_table); /* abandon all operations in progress */
  1184. if ( ! in_referral_mode ) {
  1185. ps_stop_psearch_system(); /* stop any persistent searches */
  1186. }
  1187. /* free the listener indexes */
  1188. slapi_ch_free((void **)&listener_idxs);
  1189. for (fdesp = n_tcps; fdesp && *fdesp; fdesp++) {
  1190. PR_Close( *fdesp );
  1191. }
  1192. slapi_ch_free ((void**)&n_tcps);
  1193. for (fdesp = i_unix; fdesp && *fdesp; fdesp++) {
  1194. PR_Close( *fdesp );
  1195. }
  1196. slapi_ch_free ((void**)&i_unix);
  1197. for (fdesp = s_tcps; fdesp && *fdesp; fdesp++) {
  1198. PR_Close( *fdesp );
  1199. }
  1200. slapi_ch_free ((void**)&s_tcps);
  1201. /* freeing NetAddrs */
  1202. {
  1203. PRNetAddr **nap;
  1204. for (nap = ports->n_listenaddr; nap && *nap; nap++) {
  1205. slapi_ch_free ((void**)nap);
  1206. }
  1207. slapi_ch_free ((void**)&ports->n_listenaddr);
  1208. for (nap = ports->s_listenaddr; nap && *nap; nap++) {
  1209. slapi_ch_free ((void**)nap);
  1210. }
  1211. slapi_ch_free ((void**)&ports->s_listenaddr);
  1212. #if defined(ENABLE_LDAPI)
  1213. for (nap = ports->i_listenaddr; nap && *nap; nap++) {
  1214. slapi_ch_free ((void**)nap);
  1215. }
  1216. slapi_ch_free ((void**)&ports->i_listenaddr);
  1217. #endif
  1218. }
  1219. /* Might compete with housecleaning thread, but so far so good */
  1220. be_flushall();
  1221. op_thread_cleanup();
  1222. housekeeping_stop(); /* Run this after op_thread_cleanup() logged sth */
  1223. disk_monitoring_stop(disk_thread_p);
  1224. threads = g_get_active_threadcnt();
  1225. if ( threads > 0 ) {
  1226. LDAPDebug( LDAP_DEBUG_ANY,
  1227. "slapd shutting down - waiting for %d thread%s to terminate\n",
  1228. threads, ( threads > 1 ) ? "s" : "", 0 );
  1229. }
  1230. threads = g_get_active_threadcnt();
  1231. while ( threads > 0 ) {
  1232. if (!enable_nunc_stans) {
  1233. PRPollDesc xpd;
  1234. char x;
  1235. int spe = 0;
  1236. /* try to read from the signal pipe, in case threads are
  1237. * blocked on it. */
  1238. xpd.fd = signalpipe[0];
  1239. xpd.in_flags = PR_POLL_READ;
  1240. xpd.out_flags = 0;
  1241. spe = PR_Poll(&xpd, 1, PR_INTERVAL_NO_WAIT);
  1242. if (spe > 0) {
  1243. spe = PR_Read(signalpipe[0], &x, 1);
  1244. if (spe < 0) {
  1245. PRErrorCode prerr = PR_GetError();
  1246. LDAPDebug( LDAP_DEBUG_ANY, "listener could not clear signal pipe, "
  1247. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1248. prerr, slapd_system_strerror(prerr), 0 );
  1249. break;
  1250. }
  1251. } else if (spe == -1) {
  1252. PRErrorCode prerr = PR_GetError();
  1253. LDAPDebug( LDAP_DEBUG_ANY, "PR_Poll() failed, "
  1254. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1255. prerr, slapd_system_strerror(prerr), 0 );
  1256. break;
  1257. } else {
  1258. /* no data */
  1259. }
  1260. }
  1261. DS_Sleep(PR_INTERVAL_NO_WAIT);
  1262. if ( threads != g_get_active_threadcnt() ) {
  1263. LDAPDebug( LDAP_DEBUG_TRACE,
  1264. "slapd shutting down - waiting for %d threads to terminate\n",
  1265. g_get_active_threadcnt(), 0, 0 );
  1266. threads = g_get_active_threadcnt();
  1267. }
  1268. }
  1269. LDAPDebug( LDAP_DEBUG_ANY,
  1270. "slapd shutting down - closing down internal subsystems and plugins\n",
  1271. 0, 0, 0 );
  1272. log_access_flush();
  1273. /* let backends do whatever cleanup they need to do */
  1274. LDAPDebug( LDAP_DEBUG_TRACE,"slapd shutting down - waiting for backends to close down\n", 0, 0,0 );
  1275. eq_stop();
  1276. if ( ! in_referral_mode ) {
  1277. task_shutdown();
  1278. uniqueIDGenCleanup ();
  1279. }
  1280. plugin_closeall( 1 /* Close Backends */, 1 /* Close Globals */);
  1281. if ( ! in_referral_mode ) {
  1282. /* Close SNMP collator after the plugins closed...
  1283. * Replication plugin still performs internal ops that
  1284. * may try to increment snmp stats.
  1285. * Fix for defect 523780
  1286. */
  1287. snmp_collator_stop();
  1288. mapping_tree_free ();
  1289. }
  1290. /*
  1291. * connection_table_free could use callbacks in the backend.
  1292. * (e.g., be_search_results_release)
  1293. * Thus, it needs to be called before be_cleanupall.
  1294. */
  1295. connection_table_free(the_connection_table);
  1296. the_connection_table= NULL;
  1297. #ifdef ENABLE_NUNC_STANS
  1298. if (enable_nunc_stans) {
  1299. ns_thrpool_destroy(tp);
  1300. }
  1301. #endif
  1302. be_cleanupall ();
  1303. connection_post_shutdown_cleanup();
  1304. LDAPDebug( LDAP_DEBUG_TRACE, "slapd shutting down - backends closed down\n",
  1305. 0, 0, 0 );
  1306. referrals_free();
  1307. schema_destroy_dse_lock();
  1308. /* tell the time thread to shutdown and then wait for it */
  1309. time_shutdown = 1;
  1310. PR_JoinThread( time_thread_p );
  1311. if ( g_get_shutdown() == SLAPI_SHUTDOWN_DISKFULL ){
  1312. /* This is a server-induced shutdown, we need to manually remove the pid file */
  1313. if( unlink(get_pid_file()) ){
  1314. LDAPDebug( LDAP_DEBUG_ANY, "Failed to remove pid file %s\n", get_pid_file(), 0, 0 );
  1315. }
  1316. }
  1317. }
  1318. int signal_listner()
  1319. {
  1320. if (enable_nunc_stans) {
  1321. return( 0 );
  1322. }
  1323. /* Replaces previous macro---called to bump the thread out of select */
  1324. if ( write( writesignalpipe, "", 1) != 1 ) {
  1325. /* this now means that the pipe is full
  1326. * this is not a problem just go-on
  1327. */
  1328. LDAPDebug( LDAP_DEBUG_CONNS,
  1329. "listener could not write to signal pipe %d\n",
  1330. errno, 0, 0 );
  1331. }
  1332. return( 0 );
  1333. }
  1334. static int clear_signal(struct POLL_STRUCT *fds)
  1335. {
  1336. if (enable_nunc_stans) {
  1337. return 0;
  1338. }
  1339. if ( fds[FDS_SIGNAL_PIPE].out_flags & SLAPD_POLL_FLAGS ) {
  1340. char buf[200];
  1341. LDAPDebug( LDAP_DEBUG_CONNS, "listener got signaled\n", 0, 0, 0 );
  1342. if ( read( readsignalpipe, buf, 200 ) < 1 ) {
  1343. LDAPDebug( LDAP_DEBUG_ANY, "listener could not clear signal pipe\n",
  1344. 0, 0, 0 );
  1345. }
  1346. }
  1347. return 0;
  1348. }
  1349. static int first_time_setup_pr_read_pds = 1;
  1350. static int listen_addr_count = 0;
  1351. static void
  1352. setup_pr_read_pds(Connection_Table *ct, PRFileDesc **n_tcps, PRFileDesc **s_tcps, PRFileDesc **i_unix, PRIntn *num_to_read)
  1353. {
  1354. Connection *c= NULL;
  1355. Connection *next= NULL;
  1356. LBER_SOCKET socketdesc = SLAPD_INVALID_SOCKET;
  1357. int accept_new_connections;
  1358. static int last_accept_new_connections = -1;
  1359. PRIntn count = 0;
  1360. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  1361. int max_threads_per_conn = config_get_maxthreadsperconn();
  1362. int n_listeners = 0;
  1363. accept_new_connections = ((ct->size - g_get_current_conn_count())
  1364. > slapdFrontendConfig->reservedescriptors);
  1365. if ( ! accept_new_connections ) {
  1366. if ( last_accept_new_connections ) {
  1367. LDAPDebug( LDAP_DEBUG_ANY, "Not listening for new "
  1368. "connections - too many fds open\n", 0, 0, 0 );
  1369. /* reinitialize n_tcps and s_tcps to the pds */
  1370. first_time_setup_pr_read_pds = 1;
  1371. }
  1372. } else {
  1373. if ( ! last_accept_new_connections &&
  1374. last_accept_new_connections != -1 ) {
  1375. LDAPDebug( LDAP_DEBUG_ANY, "Listening for new "
  1376. "connections again\n", 0, 0, 0 );
  1377. /* reinitialize n_tcps and s_tcps to the pds */
  1378. first_time_setup_pr_read_pds = 1;
  1379. }
  1380. }
  1381. last_accept_new_connections = accept_new_connections;
  1382. /* initialize the mapping from connection table entries to fds entries */
  1383. if (first_time_setup_pr_read_pds)
  1384. {
  1385. int i;
  1386. for (i = 0; i < ct->size; i++)
  1387. {
  1388. ct->c[i].c_fdi = SLAPD_INVALID_SOCKET_INDEX;
  1389. }
  1390. if (!enable_nunc_stans) {
  1391. /* The fds entry for the signalpipe is always FDS_SIGNAL_PIPE (== 0) */
  1392. count = FDS_SIGNAL_PIPE;
  1393. ct->fd[count].fd = signalpipe[0];
  1394. ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
  1395. ct->fd[count].out_flags = 0;
  1396. count++;
  1397. }
  1398. /* The fds entry for n_tcps starts with n_tcps and less than n_tcpe */
  1399. ct->n_tcps = count;
  1400. if (n_tcps != NULL && accept_new_connections)
  1401. {
  1402. PRFileDesc **fdesc = NULL;
  1403. for (fdesc = n_tcps; fdesc && *fdesc; fdesc++, count++) {
  1404. ct->fd[count].fd = *fdesc;
  1405. ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
  1406. ct->fd[count].out_flags = 0;
  1407. listener_idxs[n_listeners].listenfd = *fdesc;
  1408. listener_idxs[n_listeners].idx = count;
  1409. n_listeners++;
  1410. LDAPDebug( LDAP_DEBUG_HOUSE,
  1411. "listening for connections on %d\n", socketdesc, 0, 0 );
  1412. }
  1413. } else {
  1414. ct->fd[count].fd = NULL;
  1415. count++;
  1416. }
  1417. ct->n_tcpe = count;
  1418. ct->s_tcps = count;
  1419. /* The fds entry for s_tcps starts with s_tcps and less than s_tcpe */
  1420. if (s_tcps != NULL && accept_new_connections)
  1421. {
  1422. PRFileDesc **fdesc = NULL;
  1423. for (fdesc = s_tcps; fdesc && *fdesc; fdesc++, count++) {
  1424. ct->fd[count].fd = *fdesc;
  1425. ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
  1426. ct->fd[count].out_flags = 0;
  1427. listener_idxs[n_listeners].listenfd = *fdesc;
  1428. listener_idxs[n_listeners].idx = count;
  1429. listener_idxs[n_listeners].secure = 1;
  1430. n_listeners++;
  1431. LDAPDebug( LDAP_DEBUG_HOUSE,
  1432. "listening for SSL connections on %d\n", socketdesc, 0, 0 );
  1433. }
  1434. } else {
  1435. ct->fd[count].fd = NULL;
  1436. count++;
  1437. }
  1438. ct->s_tcpe = count;
  1439. #if defined(ENABLE_LDAPI)
  1440. ct->i_unixs = count;
  1441. /* The fds entry for i_unix starts with i_unixs and less than i_unixe */
  1442. if (i_unix != NULL && accept_new_connections)
  1443. {
  1444. PRFileDesc **fdesc = NULL;
  1445. for (fdesc = i_unix; fdesc && *fdesc; fdesc++, count++) {
  1446. ct->fd[count].fd = *fdesc;
  1447. ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
  1448. ct->fd[count].out_flags = 0;
  1449. listener_idxs[n_listeners].listenfd = *fdesc;
  1450. listener_idxs[n_listeners].idx = count;
  1451. listener_idxs[n_listeners].local = 1;
  1452. n_listeners++;
  1453. LDAPDebug( LDAP_DEBUG_HOUSE,
  1454. "listening for LDAPI connections on %d\n", socketdesc, 0, 0 );
  1455. }
  1456. } else {
  1457. ct->fd[count].fd = NULL;
  1458. count++;
  1459. }
  1460. ct->i_unixe = count;
  1461. #endif
  1462. first_time_setup_pr_read_pds = 0;
  1463. listen_addr_count = count;
  1464. if (n_listeners < listeners) {
  1465. listener_idxs[n_listeners].idx = 0;
  1466. listener_idxs[n_listeners].listenfd = NULL;
  1467. }
  1468. }
  1469. /* count is the number of entries we've place in the fds array.
  1470. * listen_addr_count is counted up when
  1471. * first_time_setup_pr_read_pds is TURE. */
  1472. count = listen_addr_count;
  1473. /* Walk down the list of active connections to find
  1474. * out which connections we should poll over. If a connection
  1475. * is no longer in use, we should remove it from the linked
  1476. * list. */
  1477. c = connection_table_get_first_active_connection (ct);
  1478. while (c)
  1479. {
  1480. next = connection_table_get_next_active_connection (ct, c);
  1481. if ( c->c_mutex == NULL )
  1482. {
  1483. connection_table_move_connection_out_of_active_list(ct,c);
  1484. }
  1485. else
  1486. {
  1487. PR_EnterMonitor(c->c_mutex);
  1488. if (c->c_flags & CONN_FLAG_CLOSING)
  1489. {
  1490. /* A worker thread has marked that this connection
  1491. * should be closed by calling disconnect_server.
  1492. * move this connection out of the active list
  1493. * the last thread to use the connection will close it
  1494. */
  1495. connection_table_move_connection_out_of_active_list(ct,c);
  1496. }
  1497. else if ( c->c_sd == SLAPD_INVALID_SOCKET )
  1498. {
  1499. connection_table_move_connection_out_of_active_list(ct,c);
  1500. }
  1501. else if ( c->c_prfd != NULL)
  1502. {
  1503. if ((!c->c_gettingber)
  1504. && (c->c_threadnumber < max_threads_per_conn))
  1505. {
  1506. int add_fd = 1;
  1507. /* check timeout for PAGED RESULTS */
  1508. if (pagedresults_is_timedout_nolock(c))
  1509. {
  1510. /* Exceeded the timelimit; disconnect the client */
  1511. disconnect_server_nomutex(c, c->c_connid, -1,
  1512. SLAPD_DISCONNECT_IO_TIMEOUT,
  1513. 0);
  1514. connection_table_move_connection_out_of_active_list(ct,
  1515. c);
  1516. add_fd = 0; /* do not poll on this fd */
  1517. }
  1518. if (add_fd)
  1519. {
  1520. ct->fd[count].fd = c->c_prfd;
  1521. ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
  1522. /* slot i of the connection table is mapped to slot
  1523. * count of the fds array */
  1524. c->c_fdi = count;
  1525. count++;
  1526. }
  1527. }
  1528. else
  1529. {
  1530. if(c->c_threadnumber >= max_threads_per_conn){
  1531. c->c_maxthreadsblocked++;
  1532. }
  1533. c->c_fdi = SLAPD_INVALID_SOCKET_INDEX;
  1534. }
  1535. }
  1536. PR_ExitMonitor(c->c_mutex);
  1537. }
  1538. c = next;
  1539. }
  1540. if( num_to_read )
  1541. (*num_to_read) = count;
  1542. }
  1543. #ifdef notdef /* GGOODREPL */
  1544. static void
  1545. handle_timeout( void )
  1546. {
  1547. static time_t prevtime = 0;
  1548. static time_t housekeeping_fire_time = 0;
  1549. time_t curtime = current_time();
  1550. if (0 == prevtime) {
  1551. prevtime = time (&housekeeping_fire_time);
  1552. }
  1553. if ( difftime(curtime, prevtime) >=
  1554. slapd_housekeeping_timer ) {
  1555. int num_active_threads;
  1556. snmp_collator_update();
  1557. prevtime = curtime;
  1558. num_active_threads = g_get_active_threadcnt();
  1559. if ( (num_active_threads == 0) ||
  1560. (difftime(curtime, housekeeping_fire_time) >=
  1561. slapd_housekeeping_timer*3) ) {
  1562. housekeeping_fire_time = curtime;
  1563. housekeeping_start(curtime);
  1564. }
  1565. }
  1566. }
  1567. #endif /* notdef */
  1568. static int idletimeout_reslimit_handle = -1;
  1569. /*
  1570. * Register the idletimeout with the binder-based resource limits
  1571. * subsystem. A SLAPI_RESLIMIT_STATUS_... code is returned.
  1572. */
  1573. int
  1574. daemon_register_reslimits( void )
  1575. {
  1576. return( slapi_reslimit_register( SLAPI_RESLIMIT_TYPE_INT, "nsIdleTimeout",
  1577. &idletimeout_reslimit_handle ));
  1578. }
  1579. static void
  1580. handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll)
  1581. {
  1582. Connection *c;
  1583. time_t curtime = current_time();
  1584. int maxthreads = config_get_maxthreadsperconn();
  1585. #if LDAP_DEBUG
  1586. if ( slapd_ldap_debug & LDAP_DEBUG_CONNS )
  1587. {
  1588. connection_table_dump_activity_to_errors_log(ct);
  1589. }
  1590. #endif /* LDAP_DEBUG */
  1591. /*
  1592. * This function is called for all connections, so we traverse the entire
  1593. * active connection list to find any errors, activity, etc.
  1594. */
  1595. for ( c = connection_table_get_first_active_connection (ct); c != NULL;
  1596. c = connection_table_get_next_active_connection (ct, c) )
  1597. {
  1598. if ( c->c_mutex != NULL )
  1599. {
  1600. /* this check can be done without acquiring the mutex */
  1601. if (c->c_gettingber) continue;
  1602. PR_EnterMonitor(c->c_mutex);
  1603. if ( connection_is_active_nolock (c) && c->c_gettingber == 0 )
  1604. {
  1605. PRInt16 out_flags;
  1606. short readready;
  1607. if (c->c_fdi != SLAPD_INVALID_SOCKET_INDEX)
  1608. {
  1609. out_flags = ct->fd[c->c_fdi].out_flags;
  1610. }
  1611. else
  1612. {
  1613. out_flags = 0;
  1614. }
  1615. readready = ( out_flags & SLAPD_POLL_FLAGS );
  1616. if ( !readready && out_flags )
  1617. {
  1618. /* some error occured */
  1619. LDAPDebug( LDAP_DEBUG_CONNS,
  1620. "POLL_FN() says connection on sd %d is bad "
  1621. "(closing)\n", c->c_sd, 0, 0 );
  1622. disconnect_server_nomutex( c, c->c_connid, -1,
  1623. SLAPD_DISCONNECT_POLL, EPIPE );
  1624. }
  1625. else if ( readready )
  1626. {
  1627. /* read activity */
  1628. LDAPDebug( LDAP_DEBUG_CONNS,
  1629. "read activity on %d\n", c->c_ci, 0, 0 );
  1630. c->c_idlesince = curtime;
  1631. /* This is where the work happens ! */
  1632. /* MAB: 25 jan 01, error handling added */
  1633. if ((connection_activity( c, maxthreads )) == -1) {
  1634. /* This might happen as a result of
  1635. * trying to acquire a closing connection
  1636. */
  1637. LDAPDebug (LDAP_DEBUG_ANY,
  1638. "connection_activity: abandoning conn %" NSPRIu64 " as fd=%d is already closing\n",
  1639. c->c_connid,c->c_sd,0);
  1640. /* The call disconnect_server should do nothing,
  1641. * as the connection c should be already set to CLOSING */
  1642. disconnect_server_nomutex( c, c->c_connid, -1,
  1643. SLAPD_DISCONNECT_POLL, EPIPE );
  1644. }
  1645. }
  1646. else if (c->c_idletimeout > 0 &&
  1647. (curtime - c->c_idlesince) >= c->c_idletimeout &&
  1648. NULL == c->c_ops )
  1649. {
  1650. /* idle timeout */
  1651. disconnect_server_nomutex( c, c->c_connid, -1,
  1652. SLAPD_DISCONNECT_IDLE_TIMEOUT, EAGAIN );
  1653. }
  1654. }
  1655. PR_ExitMonitor(c->c_mutex);
  1656. }
  1657. }
  1658. }
  1659. #ifdef ENABLE_NUNC_STANS
  1660. #define CONN_NEEDS_CLOSING(c) (c->c_flags & CONN_FLAG_CLOSING) || (c->c_sd == SLAPD_INVALID_SOCKET)
  1661. /* Used internally by ns_handle_closure and ns_handle_pr_read_ready.
  1662. * Returns 0 if the connection was successfully closed, or 1 otherwise.
  1663. * Must be called with the c->c_mutex locked.
  1664. */
  1665. static int
  1666. ns_handle_closure_nomutex(Connection *c)
  1667. {
  1668. int rc = 0;
  1669. PR_ASSERT(c->c_refcnt > 0); /* one for the conn active list, plus possible other threads */
  1670. PR_ASSERT(CONN_NEEDS_CLOSING(c));
  1671. if (connection_table_move_connection_out_of_active_list(c->c_ct, c)) {
  1672. /* not closed - another thread still has a ref */
  1673. rc = 1;
  1674. /* reschedule closure job */
  1675. ns_connection_post_io_or_closing(c);
  1676. }
  1677. return rc;
  1678. }
  1679. /* This function is called when the connection has been marked
  1680. * as closing and needs to be cleaned up. It will keep trying
  1681. * and re-arming itself until there are no references.
  1682. */
  1683. static void
  1684. ns_handle_closure(struct ns_job_t *job)
  1685. {
  1686. Connection *c = (Connection *)ns_job_get_data(job);
  1687. int do_yield = 0;
  1688. /* this function must be called from the event loop thread */
  1689. #ifdef DEBUG
  1690. PR_ASSERT(0 == NS_JOB_IS_THREAD(ns_job_get_type(job)));
  1691. #else
  1692. /* This doesn't actually confirm it's in the event loop thread, but it's a start */
  1693. if (NS_JOB_IS_THREAD(ns_job_get_type(job)) != 0) {
  1694. LDAPDebug2Args(LDAP_DEBUG_ANY, "ns_handle_closure: Attempt to close outside of event loop thread %" NSPRIu64 " for fd=%d\n",
  1695. c->c_connid, c->c_sd);
  1696. return;
  1697. }
  1698. #endif
  1699. PR_EnterMonitor(c->c_mutex);
  1700. connection_release_nolock_ext(c, 1); /* release ref acquired for event framework */
  1701. PR_ASSERT(c->c_ns_close_jobs == 1); /* should be exactly 1 active close job - this one */
  1702. c->c_ns_close_jobs--; /* this job is processing closure */
  1703. do_yield = ns_handle_closure_nomutex(c);
  1704. PR_ExitMonitor(c->c_mutex);
  1705. ns_job_done(job);
  1706. if (do_yield) {
  1707. /* closure not done - another reference still outstanding */
  1708. /* yield thread after unlocking conn mutex */
  1709. PR_Sleep(PR_INTERVAL_NO_WAIT); /* yield to allow other thread to release conn */
  1710. }
  1711. return;
  1712. }
  1713. #endif
  1714. /**
  1715. * Schedule more I/O for this connection, or make sure that it
  1716. * is closed in the event loop.
  1717. */
  1718. void
  1719. ns_connection_post_io_or_closing(Connection *conn)
  1720. {
  1721. #ifdef ENABLE_NUNC_STANS
  1722. struct timeval tv;
  1723. if (!enable_nunc_stans) {
  1724. return;
  1725. }
  1726. if (CONN_NEEDS_CLOSING(conn)) {
  1727. /* there should only ever be 0 or 1 active closure jobs */
  1728. PR_ASSERT((conn->c_ns_close_jobs == 0) || (conn->c_ns_close_jobs == 1));
  1729. if (conn->c_ns_close_jobs) {
  1730. LDAPDebug2Args(LDAP_DEBUG_CONNS, "already a close job in progress on conn %" NSPRIu64 " for fd=%d\n",
  1731. conn->c_connid, conn->c_sd);
  1732. return;
  1733. } else {
  1734. /* just make sure we schedule the event to be closed in a timely manner */
  1735. tv.tv_sec = 0;
  1736. tv.tv_usec = slapd_wakeup_timer * 1000;
  1737. conn->c_ns_close_jobs++; /* now 1 active closure job */
  1738. connection_acquire_nolock_ext(conn, 1 /* allow acquire even when closing */); /* event framework now has a reference */
  1739. ns_add_timeout_job(conn->c_tp, &tv, NS_JOB_TIMER,
  1740. ns_handle_closure, conn, NULL);
  1741. LDAPDebug2Args(LDAP_DEBUG_CONNS, "post closure job for conn %" NSPRIu64 " for fd=%d\n",
  1742. conn->c_connid, conn->c_sd);
  1743. }
  1744. } else {
  1745. /* process event normally - wait for I/O until idletimeout */
  1746. tv.tv_sec = conn->c_idletimeout;
  1747. tv.tv_usec = 0;
  1748. #ifdef DEBUG
  1749. PR_ASSERT(0 == connection_acquire_nolock(conn));
  1750. #else
  1751. if (connection_acquire_nolock(conn) != 0) { /* event framework now has a reference */
  1752. /*
  1753. * This has already been logged as an error in ./ldap/servers/slapd/connection.c
  1754. * The error occurs when we get a connection in a closing state.
  1755. * For now we return, but there is probably a better way to handle the error case.
  1756. */
  1757. return;
  1758. }
  1759. #endif
  1760. ns_add_io_timeout_job(conn->c_tp, conn->c_prfd, &tv,
  1761. NS_JOB_READ|NS_JOB_PRESERVE_FD,
  1762. ns_handle_pr_read_ready, conn, NULL);
  1763. LDAPDebug2Args(LDAP_DEBUG_CONNS, "post I/O job for conn %" NSPRIu64 " for fd=%d\n",
  1764. conn->c_connid, conn->c_sd);
  1765. }
  1766. #endif
  1767. }
  1768. #ifdef ENABLE_NUNC_STANS
  1769. /* This function must be called without the thread flag, in the
  1770. * event loop. This function may free the connection. This can
  1771. * only be done in the event loop thread.
  1772. */
  1773. void
  1774. ns_handle_pr_read_ready(struct ns_job_t *job)
  1775. {
  1776. int maxthreads = config_get_maxthreadsperconn();
  1777. Connection *c = (Connection *)ns_job_get_data(job);
  1778. /* this function must be called from the event loop thread */
  1779. #ifdef DEBUG
  1780. PR_ASSERT(0 == NS_JOB_IS_THREAD(ns_job_get_type(job)));
  1781. #else
  1782. /* This doesn't actually confirm it's in the event loop thread, but it's a start */
  1783. if (NS_JOB_IS_THREAD(ns_job_get_type(job)) != 0) {
  1784. LDAPDebug2Args(LDAP_DEBUG_ANY, "ns_handle_pr_read_ready: Attempt to handle read ready outside of event loop thread %" NSPRIu64 " for fd=%d\n",
  1785. c->c_connid, c->c_sd);
  1786. return;
  1787. }
  1788. #endif
  1789. PR_EnterMonitor(c->c_mutex);
  1790. LDAPDebug2Args(LDAP_DEBUG_CONNS, "activity on conn %" NSPRIu64 " for fd=%d\n",
  1791. c->c_connid, c->c_sd);
  1792. /* if we were called due to some i/o event, see what the state of the socket is */
  1793. if (slapi_is_loglevel_set(SLAPI_LOG_CONNS) && !NS_JOB_IS_TIMER(ns_job_get_output_type(job)) && c && c->c_sd) {
  1794. /* check socket state */
  1795. char buf[1];
  1796. ssize_t rc = recv(c->c_sd, buf, sizeof(buf), MSG_PEEK);
  1797. if (!rc) {
  1798. LDAPDebug2Args(LDAP_DEBUG_CONNS, "socket is closed conn %" NSPRIu64 " for fd=%d\n",
  1799. c->c_connid, c->c_sd);
  1800. } else if (rc > 0) {
  1801. LDAPDebug2Args(LDAP_DEBUG_CONNS, "socket read data available for conn %" NSPRIu64 " for fd=%d\n",
  1802. c->c_connid, c->c_sd);
  1803. } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
  1804. LDAPDebug2Args(LDAP_DEBUG_CONNS, "socket has no data available conn %" NSPRIu64 " for fd=%d\n",
  1805. c->c_connid, c->c_sd);
  1806. } else {
  1807. LDAPDebug(LDAP_DEBUG_CONNS, "socket has error [%d] conn %" NSPRIu64 " for fd=%d\n",
  1808. errno, c->c_connid, c->c_sd);
  1809. }
  1810. }
  1811. connection_release_nolock_ext(c, 1); /* release ref acquired when job was added */
  1812. if (CONN_NEEDS_CLOSING(c)) {
  1813. ns_handle_closure_nomutex(c);
  1814. } else if (NS_JOB_IS_TIMER(ns_job_get_output_type(job))) {
  1815. /* idle timeout */
  1816. disconnect_server_nomutex_ext(c, c->c_connid, -1,
  1817. SLAPD_DISCONNECT_IDLE_TIMEOUT, EAGAIN,
  1818. 0 /* do not schedule closure, do it next */);
  1819. ns_handle_closure_nomutex(c);
  1820. } else if ((connection_activity(c, maxthreads)) == -1) {
  1821. /* This might happen as a result of
  1822. * trying to acquire a closing connection
  1823. */
  1824. LDAPDebug2Args(LDAP_DEBUG_ANY, "connection_activity: abandoning conn %" NSPRIu64
  1825. " as fd=%d is already closing\n", c->c_connid, c->c_sd);
  1826. /* The call disconnect_server should do nothing,
  1827. * as the connection c should be already set to CLOSING */
  1828. disconnect_server_nomutex_ext(c, c->c_connid, -1,
  1829. SLAPD_DISCONNECT_POLL, EPIPE,
  1830. 0 /* do not schedule closure, do it next */);
  1831. ns_handle_closure_nomutex(c);
  1832. } else {
  1833. LDAPDebug2Args(LDAP_DEBUG_CONNS, "queued conn %" NSPRIu64 " for fd=%d\n",
  1834. c->c_connid, c->c_sd);
  1835. }
  1836. PR_ExitMonitor(c->c_mutex);
  1837. ns_job_done(job);
  1838. return;
  1839. }
  1840. #endif
  1841. /*
  1842. * wrapper functions required so we can implement ioblock_timeout and
  1843. * avoid blocking forever.
  1844. */
  1845. #define SLAPD_POLLIN 0
  1846. #define SLAPD_POLLOUT 1
  1847. /* Return 1 if the given handle is ready for input or output,
  1848. * or if it becomes ready within g_ioblock_timeout [msec].
  1849. * Return -1 if handle is not ready and g_ioblock_timeout > 0,
  1850. * or something goes seriously wrong. Otherwise, return 0.
  1851. * If -1 is returned, PR_GetError() explains why.
  1852. * Revision: handle changed to void * to allow 64bit support
  1853. */
  1854. static int
  1855. slapd_poll( void *handle, int output )
  1856. {
  1857. int rc;
  1858. int ioblock_timeout = config_get_ioblocktimeout();
  1859. struct POLL_STRUCT pr_pd;
  1860. PRIntervalTime timeout = PR_MillisecondsToInterval(ioblock_timeout);
  1861. pr_pd.fd = (PRFileDesc *)handle;
  1862. pr_pd.in_flags = output ? PR_POLL_WRITE : PR_POLL_READ;
  1863. pr_pd.out_flags = 0;
  1864. rc = POLL_FN(&pr_pd, 1, timeout);
  1865. if (rc < 0) {
  1866. PRErrorCode prerr = PR_GetError();
  1867. LDAPDebug(LDAP_DEBUG_ANY, "slapd_poll(%d) "
  1868. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1869. handle, prerr, slapd_pr_strerror(prerr));
  1870. if ( prerr == PR_PENDING_INTERRUPT_ERROR ||
  1871. SLAPD_PR_WOULD_BLOCK_ERROR(prerr))
  1872. {
  1873. rc = 0; /* try again */
  1874. }
  1875. } else if (rc == 0 && ioblock_timeout > 0) {
  1876. PRIntn ihandle;
  1877. ihandle = PR_FileDesc2NativeHandle((PRFileDesc *)handle);
  1878. LDAPDebug(LDAP_DEBUG_ANY, "slapd_poll(%d) timed out\n",
  1879. ihandle, 0, 0);
  1880. PR_SetError(PR_IO_TIMEOUT_ERROR, EAGAIN); /* timeout */
  1881. rc = -1;
  1882. }
  1883. return rc;
  1884. }
  1885. /*
  1886. * Revision: handle changed to void * and first
  1887. * argument which used to be integer system fd is now ignored.
  1888. */
  1889. #if defined(USE_OPENLDAP)
  1890. static int
  1891. write_function( int ignore, void *buffer, int count, void *handle )
  1892. #else
  1893. static int
  1894. write_function( int ignore, const void *buffer, int count, struct lextiof_socket_private *handle )
  1895. #endif
  1896. {
  1897. int sentbytes = 0;
  1898. int bytes;
  1899. int fd = PR_FileDesc2NativeHandle((PRFileDesc *)handle);
  1900. if (handle == SLAPD_INVALID_SOCKET) {
  1901. PR_SetError(PR_NOT_SOCKET_ERROR, EBADF);
  1902. } else {
  1903. while (1) {
  1904. if (slapd_poll(handle, SLAPD_POLLOUT) < 0) { /* error */
  1905. break;
  1906. }
  1907. bytes = PR_Write((PRFileDesc *)handle, (char *)buffer + sentbytes,
  1908. count - sentbytes);
  1909. if (bytes > 0) {
  1910. sentbytes += bytes;
  1911. } else if (bytes < 0) {
  1912. PRErrorCode prerr = PR_GetError();
  1913. LDAPDebug(LDAP_DEBUG_CONNS, "PR_Write(%d) "
  1914. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1915. fd, prerr, slapd_pr_strerror( prerr ));
  1916. if ( !SLAPD_PR_WOULD_BLOCK_ERROR(prerr)) {
  1917. if (prerr != PR_CONNECT_RESET_ERROR) {
  1918. /* 'TCP connection reset by peer': no need to log */
  1919. LDAPDebug(LDAP_DEBUG_ANY, "PR_Write(%d) "
  1920. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1921. fd, prerr, slapd_pr_strerror( prerr ));
  1922. }
  1923. if (sentbytes < count) {
  1924. LDAPDebug(LDAP_DEBUG_CONNS,
  1925. "PR_Write(%d) - wrote only %d bytes (expected %d bytes) - 0 (EOF)\n", /* disconnected */
  1926. fd, sentbytes, count);
  1927. }
  1928. break; /* fatal error */
  1929. }
  1930. } else if (bytes == 0) { /* disconnect */
  1931. PRErrorCode prerr = PR_GetError();
  1932. LDAPDebug(LDAP_DEBUG_CONNS,
  1933. "PR_Write(%d) - 0 (EOF) %d:%s\n", /* disconnected */
  1934. fd, prerr, slapd_pr_strerror(prerr));
  1935. PR_SetError(PR_PIPE_ERROR, EPIPE);
  1936. break;
  1937. }
  1938. if (sentbytes == count) { /* success */
  1939. return count;
  1940. } else if (sentbytes > count) { /* too many bytes */
  1941. LDAPDebug(LDAP_DEBUG_ANY,
  1942. "PR_Write(%d) overflow - sent %d bytes (expected %d bytes) - error\n",
  1943. fd, sentbytes, count);
  1944. PR_SetError(PR_BUFFER_OVERFLOW_ERROR, EMSGSIZE);
  1945. break;
  1946. }
  1947. }
  1948. }
  1949. return -1;
  1950. }
  1951. #if defined(USE_OPENLDAP)
  1952. /* The argument is a pointer to the socket descriptor */
  1953. static int
  1954. openldap_io_setup(Sockbuf_IO_Desc *sbiod, void *arg)
  1955. {
  1956. PR_ASSERT(sbiod);
  1957. if (arg != NULL) {
  1958. sbiod->sbiod_pvt = arg;
  1959. }
  1960. return 0;
  1961. }
  1962. static ber_slen_t
  1963. openldap_write_function(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
  1964. {
  1965. Connection *conn = NULL;
  1966. PRFileDesc *fd = NULL;
  1967. PR_ASSERT(sbiod);
  1968. PR_ASSERT(sbiod->sbiod_pvt);
  1969. conn = (Connection *)sbiod->sbiod_pvt;
  1970. PR_ASSERT(conn->c_prfd);
  1971. fd = (PRFileDesc *)conn->c_prfd;
  1972. PR_ASSERT(fd != SLAPD_INVALID_SOCKET);
  1973. return write_function(0, buf, len, fd);
  1974. }
  1975. static int
  1976. openldap_io_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
  1977. {
  1978. PR_ASSERT(0); /* not sure if this is needed */
  1979. return -1;
  1980. }
  1981. static int
  1982. openldap_io_close(Sockbuf_IO_Desc *sbiod)
  1983. {
  1984. return 0; /* closing done in connection_cleanup() */
  1985. }
  1986. static Sockbuf_IO openldap_sockbuf_io = {
  1987. openldap_io_setup, /* sbi_setup */
  1988. NULL, /* sbi_remove */
  1989. openldap_io_ctrl, /* sbi_ctrl */
  1990. openldap_read_function, /* sbi_read */ /* see connection.c */
  1991. openldap_write_function, /* sbi_write */
  1992. openldap_io_close /* sbi_close */
  1993. };
  1994. #endif /* USE_OPENLDAP */
  1995. int connection_type = -1; /* The type number assigned by the Factory for 'Connection' */
  1996. void
  1997. daemon_register_connection()
  1998. {
  1999. if(connection_type==-1)
  2000. {
  2001. /* The factory is given the name of the object type, in
  2002. * return for a type handle. Whenever the object is created
  2003. * or destroyed the factory is called with the handle so
  2004. * that it may call the constructors or destructors registered
  2005. * with it.
  2006. */
  2007. connection_type= factory_register_type(SLAPI_EXT_CONNECTION,offsetof(Connection,c_extension));
  2008. }
  2009. }
  2010. #if defined(ENABLE_LDAPI)
  2011. int
  2012. slapd_identify_local_user(Connection *conn)
  2013. {
  2014. int ret = -1;
  2015. uid_t uid = 0;
  2016. gid_t gid = 0;
  2017. conn->c_local_valid = 0;
  2018. if(0 == slapd_get_socket_peer(conn->c_prfd, &uid, &gid))
  2019. {
  2020. conn->c_local_uid = uid;
  2021. conn->c_local_gid = gid;
  2022. conn->c_local_valid = 1;
  2023. ret = 0;
  2024. }
  2025. return ret;
  2026. }
  2027. #if defined(ENABLE_AUTOBIND)
  2028. int
  2029. slapd_bind_local_user(Connection *conn)
  2030. {
  2031. int ret = -1;
  2032. uid_t uid = conn->c_local_uid;
  2033. gid_t gid = conn->c_local_gid;
  2034. if (!conn->c_local_valid)
  2035. {
  2036. goto bail;
  2037. }
  2038. /* observe configuration for auto binding */
  2039. /* bind at all? */
  2040. if(config_get_ldapi_bind_switch())
  2041. {
  2042. /* map users to a dn
  2043. root may also map to an entry
  2044. */
  2045. /* require real entry? */
  2046. if(config_get_ldapi_map_entries())
  2047. {
  2048. /* get uid type to map to (e.g. uidNumber) */
  2049. char *utype = config_get_ldapi_uidnumber_type();
  2050. /* get gid type to map to (e.g. gidNumber) */
  2051. char *gtype = config_get_ldapi_gidnumber_type();
  2052. /* get base dn for search */
  2053. char *base_dn = config_get_ldapi_search_base_dn();
  2054. /* search vars */
  2055. Slapi_PBlock *search_pb = 0;
  2056. Slapi_Entry **entries = 0;
  2057. int result;
  2058. /* filter manipulation vars */
  2059. char *one_type = 0;
  2060. char *filter_tpl = 0;
  2061. char *filter = 0;
  2062. /* create filter, matching whatever is given */
  2063. if(utype && gtype)
  2064. {
  2065. filter_tpl = "(&(%s=%u)(%s=%u))";
  2066. }
  2067. else
  2068. {
  2069. if(utype || gtype)
  2070. {
  2071. filter_tpl = "(%s=%u)";
  2072. if(utype)
  2073. one_type = utype;
  2074. else
  2075. one_type = gtype;
  2076. }
  2077. else
  2078. {
  2079. goto entry_map_free;
  2080. }
  2081. }
  2082. if(one_type)
  2083. {
  2084. if(one_type == utype)
  2085. filter = slapi_ch_smprintf(filter_tpl,
  2086. utype, uid);
  2087. else
  2088. filter = slapi_ch_smprintf(filter_tpl,
  2089. gtype, gid);
  2090. }
  2091. else
  2092. {
  2093. filter = slapi_ch_smprintf(filter_tpl,
  2094. utype, uid, gtype, gid);
  2095. }
  2096. /* search for single entry matching types */
  2097. search_pb = slapi_pblock_new();
  2098. slapi_search_internal_set_pb(
  2099. search_pb,
  2100. base_dn,
  2101. LDAP_SCOPE_SUBTREE,
  2102. filter,
  2103. NULL, 0, NULL, NULL,
  2104. (void*)plugin_get_default_component_id(),
  2105. 0);
  2106. slapi_search_internal_pb(search_pb);
  2107. slapi_pblock_get(
  2108. search_pb,
  2109. SLAPI_PLUGIN_INTOP_RESULT,
  2110. &result);
  2111. if(LDAP_SUCCESS == result)
  2112. slapi_pblock_get(
  2113. search_pb,
  2114. SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
  2115. &entries);
  2116. if(entries)
  2117. {
  2118. /* zero or multiple entries fail */
  2119. if(entries[0] && 0 == entries[1])
  2120. {
  2121. /* observe account locking */
  2122. ret = slapi_check_account_lock(
  2123. 0, /* pb not req */
  2124. entries[0],
  2125. 0, /* no response control */
  2126. 0, /* don't check password policy */
  2127. 0 /* don't send ldap result */
  2128. );
  2129. if(0 == ret)
  2130. {
  2131. char *auth_dn = slapi_ch_strdup(
  2132. slapi_entry_get_ndn(
  2133. entries[0]));
  2134. auth_dn = slapi_dn_normalize(
  2135. auth_dn);
  2136. bind_credentials_set_nolock(
  2137. conn,
  2138. SLAPD_AUTH_OS,
  2139. auth_dn,
  2140. NULL, NULL,
  2141. NULL , entries[0]);
  2142. ret = 0;
  2143. }
  2144. }
  2145. }
  2146. entry_map_free:
  2147. /* auth_dn consumed by bind creds set */
  2148. slapi_free_search_results_internal(search_pb);
  2149. slapi_pblock_destroy(search_pb);
  2150. slapi_ch_free_string(&filter);
  2151. slapi_ch_free_string(&utype);
  2152. slapi_ch_free_string(&gtype);
  2153. slapi_ch_free_string(&base_dn);
  2154. }
  2155. if(ret && 0 == uid)
  2156. {
  2157. /* map unix root (uidNumber:0)? */
  2158. char *root_dn = config_get_ldapi_root_dn();
  2159. if(root_dn)
  2160. {
  2161. Slapi_DN *edn = slapi_sdn_new_dn_byref(
  2162. slapi_dn_normalize(root_dn));
  2163. Slapi_Entry *e = 0;
  2164. /* root might be locked too! :) */
  2165. ret = slapi_search_internal_get_entry(
  2166. edn, 0,
  2167. &e,
  2168. (void*)plugin_get_default_component_id()
  2169. );
  2170. if(0 == ret && e)
  2171. {
  2172. ret = slapi_check_account_lock(
  2173. 0, /* pb not req */
  2174. e,
  2175. 0, /* no response control */
  2176. 0, /* don't check password policy */
  2177. 0 /* don't send ldap result */
  2178. );
  2179. if(1 == ret)
  2180. /* sorry root,
  2181. * just not cool enough
  2182. */
  2183. goto root_map_free;
  2184. }
  2185. /* it's ok not to find the entry,
  2186. * dn doesn't have to have an entry
  2187. * e.g. cn=Directory Manager
  2188. */
  2189. bind_credentials_set_nolock(
  2190. conn, SLAPD_AUTH_OS, root_dn,
  2191. NULL, NULL, NULL , e);
  2192. root_map_free:
  2193. /* root_dn consumed by bind creds set */
  2194. slapi_sdn_free(&edn);
  2195. slapi_entry_free(e);
  2196. ret = 0;
  2197. }
  2198. }
  2199. #if defined(ENABLE_AUTO_DN_SUFFIX)
  2200. if(ret)
  2201. {
  2202. /* create phony auth dn? */
  2203. char *base = config_get_ldapi_auto_dn_suffix();
  2204. if(base)
  2205. {
  2206. char *tpl = "gidNumber=%u+uidNumber=%u,";
  2207. int len =
  2208. strlen(tpl) +
  2209. strlen(base) +
  2210. 51 /* uid,gid,null,w/padding */
  2211. ;
  2212. char *dn_str = (char*)slapi_ch_malloc(
  2213. len);
  2214. char *auth_dn = (char*)slapi_ch_malloc(
  2215. len);
  2216. dn_str[0] = 0;
  2217. strcpy(dn_str, tpl);
  2218. strcat(dn_str, base);
  2219. sprintf(auth_dn, dn_str, gid, uid);
  2220. auth_dn = slapi_dn_normalize(auth_dn);
  2221. bind_credentials_set_nolock(
  2222. conn,
  2223. SLAPD_AUTH_OS,
  2224. auth_dn,
  2225. NULL, NULL, NULL , NULL);
  2226. /* auth_dn consumed by bind creds set */
  2227. slapi_ch_free_string(&dn_str);
  2228. slapi_ch_free_string(&base);
  2229. ret = 0;
  2230. }
  2231. }
  2232. #endif
  2233. }
  2234. bail:
  2235. /* if all fails, the peer is anonymous */
  2236. if(conn->c_dn)
  2237. {
  2238. /* log the auto bind */
  2239. slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " AUTOBIND dn=\"%s\"\n", conn->c_connid, conn->c_dn);
  2240. }
  2241. return ret;
  2242. }
  2243. #endif /* ENABLE_AUTOBIND */
  2244. #endif /* ENABLE_LDAPI */
  2245. void
  2246. handle_closed_connection(Connection *conn)
  2247. {
  2248. #ifdef USE_OPENLDAP
  2249. ber_sockbuf_remove_io(conn->c_sb, &openldap_sockbuf_io, LBER_SBIOD_LEVEL_PROVIDER);
  2250. #endif
  2251. }
  2252. /* NOTE: this routine is not reentrant */
  2253. static int
  2254. handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, int secure, int local, Connection **newconn)
  2255. {
  2256. int ns = 0;
  2257. Connection *conn = NULL;
  2258. /* struct sockaddr_in from;*/
  2259. PRNetAddr from;
  2260. PRFileDesc *pr_clonefd = NULL;
  2261. ber_len_t maxbersize;
  2262. slapdFrontendConfig_t *fecfg = getFrontendConfig();
  2263. if (newconn) {
  2264. *newconn = NULL;
  2265. }
  2266. memset(&from, 0, sizeof(from)); /* reset to nulls so we can see what was set */
  2267. if ( (ns = accept_and_configure( tcps, pr_acceptfd, &from,
  2268. sizeof(from), secure, local, &pr_clonefd)) == SLAPD_INVALID_SOCKET ) {
  2269. return -1;
  2270. }
  2271. /* get a new Connection from the Connection Table */
  2272. conn= connection_table_get_connection(ct,ns);
  2273. if(conn==NULL)
  2274. {
  2275. PR_Close(pr_acceptfd);
  2276. return -1;
  2277. }
  2278. PR_EnterMonitor(conn->c_mutex);
  2279. /*
  2280. * Set the default idletimeout and the handle. We'll update c_idletimeout
  2281. * after each bind so we can correctly set the resource limit.
  2282. */
  2283. conn->c_idletimeout = fecfg->idletimeout;
  2284. conn->c_idletimeout_handle = idletimeout_reslimit_handle;
  2285. conn->c_sd = ns;
  2286. conn->c_prfd = pr_clonefd;
  2287. conn->c_flags &= ~CONN_FLAG_CLOSING;
  2288. /* Store the fact that this new connection is an SSL connection */
  2289. if (secure) {
  2290. conn->c_flags |= CONN_FLAG_SSL;
  2291. }
  2292. /*
  2293. * clear the "returned events" field in ns' slot within the poll fds
  2294. * array so that handle_read_ready() doesn't look at out_flags for an
  2295. * old connection by mistake and do something bad such as close the
  2296. * connection we just accepted.
  2297. */
  2298. /* Dont have to worry about this now because of our mapping from
  2299. * the connection table to the fds array. This new connection
  2300. * won't have a mapping. */
  2301. /* fds[ns].out_flags = 0; */
  2302. #if defined(USE_OPENLDAP)
  2303. ber_sockbuf_add_io( conn->c_sb, &openldap_sockbuf_io,
  2304. LBER_SBIOD_LEVEL_PROVIDER, conn );
  2305. #else /* !USE_OPENLDAP */
  2306. {
  2307. struct lber_x_ext_io_fns func_pointers;
  2308. memset(&func_pointers, 0, sizeof(func_pointers));
  2309. func_pointers.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
  2310. func_pointers.lbextiofn_read = NULL; /* see connection_read_function */
  2311. func_pointers.lbextiofn_write = write_function;
  2312. func_pointers.lbextiofn_writev = NULL;
  2313. func_pointers.lbextiofn_socket_arg = (struct lextiof_socket_private *) pr_clonefd;
  2314. ber_sockbuf_set_option(conn->c_sb,
  2315. LBER_SOCKBUF_OPT_EXT_IO_FNS, &func_pointers);
  2316. }
  2317. #endif /* !USE_OPENLDAP */
  2318. maxbersize = config_get_maxbersize();
  2319. #if defined(USE_OPENLDAP)
  2320. ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &maxbersize );
  2321. #endif
  2322. if( secure && config_get_SSLclientAuth() != SLAPD_SSLCLIENTAUTH_OFF ) {
  2323. /* Prepare to handle the client's certificate (if any): */
  2324. int rv;
  2325. rv = slapd_ssl_handshakeCallback (conn->c_prfd, (void*)handle_handshake_done, conn);
  2326. if (rv < 0) {
  2327. PRErrorCode prerr = PR_GetError();
  2328. LDAPDebug (LDAP_DEBUG_ANY, "SSL_HandshakeCallback() %d "
  2329. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  2330. rv, prerr, slapd_pr_strerror( prerr ));
  2331. }
  2332. rv = slapd_ssl_badCertHook (conn->c_prfd, (void*)handle_bad_certificate, conn);
  2333. if (rv < 0) {
  2334. PRErrorCode prerr = PR_GetError();
  2335. LDAPDebug (LDAP_DEBUG_ANY, "SSL_BadCertHook(%i) %i "
  2336. SLAPI_COMPONENT_NAME_NSPR " error %d\n",
  2337. conn->c_sd, rv, prerr);
  2338. }
  2339. }
  2340. connection_reset(conn, ns, &from, sizeof(from), secure);
  2341. /* Call the plugin extension constructors */
  2342. conn->c_extension = factory_create_extension(connection_type,conn,NULL /* Parent */);
  2343. #if defined(ENABLE_LDAPI)
  2344. /* ldapi */
  2345. if( local )
  2346. {
  2347. conn->c_unix_local = 1;
  2348. conn->c_local_ssf = config_get_localssf();
  2349. slapd_identify_local_user(conn);
  2350. }
  2351. #endif /* ENABLE_LDAPI */
  2352. connection_new_private(conn);
  2353. /* Add this connection slot to the doubly linked list of active connections. This
  2354. * list is used to find the connections that should be used in the poll call. This
  2355. * connection will be added directly after slot 0 which serves as the head of the list.
  2356. * This must be done as the very last thing before we unlock the mutex, because once it
  2357. * is added to the active list, it is live. */
  2358. if ( conn != NULL && conn->c_next == NULL && conn->c_prev == NULL )
  2359. {
  2360. /* Now give the new connection to the connection code */
  2361. connection_table_move_connection_on_to_active_list(the_connection_table,conn);
  2362. }
  2363. PR_ExitMonitor(conn->c_mutex);
  2364. g_increment_current_conn_count();
  2365. if (newconn) {
  2366. *newconn = conn;
  2367. }
  2368. return 0;
  2369. }
  2370. #ifdef ENABLE_NUNC_STANS
  2371. static void
  2372. ns_handle_new_connection(struct ns_job_t *job)
  2373. {
  2374. int rc;
  2375. Connection *c = NULL;
  2376. listener_info *li = (listener_info *)ns_job_get_data(job);
  2377. /* only accept new connections if we have enough fds, more than
  2378. * the number of reserved descriptors
  2379. */
  2380. if ((li->ct->size - g_get_current_conn_count())
  2381. <= config_get_reservedescriptors()) {
  2382. /* too many open fds - shut off this listener - when an fd is
  2383. * closed, try to resume this listener
  2384. */
  2385. ns_disable_listener(li);
  2386. return;
  2387. }
  2388. rc = handle_new_connection(li->ct, SLAPD_INVALID_SOCKET, li->listenfd, li->secure, li->local, &c);
  2389. if (rc) {
  2390. PRErrorCode prerr = PR_GetError();
  2391. if (PR_PROC_DESC_TABLE_FULL_ERROR == prerr) {
  2392. /* too many open fds - shut off this listener - when an fd is
  2393. * closed, try to resume this listener
  2394. */
  2395. ns_disable_listener(li);
  2396. } else {
  2397. LDAPDebug(LDAP_DEBUG_CONNS, "Error accepting new connection listenfd=%d [%d:%s]\n",
  2398. PR_FileDesc2NativeHandle(li->listenfd), prerr,
  2399. slapd_pr_strerror(prerr));
  2400. }
  2401. return;
  2402. }
  2403. c->c_tp = ns_job_get_tp(job);
  2404. /* This originally just called ns_handle_pr_read_ready directly - however, there
  2405. * are certain cases where accept() will return a file descriptor that is not
  2406. * immediately available for reading - this would cause the poll() in
  2407. * connection_read_operation() to be hit - it seemed to perform better when
  2408. * that poll() was avoided, even at the expense of putting this new fd back
  2409. * in nunc-stans to poll for read ready.
  2410. */
  2411. ns_connection_post_io_or_closing(c);
  2412. return;
  2413. }
  2414. #endif
  2415. static int init_shutdown_detect()
  2416. {
  2417. /* First of all, we must reset the signal mask to get rid of any blockages
  2418. * the process may have inherited from its parent (such as the console), which
  2419. * might result in the process not delivering those blocked signals, and thus,
  2420. * misbehaving....
  2421. */
  2422. {
  2423. int rc;
  2424. sigset_t proc_mask;
  2425. LDAPDebug( LDAP_DEBUG_TRACE, "Reseting signal mask....\n", 0, 0, 0);
  2426. (void)sigemptyset( &proc_mask );
  2427. rc = pthread_sigmask( SIG_SETMASK, &proc_mask, NULL );
  2428. LDAPDebug( LDAP_DEBUG_TRACE, " %s \n",
  2429. rc ? "Failed to reset signal mask":"....Done (signal mask reset)!!", 0, 0 );
  2430. }
  2431. #if defined ( HPUX10 )
  2432. PR_CreateThread ( PR_USER_THREAD,
  2433. catch_signals,
  2434. NULL,
  2435. PR_PRIORITY_NORMAL,
  2436. PR_GLOBAL_THREAD,
  2437. PR_UNJOINABLE_THREAD,
  2438. SLAPD_DEFAULT_THREAD_STACKSIZE);
  2439. #else
  2440. #ifdef HPUX11
  2441. /* In the optimized builds for HPUX, the signal handler doesn't seem
  2442. * to get set correctly unless the primordial thread gets a chance
  2443. * to run before we make the call to SIGNAL. (At this point the
  2444. * the primordial thread has spawned the daemon thread which called
  2445. * this function.) The call to DS_Sleep will give the primordial
  2446. * thread a chance to run.
  2447. */
  2448. DS_Sleep(0);
  2449. #endif
  2450. (void) SIGNAL( SIGPIPE, SIG_IGN );
  2451. (void) SIGNAL( SIGCHLD, slapd_wait4child );
  2452. #ifndef LINUX
  2453. /* linux uses USR1/USR2 for thread synchronization, so we aren't
  2454. * allowed to mess with those.
  2455. */
  2456. (void) SIGNAL( SIGUSR1, slapd_do_nothing );
  2457. (void) SIGNAL( SIGUSR2, set_shutdown );
  2458. #endif
  2459. if (!enable_nunc_stans) {
  2460. (void) SIGNAL( SIGTERM, set_shutdown );
  2461. (void) SIGNAL( SIGHUP, set_shutdown );
  2462. }
  2463. #endif /* HPUX */
  2464. return 0;
  2465. }
  2466. static void
  2467. unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, PRFileDesc **n_tcps, PRFileDesc **s_tcps, PRFileDesc **i_unix)
  2468. {
  2469. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  2470. char addrbuf[ 256 ];
  2471. int isfirsttime = 1;
  2472. if ( ct->size <= slapdFrontendConfig->reservedescriptors ) {
  2473. LDAPDebug( LDAP_DEBUG_ANY,
  2474. "ERROR: Not enough descriptors to accept any connections. "
  2475. "This may be because the maxdescriptors configuration "
  2476. "directive is too small, the hard limit on descriptors is "
  2477. "too small (see limit(1)), or the reservedescriptors "
  2478. "configuration directive is too large. "
  2479. "Try increasing the number of descriptors available to "
  2480. "the slapd process. The current value is %d. %d "
  2481. "descriptors are currently reserved for internal "
  2482. "slapd use, so the total number of descriptors available "
  2483. "to the process must be greater than %d.\n",
  2484. ct->size, slapdFrontendConfig->reservedescriptors, slapdFrontendConfig->reservedescriptors );
  2485. exit( 1 );
  2486. }
  2487. /*
  2488. * This final startup message gives a definite signal to the admin
  2489. * program that the server is up. It must contain the string
  2490. * "slapd started." because some of the administrative programs
  2491. * depend on this. See ldap/admin/lib/dsalib_updown.c.
  2492. */
  2493. if ( n_tcps != NULL ) { /* standard LDAP */
  2494. PRNetAddr **nap = NULL;
  2495. for (nap = ports->n_listenaddr; nap && *nap; nap++) {
  2496. if (isfirsttime) {
  2497. LDAPDebug( LDAP_DEBUG_ANY,
  2498. "slapd started. Listening on %s port %d for LDAP requests\n",
  2499. netaddr2string(*nap, addrbuf, sizeof(addrbuf)),
  2500. ports->n_port, 0 );
  2501. isfirsttime = 0;
  2502. } else {
  2503. LDAPDebug( LDAP_DEBUG_ANY,
  2504. "Listening on %s port %d for LDAP requests\n",
  2505. netaddr2string(*nap, addrbuf, sizeof(addrbuf)),
  2506. ports->n_port, 0 );
  2507. }
  2508. }
  2509. }
  2510. if ( s_tcps != NULL ) { /* LDAP over SSL; separate port */
  2511. PRNetAddr **sap = NULL;
  2512. for (sap = ports->s_listenaddr; sap && *sap; sap++) {
  2513. if (isfirsttime) {
  2514. LDAPDebug( LDAP_DEBUG_ANY,
  2515. "slapd started. Listening on %s port %d for LDAPS requests\n",
  2516. netaddr2string(*sap, addrbuf, sizeof(addrbuf)),
  2517. ports->s_port, 0 );
  2518. isfirsttime = 0;
  2519. } else {
  2520. LDAPDebug( LDAP_DEBUG_ANY,
  2521. "Listening on %s port %d for LDAPS requests\n",
  2522. netaddr2string(*sap, addrbuf, sizeof(addrbuf)),
  2523. ports->s_port, 0 );
  2524. }
  2525. }
  2526. }
  2527. #if defined(ENABLE_LDAPI)
  2528. if ( i_unix != NULL ) { /* LDAPI */
  2529. PRNetAddr **iap = ports->i_listenaddr;
  2530. LDAPDebug( LDAP_DEBUG_ANY,
  2531. "%sListening on %s for LDAPI requests\n", isfirsttime?"slapd started. ":"",
  2532. (*iap)->local.path, 0 );
  2533. }
  2534. #endif /* ENABLE_LDAPI */
  2535. }
  2536. /* On UNIX, we create a file with our PID in it */
  2537. static int
  2538. write_pid_file()
  2539. {
  2540. FILE *fp = NULL;
  2541. /*
  2542. * The following section of code is closely coupled with the
  2543. * admin programs. Please do not make changes here without
  2544. * consulting the start/stop code for the admin code.
  2545. */
  2546. if ( (fp = fopen( get_pid_file(), "w" )) != NULL ) {
  2547. fprintf( fp, "%d\n", getpid() );
  2548. fclose( fp );
  2549. if ( chmod(get_pid_file(), S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) != 0 ) {
  2550. unlink(get_pid_file());
  2551. } else {
  2552. return 0;
  2553. }
  2554. }
  2555. return -1;
  2556. }
  2557. static void
  2558. set_shutdown (int sig)
  2559. {
  2560. /* don't log anything from a signal handler:
  2561. * you could be holding a lock when the signal was trapped. more
  2562. * specifically, you could be holding the logfile lock (and deadlock
  2563. * yourself).
  2564. */
  2565. #if 0
  2566. LDAPDebug( LDAP_DEBUG_ANY, "slapd got shutdown signal\n", 0, 0, 0 );
  2567. #endif
  2568. g_set_shutdown( SLAPI_SHUTDOWN_SIGNAL );
  2569. #ifndef LINUX
  2570. /* don't mess with USR1/USR2 on linux, used by libpthread */
  2571. (void) SIGNAL( SIGUSR2, set_shutdown );
  2572. #endif
  2573. (void) SIGNAL( SIGTERM, set_shutdown );
  2574. (void) SIGNAL( SIGHUP, set_shutdown );
  2575. }
  2576. #ifdef ENABLE_NUNC_STANS
  2577. static void
  2578. ns_set_shutdown(struct ns_job_t *job)
  2579. {
  2580. int i;
  2581. set_shutdown(0);
  2582. /* Stop all the long running jobs */
  2583. for (i = 0; i < listeners; ++i) {
  2584. ns_job_done(listener_idxs[i].ns_job);
  2585. listener_idxs[i].ns_job = NULL;
  2586. }
  2587. /* Signal all the worker threads to stop */
  2588. ns_thrpool_shutdown(ns_job_get_tp(job));
  2589. /* Free all the signal jobs */
  2590. ns_job_done(ns_signal_job[0]);
  2591. ns_job_done(ns_signal_job[1]);
  2592. ns_job_done(ns_signal_job[2]);
  2593. }
  2594. #endif
  2595. #ifndef LINUX
  2596. void
  2597. slapd_do_nothing (int sig)
  2598. {
  2599. /* don't log anything from a signal handler:
  2600. * you could be holding a lock when the signal was trapped. more
  2601. * specifically, you could be holding the logfile lock (and deadlock
  2602. * yourself).
  2603. */
  2604. #if 0
  2605. LDAPDebug( LDAP_DEBUG_TRACE, "slapd got SIGUSR1\n", 0, 0, 0 );
  2606. #endif
  2607. (void) SIGNAL( SIGUSR1, slapd_do_nothing );
  2608. #if 0
  2609. /*
  2610. * Actually do a little more: dump the conn struct and
  2611. * send it to a tmp file
  2612. */
  2613. connection_table_dump(connection_table);
  2614. #endif
  2615. }
  2616. #endif /* LINUX */
  2617. void
  2618. slapd_wait4child(int sig)
  2619. {
  2620. WAITSTATUSTYPE status;
  2621. /* don't log anything from a signal handler:
  2622. * you could be holding a lock when the signal was trapped. more
  2623. * specifically, you could be holding the logfile lock (and deadlock
  2624. * yourself).
  2625. */
  2626. #if 0
  2627. LDAPDebug( LDAP_DEBUG_ARGS, "listener: catching SIGCHLD\n", 0, 0, 0 );
  2628. #endif
  2629. #ifdef USE_WAITPID
  2630. while (waitpid ((pid_t) -1, 0, WAIT_FLAGS) > 0)
  2631. #else /* USE_WAITPID */
  2632. while ( wait3( &status, WAIT_FLAGS, 0 ) > 0 )
  2633. #endif /* USE_WAITPID */
  2634. ; /* NULL */
  2635. (void) SIGNAL( SIGCHLD, slapd_wait4child );
  2636. }
  2637. static PRFileDesc **
  2638. createprlistensockets(PRUint16 port, PRNetAddr **listenaddr,
  2639. int secure, int local)
  2640. {
  2641. PRFileDesc **sock;
  2642. PRNetAddr sa_server;
  2643. PRErrorCode prerr = 0;
  2644. PRSocketOptionData pr_socketoption;
  2645. char addrbuf[ 256 ];
  2646. char *logname = "createprlistensockets";
  2647. int sockcnt = 0;
  2648. int socktype;
  2649. char *socktype_str = NULL;
  2650. PRNetAddr **lap;
  2651. int i;
  2652. if (!port) goto suppressed;
  2653. PR_ASSERT( listenaddr != NULL );
  2654. /* need to know the count */
  2655. sockcnt = 0;
  2656. for (lap = listenaddr; lap && *lap; lap++) {
  2657. sockcnt++;
  2658. }
  2659. if (0 == sockcnt) {
  2660. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2661. "There is no address to listen\n");
  2662. goto failed;
  2663. }
  2664. sock = (PRFileDesc **)slapi_ch_calloc(sockcnt + 1, sizeof(PRFileDesc *));
  2665. pr_socketoption.option = PR_SockOpt_Reuseaddr;
  2666. pr_socketoption.value.reuse_addr = 1;
  2667. for (i = 0, lap = listenaddr; lap && *lap && i < sockcnt; i++, lap++) {
  2668. /* create TCP socket */
  2669. socktype = PR_NetAddrFamily(*lap);
  2670. #if defined(ENABLE_LDAPI)
  2671. if (PR_AF_LOCAL == socktype) {
  2672. socktype_str = "PR_AF_LOCAL";
  2673. } else
  2674. #endif
  2675. if (PR_AF_INET6 == socktype) {
  2676. socktype_str = "PR_AF_INET6";
  2677. } else {
  2678. socktype_str = "PR_AF_INET";
  2679. }
  2680. if ((sock[i] = PR_OpenTCPSocket(socktype)) == SLAPD_INVALID_SOCKET) {
  2681. prerr = PR_GetError();
  2682. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2683. "PR_OpenTCPSocket(%s) failed: %s error %d (%s)\n",
  2684. socktype_str,
  2685. SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
  2686. goto failed;
  2687. }
  2688. if ( PR_SetSocketOption(sock[i], &pr_socketoption ) == PR_FAILURE) {
  2689. prerr = PR_GetError();
  2690. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2691. "PR_SetSocketOption(PR_SockOpt_Reuseaddr) failed: %s error %d (%s)\n",
  2692. SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror( prerr ));
  2693. goto failed;
  2694. }
  2695. /* set up listener address, including port */
  2696. memcpy(&sa_server, *lap, sizeof(sa_server));
  2697. if(!local)
  2698. PRLDAP_SET_PORT( &sa_server, port );
  2699. if ( PR_Bind(sock[i], &sa_server) == PR_FAILURE) {
  2700. prerr = PR_GetError();
  2701. if(!local)
  2702. {
  2703. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2704. "PR_Bind() on %s port %d failed: %s error %d (%s)\n",
  2705. netaddr2string(&sa_server, addrbuf, sizeof(addrbuf)), port,
  2706. SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
  2707. }
  2708. #if defined(ENABLE_LDAPI)
  2709. else
  2710. {
  2711. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2712. "PR_Bind() on %s file %s failed: %s error %d (%s)\n",
  2713. netaddr2string(&sa_server, addrbuf, sizeof(addrbuf)),
  2714. sa_server.local.path,
  2715. SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
  2716. }
  2717. #endif /* ENABLE_LDAPI */
  2718. goto failed;
  2719. }
  2720. }
  2721. #if defined(ENABLE_LDAPI)
  2722. if(local) { /* ldapi */
  2723. if(chmod((*listenaddr)->local.path,
  2724. S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH))
  2725. {
  2726. slapi_log_error(SLAPI_LOG_FATAL, logname, "err: %d", errno);
  2727. }
  2728. }
  2729. #endif /* ENABLE_LDAPI */
  2730. return( sock );
  2731. failed:
  2732. exit( 1 );
  2733. suppressed:
  2734. return (PRFileDesc **)-1;
  2735. } /* createprlistensockets */
  2736. /*
  2737. * Initialize the *addr structure based on listenhost.
  2738. * Returns: 0 if successful and -1 if not (after logging an error message).
  2739. */
  2740. int
  2741. slapd_listenhost2addr(const char *listenhost, PRNetAddr ***addr)
  2742. {
  2743. char *logname = "slapd_listenhost2addr";
  2744. PRErrorCode prerr = 0;
  2745. int rval = 0;
  2746. PRNetAddr *netaddr = (PRNetAddr *)slapi_ch_calloc(1, sizeof(PRNetAddr));
  2747. PR_ASSERT( addr != NULL );
  2748. *addr = NULL;
  2749. if (NULL == listenhost) {
  2750. /* listen on all interfaces */
  2751. if ( PR_SUCCESS != PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, netaddr)) {
  2752. prerr = PR_GetError();
  2753. slapi_log_error( SLAPI_LOG_FATAL, logname,
  2754. "PR_SetNetAddr(PR_IpAddrAny) failed - %s error %d (%s)\n",
  2755. SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
  2756. rval = -1;
  2757. slapi_ch_free ((void**)&netaddr);
  2758. }
  2759. *addr = (PRNetAddr **)slapi_ch_calloc(2, sizeof (PRNetAddr *));
  2760. (*addr)[0] = netaddr;
  2761. } else if (PR_SUCCESS == PR_StringToNetAddr(listenhost, netaddr)) {
  2762. /* PR_StringNetAddr newer than NSPR v4.6.2 supports both IPv4&v6 */;
  2763. *addr = (PRNetAddr **)slapi_ch_calloc(2, sizeof (PRNetAddr *));
  2764. (*addr)[0] = netaddr;
  2765. } else {
  2766. PRAddrInfo *infop = PR_GetAddrInfoByName( listenhost,
  2767. PR_AF_UNSPEC, (PR_AI_ADDRCONFIG|PR_AI_NOCANONNAME) );
  2768. if ( NULL != infop ) {
  2769. void *iter = NULL;
  2770. int addrcnt = 0;
  2771. int i = 0;
  2772. memset( netaddr, 0, sizeof( PRNetAddr ));
  2773. /* need to count the address, first */
  2774. while ( (iter = PR_EnumerateAddrInfo( iter, infop, 0, netaddr ))
  2775. != NULL ) {
  2776. addrcnt++;
  2777. }
  2778. if ( 0 == addrcnt ) {
  2779. slapi_log_error( SLAPI_LOG_FATAL, logname,
  2780. "PR_EnumerateAddrInfo for %s failed - %s error %d (%s)\n",
  2781. listenhost, SLAPI_COMPONENT_NAME_NSPR, prerr,
  2782. slapd_pr_strerror(prerr));
  2783. rval = -1;
  2784. } else {
  2785. char **strnetaddrs = NULL;
  2786. *addr = (PRNetAddr **)slapi_ch_calloc(addrcnt + 1, sizeof (PRNetAddr *));
  2787. iter = NULL; /* from the beginning */
  2788. memset( netaddr, 0, sizeof( PRNetAddr ));
  2789. for ( i = 0; i < addrcnt; i++ ) {
  2790. char abuf[256];
  2791. char *abp = abuf;
  2792. iter = PR_EnumerateAddrInfo( iter, infop, 0, netaddr );
  2793. if ( NULL == iter ) {
  2794. break;
  2795. }
  2796. /*
  2797. * Check if the netaddr is duplicated or not.
  2798. * IPv4 mapped IPv6 could be the identical to IPv4 addr.
  2799. */
  2800. netaddr2string(netaddr, abuf, sizeof(abuf));
  2801. if (PR_IsNetAddrType(netaddr, PR_IpAddrV4Mapped)) {
  2802. /* IPv4 mapped IPv6; redundant to IPv4;
  2803. * cut the "::ffff:" part. */
  2804. abp = strrchr(abuf, ':');
  2805. if (abp) {
  2806. abp++;
  2807. } else {
  2808. abp = abuf;
  2809. }
  2810. }
  2811. if (charray_inlist(strnetaddrs, abp)) {
  2812. LDAPDebug2Args(LDAP_DEBUG_ANY,
  2813. "slapd_listenhost2addr: "
  2814. "detected duplicated address %s "
  2815. "[%s]\n", abuf, abp);
  2816. } else {
  2817. LDAPDebug1Arg(LDAP_DEBUG_TRACE,
  2818. "slapd_listenhost2addr: "
  2819. "registering address %s\n", abp);
  2820. slapi_ch_array_add(&strnetaddrs, slapi_ch_strdup(abp));
  2821. (*addr)[i] = netaddr;
  2822. netaddr =
  2823. (PRNetAddr *)slapi_ch_calloc(1, sizeof(PRNetAddr));
  2824. }
  2825. }
  2826. slapi_ch_free((void **)&netaddr); /* not used */
  2827. slapi_ch_array_free(strnetaddrs);
  2828. }
  2829. PR_FreeAddrInfo( infop );
  2830. } else {
  2831. slapi_log_error( SLAPI_LOG_FATAL, logname,
  2832. "PR_GetAddrInfoByName(%s) failed - %s error %d (%s)\n",
  2833. listenhost, SLAPI_COMPONENT_NAME_NSPR, prerr,
  2834. slapd_pr_strerror(prerr));
  2835. rval = -1;
  2836. }
  2837. }
  2838. return rval;
  2839. }
  2840. /*
  2841. * Map addr to a string equivalent and place the result in addrbuf.
  2842. */
  2843. static const char *
  2844. netaddr2string(const PRNetAddr *addr, char *addrbuf, size_t addrbuflen)
  2845. {
  2846. const char *retstr;
  2847. if (NULL == addr || PR_IsNetAddrType(addr, PR_IpAddrAny)) {
  2848. retstr = "All Interfaces";
  2849. } else if (PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
  2850. if ( addr->raw.family == PR_AF_INET6 &&
  2851. !PR_IsNetAddrType(addr, PR_IpAddrV4Mapped)) {
  2852. retstr = "IPv6 Loopback";
  2853. } else {
  2854. retstr = "Loopback";
  2855. }
  2856. } else if (PR_SUCCESS == PR_NetAddrToString( addr, addrbuf, addrbuflen)) {
  2857. if (0 == strncmp( addrbuf, "::ffff:", 7 )) {
  2858. /* IPv4 address mapped into IPv6 address space */
  2859. retstr = addrbuf + 7;
  2860. } else {
  2861. /* full blown IPv6 address */
  2862. retstr = addrbuf;
  2863. }
  2864. } else { /* punt */
  2865. retstr = "address conversion failed";
  2866. }
  2867. return(retstr);
  2868. }
  2869. static int
  2870. createsignalpipe( void )
  2871. {
  2872. if (enable_nunc_stans) {
  2873. return( 0 );
  2874. }
  2875. if ( PR_CreatePipe( &signalpipe[0], &signalpipe[1] ) != 0 ) {
  2876. PRErrorCode prerr = PR_GetError();
  2877. LDAPDebug( LDAP_DEBUG_ANY, "PR_CreatePipe() failed, "
  2878. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  2879. prerr, slapd_pr_strerror(prerr), SLAPD_DEFAULT_THREAD_STACKSIZE );
  2880. return( -1 );
  2881. }
  2882. writesignalpipe = PR_FileDesc2NativeHandle(signalpipe[1]);
  2883. readsignalpipe = PR_FileDesc2NativeHandle(signalpipe[0]);
  2884. if(fcntl(writesignalpipe, F_SETFD, O_NONBLOCK) == -1){
  2885. LDAPDebug( LDAP_DEBUG_ANY,"createsignalpipe: failed to set FD for write pipe (%d).\n",
  2886. errno, 0, 0 );
  2887. }
  2888. if(fcntl(readsignalpipe, F_SETFD, O_NONBLOCK) == -1){
  2889. LDAPDebug( LDAP_DEBUG_ANY,"createsignalpipe: failed to set FD for read pipe (%d).\n",
  2890. errno, 0, 0);
  2891. }
  2892. return( 0 );
  2893. }
  2894. #ifdef HPUX10
  2895. #include <pthread.h> /* for sigwait */
  2896. /*
  2897. * Set up a thread to catch signals
  2898. * SIGUSR1 (ignore), SIGCHLD (call slapd_wait4child),
  2899. * SIGUSR2 (set slapd_shutdown), SIGTERM (set slapd_shutdown),
  2900. * SIGHUP (set slapd_shutdown)
  2901. */
  2902. static void *
  2903. catch_signals()
  2904. {
  2905. sigset_t caught_signals;
  2906. int sig;
  2907. sigemptyset( &caught_signals );
  2908. while ( !g_get_shutdown() ) {
  2909. /* Set the signals we're interested in catching */
  2910. sigaddset( &caught_signals, SIGUSR1 );
  2911. sigaddset( &caught_signals, SIGCHLD );
  2912. sigaddset( &caught_signals, SIGUSR2 );
  2913. sigaddset( &caught_signals, SIGTERM );
  2914. sigaddset( &caught_signals, SIGHUP );
  2915. (void)sigprocmask( SIG_BLOCK, &caught_signals, NULL );
  2916. if (( sig = sigwait( &caught_signals )) < 0 ) {
  2917. LDAPDebug( LDAP_DEBUG_ANY, "catch_signals: sigwait returned -1\n",
  2918. 0, 0, 0 );
  2919. continue;
  2920. } else {
  2921. LDAPDebug( LDAP_DEBUG_TRACE, "catch_signals: detected signal %d\n",
  2922. sig, 0, 0 );
  2923. switch ( sig ) {
  2924. case SIGUSR1:
  2925. continue; /* ignore SIGUSR1 */
  2926. case SIGUSR2: /* fallthrough */
  2927. case SIGTERM: /* fallthrough */
  2928. case SIGHUP:
  2929. g_set_shutdown( SLAPI_SHUTDOWN_SIGNAL );
  2930. return NULL;
  2931. case SIGCHLD:
  2932. slapd_wait4child( sig );
  2933. break;
  2934. default:
  2935. LDAPDebug( LDAP_DEBUG_ANY,
  2936. "catch_signals: unknown signal (%d) received\n",
  2937. sig, 0, 0 );
  2938. }
  2939. }
  2940. }
  2941. }
  2942. #endif /* HPUX */
  2943. static int
  2944. get_configured_connection_table_size()
  2945. {
  2946. int size = config_get_conntablesize();
  2947. int maxdesc = config_get_maxdescriptors();
  2948. /*
  2949. * Cap the table size at nsslapd-maxdescriptors.
  2950. */
  2951. if ( maxdesc >= 0 && size > maxdesc ) {
  2952. size = maxdesc;
  2953. }
  2954. return size;
  2955. }
  2956. PRFileDesc * get_ssl_listener_fd()
  2957. {
  2958. PRFileDesc * listener;
  2959. listener = the_connection_table->fd[the_connection_table->s_tcps].fd;
  2960. return listener;
  2961. }
  2962. int configure_pr_socket( PRFileDesc **pr_socket, int secure, int local )
  2963. {
  2964. int ns = 0;
  2965. int reservedescriptors = config_get_reservedescriptors();
  2966. int enable_nagle = config_get_nagle();
  2967. PRSocketOptionData pr_socketoption;
  2968. ns = PR_FileDesc2NativeHandle( *pr_socket );
  2969. /*
  2970. * Some OS or third party libraries may require that low
  2971. * numbered file descriptors be available, e.g., the DNS resolver
  2972. * library on most operating systems. Therefore, we try to
  2973. * replace the file descriptor returned by accept() with a
  2974. * higher numbered one. If this fails, we log an error and
  2975. * continue (not considered a truly fatal error).
  2976. */
  2977. if ( reservedescriptors > 0 && ns < reservedescriptors ) {
  2978. int newfd = fcntl( ns, F_DUPFD, reservedescriptors );
  2979. if ( newfd > 0 ) {
  2980. PRFileDesc *nspr_layer_fd = PR_GetIdentitiesLayer( *pr_socket,
  2981. PR_NSPR_IO_LAYER );
  2982. if ( NULL == nspr_layer_fd ) {
  2983. slapi_log_error( SLAPI_LOG_FATAL, "configure_pr_socket",
  2984. "Unable to move socket file descriptor %d above %d:"
  2985. " PR_GetIdentitiesLayer( %p, PR_NSPR_IO_LAYER )"
  2986. " failed\n", ns, reservedescriptors, *pr_socket );
  2987. close( newfd ); /* can't fix things up in NSPR -- close copy */
  2988. } else {
  2989. PR_ChangeFileDescNativeHandle( nspr_layer_fd, newfd );
  2990. close( ns ); /* dup succeeded -- close the original */
  2991. ns = newfd;
  2992. }
  2993. } else {
  2994. int oserr = errno;
  2995. slapi_log_error(SLAPI_LOG_FATAL, "configure_pr_socket",
  2996. "Unable to move socket file descriptor %d above %d:"
  2997. " OS error %d (%s)\n", ns, reservedescriptors, oserr,
  2998. slapd_system_strerror( oserr ) );
  2999. }
  3000. }
  3001. /* Set keep_alive to keep old connections from lingering */
  3002. pr_socketoption.option = PR_SockOpt_Keepalive;
  3003. pr_socketoption.value.keep_alive = 1;
  3004. if ( PR_SetSocketOption( *pr_socket, &pr_socketoption ) == PR_FAILURE ) {
  3005. PRErrorCode prerr = PR_GetError();
  3006. LDAPDebug( LDAP_DEBUG_ANY,
  3007. "PR_SetSocketOption(PR_SockOpt_Keepalive failed, "
  3008. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  3009. prerr, slapd_pr_strerror(prerr), 0 );
  3010. }
  3011. if ( secure ) {
  3012. pr_socketoption.option = PR_SockOpt_Nonblocking;
  3013. pr_socketoption.value.non_blocking = 0;
  3014. if ( PR_SetSocketOption( *pr_socket, &pr_socketoption ) == PR_FAILURE ) {
  3015. PRErrorCode prerr = PR_GetError();
  3016. LDAPDebug( LDAP_DEBUG_ANY,
  3017. "PR_SetSocketOption(PR_SockOpt_Nonblocking) failed, "
  3018. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  3019. prerr, slapd_pr_strerror(prerr), 0 );
  3020. }
  3021. } else {
  3022. /* We always want to have non-blocking I/O */
  3023. pr_socketoption.option = PR_SockOpt_Nonblocking;
  3024. pr_socketoption.value.non_blocking = 1;
  3025. if ( PR_SetSocketOption( *pr_socket, &pr_socketoption ) == PR_FAILURE ) {
  3026. PRErrorCode prerr = PR_GetError();
  3027. LDAPDebug( LDAP_DEBUG_ANY,
  3028. "PR_SetSocketOption(PR_SockOpt_Nonblocking) failed, "
  3029. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  3030. prerr, slapd_pr_strerror(prerr), 0 );
  3031. }
  3032. } /* else (secure) */
  3033. if ( !enable_nagle && !local ) {
  3034. pr_socketoption.option = PR_SockOpt_NoDelay;
  3035. pr_socketoption.value.no_delay = 1;
  3036. if ( PR_SetSocketOption( *pr_socket, &pr_socketoption ) == PR_FAILURE) {
  3037. PRErrorCode prerr = PR_GetError();
  3038. LDAPDebug( LDAP_DEBUG_ANY,
  3039. "PR_SetSocketOption(PR_SockOpt_NoDelay) failed, "
  3040. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  3041. prerr, slapd_pr_strerror( prerr ), 0 );
  3042. }
  3043. } else if( !local) {
  3044. pr_socketoption.option = PR_SockOpt_NoDelay;
  3045. pr_socketoption.value.no_delay = 0;
  3046. if ( PR_SetSocketOption( *pr_socket, &pr_socketoption ) == PR_FAILURE) {
  3047. PRErrorCode prerr = PR_GetError();
  3048. LDAPDebug( LDAP_DEBUG_ANY,
  3049. "PR_SetSocketOption(PR_SockOpt_NoDelay) failed, "
  3050. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  3051. prerr, slapd_pr_strerror( prerr ), 0 );
  3052. }
  3053. } /* else (!enable_nagle) */
  3054. return ns;
  3055. }
  3056. void configure_ns_socket( int * ns )
  3057. {
  3058. int enable_nagle = config_get_nagle();
  3059. int on, rc;
  3060. #if defined(LINUX)
  3061. /* On Linux we use TCP_CORK so we must enable nagle */
  3062. enable_nagle = 1;
  3063. #endif
  3064. /* set the nagle */
  3065. if ( !enable_nagle ) {
  3066. on = 1;
  3067. } else {
  3068. on = 0;
  3069. }
  3070. /* check for errors */
  3071. if((rc = setsockopt( *ns, IPPROTO_TCP, TCP_NODELAY, (char * ) &on, sizeof(on) ) != 0)){
  3072. LDAPDebug( LDAP_DEBUG_ANY,"configure_ns_socket: Failed to configure socket (%d).\n", rc, 0, 0);
  3073. }
  3074. return;
  3075. }
  3076. #ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS
  3077. /*
  3078. * A function that uses the DNS resolver in a simple way. This is only
  3079. * used to ensure that the DNS resolver has opened its files, etc.
  3080. * using low numbered file descriptors.
  3081. */
  3082. static void
  3083. get_loopback_by_addr( void )
  3084. {
  3085. #ifdef GETHOSTBYADDR_BUF_T
  3086. struct hostent hp;
  3087. GETHOSTBYADDR_BUF_T hbuf;
  3088. #endif
  3089. unsigned long ipaddr;
  3090. struct in_addr ia;
  3091. int herrno, rc = 0;
  3092. memset( (char *)&hp, 0, sizeof(hp));
  3093. ipaddr = htonl( INADDR_LOOPBACK );
  3094. (void) GETHOSTBYADDR( (char *)&ipaddr, sizeof( ipaddr ),
  3095. AF_INET, &hp, hbuf, sizeof(hbuf), &herrno );
  3096. }
  3097. #endif /* RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS */
  3098. void
  3099. disk_monitoring_stop()
  3100. {
  3101. if ( disk_thread_p ) {
  3102. PR_Lock( diskmon_mutex );
  3103. PR_NotifyCondVar( diskmon_cvar );
  3104. PR_Unlock( diskmon_mutex );
  3105. }
  3106. }