r19725: sync samba3's ldb with samba4
[kai/samba-autobuild/.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 Library General Public
8    License as published by the Free Software Foundation; either
9    version 2 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 Library General Public
17    License along with this library; if not, write to the
18    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA  02111-1307, USA.   
20 */
21
22 #include "ldb-nss.h"
23
24 extern struct _ldb_nss_context *_ldb_nss_ctx;
25
26 const char *_ldb_nss_pw_attrs[] = {
27         "uid",
28         "userPassword",
29         "uidNumber",
30         "gidNumber",
31         "gecos",
32         "homeDirectory",
33         "loginShell",
34         NULL
35 };
36
37 NSS_STATUS _nss_ldb_setpwent(void)
38 {
39         int ret;
40         ret = _ldb_nss_init();
41         if (ret != NSS_STATUS_SUCCESS) {
42                 return ret;
43         }
44
45         _ldb_nss_ctx->pw_cur = 0;
46         if (_ldb_nss_ctx->pw_res != NULL) {
47                 talloc_free(_ldb_nss_ctx->pw_res);
48                 _ldb_nss_ctx->pw_res = NULL;
49         }
50
51         ret = ldb_search(_ldb_nss_ctx->ldb,
52                          _ldb_nss_ctx->base,
53                          LDB_SCOPE_SUBTREE,
54                          _LDB_NSS_PWENT_FILTER,
55                          _ldb_nss_pw_attrs,
56                          &_ldb_nss_ctx->pw_res);
57         if (ret != LDB_SUCCESS) {
58                 return NSS_STATUS_UNAVAIL;
59         }
60
61         return NSS_STATUS_SUCCESS;
62 }
63
64 NSS_STATUS _nss_ldb_endpwent(void)
65 {
66         int ret;
67
68         ret = _ldb_nss_init();
69         if (ret != NSS_STATUS_SUCCESS) {
70                 return ret;
71         }
72
73         _ldb_nss_ctx->pw_cur = 0;
74         if (_ldb_nss_ctx->pw_res) {
75                 talloc_free(_ldb_nss_ctx->pw_res);
76                 _ldb_nss_ctx->pw_res = NULL;
77         }
78
79         return NSS_STATUS_SUCCESS;
80 }
81
82 NSS_STATUS _nss_ldb_getpwent_r(struct passwd *result_buf,
83                                 char *buffer,
84                                 int buflen,
85                                 int *errnop)
86 {
87         int ret;
88
89         ret = _ldb_nss_init();
90         if (ret != NSS_STATUS_SUCCESS) {
91                 return ret;
92         }
93
94         *errnop = 0;
95
96         if (_ldb_nss_ctx->pw_cur >= _ldb_nss_ctx->pw_res->count) {
97                 /* already returned all entries */
98                 return NSS_STATUS_NOTFOUND;
99         }
100
101         ret = _ldb_nss_fill_passwd(result_buf,
102                                    buffer,
103                                    buflen,
104                                    errnop,
105                                    _ldb_nss_ctx->pw_res->msgs[_ldb_nss_ctx->pw_cur]);
106         if (ret != NSS_STATUS_SUCCESS) {
107                 return ret;
108         }
109
110         _ldb_nss_ctx->pw_cur++;
111
112         return NSS_STATUS_SUCCESS;
113 }
114
115 NSS_STATUS _nss_ldb_getpwuid_r(uid_t uid, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop)
116 {
117         int ret;
118         char *filter;
119         struct ldb_result *res;
120
121         if (uid == 0) { /* we don't serve root uid by policy */
122                 *errnop = errno = ENOENT;
123                 return NSS_STATUS_NOTFOUND;
124         }
125
126         ret = _ldb_nss_init();
127         if (ret != NSS_STATUS_SUCCESS) {
128                 return ret;
129         }
130
131         /* build the filter for this uid */
132         filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWUID_FILTER, uid);
133         if (filter == NULL) {
134                 /* this is a fatal error */
135                 *errnop = errno = ENOMEM;
136                 ret = NSS_STATUS_UNAVAIL;
137                 goto done;
138         }
139
140         /* search the entry */
141         ret = ldb_search(_ldb_nss_ctx->ldb,
142                          _ldb_nss_ctx->base,
143                          LDB_SCOPE_SUBTREE,
144                          filter,
145                          _ldb_nss_pw_attrs,
146                          &res);
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->base,
204                          LDB_SCOPE_SUBTREE,
205                          filter,
206                          _ldb_nss_pw_attrs,
207                          &res);
208         if (ret != LDB_SUCCESS) {
209                 /* this is a fatal error */
210                 *errnop = errno = ENOENT;
211                 ret = NSS_STATUS_UNAVAIL;
212                 goto done;
213         }
214
215         /* if none found return */
216         if (res->count == 0) {
217                 *errnop = errno = ENOENT;
218                 ret = NSS_STATUS_NOTFOUND;
219                 goto done;
220         }
221
222         if (res->count != 1) {
223                 /* this is a fatal error */
224                 *errnop = errno = ENOENT;
225                 ret = NSS_STATUS_UNAVAIL;
226                 goto done;
227         }
228
229         /* fill in the passwd struct */
230         ret = _ldb_nss_fill_passwd(result_buf,
231                                    buffer,
232                                    buflen,
233                                    errnop,
234                                    res->msgs[0]);
235
236 done:
237         talloc_free(filter);
238         talloc_free(res);
239         return ret;
240 }
241