1
0

nsgmgmt.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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 (nsgmgmt.c)
  8. *
  9. * This module contains routines for managing information in a
  10. * Netscape group database. Information for a particular group
  11. * is modified by retrieving the current information in the form
  12. * of a group object (GroupObj_t), calling functions in this module,
  13. * to modify the group object, and then calling groupStore() to
  14. * write the information in the group object back to the database.
  15. */
  16. #include "base/systems.h"
  17. #include "netsite.h"
  18. #include "assert.h"
  19. #include "libaccess/nsdbmgmt.h"
  20. #define __PRIVATE_NSGROUP
  21. #include "libaccess/nsgmgmt.h"
  22. /*
  23. * Description (groupAddMember)
  24. *
  25. * This function adds a member to a group object. The member may
  26. * be another group or a user, expressed as a group id or user id,
  27. * respectively. The 'isgid' argument is non-zero if the new
  28. * member is a group, or zero if it is a user.
  29. *
  30. * Arguments:
  31. *
  32. * goptr - group object pointer
  33. * isgid - non-zero if 'id' is a group id
  34. * zero if 'id' is a user id
  35. * id - group or user id to be added
  36. *
  37. * Returns:
  38. *
  39. * Returns zero if the specified member is already a direct member
  40. * of the group. Returns one if the member was added successfully.
  41. */
  42. NSAPI_PUBLIC int groupAddMember(GroupObj_t * goptr, int isgid, USI_t id)
  43. {
  44. USIList_t * uilptr;
  45. int rv = 0;
  46. /* Point to the relevant uid or gid list */
  47. uilptr = (isgid) ? &goptr->go_groups : &goptr->go_users;
  48. /* Add the id to the selected list */
  49. rv = usiInsert(uilptr, id);
  50. if (rv > 0) {
  51. goptr->go_flags |= GOF_MODIFIED;
  52. }
  53. return rv;
  54. }
  55. /*
  56. * Description (groupCreate)
  57. *
  58. * This function creates a group object, using information about
  59. * the group provided by the caller. The strings passed for the
  60. * group name and description may be on the stack. The group id
  61. * is set to zero, but the group object is marked as being new.
  62. * A group id will be assigned when groupStore() is called to add
  63. * the group to a group database.
  64. *
  65. * Arguments:
  66. *
  67. * name - pointer to group name string
  68. * desc - pointer to group description string
  69. *
  70. * Returns:
  71. *
  72. * A pointer to a dynamically allocated GroupObj_t structure is
  73. * returned.
  74. */
  75. NSAPI_PUBLIC GroupObj_t * groupCreate(NTS_t name, NTS_t desc)
  76. {
  77. GroupObj_t * goptr; /* group object pointer */
  78. goptr = (GroupObj_t *)MALLOC(sizeof(GroupObj_t));
  79. if (goptr) {
  80. goptr->go_name = (NTS_t)STRDUP((char *)name);
  81. goptr->go_gid = 0;
  82. goptr->go_flags = (GOF_MODIFIED | GOF_NEW);
  83. if (desc) {
  84. goptr->go_desc = (desc) ? (NTS_t)STRDUP((char *)desc) : 0;
  85. }
  86. UILINIT(&goptr->go_users);
  87. UILINIT(&goptr->go_groups);
  88. UILINIT(&goptr->go_pgroups);
  89. }
  90. return goptr;
  91. }
  92. /*
  93. * Description (groupDeleteMember)
  94. *
  95. * This function removes a specified member from a group object's
  96. * list of members. The member to be remove may be a group or a
  97. * user, expressed as a group id or user id, respectively. The
  98. * 'isgid' argument is non-zero if the member being removed is a
  99. * group, or zero if it is a user.
  100. *
  101. * Arguments:
  102. *
  103. * goptr - pointer to group object
  104. * isgid - non-zero if 'id' is a group id
  105. * zero if 'id' is a user id
  106. * id - group or user id to be removed
  107. *
  108. * Returns:
  109. *
  110. * The return value is zero if the specified member was not present
  111. * in the group object, or one if the member was successfully removed.
  112. */
  113. NSAPI_PUBLIC int groupDeleteMember(GroupObj_t * goptr, int isgid, USI_t id)
  114. {
  115. USIList_t * uilptr; /* pointer to list of member users or groups */
  116. int rv; /* return value */
  117. /* Get pointer to appropriate list of ids */
  118. uilptr = (isgid) ? &goptr->go_groups : &goptr->go_users;
  119. /* Remove the specified id */
  120. rv = usiRemove(uilptr, id);
  121. if (rv > 0) {
  122. goptr->go_flags |= GOF_MODIFIED;
  123. }
  124. return rv;
  125. }
  126. /*
  127. * Description (groupEncode)
  128. *
  129. * This function encodes a group object into a group DB record.
  130. *
  131. * Arguments:
  132. *
  133. * goptr - pointer to group object
  134. * greclen - pointer to returned record length
  135. * grecptr - pointer to returned record pointer
  136. *
  137. * Returns:
  138. *
  139. * The function return value is zero if successful. The length
  140. * and location of the created attribute record are returned
  141. * through 'greclen' and 'grecptr'. A non-zero function value
  142. * is returned if there's an error.
  143. */
  144. NSAPI_PUBLIC int groupEncode(GroupObj_t * goptr, int * greclen, ATR_t * grecptr)
  145. {
  146. int reclen; /* length of DB record */
  147. ATR_t rptr; /* DB record pointer */
  148. ATR_t rstart = 0; /* pointer to beginning of DB record */
  149. ATR_t glptr; /* saved pointer to UAT_GROUPS length */
  150. ATR_t gptr; /* saved pointer to after length at glptr */
  151. int gidlen; /* gid encoding length */
  152. int fllen; /* flags encoding length */
  153. USI_t dsclen; /* group description encoding length */
  154. USI_t nulen; /* member user count encoding length */
  155. USI_t nglen; /* member group count encoding length */
  156. int idcnt; /* count of user or group ids */
  157. USI_t * ids; /* pointer to array of user or group ids */
  158. int i; /* id index */
  159. int rv = -1;
  160. /*
  161. * First we need to figure out how long the generated record will be.
  162. * This doesn't have to be exact, but it must not be smaller than the
  163. * actual record size.
  164. */
  165. /* GAT_GID attribute: tag, length, USI */
  166. gidlen = USILENGTH(goptr->go_gid);
  167. reclen = (1 + 1 + gidlen);
  168. /* GAT_FLAGS attribute: tag, length, USI */
  169. fllen = USILENGTH(goptr->go_flags & GOF_DBFLAGS);
  170. reclen += (1 + 1 + fllen);
  171. /* GAT_DESCRIPT attribute: tag, length, NTS */
  172. dsclen = NTSLENGTH(goptr->go_desc);
  173. reclen += (1 + USILENGTH(dsclen) + dsclen);
  174. /* GAT_USERS attribute: tag, length, USI(count), USI(uid)... */
  175. idcnt = UILCOUNT(&goptr->go_users);
  176. nulen = USILENGTH(idcnt);
  177. reclen += (1 + USIALLOC() + nulen + (5 * idcnt));
  178. /* GAT_GROUPS attribute: tag, length, USI(count), USI(gid)... */
  179. idcnt = UILCOUNT(&goptr->go_groups);
  180. nglen = USILENGTH(idcnt);
  181. reclen += (1 + USIALLOC() + nglen + (5 * idcnt));
  182. /* GAT_PGROUPS attribute: tag, length, USI(count), USI(gid)... */
  183. idcnt = UILCOUNT(&goptr->go_pgroups);
  184. nglen = USILENGTH(idcnt);
  185. reclen += (1 + USIALLOC() + nglen + (5 * idcnt));
  186. /* Allocate the attribute record buffer */
  187. rptr = (ATR_t)MALLOC(reclen);
  188. if (rptr) {
  189. /* Save pointer to start of record */
  190. rstart = rptr;
  191. /* Encode GAT_GID attribute */
  192. *rptr++ = GAT_GID;
  193. *rptr++ = gidlen;
  194. rptr = USIENCODE(rptr, goptr->go_gid);
  195. /* Encode GAT_FLAGS attribute */
  196. *rptr++ = GAT_FLAGS;
  197. *rptr++ = fllen;
  198. rptr = USIENCODE(rptr, (goptr->go_flags & GOF_DBFLAGS));
  199. /* Encode GAT_DESCRIPT attribute */
  200. *rptr++ = GAT_DESCRIPT;
  201. rptr = USIENCODE(rptr, dsclen);
  202. rptr = NTSENCODE(rptr, goptr->go_desc);
  203. /* Encode GAT_USERS attribute */
  204. *rptr++ = GAT_USERS;
  205. /*
  206. * Save a pointer to the attribute encoding length, and reserve
  207. * space for the maximum encoding size of a USI_t value.
  208. */
  209. glptr = rptr;
  210. rptr += USIALLOC();
  211. gptr = rptr;
  212. /* Encode number of user members */
  213. idcnt = UILCOUNT(&goptr->go_users);
  214. rptr = USIENCODE(rptr, idcnt);
  215. /* Generate user ids encodings */
  216. ids = UILLIST(&goptr->go_users);
  217. for (i = 0; i < idcnt; ++i) {
  218. rptr = USIENCODE(rptr, ids[i]);
  219. }
  220. /* Now fix up the GAT_USERS attribute encoding length */
  221. glptr = USIINSERT(glptr, (USI_t)(rptr - gptr));
  222. /* Encode GAT_GROUPS attribute */
  223. *rptr++ = GAT_GROUPS;
  224. /*
  225. * Save a pointer to the attribute encoding length, and reserve
  226. * space for the maximum encoding size of a USI_t value.
  227. */
  228. glptr = rptr;
  229. rptr += USIALLOC();
  230. gptr = rptr;
  231. /* Encode number of groups */
  232. idcnt = UILCOUNT(&goptr->go_groups);
  233. rptr = USIENCODE(rptr, idcnt);
  234. /* Generate group ids encodings */
  235. ids = UILLIST(&goptr->go_groups);
  236. for (i = 0; i < idcnt; ++i) {
  237. rptr = USIENCODE(rptr, ids[i]);
  238. }
  239. /* Now fix up the GAT_GROUPS attribute encoding length */
  240. glptr = USIINSERT(glptr, (USI_t)(rptr - gptr));
  241. /* Encode GAT_PGROUPS attribute */
  242. *rptr++ = GAT_PGROUPS;
  243. /*
  244. * Save a pointer to the attribute encoding length, and reserve
  245. * space for the maximum encoding size of a USI_t value.
  246. */
  247. glptr = rptr;
  248. rptr += USIALLOC();
  249. gptr = rptr;
  250. /* Encode number of groups */
  251. idcnt = UILCOUNT(&goptr->go_pgroups);
  252. rptr = USIENCODE(rptr, idcnt);
  253. /* Generate group ids encodings */
  254. ids = UILLIST(&goptr->go_pgroups);
  255. for (i = 0; i < idcnt; ++i) {
  256. rptr = USIENCODE(rptr, ids[i]);
  257. }
  258. /* Now fix up the GAT_PGROUPS attribute encoding length */
  259. glptr = USIINSERT(glptr, (USI_t)(rptr - gptr));
  260. /* Return record length and location if requested */
  261. if (greclen) *greclen = rptr - rstart;
  262. if (grecptr) *grecptr = rstart;
  263. /* Indicate success */
  264. rv = 0;
  265. }
  266. return rv;
  267. }
  268. /*
  269. * Description (groupRemove)
  270. *
  271. * This function is called to remove a group from a specified group
  272. * database. Both the primary DB file and the id-to-name DB file
  273. * are updated.
  274. *
  275. * Arguments:
  276. *
  277. * errp - error frame list pointer (may be null)
  278. * groupdb - handle for group DB access
  279. * flags - (unused - must be zero)
  280. * name - pointer to group name
  281. *
  282. * Returns:
  283. *
  284. * If successful, the return value is zero. Otherwise it is a
  285. * non-zero error code.
  286. */
  287. NSAPI_PUBLIC int groupRemove(NSErr_t * errp, void * groupdb, int flags, NTS_t name)
  288. {
  289. GroupObj_t * goptr; /* group object pointer */
  290. int rv;
  291. int rv2;
  292. /* First retrieve the group record */
  293. goptr = groupFindByName(errp, groupdb, name);
  294. if (!goptr) {
  295. /* Error - specified group not found */
  296. return NSAERRNAME;
  297. }
  298. /* Free the group id value, if any */
  299. rv = 0;
  300. if (goptr->go_gid != 0) {
  301. rv = ndbFreeId(errp, groupdb, 0, (char *)name, goptr->go_gid);
  302. }
  303. rv2 = ndbDeleteName(errp, groupdb, 0, 0, (char *)name);
  304. return (rv) ? rv : rv2;
  305. }
  306. /*
  307. * Description (groupStore)
  308. *
  309. * This function is called to store a group object in the database.
  310. * If the object was created by groupCreate(), it is assumed to be
  311. * a new group, the group account name must not match any existing
  312. * group account names in the database, and a gid is assigned before
  313. * adding the group to the database. If the object was created by
  314. * groupFindByName(), the information in the group object will
  315. * replace the existing database entry for the indicated group
  316. * name.
  317. *
  318. * Arguments:
  319. *
  320. * errp - error frame list pointer (may be null)
  321. * groupdb - handle for group DB access
  322. * flags - (unused - must be zero)
  323. * goptr - group object pointer
  324. *
  325. * Returns:
  326. *
  327. * If successful, the return value is zero. Otherwise it is a
  328. * non-zero error code. The group object remains intact in either
  329. * case.
  330. */
  331. NSAPI_PUBLIC int groupStore(NSErr_t * errp, void * groupdb, int flags, GroupObj_t * goptr)
  332. {
  333. ATR_t recptr = 0;
  334. USI_t gid;
  335. int reclen = 0;
  336. int stflags = 0;
  337. int eid;
  338. int rv;
  339. /* If this is a new group, allocate a uid value */
  340. if (goptr->go_flags & GOF_NEW) {
  341. rv = ndbAllocId(errp, groupdb, 0, (char *)goptr->go_name, &gid);
  342. if (rv) goto punt;
  343. goptr->go_gid = gid;
  344. /* Let the database manager know that this is a new entry */
  345. stflags = NDBF_NEWNAME;
  346. }
  347. /* Convert the information in the group object to a DB record */
  348. rv = groupEncode(goptr, &reclen, &recptr);
  349. if (rv) goto err_nomem;
  350. /*
  351. * Store the record in the database under the group name.
  352. * If this is a new entry, a group id to group name mapping
  353. * also will be added to the id-to-name DB file.
  354. */
  355. rv = ndbStoreName(errp, groupdb, stflags,
  356. 0, (char *)goptr->go_name, reclen, (char *)recptr);
  357. FREE(recptr);
  358. if (rv == 0) {
  359. goptr->go_flags &= ~(GOF_NEW | GOF_MODIFIED);
  360. }
  361. punt:
  362. return rv;
  363. err_nomem:
  364. eid = NSAUERR2000;
  365. rv = NSAERRNOMEM;
  366. nserrGenerate(errp, rv, eid, NSAuth_Program, 0);
  367. goto punt;
  368. }