/nsswitch/winbind_nss_netbsd.c

https://gitlab.com/miztake/samba · C · 405 lines · 298 code · 73 blank · 34 comment · 33 complexity · 87b3fdd4a52ec994de77afb460acfccc MD5 · raw file

  1. /*
  2. Unix SMB/CIFS implementation.
  3. NetBSD loadable authentication module, providing identification
  4. routines against Samba winbind/Windows NT Domain
  5. Copyright (C) Luke Mewburn 2004-2005
  6. This library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Lesser General Public
  8. License as published by the Free Software Foundation; either
  9. version 3 of the License, or (at your option) any later version.
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. Library General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public
  15. License along with this library; if not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "winbind_client.h"
  18. #include <sys/param.h>
  19. #include <stdarg.h>
  20. #include <syslog.h>
  21. /* dynamic nsswitch with "new" getpw* nsdispatch API available */
  22. #if defined(NSS_MODULE_INTERFACE_VERSION) && defined(HAVE_GETPWENT_R)
  23. /*
  24. group functions
  25. ---------------
  26. */
  27. static struct group _winbind_group;
  28. static char _winbind_groupbuf[1024];
  29. int
  30. netbsdwinbind_endgrent(void *nsrv, void *nscb, va_list ap)
  31. {
  32. int rv;
  33. rv = _nss_winbind_endgrent();
  34. return rv;
  35. }
  36. int
  37. netbsdwinbind_setgrent(void *nsrv, void *nscb, va_list ap)
  38. {
  39. int rv;
  40. rv = _nss_winbind_setgrent();
  41. return rv;
  42. }
  43. int
  44. netbsdwinbind_getgrent(void *nsrv, void *nscb, va_list ap)
  45. {
  46. struct group **retval = va_arg(ap, struct group **);
  47. int rv, rerrno;
  48. *retval = NULL;
  49. rv = _nss_winbind_getgrent_r(&_winbind_group,
  50. _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
  51. if (rv == NS_SUCCESS)
  52. *retval = &_winbind_group;
  53. return rv;
  54. }
  55. int
  56. netbsdwinbind_getgrent_r(void *nsrv, void *nscb, va_list ap)
  57. {
  58. int *retval = va_arg(ap, int *);
  59. struct group *grp = va_arg(ap, struct group *);
  60. char *buffer = va_arg(ap, char *);
  61. size_t buflen = va_arg(ap, size_t);
  62. struct group **result = va_arg(ap, struct group **);
  63. int rv, rerrno;
  64. *result = NULL;
  65. rerrno = 0;
  66. rv = _nss_winbind_getgrent_r(grp, buffer, buflen, &rerrno);
  67. if (rv == NS_SUCCESS)
  68. *result = grp;
  69. else
  70. *retval = rerrno;
  71. return rv;
  72. }
  73. int
  74. netbsdwinbind_getgrgid(void *nsrv, void *nscb, va_list ap)
  75. {
  76. struct group **retval = va_arg(ap, struct group **);
  77. gid_t gid = va_arg(ap, gid_t);
  78. int rv, rerrno;
  79. *retval = NULL;
  80. rv = _nss_winbind_getgrgid_r(gid, &_winbind_group,
  81. _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
  82. if (rv == NS_SUCCESS)
  83. *retval = &_winbind_group;
  84. return rv;
  85. }
  86. int
  87. netbsdwinbind_getgrgid_r(void *nsrv, void *nscb, va_list ap)
  88. {
  89. int *retval = va_arg(ap, int *);
  90. gid_t gid = va_arg(ap, gid_t);
  91. struct group *grp = va_arg(ap, struct group *);
  92. char *buffer = va_arg(ap, char *);
  93. size_t buflen = va_arg(ap, size_t);
  94. struct group **result = va_arg(ap, struct group **);
  95. int rv, rerrno;
  96. *result = NULL;
  97. rerrno = 0;
  98. rv = _nss_winbind_getgrgid_r(gid, grp, buffer, buflen, &rerrno);
  99. if (rv == NS_SUCCESS)
  100. *result = grp;
  101. else
  102. *retval = rerrno;
  103. return rv;
  104. }
  105. int
  106. netbsdwinbind_getgrnam(void *nsrv, void *nscb, va_list ap)
  107. {
  108. struct group **retval = va_arg(ap, struct group **);
  109. const char *name = va_arg(ap, const char *);
  110. int rv, rerrno;
  111. *retval = NULL;
  112. rv = _nss_winbind_getgrnam_r(name, &_winbind_group,
  113. _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
  114. if (rv == NS_SUCCESS)
  115. *retval = &_winbind_group;
  116. return rv;
  117. }
  118. int
  119. netbsdwinbind_getgrnam_r(void *nsrv, void *nscb, va_list ap)
  120. {
  121. int *retval = va_arg(ap, int *);
  122. const char *name = va_arg(ap, const char *);
  123. struct group *grp = va_arg(ap, struct group *);
  124. char *buffer = va_arg(ap, char *);
  125. size_t buflen = va_arg(ap, size_t);
  126. struct group **result = va_arg(ap, struct group **);
  127. int rv, rerrno;
  128. *result = NULL;
  129. rerrno = 0;
  130. rv = _nss_winbind_getgrnam_r(name, grp, buffer, buflen, &rerrno);
  131. if (rv == NS_SUCCESS)
  132. *result = grp;
  133. else
  134. *retval = rerrno;
  135. return rv;
  136. }
  137. int
  138. netbsdwinbind_getgroupmembership(void *nsrv, void *nscb, va_list ap)
  139. {
  140. int *result = va_arg(ap, int *);
  141. const char *uname = va_arg(ap, const char *);
  142. gid_t *groups = va_arg(ap, gid_t *);
  143. int maxgrp = va_arg(ap, int);
  144. int *groupc = va_arg(ap, int *);
  145. struct winbindd_request request = {
  146. .wb_flags = WBFLAG_FROM_NSS,
  147. };
  148. struct winbindd_response response = {
  149. .length = 0,
  150. }
  151. gid_t *wblistv;
  152. int wblistc, i, isdup, dupc;
  153. strncpy(request.data.username, uname,
  154. sizeof(request.data.username) - 1);
  155. i = winbindd_request_response(NULL, WINBINDD_GETGROUPS,
  156. &request, &response);
  157. if (i != NSS_STATUS_SUCCESS)
  158. return NS_NOTFOUND;
  159. wblistv = (gid_t *)response.extra_data.data;
  160. wblistc = response.data.num_entries;
  161. for (i = 0; i < wblistc; i++) { /* add winbind gids */
  162. isdup = 0; /* skip duplicates */
  163. for (dupc = 0; dupc < MIN(maxgrp, *groupc); dupc++) {
  164. if (groups[dupc] == wblistv[i]) {
  165. isdup = 1;
  166. break;
  167. }
  168. }
  169. if (isdup)
  170. continue;
  171. if (*groupc < maxgrp) /* add this gid */
  172. groups[*groupc] = wblistv[i];
  173. else
  174. *result = -1;
  175. (*groupc)++;
  176. }
  177. SAFE_FREE(wblistv);
  178. return NS_NOTFOUND;
  179. }
  180. /*
  181. passwd functions
  182. ----------------
  183. */
  184. static struct passwd _winbind_passwd;
  185. static char _winbind_passwdbuf[1024];
  186. int
  187. netbsdwinbind_endpwent(void *nsrv, void *nscb, va_list ap)
  188. {
  189. int rv;
  190. rv = _nss_winbind_endpwent();
  191. return rv;
  192. }
  193. int
  194. netbsdwinbind_setpwent(void *nsrv, void *nscb, va_list ap)
  195. {
  196. int rv;
  197. rv = _nss_winbind_setpwent();
  198. return rv;
  199. }
  200. int
  201. netbsdwinbind_getpwent(void *nsrv, void *nscb, va_list ap)
  202. {
  203. struct passwd **retval = va_arg(ap, struct passwd **);
  204. int rv, rerrno;
  205. *retval = NULL;
  206. rv = _nss_winbind_getpwent_r(&_winbind_passwd,
  207. _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
  208. if (rv == NS_SUCCESS)
  209. *retval = &_winbind_passwd;
  210. return rv;
  211. }
  212. int
  213. netbsdwinbind_getpwent_r(void *nsrv, void *nscb, va_list ap)
  214. {
  215. int *retval = va_arg(ap, int *);
  216. struct passwd *pw = va_arg(ap, struct passwd *);
  217. char *buffer = va_arg(ap, char *);
  218. size_t buflen = va_arg(ap, size_t);
  219. struct passwd **result = va_arg(ap, struct passwd **);
  220. int rv, rerrno;
  221. *result = NULL;
  222. rerrno = 0;
  223. rv = _nss_winbind_getpwent_r(pw, buffer, buflen, &rerrno);
  224. if (rv == NS_SUCCESS)
  225. *result = pw;
  226. else
  227. *retval = rerrno;
  228. return rv;
  229. }
  230. int
  231. netbsdwinbind_getpwnam(void *nsrv, void *nscb, va_list ap)
  232. {
  233. struct passwd **retval = va_arg(ap, struct passwd **);
  234. const char *name = va_arg(ap, const char *);
  235. int rv, rerrno;
  236. *retval = NULL;
  237. rv = _nss_winbind_getpwnam_r(name, &_winbind_passwd,
  238. _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
  239. if (rv == NS_SUCCESS)
  240. *retval = &_winbind_passwd;
  241. return rv;
  242. }
  243. int
  244. netbsdwinbind_getpwnam_r(void *nsrv, void *nscb, va_list ap)
  245. {
  246. int *retval = va_arg(ap, int *);
  247. const char *name = va_arg(ap, const char *);
  248. struct passwd *pw = va_arg(ap, struct passwd *);
  249. char *buffer = va_arg(ap, char *);
  250. size_t buflen = va_arg(ap, size_t);
  251. struct passwd **result = va_arg(ap, struct passwd **);
  252. int rv, rerrno;
  253. *result = NULL;
  254. rerrno = 0;
  255. rv = _nss_winbind_getpwnam_r(name, pw, buffer, buflen, &rerrno);
  256. if (rv == NS_SUCCESS)
  257. *result = pw;
  258. else
  259. *retval = rerrno;
  260. return rv;
  261. }
  262. int
  263. netbsdwinbind_getpwuid(void *nsrv, void *nscb, va_list ap)
  264. {
  265. struct passwd **retval = va_arg(ap, struct passwd **);
  266. uid_t uid = va_arg(ap, uid_t);
  267. int rv, rerrno;
  268. *retval = NULL;
  269. rv = _nss_winbind_getpwuid_r(uid, &_winbind_passwd,
  270. _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
  271. if (rv == NS_SUCCESS)
  272. *retval = &_winbind_passwd;
  273. return rv;
  274. }
  275. int
  276. netbsdwinbind_getpwuid_r(void *nsrv, void *nscb, va_list ap)
  277. {
  278. int *retval = va_arg(ap, int *);
  279. uid_t uid = va_arg(ap, uid_t);
  280. struct passwd *pw = va_arg(ap, struct passwd *);
  281. char *buffer = va_arg(ap, char *);
  282. size_t buflen = va_arg(ap, size_t);
  283. struct passwd **result = va_arg(ap, struct passwd **);
  284. int rv, rerrno;
  285. *result = NULL;
  286. rerrno = 0;
  287. rv = _nss_winbind_getpwuid_r(uid, pw, buffer, buflen, &rerrno);
  288. if (rv == NS_SUCCESS)
  289. *result = pw;
  290. else
  291. *retval = rerrno;
  292. return rv;
  293. }
  294. /*
  295. nsswitch module setup
  296. ---------------------
  297. */
  298. static ns_mtab winbind_methods[] = {
  299. { NSDB_GROUP, "endgrent", netbsdwinbind_endgrent, NULL },
  300. { NSDB_GROUP, "getgrent", netbsdwinbind_getgrent, NULL },
  301. { NSDB_GROUP, "getgrent_r", netbsdwinbind_getgrent_r, NULL },
  302. { NSDB_GROUP, "getgrgid", netbsdwinbind_getgrgid, NULL },
  303. { NSDB_GROUP, "getgrgid_r", netbsdwinbind_getgrgid_r, NULL },
  304. { NSDB_GROUP, "getgrnam", netbsdwinbind_getgrnam, NULL },
  305. { NSDB_GROUP, "getgrnam_r", netbsdwinbind_getgrnam_r, NULL },
  306. { NSDB_GROUP, "setgrent", netbsdwinbind_setgrent, NULL },
  307. { NSDB_GROUP, "setgroupent", netbsdwinbind_setgrent, NULL },
  308. { NSDB_GROUP, "getgroupmembership", netbsdwinbind_getgroupmembership, NULL },
  309. { NSDB_PASSWD, "endpwent", netbsdwinbind_endpwent, NULL },
  310. { NSDB_PASSWD, "getpwent", netbsdwinbind_getpwent, NULL },
  311. { NSDB_PASSWD, "getpwent_r", netbsdwinbind_getpwent_r, NULL },
  312. { NSDB_PASSWD, "getpwnam", netbsdwinbind_getpwnam, NULL },
  313. { NSDB_PASSWD, "getpwnam_r", netbsdwinbind_getpwnam_r, NULL },
  314. { NSDB_PASSWD, "getpwuid", netbsdwinbind_getpwuid, NULL },
  315. { NSDB_PASSWD, "getpwuid_r", netbsdwinbind_getpwuid_r, NULL },
  316. { NSDB_PASSWD, "setpassent", netbsdwinbind_setpwent, NULL },
  317. { NSDB_PASSWD, "setpwent", netbsdwinbind_setpwent, NULL },
  318. };
  319. ns_mtab *
  320. nss_module_register(const char *source, unsigned int *mtabsize,
  321. nss_module_unregister_fn *unreg)
  322. {
  323. *mtabsize = sizeof(winbind_methods)/sizeof(winbind_methods[0]);
  324. *unreg = NULL;
  325. return (winbind_methods);
  326. }
  327. #endif /* NSS_MODULE_INTERFACE_VERSION && HAVE_GETPWENT_R */