6ab103a6fed6a19cdedbef91060626af5faf384c
[ira/wip.git] / source4 / 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,
50                          _ldb_nss_ctx->ldb,
51                          &_ldb_nss_ctx->pw_res,
52                          _ldb_nss_ctx->base,
53                          LDB_SCOPE_SUBTREE,
54                          _ldb_nss_pw_attrs,
55                          _LDB_NSS_PWENT_FILTER);
56         if (ret != LDB_SUCCESS) {
57                 return NSS_STATUS_UNAVAIL;
58         }
59
60         return NSS_STATUS_SUCCESS;
61 }
62
63 NSS_STATUS _nss_ldb_endpwent(void)
64 {
65         int ret;
66
67         ret = _ldb_nss_init();
68         if (ret != NSS_STATUS_SUCCESS) {
69                 return ret;
70         }
71
72         _ldb_nss_ctx->pw_cur = 0;
73         if (_ldb_nss_ctx->pw_res) {
74                 talloc_free(_ldb_nss_ctx->pw_res);
75                 _ldb_nss_ctx->pw_res = NULL;
76         }
77
78         return NSS_STATUS_SUCCESS;
79 }
80
81 NSS_STATUS _nss_ldb_getpwent_r(struct passwd *result_buf,
82                                 char *buffer,
83                                 int buflen,
84                                 int *errnop)
85 {
86         int ret;
87
88         ret = _ldb_nss_init();
89         if (ret != NSS_STATUS_SUCCESS) {
90                 return ret;
91         }
92
93         *errnop = 0;
94
95         if (_ldb_nss_ctx->pw_cur >= _ldb_nss_ctx->pw_res->count) {
96                 /* already returned all entries */
97                 return NSS_STATUS_NOTFOUND;
98         }
99
100         ret = _ldb_nss_fill_passwd(result_buf,
101                                    buffer,
102                                    buflen,
103                                    errnop,
104                                    _ldb_nss_ctx->pw_res->msgs[_ldb_nss_ctx->pw_cur]);
105         if (ret != NSS_STATUS_SUCCESS) {
106                 return ret;
107         }
108
109         _ldb_nss_ctx->pw_cur++;
110
111         return NSS_STATUS_SUCCESS;
112 }
113
114 NSS_STATUS _nss_ldb_getpwuid_r(uid_t uid, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop)
115 {
116         int ret;
117         char *filter;
118         struct ldb_result *res;
119
120         if (uid == 0) { /* we don't serve root uid by policy */
121                 *errnop = errno = ENOENT;
122                 return NSS_STATUS_NOTFOUND;
123         }
124
125         ret = _ldb_nss_init();
126         if (ret != NSS_STATUS_SUCCESS) {
127                 return ret;
128         }
129
130         /* build the filter for this uid */
131         filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWUID_FILTER, uid);
132         if (filter == NULL) {
133                 /* this is a fatal error */
134                 *errnop = errno = ENOMEM;
135                 ret = NSS_STATUS_UNAVAIL;
136                 goto done;
137         }
138
139         /* search the entry */
140         ret = ldb_search(_ldb_nss_ctx->ldb,
141                          _ldb_nss_ctx->ldb,
142                          &res,
143                          _ldb_nss_ctx->base,
144                          LDB_SCOPE_SUBTREE,
145                          _ldb_nss_pw_attrs,
146                          filter);
147         if (ret != LDB_SUCCESS) {
148                 /* this is a fatal error */
149                 *errnop = errno = ENOENT;
150                 ret = NSS_STATUS_UNAVAIL;
151                 goto done;
152         }
153
154         /* if none found return */
155         if (res->count == 0) {
156                 *errnop = errno = ENOENT;
157                 ret = NSS_STATUS_NOTFOUND;
158                 goto done;
159         }
160
161         if (res->count != 1) {
162                 /* this is a fatal error */
163                 *errnop = errno = ENOENT;
164                 ret = NSS_STATUS_UNAVAIL;
165                 goto done;
166         }
167
168         /* fill in the passwd struct */
169         ret = _ldb_nss_fill_passwd(result_buf,
170                                    buffer,
171                                    buflen,
172                                    errnop,
173                                    res->msgs[0]);
174
175 done:
176         talloc_free(filter);
177         talloc_free(res);
178         return ret;
179 }
180
181 NSS_STATUS _nss_ldb_getpwnam_r(const char *name, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop)
182 {
183         int ret;
184         char *filter;
185         struct ldb_result *res;
186
187         ret = _ldb_nss_init();
188         if (ret != NSS_STATUS_SUCCESS) {
189                 return ret;
190         }
191
192         /* build the filter for this name */
193         filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWNAM_FILTER, name);
194         if (filter == NULL) {
195                 /* this is a fatal error */
196                 *errnop = errno = ENOENT;
197                 ret = NSS_STATUS_UNAVAIL;
198                 goto done;
199         }
200
201         /* search the entry */
202         ret = ldb_search(_ldb_nss_ctx->ldb,
203                          _ldb_nss_ctx->ldb,
204                          &res,
205                          _ldb_nss_ctx->base,
206                          LDB_SCOPE_SUBTREE,
207                          _ldb_nss_pw_attrs,
208                          filter);
209         if (ret != LDB_SUCCESS) {
210                 /* this is a fatal error */
211                 *errnop = errno = ENOENT;
212                 ret = NSS_STATUS_UNAVAIL;
213                 goto done;
214         }
215
216         /* if none found return */
217         if (res->count == 0) {
218                 *errnop = errno = ENOENT;
219                 ret = NSS_STATUS_NOTFOUND;
220                 goto done;
221         }
222
223         if (res->count != 1) {
224                 /* this is a fatal error */
225                 *errnop = errno = ENOENT;
226                 ret = NSS_STATUS_UNAVAIL;
227                 goto done;
228         }
229
230         /* fill in the passwd struct */
231         ret = _ldb_nss_fill_passwd(result_buf,
232                                    buffer,
233                                    buflen,
234                                    errnop,
235                                    res->msgs[0]);
236
237 done:
238         talloc_free(filter);
239         talloc_free(res);
240         return ret;
241 }
242