0af7af998187c209ace868350267260c1f7074b4
[jra/samba/.git] / source3 / lib / ldb / nssldb / ldb-pwd.c
1 /* 
2    LDB nsswitch module
3
4    Copyright (C) Simo Sorce 2006
5    
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    
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15    
16    You should have received a copy of the GNU Lesser General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "ldb-nss.h"
21
22 extern struct _ldb_nss_context *_ldb_nss_ctx;
23
24 const char *_ldb_nss_pw_attrs[] = {
25         "uid",
26         "userPassword",
27         "uidNumber",
28         "gidNumber",
29         "gecos",
30         "homeDirectory",
31         "loginShell",
32         NULL
33 };
34
35 NSS_STATUS _nss_ldb_setpwent(void)
36 {
37         int ret;
38         ret = _ldb_nss_init();
39         if (ret != NSS_STATUS_SUCCESS) {
40                 return ret;
41         }
42
43         _ldb_nss_ctx->pw_cur = 0;
44         if (_ldb_nss_ctx->pw_res != NULL) {
45                 talloc_free(_ldb_nss_ctx->pw_res);
46                 _ldb_nss_ctx->pw_res = NULL;
47         }
48
49         ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, 
50                                          &_ldb_nss_ctx->pw_res,
51                          _ldb_nss_ctx->base,
52                          LDB_SCOPE_SUBTREE,
53                          _ldb_nss_pw_attrs,
54                          _LDB_NSS_PWENT_FILTER);
55         if (ret != LDB_SUCCESS) {
56                 return NSS_STATUS_UNAVAIL;
57         }
58
59         return NSS_STATUS_SUCCESS;
60 }
61
62 NSS_STATUS _nss_ldb_endpwent(void)
63 {
64         int ret;
65
66         ret = _ldb_nss_init();
67         if (ret != NSS_STATUS_SUCCESS) {
68                 return ret;
69         }
70
71         _ldb_nss_ctx->pw_cur = 0;
72         if (_ldb_nss_ctx->pw_res) {
73                 talloc_free(_ldb_nss_ctx->pw_res);
74                 _ldb_nss_ctx->pw_res = NULL;
75         }
76
77         return NSS_STATUS_SUCCESS;
78 }
79
80 NSS_STATUS _nss_ldb_getpwent_r(struct passwd *result_buf,
81                                 char *buffer,
82                                 int buflen,
83                                 int *errnop)
84 {
85         int ret;
86
87         ret = _ldb_nss_init();
88         if (ret != NSS_STATUS_SUCCESS) {
89                 return ret;
90         }
91
92         *errnop = 0;
93
94         if (_ldb_nss_ctx->pw_cur >= _ldb_nss_ctx->pw_res->count) {
95                 /* already returned all entries */
96                 return NSS_STATUS_NOTFOUND;
97         }
98
99         ret = _ldb_nss_fill_passwd(result_buf,
100                                    buffer,
101                                    buflen,
102                                    errnop,
103                                    _ldb_nss_ctx->pw_res->msgs[_ldb_nss_ctx->pw_cur]);
104         if (ret != NSS_STATUS_SUCCESS) {
105                 return ret;
106         }
107
108         _ldb_nss_ctx->pw_cur++;
109
110         return NSS_STATUS_SUCCESS;
111 }
112
113 NSS_STATUS _nss_ldb_getpwuid_r(uid_t uid, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop)
114 {
115         int ret;
116         char *filter;
117         struct ldb_result *res;
118
119         if (uid == 0) { /* we don't serve root uid by policy */
120                 *errnop = errno = ENOENT;
121                 return NSS_STATUS_NOTFOUND;
122         }
123
124         ret = _ldb_nss_init();
125         if (ret != NSS_STATUS_SUCCESS) {
126                 return ret;
127         }
128
129         /* build the filter for this uid */
130         filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWUID_FILTER, uid);
131         if (filter == NULL) {
132                 /* this is a fatal error */
133                 *errnop = errno = ENOMEM;
134                 ret = NSS_STATUS_UNAVAIL;
135                 goto done;
136         }
137
138         /* search the entry */
139         ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &res, 
140                          _ldb_nss_ctx->base,
141                          LDB_SCOPE_SUBTREE,
142                          _ldb_nss_pw_attrs,
143                          filter
144                          );
145         if (ret != LDB_SUCCESS) {
146                 /* this is a fatal error */
147                 *errnop = errno = ENOENT;
148                 ret = NSS_STATUS_UNAVAIL;
149                 goto done;
150         }
151
152         /* if none found return */
153         if (res->count == 0) {
154                 *errnop = errno = ENOENT;
155                 ret = NSS_STATUS_NOTFOUND;
156                 goto done;
157         }
158
159         if (res->count != 1) {
160                 /* this is a fatal error */
161                 *errnop = errno = ENOENT;
162                 ret = NSS_STATUS_UNAVAIL;
163                 goto done;
164         }
165
166         /* fill in the passwd struct */
167         ret = _ldb_nss_fill_passwd(result_buf,
168                                    buffer,
169                                    buflen,
170                                    errnop,
171                                    res->msgs[0]);
172
173 done:
174         talloc_free(filter);
175         talloc_free(res);
176         return ret;
177 }
178
179 NSS_STATUS _nss_ldb_getpwnam_r(const char *name, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop)
180 {
181         int ret;
182         char *filter;
183         struct ldb_result *res;
184
185         ret = _ldb_nss_init();
186         if (ret != NSS_STATUS_SUCCESS) {
187                 return ret;
188         }
189
190         /* build the filter for this name */
191         filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWNAM_FILTER, name);
192         if (filter == NULL) {
193                 /* this is a fatal error */
194                 *errnop = errno = ENOENT;
195                 ret = NSS_STATUS_UNAVAIL;
196                 goto done;
197         }
198
199         /* search the entry */
200         ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &res,
201                          _ldb_nss_ctx->base,
202                          LDB_SCOPE_SUBTREE,
203                          _ldb_nss_pw_attrs,
204                          filter);
205         if (ret != LDB_SUCCESS) {
206                 /* this is a fatal error */
207                 *errnop = errno = ENOENT;
208                 ret = NSS_STATUS_UNAVAIL;
209                 goto done;
210         }
211
212         /* if none found return */
213         if (res->count == 0) {
214                 *errnop = errno = ENOENT;
215                 ret = NSS_STATUS_NOTFOUND;
216                 goto done;
217         }
218
219         if (res->count != 1) {
220                 /* this is a fatal error */
221                 *errnop = errno = ENOENT;
222                 ret = NSS_STATUS_UNAVAIL;
223                 goto done;
224         }
225
226         /* fill in the passwd struct */
227         ret = _ldb_nss_fill_passwd(result_buf,
228                                    buffer,
229                                    buflen,
230                                    errnop,
231                                    res->msgs[0]);
232
233 done:
234         talloc_free(filter);
235         talloc_free(res);
236         return ret;
237 }
238