daemon.c 127 KB

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