import HEAD into svn+ssh://svn.samba.org/home/svn/samba/trunk
[metze/old/v3-2-winbind-ndr.git] / source / nsswitch / winbind_nss_solaris.c
1 /*
2   Solaris NSS wrapper for winbind 
3   - Shirish Kalele 2000
4   
5   Based on Luke Howard's ldap_nss module for Solaris 
6   */
7
8 /*
9   Copyright (C) 1997-2003 Luke Howard.
10   This file is part of the nss_ldap library.
11
12   The nss_ldap library is free software; you can redistribute it and/or
13   modify it under the terms of the GNU Library General Public License as
14   published by the Free Software Foundation; either version 2 of the
15   License, or (at your option) any later version.
16
17   The nss_ldap library is distributed in the hope that it will be useful,
18   but WITHOUT ANY WARRANTY; without even the implied warranty of
19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20   Library General Public License for more details.
21
22   You should have received a copy of the GNU Library General Public
23   License along with the nss_ldap library; see the file COPYING.LIB.  If not,
24   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25   Boston, MA 02111-1307, USA.
26 */
27
28 #include <stdlib.h>
29 #include <sys/types.h>
30 #include <sys/param.h>
31 #include <string.h>
32 #include <pwd.h>
33 #include "includes.h"
34 #include <syslog.h>
35 #if !defined(HPUX)
36 #include <sys/syslog.h>
37 #endif /*hpux*/
38 #include "winbind_nss_config.h"
39
40 #if defined(HAVE_NSS_COMMON_H) || defined(HPUX) 
41
42 #undef NSS_DEBUG
43
44 #ifdef NSS_DEBUG
45 #define NSS_DEBUG(str) syslog(LOG_DEBUG, "nss_winbind: %s", str);
46 #else
47 #define NSS_DEBUG(str) ;
48 #endif
49
50 #define NSS_ARGS(args) ((nss_XbyY_args_t *)args)
51
52 #define make_pwent_str(dest, src)                                       \
53 {                                                                       \
54   if((dest = get_static(buffer, buflen, strlen(src)+1)) == NULL)        \
55     {                                                                   \
56       *errnop = ERANGE;                                                 \
57       NSS_DEBUG("ERANGE error");                                        \
58       return NSS_STATUS_TRYAGAIN;                                       \
59     }                                                                   \
60   strcpy(dest, src);                                                    \
61 }
62
63 static NSS_STATUS _nss_winbind_setpwent_solwrap (nss_backend_t* be, void* args)
64 {
65         NSS_DEBUG("_nss_winbind_setpwent_solwrap");
66         return _nss_winbind_setpwent();
67 }
68
69 static NSS_STATUS
70 _nss_winbind_endpwent_solwrap (nss_backend_t * be, void *args)
71 {
72         NSS_DEBUG("_nss_winbind_endpwent_solwrap");
73         return _nss_winbind_endpwent();
74 }
75
76 static NSS_STATUS
77 _nss_winbind_getpwent_solwrap (nss_backend_t* be, void *args)
78 {
79         NSS_STATUS ret;
80         char* buffer = NSS_ARGS(args)->buf.buffer;
81         int buflen = NSS_ARGS(args)->buf.buflen;
82         struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
83         int* errnop = &NSS_ARGS(args)->erange;
84         char logmsg[80];
85
86         ret = _nss_winbind_getpwent_r(result, buffer, 
87                                       buflen, errnop);
88
89         if(ret == NSS_STATUS_SUCCESS)
90                 {
91                         snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning user: %s\n",
92                                  result->pw_name);
93                         NSS_DEBUG(logmsg);
94                         NSS_ARGS(args)->returnval = (void*) result;
95                 } else {
96                         snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning error: %d.\n",ret);
97                         NSS_DEBUG(logmsg);
98                 }
99     
100         return ret;
101 }
102
103 static NSS_STATUS
104 _nss_winbind_getpwnam_solwrap (nss_backend_t* be, void* args)
105 {
106         NSS_STATUS ret;
107         struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
108
109         NSS_DEBUG("_nss_winbind_getpwnam_solwrap");
110
111         ret = _nss_winbind_getpwnam_r (NSS_ARGS(args)->key.name,
112                                                 result,
113                                                 NSS_ARGS(args)->buf.buffer,
114                                                 NSS_ARGS(args)->buf.buflen,
115                                                 &NSS_ARGS(args)->erange);
116         if(ret == NSS_STATUS_SUCCESS)
117                 NSS_ARGS(args)->returnval = (void*) result;
118   
119         return ret;
120 }
121
122 static NSS_STATUS
123 _nss_winbind_getpwuid_solwrap(nss_backend_t* be, void* args)
124 {
125         NSS_STATUS ret;
126         struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
127   
128         NSS_DEBUG("_nss_winbind_getpwuid_solwrap");
129         ret = _nss_winbind_getpwuid_r (NSS_ARGS(args)->key.uid,
130                                        result,
131                                        NSS_ARGS(args)->buf.buffer,
132                                        NSS_ARGS(args)->buf.buflen,
133                                        &NSS_ARGS(args)->erange);
134         if(ret == NSS_STATUS_SUCCESS)
135                 NSS_ARGS(args)->returnval = (void*) result;
136   
137         return ret;
138 }
139
140 static NSS_STATUS _nss_winbind_passwd_destr (nss_backend_t * be, void *args)
141 {
142         SAFE_FREE(be);
143         NSS_DEBUG("_nss_winbind_passwd_destr");
144         return NSS_STATUS_SUCCESS;
145 }
146
147 static nss_backend_op_t passwd_ops[] =
148 {
149         _nss_winbind_passwd_destr,
150         _nss_winbind_endpwent_solwrap,          /* NSS_DBOP_ENDENT */
151         _nss_winbind_setpwent_solwrap,          /* NSS_DBOP_SETENT */
152         _nss_winbind_getpwent_solwrap,          /* NSS_DBOP_GETENT */
153         _nss_winbind_getpwnam_solwrap,          /* NSS_DBOP_PASSWD_BYNAME */
154         _nss_winbind_getpwuid_solwrap           /* NSS_DBOP_PASSWD_BYUID */
155 };
156
157 nss_backend_t*
158 _nss_winbind_passwd_constr (const char* db_name,
159                             const char* src_name,
160                             const char* cfg_args)
161 {
162         nss_backend_t *be;
163   
164         if(!(be = (nss_backend_t*) malloc(sizeof(nss_backend_t))) )
165                 return NULL;
166
167         be->ops = passwd_ops;
168         be->n_ops = sizeof(passwd_ops) / sizeof(nss_backend_op_t);
169
170         NSS_DEBUG("Initialized nss_winbind passwd backend");
171         return be;
172 }
173
174 /*****************************************************************
175  GROUP database backend
176  *****************************************************************/
177
178 static NSS_STATUS _nss_winbind_setgrent_solwrap (nss_backend_t* be, void* args)
179 {
180         NSS_DEBUG("_nss_winbind_setgrent_solwrap");
181         return _nss_winbind_setgrent();
182 }
183
184 static NSS_STATUS
185 _nss_winbind_endgrent_solwrap (nss_backend_t * be, void *args)
186 {
187         NSS_DEBUG("_nss_winbind_endgrent_solwrap");
188         return _nss_winbind_endgrent();
189 }
190
191 static NSS_STATUS
192 _nss_winbind_getgrent_solwrap(nss_backend_t* be, void* args)
193 {
194         NSS_STATUS ret;
195         char* buffer = NSS_ARGS(args)->buf.buffer;
196         int buflen = NSS_ARGS(args)->buf.buflen;
197         struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
198         int* errnop = &NSS_ARGS(args)->erange;
199         char logmsg[80];
200
201         ret = _nss_winbind_getgrent_r(result, buffer, 
202                                       buflen, errnop);
203
204         if(ret == NSS_STATUS_SUCCESS)
205                 {
206                         snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning group: %s\n", result->gr_name);
207                         NSS_DEBUG(logmsg);
208                         NSS_ARGS(args)->returnval = (void*) result;
209                 } else {
210                         snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning error: %d.\n", ret);
211                         NSS_DEBUG(logmsg);
212                 }
213
214         return ret;
215         
216 }
217
218 static NSS_STATUS
219 _nss_winbind_getgrnam_solwrap(nss_backend_t* be, void* args)
220 {
221         NSS_STATUS ret;
222         struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
223
224         NSS_DEBUG("_nss_winbind_getgrnam_solwrap");
225         ret = _nss_winbind_getgrnam_r(NSS_ARGS(args)->key.name,
226                                       result,
227                                       NSS_ARGS(args)->buf.buffer,
228                                       NSS_ARGS(args)->buf.buflen,
229                                       &NSS_ARGS(args)->erange);
230
231         if(ret == NSS_STATUS_SUCCESS)
232                 NSS_ARGS(args)->returnval = (void*) result;
233   
234         return ret;
235 }
236   
237 static NSS_STATUS
238 _nss_winbind_getgrgid_solwrap(nss_backend_t* be, void* args)
239 {
240         NSS_STATUS ret;
241         struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
242
243         NSS_DEBUG("_nss_winbind_getgrgid_solwrap");
244         ret = _nss_winbind_getgrgid_r (NSS_ARGS(args)->key.gid,
245                                        result,
246                                        NSS_ARGS(args)->buf.buffer,
247                                        NSS_ARGS(args)->buf.buflen,
248                                        &NSS_ARGS(args)->erange);
249
250         if(ret == NSS_STATUS_SUCCESS)
251                 NSS_ARGS(args)->returnval = (void*) result;
252
253         return ret;
254 }
255
256 static NSS_STATUS
257 _nss_winbind_getgroupsbymember_solwrap(nss_backend_t* be, void* args)
258 {
259         int errnop;
260         struct nss_groupsbymem *gmem = (struct nss_groupsbymem *)args;
261
262         NSS_DEBUG("_nss_winbind_getgroupsbymember");
263
264         _nss_winbind_initgroups_dyn(gmem->username,
265                 gmem->gid_array[0], /* Primary Group */
266                 &gmem->numgids,
267                 &gmem->maxgids,
268                 &gmem->gid_array,
269                 gmem->maxgids,
270                 &errnop);
271
272         /*
273         * Always return NOTFOUND so nsswitch will get info from all
274         * the database backends specified in the nsswitch.conf file.
275         */
276         return NSS_STATUS_NOTFOUND;
277 }
278
279 static NSS_STATUS
280 _nss_winbind_group_destr (nss_backend_t* be, void* args)
281 {
282         SAFE_FREE(be);
283         NSS_DEBUG("_nss_winbind_group_destr");
284         return NSS_STATUS_SUCCESS;
285 }
286
287 static nss_backend_op_t group_ops[] = 
288 {
289         _nss_winbind_group_destr,
290         _nss_winbind_endgrent_solwrap,
291         _nss_winbind_setgrent_solwrap,
292         _nss_winbind_getgrent_solwrap,
293         _nss_winbind_getgrnam_solwrap,
294         _nss_winbind_getgrgid_solwrap,
295         _nss_winbind_getgroupsbymember_solwrap
296 }; 
297
298 nss_backend_t*
299 _nss_winbind_group_constr (const char* db_name,
300                            const char* src_name,
301                            const char* cfg_args)
302 {
303         nss_backend_t* be;
304
305         if(!(be = (nss_backend_t*) malloc(sizeof(nss_backend_t))) )
306                 return NULL;
307
308         be->ops = group_ops;
309         be->n_ops = sizeof(group_ops) / sizeof(nss_backend_op_t);
310   
311         NSS_DEBUG("Initialized nss_winbind group backend");
312         return be;
313 }
314
315 #endif /* SUN_NSS */