1
0

nsadb.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. * END COPYRIGHT BLOCK **/
  6. /*
  7. * Description (nsadb.c)
  8. *
  9. * This module contains routines for retrieving information from
  10. * a Netscape authentication database. An authentication database
  11. * consists of a user database and a group database. This module
  12. * implements an authentication database based on Netscape user and
  13. * group databases defined in nsuser.h and nsgroup.h, which in turn
  14. * are based on the Netscape (server) database implementation
  15. * defined in nsdb.h. The interface for managing information in
  16. * an authentication database is described separately in nsamgmt.h.
  17. */
  18. #include <base/systems.h>
  19. #include <netsite.h>
  20. #include <base/file.h>
  21. #include <base/fsmutex.h>
  22. #include <libaccess/nsdbmgmt.h>
  23. #define __PRIVATE_NSADB
  24. #include <libaccess/nsadb.h>
  25. #include <libaccess/nsuser.h>
  26. #include <libaccess/nsgroup.h>
  27. /*
  28. * Description (NSADB_AuthIF)
  29. *
  30. * This structure defines a generic authentication database
  31. * interface for this module. It does not currently support
  32. * user/group id lookup.
  33. */
  34. AuthIF_t NSADB_AuthIF = {
  35. 0, /* find user/group by id */
  36. nsadbFindByName, /* find user/group by name */
  37. nsadbIdToName, /* lookup name for user/group id */
  38. nsadbOpen, /* open a named database */
  39. nsadbClose, /* close a database */
  40. };
  41. /*
  42. * Description (nsadbClose)
  43. *
  44. * This function closes an authentication database previously opened
  45. * via nsadbOpen().
  46. *
  47. * Arguments:
  48. *
  49. * authdb - handle returned by nsadbOpen()
  50. * flags - unused (must be zero)
  51. */
  52. NSAPI_PUBLIC void nsadbClose(void * authdb, int flags)
  53. {
  54. AuthDB_t * adb = (AuthDB_t *)authdb;
  55. if (adb->adb_userdb != 0) {
  56. ndbClose(adb->adb_userdb, 0);
  57. }
  58. if (adb->adb_groupdb != 0) {
  59. ndbClose(adb->adb_groupdb, 0);
  60. }
  61. #if defined(CLIENT_AUTH)
  62. nsadbCloseCerts(authdb, flags);
  63. #endif
  64. if (adb->adb_dbname) {
  65. FREE(adb->adb_dbname);
  66. }
  67. FREE(adb);
  68. }
  69. /*
  70. * Description (nsadbOpen)
  71. *
  72. * This function is used to open an authentication database.
  73. * The caller specifies a name for the database, which is actually
  74. * the name of a directory containing the files which comprise the
  75. * database. The caller also indicates whether this is a new
  76. * database, in which case it is created.
  77. *
  78. * Arguments:
  79. *
  80. * errp - error frame list pointer (may be null)
  81. * adbname - name of this database (directory)
  82. * flags - open flags:
  83. * AIF_CREATE - new database (create)
  84. * rptr - pointer to returned handle
  85. *
  86. * Returns:
  87. *
  88. * A handle for accessing the database is always returned via 'rptr'
  89. * unless there was a shortage of dynamic memory, in which case a
  90. * null handle is returned. The return value of the function is
  91. * 0 if it completes successfully. An error is indicated by a
  92. * negative return value (see nsautherr.h).
  93. */
  94. NSAPI_PUBLIC int nsadbOpen(NSErr_t * errp,
  95. char * adbname, int flags, void **rptr)
  96. {
  97. AuthDB_t * authdb = 0; /* pointer to database descriptor */
  98. SYS_DIR dbdir; /* database directory handle */
  99. int eid; /* error id code */
  100. int rv; /* result value */
  101. /* Make sure we have a place to return the database handle */
  102. if (rptr == 0) goto err_inval;
  103. /* Allocate the database descriptor */
  104. authdb = (AuthDB_t *)MALLOC(sizeof(AuthDB_t));
  105. if (authdb == 0) goto err_nomem;
  106. /* Return the descriptor pointer as the database handle */
  107. *rptr = (void *)authdb;
  108. authdb->adb_dbname = STRDUP(adbname);
  109. authdb->adb_userdb = 0;
  110. authdb->adb_groupdb = 0;
  111. #if defined(CLIENT_AUTH)
  112. authdb->adb_certdb = 0;
  113. authdb->adb_certlock = 0;
  114. authdb->adb_certnm = 0;
  115. #endif
  116. authdb->adb_flags = 0;
  117. /* See if the database directory exists */
  118. dbdir = dir_open(adbname);
  119. if (dbdir == 0) {
  120. /* No, create it if this is a new database, else error */
  121. if (flags & AIF_CREATE) {
  122. rv = dir_create(adbname);
  123. if (rv < 0) goto err_mkdir;
  124. authdb->adb_flags |= ADBF_NEW;
  125. }
  126. else goto err_dopen;
  127. }
  128. else {
  129. /* Ok, it's there */
  130. dir_close(dbdir);
  131. }
  132. return 0;
  133. err_inval:
  134. eid = NSAUERR3000;
  135. rv = NSAERRINVAL;
  136. goto err_ret;
  137. err_nomem:
  138. /* Error - insufficient dynamic memory */
  139. eid = NSAUERR3020;
  140. rv = NSAERRNOMEM;
  141. goto err_ret;
  142. err_ret:
  143. nserrGenerate(errp, rv, eid, NSAuth_Program, 0);
  144. goto punt;
  145. err_mkdir:
  146. eid = NSAUERR3040;
  147. rv = NSAERRMKDIR;
  148. goto err_dir;
  149. err_dopen:
  150. eid = NSAUERR3060;
  151. rv = NSAERROPEN;
  152. goto err_dir;
  153. err_dir:
  154. nserrGenerate(errp, rv, eid, NSAuth_Program, 1, adbname);
  155. goto punt;
  156. punt:
  157. /* Fatal error - free database descriptor and return null handle */
  158. if (authdb) {
  159. if (authdb->adb_dbname) {
  160. FREE(authdb->adb_dbname);
  161. }
  162. FREE(authdb);
  163. }
  164. if (rptr) *rptr = 0;
  165. return rv;
  166. }
  167. /*
  168. * Description (nsadbOpenUsers)
  169. *
  170. * This function is called to open the users subdatabase of an
  171. * open authentication database. The caller specifies flags to
  172. * indicate whether read or write access is required. This
  173. * function is normally called only by routines below the
  174. * nsadbOpen() API, in response to perform particular operations
  175. * on user or group objects. If the open is successful, the
  176. * resulting handle is stored in the AuthDB_t structure.
  177. *
  178. * Arguments:
  179. *
  180. * errp - error frame list pointer (may be null)
  181. * authdb - handle returned by nsadbOpen()
  182. * flags - open flags:
  183. * ADBF_UREAD - open for read
  184. * ADBF_UWRITE - open for read/write
  185. * Returns:
  186. *
  187. * The return value is zero if the operation is successfully
  188. * completed. An error is indicated by a negative return value
  189. * (see nsautherr.h), and an error frame is generated if an error
  190. * frame list was provided.
  191. */
  192. NSAPI_PUBLIC int nsadbOpenUsers(NSErr_t * errp, void * authdb, int flags)
  193. {
  194. AuthDB_t * adb = (AuthDB_t *)authdb;
  195. char * userfn = 0; /* user database name */
  196. int dblen; /* strlen(adb_dbname) */
  197. int uversion; /* user database version number */
  198. int eid; /* error id code */
  199. int rv; /* result value */
  200. if (adb == 0) goto err_inval;
  201. /* Is the user database already open? */
  202. if (adb->adb_userdb != 0) {
  203. /* Yes, is it open for the desired access? */
  204. if (adb->adb_flags & flags) {
  205. /* Yes, that was easy */
  206. return 0;
  207. }
  208. }
  209. else {
  210. /* We need to open the database */
  211. /* Allocate space for the user database filename */
  212. dblen = strlen(adb->adb_dbname);
  213. userfn = (char *)MALLOC(dblen + strlen(ADBUSERDBNAME) + 2);
  214. if (userfn == 0) goto err_nomem;
  215. /* Construct user database name */
  216. strcpy(userfn, adb->adb_dbname);
  217. /* Put in a '/' (or '\') if it's not there */
  218. if (userfn[dblen-1] != FILE_PATHSEP) {
  219. userfn[dblen] = FILE_PATHSEP;
  220. userfn[dblen+1] = 0;
  221. ++dblen;
  222. }
  223. strcpy(&userfn[dblen], ADBUSERDBNAME);
  224. adb->adb_userdb = ndbOpen(errp,
  225. userfn, 0, NDB_TYPE_USERDB, &uversion);
  226. if (adb->adb_userdb == 0) goto err_uopen;
  227. FREE(userfn);
  228. }
  229. /*
  230. * We don't really reopen the database to get the desired
  231. * access mode, since that is handled at the nsdb level.
  232. * But we do update the flags, just for the record.
  233. */
  234. adb->adb_flags &= ~(ADBF_UREAD|ADBF_UWRITE);
  235. if (flags & ADBF_UWRITE) adb->adb_flags |= ADBF_UWRITE;
  236. else adb->adb_flags |= ADBF_UREAD;
  237. return 0;
  238. err_inval:
  239. eid = NSAUERR3200;
  240. rv = NSAERRINVAL;
  241. goto err_ret;
  242. err_nomem:
  243. eid = NSAUERR3220;
  244. rv = NSAERRNOMEM;
  245. goto err_ret;
  246. err_ret:
  247. nserrGenerate(errp, rv, eid, NSAuth_Program, 0);
  248. goto punt;
  249. err_uopen:
  250. eid = NSAUERR3240;
  251. rv = NSAERROPEN;
  252. nserrGenerate(errp, rv, eid, NSAuth_Program, 1, userfn);
  253. goto punt;
  254. punt:
  255. return rv;
  256. }
  257. /*
  258. * Description (nsadbOpenGroups)
  259. *
  260. * This function is called to open the groups subdatabase of an
  261. * open authentication database. The caller specifies flags to
  262. * indicate whether read or write access is required. This
  263. * function is normally called only by routines below the
  264. * nsadbOpen() API, in response to perform particular operations
  265. * on user or group objects. If the open is successful, the
  266. * resulting handle is stored in the AuthDB_t structure.
  267. *
  268. * Arguments:
  269. *
  270. * errp - error frame list pointer (may be null)
  271. * authdb - handle returned by nsadbOpen()
  272. * flags - open flags:
  273. * ADBF_GREAD - open for read
  274. * ADBF_GWRITE - open for read/write
  275. * Returns:
  276. *
  277. * The return value is zero if the operation is successfully
  278. * completed. An error is indicated by a negative return value
  279. * (see nsautherr.h), and an error frame is generated if an error
  280. * frame list was provided.
  281. */
  282. NSAPI_PUBLIC int nsadbOpenGroups(NSErr_t * errp, void * authdb, int flags)
  283. {
  284. AuthDB_t * adb = (AuthDB_t *)authdb;
  285. char * groupfn = 0; /* group database name */
  286. int dblen; /* strlen(adb_dbname) */
  287. int gversion; /* group database version number */
  288. int eid; /* error id code */
  289. int rv; /* result value */
  290. if (adb == 0) goto err_inval;
  291. /* Is the group database already open? */
  292. if (adb->adb_groupdb != 0) {
  293. /* Yes, is it open for the desired access? */
  294. if (adb->adb_flags & flags) {
  295. /* Yes, that was easy */
  296. return 0;
  297. }
  298. }
  299. else {
  300. /* We need to open the database */
  301. /* Allocate space for the group database filename */
  302. dblen = strlen(adb->adb_dbname);
  303. groupfn = (char *)MALLOC(dblen + strlen(ADBGROUPDBNAME) + 2);
  304. if (groupfn == 0) goto err_nomem;
  305. /* Construct group database name */
  306. strcpy(groupfn, adb->adb_dbname);
  307. /* Put in a '/' (or '\') if it's not there */
  308. if (groupfn[dblen-1] != FILE_PATHSEP) {
  309. groupfn[dblen] = FILE_PATHSEP;
  310. groupfn[dblen+1] = 0;
  311. ++dblen;
  312. }
  313. strcpy(&groupfn[dblen], ADBGROUPDBNAME);
  314. adb->adb_groupdb = ndbOpen(errp,
  315. groupfn, 0, NDB_TYPE_GROUPDB, &gversion);
  316. if (adb->adb_groupdb == 0) goto err_gopen;
  317. FREE(groupfn);
  318. }
  319. /*
  320. * We don't really reopen the database to get the desired
  321. * access mode, since that is handled at the nsdb level.
  322. * But we do update the flags, just for the record.
  323. */
  324. adb->adb_flags &= ~(ADBF_GREAD|ADBF_GWRITE);
  325. if (flags & ADBF_GWRITE) adb->adb_flags |= ADBF_GWRITE;
  326. else adb->adb_flags |= ADBF_GREAD;
  327. return 0;
  328. err_inval:
  329. eid = NSAUERR3300;
  330. rv = NSAERRINVAL;
  331. goto err_ret;
  332. err_nomem:
  333. eid = NSAUERR3320;
  334. rv = NSAERRNOMEM;
  335. goto err_ret;
  336. err_ret:
  337. nserrGenerate(errp, rv, eid, NSAuth_Program, 0);
  338. goto punt;
  339. err_gopen:
  340. eid = NSAUERR3340;
  341. rv = NSAERROPEN;
  342. nserrGenerate(errp, rv, eid, NSAuth_Program, 1, groupfn);
  343. goto punt;
  344. punt:
  345. return rv;
  346. }
  347. /*
  348. * Description (nsadbIdToName)
  349. *
  350. * This function looks up a specified user or group id in the
  351. * authentication database. The name associated with the specified
  352. * id is returned.
  353. *
  354. * Arguments:
  355. *
  356. * errp - error frame list pointer (may be null)
  357. * authdb - handle returned by nsadbOpen()
  358. * id - user or group id
  359. * flags - AIF_USER or AIF_GROUP (defined in nsauth.h)
  360. * rptr - pointer to returned group or user name
  361. *
  362. * Returns:
  363. *
  364. * The return value is zero if no error occurs,
  365. * A negative return value indicates an error.
  366. */
  367. NSAPI_PUBLIC int nsadbIdToName(NSErr_t * errp,
  368. void * authdb, USI_t id, int flags, char **rptr)
  369. {
  370. AuthDB_t * adb = (AuthDB_t *)authdb;
  371. void * whichdb = 0;
  372. char * name;
  373. int rv;
  374. if (rptr != 0) *rptr = 0;
  375. /* Decide whether to use user or group database */
  376. if (flags & AIF_USER) {
  377. whichdb = adb->adb_userdb;
  378. if (whichdb == 0) {
  379. rv = nsadbOpenUsers(errp, authdb, ADBF_UREAD);
  380. if (rv < 0) goto punt;
  381. whichdb = adb->adb_userdb;
  382. }
  383. }
  384. else if (flags & AIF_GROUP) {
  385. whichdb = adb->adb_groupdb;
  386. if (whichdb == 0) {
  387. rv = nsadbOpenGroups(errp, authdb, ADBF_GREAD);
  388. if (rv < 0) goto punt;
  389. whichdb = adb->adb_groupdb;
  390. }
  391. }
  392. if (whichdb != 0) {
  393. /* Get the name corresponding to the id */
  394. rv = ndbIdToName(errp, whichdb, id, 0, &name);
  395. if (rv < 0) goto punt;
  396. if ((rptr != 0)) *rptr = name;
  397. rv = 0;
  398. }
  399. punt:
  400. return rv;
  401. }
  402. /*
  403. * Description (nsadbFindByName)
  404. *
  405. * This function looks up a specified name in the authentication
  406. * database. Flags specified by the caller indicate whether a
  407. * group name, user name, or either should be found. The caller
  408. * may optionally provide for the return of a user or group object
  409. * pointer, in which case the information associated with a
  410. * matching group or user is used to create a group or user object.
  411. *
  412. * Arguments:
  413. *
  414. * errp - error frame list pointer (may be null)
  415. * authdb - handle returned by nsadbOpen()
  416. * name - name of group or user
  417. * flags - search flags (defined in nsauth.h)
  418. * rptr - pointer to returned group or user
  419. * object pointer (may be null)
  420. *
  421. * Returns:
  422. *
  423. * The return value is a non-negative value if no error occurs,
  424. * and the value indicates whether the name matched a group or
  425. * user:
  426. *
  427. * AIF_NONE - name did not match a group or user name
  428. * AIF_GROUP - name matched a group name
  429. * AIF_USER - name matched a user name
  430. *
  431. * If the value is AIF_GROUP or AIF_USER, and rptr is non-null,
  432. * then a group or user object is created, and a pointer to it is
  433. * returned in the location indicated by rptr.
  434. *
  435. * A negative return value indicates an error.
  436. */
  437. NSAPI_PUBLIC int nsadbFindByName(NSErr_t * errp, void * authdb,
  438. char * name, int flags, void **rptr)
  439. {
  440. AuthDB_t * adb = (AuthDB_t *)authdb;
  441. ATR_t recptr;
  442. int reclen;
  443. int rv;
  444. if (rptr != 0) *rptr = 0;
  445. /* Search for group name? */
  446. if (flags & AIF_GROUP) {
  447. if (adb->adb_groupdb == 0) {
  448. rv = nsadbOpenGroups(errp, authdb, ADBF_GREAD);
  449. if (rv < 0) goto punt;
  450. }
  451. /* Look up the name in the group database */
  452. rv = ndbFindName(errp, adb->adb_groupdb, 0, (char *)name,
  453. &reclen, (char **)&recptr);
  454. if (rv == 0) {
  455. /* Found it. Make a group object if requested. */
  456. if (rptr != 0) {
  457. /* Got the group record. Decode into a group object. */
  458. *rptr = (void *)groupDecode((NTS_t)name, reclen, recptr);
  459. }
  460. return AIF_GROUP;
  461. }
  462. }
  463. /* Search for user name? */
  464. if (flags & AIF_USER) {
  465. if (adb->adb_userdb == 0) {
  466. rv = nsadbOpenUsers(errp, authdb, ADBF_UREAD);
  467. if (rv < 0) goto punt;
  468. }
  469. /* Look up the name in the user database */
  470. rv = ndbFindName(errp, adb->adb_userdb, 0, (char *)name,
  471. &reclen, (char **)&recptr);
  472. if (rv == 0) {
  473. /* Found it. Make a user object if requested. */
  474. if (rptr != 0) {
  475. /* Got the user record. Decode into a user object. */
  476. *rptr = (void *)userDecode((NTS_t)name, reclen, recptr);
  477. }
  478. return AIF_USER;
  479. }
  480. }
  481. /* Nothing found */
  482. nserrDispose(errp);
  483. return AIF_NONE;
  484. punt:
  485. return rv;
  486. }