connections.c 68 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549
  1. /* Inner loops of cache daemon.
  2. Copyright (C) 1998-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, see <https://www.gnu.org/licenses/>. */
  14. #include <alloca.h>
  15. #include <assert.h>
  16. #include <atomic.h>
  17. #include <error.h>
  18. #include <errno.h>
  19. #include <fcntl.h>
  20. #include <grp.h>
  21. #include <ifaddrs.h>
  22. #include <libintl.h>
  23. #include <pthread.h>
  24. #include <pwd.h>
  25. #include <resolv.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <unistd.h>
  29. #include <stdint.h>
  30. #include <arpa/inet.h>
  31. #ifdef HAVE_NETLINK
  32. # include <linux/netlink.h>
  33. # include <linux/rtnetlink.h>
  34. #endif
  35. #ifdef HAVE_EPOLL
  36. # include <sys/epoll.h>
  37. #endif
  38. #ifdef HAVE_INOTIFY
  39. # include <sys/inotify.h>
  40. #endif
  41. #include <sys/mman.h>
  42. #include <sys/param.h>
  43. #include <sys/poll.h>
  44. #include <sys/socket.h>
  45. #include <sys/stat.h>
  46. #include <sys/un.h>
  47. #include "nscd.h"
  48. #include "dbg_log.h"
  49. #include "selinux.h"
  50. #include <resolv/resolv.h>
  51. #include <kernel-features.h>
  52. #include <libc-diag.h>
  53. /* Support to run nscd as an unprivileged user */
  54. const char *server_user;
  55. static uid_t server_uid;
  56. static gid_t server_gid;
  57. const char *stat_user;
  58. uid_t stat_uid;
  59. static gid_t *server_groups;
  60. #ifndef NGROUPS
  61. # define NGROUPS 32
  62. #endif
  63. static int server_ngroups;
  64. static pthread_attr_t attr;
  65. static void begin_drop_privileges (void);
  66. static void finish_drop_privileges (void);
  67. /* Map request type to a string. */
  68. const char *const serv2str[LASTREQ] =
  69. {
  70. [GETPWBYNAME] = "GETPWBYNAME",
  71. [GETPWBYUID] = "GETPWBYUID",
  72. [GETGRBYNAME] = "GETGRBYNAME",
  73. [GETGRBYGID] = "GETGRBYGID",
  74. [GETHOSTBYNAME] = "GETHOSTBYNAME",
  75. [GETHOSTBYNAMEv6] = "GETHOSTBYNAMEv6",
  76. [GETHOSTBYADDR] = "GETHOSTBYADDR",
  77. [GETHOSTBYADDRv6] = "GETHOSTBYADDRv6",
  78. [SHUTDOWN] = "SHUTDOWN",
  79. [GETSTAT] = "GETSTAT",
  80. [INVALIDATE] = "INVALIDATE",
  81. [GETFDPW] = "GETFDPW",
  82. [GETFDGR] = "GETFDGR",
  83. [GETFDHST] = "GETFDHST",
  84. [GETAI] = "GETAI",
  85. [INITGROUPS] = "INITGROUPS",
  86. [GETSERVBYNAME] = "GETSERVBYNAME",
  87. [GETSERVBYPORT] = "GETSERVBYPORT",
  88. [GETFDSERV] = "GETFDSERV",
  89. [GETNETGRENT] = "GETNETGRENT",
  90. [INNETGR] = "INNETGR",
  91. [GETFDNETGR] = "GETFDNETGR"
  92. };
  93. #ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
  94. # define RWLOCK_INITIALIZER PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
  95. #else
  96. # define RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER
  97. #endif
  98. /* The control data structures for the services. */
  99. struct database_dyn dbs[lastdb] =
  100. {
  101. [pwddb] = {
  102. .lock = RWLOCK_INITIALIZER,
  103. .prune_lock = PTHREAD_MUTEX_INITIALIZER,
  104. .prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
  105. .enabled = 0,
  106. .check_file = 1,
  107. .persistent = 0,
  108. .propagate = 1,
  109. .shared = 0,
  110. .max_db_size = DEFAULT_MAX_DB_SIZE,
  111. .suggested_module = DEFAULT_SUGGESTED_MODULE,
  112. .db_filename = _PATH_NSCD_PASSWD_DB,
  113. .disabled_iov = &pwd_iov_disabled,
  114. .postimeout = 3600,
  115. .negtimeout = 20,
  116. .wr_fd = -1,
  117. .ro_fd = -1,
  118. .mmap_used = false
  119. },
  120. [grpdb] = {
  121. .lock = RWLOCK_INITIALIZER,
  122. .prune_lock = PTHREAD_MUTEX_INITIALIZER,
  123. .prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
  124. .enabled = 0,
  125. .check_file = 1,
  126. .persistent = 0,
  127. .propagate = 1,
  128. .shared = 0,
  129. .max_db_size = DEFAULT_MAX_DB_SIZE,
  130. .suggested_module = DEFAULT_SUGGESTED_MODULE,
  131. .db_filename = _PATH_NSCD_GROUP_DB,
  132. .disabled_iov = &grp_iov_disabled,
  133. .postimeout = 3600,
  134. .negtimeout = 60,
  135. .wr_fd = -1,
  136. .ro_fd = -1,
  137. .mmap_used = false
  138. },
  139. [hstdb] = {
  140. .lock = RWLOCK_INITIALIZER,
  141. .prune_lock = PTHREAD_MUTEX_INITIALIZER,
  142. .prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
  143. .enabled = 0,
  144. .check_file = 1,
  145. .persistent = 0,
  146. .propagate = 0, /* Not used. */
  147. .shared = 0,
  148. .max_db_size = DEFAULT_MAX_DB_SIZE,
  149. .suggested_module = DEFAULT_SUGGESTED_MODULE,
  150. .db_filename = _PATH_NSCD_HOSTS_DB,
  151. .disabled_iov = &hst_iov_disabled,
  152. .postimeout = 3600,
  153. .negtimeout = 20,
  154. .wr_fd = -1,
  155. .ro_fd = -1,
  156. .mmap_used = false
  157. },
  158. [servdb] = {
  159. .lock = RWLOCK_INITIALIZER,
  160. .prune_lock = PTHREAD_MUTEX_INITIALIZER,
  161. .prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
  162. .enabled = 0,
  163. .check_file = 1,
  164. .persistent = 0,
  165. .propagate = 0, /* Not used. */
  166. .shared = 0,
  167. .max_db_size = DEFAULT_MAX_DB_SIZE,
  168. .suggested_module = DEFAULT_SUGGESTED_MODULE,
  169. .db_filename = _PATH_NSCD_SERVICES_DB,
  170. .disabled_iov = &serv_iov_disabled,
  171. .postimeout = 28800,
  172. .negtimeout = 20,
  173. .wr_fd = -1,
  174. .ro_fd = -1,
  175. .mmap_used = false
  176. },
  177. [netgrdb] = {
  178. .lock = RWLOCK_INITIALIZER,
  179. .prune_lock = PTHREAD_MUTEX_INITIALIZER,
  180. .prune_run_lock = PTHREAD_MUTEX_INITIALIZER,
  181. .enabled = 0,
  182. .check_file = 1,
  183. .persistent = 0,
  184. .propagate = 0, /* Not used. */
  185. .shared = 0,
  186. .max_db_size = DEFAULT_MAX_DB_SIZE,
  187. .suggested_module = DEFAULT_SUGGESTED_MODULE,
  188. .db_filename = _PATH_NSCD_NETGROUP_DB,
  189. .disabled_iov = &netgroup_iov_disabled,
  190. .postimeout = 28800,
  191. .negtimeout = 20,
  192. .wr_fd = -1,
  193. .ro_fd = -1,
  194. .mmap_used = false
  195. }
  196. };
  197. /* Mapping of request type to database. */
  198. static struct
  199. {
  200. bool data_request;
  201. struct database_dyn *db;
  202. } const reqinfo[LASTREQ] =
  203. {
  204. [GETPWBYNAME] = { true, &dbs[pwddb] },
  205. [GETPWBYUID] = { true, &dbs[pwddb] },
  206. [GETGRBYNAME] = { true, &dbs[grpdb] },
  207. [GETGRBYGID] = { true, &dbs[grpdb] },
  208. [GETHOSTBYNAME] = { true, &dbs[hstdb] },
  209. [GETHOSTBYNAMEv6] = { true, &dbs[hstdb] },
  210. [GETHOSTBYADDR] = { true, &dbs[hstdb] },
  211. [GETHOSTBYADDRv6] = { true, &dbs[hstdb] },
  212. [SHUTDOWN] = { false, NULL },
  213. [GETSTAT] = { false, NULL },
  214. [GETFDPW] = { false, &dbs[pwddb] },
  215. [GETFDGR] = { false, &dbs[grpdb] },
  216. [GETFDHST] = { false, &dbs[hstdb] },
  217. [GETAI] = { true, &dbs[hstdb] },
  218. [INITGROUPS] = { true, &dbs[grpdb] },
  219. [GETSERVBYNAME] = { true, &dbs[servdb] },
  220. [GETSERVBYPORT] = { true, &dbs[servdb] },
  221. [GETFDSERV] = { false, &dbs[servdb] },
  222. [GETNETGRENT] = { true, &dbs[netgrdb] },
  223. [INNETGR] = { true, &dbs[netgrdb] },
  224. [GETFDNETGR] = { false, &dbs[netgrdb] }
  225. };
  226. /* Initial number of threads to use. */
  227. int nthreads = -1;
  228. /* Maximum number of threads to use. */
  229. int max_nthreads = 32;
  230. /* Socket for incoming connections. */
  231. static int sock;
  232. #ifdef HAVE_INOTIFY
  233. /* Inotify descriptor. */
  234. int inotify_fd = -1;
  235. #endif
  236. #ifdef HAVE_NETLINK
  237. /* Descriptor for netlink status updates. */
  238. static int nl_status_fd = -1;
  239. static uint32_t
  240. __bump_nl_timestamp (void)
  241. {
  242. static uint32_t nl_timestamp;
  243. if (atomic_fetch_add_relaxed (&nl_timestamp, 1) + 1 == 0)
  244. atomic_fetch_add_relaxed (&nl_timestamp, 1);
  245. return nl_timestamp;
  246. }
  247. #endif
  248. /* Number of times clients had to wait. */
  249. unsigned long int client_queued;
  250. ssize_t
  251. writeall (int fd, const void *buf, size_t len)
  252. {
  253. size_t n = len;
  254. ssize_t ret;
  255. do
  256. {
  257. ret = TEMP_FAILURE_RETRY (send (fd, buf, n, MSG_NOSIGNAL));
  258. if (ret <= 0)
  259. break;
  260. buf = (const char *) buf + ret;
  261. n -= ret;
  262. }
  263. while (n > 0);
  264. return ret < 0 ? ret : len - n;
  265. }
  266. enum usekey
  267. {
  268. use_not = 0,
  269. /* The following three are not really used, they are symbolic constants. */
  270. use_first = 16,
  271. use_begin = 32,
  272. use_end = 64,
  273. use_he = 1,
  274. use_he_begin = use_he | use_begin,
  275. use_he_end = use_he | use_end,
  276. use_data = 3,
  277. use_data_begin = use_data | use_begin,
  278. use_data_end = use_data | use_end,
  279. use_data_first = use_data_begin | use_first
  280. };
  281. static int
  282. check_use (const char *data, nscd_ssize_t first_free, uint8_t *usemap,
  283. enum usekey use, ref_t start, size_t len)
  284. {
  285. if (len < 2)
  286. return 0;
  287. if (start > first_free || start + len > first_free
  288. || (start & BLOCK_ALIGN_M1))
  289. return 0;
  290. if (usemap[start] == use_not)
  291. {
  292. /* Add the start marker. */
  293. usemap[start] = use | use_begin;
  294. use &= ~use_first;
  295. while (--len > 0)
  296. if (usemap[++start] != use_not)
  297. return 0;
  298. else
  299. usemap[start] = use;
  300. /* Add the end marker. */
  301. usemap[start] = use | use_end;
  302. }
  303. else if ((usemap[start] & ~use_first) == ((use | use_begin) & ~use_first))
  304. {
  305. /* Hash entries can't be shared. */
  306. if (use == use_he)
  307. return 0;
  308. usemap[start] |= (use & use_first);
  309. use &= ~use_first;
  310. while (--len > 1)
  311. if (usemap[++start] != use)
  312. return 0;
  313. if (usemap[++start] != (use | use_end))
  314. return 0;
  315. }
  316. else
  317. /* Points to a wrong object or somewhere in the middle. */
  318. return 0;
  319. return 1;
  320. }
  321. /* Verify data in persistent database. */
  322. static int
  323. verify_persistent_db (void *mem, struct database_pers_head *readhead, int dbnr)
  324. {
  325. assert (dbnr == pwddb || dbnr == grpdb || dbnr == hstdb || dbnr == servdb
  326. || dbnr == netgrdb);
  327. time_t now = time (NULL);
  328. struct database_pers_head *head = mem;
  329. struct database_pers_head head_copy = *head;
  330. /* Check that the header that was read matches the head in the database. */
  331. if (memcmp (head, readhead, sizeof (*head)) != 0)
  332. return 0;
  333. /* First some easy tests: make sure the database header is sane. */
  334. if (head->version != DB_VERSION
  335. || head->header_size != sizeof (*head)
  336. /* We allow a timestamp to be one hour ahead of the current time.
  337. This should cover daylight saving time changes. */
  338. || head->timestamp > now + 60 * 60 + 60
  339. || (head->gc_cycle & 1)
  340. || head->module == 0
  341. || (size_t) head->module > INT32_MAX / sizeof (ref_t)
  342. || (size_t) head->data_size > INT32_MAX - head->module * sizeof (ref_t)
  343. || head->first_free < 0
  344. || head->first_free > head->data_size
  345. || (head->first_free & BLOCK_ALIGN_M1) != 0
  346. || head->maxnentries < 0
  347. || head->maxnsearched < 0)
  348. return 0;
  349. uint8_t *usemap = calloc (head->first_free, 1);
  350. if (usemap == NULL)
  351. return 0;
  352. const char *data = (char *) &head->array[roundup (head->module,
  353. ALIGN / sizeof (ref_t))];
  354. nscd_ssize_t he_cnt = 0;
  355. for (nscd_ssize_t cnt = 0; cnt < head->module; ++cnt)
  356. {
  357. ref_t trail = head->array[cnt];
  358. ref_t work = trail;
  359. int tick = 0;
  360. while (work != ENDREF)
  361. {
  362. if (! check_use (data, head->first_free, usemap, use_he, work,
  363. sizeof (struct hashentry)))
  364. goto fail;
  365. /* Now we know we can dereference the record. */
  366. struct hashentry *here = (struct hashentry *) (data + work);
  367. ++he_cnt;
  368. /* Make sure the record is for this type of service. */
  369. if (here->type >= LASTREQ
  370. || reqinfo[here->type].db != &dbs[dbnr])
  371. goto fail;
  372. /* Validate boolean field value. */
  373. if (here->first != false && here->first != true)
  374. goto fail;
  375. if (here->len < 0)
  376. goto fail;
  377. /* Now the data. */
  378. if (here->packet < 0
  379. || here->packet > head->first_free
  380. || here->packet + sizeof (struct datahead) > head->first_free)
  381. goto fail;
  382. struct datahead *dh = (struct datahead *) (data + here->packet);
  383. if (! check_use (data, head->first_free, usemap,
  384. use_data | (here->first ? use_first : 0),
  385. here->packet, dh->allocsize))
  386. goto fail;
  387. if (dh->allocsize < sizeof (struct datahead)
  388. || dh->recsize > dh->allocsize
  389. || (dh->notfound != false && dh->notfound != true)
  390. || (dh->usable != false && dh->usable != true))
  391. goto fail;
  392. if (here->key < here->packet + sizeof (struct datahead)
  393. || here->key > here->packet + dh->allocsize
  394. || here->key + here->len > here->packet + dh->allocsize)
  395. goto fail;
  396. work = here->next;
  397. if (work == trail)
  398. /* A circular list, this must not happen. */
  399. goto fail;
  400. if (tick)
  401. trail = ((struct hashentry *) (data + trail))->next;
  402. tick = 1 - tick;
  403. }
  404. }
  405. if (he_cnt != head->nentries)
  406. goto fail;
  407. /* See if all data and keys had at least one reference from
  408. he->first == true hashentry. */
  409. for (ref_t idx = 0; idx < head->first_free; ++idx)
  410. {
  411. if (usemap[idx] == use_data_begin)
  412. goto fail;
  413. }
  414. /* Finally, make sure the database hasn't changed since the first test. */
  415. if (memcmp (mem, &head_copy, sizeof (*head)) != 0)
  416. goto fail;
  417. free (usemap);
  418. return 1;
  419. fail:
  420. free (usemap);
  421. return 0;
  422. }
  423. /* Initialize database information structures. */
  424. void
  425. nscd_init (void)
  426. {
  427. /* Look up unprivileged uid/gid/groups before we start listening on the
  428. socket */
  429. if (server_user != NULL)
  430. begin_drop_privileges ();
  431. if (nthreads == -1)
  432. /* No configuration for this value, assume a default. */
  433. nthreads = 4;
  434. for (size_t cnt = 0; cnt < lastdb; ++cnt)
  435. if (dbs[cnt].enabled)
  436. {
  437. pthread_rwlock_init (&dbs[cnt].lock, NULL);
  438. pthread_mutex_init (&dbs[cnt].memlock, NULL);
  439. if (dbs[cnt].persistent)
  440. {
  441. /* Try to open the appropriate file on disk. */
  442. int fd = open (dbs[cnt].db_filename, O_RDWR | O_CLOEXEC);
  443. if (fd != -1)
  444. {
  445. char *msg = NULL;
  446. struct stat64 st;
  447. void *mem;
  448. size_t total;
  449. struct database_pers_head head;
  450. ssize_t n = TEMP_FAILURE_RETRY (read (fd, &head,
  451. sizeof (head)));
  452. if (n != sizeof (head) || fstat64 (fd, &st) != 0)
  453. {
  454. fail_db_errno:
  455. /* The code is single-threaded at this point so
  456. using strerror is just fine. */
  457. msg = strerror (errno);
  458. fail_db:
  459. dbg_log (_("invalid persistent database file \"%s\": %s"),
  460. dbs[cnt].db_filename, msg);
  461. unlink (dbs[cnt].db_filename);
  462. }
  463. else if (head.module == 0 && head.data_size == 0)
  464. {
  465. /* The file has been created, but the head has not
  466. been initialized yet. */
  467. msg = _("uninitialized header");
  468. goto fail_db;
  469. }
  470. else if (head.header_size != (int) sizeof (head))
  471. {
  472. msg = _("header size does not match");
  473. goto fail_db;
  474. }
  475. else if ((total = (sizeof (head)
  476. + roundup (head.module * sizeof (ref_t),
  477. ALIGN)
  478. + head.data_size))
  479. > st.st_size
  480. || total < sizeof (head))
  481. {
  482. msg = _("file size does not match");
  483. goto fail_db;
  484. }
  485. /* Note we map with the maximum size allowed for the
  486. database. This is likely much larger than the
  487. actual file size. This is OK on most OSes since
  488. extensions of the underlying file will
  489. automatically translate more pages available for
  490. memory access. */
  491. else if ((mem = mmap (NULL, dbs[cnt].max_db_size,
  492. PROT_READ | PROT_WRITE,
  493. MAP_SHARED, fd, 0))
  494. == MAP_FAILED)
  495. goto fail_db_errno;
  496. else if (!verify_persistent_db (mem, &head, cnt))
  497. {
  498. munmap (mem, total);
  499. msg = _("verification failed");
  500. goto fail_db;
  501. }
  502. else
  503. {
  504. /* Success. We have the database. */
  505. dbs[cnt].head = mem;
  506. dbs[cnt].memsize = total;
  507. dbs[cnt].data = (char *)
  508. &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
  509. ALIGN / sizeof (ref_t))];
  510. dbs[cnt].mmap_used = true;
  511. if (dbs[cnt].suggested_module > head.module)
  512. dbg_log (_("suggested size of table for database %s larger than the persistent database's table"),
  513. dbnames[cnt]);
  514. dbs[cnt].wr_fd = fd;
  515. fd = -1;
  516. /* We also need a read-only descriptor. */
  517. if (dbs[cnt].shared)
  518. {
  519. dbs[cnt].ro_fd = open (dbs[cnt].db_filename,
  520. O_RDONLY | O_CLOEXEC);
  521. if (dbs[cnt].ro_fd == -1)
  522. dbg_log (_("\
  523. cannot create read-only descriptor for \"%s\"; no mmap"),
  524. dbs[cnt].db_filename);
  525. }
  526. // XXX Shall we test whether the descriptors actually
  527. // XXX point to the same file?
  528. }
  529. /* Close the file descriptors in case something went
  530. wrong in which case the variable have not been
  531. assigned -1. */
  532. if (fd != -1)
  533. close (fd);
  534. }
  535. else if (errno == EACCES)
  536. do_exit (EXIT_FAILURE, 0, _("cannot access '%s'"),
  537. dbs[cnt].db_filename);
  538. }
  539. if (dbs[cnt].head == NULL)
  540. {
  541. /* No database loaded. Allocate the data structure,
  542. possibly on disk. */
  543. struct database_pers_head head;
  544. size_t total = (sizeof (head)
  545. + roundup (dbs[cnt].suggested_module
  546. * sizeof (ref_t), ALIGN)
  547. + (dbs[cnt].suggested_module
  548. * DEFAULT_DATASIZE_PER_BUCKET));
  549. /* Try to create the database. If we do not need a
  550. persistent database create a temporary file. */
  551. int fd;
  552. int ro_fd = -1;
  553. if (dbs[cnt].persistent)
  554. {
  555. fd = open (dbs[cnt].db_filename,
  556. O_RDWR | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC,
  557. S_IRUSR | S_IWUSR);
  558. if (fd != -1 && dbs[cnt].shared)
  559. ro_fd = open (dbs[cnt].db_filename,
  560. O_RDONLY | O_CLOEXEC);
  561. }
  562. else
  563. {
  564. char fname[] = _PATH_NSCD_XYZ_DB_TMP;
  565. fd = mkostemp (fname, O_CLOEXEC);
  566. /* We do not need the file name anymore after we
  567. opened another file descriptor in read-only mode. */
  568. if (fd != -1)
  569. {
  570. if (dbs[cnt].shared)
  571. ro_fd = open (fname, O_RDONLY | O_CLOEXEC);
  572. unlink (fname);
  573. }
  574. }
  575. if (fd == -1)
  576. {
  577. if (errno == EEXIST)
  578. {
  579. dbg_log (_("database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"),
  580. dbnames[cnt], dbs[cnt].db_filename);
  581. do_exit (1, 0, NULL);
  582. }
  583. if (dbs[cnt].persistent)
  584. dbg_log (_("cannot create %s; no persistent database used"),
  585. dbs[cnt].db_filename);
  586. else
  587. dbg_log (_("cannot create %s; no sharing possible"),
  588. dbs[cnt].db_filename);
  589. dbs[cnt].persistent = 0;
  590. // XXX remember: no mmap
  591. }
  592. else
  593. {
  594. /* Tell the user if we could not create the read-only
  595. descriptor. */
  596. if (ro_fd == -1 && dbs[cnt].shared)
  597. dbg_log (_("\
  598. cannot create read-only descriptor for \"%s\"; no mmap"),
  599. dbs[cnt].db_filename);
  600. /* Before we create the header, initialize the hash
  601. table. That way if we get interrupted while writing
  602. the header we can recognize a partially initialized
  603. database. */
  604. size_t ps = sysconf (_SC_PAGESIZE);
  605. char tmpbuf[ps];
  606. assert (~ENDREF == 0);
  607. memset (tmpbuf, '\xff', ps);
  608. size_t remaining = dbs[cnt].suggested_module * sizeof (ref_t);
  609. off_t offset = sizeof (head);
  610. size_t towrite;
  611. if (offset % ps != 0)
  612. {
  613. towrite = MIN (remaining, ps - (offset % ps));
  614. if (pwrite (fd, tmpbuf, towrite, offset) != towrite)
  615. goto write_fail;
  616. offset += towrite;
  617. remaining -= towrite;
  618. }
  619. while (remaining > ps)
  620. {
  621. if (pwrite (fd, tmpbuf, ps, offset) == -1)
  622. goto write_fail;
  623. offset += ps;
  624. remaining -= ps;
  625. }
  626. if (remaining > 0
  627. && pwrite (fd, tmpbuf, remaining, offset) != remaining)
  628. goto write_fail;
  629. /* Create the header of the file. */
  630. struct database_pers_head head =
  631. {
  632. .version = DB_VERSION,
  633. .header_size = sizeof (head),
  634. .module = dbs[cnt].suggested_module,
  635. .data_size = (dbs[cnt].suggested_module
  636. * DEFAULT_DATASIZE_PER_BUCKET),
  637. .first_free = 0
  638. };
  639. void *mem;
  640. if ((TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head)))
  641. != sizeof (head))
  642. || (TEMP_FAILURE_RETRY_VAL (posix_fallocate (fd, 0, total))
  643. != 0)
  644. || (mem = mmap (NULL, dbs[cnt].max_db_size,
  645. PROT_READ | PROT_WRITE,
  646. MAP_SHARED, fd, 0)) == MAP_FAILED)
  647. {
  648. write_fail:
  649. unlink (dbs[cnt].db_filename);
  650. dbg_log (_("cannot write to database file %s: %s"),
  651. dbs[cnt].db_filename, strerror (errno));
  652. dbs[cnt].persistent = 0;
  653. }
  654. else
  655. {
  656. /* Success. */
  657. dbs[cnt].head = mem;
  658. dbs[cnt].data = (char *)
  659. &dbs[cnt].head->array[roundup (dbs[cnt].head->module,
  660. ALIGN / sizeof (ref_t))];
  661. dbs[cnt].memsize = total;
  662. dbs[cnt].mmap_used = true;
  663. /* Remember the descriptors. */
  664. dbs[cnt].wr_fd = fd;
  665. dbs[cnt].ro_fd = ro_fd;
  666. fd = -1;
  667. ro_fd = -1;
  668. }
  669. if (fd != -1)
  670. close (fd);
  671. if (ro_fd != -1)
  672. close (ro_fd);
  673. }
  674. }
  675. if (dbs[cnt].head == NULL)
  676. {
  677. /* We do not use the persistent database. Just
  678. create an in-memory data structure. */
  679. assert (! dbs[cnt].persistent);
  680. dbs[cnt].head = xmalloc (sizeof (struct database_pers_head)
  681. + (dbs[cnt].suggested_module
  682. * sizeof (ref_t)));
  683. memset (dbs[cnt].head, '\0', sizeof (struct database_pers_head));
  684. assert (~ENDREF == 0);
  685. memset (dbs[cnt].head->array, '\xff',
  686. dbs[cnt].suggested_module * sizeof (ref_t));
  687. dbs[cnt].head->module = dbs[cnt].suggested_module;
  688. dbs[cnt].head->data_size = (DEFAULT_DATASIZE_PER_BUCKET
  689. * dbs[cnt].head->module);
  690. dbs[cnt].data = xmalloc (dbs[cnt].head->data_size);
  691. dbs[cnt].head->first_free = 0;
  692. dbs[cnt].shared = 0;
  693. assert (dbs[cnt].ro_fd == -1);
  694. }
  695. }
  696. /* Create the socket. */
  697. sock = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
  698. if (sock < 0)
  699. {
  700. dbg_log (_("cannot open socket: %s"), strerror (errno));
  701. do_exit (errno == EACCES ? 4 : 1, 0, NULL);
  702. }
  703. /* Bind a name to the socket. */
  704. struct sockaddr_un sock_addr;
  705. sock_addr.sun_family = AF_UNIX;
  706. strcpy (sock_addr.sun_path, _PATH_NSCDSOCKET);
  707. if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
  708. {
  709. dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
  710. do_exit (errno == EACCES ? 4 : 1, 0, NULL);
  711. }
  712. /* Set permissions for the socket. */
  713. chmod (_PATH_NSCDSOCKET, DEFFILEMODE);
  714. /* Set the socket up to accept connections. */
  715. if (listen (sock, SOMAXCONN) < 0)
  716. {
  717. dbg_log (_("cannot enable socket to accept connections: %s"),
  718. strerror (errno));
  719. do_exit (1, 0, NULL);
  720. }
  721. #ifdef HAVE_NETLINK
  722. if (dbs[hstdb].enabled)
  723. {
  724. /* Try to open netlink socket to monitor network setting changes. */
  725. nl_status_fd = socket (AF_NETLINK,
  726. SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
  727. NETLINK_ROUTE);
  728. if (nl_status_fd != -1)
  729. {
  730. struct sockaddr_nl snl;
  731. memset (&snl, '\0', sizeof (snl));
  732. snl.nl_family = AF_NETLINK;
  733. /* XXX Is this the best set to use? */
  734. snl.nl_groups = (RTMGRP_IPV4_IFADDR | RTMGRP_TC | RTMGRP_IPV4_MROUTE
  735. | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_RULE
  736. | RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_MROUTE
  737. | RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFINFO
  738. | RTMGRP_IPV6_PREFIX);
  739. if (bind (nl_status_fd, (struct sockaddr *) &snl, sizeof (snl)) != 0)
  740. {
  741. close (nl_status_fd);
  742. nl_status_fd = -1;
  743. }
  744. else
  745. {
  746. /* Start the timestamp process. */
  747. dbs[hstdb].head->extra_data[NSCD_HST_IDX_CONF_TIMESTAMP]
  748. = __bump_nl_timestamp ();
  749. }
  750. }
  751. }
  752. #endif
  753. /* Change to unprivileged uid/gid/groups if specified in config file */
  754. if (server_user != NULL)
  755. finish_drop_privileges ();
  756. }
  757. #ifdef HAVE_INOTIFY
  758. #define TRACED_FILE_MASK (IN_DELETE_SELF | IN_CLOSE_WRITE | IN_MOVE_SELF)
  759. #define TRACED_DIR_MASK (IN_DELETE_SELF | IN_CREATE | IN_MOVED_TO | IN_MOVE_SELF)
  760. void
  761. install_watches (struct traced_file *finfo)
  762. {
  763. /* Use inotify support if we have it. */
  764. if (finfo->inotify_descr[TRACED_FILE] < 0)
  765. finfo->inotify_descr[TRACED_FILE] = inotify_add_watch (inotify_fd,
  766. finfo->fname,
  767. TRACED_FILE_MASK);
  768. if (finfo->inotify_descr[TRACED_FILE] < 0)
  769. {
  770. dbg_log (_("disabled inotify-based monitoring for file `%s': %s"),
  771. finfo->fname, strerror (errno));
  772. return;
  773. }
  774. dbg_log (_("monitoring file `%s` (%d)"),
  775. finfo->fname, finfo->inotify_descr[TRACED_FILE]);
  776. /* Additionally listen for events in the file's parent directory.
  777. We do this because the file to be watched might be
  778. deleted and then added back again. When it is added back again
  779. we must re-add the watch. We must also cover IN_MOVED_TO to
  780. detect a file being moved into the directory. */
  781. if (finfo->inotify_descr[TRACED_DIR] < 0)
  782. finfo->inotify_descr[TRACED_DIR] = inotify_add_watch (inotify_fd,
  783. finfo->dname,
  784. TRACED_DIR_MASK);
  785. if (finfo->inotify_descr[TRACED_DIR] < 0)
  786. {
  787. dbg_log (_("disabled inotify-based monitoring for directory `%s': %s"),
  788. finfo->fname, strerror (errno));
  789. return;
  790. }
  791. dbg_log (_("monitoring directory `%s` (%d)"),
  792. finfo->dname, finfo->inotify_descr[TRACED_DIR]);
  793. }
  794. #endif
  795. /* Register the file in FINFO as a traced file for the database DBS[DBIX].
  796. We support registering multiple files per database. Each call to
  797. register_traced_file adds to the list of registered files.
  798. When we prune the database, either through timeout or a request to
  799. invalidate, we will check to see if any of the registered files has changed.
  800. When we accept new connections to handle a cache request we will also
  801. check to see if any of the registered files has changed.
  802. If we have inotify support then we install an inotify fd to notify us of
  803. file deletion or modification, both of which will require we invalidate
  804. the cache for the database. Without inotify support we stat the file and
  805. store st_mtime to determine if the file has been modified. */
  806. void
  807. register_traced_file (size_t dbidx, struct traced_file *finfo)
  808. {
  809. /* If the database is disabled or file checking is disabled
  810. then ignore the registration. */
  811. if (! dbs[dbidx].enabled || ! dbs[dbidx].check_file)
  812. return;
  813. if (__glibc_unlikely (debug_level > 0))
  814. dbg_log (_("monitoring file %s for database %s"),
  815. finfo->fname, dbnames[dbidx]);
  816. #ifdef HAVE_INOTIFY
  817. install_watches (finfo);
  818. #endif
  819. struct stat64 st;
  820. if (stat64 (finfo->fname, &st) < 0)
  821. {
  822. /* We cannot stat() the file. Set mtime to zero and try again later. */
  823. dbg_log (_("stat failed for file `%s'; will try again later: %s"),
  824. finfo->fname, strerror (errno));
  825. finfo->mtime = 0;
  826. }
  827. else
  828. finfo->mtime = st.st_mtime;
  829. /* Queue up the file name. */
  830. finfo->next = dbs[dbidx].traced_files;
  831. dbs[dbidx].traced_files = finfo;
  832. }
  833. /* Close the connections. */
  834. void
  835. close_sockets (void)
  836. {
  837. close (sock);
  838. }
  839. static void
  840. invalidate_cache (char *key, int fd)
  841. {
  842. dbtype number;
  843. int32_t resp;
  844. for (number = pwddb; number < lastdb; ++number)
  845. if (strcmp (key, dbnames[number]) == 0)
  846. {
  847. struct traced_file *runp = dbs[number].traced_files;
  848. while (runp != NULL)
  849. {
  850. /* Make sure we reload from file when checking mtime. */
  851. runp->mtime = 0;
  852. #ifdef HAVE_INOTIFY
  853. /* During an invalidation we try to reload the traced
  854. file watches. This allows the user to re-sync if
  855. inotify events were lost. Similar to what we do during
  856. pruning. */
  857. install_watches (runp);
  858. #endif
  859. if (runp->call_res_init)
  860. {
  861. res_init ();
  862. break;
  863. }
  864. runp = runp->next;
  865. }
  866. break;
  867. }
  868. if (number == lastdb)
  869. {
  870. resp = EINVAL;
  871. writeall (fd, &resp, sizeof (resp));
  872. return;
  873. }
  874. if (dbs[number].enabled)
  875. {
  876. pthread_mutex_lock (&dbs[number].prune_run_lock);
  877. prune_cache (&dbs[number], LONG_MAX, fd);
  878. pthread_mutex_unlock (&dbs[number].prune_run_lock);
  879. }
  880. else
  881. {
  882. resp = 0;
  883. writeall (fd, &resp, sizeof (resp));
  884. }
  885. }
  886. #ifdef SCM_RIGHTS
  887. static void
  888. send_ro_fd (struct database_dyn *db, char *key, int fd)
  889. {
  890. /* If we do not have an read-only file descriptor do nothing. */
  891. if (db->ro_fd == -1)
  892. return;
  893. /* We need to send some data along with the descriptor. */
  894. uint64_t mapsize = (db->head->data_size
  895. + roundup (db->head->module * sizeof (ref_t), ALIGN)
  896. + sizeof (struct database_pers_head));
  897. struct iovec iov[2];
  898. iov[0].iov_base = key;
  899. iov[0].iov_len = strlen (key) + 1;
  900. iov[1].iov_base = &mapsize;
  901. iov[1].iov_len = sizeof (mapsize);
  902. /* Prepare the control message to transfer the descriptor. */
  903. union
  904. {
  905. struct cmsghdr hdr;
  906. char bytes[CMSG_SPACE (sizeof (int))];
  907. } buf;
  908. struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 2,
  909. .msg_control = buf.bytes,
  910. .msg_controllen = sizeof (buf) };
  911. struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
  912. cmsg->cmsg_level = SOL_SOCKET;
  913. cmsg->cmsg_type = SCM_RIGHTS;
  914. cmsg->cmsg_len = CMSG_LEN (sizeof (int));
  915. int *ip = (int *) CMSG_DATA (cmsg);
  916. *ip = db->ro_fd;
  917. msg.msg_controllen = cmsg->cmsg_len;
  918. /* Send the control message. We repeat when we are interrupted but
  919. everything else is ignored. */
  920. #ifndef MSG_NOSIGNAL
  921. # define MSG_NOSIGNAL 0
  922. #endif
  923. (void) TEMP_FAILURE_RETRY (sendmsg (fd, &msg, MSG_NOSIGNAL));
  924. if (__glibc_unlikely (debug_level > 0))
  925. dbg_log (_("provide access to FD %d, for %s"), db->ro_fd, key);
  926. }
  927. #endif /* SCM_RIGHTS */
  928. /* Handle new request. */
  929. static void
  930. handle_request (int fd, request_header *req, void *key, uid_t uid, pid_t pid)
  931. {
  932. if (__builtin_expect (req->version, NSCD_VERSION) != NSCD_VERSION)
  933. {
  934. if (debug_level > 0)
  935. dbg_log (_("\
  936. cannot handle old request version %d; current version is %d"),
  937. req->version, NSCD_VERSION);
  938. return;
  939. }
  940. /* Perform the SELinux check before we go on to the standard checks. */
  941. if (selinux_enabled && nscd_request_avc_has_perm (fd, req->type) != 0)
  942. {
  943. if (debug_level > 0)
  944. {
  945. #ifdef SO_PEERCRED
  946. char pbuf[sizeof ("/proc//exe") + 3 * sizeof (long int)];
  947. # ifdef PATH_MAX
  948. char buf[PATH_MAX];
  949. # else
  950. char buf[4096];
  951. # endif
  952. snprintf (pbuf, sizeof (pbuf), "/proc/%ld/exe", (long int) pid);
  953. ssize_t n = readlink (pbuf, buf, sizeof (buf) - 1);
  954. if (n <= 0)
  955. dbg_log (_("\
  956. request from %ld not handled due to missing permission"), (long int) pid);
  957. else
  958. {
  959. buf[n] = '\0';
  960. dbg_log (_("\
  961. request from '%s' [%ld] not handled due to missing permission"),
  962. buf, (long int) pid);
  963. }
  964. #else
  965. dbg_log (_("request not handled due to missing permission"));
  966. #endif
  967. }
  968. return;
  969. }
  970. struct database_dyn *db = reqinfo[req->type].db;
  971. /* See whether we can service the request from the cache. */
  972. if (__builtin_expect (reqinfo[req->type].data_request, true))
  973. {
  974. if (__builtin_expect (debug_level, 0) > 0)
  975. {
  976. if (req->type == GETHOSTBYADDR || req->type == GETHOSTBYADDRv6)
  977. {
  978. char buf[INET6_ADDRSTRLEN];
  979. dbg_log ("\t%s (%s)", serv2str[req->type],
  980. inet_ntop (req->type == GETHOSTBYADDR
  981. ? AF_INET : AF_INET6,
  982. key, buf, sizeof (buf)));
  983. }
  984. else
  985. dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
  986. }
  987. /* Is this service enabled? */
  988. if (__glibc_unlikely (!db->enabled))
  989. {
  990. /* No, sent the prepared record. */
  991. if (TEMP_FAILURE_RETRY (send (fd, db->disabled_iov->iov_base,
  992. db->disabled_iov->iov_len,
  993. MSG_NOSIGNAL))
  994. != (ssize_t) db->disabled_iov->iov_len
  995. && __builtin_expect (debug_level, 0) > 0)
  996. {
  997. /* We have problems sending the result. */
  998. char buf[256];
  999. dbg_log (_("cannot write result: %s"),
  1000. strerror_r (errno, buf, sizeof (buf)));
  1001. }
  1002. return;
  1003. }
  1004. /* Be sure we can read the data. */
  1005. if (__glibc_unlikely (pthread_rwlock_tryrdlock (&db->lock) != 0))
  1006. {
  1007. ++db->head->rdlockdelayed;
  1008. pthread_rwlock_rdlock (&db->lock);
  1009. }
  1010. /* See whether we can handle it from the cache. */
  1011. struct datahead *cached;
  1012. cached = (struct datahead *) cache_search (req->type, key, req->key_len,
  1013. db, uid);
  1014. if (cached != NULL)
  1015. {
  1016. /* Hurray it's in the cache. */
  1017. if (writeall (fd, cached->data, cached->recsize) != cached->recsize
  1018. && __glibc_unlikely (debug_level > 0))
  1019. {
  1020. /* We have problems sending the result. */
  1021. char buf[256];
  1022. dbg_log (_("cannot write result: %s"),
  1023. strerror_r (errno, buf, sizeof (buf)));
  1024. }
  1025. pthread_rwlock_unlock (&db->lock);
  1026. return;
  1027. }
  1028. pthread_rwlock_unlock (&db->lock);
  1029. }
  1030. else if (__builtin_expect (debug_level, 0) > 0)
  1031. {
  1032. if (req->type == INVALIDATE)
  1033. dbg_log ("\t%s (%s)", serv2str[req->type], (char *) key);
  1034. else
  1035. dbg_log ("\t%s", serv2str[req->type]);
  1036. }
  1037. /* Handle the request. */
  1038. switch (req->type)
  1039. {
  1040. case GETPWBYNAME:
  1041. addpwbyname (db, fd, req, key, uid);
  1042. break;
  1043. case GETPWBYUID:
  1044. addpwbyuid (db, fd, req, key, uid);
  1045. break;
  1046. case GETGRBYNAME:
  1047. addgrbyname (db, fd, req, key, uid);
  1048. break;
  1049. case GETGRBYGID:
  1050. addgrbygid (db, fd, req, key, uid);
  1051. break;
  1052. case GETHOSTBYNAME:
  1053. addhstbyname (db, fd, req, key, uid);
  1054. break;
  1055. case GETHOSTBYNAMEv6:
  1056. addhstbynamev6 (db, fd, req, key, uid);
  1057. break;
  1058. case GETHOSTBYADDR:
  1059. addhstbyaddr (db, fd, req, key, uid);
  1060. break;
  1061. case GETHOSTBYADDRv6:
  1062. addhstbyaddrv6 (db, fd, req, key, uid);
  1063. break;
  1064. case GETAI:
  1065. addhstai (db, fd, req, key, uid);
  1066. break;
  1067. case INITGROUPS:
  1068. addinitgroups (db, fd, req, key, uid);
  1069. break;
  1070. case GETSERVBYNAME:
  1071. addservbyname (db, fd, req, key, uid);
  1072. break;
  1073. case GETSERVBYPORT:
  1074. addservbyport (db, fd, req, key, uid);
  1075. break;
  1076. case GETNETGRENT:
  1077. addgetnetgrent (db, fd, req, key, uid);
  1078. break;
  1079. case INNETGR:
  1080. addinnetgr (db, fd, req, key, uid);
  1081. break;
  1082. case GETSTAT:
  1083. case SHUTDOWN:
  1084. case INVALIDATE:
  1085. {
  1086. /* Get the callers credentials. */
  1087. #ifdef SO_PEERCRED
  1088. struct ucred caller;
  1089. socklen_t optlen = sizeof (caller);
  1090. if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
  1091. {
  1092. char buf[256];
  1093. dbg_log (_("error getting caller's id: %s"),
  1094. strerror_r (errno, buf, sizeof (buf)));
  1095. break;
  1096. }
  1097. uid = caller.uid;
  1098. #else
  1099. /* Some systems have no SO_PEERCRED implementation. They don't
  1100. care about security so we don't as well. */
  1101. uid = 0;
  1102. #endif
  1103. }
  1104. /* Accept shutdown, getstat and invalidate only from root. For
  1105. the stat call also allow the user specified in the config file. */
  1106. if (req->type == GETSTAT)
  1107. {
  1108. if (uid == 0 || uid == stat_uid)
  1109. send_stats (fd, dbs);
  1110. }
  1111. else if (uid == 0)
  1112. {
  1113. if (req->type == INVALIDATE)
  1114. invalidate_cache (key, fd);
  1115. else
  1116. termination_handler (0);
  1117. }
  1118. break;
  1119. case GETFDPW:
  1120. case GETFDGR:
  1121. case GETFDHST:
  1122. case GETFDSERV:
  1123. case GETFDNETGR:
  1124. #ifdef SCM_RIGHTS
  1125. send_ro_fd (reqinfo[req->type].db, key, fd);
  1126. #endif
  1127. break;
  1128. default:
  1129. /* Ignore the command, it's nothing we know. */
  1130. break;
  1131. }
  1132. }
  1133. static char *
  1134. read_cmdline (size_t *size)
  1135. {
  1136. int fd = open ("/proc/self/cmdline", O_RDONLY);
  1137. if (fd < 0)
  1138. return NULL;
  1139. size_t current = 0;
  1140. size_t limit = 1024;
  1141. char *buffer = malloc (limit);
  1142. if (buffer == NULL)
  1143. {
  1144. close (fd);
  1145. errno = ENOMEM;
  1146. return NULL;
  1147. }
  1148. while (1)
  1149. {
  1150. if (current == limit)
  1151. {
  1152. char *newptr;
  1153. if (2 * limit < limit
  1154. || (newptr = realloc (buffer, 2 * limit)) == NULL)
  1155. {
  1156. free (buffer);
  1157. close (fd);
  1158. errno = ENOMEM;
  1159. return NULL;
  1160. }
  1161. buffer = newptr;
  1162. limit *= 2;
  1163. }
  1164. ssize_t n = TEMP_FAILURE_RETRY (read (fd, buffer + current,
  1165. limit - current));
  1166. if (n == -1)
  1167. {
  1168. int e = errno;
  1169. free (buffer);
  1170. close (fd);
  1171. errno = e;
  1172. return NULL;
  1173. }
  1174. if (n == 0)
  1175. break;
  1176. current += n;
  1177. }
  1178. close (fd);
  1179. *size = current;
  1180. return buffer;
  1181. }
  1182. /* Restart the process. */
  1183. static void
  1184. restart (void)
  1185. {
  1186. /* First determine the parameters. We do not use the parameters
  1187. passed to main because then nscd would use the system libc after
  1188. restarting even if it was started by a non-system dynamic linker
  1189. during glibc testing. */
  1190. size_t readlen;
  1191. char *cmdline = read_cmdline (&readlen);
  1192. if (cmdline == NULL)
  1193. {
  1194. dbg_log (_("\
  1195. cannot open /proc/self/cmdline: %m; disabling paranoia mode"));
  1196. paranoia = 0;
  1197. return;
  1198. }
  1199. /* Parse the command line. Worst case scenario: every two
  1200. characters form one parameter (one character plus NUL). */
  1201. char **argv = alloca ((readlen / 2 + 1) * sizeof (argv[0]));
  1202. int argc = 0;
  1203. for (char *cp = cmdline; cp < cmdline + readlen;)
  1204. {
  1205. argv[argc++] = cp;
  1206. cp = strchr (cp, '\0') + 1;
  1207. }
  1208. argv[argc] = NULL;
  1209. /* Second, change back to the old user if we changed it. */
  1210. if (server_user != NULL)
  1211. {
  1212. if (setresuid (old_uid, old_uid, old_uid) != 0)
  1213. {
  1214. dbg_log (_("\
  1215. cannot change to old UID: %s; disabling paranoia mode"),
  1216. strerror (errno));
  1217. paranoia = 0;
  1218. free (cmdline);
  1219. return;
  1220. }
  1221. if (setresgid (old_gid, old_gid, old_gid) != 0)
  1222. {
  1223. dbg_log (_("\
  1224. cannot change to old GID: %s; disabling paranoia mode"),
  1225. strerror (errno));
  1226. ignore_value (setuid (server_uid));
  1227. paranoia = 0;
  1228. free (cmdline);
  1229. return;
  1230. }
  1231. }
  1232. /* Next change back to the old working directory. */
  1233. if (chdir (oldcwd) == -1)
  1234. {
  1235. dbg_log (_("\
  1236. cannot change to old working directory: %s; disabling paranoia mode"),
  1237. strerror (errno));
  1238. if (server_user != NULL)
  1239. {
  1240. ignore_value (setuid (server_uid));
  1241. ignore_value (setgid (server_gid));
  1242. }
  1243. paranoia = 0;
  1244. free (cmdline);
  1245. return;
  1246. }
  1247. /* Synchronize memory. */
  1248. int32_t certainly[lastdb];
  1249. for (int cnt = 0; cnt < lastdb; ++cnt)
  1250. if (dbs[cnt].enabled)
  1251. {
  1252. /* Make sure nobody keeps using the database. */
  1253. dbs[cnt].head->timestamp = 0;
  1254. certainly[cnt] = dbs[cnt].head->nscd_certainly_running;
  1255. dbs[cnt].head->nscd_certainly_running = 0;
  1256. if (dbs[cnt].persistent)
  1257. // XXX async OK?
  1258. msync (dbs[cnt].head, dbs[cnt].memsize, MS_ASYNC);
  1259. }
  1260. /* The preparations are done. */
  1261. #ifdef PATH_MAX
  1262. char pathbuf[PATH_MAX];
  1263. #else
  1264. char pathbuf[256];
  1265. #endif
  1266. /* Try to exec the real nscd program so the process name (as reported
  1267. in /proc/PID/status) will be 'nscd', but fall back to /proc/self/exe
  1268. if readlink or the exec with the result of the readlink call fails. */
  1269. ssize_t n = readlink ("/proc/self/exe", pathbuf, sizeof (pathbuf) - 1);
  1270. if (n != -1)
  1271. {
  1272. pathbuf[n] = '\0';
  1273. execv (pathbuf, argv);
  1274. }
  1275. execv ("/proc/self/exe", argv);
  1276. /* If we come here, we will never be able to re-exec. */
  1277. dbg_log (_("re-exec failed: %s; disabling paranoia mode"),
  1278. strerror (errno));
  1279. if (server_user != NULL)
  1280. {
  1281. ignore_value (setuid (server_uid));
  1282. ignore_value (setgid (server_gid));
  1283. }
  1284. if (chdir ("/") != 0)
  1285. dbg_log (_("cannot change current working directory to \"/\": %s"),
  1286. strerror (errno));
  1287. paranoia = 0;
  1288. free (cmdline);
  1289. /* Re-enable the databases. */
  1290. time_t now = time (NULL);
  1291. for (int cnt = 0; cnt < lastdb; ++cnt)
  1292. if (dbs[cnt].enabled)
  1293. {
  1294. dbs[cnt].head->timestamp = now;
  1295. dbs[cnt].head->nscd_certainly_running = certainly[cnt];
  1296. }
  1297. }
  1298. /* List of file descriptors. */
  1299. struct fdlist
  1300. {
  1301. int fd;
  1302. struct fdlist *next;
  1303. };
  1304. /* Memory allocated for the list. */
  1305. static struct fdlist *fdlist;
  1306. /* List of currently ready-to-read file descriptors. */
  1307. static struct fdlist *readylist;
  1308. /* Conditional variable and mutex to signal availability of entries in
  1309. READYLIST. The condvar is initialized dynamically since we might
  1310. use a different clock depending on availability. */
  1311. static pthread_cond_t readylist_cond = PTHREAD_COND_INITIALIZER;
  1312. static pthread_mutex_t readylist_lock = PTHREAD_MUTEX_INITIALIZER;
  1313. /* The clock to use with the condvar. */
  1314. static clockid_t timeout_clock = CLOCK_REALTIME;
  1315. /* Number of threads ready to handle the READYLIST. */
  1316. static unsigned long int nready;
  1317. /* Function for the clean-up threads. */
  1318. static void *
  1319. __attribute__ ((__noreturn__))
  1320. nscd_run_prune (void *p)
  1321. {
  1322. const long int my_number = (long int) p;
  1323. assert (dbs[my_number].enabled);
  1324. int dont_need_update = setup_thread (&dbs[my_number]);
  1325. time_t now = time (NULL);
  1326. /* We are running. */
  1327. dbs[my_number].head->timestamp = now;
  1328. struct timespec prune_ts;
  1329. if (__glibc_unlikely (clock_gettime (timeout_clock, &prune_ts) == -1))
  1330. /* Should never happen. */
  1331. abort ();
  1332. /* Compute the initial timeout time. Prevent all the timers to go
  1333. off at the same time by adding a db-based value. */
  1334. prune_ts.tv_sec += CACHE_PRUNE_INTERVAL + my_number;
  1335. dbs[my_number].wakeup_time = now + CACHE_PRUNE_INTERVAL + my_number;
  1336. pthread_mutex_t *prune_lock = &dbs[my_number].prune_lock;
  1337. pthread_mutex_t *prune_run_lock = &dbs[my_number].prune_run_lock;
  1338. pthread_cond_t *prune_cond = &dbs[my_number].prune_cond;
  1339. pthread_mutex_lock (prune_lock);
  1340. while (1)
  1341. {
  1342. /* Wait, but not forever. */
  1343. int e = 0;
  1344. if (! dbs[my_number].clear_cache)
  1345. e = pthread_cond_timedwait (prune_cond, prune_lock, &prune_ts);
  1346. assert (__builtin_expect (e == 0 || e == ETIMEDOUT, 1));
  1347. time_t next_wait;
  1348. now = time (NULL);
  1349. if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time
  1350. || dbs[my_number].clear_cache)
  1351. {
  1352. /* We will determine the new timeout values based on the
  1353. cache content. Should there be concurrent additions to
  1354. the cache which are not accounted for in the cache
  1355. pruning we want to know about it. Therefore set the
  1356. timeout to the maximum. It will be decreased when adding
  1357. new entries to the cache, if necessary. */
  1358. dbs[my_number].wakeup_time = MAX_TIMEOUT_VALUE;
  1359. /* Unconditionally reset the flag. */
  1360. time_t prune_now = dbs[my_number].clear_cache ? LONG_MAX : now;
  1361. dbs[my_number].clear_cache = 0;
  1362. pthread_mutex_unlock (prune_lock);
  1363. /* We use a separate lock for running the prune function (instead
  1364. of keeping prune_lock locked) because this enables concurrent
  1365. invocations of cache_add which might modify the timeout value. */
  1366. pthread_mutex_lock (prune_run_lock);
  1367. next_wait = prune_cache (&dbs[my_number], prune_now, -1);
  1368. pthread_mutex_unlock (prune_run_lock);
  1369. next_wait = MAX (next_wait, CACHE_PRUNE_INTERVAL);
  1370. /* If clients cannot determine for sure whether nscd is running
  1371. we need to wake up occasionally to update the timestamp.
  1372. Wait 90% of the update period. */
  1373. #define UPDATE_MAPPING_TIMEOUT (MAPPING_TIMEOUT * 9 / 10)
  1374. if (__glibc_unlikely (! dont_need_update))
  1375. {
  1376. next_wait = MIN (UPDATE_MAPPING_TIMEOUT, next_wait);
  1377. dbs[my_number].head->timestamp = now;
  1378. }
  1379. pthread_mutex_lock (prune_lock);
  1380. /* Make it known when we will wake up again. */
  1381. if (now + next_wait < dbs[my_number].wakeup_time)
  1382. dbs[my_number].wakeup_time = now + next_wait;
  1383. else
  1384. next_wait = dbs[my_number].wakeup_time - now;
  1385. }
  1386. else
  1387. /* The cache was just pruned. Do not do it again now. Just
  1388. use the new timeout value. */
  1389. next_wait = dbs[my_number].wakeup_time - now;
  1390. if (clock_gettime (timeout_clock, &prune_ts) == -1)
  1391. /* Should never happen. */
  1392. abort ();
  1393. /* Compute next timeout time. */
  1394. prune_ts.tv_sec += next_wait;
  1395. }
  1396. }
  1397. /* This is the main loop. It is replicated in different threads but
  1398. the use of the ready list makes sure only one thread handles an
  1399. incoming connection. */
  1400. static void *
  1401. __attribute__ ((__noreturn__))
  1402. nscd_run_worker (void *p)
  1403. {
  1404. char buf[256];
  1405. /* Initial locking. */
  1406. pthread_mutex_lock (&readylist_lock);
  1407. /* One more thread available. */
  1408. ++nready;
  1409. while (1)
  1410. {
  1411. while (readylist == NULL)
  1412. pthread_cond_wait (&readylist_cond, &readylist_lock);
  1413. struct fdlist *it = readylist->next;
  1414. if (readylist->next == readylist)
  1415. /* Just one entry on the list. */
  1416. readylist = NULL;
  1417. else
  1418. readylist->next = it->next;
  1419. /* Extract the information and mark the record ready to be used
  1420. again. */
  1421. int fd = it->fd;
  1422. it->next = NULL;
  1423. /* One more thread available. */
  1424. --nready;
  1425. /* We are done with the list. */
  1426. pthread_mutex_unlock (&readylist_lock);
  1427. /* Now read the request. */
  1428. request_header req;
  1429. if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, &req, sizeof (req)))
  1430. != sizeof (req), 0))
  1431. {
  1432. /* We failed to read data. Note that this also might mean we
  1433. failed because we would have blocked. */
  1434. if (debug_level > 0)
  1435. dbg_log (_("short read while reading request: %s"),
  1436. strerror_r (errno, buf, sizeof (buf)));
  1437. goto close_and_out;
  1438. }
  1439. /* Check whether this is a valid request type. */
  1440. if (req.type < GETPWBYNAME || req.type >= LASTREQ)
  1441. goto close_and_out;
  1442. /* Some systems have no SO_PEERCRED implementation. They don't
  1443. care about security so we don't as well. */
  1444. uid_t uid = -1;
  1445. #ifdef SO_PEERCRED
  1446. pid_t pid = 0;
  1447. if (__glibc_unlikely (debug_level > 0))
  1448. {
  1449. struct ucred caller;
  1450. socklen_t optlen = sizeof (caller);
  1451. if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) == 0)
  1452. pid = caller.pid;
  1453. }
  1454. #else
  1455. const pid_t pid = 0;
  1456. #endif
  1457. /* It should not be possible to crash the nscd with a silly
  1458. request (i.e., a terribly large key). We limit the size to 1kb. */
  1459. if (__builtin_expect (req.key_len, 1) < 0
  1460. || __builtin_expect (req.key_len, 1) > MAXKEYLEN)
  1461. {
  1462. if (debug_level > 0)
  1463. dbg_log (_("key length in request too long: %d"), req.key_len);
  1464. }
  1465. else
  1466. {
  1467. /* Get the key. */
  1468. char keybuf[MAXKEYLEN + 1];
  1469. if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, keybuf,
  1470. req.key_len))
  1471. != req.key_len, 0))
  1472. {
  1473. /* Again, this can also mean we would have blocked. */
  1474. if (debug_level > 0)
  1475. dbg_log (_("short read while reading request key: %s"),
  1476. strerror_r (errno, buf, sizeof (buf)));
  1477. goto close_and_out;
  1478. }
  1479. keybuf[req.key_len] = '\0';
  1480. if (__builtin_expect (debug_level, 0) > 0)
  1481. {
  1482. #ifdef SO_PEERCRED
  1483. if (pid != 0)
  1484. dbg_log (_("\
  1485. handle_request: request received (Version = %d) from PID %ld"),
  1486. req.version, (long int) pid);
  1487. else
  1488. #endif
  1489. dbg_log (_("\
  1490. handle_request: request received (Version = %d)"), req.version);
  1491. }
  1492. /* Phew, we got all the data, now process it. */
  1493. handle_request (fd, &req, keybuf, uid, pid);
  1494. }
  1495. close_and_out:
  1496. /* We are done. */
  1497. close (fd);
  1498. /* Re-locking. */
  1499. pthread_mutex_lock (&readylist_lock);
  1500. /* One more thread available. */
  1501. ++nready;
  1502. }
  1503. /* NOTREACHED */
  1504. }
  1505. static unsigned int nconns;
  1506. static void
  1507. fd_ready (int fd)
  1508. {
  1509. pthread_mutex_lock (&readylist_lock);
  1510. /* Find an empty entry in FDLIST. */
  1511. size_t inner;
  1512. for (inner = 0; inner < nconns; ++inner)
  1513. if (fdlist[inner].next == NULL)
  1514. break;
  1515. assert (inner < nconns);
  1516. fdlist[inner].fd = fd;
  1517. if (readylist == NULL)
  1518. readylist = fdlist[inner].next = &fdlist[inner];
  1519. else
  1520. {
  1521. fdlist[inner].next = readylist->next;
  1522. readylist = readylist->next = &fdlist[inner];
  1523. }
  1524. bool do_signal = true;
  1525. if (__glibc_unlikely (nready == 0))
  1526. {
  1527. ++client_queued;
  1528. do_signal = false;
  1529. /* Try to start another thread to help out. */
  1530. pthread_t th;
  1531. if (nthreads < max_nthreads
  1532. && pthread_create (&th, &attr, nscd_run_worker,
  1533. (void *) (long int) nthreads) == 0)
  1534. {
  1535. /* We got another thread. */
  1536. ++nthreads;
  1537. /* The new thread might need a kick. */
  1538. do_signal = true;
  1539. }
  1540. }
  1541. pthread_mutex_unlock (&readylist_lock);
  1542. /* Tell one of the worker threads there is work to do. */
  1543. if (do_signal)
  1544. pthread_cond_signal (&readylist_cond);
  1545. }
  1546. /* Check whether restarting should happen. */
  1547. static bool
  1548. restart_p (time_t now)
  1549. {
  1550. return (paranoia && readylist == NULL && nready == nthreads
  1551. && now >= restart_time);
  1552. }
  1553. /* Array for times a connection was accepted. */
  1554. static time_t *starttime;
  1555. #ifdef HAVE_INOTIFY
  1556. /* Inotify event for changed file. */
  1557. union __inev
  1558. {
  1559. struct inotify_event i;
  1560. # ifndef PATH_MAX
  1561. # define PATH_MAX 1024
  1562. # endif
  1563. char buf[sizeof (struct inotify_event) + PATH_MAX];
  1564. };
  1565. /* Returns 0 if the file is there otherwise -1. */
  1566. int
  1567. check_file (struct traced_file *finfo)
  1568. {
  1569. struct stat64 st;
  1570. /* We could check mtime and if different re-add
  1571. the watches, and invalidate the database, but we
  1572. don't because we are called from inotify_check_files
  1573. which should be doing that work. If sufficient inotify
  1574. events were lost then the next pruning or invalidation
  1575. will do the stat and mtime check. We don't do it here to
  1576. keep the logic simple. */
  1577. if (stat64 (finfo->fname, &st) < 0)
  1578. return -1;
  1579. return 0;
  1580. }
  1581. /* Process the inotify event in INEV. If the event matches any of the files
  1582. registered with a database then mark that database as requiring its cache
  1583. to be cleared. We indicate the cache needs clearing by setting
  1584. TO_CLEAR[DBCNT] to true for the matching database. */
  1585. static void
  1586. inotify_check_files (bool *to_clear, union __inev *inev)
  1587. {
  1588. /* Check which of the files changed. */
  1589. for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
  1590. {
  1591. struct traced_file *finfo = dbs[dbcnt].traced_files;
  1592. while (finfo != NULL)
  1593. {
  1594. /* The configuration file was moved or deleted.
  1595. We stop watching it at that point, and reinitialize. */
  1596. if (finfo->inotify_descr[TRACED_FILE] == inev->i.wd
  1597. && ((inev->i.mask & IN_MOVE_SELF)
  1598. || (inev->i.mask & IN_DELETE_SELF)
  1599. || (inev->i.mask & IN_IGNORED)))
  1600. {
  1601. int ret;
  1602. bool moved = (inev->i.mask & IN_MOVE_SELF) != 0;
  1603. if (check_file (finfo) == 0)
  1604. {
  1605. dbg_log (_("ignored inotify event for `%s` (file exists)"),
  1606. finfo->fname);
  1607. return;
  1608. }
  1609. dbg_log (_("monitored file `%s` was %s, removing watch"),
  1610. finfo->fname, moved ? "moved" : "deleted");
  1611. /* File was moved out, remove the watch. Watches are
  1612. automatically removed when the file is deleted. */
  1613. if (moved)
  1614. {
  1615. ret = inotify_rm_watch (inotify_fd, inev->i.wd);
  1616. if (ret < 0)
  1617. dbg_log (_("failed to remove file watch `%s`: %s"),
  1618. finfo->fname, strerror (errno));
  1619. }
  1620. finfo->inotify_descr[TRACED_FILE] = -1;
  1621. to_clear[dbcnt] = true;
  1622. if (finfo->call_res_init)
  1623. res_init ();
  1624. return;
  1625. }
  1626. /* The configuration file was open for writing and has just closed.
  1627. We reset the cache and reinitialize. */
  1628. if (finfo->inotify_descr[TRACED_FILE] == inev->i.wd
  1629. && inev->i.mask & IN_CLOSE_WRITE)
  1630. {
  1631. /* Mark cache as needing to be cleared and reinitialize. */
  1632. dbg_log (_("monitored file `%s` was written to"), finfo->fname);
  1633. to_clear[dbcnt] = true;
  1634. if (finfo->call_res_init)
  1635. res_init ();
  1636. return;
  1637. }
  1638. /* The parent directory was moved or deleted. We trigger one last
  1639. invalidation. At the next pruning or invalidation we may add
  1640. this watch back if the file is present again. */
  1641. if (finfo->inotify_descr[TRACED_DIR] == inev->i.wd
  1642. && ((inev->i.mask & IN_DELETE_SELF)
  1643. || (inev->i.mask & IN_MOVE_SELF)
  1644. || (inev->i.mask & IN_IGNORED)))
  1645. {
  1646. bool moved = (inev->i.mask & IN_MOVE_SELF) != 0;
  1647. /* The directory watch may have already been removed
  1648. but we don't know so we just remove it again and
  1649. ignore the error. Then we remove the file watch.
  1650. Note: watches are automatically removed for deleted
  1651. files. */
  1652. if (moved)
  1653. inotify_rm_watch (inotify_fd, inev->i.wd);
  1654. if (finfo->inotify_descr[TRACED_FILE] != -1)
  1655. {
  1656. dbg_log (_("monitored parent directory `%s` was %s, removing watch on `%s`"),
  1657. finfo->dname, moved ? "moved" : "deleted", finfo->fname);
  1658. if (inotify_rm_watch (inotify_fd, finfo->inotify_descr[TRACED_FILE]) < 0)
  1659. dbg_log (_("failed to remove file watch `%s`: %s"),
  1660. finfo->dname, strerror (errno));
  1661. }
  1662. finfo->inotify_descr[TRACED_FILE] = -1;
  1663. finfo->inotify_descr[TRACED_DIR] = -1;
  1664. to_clear[dbcnt] = true;
  1665. if (finfo->call_res_init)
  1666. res_init ();
  1667. /* Continue to the next entry since this might be the
  1668. parent directory for multiple registered files and
  1669. we want to remove watches for all registered files. */
  1670. continue;
  1671. }
  1672. /* The parent directory had a create or moved to event. */
  1673. if (finfo->inotify_descr[TRACED_DIR] == inev->i.wd
  1674. && ((inev->i.mask & IN_MOVED_TO)
  1675. || (inev->i.mask & IN_CREATE))
  1676. && strcmp (inev->i.name, finfo->sfname) == 0)
  1677. {
  1678. /* We detected a directory change. We look for the creation
  1679. of the file we are tracking or the move of the same file
  1680. into the directory. */
  1681. int ret;
  1682. dbg_log (_("monitored file `%s` was %s, adding watch"),
  1683. finfo->fname,
  1684. inev->i.mask & IN_CREATE ? "created" : "moved into place");
  1685. /* File was moved in or created. Regenerate the watch. */
  1686. if (finfo->inotify_descr[TRACED_FILE] != -1)
  1687. inotify_rm_watch (inotify_fd,
  1688. finfo->inotify_descr[TRACED_FILE]);
  1689. ret = inotify_add_watch (inotify_fd,
  1690. finfo->fname,
  1691. TRACED_FILE_MASK);
  1692. if (ret < 0)
  1693. dbg_log (_("failed to add file watch `%s`: %s"),
  1694. finfo->fname, strerror (errno));
  1695. finfo->inotify_descr[TRACED_FILE] = ret;
  1696. /* The file is new or moved so mark cache as needing to
  1697. be cleared and reinitialize. */
  1698. to_clear[dbcnt] = true;
  1699. if (finfo->call_res_init)
  1700. res_init ();
  1701. /* Done re-adding the watch. Don't return, we may still
  1702. have other files in this same directory, same watch
  1703. descriptor, and need to process them. */
  1704. }
  1705. /* Other events are ignored, and we move on to the next file. */
  1706. finfo = finfo->next;
  1707. }
  1708. }
  1709. }
  1710. /* If an entry in the array of booleans TO_CLEAR is TRUE then clear the cache
  1711. for the associated database, otherwise do nothing. The TO_CLEAR array must
  1712. have LASTDB entries. */
  1713. static inline void
  1714. clear_db_cache (bool *to_clear)
  1715. {
  1716. for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
  1717. if (to_clear[dbcnt])
  1718. {
  1719. pthread_mutex_lock (&dbs[dbcnt].prune_lock);
  1720. dbs[dbcnt].clear_cache = 1;
  1721. pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
  1722. pthread_cond_signal (&dbs[dbcnt].prune_cond);
  1723. }
  1724. }
  1725. int
  1726. handle_inotify_events (void)
  1727. {
  1728. bool to_clear[lastdb] = { false, };
  1729. union __inev inev;
  1730. /* Read all inotify events for files registered via
  1731. register_traced_file(). */
  1732. while (1)
  1733. {
  1734. /* Potentially read multiple events into buf. */
  1735. ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd,
  1736. &inev.buf,
  1737. sizeof (inev)));
  1738. if (nb < (ssize_t) sizeof (struct inotify_event))
  1739. {
  1740. /* Not even 1 event. */
  1741. if (__glibc_unlikely (nb == -1 && errno != EAGAIN))
  1742. return -1;
  1743. /* Done reading events that are ready. */
  1744. break;
  1745. }
  1746. /* Process all events. The normal inotify interface delivers
  1747. complete events on a read and never a partial event. */
  1748. char *eptr = &inev.buf[0];
  1749. ssize_t count;
  1750. while (1)
  1751. {
  1752. /* Check which of the files changed. */
  1753. inotify_check_files (to_clear, &inev);
  1754. count = sizeof (struct inotify_event) + inev.i.len;
  1755. eptr += count;
  1756. nb -= count;
  1757. if (nb >= (ssize_t) sizeof (struct inotify_event))
  1758. memcpy (&inev, eptr, nb);
  1759. else
  1760. break;
  1761. }
  1762. continue;
  1763. }
  1764. /* Actually perform the cache clearing. */
  1765. clear_db_cache (to_clear);
  1766. return 0;
  1767. }
  1768. #endif
  1769. static void
  1770. __attribute__ ((__noreturn__))
  1771. main_loop_poll (void)
  1772. {
  1773. struct pollfd *conns = (struct pollfd *) xmalloc (nconns
  1774. * sizeof (conns[0]));
  1775. conns[0].fd = sock;
  1776. conns[0].events = POLLRDNORM;
  1777. size_t nused = 1;
  1778. size_t firstfree = 1;
  1779. #ifdef HAVE_INOTIFY
  1780. if (inotify_fd != -1)
  1781. {
  1782. conns[1].fd = inotify_fd;
  1783. conns[1].events = POLLRDNORM;
  1784. nused = 2;
  1785. firstfree = 2;
  1786. }
  1787. #endif
  1788. #ifdef HAVE_NETLINK
  1789. size_t idx_nl_status_fd = 0;
  1790. if (nl_status_fd != -1)
  1791. {
  1792. idx_nl_status_fd = nused;
  1793. conns[nused].fd = nl_status_fd;
  1794. conns[nused].events = POLLRDNORM;
  1795. ++nused;
  1796. firstfree = nused;
  1797. }
  1798. #endif
  1799. while (1)
  1800. {
  1801. /* Wait for any event. We wait at most a couple of seconds so
  1802. that we can check whether we should close any of the accepted
  1803. connections since we have not received a request. */
  1804. #define MAX_ACCEPT_TIMEOUT 30
  1805. #define MIN_ACCEPT_TIMEOUT 5
  1806. #define MAIN_THREAD_TIMEOUT \
  1807. (MAX_ACCEPT_TIMEOUT * 1000 \
  1808. - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * 1000 * nused) / (2 * nconns))
  1809. int n = poll (conns, nused, MAIN_THREAD_TIMEOUT);
  1810. time_t now = time (NULL);
  1811. /* If there is a descriptor ready for reading or there is a new
  1812. connection, process this now. */
  1813. if (n > 0)
  1814. {
  1815. if (conns[0].revents != 0)
  1816. {
  1817. /* We have a new incoming connection. Accept the connection. */
  1818. int fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL,
  1819. SOCK_NONBLOCK));
  1820. /* Use the descriptor if we have not reached the limit. */
  1821. if (fd >= 0)
  1822. {
  1823. if (firstfree < nconns)
  1824. {
  1825. conns[firstfree].fd = fd;
  1826. conns[firstfree].events = POLLRDNORM;
  1827. starttime[firstfree] = now;
  1828. if (firstfree >= nused)
  1829. nused = firstfree + 1;
  1830. do
  1831. ++firstfree;
  1832. while (firstfree < nused && conns[firstfree].fd != -1);
  1833. }
  1834. else
  1835. /* We cannot use the connection so close it. */
  1836. close (fd);
  1837. }
  1838. --n;
  1839. }
  1840. size_t first = 1;
  1841. #ifdef HAVE_INOTIFY
  1842. if (inotify_fd != -1 && conns[1].fd == inotify_fd)
  1843. {
  1844. if (conns[1].revents != 0)
  1845. {
  1846. int ret;
  1847. ret = handle_inotify_events ();
  1848. if (ret == -1)
  1849. {
  1850. /* Something went wrong when reading the inotify
  1851. data. Better disable inotify. */
  1852. dbg_log (_("disabled inotify-based monitoring after read error %d"), errno);
  1853. conns[1].fd = -1;
  1854. firstfree = 1;
  1855. if (nused == 2)
  1856. nused = 1;
  1857. close (inotify_fd);
  1858. inotify_fd = -1;
  1859. }
  1860. --n;
  1861. }
  1862. first = 2;
  1863. }
  1864. #endif
  1865. #ifdef HAVE_NETLINK
  1866. if (idx_nl_status_fd != 0 && conns[idx_nl_status_fd].revents != 0)
  1867. {
  1868. char buf[4096];
  1869. /* Read all the data. We do not interpret it here. */
  1870. while (TEMP_FAILURE_RETRY (read (nl_status_fd, buf,
  1871. sizeof (buf))) != -1)
  1872. ;
  1873. dbs[hstdb].head->extra_data[NSCD_HST_IDX_CONF_TIMESTAMP]
  1874. = __bump_nl_timestamp ();
  1875. }
  1876. #endif
  1877. for (size_t cnt = first; cnt < nused && n > 0; ++cnt)
  1878. if (conns[cnt].revents != 0)
  1879. {
  1880. fd_ready (conns[cnt].fd);
  1881. /* Clean up the CONNS array. */
  1882. conns[cnt].fd = -1;
  1883. if (cnt < firstfree)
  1884. firstfree = cnt;
  1885. if (cnt == nused - 1)
  1886. do
  1887. --nused;
  1888. while (conns[nused - 1].fd == -1);
  1889. --n;
  1890. }
  1891. }
  1892. /* Now find entries which have timed out. */
  1893. assert (nused > 0);
  1894. /* We make the timeout length depend on the number of file
  1895. descriptors currently used. */
  1896. #define ACCEPT_TIMEOUT \
  1897. (MAX_ACCEPT_TIMEOUT \
  1898. - ((MAX_ACCEPT_TIMEOUT - MIN_ACCEPT_TIMEOUT) * nused) / nconns)
  1899. time_t laststart = now - ACCEPT_TIMEOUT;
  1900. for (size_t cnt = nused - 1; cnt > 0; --cnt)
  1901. {
  1902. if (conns[cnt].fd != -1 && starttime[cnt] < laststart)
  1903. {
  1904. /* Remove the entry, it timed out. */
  1905. (void) close (conns[cnt].fd);
  1906. conns[cnt].fd = -1;
  1907. if (cnt < firstfree)
  1908. firstfree = cnt;
  1909. if (cnt == nused - 1)
  1910. do
  1911. --nused;
  1912. while (conns[nused - 1].fd == -1);
  1913. }
  1914. }
  1915. if (restart_p (now))
  1916. restart ();
  1917. }
  1918. }
  1919. #ifdef HAVE_EPOLL
  1920. static void
  1921. main_loop_epoll (int efd)
  1922. {
  1923. struct epoll_event ev = { 0, };
  1924. int nused = 1;
  1925. size_t highest = 0;
  1926. /* Add the socket. */
  1927. ev.events = EPOLLRDNORM;
  1928. ev.data.fd = sock;
  1929. if (epoll_ctl (efd, EPOLL_CTL_ADD, sock, &ev) == -1)
  1930. /* We cannot use epoll. */
  1931. return;
  1932. # ifdef HAVE_INOTIFY
  1933. if (inotify_fd != -1)
  1934. {
  1935. ev.events = EPOLLRDNORM;
  1936. ev.data.fd = inotify_fd;
  1937. if (epoll_ctl (efd, EPOLL_CTL_ADD, inotify_fd, &ev) == -1)
  1938. /* We cannot use epoll. */
  1939. return;
  1940. nused = 2;
  1941. }
  1942. # endif
  1943. # ifdef HAVE_NETLINK
  1944. if (nl_status_fd != -1)
  1945. {
  1946. ev.events = EPOLLRDNORM;
  1947. ev.data.fd = nl_status_fd;
  1948. if (epoll_ctl (efd, EPOLL_CTL_ADD, nl_status_fd, &ev) == -1)
  1949. /* We cannot use epoll. */
  1950. return;
  1951. }
  1952. # endif
  1953. while (1)
  1954. {
  1955. struct epoll_event revs[100];
  1956. # define nrevs (sizeof (revs) / sizeof (revs[0]))
  1957. int n = epoll_wait (efd, revs, nrevs, MAIN_THREAD_TIMEOUT);
  1958. time_t now = time (NULL);
  1959. for (int cnt = 0; cnt < n; ++cnt)
  1960. if (revs[cnt].data.fd == sock)
  1961. {
  1962. /* A new connection. */
  1963. int fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL,
  1964. SOCK_NONBLOCK));
  1965. /* Use the descriptor if we have not reached the limit. */
  1966. if (fd >= 0)
  1967. {
  1968. /* Try to add the new descriptor. */
  1969. ev.data.fd = fd;
  1970. if (fd >= nconns
  1971. || epoll_ctl (efd, EPOLL_CTL_ADD, fd, &ev) == -1)
  1972. /* The descriptor is too large or something went
  1973. wrong. Close the descriptor. */
  1974. close (fd);
  1975. else
  1976. {
  1977. /* Remember when we accepted the connection. */
  1978. starttime[fd] = now;
  1979. if (fd > highest)
  1980. highest = fd;
  1981. ++nused;
  1982. }
  1983. }
  1984. }
  1985. # ifdef HAVE_INOTIFY
  1986. else if (revs[cnt].data.fd == inotify_fd)
  1987. {
  1988. int ret;
  1989. ret = handle_inotify_events ();
  1990. if (ret == -1)
  1991. {
  1992. /* Something went wrong when reading the inotify
  1993. data. Better disable inotify. */
  1994. dbg_log (_("disabled inotify-based monitoring after read error %d"), errno);
  1995. (void) epoll_ctl (efd, EPOLL_CTL_DEL, inotify_fd, NULL);
  1996. close (inotify_fd);
  1997. inotify_fd = -1;
  1998. break;
  1999. }
  2000. }
  2001. # endif
  2002. # ifdef HAVE_NETLINK
  2003. else if (revs[cnt].data.fd == nl_status_fd)
  2004. {
  2005. char buf[4096];
  2006. /* Read all the data. We do not interpret it here. */
  2007. while (TEMP_FAILURE_RETRY (read (nl_status_fd, buf,
  2008. sizeof (buf))) != -1)
  2009. ;
  2010. dbs[hstdb].head->extra_data[NSCD_HST_IDX_CONF_TIMESTAMP]
  2011. = __bump_nl_timestamp ();
  2012. }
  2013. # endif
  2014. else
  2015. {
  2016. /* Remove the descriptor from the epoll descriptor. */
  2017. (void) epoll_ctl (efd, EPOLL_CTL_DEL, revs[cnt].data.fd, NULL);
  2018. /* Get a worker to handle the request. */
  2019. fd_ready (revs[cnt].data.fd);
  2020. /* Reset the time. */
  2021. starttime[revs[cnt].data.fd] = 0;
  2022. if (revs[cnt].data.fd == highest)
  2023. do
  2024. --highest;
  2025. while (highest > 0 && starttime[highest] == 0);
  2026. --nused;
  2027. }
  2028. /* Now look for descriptors for accepted connections which have
  2029. no reply in too long of a time. */
  2030. time_t laststart = now - ACCEPT_TIMEOUT;
  2031. assert (starttime[sock] == 0);
  2032. # ifdef HAVE_INOTIFY
  2033. assert (inotify_fd == -1 || starttime[inotify_fd] == 0);
  2034. # endif
  2035. assert (nl_status_fd == -1 || starttime[nl_status_fd] == 0);
  2036. for (int cnt = highest; cnt > STDERR_FILENO; --cnt)
  2037. if (starttime[cnt] != 0 && starttime[cnt] < laststart)
  2038. {
  2039. /* We are waiting for this one for too long. Close it. */
  2040. (void) epoll_ctl (efd, EPOLL_CTL_DEL, cnt, NULL);
  2041. (void) close (cnt);
  2042. starttime[cnt] = 0;
  2043. if (cnt == highest)
  2044. --highest;
  2045. }
  2046. else if (cnt != sock && starttime[cnt] == 0 && cnt == highest)
  2047. --highest;
  2048. if (restart_p (now))
  2049. restart ();
  2050. }
  2051. }
  2052. #endif
  2053. /* Start all the threads we want. The initial process is thread no. 1. */
  2054. void
  2055. start_threads (void)
  2056. {
  2057. /* Initialize the conditional variable we will use. The only
  2058. non-standard attribute we might use is the clock selection. */
  2059. pthread_condattr_t condattr;
  2060. pthread_condattr_init (&condattr);
  2061. #if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0 \
  2062. && defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
  2063. /* Determine whether the monotonous clock is available. */
  2064. struct timespec dummy;
  2065. # if _POSIX_MONOTONIC_CLOCK == 0
  2066. if (sysconf (_SC_MONOTONIC_CLOCK) > 0)
  2067. # endif
  2068. # if _POSIX_CLOCK_SELECTION == 0
  2069. if (sysconf (_SC_CLOCK_SELECTION) > 0)
  2070. # endif
  2071. if (clock_getres (CLOCK_MONOTONIC, &dummy) == 0
  2072. && pthread_condattr_setclock (&condattr, CLOCK_MONOTONIC) == 0)
  2073. timeout_clock = CLOCK_MONOTONIC;
  2074. #endif
  2075. /* Create the attribute for the threads. They are all created
  2076. detached. */
  2077. pthread_attr_init (&attr);
  2078. pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
  2079. /* Use 1MB stacks, twice as much for 64-bit architectures. */
  2080. pthread_attr_setstacksize (&attr, NSCD_THREAD_STACKSIZE);
  2081. /* We allow less than LASTDB threads only for debugging. */
  2082. if (debug_level == 0)
  2083. nthreads = MAX (nthreads, lastdb);
  2084. /* Create the threads which prune the databases. */
  2085. // XXX Ideally this work would be done by some of the worker threads.
  2086. // XXX But this is problematic since we would need to be able to wake
  2087. // XXX them up explicitly as well as part of the group handling the
  2088. // XXX ready-list. This requires an operation where we can wait on
  2089. // XXX two conditional variables at the same time. This operation
  2090. // XXX does not exist (yet).
  2091. for (long int i = 0; i < lastdb; ++i)
  2092. {
  2093. /* Initialize the conditional variable. */
  2094. if (pthread_cond_init (&dbs[i].prune_cond, &condattr) != 0)
  2095. {
  2096. dbg_log (_("could not initialize conditional variable"));
  2097. do_exit (1, 0, NULL);
  2098. }
  2099. pthread_t th;
  2100. if (dbs[i].enabled
  2101. && pthread_create (&th, &attr, nscd_run_prune, (void *) i) != 0)
  2102. {
  2103. dbg_log (_("could not start clean-up thread; terminating"));
  2104. do_exit (1, 0, NULL);
  2105. }
  2106. }
  2107. pthread_condattr_destroy (&condattr);
  2108. for (long int i = 0; i < nthreads; ++i)
  2109. {
  2110. pthread_t th;
  2111. if (pthread_create (&th, &attr, nscd_run_worker, NULL) != 0)
  2112. {
  2113. if (i == 0)
  2114. {
  2115. dbg_log (_("could not start any worker thread; terminating"));
  2116. do_exit (1, 0, NULL);
  2117. }
  2118. break;
  2119. }
  2120. }
  2121. /* Now it is safe to let the parent know that we're doing fine and it can
  2122. exit. */
  2123. notify_parent (0);
  2124. /* Determine how much room for descriptors we should initially
  2125. allocate. This might need to change later if we cap the number
  2126. with MAXCONN. */
  2127. const long int nfds = sysconf (_SC_OPEN_MAX);
  2128. #define MINCONN 32
  2129. #define MAXCONN 16384
  2130. if (nfds == -1 || nfds > MAXCONN)
  2131. nconns = MAXCONN;
  2132. else if (nfds < MINCONN)
  2133. nconns = MINCONN;
  2134. else
  2135. nconns = nfds;
  2136. /* We need memory to pass descriptors on to the worker threads. */
  2137. fdlist = (struct fdlist *) xcalloc (nconns, sizeof (fdlist[0]));
  2138. /* Array to keep track when connection was accepted. */
  2139. starttime = (time_t *) xcalloc (nconns, sizeof (starttime[0]));
  2140. /* In the main thread we execute the loop which handles incoming
  2141. connections. */
  2142. #ifdef HAVE_EPOLL
  2143. int efd = epoll_create (100);
  2144. if (efd != -1)
  2145. {
  2146. main_loop_epoll (efd);
  2147. close (efd);
  2148. }
  2149. #endif
  2150. main_loop_poll ();
  2151. }
  2152. /* Look up the uid, gid, and supplementary groups to run nscd as. When
  2153. this function is called, we are not listening on the nscd socket yet so
  2154. we can just use the ordinary lookup functions without causing a lockup */
  2155. static void
  2156. begin_drop_privileges (void)
  2157. {
  2158. struct passwd *pwd = getpwnam (server_user);
  2159. if (pwd == NULL)
  2160. {
  2161. dbg_log (_("Failed to run nscd as user '%s'"), server_user);
  2162. do_exit (EXIT_FAILURE, 0,
  2163. _("Failed to run nscd as user '%s'"), server_user);
  2164. }
  2165. server_uid = pwd->pw_uid;
  2166. server_gid = pwd->pw_gid;
  2167. /* Save the old UID/GID if we have to change back. */
  2168. if (paranoia)
  2169. {
  2170. old_uid = getuid ();
  2171. old_gid = getgid ();
  2172. }
  2173. if (getgrouplist (server_user, server_gid, NULL, &server_ngroups) == 0)
  2174. {
  2175. /* This really must never happen. */
  2176. dbg_log (_("Failed to run nscd as user '%s'"), server_user);
  2177. do_exit (EXIT_FAILURE, errno,
  2178. _("initial getgrouplist failed"));
  2179. }
  2180. server_groups = (gid_t *) xmalloc (server_ngroups * sizeof (gid_t));
  2181. if (getgrouplist (server_user, server_gid, server_groups, &server_ngroups)
  2182. == -1)
  2183. {
  2184. dbg_log (_("Failed to run nscd as user '%s'"), server_user);
  2185. do_exit (EXIT_FAILURE, errno, _("getgrouplist failed"));
  2186. }
  2187. }
  2188. /* Call setgroups(), setgid(), and setuid() to drop root privileges and
  2189. run nscd as the user specified in the configuration file. */
  2190. static void
  2191. finish_drop_privileges (void)
  2192. {
  2193. #if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
  2194. /* We need to preserve the capabilities to connect to the audit daemon. */
  2195. cap_t new_caps = preserve_capabilities ();
  2196. #endif
  2197. if (setgroups (server_ngroups, server_groups) == -1)
  2198. {
  2199. dbg_log (_("Failed to run nscd as user '%s'"), server_user);
  2200. do_exit (EXIT_FAILURE, errno, _("setgroups failed"));
  2201. }
  2202. int res;
  2203. if (paranoia)
  2204. res = setresgid (server_gid, server_gid, old_gid);
  2205. else
  2206. res = setgid (server_gid);
  2207. if (res == -1)
  2208. {
  2209. dbg_log (_("Failed to run nscd as user '%s'"), server_user);
  2210. do_exit (4, errno, "setgid");
  2211. }
  2212. if (paranoia)
  2213. res = setresuid (server_uid, server_uid, old_uid);
  2214. else
  2215. res = setuid (server_uid);
  2216. if (res == -1)
  2217. {
  2218. dbg_log (_("Failed to run nscd as user '%s'"), server_user);
  2219. do_exit (4, errno, "setuid");
  2220. }
  2221. #if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
  2222. /* Remove the temporary capabilities. */
  2223. install_real_capabilities (new_caps);
  2224. #endif
  2225. }