daemon.c 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724
  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. #include <string.h>
  39. #include <sys/types.h>
  40. #ifdef _WIN32
  41. #include <windows.h>
  42. #include <process.h> /* for getpid */
  43. #include "proto-ntutil.h"
  44. #include "ntslapdmessages.h"
  45. #else
  46. #include <unistd.h>
  47. #include <sys/socket.h>
  48. #include <errno.h>
  49. #include <netinet/in.h>
  50. #include <arpa/inet.h>
  51. #include <sys/types.h>
  52. #include <netinet/tcp.h>
  53. #include <netdb.h>
  54. #include <sys/time.h>
  55. #include <sys/wait.h>
  56. #include <pthread.h>
  57. #endif
  58. #include <time.h>
  59. #include <signal.h>
  60. #if defined(IRIX6_2) || defined(IRIX6_3)
  61. #include <sys/param.h>
  62. #endif
  63. #if defined(_AIX)
  64. #include <sys/select.h>
  65. #include <sys/param.h>
  66. #endif
  67. #include <fcntl.h>
  68. #define TCPLEN_T int
  69. #if !defined( _WIN32 )
  70. #ifdef NEED_FILIO
  71. #include <sys/filio.h>
  72. #else /* NEED_FILIO */
  73. #include <sys/ioctl.h>
  74. #endif /* NEED_FILIO */
  75. #endif /* !defined( _WIN32 ) */
  76. /* for some reason, linux tty stuff defines CTIME */
  77. #ifdef LINUX
  78. #undef CTIME
  79. #endif
  80. #include "slap.h"
  81. #include "slapi-plugin.h"
  82. #include "snmp_collator.h"
  83. #include <private/pprio.h>
  84. #if defined( NET_SSL )
  85. #include <ssl.h>
  86. #endif /* defined(NET_SSL) */
  87. #include "fe.h"
  88. /*
  89. * Define the backlog number for use in listen() call.
  90. * We use the same definition as in ldapserver/include/base/systems.h
  91. */
  92. #ifndef DAEMON_LISTEN_SIZE
  93. #define DAEMON_LISTEN_SIZE 128
  94. #endif
  95. #if defined (LDAP_IOCP)
  96. #define SLAPD_WAKEUP_TIMER 250
  97. #else
  98. #define SLAPD_WAKEUP_TIMER 250
  99. #endif
  100. int slapd_wakeup_timer = SLAPD_WAKEUP_TIMER; /* time in ms to wakeup */
  101. #ifdef notdef /* GGOODREPL */
  102. /*
  103. * time in secs to do housekeeping:
  104. * this must be greater than slapd_wakeup_timer
  105. */
  106. short slapd_housekeeping_timer = 10;
  107. #endif /* notdef GGOODREPL */
  108. /* Do we support timeout on socket send() ? */
  109. int have_send_timeouts = 0;
  110. PRFileDesc* signalpipe[2];
  111. static int writesignalpipe = SLAPD_INVALID_SOCKET;
  112. static int readsignalpipe = SLAPD_INVALID_SOCKET;
  113. #define FDS_SIGNAL_PIPE 0
  114. #define FDS_N_TCPS 1
  115. #define FDS_S_TCPS 2
  116. static int get_configured_connection_table_size();
  117. #ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS
  118. static void get_loopback_by_addr( void );
  119. #endif
  120. #ifdef XP_WIN32
  121. static int createlistensocket(unsigned short port, const PRNetAddr *listenaddr);
  122. #endif
  123. static PRFileDesc *createprlistensocket(unsigned short port,
  124. const PRNetAddr *listenaddr, int secure);
  125. static const char *netaddr2string(const PRNetAddr *addr, char *addrbuf,
  126. size_t addrbuflen);
  127. static void set_shutdown (int);
  128. static void setup_pr_read_pds(Connection_Table *ct, PRFileDesc *n_tcps, PRFileDesc *s_tcps, PRIntn *num_to_read);
  129. #ifdef HPUX10
  130. static void* catch_signals();
  131. #endif
  132. #if defined( _WIN32 )
  133. HANDLE hServDoneEvent = NULL;
  134. #endif
  135. static int createsignalpipe( void );
  136. #if defined( _WIN32 )
  137. /* Set an event to hook the NT Service termination */
  138. void *slapd_service_exit_wait()
  139. {
  140. #if defined( PURIFYING )
  141. #include <sys/types.h>
  142. #include <sys/stat.h>
  143. char module[_MAX_FNAME];
  144. char exit_file_name[_MAX_FNAME];
  145. char drive[_MAX_DRIVE];
  146. char dir[_MAX_DIR];
  147. char fname[_MAX_FNAME];
  148. char ext[_MAX_EXT];
  149. struct stat statbuf;
  150. memset( module, 0, sizeof( module ) );
  151. memset( exit_file_name, 0, sizeof( exit_file_name ) );
  152. GetModuleFileName(GetModuleHandle( NULL ), module, sizeof( module ) );
  153. _splitpath( module, drive, dir, fname, ext );
  154. PR_snprintf( exit_file_name, sizeof(exit_file_name), "%s%s%s", drive, dir, "exitnow.txt" );
  155. LDAPDebug( LDAP_DEBUG_ANY, "PURIFYING - Create %s to terminate the process.\n", exit_file_name, 0, 0 );
  156. while ( TRUE )
  157. {
  158. if( stat( exit_file_name, &statbuf ) < 0)
  159. {
  160. Sleep( 5000 ); /* 5 Seconds */
  161. continue;
  162. }
  163. LDAPDebug( LDAP_DEBUG_ANY, "slapd shutting down immediately, "
  164. "\"%s\" exists - don't forget to delete it\n", exit_file_name, 0, 0 );
  165. g_set_shutdown( SLAPI_SHUTDOWN_SIGNAL );
  166. return NULL;
  167. }
  168. #else /* PURIFYING */
  169. DWORD dwWait;
  170. char szDoneEvent[256];
  171. PR_snprintf(szDoneEvent, sizeof(szDoneEvent), "NS_%s", pszServerName);
  172. hServDoneEvent = CreateEvent( NULL, // default security attributes (LocalSystem)
  173. TRUE, // manual reset event
  174. FALSE, // not-signalled
  175. szDoneEvent );// named after the service itself.
  176. /* Wait indefinitely until hServDoneEvent is signaled. */
  177. dwWait = WaitForSingleObject( hServDoneEvent, // event object
  178. INFINITE ); // wait indefinitely
  179. /* The termination event has been signalled, log this occurrence, and signal to exit. */
  180. ReportSlapdEvent( EVENTLOG_INFORMATION_TYPE, MSG_SERVER_SHUTDOWN_STARTING, 0, NULL );
  181. g_set_shutdown( SLAPI_SHUTDOWN_SIGNAL );
  182. return NULL;
  183. #endif /* PURIFYING */
  184. }
  185. #endif /* _WIN32 */
  186. static char *
  187. get_pid_file()
  188. {
  189. return(pid_file);
  190. }
  191. static int daemon_configure_send_timeout(int s,size_t timeout /* Miliseconds*/)
  192. {
  193. /* Currently this function is only good for NT, and expects the s argument to be a SOCKET */
  194. #if defined(_WIN32)
  195. return setsockopt(
  196. s,
  197. SOL_SOCKET,
  198. SO_SNDTIMEO,
  199. (char*) &timeout,
  200. sizeof(timeout)
  201. );
  202. #else
  203. return 0;
  204. #endif
  205. }
  206. #if defined (_WIN32)
  207. /* This function is a workaround for accept problem on NT.
  208. Accept call fires on NT during syn scan even though the connection is not
  209. open. This causes a resource leak. For more details, see bug 391414.
  210. Experimentally, we determined that, in case of syn scan, the local
  211. address is set to 0. This in undocumented and my change in the future
  212. The function returns 0 if this is normal connection
  213. 1 if this is syn_scan connection
  214. -1 in case of any other error
  215. */
  216. static int
  217. syn_scan (int sock)
  218. {
  219. int rc;
  220. struct sockaddr_in addr;
  221. int size = sizeof (addr);
  222. if (sock == SLAPD_INVALID_SOCKET)
  223. return -1;
  224. rc = getsockname (sock, (struct sockaddr*)&addr, &size);
  225. if (rc != 0)
  226. return -1;
  227. else if (addr.sin_addr.s_addr == 0)
  228. return 1;
  229. else
  230. return 0;
  231. }
  232. #endif
  233. static int
  234. accept_and_configure(int s, PRFileDesc *pr_acceptfd, PRNetAddr *pr_netaddr,
  235. int addrlen, int secure, PRFileDesc **pr_clonefd)
  236. {
  237. int ns = 0;
  238. PRIntervalTime pr_timeout = PR_MillisecondsToInterval(slapd_wakeup_timer);
  239. #if !defined( XP_WIN32 )
  240. (*pr_clonefd) = PR_Accept(pr_acceptfd, pr_netaddr, pr_timeout);
  241. if( !(*pr_clonefd) ) {
  242. PRErrorCode prerr = PR_GetError();
  243. LDAPDebug( LDAP_DEBUG_ANY, "PR_Accept() failed, "
  244. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  245. prerr, slapd_pr_strerror(prerr), 0 );
  246. return(SLAPD_INVALID_SOCKET);
  247. }
  248. ns = configure_pr_socket( pr_clonefd, secure );
  249. #else
  250. if( secure ) {
  251. (*pr_clonefd) = PR_Accept(pr_acceptfd, pr_netaddr, pr_timeout);
  252. if( !(*pr_clonefd) ) {
  253. PRErrorCode prerr = PR_GetError();
  254. LDAPDebug( LDAP_DEBUG_ANY, "PR_Accept() failed, "
  255. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  256. prerr, slapd_pr_strerror(prerr), 0 );
  257. /* Bug 613324: Call PR_NT_CancelIo if an error occurs */
  258. if( (prerr == PR_IO_TIMEOUT_ERROR ) ||
  259. (prerr == PR_PENDING_INTERRUPT_ERROR) ) {
  260. if( (PR_NT_CancelIo( pr_acceptfd )) != PR_SUCCESS) {
  261. prerr = PR_GetError();
  262. LDAPDebug( LDAP_DEBUG_ANY,
  263. "PR_NT_CancelIo() failed, "
  264. SLAPI_COMPONENT_NAME_NSPR
  265. " error %d (%s)\n",
  266. prerr, slapd_pr_strerror(prerr), 0 );
  267. }
  268. }
  269. return(SLAPD_INVALID_SOCKET);
  270. }
  271. ns = configure_pr_socket( pr_clonefd, secure );
  272. } else {
  273. struct sockaddr *addr;
  274. addr = (struct sockaddr *) slapi_ch_malloc( sizeof(struct sockaddr) );
  275. ns = accept (s, addr, (TCPLEN_T *)&addrlen);
  276. if (ns == SLAPD_INVALID_SOCKET) {
  277. int oserr = errno;
  278. LDAPDebug( LDAP_DEBUG_ANY,
  279. "accept(%d) failed errno %d (%s)\n",
  280. s, oserr, slapd_system_strerror(oserr));
  281. }
  282. else if (syn_scan (ns))
  283. {
  284. /* this is a work around for accept problem with SYN scan on NT.
  285. See bug 391414 for more details */
  286. LDAPDebug(LDAP_DEBUG_ANY, "syn-scan request is received - ignored\n", 0, 0, 0);
  287. closesocket (ns);
  288. ns = SLAPD_INVALID_SOCKET;
  289. }
  290. if ( PR_SetNetAddr(PR_IpAddrNull, PR_AF_INET6, ((struct sockaddr_in *)addr)->sin_port, pr_netaddr)
  291. != PR_SUCCESS ) {
  292. int oserr = PR_GetError();
  293. LDAPDebug( LDAP_DEBUG_ANY, "PR_SetNetAddr() failed, "
  294. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  295. oserr, slapd_pr_strerror(oserr), 0 );
  296. } else {
  297. PR_ConvertIPv4AddrToIPv6(((struct sockaddr_in *)addr)->sin_addr.s_addr, &(pr_netaddr->ipv6.ip));
  298. }
  299. (*pr_clonefd) = NULL;
  300. slapi_ch_free( (void **)&addr );
  301. configure_ns_socket( &ns );
  302. }
  303. #endif
  304. return ns;
  305. }
  306. /*
  307. * This is the shiny new re-born daemon function, without all the hair
  308. */
  309. #ifdef _WIN32
  310. static void setup_read_fds(Connection_Table *ct, fd_set *readfds, int n_tcps, int s_tcps );
  311. static void handle_read_ready(Connection_Table *ct, fd_set *readfds);
  312. static void set_timeval_ms(struct timeval *t, int ms);
  313. #endif
  314. /* GGOODREPL static void handle_timeout( void ); */
  315. static void handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll);
  316. static int handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, int secure );
  317. #ifdef _WIN32
  318. static void unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, int n_tcps, PRFileDesc *s_tcps);
  319. #else
  320. static void unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, PRFileDesc *n_tcps, PRFileDesc *s_tcps);
  321. #endif
  322. static int write_pid_file();
  323. static int init_shutdown_detect();
  324. #ifdef _WIN32
  325. static int clear_signal(fd_set *readfdset);
  326. #else
  327. static int clear_signal(struct POLL_STRUCT *fds);
  328. #endif
  329. /* Globals which are used to store the sockets between
  330. * calls to daemon_pre_setuid_init() and the daemon thread
  331. * creation. */
  332. int daemon_pre_setuid_init(daemon_ports_t *ports)
  333. {
  334. int rc = 0;
  335. if (0 != ports->n_port) {
  336. #if defined( XP_WIN32 )
  337. ports->n_socket = createlistensocket((unsigned short)ports->n_port,
  338. &ports->n_listenaddr);
  339. #else
  340. ports->n_socket = createprlistensocket(ports->n_port,
  341. &ports->n_listenaddr, 0);
  342. #endif
  343. }
  344. if ( config_get_security() && (0 != ports->s_port) ) {
  345. ports->s_socket = createprlistensocket((unsigned short)ports->s_port,
  346. &ports->s_listenaddr, 1);
  347. #ifdef XP_WIN32
  348. ports->s_socket_native = PR_FileDesc2NativeHandle(ports->s_socket);
  349. #endif
  350. /* check if ports->s_socket != -1 ? */
  351. rc = slapd_ssl_init2 ( &ports->s_socket, 0 );
  352. } else {
  353. ports->s_socket = SLAPD_INVALID_SOCKET;
  354. #ifdef XP_WIN32
  355. ports->s_socket_native = SLAPD_INVALID_SOCKET;
  356. #endif
  357. }
  358. return( rc );
  359. }
  360. /* Decide whether we're running on a platform which supports send with timeouts */
  361. static void detect_timeout_support()
  362. {
  363. /* Currently we know that NT4.0 or higher DOES support timeouts */
  364. #if defined _WIN32
  365. /* Get the OS revision */
  366. OSVERSIONINFO ver;
  367. ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  368. GetVersionEx(&ver);
  369. if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT && ver.dwMajorVersion >= 4) {
  370. have_send_timeouts = 1;
  371. }
  372. #else
  373. /* Some UNIXen do, but for now I don't feel confident which , and whether timeouts really work there */
  374. #endif
  375. }
  376. /*
  377. * The time_shutdown static variable is used to signal the time thread
  378. * to shutdown. We used to shut down the time thread when g_get_shutdown()
  379. * returned a non-zero value, but that caused the clock to stop, so to speak,
  380. * and all error log entries to have the same timestamp once the shutdown
  381. * process began.
  382. */
  383. static int time_shutdown = 0;
  384. void *
  385. time_thread(void *nothing)
  386. {
  387. PRIntervalTime interval;
  388. interval = PR_SecondsToInterval(1);
  389. while(!time_shutdown) {
  390. poll_current_time();
  391. csngen_update_time ();
  392. DS_Sleep(interval);
  393. }
  394. /*NOTREACHED*/
  395. return(NULL);
  396. }
  397. void slapd_daemon( daemon_ports_t *ports )
  398. {
  399. /* We are passed a pair of ports---one for regular connections, the
  400. * other for SSL connections.
  401. */
  402. /* Previously there was a ton of code #defined on NET_SSL.
  403. * This looked horrible, so now I'm doing it this way:
  404. * If you want me to do SSL, pass me something in the ssl port number.
  405. * If you don't, pass me zero.
  406. */
  407. #if defined( XP_WIN32 )
  408. int n_tcps = 0;
  409. int s_tcps_native = 0;
  410. #else
  411. PRFileDesc *n_tcps = NULL;
  412. PRFileDesc *tcps = 0;
  413. #endif
  414. PRFileDesc *s_tcps = NULL;
  415. PRIntn num_poll = 0;
  416. PRIntervalTime pr_timeout = PR_MillisecondsToInterval(slapd_wakeup_timer);
  417. PRThread *time_thread_p;
  418. int threads;
  419. int in_referral_mode = config_check_referral_mode();
  420. int connection_table_size = get_configured_connection_table_size();
  421. the_connection_table= connection_table_new(connection_table_size);
  422. #ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS
  423. /*
  424. * Some DNS resolver implementations, such as the one built into
  425. * Solaris <= 8, need to use one or more low numbered file
  426. * descriptors internally (probably because they use a deficient
  427. * implementation of stdio). So we make a call now that uses the
  428. * resolver so it has an opportunity to grab whatever low file
  429. * descriptors it needs (before we use up all of the low numbered
  430. * ones for incoming client connections and so on).
  431. */
  432. get_loopback_by_addr();
  433. #endif
  434. /* Retrieve the sockets from their hiding place */
  435. n_tcps = ports->n_socket;
  436. s_tcps = ports->s_socket;
  437. #ifdef XP_WIN32
  438. s_tcps_native = ports->s_socket_native;
  439. #endif
  440. createsignalpipe();
  441. init_shutdown_detect();
  442. #if defined( XP_WIN32 )
  443. if ( (n_tcps == SLAPD_INVALID_SOCKET) &&
  444. #else
  445. if ( (n_tcps == NULL) &&
  446. #endif
  447. (s_tcps == NULL) ) { /* nothing to do */
  448. LDAPDebug( LDAP_DEBUG_ANY,
  449. "no port to listen on\n", 0, 0, 0 );
  450. exit( 1 );
  451. }
  452. unfurl_banners(the_connection_table,ports,n_tcps,s_tcps);
  453. init_op_threads ();
  454. detect_timeout_support();
  455. /* Start the time thread */
  456. time_thread_p = PR_CreateThread(PR_SYSTEM_THREAD,
  457. (VFP) (void *) time_thread, NULL,
  458. PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
  459. PR_JOINABLE_THREAD,
  460. SLAPD_DEFAULT_THREAD_STACKSIZE);
  461. if ( NULL == time_thread_p ) {
  462. PRErrorCode errorCode = PR_GetError();
  463. LDAPDebug(LDAP_DEBUG_ANY, "Unable to create time thread - Shutting Down ("
  464. SLAPI_COMPONENT_NAME_NSPR " error %d - %s)\n",
  465. errorCode, slapd_pr_strerror(errorCode), 0);
  466. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  467. }
  468. /* We are now ready to accept imcoming connections */
  469. #if defined( XP_WIN32 )
  470. if ( n_tcps != SLAPD_INVALID_SOCKET
  471. && listen( n_tcps, DAEMON_LISTEN_SIZE ) == -1 ) {
  472. int oserr = errno;
  473. char addrbuf[ 256 ];
  474. slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
  475. "listen() on %s port %d failed: OS error %d (%s)\n",
  476. netaddr2string(&ports->n_listenaddr, addrbuf, sizeof(addrbuf)),
  477. ports->n_port, oserr, slapd_system_strerror( oserr ) );
  478. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  479. }
  480. #else
  481. if ( n_tcps != NULL
  482. && PR_Listen( n_tcps, DAEMON_LISTEN_SIZE ) == PR_FAILURE) {
  483. PRErrorCode prerr = PR_GetError();
  484. char addrbuf[ 256 ];
  485. slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
  486. "PR_Listen() on %s port %d failed: %s error %d (%s)\n",
  487. netaddr2string(&ports->n_listenaddr, addrbuf, sizeof(addrbuf)),
  488. ports->n_port, SLAPI_COMPONENT_NAME_NSPR, prerr,
  489. slapd_pr_strerror( prerr ));
  490. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  491. }
  492. #endif
  493. if ( s_tcps != NULL
  494. && PR_Listen( s_tcps, DAEMON_LISTEN_SIZE ) == PR_FAILURE ) {
  495. PRErrorCode prerr = PR_GetError();
  496. char addrbuf[ 256 ];
  497. slapi_log_error(SLAPI_LOG_FATAL, "slapd_daemon",
  498. "PR_Listen() on %s port %d failed: %s error %d (%s)\n",
  499. netaddr2string(&ports->s_listenaddr, addrbuf, sizeof(addrbuf)),
  500. ports->s_port, SLAPI_COMPONENT_NAME_NSPR, prerr,
  501. slapd_pr_strerror( prerr ));
  502. g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
  503. }
  504. /* Now we write the pid file, indicating that the server is finally and listening for connections */
  505. write_pid_file();
  506. /* The meat of the operation is in a loop on a call to select */
  507. while(!g_get_shutdown())
  508. {
  509. #ifdef _WIN32
  510. fd_set readfds;
  511. struct timeval wakeup_timer;
  512. int oserr;
  513. #endif
  514. int select_return = 0;
  515. int secure = 0; /* is a new connection an SSL one ? */
  516. #ifndef _WIN32
  517. PRErrorCode prerr;
  518. #endif
  519. #ifdef _WIN32
  520. set_timeval_ms(&wakeup_timer, slapd_wakeup_timer);
  521. setup_read_fds(the_connection_table,&readfds,n_tcps, s_tcps_native);
  522. /* This select needs to timeout to give the server a chance to test for shutdown */
  523. select_return = select(connection_table_size, &readfds, NULL, 0, &wakeup_timer);
  524. #else
  525. setup_pr_read_pds(the_connection_table,n_tcps,s_tcps,&num_poll);
  526. select_return = POLL_FN(the_connection_table->fd, num_poll, pr_timeout);
  527. #endif
  528. switch (select_return) {
  529. case 0: /* Timeout */
  530. /* GGOODREPL handle_timeout(); */
  531. break;
  532. case -1: /* Error */
  533. #ifdef _WIN32
  534. oserr = errno;
  535. LDAPDebug( LDAP_DEBUG_TRACE,
  536. "select failed errno %d (%s)\n", oserr,
  537. slapd_system_strerror(oserr), 0 );
  538. #else
  539. prerr = PR_GetError();
  540. LDAPDebug( LDAP_DEBUG_TRACE, "PR_Poll() failed, "
  541. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  542. prerr, slapd_system_strerror(prerr), 0 );
  543. #endif
  544. break;
  545. default: /* either a new connection or some new data ready */
  546. /* Figure out if we are dealing with one of the listen sockets */
  547. #ifdef _WIN32
  548. /* If so, then handle a new connection */
  549. if ( n_tcps != SLAPD_INVALID_SOCKET && FD_ISSET( n_tcps,&readfds ) ) {
  550. handle_new_connection(the_connection_table,n_tcps,NULL,0);
  551. }
  552. /* If so, then handle a new connection */
  553. if ( s_tcps != SLAPD_INVALID_SOCKET && FD_ISSET( s_tcps_native,&readfds ) ) {
  554. handle_new_connection(the_connection_table,SLAPD_INVALID_SOCKET,s_tcps,1);
  555. }
  556. /* handle new data ready */
  557. handle_read_ready(the_connection_table,&readfds);
  558. clear_signal(&readfds);
  559. #else
  560. tcps = NULL;
  561. /* info for n_tcps is always in fd[FDS_N_TCPS] and info for s_tcps is always
  562. * in fd[FDS_S_TCPS] */
  563. if( n_tcps != NULL &&
  564. the_connection_table->fd[FDS_N_TCPS].out_flags & SLAPD_POLL_FLAGS ) {
  565. tcps = n_tcps;
  566. } else if ( s_tcps != NULL &&
  567. the_connection_table->fd[FDS_S_TCPS].out_flags & SLAPD_POLL_FLAGS ) {
  568. tcps = s_tcps;
  569. secure = 1;
  570. }
  571. /* If so, then handle a new connection */
  572. if ( tcps != NULL ) {
  573. handle_new_connection(the_connection_table,SLAPD_INVALID_SOCKET,tcps,secure);
  574. }
  575. /* handle new data ready */
  576. handle_pr_read_ready(the_connection_table, connection_table_size);
  577. clear_signal(the_connection_table->fd);
  578. #endif
  579. break;
  580. }
  581. }
  582. /* We get here when the server is shutting down */
  583. /* Do what we have to do before death */
  584. connection_table_abandon_all_operations(the_connection_table); /* abandon all operations in progress */
  585. if ( ! in_referral_mode ) {
  586. ps_stop_psearch_system(); /* stop any persistent searches */
  587. }
  588. #ifdef _WIN32
  589. if ( n_tcps != SLAPD_INVALID_SOCKET ) {
  590. closesocket( n_tcps );
  591. #else
  592. if ( n_tcps != NULL ) {
  593. PR_Close( n_tcps );
  594. #endif
  595. }
  596. if ( s_tcps != NULL ) {
  597. PR_Close( s_tcps );
  598. }
  599. /* Might compete with housecleaning thread, but so far so good */
  600. be_flushall();
  601. op_thread_cleanup();
  602. housekeeping_stop(); /* Run this after op_thread_cleanup() logged sth */
  603. #ifndef _WIN32
  604. if ( active_threads > 0 ) {
  605. LDAPDebug( LDAP_DEBUG_ANY,
  606. "slapd shutting down - waiting for %d thread%s to terminate\n",
  607. active_threads, ( active_threads > 1 ) ? "s" : "", 0 );
  608. }
  609. #endif
  610. threads = active_threads;
  611. while ( active_threads > 0 ) {
  612. PRPollDesc xpd;
  613. char x;
  614. int spe = 0;
  615. /* try to read from the signal pipe, in case threads are
  616. * blocked on it. */
  617. xpd.fd = signalpipe[0];
  618. xpd.in_flags = PR_POLL_READ;
  619. xpd.out_flags = 0;
  620. spe = PR_Poll(&xpd, 1, PR_INTERVAL_NO_WAIT);
  621. if (spe > 0) {
  622. spe = PR_Read(signalpipe[0], &x, 1);
  623. if (spe < 0) {
  624. PRErrorCode prerr = PR_GetError();
  625. LDAPDebug( LDAP_DEBUG_ANY, "listener could not clear signal pipe, "
  626. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  627. prerr, slapd_system_strerror(prerr), 0 );
  628. break;
  629. }
  630. } else if (spe == -1) {
  631. PRErrorCode prerr = PR_GetError();
  632. LDAPDebug( LDAP_DEBUG_ANY, "PR_Poll() failed, "
  633. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  634. prerr, slapd_system_strerror(prerr), 0 );
  635. break;
  636. } else {
  637. /* no data */
  638. }
  639. DS_Sleep(PR_INTERVAL_NO_WAIT);
  640. if ( threads != active_threads ) {
  641. LDAPDebug( LDAP_DEBUG_TRACE,
  642. "slapd shutting down - waiting for %d threads to terminate\n",
  643. active_threads, 0, 0 );
  644. threads = active_threads;
  645. }
  646. }
  647. LDAPDebug( LDAP_DEBUG_ANY,
  648. "slapd shutting down - closing down internal subsystems and plugins\n",
  649. 0, 0, 0 );
  650. log_access_flush();
  651. /* let backends do whatever cleanup they need to do */
  652. LDAPDebug( LDAP_DEBUG_TRACE,"slapd shutting down - waiting for backends to close down\n", 0, 0,0 );
  653. eq_stop();
  654. if ( ! in_referral_mode ) {
  655. task_shutdown();
  656. uniqueIDGenCleanup ();
  657. }
  658. plugin_closeall( 1 /* Close Backends */, 1 /* Close Gloabls */);
  659. if ( ! in_referral_mode ) {
  660. /* Close SNMP collator after the plugins closed...
  661. * Replication plugin still performs internal ops that
  662. * may try to increment snmp stats.
  663. * Fix for defect 523780
  664. */
  665. snmp_collator_stop();
  666. mapping_tree_free ();
  667. }
  668. be_cleanupall ();
  669. LDAPDebug( LDAP_DEBUG_TRACE, "slapd shutting down - backends closed down\n",
  670. 0, 0, 0 );
  671. referrals_free();
  672. connection_table_free(the_connection_table);
  673. the_connection_table= NULL;
  674. /* tell the time thread to shutdown and then wait for it */
  675. time_shutdown = 1;
  676. PR_JoinThread( time_thread_p );
  677. #ifdef _WIN32
  678. WSACleanup();
  679. #endif
  680. }
  681. int signal_listner()
  682. {
  683. /* Replaces previous macro---called to bump the thread out of select */
  684. #if defined( _WIN32 )
  685. if ( PR_Write( signalpipe[1], "", 1) != 1 ) {
  686. /* this now means that the pipe is full
  687. * this is not a problem just go-on
  688. */
  689. LDAPDebug( LDAP_DEBUG_CONNS,
  690. "listener could not write to signal pipe %d\n",
  691. errno, 0, 0 );
  692. }
  693. #else
  694. if ( write( writesignalpipe, "", 1) != 1 ) {
  695. /* this now means that the pipe is full
  696. * this is not a problem just go-on
  697. */
  698. LDAPDebug( LDAP_DEBUG_CONNS,
  699. "listener could not write to signal pipe %d\n",
  700. errno, 0, 0 );
  701. }
  702. #endif
  703. return( 0 );
  704. }
  705. #ifdef _WIN32
  706. static int clear_signal(fd_set *readfdset)
  707. #else
  708. static int clear_signal(struct POLL_STRUCT *fds)
  709. #endif
  710. {
  711. #ifdef _WIN32
  712. if ( FD_ISSET(readsignalpipe, readfdset)) {
  713. #else
  714. if ( fds[FDS_SIGNAL_PIPE].out_flags & SLAPD_POLL_FLAGS ) {
  715. #endif
  716. char buf[200];
  717. LDAPDebug( LDAP_DEBUG_CONNS,
  718. "listener got signaled\n",
  719. 0, 0, 0 );
  720. #ifdef _WIN32
  721. if ( PR_Read( signalpipe[0], buf, 20 ) < 1 ) {
  722. #else
  723. if ( read( readsignalpipe, buf, 200 ) < 1 ) {
  724. #endif
  725. LDAPDebug( LDAP_DEBUG_ANY,
  726. "listener could not clear signal pipe\n",
  727. 0, 0, 0 );
  728. }
  729. }
  730. return 0;
  731. }
  732. #ifdef _WIN32
  733. static void set_timeval_ms(struct timeval *t, int ms)
  734. {
  735. t->tv_sec = ms/1000;
  736. t->tv_usec = (ms % 1000)*1000;
  737. }
  738. #endif
  739. #ifdef _WIN32
  740. static void setup_read_fds(Connection_Table *ct, fd_set *readfds, int n_tcps, int s_tcps)
  741. {
  742. Connection *c= NULL;
  743. Connection *next= NULL;
  744. int accept_new_connections;
  745. static int last_accept_new_connections = -1;
  746. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  747. LBER_SOCKET socketdesc = SLAPD_INVALID_SOCKET;
  748. FD_ZERO( readfds );
  749. accept_new_connections = ((ct->size - g_get_current_conn_count())
  750. > slapdFrontendConfig->reservedescriptors);
  751. if ( ! accept_new_connections ) {
  752. if ( last_accept_new_connections ) {
  753. LDAPDebug( LDAP_DEBUG_ANY, "Not listening for new "
  754. "connections - too many fds open\n", 0, 0, 0 );
  755. }
  756. } else {
  757. if ( ! last_accept_new_connections &&
  758. last_accept_new_connections != -1 ) {
  759. LDAPDebug( LDAP_DEBUG_ANY, "Listening for new "
  760. "connections again\n", 0, 0, 0 );
  761. }
  762. }
  763. last_accept_new_connections = accept_new_connections;
  764. if (n_tcps != SLAPD_INVALID_SOCKET && accept_new_connections) {
  765. FD_SET( n_tcps, readfds );
  766. LDAPDebug( LDAP_DEBUG_HOUSE,
  767. "listening for connections on %d\n", n_tcps, 0, 0 );
  768. }
  769. if (s_tcps != SLAPD_INVALID_SOCKET && accept_new_connections) {
  770. FD_SET( s_tcps, readfds );
  771. LDAPDebug( LDAP_DEBUG_HOUSE,
  772. "listening for connections on %d\n", s_tcps, 0, 0 );
  773. }
  774. if ((s_tcps != SLAPD_INVALID_SOCKET)
  775. && (readsignalpipe != SLAPD_INVALID_SOCKET)) {
  776. FD_SET( readsignalpipe, readfds );
  777. }
  778. /* Walk down the list of active connections to find
  779. * out which connections we should poll over. If a connection
  780. * is no longer in use, we should remove it from the linked
  781. * list. */
  782. c= connection_table_get_first_active_connection (ct);
  783. while (c)
  784. {
  785. next = connection_table_get_next_active_connection (ct, c);
  786. if ( c->c_mutex == NULL )
  787. {
  788. connection_table_move_connection_out_of_active_list(ct,c);
  789. }
  790. else
  791. {
  792. PR_Lock( c->c_mutex );
  793. if ( c->c_flags & CONN_FLAG_CLOSING )
  794. {
  795. /* A worker thread has marked that this connection
  796. * should be closed by calling disconnect_server.
  797. * move this connection out of the active list
  798. * the last thread to use the connection will close it
  799. */
  800. connection_table_move_connection_out_of_active_list(ct,c);
  801. }
  802. else if ( c->c_sd == SLAPD_INVALID_SOCKET )
  803. {
  804. connection_table_move_connection_out_of_active_list(ct,c);
  805. }
  806. else
  807. {
  808. #if defined(LDAP_IOCP) /* When we have IO completion ports, we don't want to do this */
  809. if ( !c->c_gettingber && (c->c_flags & CONN_FLAG_SSL) )
  810. #else
  811. if ( !c->c_gettingber )
  812. #endif
  813. {
  814. FD_SET( c->c_sd, readfds );
  815. }
  816. }
  817. PR_Unlock( c->c_mutex );
  818. }
  819. c = next;
  820. }
  821. }
  822. #endif /* _WIN32 */
  823. static int first_time_setup_pr_read_pds = 1;
  824. static void
  825. setup_pr_read_pds(Connection_Table *ct, PRFileDesc *n_tcps, PRFileDesc *s_tcps, PRIntn *num_to_read)
  826. {
  827. Connection *c= NULL;
  828. Connection *next= NULL;
  829. LBER_SOCKET socketdesc = SLAPD_INVALID_SOCKET;
  830. int accept_new_connections;
  831. static int last_accept_new_connections = -1;
  832. PRIntn count = 0;
  833. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  834. int max_threads_per_conn = config_get_maxthreadsperconn();
  835. accept_new_connections = ((ct->size - g_get_current_conn_count())
  836. > slapdFrontendConfig->reservedescriptors);
  837. if ( ! accept_new_connections ) {
  838. if ( last_accept_new_connections ) {
  839. LDAPDebug( LDAP_DEBUG_ANY, "Not listening for new "
  840. "connections - too many fds open\n", 0, 0, 0 );
  841. /* reinitialize n_tcps and s_tcps to the pds */
  842. first_time_setup_pr_read_pds = 1;
  843. }
  844. } else {
  845. if ( ! last_accept_new_connections &&
  846. last_accept_new_connections != -1 ) {
  847. LDAPDebug( LDAP_DEBUG_ANY, "Listening for new "
  848. "connections again\n", 0, 0, 0 );
  849. /* reinitialize n_tcps and s_tcps to the pds */
  850. first_time_setup_pr_read_pds = 1;
  851. }
  852. }
  853. last_accept_new_connections = accept_new_connections;
  854. /* initialize the mapping from connection table entries to fds entries */
  855. if (first_time_setup_pr_read_pds)
  856. {
  857. int i;
  858. for (i = 0; i < ct->size; i++)
  859. {
  860. ct->c[i].c_fdi = SLAPD_INVALID_SOCKET_INDEX;
  861. }
  862. /* The fds entry for n_tcps is always FDS_N_TCPS */
  863. if (n_tcps != NULL && accept_new_connections)
  864. {
  865. ct->fd[FDS_N_TCPS].fd = n_tcps;
  866. ct->fd[FDS_N_TCPS].in_flags = SLAPD_POLL_FLAGS;
  867. ct->fd[FDS_N_TCPS].out_flags = 0;
  868. LDAPDebug( LDAP_DEBUG_HOUSE,
  869. "listening for connections on %d\n", socketdesc, 0, 0 );
  870. } else {
  871. ct->fd[FDS_N_TCPS].fd = NULL;
  872. }
  873. /* The fds entry for s_tcps is always FDS_S_TCPS */
  874. if (s_tcps != NULL && accept_new_connections)
  875. {
  876. ct->fd[FDS_S_TCPS].fd = s_tcps;
  877. ct->fd[FDS_S_TCPS].in_flags = SLAPD_POLL_FLAGS;
  878. ct->fd[FDS_S_TCPS].out_flags = 0;
  879. LDAPDebug( LDAP_DEBUG_HOUSE,
  880. "listening for SSL connections on %d\n", socketdesc, 0, 0 );
  881. } else {
  882. ct->fd[FDS_S_TCPS].fd = NULL;
  883. }
  884. #if !defined(_WIN32)
  885. /* The fds entry for the signalpipe is always FDS_SIGNAL_PIPE */
  886. ct->fd[FDS_SIGNAL_PIPE].fd = signalpipe[0];
  887. ct->fd[FDS_SIGNAL_PIPE].in_flags = SLAPD_POLL_FLAGS;
  888. ct->fd[FDS_SIGNAL_PIPE].out_flags = 0;
  889. #else
  890. ct->fd[FDS_SIGNAL_PIPE].fd = NULL;
  891. #endif
  892. first_time_setup_pr_read_pds = 0;
  893. }
  894. /* count is the number of entries we've place in the fds array.
  895. * we always put n_tcps in slot FDS_N_TCPS, s_tcps in slot
  896. * FDS_S_TCPS and the signal pipe in slot FDS_SIGNAL_PIPE
  897. * so we now set count to 3 */
  898. count = 3;
  899. /* Walk down the list of active connections to find
  900. * out which connections we should poll over. If a connection
  901. * is no longer in use, we should remove it from the linked
  902. * list. */
  903. c = connection_table_get_first_active_connection (ct);
  904. while (c)
  905. {
  906. next = connection_table_get_next_active_connection (ct, c);
  907. if ( c->c_mutex == NULL )
  908. {
  909. connection_table_move_connection_out_of_active_list(ct,c);
  910. }
  911. else
  912. {
  913. PR_Lock( c->c_mutex );
  914. if (c->c_flags & CONN_FLAG_CLOSING)
  915. {
  916. /* A worker thread has marked that this connection
  917. * should be closed by calling disconnect_server.
  918. * move this connection out of the active list
  919. * the last thread to use the connection will close it
  920. */
  921. connection_table_move_connection_out_of_active_list(ct,c);
  922. }
  923. else if ( c->c_sd == SLAPD_INVALID_SOCKET )
  924. {
  925. connection_table_move_connection_out_of_active_list(ct,c);
  926. }
  927. else if ( c->c_prfd != NULL)
  928. {
  929. if ((!c->c_gettingber)
  930. && (c->c_threadnumber < max_threads_per_conn))
  931. {
  932. ct->fd[count].fd = c->c_prfd;
  933. ct->fd[count].in_flags = SLAPD_POLL_FLAGS;
  934. /* slot i of the connection table is mapped to slot
  935. * count of the fds array */
  936. c->c_fdi = count;
  937. count++;
  938. }
  939. else
  940. {
  941. c->c_fdi = SLAPD_INVALID_SOCKET_INDEX;
  942. }
  943. }
  944. PR_Unlock( c->c_mutex );
  945. }
  946. c = next;
  947. }
  948. if( num_to_read )
  949. (*num_to_read) = count;
  950. }
  951. #ifdef notdef /* GGOODREPL */
  952. static void
  953. handle_timeout( void )
  954. {
  955. static time_t prevtime = 0;
  956. static time_t housekeeping_fire_time = 0;
  957. time_t curtime = current_time();
  958. if (0 == prevtime) {
  959. prevtime = time (&housekeeping_fire_time);
  960. }
  961. if ( difftime(curtime, prevtime) >=
  962. slapd_housekeeping_timer ) {
  963. int num_active_threads;
  964. snmp_collator_update();
  965. prevtime = curtime;
  966. num_active_threads = active_threads;
  967. if ( (num_active_threads == 0) ||
  968. (difftime(curtime, housekeeping_fire_time) >=
  969. slapd_housekeeping_timer*3) ) {
  970. housekeeping_fire_time = curtime;
  971. housekeeping_start(curtime);
  972. }
  973. }
  974. }
  975. #endif /* notdef */
  976. static int idletimeout_reslimit_handle = -1;
  977. /*
  978. * Register the idletimeout with the binder-based resource limits
  979. * subsystem. A SLAPI_RESLIMIT_STATUS_... code is returned.
  980. */
  981. int
  982. daemon_register_reslimits( void )
  983. {
  984. return( slapi_reslimit_register( SLAPI_RESLIMIT_TYPE_INT, "nsIdleTimeout",
  985. &idletimeout_reslimit_handle ));
  986. }
  987. /*
  988. * Compute the idle timeout for the connection.
  989. *
  990. * Note: this function must always be called with conn->c_mutex locked.
  991. */
  992. static int
  993. compute_idletimeout( slapdFrontendConfig_t *fecfg, Connection *conn )
  994. {
  995. int idletimeout;
  996. if ( slapi_reslimit_get_integer_limit( conn, idletimeout_reslimit_handle,
  997. &idletimeout ) != SLAPI_RESLIMIT_STATUS_SUCCESS ) {
  998. /*
  999. * no limit associated with binder/connection or some other error
  1000. * occurred. use the default idle timeout.
  1001. */
  1002. if ( conn->c_isroot ) {
  1003. idletimeout = 0; /* no limit for Directory Manager */
  1004. } else {
  1005. idletimeout = fecfg->idletimeout;
  1006. }
  1007. }
  1008. return( idletimeout );
  1009. }
  1010. #ifdef _WIN32
  1011. static void
  1012. handle_read_ready(Connection_Table *ct, fd_set *readfds)
  1013. {
  1014. Connection *c= NULL;
  1015. time_t curtime = current_time();
  1016. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  1017. int idletimeout;
  1018. #ifdef LDAP_DEBUG
  1019. if ( slapd_ldap_debug & LDAP_DEBUG_CONNS )
  1020. {
  1021. connection_table_dump_activity_to_errors_log(ct);
  1022. }
  1023. #endif /* LDAP_DEBUG */
  1024. /* Instead of going through the whole connection table to see which
  1025. * connections we can read from, we'll only check the slots in the
  1026. * linked list */
  1027. c = connection_table_get_first_active_connection (ct);
  1028. while ( c!=NULL )
  1029. {
  1030. if ( c->c_mutex != NULL )
  1031. {
  1032. PR_Lock( c->c_mutex );
  1033. if (connection_is_active_nolock (c) && c->c_gettingber == 0 )
  1034. {
  1035. /* read activity */
  1036. short readready= ( FD_ISSET( c->c_sd, readfds ) );
  1037. /* read activity */
  1038. if ( readready )
  1039. {
  1040. LDAPDebug( LDAP_DEBUG_CONNS, "read activity on %d\n", c->c_ci, 0, 0 );
  1041. c->c_idlesince = curtime;
  1042. /* This is where the work happens ! */
  1043. connection_activity( c );
  1044. /* idle timeout */
  1045. }
  1046. else if (( idletimeout = compute_idletimeout(
  1047. slapdFrontendConfig, c )) > 0 &&
  1048. (curtime - c->c_idlesince) >= idletimeout &&
  1049. NULL == c->c_ops )
  1050. {
  1051. disconnect_server_nomutex( c, c->c_connid, -1,
  1052. SLAPD_DISCONNECT_IDLE_TIMEOUT, EAGAIN );
  1053. }
  1054. }
  1055. PR_Unlock( c->c_mutex );
  1056. }
  1057. c = connection_table_get_next_active_connection (ct, c);
  1058. }
  1059. }
  1060. #endif /* _WIN32 */
  1061. static void
  1062. handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll)
  1063. {
  1064. Connection *c;
  1065. time_t curtime = current_time();
  1066. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  1067. int idletimeout;
  1068. #if defined( XP_WIN32 )
  1069. int i;
  1070. #endif
  1071. #if LDAP_DEBUG
  1072. if ( slapd_ldap_debug & LDAP_DEBUG_CONNS )
  1073. {
  1074. connection_table_dump_activity_to_errors_log(ct);
  1075. }
  1076. #endif /* LDAP_DEBUG */
  1077. #if defined( XP_WIN32 )
  1078. /*
  1079. * WIN32: this function is only called for SSL connections and
  1080. * num_poll indicates exactly how many PR fds we polled on.
  1081. */
  1082. for ( i = 0; i < num_poll; i++ )
  1083. {
  1084. short readready;
  1085. readready = (ct->fd[i].out_flags & SLAPD_POLL_FLAGS);
  1086. /* Find the connection we are referring to */
  1087. for ( c = connection_table_get_first_active_connection (ct); c != NULL;
  1088. c = connection_table_get_next_active_connection (ct, c) )
  1089. {
  1090. if ( c->c_mutex != NULL )
  1091. {
  1092. PR_Lock( c->c_mutex );
  1093. if ( c->c_prfd == ct->fd[i].fd )
  1094. {
  1095. break; /* c_mutex is still locked! */
  1096. }
  1097. PR_Unlock( c->c_mutex );
  1098. }
  1099. }
  1100. if ( c == NULL )
  1101. { /* connection not found! */
  1102. LDAPDebug( LDAP_DEBUG_CONNS, "handle_pr_read_ready: "
  1103. "connection not found for poll slot %d\n", i,0,0 );
  1104. }
  1105. else
  1106. {
  1107. /* c_mutex is still locked... check for activity and errors */
  1108. if ( !readready && ct->fd[i].out_flags && c->c_prfd == ct->fd[i].fd )
  1109. {
  1110. /* some error occured */
  1111. LDAPDebug( LDAP_DEBUG_CONNS,
  1112. "poll says connection on sd %d is bad "
  1113. "(closing)\n", c->c_sd, 0, 0 );
  1114. disconnect_server_nomutex( c, c->c_connid, -1, SLAPD_DISCONNECT_POLL, EPIPE );
  1115. }
  1116. else if ( readready && c->c_prfd == ct->fd[i].fd )
  1117. {
  1118. /* read activity */
  1119. LDAPDebug( LDAP_DEBUG_CONNS,
  1120. "read activity on %d\n", i, 0, 0 );
  1121. c->c_idlesince = curtime;
  1122. /* This is where the work happens ! */
  1123. connection_activity( c );
  1124. }
  1125. else if (( idletimeout = compute_idletimeout( slapdFrontendConfig,
  1126. c )) > 0 &&
  1127. c->c_prfd == ct->fd[i].fd &&
  1128. (curtime - c->c_idlesince) >= idletimeout &&
  1129. NULL == c->c_ops )
  1130. {
  1131. /* idle timeout */
  1132. disconnect_server_nomutex( c, c->c_connid, -1,
  1133. SLAPD_DISCONNECT_IDLE_TIMEOUT, EAGAIN );
  1134. }
  1135. PR_Unlock( c->c_mutex );
  1136. }
  1137. }
  1138. #else
  1139. /*
  1140. * non-WIN32: this function is called for all connections, so we
  1141. * traverse the entire active connection list to find any errors,
  1142. * activity, etc.
  1143. */
  1144. for ( c = connection_table_get_first_active_connection (ct); c != NULL;
  1145. c = connection_table_get_next_active_connection (ct, c) )
  1146. {
  1147. if ( c->c_mutex != NULL )
  1148. {
  1149. PR_Lock( c->c_mutex );
  1150. if ( connection_is_active_nolock (c) && c->c_gettingber == 0 )
  1151. {
  1152. PRInt16 out_flags;
  1153. short readready;
  1154. if (c->c_fdi != SLAPD_INVALID_SOCKET_INDEX)
  1155. {
  1156. out_flags = ct->fd[c->c_fdi].out_flags;
  1157. }
  1158. else
  1159. {
  1160. out_flags = 0;
  1161. }
  1162. readready = ( out_flags & SLAPD_POLL_FLAGS );
  1163. if ( !readready && out_flags )
  1164. {
  1165. /* some error occured */
  1166. LDAPDebug( LDAP_DEBUG_CONNS,
  1167. "POLL_FN() says connection on sd %d is bad "
  1168. "(closing)\n", c->c_sd, 0, 0 );
  1169. disconnect_server_nomutex( c, c->c_connid, -1,
  1170. SLAPD_DISCONNECT_POLL, EPIPE );
  1171. }
  1172. else if ( readready )
  1173. {
  1174. /* read activity */
  1175. LDAPDebug( LDAP_DEBUG_CONNS,
  1176. "read activity on %d\n", c->c_ci, 0, 0 );
  1177. c->c_idlesince = curtime;
  1178. /* This is where the work happens ! */
  1179. /* MAB: 25 jan 01, error handling added */
  1180. if ((connection_activity( c )) == -1) {
  1181. /* This might happen as a result of
  1182. * trying to acquire a closing connection
  1183. */
  1184. LDAPDebug (LDAP_DEBUG_ANY,
  1185. "connection_activity: abandoning conn %d as fd=%d is already closing\n",
  1186. c->c_connid,c->c_sd,0);
  1187. /* The call disconnect_server should do nothing,
  1188. * as the connection c should be already set to CLOSING */
  1189. disconnect_server_nomutex( c, c->c_connid, -1,
  1190. SLAPD_DISCONNECT_POLL, EPIPE );
  1191. }
  1192. }
  1193. else if (( idletimeout = compute_idletimeout(
  1194. slapdFrontendConfig, c )) > 0 &&
  1195. (curtime - c->c_idlesince) >= idletimeout &&
  1196. NULL == c->c_ops )
  1197. {
  1198. /* idle timeout */
  1199. disconnect_server_nomutex( c, c->c_connid, -1,
  1200. SLAPD_DISCONNECT_IDLE_TIMEOUT, EAGAIN );
  1201. }
  1202. }
  1203. PR_Unlock( c->c_mutex );
  1204. }
  1205. }
  1206. #endif
  1207. }
  1208. /*
  1209. * wrapper functions required so we can implement ioblock_timeout and
  1210. * avoid blocking forever.
  1211. */
  1212. #define SLAPD_POLLIN 0
  1213. #define SLAPD_POLLOUT 1
  1214. /* Return 1 if the given handle is ready for input or output,
  1215. * or if it becomes ready within g_ioblock_timeout [msec].
  1216. * Return -1 if handle is not ready and g_ioblock_timeout > 0,
  1217. * or something goes seriously wrong. Otherwise, return 0.
  1218. * If -1 is returned, PR_GetError() explains why.
  1219. * Revision: handle changed to void * to allow 64bit support
  1220. */
  1221. static int
  1222. slapd_poll( void *handle, int output, int secure )
  1223. {
  1224. int rc;
  1225. int ioblock_timeout = config_get_ioblocktimeout();
  1226. #if defined( XP_WIN32 )
  1227. if( !secure ) {
  1228. fd_set handle_set;
  1229. struct timeval timeout;
  1230. int windows_handle = (int) handle;
  1231. memset (&timeout, 0, sizeof(timeout));
  1232. if (ioblock_timeout > 0) {
  1233. timeout.tv_sec = ioblock_timeout / 1000;
  1234. timeout.tv_usec = (ioblock_timeout % 1000) * 1000;
  1235. }
  1236. FD_ZERO(&handle_set);
  1237. FD_SET(windows_handle, &handle_set);
  1238. rc = output ? select(FD_SETSIZE, NULL, &handle_set, NULL, &timeout)
  1239. : select(FD_SETSIZE, &handle_set, NULL, NULL, &timeout);
  1240. } else {
  1241. struct POLL_STRUCT pr_pd;
  1242. PRIntervalTime timeout = PR_MillisecondsToInterval( ioblock_timeout );
  1243. if (timeout < 0) timeout = 0;
  1244. pr_pd.fd = (PRFileDesc *)handle;
  1245. pr_pd.in_flags = output ? PR_POLL_WRITE : PR_POLL_READ;
  1246. pr_pd.out_flags = 0;
  1247. rc = POLL_FN(&pr_pd, 1, timeout);
  1248. }
  1249. #else
  1250. struct POLL_STRUCT pr_pd;
  1251. PRIntervalTime timeout = PR_MillisecondsToInterval(ioblock_timeout);
  1252. if (timeout < 0) timeout = 0;
  1253. pr_pd.fd = (PRFileDesc *)handle;
  1254. pr_pd.in_flags = output ? PR_POLL_WRITE : PR_POLL_READ;
  1255. pr_pd.out_flags = 0;
  1256. rc = POLL_FN(&pr_pd, 1, timeout);
  1257. #endif
  1258. if (rc < 0) {
  1259. #if defined( XP_WIN32 )
  1260. if( !secure ) {
  1261. int oserr = errno;
  1262. LDAPDebug(LDAP_DEBUG_CONNS, "slapd_poll(%d) error %d (%s)\n",
  1263. handle, oserr, slapd_system_strerror(oserr));
  1264. if ( SLAPD_SYSTEM_WOULD_BLOCK_ERROR(oserr)) {
  1265. rc = 0; /* try again */
  1266. }
  1267. } else {
  1268. PRErrorCode prerr = PR_GetError();
  1269. LDAPDebug(LDAP_DEBUG_CONNS, "slapd_poll(%d) "
  1270. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1271. handle, prerr, slapd_pr_strerror(prerr));
  1272. if ( prerr == PR_PENDING_INTERRUPT_ERROR ||
  1273. SLAPD_PR_WOULD_BLOCK_ERROR(prerr)) {
  1274. rc = 0; /* try again */
  1275. }
  1276. }
  1277. #else
  1278. PRErrorCode prerr = PR_GetError();
  1279. LDAPDebug(LDAP_DEBUG_ANY, "slapd_poll(%d) "
  1280. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1281. handle, prerr, slapd_pr_strerror(prerr));
  1282. if ( prerr == PR_PENDING_INTERRUPT_ERROR ||
  1283. SLAPD_PR_WOULD_BLOCK_ERROR(prerr)) {
  1284. rc = 0; /* try again */
  1285. }
  1286. #endif
  1287. } else if (rc == 0 && ioblock_timeout > 0) {
  1288. PRIntn ihandle;
  1289. #if !defined( XP_WIN32 )
  1290. ihandle = PR_FileDesc2NativeHandle((PRFileDesc *)handle);
  1291. #else
  1292. if( secure )
  1293. ihandle = PR_FileDesc2NativeHandle((PRFileDesc *)handle);
  1294. else
  1295. ihandle = (PRIntn)handle;
  1296. #endif
  1297. LDAPDebug(LDAP_DEBUG_ANY, "slapd_poll(%d) timed out\n",
  1298. ihandle, 0, 0);
  1299. #if defined( XP_WIN32 )
  1300. /*
  1301. * Bug 624303 - This connection will be cleaned up soon.
  1302. * During cleanup (see connection_cleanup()), SSL3_SendAlert()
  1303. * will be called by PR_Close(), and its default wTimeout
  1304. * in sslSocket associated with the handle
  1305. * is no time out (I gave up after waited for 30 minutes).
  1306. * It was during this closing period that server won't
  1307. * response to new connection requests.
  1308. * PR_Send() null is a hack here to change the default wTimeout
  1309. * (see ssl_Send()) to one second which affects PR_Close()
  1310. * only in the current scenario.
  1311. */
  1312. if( secure ) {
  1313. PR_Send ((PRFileDesc *)handle, NULL, 0, 0, PR_SecondsToInterval(1));
  1314. }
  1315. #endif
  1316. PR_SetError(PR_IO_TIMEOUT_ERROR, EAGAIN); /* timeout */
  1317. rc = -1;
  1318. }
  1319. return rc;
  1320. }
  1321. /* The following 4 functions each read or write count bytes from or to
  1322. * a socket handle. If all goes well, they return the same count;
  1323. * otherwise they return -1 and PR_GetError() explains the problem.
  1324. * Revision: handle changed to struct lextiof_socket_private * and first
  1325. * argument which used to be handle is now ignored.
  1326. */
  1327. int
  1328. secure_read_function( int ignore, void *buffer, int count, struct lextiof_socket_private *handle )
  1329. {
  1330. int gotbytes = 0;
  1331. int bytes;
  1332. int ioblock_timeout = config_get_ioblocktimeout();
  1333. PRIntervalTime pr_timeout = PR_MillisecondsToInterval(ioblock_timeout);
  1334. if (handle == SLAPD_INVALID_SOCKET) {
  1335. PR_SetError(PR_NOT_SOCKET_ERROR, EBADF);
  1336. } else {
  1337. while (1) {
  1338. bytes = PR_Recv( (PRFileDesc *)handle, (char *)buffer + gotbytes,
  1339. count - gotbytes, 0, pr_timeout );
  1340. if (bytes > 0) {
  1341. gotbytes += bytes;
  1342. } else if (bytes < 0) {
  1343. PRErrorCode prerr = PR_GetError();
  1344. #ifdef _WIN32
  1345. /* we need to do this because on NT, once an I/O
  1346. times out on an NSPR socket, that socket must
  1347. be closed before any other I/O can happen in
  1348. this thread.
  1349. */
  1350. if (prerr == PR_IO_TIMEOUT_ERROR){
  1351. Connection *conn = connection_table_get_connection_from_fd(the_connection_table,(PRFileDesc *)handle);
  1352. if (conn == NULL)
  1353. return -1;
  1354. disconnect_server (conn, conn->c_connid, -1, SLAPD_DISCONNECT_NTSSL_TIMEOUT, 0);
  1355. /* Disconnect_server just tells the poll thread that the
  1356. * socket should be closed. We'll sleep 2 seconds here to
  1357. * to make sure that the poll thread has time to run
  1358. * and close this socket. */
  1359. DS_Sleep(PR_SecondsToInterval(2));
  1360. LDAPDebug(LDAP_DEBUG_CONNS, "SSL PR_Recv(%d) "
  1361. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1362. handle, prerr, slapd_pr_strerror(prerr));
  1363. return -1;
  1364. }
  1365. #endif
  1366. LDAPDebug(LDAP_DEBUG_CONNS,
  1367. "SSL PR_Recv(%d) error %d (%s)\n",
  1368. handle, prerr, slapd_pr_strerror(prerr));
  1369. if ( !SLAPD_PR_WOULD_BLOCK_ERROR(prerr) ) {
  1370. break; /* fatal error */
  1371. }
  1372. } else if (gotbytes < count) {
  1373. LDAPDebug(LDAP_DEBUG_CONNS,
  1374. "SSL PR_Recv(%d) 0 (EOF)\n", /* disconnected */
  1375. handle, 0, 0);
  1376. PR_SetError(PR_PIPE_ERROR, EPIPE);
  1377. break;
  1378. }
  1379. if (gotbytes == count) { /* success */
  1380. return count;
  1381. } else if (gotbytes > count) { /* too many bytes */
  1382. PR_SetError(PR_BUFFER_OVERFLOW_ERROR, EMSGSIZE);
  1383. break;
  1384. } else if (slapd_poll(handle, SLAPD_POLLIN, 1) < 0) { /* error */
  1385. break;
  1386. }
  1387. }
  1388. }
  1389. return -1;
  1390. }
  1391. /*
  1392. * Revision: handle changed to struct lextiof_socket_private * and first
  1393. * argument which used to be handle is now ignored.
  1394. */
  1395. int
  1396. secure_write_function( int ignore, const void *buffer, int count, struct lextiof_socket_private *handle )
  1397. {
  1398. int sentbytes = 0;
  1399. int bytes;
  1400. if (handle == SLAPD_INVALID_SOCKET) {
  1401. PR_SetError(PR_NOT_SOCKET_ERROR, EBADF);
  1402. } else {
  1403. while (1) {
  1404. if (slapd_poll(handle, SLAPD_POLLOUT, 1) < 0) { /* error */
  1405. break;
  1406. }
  1407. bytes = PR_Write((PRFileDesc *)handle, (char *)buffer + sentbytes,
  1408. count - sentbytes);
  1409. if (bytes > 0) {
  1410. sentbytes += bytes;
  1411. } else if (bytes < 0) {
  1412. PRErrorCode prerr = PR_GetError();
  1413. LDAPDebug(LDAP_DEBUG_CONNS, "SSL PR_Write(%d) "
  1414. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1415. handle, prerr, slapd_pr_strerror( prerr ));
  1416. if ( !SLAPD_PR_WOULD_BLOCK_ERROR(prerr)) {
  1417. break; /* fatal error */
  1418. }
  1419. } else if (sentbytes < count) {
  1420. LDAPDebug( LDAP_DEBUG_CONNS,
  1421. "SSL PR_Write(%d) 0\n", /* ??? */ handle, 0, 0);
  1422. PR_SetError(PR_PIPE_ERROR, EPIPE);
  1423. break;
  1424. }
  1425. if (sentbytes == count) { /* success */
  1426. return count;
  1427. } else if (sentbytes > count) { /* too many bytes */
  1428. PR_SetError(PR_BUFFER_OVERFLOW_ERROR, EMSGSIZE);
  1429. break;
  1430. }
  1431. }
  1432. }
  1433. return -1;
  1434. }
  1435. /* stub functions required because we need to call send/recv on NT,
  1436. * but the SDK requires functions with a read/write signature.
  1437. * Revision: handle changed to struct lextiof_socket_private * and first
  1438. * argument which used to be handle is now ignored.
  1439. */
  1440. int
  1441. read_function(int ignore, void *buffer, int count, struct lextiof_socket_private *handle )
  1442. {
  1443. int gotbytes = 0;
  1444. int bytes;
  1445. #if !defined( XP_WIN32 )
  1446. PRIntervalTime pr_timeout = PR_MillisecondsToInterval(1000);
  1447. #endif
  1448. if (handle == SLAPD_INVALID_SOCKET) {
  1449. PR_SetError(PR_NOT_SOCKET_ERROR, EBADF);
  1450. } else {
  1451. while (1) {
  1452. #if !defined( XP_WIN32 )
  1453. bytes = PR_Recv((PRFileDesc *)handle, (char *)buffer + gotbytes,
  1454. count - gotbytes, 0, pr_timeout);
  1455. #else
  1456. bytes = recv((int)handle, (char *)buffer + gotbytes,
  1457. count - gotbytes, 0);
  1458. #endif
  1459. if (bytes > 0) {
  1460. gotbytes += bytes;
  1461. } else if (bytes < 0) {
  1462. #if !defined( XP_WIN32 )
  1463. PRErrorCode prerr = PR_GetError();
  1464. LDAPDebug(LDAP_DEBUG_CONNS, "PR_Recv(%d) "
  1465. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1466. handle, prerr, slapd_pr_strerror( prerr ));
  1467. if ( !SLAPD_PR_WOULD_BLOCK_ERROR(prerr)) {
  1468. #else
  1469. int oserr = errno;
  1470. LDAPDebug(LDAP_DEBUG_CONNS, "recv(%d) OS error %d (%s)\n",
  1471. handle, oserr, slapd_system_strerror(oserr));
  1472. if ( !SLAPD_SYSTEM_WOULD_BLOCK_ERROR(oserr)) {
  1473. PR_SetError(PR_UNKNOWN_ERROR, oserr);
  1474. #endif
  1475. break; /* fatal error */
  1476. }
  1477. } else if (gotbytes < count) { /* disconnected */
  1478. #if !defined( XP_WIN32 )
  1479. LDAPDebug(LDAP_DEBUG_CONNS, "PR_Recv(%d) 0 (EOF)\n",
  1480. handle, 0, 0);
  1481. #else
  1482. LDAPDebug(LDAP_DEBUG_CONNS, "recv(%d) 0 (EOF)\n",
  1483. handle, 0, 0);
  1484. #endif
  1485. PR_SetError(PR_PIPE_ERROR, EPIPE);
  1486. break;
  1487. }
  1488. if (gotbytes == count) { /* success */
  1489. return count;
  1490. } else if (gotbytes > count) { /* too many bytes */
  1491. PR_SetError(PR_BUFFER_OVERFLOW_ERROR, EMSGSIZE);
  1492. break;
  1493. }
  1494. /* we did not get the whole PDU
  1495. * call slapd_poll before starting a new read to get
  1496. * sure some new data have been received and
  1497. * thus avoid active looping in the while
  1498. */
  1499. if (slapd_poll(handle, SLAPD_POLLIN, 0) < 0) {
  1500. break;
  1501. }
  1502. }
  1503. }
  1504. return -1;
  1505. }
  1506. /*
  1507. Slapd's old (3.x) network I/O code works something like this:
  1508. when I want to send some data to the client, I will call send().
  1509. That might block for a long time, resulting in thread pool starvation,
  1510. so let's not call it unless we're sure that data can be buffered
  1511. locally. The mechanism for achieving this is to call select()
  1512. (poll() on UNIX), on the target socket, passing a short timeout
  1513. (configurable via cn=config).
  1514. Now, this means that to send some data we're making two system
  1515. calls. Slowness results.
  1516. I did some research and found the following in the MSDN
  1517. that NT4.0 and beyond do support the configuration of a send timeout
  1518. on sockets, so this is code which makes use of that and saves the
  1519. call to select.
  1520. */
  1521. /*Revision: handle changed from int to void * to allow 64bit support
  1522. *
  1523. */
  1524. static int send_with_timeout(void *handle, const char * buffer, int count,int *bytes_sent)
  1525. {
  1526. int ret = 0;
  1527. #if defined( XP_WIN32 )
  1528. *bytes_sent = send((SOCKET)handle, buffer,count,0);
  1529. #else
  1530. *bytes_sent = PR_Write((PRFileDesc *)handle,buffer,count);
  1531. if (*bytes_sent < 0)
  1532. {
  1533. PRErrorCode prerr = PR_GetError();
  1534. if (SLAPD_PR_WOULD_BLOCK_ERROR(prerr))
  1535. {
  1536. if ((ret = slapd_poll(handle, SLAPD_POLLOUT, 0)) < 0)
  1537. { /* error */
  1538. *bytes_sent = 0;
  1539. return ret;
  1540. }
  1541. }
  1542. }
  1543. #endif
  1544. return ret;
  1545. }
  1546. int
  1547. write_function(int ignore, const void *buffer, int count, struct lextiof_socket_private *handle)
  1548. {
  1549. int sentbytes = 0;
  1550. int bytes;
  1551. if (handle == SLAPD_INVALID_SOCKET) {
  1552. PR_SetError(PR_NOT_SOCKET_ERROR, EBADF);
  1553. } else {
  1554. while (1) {
  1555. if (send_with_timeout(handle, (char *)buffer + sentbytes, count - sentbytes,&bytes) < 0) { /* error */
  1556. break;
  1557. }
  1558. if (bytes > 0) {
  1559. sentbytes += bytes;
  1560. } else if (bytes < 0) {
  1561. #if !defined( XP_WIN32 )
  1562. PRErrorCode prerr = PR_GetError();
  1563. LDAPDebug(LDAP_DEBUG_CONNS, "PR_Write(%d) "
  1564. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1565. handle, prerr, slapd_pr_strerror(prerr));
  1566. if ( !SLAPD_PR_WOULD_BLOCK_ERROR(prerr)) {
  1567. #else
  1568. int oserr = errno; /* DBDB this is almost certainly wrong, should be a call to WSAGetLastError() */
  1569. LDAPDebug(LDAP_DEBUG_CONNS, "send(%d) error %d (%s)\n",
  1570. handle, oserr, slapd_system_strerror(oserr));
  1571. if ( !SLAPD_SYSTEM_WOULD_BLOCK_ERROR(oserr)) {
  1572. PR_SetError(PR_UNKNOWN_ERROR, oserr);
  1573. #endif
  1574. break; /* fatal error */
  1575. }
  1576. } else if (sentbytes < count) {
  1577. LDAPDebug(LDAP_DEBUG_CONNS, "send(%d) 0\n", /* ??? */
  1578. handle, 0, 0);
  1579. PR_SetError(PR_PIPE_ERROR, EPIPE);
  1580. break;
  1581. }
  1582. if (sentbytes == count) { /* success */
  1583. return count;
  1584. } else if (sentbytes > count) { /* too many bytes */
  1585. PR_SetError(PR_BUFFER_OVERFLOW_ERROR, EMSGSIZE);
  1586. break;
  1587. }
  1588. }
  1589. }
  1590. return -1;
  1591. }
  1592. int connection_type = -1; /* The type number assigned by the Factory for 'Connection' */
  1593. void
  1594. daemon_register_connection()
  1595. {
  1596. if(connection_type==-1)
  1597. {
  1598. /* The factory is given the name of the object type, in
  1599. * return for a type handle. Whenever the object is created
  1600. * or destroyed the factory is called with the handle so
  1601. * that it may call the constructors or destructors registered
  1602. * with it.
  1603. */
  1604. connection_type= factory_register_type(SLAPI_EXT_CONNECTION,offsetof(Connection,c_extension));
  1605. }
  1606. }
  1607. /* NOTE: this routine is not reentrant */
  1608. static int
  1609. handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, int secure)
  1610. {
  1611. int ns = 0;
  1612. Connection *conn = NULL;
  1613. /* struct sockaddr_in from;*/
  1614. PRNetAddr from;
  1615. PRFileDesc *pr_clonefd = NULL;
  1616. if ( (ns = accept_and_configure( tcps, pr_acceptfd, &from,
  1617. sizeof(from), secure, &pr_clonefd)) == SLAPD_INVALID_SOCKET ) {
  1618. return -1;
  1619. }
  1620. /* get a new Connection from the Connection Table */
  1621. conn= connection_table_get_connection(ct,ns);
  1622. if(conn==NULL)
  1623. {
  1624. PR_Close(pr_acceptfd);
  1625. return -1;
  1626. }
  1627. PR_Lock( conn->c_mutex );
  1628. #if !defined( XP_WIN32 )
  1629. ber_sockbuf_set_option(conn->c_sb,LBER_SOCKBUF_OPT_DESC,&pr_clonefd);
  1630. #else
  1631. if( !secure )
  1632. ber_sockbuf_set_option(conn->c_sb,LBER_SOCKBUF_OPT_DESC,&ns);
  1633. else
  1634. ber_sockbuf_set_option(conn->c_sb,LBER_SOCKBUF_OPT_DESC,&pr_clonefd);
  1635. #endif
  1636. conn->c_sd = ns;
  1637. conn->c_prfd = pr_clonefd;
  1638. conn->c_flags &= ~CONN_FLAG_CLOSING;
  1639. /* Store the fact that this new connection is an SSL connection */
  1640. if (secure) {
  1641. conn->c_flags |= CONN_FLAG_SSL;
  1642. }
  1643. #ifndef _WIN32
  1644. /*
  1645. * clear the "returned events" field in ns' slot within the poll fds
  1646. * array so that handle_read_ready() doesn't look at out_flags for an
  1647. * old connection by mistake and do something bad such as close the
  1648. * connection we just accepted.
  1649. */
  1650. /* Dont have to worry about this now because of our mapping from
  1651. * the connection table to the fds array. This new connection
  1652. * won't have a mapping. */
  1653. /* fds[ns].out_flags = 0; */
  1654. #endif
  1655. if (secure) {
  1656. /*structure added to enable 64bit support changed from
  1657. *the commented code that follows each of the next two
  1658. *blocks of code
  1659. */
  1660. struct lber_x_ext_io_fns func_pointers;
  1661. memset(&func_pointers, 0, sizeof(func_pointers));
  1662. func_pointers.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
  1663. func_pointers.lbextiofn_read = secure_read_function;
  1664. func_pointers.lbextiofn_write = secure_write_function;
  1665. func_pointers.lbextiofn_writev = NULL;
  1666. func_pointers.lbextiofn_socket_arg = (struct lextiof_socket_private *) pr_clonefd;
  1667. ber_sockbuf_set_option( conn->c_sb,
  1668. LBER_SOCKBUF_OPT_EXT_IO_FNS, &func_pointers);
  1669. /* changed here by Cheston
  1670. ber_sockbuf_set_option( conn->c_sb,
  1671. LBER_SOCKBUF_OPT_READ_FN, (void *)secure_read_function );
  1672. ber_sockbuf_set_option( conn->c_sb,
  1673. LBER_SOCKBUF_OPT_WRITE_FN, (void *)secure_write_function );
  1674. */
  1675. } else {
  1676. struct lber_x_ext_io_fns func_pointers;
  1677. memset(&func_pointers, 0, sizeof(func_pointers));
  1678. func_pointers.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
  1679. func_pointers.lbextiofn_read = read_function;
  1680. func_pointers.lbextiofn_write = write_function;
  1681. func_pointers.lbextiofn_writev = NULL;
  1682. #ifdef _WIN32
  1683. func_pointers.lbextiofn_socket_arg = (struct lextiof_socket_private *) ns;
  1684. #else
  1685. func_pointers.lbextiofn_socket_arg = (struct lextiof_socket_private *) pr_clonefd;
  1686. #endif
  1687. ber_sockbuf_set_option( conn->c_sb,
  1688. LBER_SOCKBUF_OPT_EXT_IO_FNS, &func_pointers);
  1689. /*
  1690. ber_sockbuf_set_option( conn->c_sb,
  1691. LBER_SOCKBUF_OPT_READ_FN, (void *)read_function );
  1692. ber_sockbuf_set_option( conn->c_sb,
  1693. LBER_SOCKBUF_OPT_WRITE_FN, (void *)write_function );
  1694. */
  1695. }
  1696. #if defined(NET_SSL)
  1697. if( secure && config_get_SSLclientAuth() != SLAPD_SSLCLIENTAUTH_OFF ) {
  1698. /* Prepare to handle the client's certificate (if any): */
  1699. int rv;
  1700. rv = slapd_ssl_handshakeCallback (conn->c_prfd, (void*)handle_handshake_done, conn);
  1701. if (rv < 0) {
  1702. PRErrorCode prerr = PR_GetError();
  1703. LDAPDebug (LDAP_DEBUG_ANY, "SSL_HandshakeCallback() %d "
  1704. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  1705. rv, prerr, slapd_pr_strerror( prerr ));
  1706. }
  1707. rv = slapd_ssl_badCertHook (conn->c_prfd, (void*)handle_bad_certificate, conn);
  1708. if (rv < 0) {
  1709. PRErrorCode prerr = PR_GetError();
  1710. LDAPDebug (LDAP_DEBUG_ANY, "SSL_BadCertHook(%i) %i "
  1711. SLAPI_COMPONENT_NAME_NSPR " error %d\n",
  1712. conn->c_sd, rv, prerr);
  1713. }
  1714. }
  1715. #endif
  1716. connection_reset(conn, ns, &from, sizeof(from), secure);
  1717. /* Call the plugin extension constructors */
  1718. conn->c_extension = factory_create_extension(connection_type,conn,NULL /* Parent */);
  1719. /* Add this connection slot to the doubly linked list of active connections. This
  1720. * list is used to find the connections that should be used in the poll call. This
  1721. * connection will be added directly after slot 0 which serves as the head of the list */
  1722. if ( conn != NULL && conn->c_next == NULL && conn->c_prev == NULL )
  1723. {
  1724. /* Now give the new connection to the connection code */
  1725. connection_table_move_connection_on_to_active_list(the_connection_table,conn);
  1726. }
  1727. PR_Unlock( conn->c_mutex );
  1728. connection_new_private(conn);
  1729. g_increment_current_conn_count();
  1730. return 0;
  1731. }
  1732. static int init_shutdown_detect()
  1733. {
  1734. #ifdef _WIN32
  1735. PRThread *service_exit_wait_tid;
  1736. #else
  1737. /* First of all, we must reset the signal mask to get rid of any blockages
  1738. * the process may have inherited from its parent (such as the console), which
  1739. * might result in the process not delivering those blocked signals, and thus,
  1740. * misbehaving....
  1741. */
  1742. {
  1743. int rc;
  1744. sigset_t proc_mask;
  1745. LDAPDebug( LDAP_DEBUG_TRACE, "Reseting signal mask....\n", 0, 0, 0);
  1746. (void)sigemptyset( &proc_mask );
  1747. rc = pthread_sigmask( SIG_SETMASK, &proc_mask, NULL );
  1748. LDAPDebug( LDAP_DEBUG_TRACE, " %s \n",
  1749. rc ? "Failed to reset signal mask":"....Done (signal mask reset)!!", 0, 0 );
  1750. }
  1751. #endif
  1752. #ifdef _WIN32
  1753. /* Create a thread to wait on the Win32 event which will
  1754. be signalled by the watchdog when the Service is
  1755. being halted. */
  1756. service_exit_wait_tid = PR_CreateThread( PR_USER_THREAD,
  1757. (VFP) (void *) slapd_service_exit_wait, (void *) NULL,
  1758. PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
  1759. SLAPD_DEFAULT_THREAD_STACKSIZE);
  1760. if( service_exit_wait_tid == NULL ) {
  1761. LDAPDebug( LDAP_DEBUG_ANY,
  1762. "Error: PR_CreateThread(slapd_service_exit_wait) failed\n", 0, 0, 0 );
  1763. }
  1764. #elif defined ( HPUX10 )
  1765. PR_CreateThread ( PR_USER_THREAD,
  1766. catch_signals,
  1767. NULL,
  1768. PR_PRIORITY_NORMAL,
  1769. PR_GLOBAL_THREAD,
  1770. PR_UNJOINABLE_THREAD,
  1771. SLAPD_DEFAULT_THREAD_STACKSIZE);
  1772. #else
  1773. #ifdef HPUX11
  1774. /* In the optimized builds for HPUX, the signal handler doesn't seem
  1775. * to get set correctly unless the primordial thread gets a chance
  1776. * to run before we make the call to SIGNAL. (At this point the
  1777. * the primordial thread has spawned the daemon thread which called
  1778. * this function.) The call to DS_Sleep will give the primordial
  1779. * thread a chance to run.
  1780. */
  1781. DS_Sleep(0);
  1782. #endif
  1783. (void) SIGNAL( SIGPIPE, SIG_IGN );
  1784. (void) SIGNAL( SIGCHLD, slapd_wait4child );
  1785. #ifndef LINUX
  1786. /* linux uses USR1/USR2 for thread synchronization, so we aren't
  1787. * allowed to mess with those.
  1788. */
  1789. (void) SIGNAL( SIGUSR1, slapd_do_nothing );
  1790. (void) SIGNAL( SIGUSR2, set_shutdown );
  1791. #endif
  1792. (void) SIGNAL( SIGTERM, set_shutdown );
  1793. (void) SIGNAL( SIGHUP, set_shutdown );
  1794. #endif /* _WIN32 */
  1795. return 0;
  1796. }
  1797. #if defined( XP_WIN32 )
  1798. static void
  1799. unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, int n_tcps, PRFileDesc *s_tcps)
  1800. #else
  1801. static void
  1802. unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, PRFileDesc *n_tcps, PRFileDesc *s_tcps)
  1803. #endif
  1804. {
  1805. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  1806. char addrbuf[ 256 ];
  1807. if ( ct->size <= slapdFrontendConfig->reservedescriptors ) {
  1808. #ifdef _WIN32
  1809. LDAPDebug( LDAP_DEBUG_ANY,
  1810. "ERROR: Not enough descriptors to accept any connections. "
  1811. "This may be because the maxdescriptors configuration "
  1812. "directive is too small, or the reservedescriptors "
  1813. "configuration directive is too large. "
  1814. "Try increasing the number of descriptors available to "
  1815. "the slapd process. The current value is %d. %d "
  1816. "descriptors are currently reserved for internal "
  1817. "slapd use, so the total number of descriptors available "
  1818. "to the process must be greater than %d.\n",
  1819. ct->size, slapdFrontendConfig->reservedescriptors, slapdFrontendConfig->reservedescriptors );
  1820. #else /* _WIN32 */
  1821. LDAPDebug( LDAP_DEBUG_ANY,
  1822. "ERROR: Not enough descriptors to accept any connections. "
  1823. "This may be because the maxdescriptors configuration "
  1824. "directive is too small, the hard limit on descriptors is "
  1825. "too small (see limit(1)), or the reservedescriptors "
  1826. "configuration directive is too large. "
  1827. "Try increasing the number of descriptors available to "
  1828. "the slapd process. The current value is %d. %d "
  1829. "descriptors are currently reserved for internal "
  1830. "slapd use, so the total number of descriptors available "
  1831. "to the process must be greater than %d.\n",
  1832. ct->size, slapdFrontendConfig->reservedescriptors, slapdFrontendConfig->reservedescriptors );
  1833. #endif /* _WIN32 */
  1834. exit( 1 );
  1835. }
  1836. /*
  1837. * This final startup message gives a definite signal to the admin
  1838. * program that the server is up. It must contain the string
  1839. * "slapd started." because some of the administrative programs
  1840. * depend on this. See ldap/admin/lib/dsalib_updown.c.
  1841. */
  1842. #if !defined( XP_WIN32 )
  1843. if ( n_tcps != NULL ) { /* standard LDAP */
  1844. #else
  1845. if ( n_tcps != SLAPD_INVALID_SOCKET ) { /* standard LDAP */
  1846. #endif
  1847. LDAPDebug( LDAP_DEBUG_ANY,
  1848. "slapd started. Listening on %s port %d for LDAP requests\n",
  1849. netaddr2string(&ports->n_listenaddr, addrbuf, sizeof(addrbuf)),
  1850. ports->n_port, 0 );
  1851. }
  1852. if ( s_tcps != NULL ) { /* LDAP over SSL; separate port */
  1853. LDAPDebug( LDAP_DEBUG_ANY,
  1854. "Listening on %s port %d for LDAPS requests\n",
  1855. netaddr2string(&ports->s_listenaddr, addrbuf, sizeof(addrbuf)),
  1856. ports->s_port, 0 );
  1857. }
  1858. }
  1859. #if defined( _WIN32 )
  1860. /* On Windows, we signal the SCM when we're ready to accept connections */
  1861. static int
  1862. write_pid_file()
  1863. {
  1864. if( SlapdIsAService() )
  1865. {
  1866. /* Initialization complete and successful. Set service to running */
  1867. LDAPServerStatus.dwCurrentState = SERVICE_RUNNING;
  1868. LDAPServerStatus.dwCheckPoint = 0;
  1869. LDAPServerStatus.dwWaitHint = 0;
  1870. if (!SetServiceStatus(hLDAPServerServiceStatus, &LDAPServerStatus)) {
  1871. ReportSlapdEvent(EVENTLOG_INFORMATION_TYPE, MSG_SERVER_START_FAILED, 1,
  1872. "Could not set Service status.");
  1873. exit(1);
  1874. }
  1875. }
  1876. ReportSlapdEvent(EVENTLOG_INFORMATION_TYPE, MSG_SERVER_STARTED, 0, NULL );
  1877. return 0;
  1878. }
  1879. #else /* WIN32 */
  1880. /* On UNIX, we create a file with our PID in it */
  1881. static int
  1882. write_pid_file()
  1883. {
  1884. FILE *fp = NULL;
  1885. /*
  1886. * The following section of code is closely coupled with the
  1887. * admin programs. Please do not make changes here without
  1888. * consulting the start/stop code for the admin code.
  1889. */
  1890. if ( (fp = fopen( get_pid_file(), "w" )) != NULL ) {
  1891. fprintf( fp, "%d\n", getpid() );
  1892. fclose( fp );
  1893. return 0;
  1894. } else
  1895. {
  1896. return -1;
  1897. }
  1898. }
  1899. #endif /* WIN32 */
  1900. static void
  1901. set_shutdown (int sig)
  1902. {
  1903. /* don't log anything from a signal handler:
  1904. * you could be holding a lock when the signal was trapped. more
  1905. * specifically, you could be holding the logfile lock (and deadlock
  1906. * yourself).
  1907. */
  1908. #if 0
  1909. LDAPDebug( LDAP_DEBUG_ANY, "slapd got shutdown signal\n", 0, 0, 0 );
  1910. #endif
  1911. g_set_shutdown( SLAPI_SHUTDOWN_SIGNAL );
  1912. #ifndef _WIN32
  1913. #ifndef LINUX
  1914. /* don't mess with USR1/USR2 on linux, used by libpthread */
  1915. (void) SIGNAL( SIGUSR2, set_shutdown );
  1916. #endif
  1917. (void) SIGNAL( SIGTERM, set_shutdown );
  1918. (void) SIGNAL( SIGHUP, set_shutdown );
  1919. #endif
  1920. }
  1921. #ifndef LINUX
  1922. void
  1923. slapd_do_nothing (int sig)
  1924. {
  1925. /* don't log anything from a signal handler:
  1926. * you could be holding a lock when the signal was trapped. more
  1927. * specifically, you could be holding the logfile lock (and deadlock
  1928. * yourself).
  1929. */
  1930. #if 0
  1931. LDAPDebug( LDAP_DEBUG_TRACE, "slapd got SIGUSR1\n", 0, 0, 0 );
  1932. #endif
  1933. #ifndef _WIN32
  1934. (void) SIGNAL( SIGUSR1, slapd_do_nothing );
  1935. #endif
  1936. #if 0
  1937. /*
  1938. * Actually do a little more: dump the conn struct and
  1939. * send it to a tmp file
  1940. */
  1941. connection_table_dump(connection_table);
  1942. #endif
  1943. }
  1944. #endif /* LINUX */
  1945. #ifndef _WIN32
  1946. void
  1947. slapd_wait4child(int sig)
  1948. {
  1949. WAITSTATUSTYPE status;
  1950. /* don't log anything from a signal handler:
  1951. * you could be holding a lock when the signal was trapped. more
  1952. * specifically, you could be holding the logfile lock (and deadlock
  1953. * yourself).
  1954. */
  1955. #if 0
  1956. LDAPDebug( LDAP_DEBUG_ARGS, "listener: catching SIGCHLD\n", 0, 0, 0 );
  1957. #endif
  1958. #ifdef USE_WAITPID
  1959. while (waitpid ((pid_t) -1, 0, WAIT_FLAGS) > 0)
  1960. #else /* USE_WAITPID */
  1961. while ( wait3( &status, WAIT_FLAGS, 0 ) > 0 )
  1962. #endif /* USE_WAITPID */
  1963. ; /* NULL */
  1964. (void) SIGNAL( SIGCHLD, slapd_wait4child );
  1965. }
  1966. #endif
  1967. #ifdef XP_WIN32
  1968. static int
  1969. createlistensocket(unsigned short port, const PRNetAddr *listenaddr)
  1970. {
  1971. int tcps;
  1972. struct sockaddr_in addr;
  1973. char *logname = "createlistensocket";
  1974. char addrbuf[ 256 ];
  1975. if (!port) goto suppressed;
  1976. PR_ASSERT( listenaddr != NULL );
  1977. /* create TCP socket */
  1978. if ((tcps = socket(AF_INET, SOCK_STREAM, 0))
  1979. == SLAPD_INVALID_SOCKET) {
  1980. int oserr = errno;
  1981. slapi_log_error(SLAPI_LOG_FATAL, logname,
  1982. "socket() failed: OS error %d (%s)\n",
  1983. oserr, slapd_system_strerror( oserr ));
  1984. goto failed;
  1985. }
  1986. /* initialize listener address */
  1987. (void) memset( (void *) &addr, '\0', sizeof(addr) );
  1988. addr.sin_family = AF_INET;
  1989. addr.sin_port = htons( port );
  1990. if (listenaddr->raw.family == PR_AF_INET) {
  1991. addr.sin_addr.s_addr = listenaddr->inet.ip;
  1992. } else if (PR_IsNetAddrType(listenaddr,PR_IpAddrAny)) {
  1993. addr.sin_addr.s_addr = INADDR_ANY;
  1994. } else {
  1995. if (!PR_IsNetAddrType(listenaddr,PR_IpAddrV4Mapped)) {
  1996. /*
  1997. * When Win32 supports IPv6, we will be able to use IPv6
  1998. * addresses here. But not yet.
  1999. */
  2000. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2001. "unable to listen on %s port %d (IPv6 addresses "
  2002. "are not supported on this platform)\n",
  2003. netaddr2string(listenaddr, addrbuf, sizeof(addrbuf)),
  2004. port );
  2005. goto failed;
  2006. }
  2007. addr.sin_addr.s_addr = listenaddr->ipv6.ip.pr_s6_addr32[3];
  2008. }
  2009. LDAPDebug( LDAP_DEBUG_TRACE, "%s - binding to %s:%d\n",
  2010. logname, inet_ntoa( addr.sin_addr ), port )
  2011. if ( bind( tcps, (struct sockaddr *) &addr, sizeof(addr) ) == -1 ) {
  2012. int oserr = errno;
  2013. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2014. "bind() on %s port %d failed: OS error %d (%s)\n",
  2015. inet_ntoa( addr.sin_addr ), port, oserr,
  2016. slapd_system_strerror( oserr ));
  2017. goto failed;
  2018. }
  2019. return tcps;
  2020. failed:
  2021. WSACleanup();
  2022. exit( 1 );
  2023. suppressed:
  2024. return -1;
  2025. } /* createlistensocket */
  2026. #endif /* XP_WIN32 */
  2027. static PRFileDesc *
  2028. createprlistensocket(unsigned short port, const PRNetAddr *listenaddr,
  2029. int secure)
  2030. {
  2031. PRFileDesc *sock;
  2032. PRNetAddr sa_server;
  2033. PRErrorCode prerr = 0;
  2034. PRSocketOptionData pr_socketoption;
  2035. char addrbuf[ 256 ];
  2036. char *logname = "createprlistensocket";
  2037. if (!port) goto suppressed;
  2038. PR_ASSERT( listenaddr != NULL );
  2039. /* create TCP socket */
  2040. if ((sock = PR_OpenTCPSocket(PR_AF_INET6)) == SLAPD_INVALID_SOCKET) {
  2041. prerr = PR_GetError();
  2042. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2043. "PR_OpenTCPSocket(PR_AF_INET6) failed: %s error %d (%s)\n",
  2044. SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
  2045. goto failed;
  2046. }
  2047. pr_socketoption.option = PR_SockOpt_Reuseaddr;
  2048. pr_socketoption.value.reuse_addr = 1;
  2049. if ( PR_SetSocketOption(sock, &pr_socketoption ) == PR_FAILURE) {
  2050. prerr = PR_GetError();
  2051. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2052. "PR_SetSocketOption(PR_SockOpt_Reuseaddr) failed: %s error %d (%s)\n",
  2053. SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror( prerr ));
  2054. goto failed;
  2055. }
  2056. /* set up listener address, including port */
  2057. memcpy(&sa_server, listenaddr, sizeof(sa_server));
  2058. if ( PR_SetNetAddr(PR_IpAddrNull, PR_AF_INET6, port, &sa_server)
  2059. != PR_SUCCESS ) {
  2060. prerr = PR_GetError();
  2061. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2062. "PR_SetNetAddr() failed: %s error %d (%s)\n",
  2063. SLAPI_COMPONENT_NAME_NSPR,
  2064. prerr, slapd_pr_strerror(prerr));
  2065. goto failed;
  2066. }
  2067. if ( PR_Bind(sock, &sa_server) == PR_FAILURE) {
  2068. prerr = PR_GetError();
  2069. slapi_log_error(SLAPI_LOG_FATAL, logname,
  2070. "PR_Bind() on %s port %d failed: %s error %d (%s)\n",
  2071. netaddr2string(&sa_server, addrbuf, sizeof(addrbuf)), port,
  2072. SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
  2073. goto failed;
  2074. }
  2075. return( sock );
  2076. failed:
  2077. #ifdef XP_WIN32
  2078. WSACleanup();
  2079. #endif /* XP_WIN32 */
  2080. exit( 1 );
  2081. suppressed:
  2082. return (PRFileDesc *)-1;
  2083. } /* createprlistensocket */
  2084. /*
  2085. * Initialize the *addr structure based on listenhost.
  2086. * Returns: 0 if successful and -1 if not (after logging an error message).
  2087. */
  2088. int
  2089. slapd_listenhost2addr(const char *listenhost, PRNetAddr *addr)
  2090. {
  2091. char *logname = "slapd_listenhost2addr";
  2092. PRErrorCode prerr = 0;
  2093. PRHostEnt hent;
  2094. char hbuf[ PR_NETDB_BUF_SIZE ];
  2095. PR_ASSERT( addr != NULL );
  2096. if (NULL == listenhost) {
  2097. /* listen on all interfaces */
  2098. if ( PR_SUCCESS != PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, addr)) {
  2099. prerr = PR_GetError();
  2100. slapi_log_error( SLAPI_LOG_FATAL, logname,
  2101. "PR_SetNetAddr(PR_IpAddrAny) failed - %s error %d (%s)\n",
  2102. SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
  2103. goto failed;
  2104. }
  2105. } else if (PR_SUCCESS == PR_StringToNetAddr(listenhost, addr)) {
  2106. if (PR_AF_INET == PR_NetAddrFamily(addr)) {
  2107. PRUint32 ipv4ip = addr->inet.ip;
  2108. memset(addr, 0, sizeof(PRNetAddr));
  2109. PR_ConvertIPv4AddrToIPv6(ipv4ip, &addr->ipv6.ip);
  2110. addr->ipv6.family = PR_AF_INET6;
  2111. }
  2112. } else if (PR_SUCCESS == PR_GetIPNodeByName(listenhost,
  2113. PR_AF_INET6, PR_AI_DEFAULT | PR_AI_ALL,
  2114. hbuf, sizeof(hbuf), &hent )) {
  2115. /* just use the first IP address returned */
  2116. if (PR_EnumerateHostEnt(0, &hent, 0, addr) < 0) {
  2117. slapi_log_error( SLAPI_LOG_FATAL, logname,
  2118. "PR_EnumerateHostEnt() failed - %s error %d (%s)\n",
  2119. SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
  2120. goto failed;
  2121. }
  2122. } else { /* failure */
  2123. slapi_log_error( SLAPI_LOG_FATAL, logname,
  2124. "PR_GetIPNodeByName(%s) failed - %s error %d (%s)\n",
  2125. listenhost, SLAPI_COMPONENT_NAME_NSPR, prerr,
  2126. slapd_pr_strerror(prerr));
  2127. goto failed;
  2128. }
  2129. return( 0 );
  2130. failed:
  2131. return( -1 );
  2132. }
  2133. /*
  2134. * Map addr to a string equivalent and place the result in addrbuf.
  2135. */
  2136. static const char *
  2137. netaddr2string(const PRNetAddr *addr, char *addrbuf, size_t addrbuflen)
  2138. {
  2139. const char *retstr;
  2140. if (NULL == addr || PR_IsNetAddrType(addr, PR_IpAddrAny)) {
  2141. retstr = "All Interfaces";
  2142. } else if (PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
  2143. if ( addr->raw.family == PR_AF_INET6 &&
  2144. !PR_IsNetAddrType(addr, PR_IpAddrV4Mapped)) {
  2145. retstr = "IPv6 Loopback";
  2146. } else {
  2147. retstr = "Loopback";
  2148. }
  2149. } else if (PR_SUCCESS == PR_NetAddrToString( addr, addrbuf, addrbuflen)) {
  2150. if (0 == strncmp( addrbuf, "::ffff:", 7 )) {
  2151. /* IPv4 address mapped into IPv6 address space */
  2152. retstr = addrbuf + 7;
  2153. } else {
  2154. /* full blown IPv6 address */
  2155. retstr = addrbuf;
  2156. }
  2157. } else { /* punt */
  2158. retstr = "address conversion failed";
  2159. }
  2160. return(retstr);
  2161. }
  2162. static int
  2163. createsignalpipe( void )
  2164. {
  2165. #if defined( _WIN32 )
  2166. if ( PR_NewTCPSocketPair(&signalpipe[0])) {
  2167. PRErrorCode prerr = PR_GetError();
  2168. LDAPDebug( LDAP_DEBUG_ANY, "PR_CreatePipe() failed, "
  2169. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  2170. prerr, slapd_pr_strerror(prerr), SLAPD_DEFAULT_THREAD_STACKSIZE );
  2171. return( -1 );
  2172. }
  2173. writesignalpipe = PR_FileDesc2NativeHandle(signalpipe[1]);
  2174. readsignalpipe = PR_FileDesc2NativeHandle(signalpipe[0]);
  2175. #else
  2176. if ( PR_CreatePipe( &signalpipe[0], &signalpipe[1] ) != 0 ) {
  2177. PRErrorCode prerr = PR_GetError();
  2178. LDAPDebug( LDAP_DEBUG_ANY, "PR_CreatePipe() failed, "
  2179. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  2180. prerr, slapd_pr_strerror(prerr), SLAPD_DEFAULT_THREAD_STACKSIZE );
  2181. return( -1 );
  2182. }
  2183. writesignalpipe = PR_FileDesc2NativeHandle(signalpipe[1]);
  2184. readsignalpipe = PR_FileDesc2NativeHandle(signalpipe[0]);
  2185. fcntl(writesignalpipe, F_SETFD, O_NONBLOCK);
  2186. fcntl(readsignalpipe, F_SETFD, O_NONBLOCK);
  2187. #endif
  2188. return( 0 );
  2189. }
  2190. #ifdef HPUX10
  2191. #include <pthread.h> /* for sigwait */
  2192. /*
  2193. * Set up a thread to catch signals
  2194. * SIGUSR1 (ignore), SIGCHLD (call slapd_wait4child),
  2195. * SIGUSR2 (set slapd_shutdown), SIGTERM (set slapd_shutdown),
  2196. * SIGHUP (set slapd_shutdown)
  2197. */
  2198. static void *
  2199. catch_signals()
  2200. {
  2201. sigset_t caught_signals;
  2202. int sig;
  2203. sigemptyset( &caught_signals );
  2204. while ( !g_get_shutdown() ) {
  2205. /* Set the signals we're interested in catching */
  2206. sigaddset( &caught_signals, SIGUSR1 );
  2207. sigaddset( &caught_signals, SIGCHLD );
  2208. sigaddset( &caught_signals, SIGUSR2 );
  2209. sigaddset( &caught_signals, SIGTERM );
  2210. sigaddset( &caught_signals, SIGHUP );
  2211. (void)sigprocmask( SIG_BLOCK, &caught_signals, NULL );
  2212. if (( sig = sigwait( &caught_signals )) < 0 ) {
  2213. LDAPDebug( LDAP_DEBUG_ANY, "catch_signals: sigwait returned -1\n",
  2214. 0, 0, 0 );
  2215. continue;
  2216. } else {
  2217. LDAPDebug( LDAP_DEBUG_TRACE, "catch_signals: detected signal %d\n",
  2218. sig, 0, 0 );
  2219. switch ( sig ) {
  2220. case SIGUSR1:
  2221. continue; /* ignore SIGUSR1 */
  2222. case SIGUSR2: /* fallthrough */
  2223. case SIGTERM: /* fallthrough */
  2224. case SIGHUP:
  2225. g_set_shutdown( SLAPI_SHUTDOWN_SIGNAL );
  2226. return NULL;
  2227. case SIGCHLD:
  2228. slapd_wait4child( sig );
  2229. break;
  2230. default:
  2231. LDAPDebug( LDAP_DEBUG_ANY,
  2232. "catch_signals: unknown signal (%d) received\n",
  2233. sig, 0, 0 );
  2234. }
  2235. }
  2236. }
  2237. }
  2238. #endif /* HPUX */
  2239. static int
  2240. get_configured_connection_table_size()
  2241. {
  2242. int size;
  2243. size = config_get_conntablesize();
  2244. /*
  2245. * Cap the table size at nsslapd-maxdescriptors.
  2246. */
  2247. #if !defined(_WIN32) && !defined(AIX)
  2248. {
  2249. int maxdesc = config_get_maxdescriptors();
  2250. if ( maxdesc >= 0 && size > maxdesc ) {
  2251. size = maxdesc;
  2252. }
  2253. }
  2254. #endif
  2255. return size;
  2256. }
  2257. PRFileDesc * get_ssl_listener_fd()
  2258. {
  2259. PRFileDesc * listener;
  2260. listener = the_connection_table->fd[FDS_S_TCPS].fd;
  2261. return listener;
  2262. }
  2263. int configure_pr_socket( PRFileDesc **pr_socket, int secure )
  2264. {
  2265. int ns = 0;
  2266. int reservedescriptors = config_get_reservedescriptors();
  2267. int enable_nagle = config_get_nagle();
  2268. PRSocketOptionData pr_socketoption;
  2269. #if defined(LINUX)
  2270. /* On Linux we use TCP_CORK so we must enable nagle */
  2271. enable_nagle = 1;
  2272. #endif
  2273. ns = PR_FileDesc2NativeHandle( *pr_socket );
  2274. #if !defined(_WIN32)
  2275. /*
  2276. * Some OS or third party libraries may require that low
  2277. * numbered file descriptors be available, e.g., the DNS resolver
  2278. * library on most operating systems. Therefore, we try to
  2279. * replace the file descriptor returned by accept() with a
  2280. * higher numbered one. If this fails, we log an error and
  2281. * continue (not considered a truly fatal error).
  2282. */
  2283. if ( reservedescriptors > 0 && ns < reservedescriptors ) {
  2284. int newfd = fcntl( ns, F_DUPFD, reservedescriptors );
  2285. if ( newfd > 0 ) {
  2286. PRFileDesc *nspr_layer_fd = PR_GetIdentitiesLayer( *pr_socket,
  2287. PR_NSPR_IO_LAYER );
  2288. if ( NULL == nspr_layer_fd ) {
  2289. slapi_log_error( SLAPI_LOG_FATAL, "configure_pr_socket",
  2290. "Unable to move socket file descriptor %d above %d:"
  2291. " PR_GetIdentitiesLayer( 0x%x, PR_NSPR_IO_LAYER )"
  2292. " failed\n", ns, reservedescriptors, *pr_socket );
  2293. close( newfd ); /* can't fix things up in NSPR -- close copy */
  2294. } else {
  2295. PR_ChangeFileDescNativeHandle( nspr_layer_fd, newfd );
  2296. close( ns ); /* dup succeeded -- close the original */
  2297. ns = newfd;
  2298. }
  2299. } else {
  2300. int oserr = errno;
  2301. slapi_log_error(SLAPI_LOG_FATAL, "configure_pr_socket",
  2302. "Unable to move socket file descriptor %d above %d:"
  2303. " OS error %d (%s)\n", ns, reservedescriptors, oserr,
  2304. slapd_system_strerror( oserr ) );
  2305. }
  2306. }
  2307. #endif /* !_WIN32 */
  2308. if ( secure ) {
  2309. pr_socketoption.option = PR_SockOpt_Nonblocking;
  2310. pr_socketoption.value.non_blocking = 0;
  2311. if ( PR_SetSocketOption( *pr_socket, &pr_socketoption ) == PR_FAILURE ) {
  2312. PRErrorCode prerr = PR_GetError();
  2313. LDAPDebug( LDAP_DEBUG_ANY,
  2314. "PR_SetSocketOption(PR_SockOpt_Nonblocking) failed, "
  2315. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  2316. prerr, slapd_pr_strerror(prerr), 0 );
  2317. }
  2318. } else {
  2319. /* We always want to have non-blocking I/O */
  2320. pr_socketoption.option = PR_SockOpt_Nonblocking;
  2321. pr_socketoption.value.non_blocking = 1;
  2322. if ( PR_SetSocketOption( *pr_socket, &pr_socketoption ) == PR_FAILURE ) {
  2323. PRErrorCode prerr = PR_GetError();
  2324. LDAPDebug( LDAP_DEBUG_ANY,
  2325. "PR_SetSocketOption(PR_SockOpt_Nonblocking) failed, "
  2326. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  2327. prerr, slapd_pr_strerror(prerr), 0 );
  2328. }
  2329. if ( have_send_timeouts ) {
  2330. daemon_configure_send_timeout(ns,config_get_ioblocktimeout());
  2331. }
  2332. } /* else (secure) */
  2333. if ( !enable_nagle ) {
  2334. pr_socketoption.option = PR_SockOpt_NoDelay;
  2335. pr_socketoption.value.no_delay = 1;
  2336. if ( PR_SetSocketOption( *pr_socket, &pr_socketoption ) == PR_FAILURE) {
  2337. PRErrorCode prerr = PR_GetError();
  2338. LDAPDebug( LDAP_DEBUG_ANY,
  2339. "PR_SetSocketOption(PR_SockOpt_NoDelay) failed, "
  2340. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  2341. prerr, slapd_pr_strerror( prerr ), 0 );
  2342. }
  2343. } else {
  2344. pr_socketoption.option = PR_SockOpt_NoDelay;
  2345. pr_socketoption.value.no_delay = 0;
  2346. if ( PR_SetSocketOption( *pr_socket, &pr_socketoption ) == PR_FAILURE) {
  2347. PRErrorCode prerr = PR_GetError();
  2348. LDAPDebug( LDAP_DEBUG_ANY,
  2349. "PR_SetSocketOption(PR_SockOpt_NoDelay) failed, "
  2350. SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
  2351. prerr, slapd_pr_strerror( prerr ), 0 );
  2352. }
  2353. } /* else (!enable_nagle) */
  2354. return ns;
  2355. }
  2356. void configure_ns_socket( int * ns )
  2357. {
  2358. int enable_nagle = config_get_nagle();
  2359. int on;
  2360. #if defined(LINUX)
  2361. /* On Linux we use TCP_CORK so we must enable nagle */
  2362. enable_nagle = 1;
  2363. #endif
  2364. if ( have_send_timeouts ) {
  2365. daemon_configure_send_timeout( *ns, config_get_ioblocktimeout() );
  2366. }
  2367. if ( !enable_nagle ) {
  2368. on = 1;
  2369. setsockopt( *ns, IPPROTO_TCP, TCP_NODELAY, (char * ) &on, sizeof(on) );
  2370. } else {
  2371. on = 0;
  2372. setsockopt( *ns, IPPROTO_TCP, TCP_NODELAY, (char * ) &on, sizeof(on) );
  2373. } /* else (!enable_nagle) */
  2374. return;
  2375. }
  2376. #ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS
  2377. /*
  2378. * A function that uses the DNS resolver in a simple way. This is only
  2379. * used to ensure that the DNS resolver has opened its files, etc.
  2380. * using low numbered file descriptors.
  2381. */
  2382. static void
  2383. get_loopback_by_addr( void )
  2384. {
  2385. #ifdef GETHOSTBYADDR_BUF_T
  2386. struct hostent hp;
  2387. GETHOSTBYADDR_BUF_T hbuf;
  2388. #endif
  2389. unsigned long ipaddr;
  2390. struct in_addr ia;
  2391. int herrno, rc = 0;
  2392. memset( (char *)&hp, 0, sizeof(hp));
  2393. ipaddr = htonl( INADDR_LOOPBACK );
  2394. (void) GETHOSTBYADDR( (char *)&ipaddr, sizeof( ipaddr ),
  2395. AF_INET, &hp, hbuf, sizeof(hbuf), &herrno );
  2396. }
  2397. #endif /* RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS */