~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source3/torture/nsstest.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   Unix SMB/CIFS implementation.
3
 
   nss tester for winbindd
4
 
   Copyright (C) Andrew Tridgell 2001
5
 
   Copyright (C) Tim Potter 2003
6
 
   
7
 
   This program is free software; you can redistribute it and/or modify
8
 
   it under the terms of the GNU General Public License as published by
9
 
   the Free Software Foundation; either version 3 of the License, or
10
 
   (at your option) any later version.
11
 
   
12
 
   This program is distributed in the hope that it will be useful,
13
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
   GNU General Public License for more details.
16
 
   
17
 
   You should have received a copy of the GNU General Public License
18
 
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 
*/
20
 
 
21
 
#include "includes.h"
22
 
 
23
 
#ifdef malloc
24
 
#undef malloc
25
 
#endif
26
 
#ifdef realloc
27
 
#undef realloc
28
 
#endif
29
 
 
30
 
static const char *so_path = "/lib/libnss_winbind.so";
31
 
static const char *nss_name = "winbind";
32
 
static int nss_errno;
33
 
static NSS_STATUS last_error;
34
 
static int total_errors;
35
 
 
36
 
static void *find_fn(const char *name)
37
 
{
38
 
        char *s;
39
 
        static void *h;
40
 
        void *res;
41
 
 
42
 
        if (asprintf(&s, "_nss_%s_%s", nss_name, name) < 0) {
43
 
                exit(1);
44
 
        }
45
 
 
46
 
        if (!h) {
47
 
                h = dlopen(so_path, RTLD_LAZY);
48
 
        }
49
 
        if (!h) {
50
 
                printf("Can't open shared library %s\n", so_path);
51
 
                exit(1);
52
 
        }
53
 
        res = dlsym(h, s);
54
 
        if (!res) {
55
 
                printf("Can't find function %s\n", s);
56
 
                total_errors++;
57
 
                SAFE_FREE(s);
58
 
                return NULL;
59
 
        }
60
 
        SAFE_FREE(s);
61
 
        return res;
62
 
}
63
 
 
64
 
static void report_nss_error(const char *who, NSS_STATUS status)
65
 
{
66
 
        last_error = status;
67
 
        total_errors++;
68
 
        printf("ERROR %s: NSS_STATUS=%d  %d (nss_errno=%d)\n", 
69
 
               who, status, NSS_STATUS_SUCCESS, nss_errno);
70
 
}
71
 
 
72
 
static struct passwd *nss_getpwent(void)
73
 
{
74
 
        NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *, 
75
 
                                      size_t , int *) =
76
 
                (NSS_STATUS (*)(struct passwd *, char *,
77
 
                                size_t, int *))find_fn("getpwent_r");
78
 
        static struct passwd pwd;
79
 
        static char buf[1000];
80
 
        NSS_STATUS status;
81
 
 
82
 
        if (!_nss_getpwent_r)
83
 
                return NULL;
84
 
 
85
 
        status = _nss_getpwent_r(&pwd, buf, sizeof(buf), &nss_errno);
86
 
        if (status == NSS_STATUS_NOTFOUND) {
87
 
                return NULL;
88
 
        }
89
 
        if (status != NSS_STATUS_SUCCESS) {
90
 
                report_nss_error("getpwent", status);
91
 
                return NULL;
92
 
        }
93
 
        return &pwd;
94
 
}
95
 
 
96
 
static struct passwd *nss_getpwnam(const char *name)
97
 
{
98
 
        NSS_STATUS (*_nss_getpwnam_r)(const char *, struct passwd *, char *, 
99
 
                                      size_t , int *) =
100
 
                (NSS_STATUS (*)(const char *, struct passwd *, char *,
101
 
                                size_t, int *))find_fn("getpwnam_r");
102
 
        static struct passwd pwd;
103
 
        static char buf[1000];
104
 
        NSS_STATUS status;
105
 
 
106
 
        if (!_nss_getpwnam_r)
107
 
                return NULL;
108
 
        
109
 
        status = _nss_getpwnam_r(name, &pwd, buf, sizeof(buf), &nss_errno);
110
 
        if (status == NSS_STATUS_NOTFOUND) {
111
 
                return NULL;
112
 
        }
113
 
        if (status != NSS_STATUS_SUCCESS) {
114
 
                report_nss_error("getpwnam", status);
115
 
                return NULL;
116
 
        }
117
 
        return &pwd;
118
 
}
119
 
 
120
 
static struct passwd *nss_getpwuid(uid_t uid)
121
 
{
122
 
        NSS_STATUS (*_nss_getpwuid_r)(uid_t , struct passwd *, char *, 
123
 
                                      size_t , int *) =
124
 
                (NSS_STATUS (*)(uid_t, struct passwd *, char *,
125
 
                                size_t, int *))find_fn("getpwuid_r");
126
 
        static struct passwd pwd;
127
 
        static char buf[1000];
128
 
        NSS_STATUS status;
129
 
 
130
 
        if (!_nss_getpwuid_r)
131
 
                return NULL;
132
 
        
133
 
        status = _nss_getpwuid_r(uid, &pwd, buf, sizeof(buf), &nss_errno);
134
 
        if (status == NSS_STATUS_NOTFOUND) {
135
 
                return NULL;
136
 
        }
137
 
        if (status != NSS_STATUS_SUCCESS) {
138
 
                report_nss_error("getpwuid", status);
139
 
                return NULL;
140
 
        }
141
 
        return &pwd;
142
 
}
143
 
 
144
 
static void nss_setpwent(void)
145
 
{
146
 
        NSS_STATUS (*_nss_setpwent)(void) =
147
 
                (NSS_STATUS(*)(void))find_fn("setpwent");
148
 
        NSS_STATUS status;
149
 
        
150
 
        if (!_nss_setpwent)
151
 
                return;
152
 
 
153
 
        status = _nss_setpwent();
154
 
        if (status != NSS_STATUS_SUCCESS) {
155
 
                report_nss_error("setpwent", status);
156
 
        }
157
 
}
158
 
 
159
 
static void nss_endpwent(void)
160
 
{
161
 
        NSS_STATUS (*_nss_endpwent)(void) =
162
 
                (NSS_STATUS (*)(void))find_fn("endpwent");
163
 
        NSS_STATUS status;
164
 
 
165
 
        if (!_nss_endpwent)
166
 
                return;
167
 
 
168
 
        status = _nss_endpwent();
169
 
        if (status != NSS_STATUS_SUCCESS) {
170
 
                report_nss_error("endpwent", status);
171
 
        }
172
 
}
173
 
 
174
 
 
175
 
static struct group *nss_getgrent(void)
176
 
{
177
 
        NSS_STATUS (*_nss_getgrent_r)(struct group *, char *, 
178
 
                                      size_t , int *) =
179
 
                (NSS_STATUS (*)(struct group *, char *,
180
 
                                size_t, int *))find_fn("getgrent_r");
181
 
        static struct group grp;
182
 
        static char *buf;
183
 
        static int buflen = 1024;
184
 
        NSS_STATUS status;
185
 
 
186
 
        if (!_nss_getgrent_r)
187
 
                return NULL;
188
 
 
189
 
        if (!buf) 
190
 
                buf = (char *)malloc(buflen);
191
 
 
192
 
again:  
193
 
        status = _nss_getgrent_r(&grp, buf, buflen, &nss_errno);
194
 
        if (status == NSS_STATUS_TRYAGAIN) {
195
 
                buflen *= 2;
196
 
                buf = (char *)realloc(buf, buflen);
197
 
                if (!buf) {
198
 
                        return NULL;
199
 
                }
200
 
                goto again;
201
 
        }
202
 
        if (status == NSS_STATUS_NOTFOUND) {
203
 
                SAFE_FREE(buf);
204
 
                return NULL;
205
 
        }
206
 
        if (status != NSS_STATUS_SUCCESS) {
207
 
                report_nss_error("getgrent", status);
208
 
                SAFE_FREE(buf);
209
 
                return NULL;
210
 
        }
211
 
        return &grp;
212
 
}
213
 
 
214
 
static struct group *nss_getgrnam(const char *name)
215
 
{
216
 
        NSS_STATUS (*_nss_getgrnam_r)(const char *, struct group *, char *, 
217
 
                                      size_t , int *) =
218
 
                (NSS_STATUS (*)(const char *, struct group *, char *,
219
 
                                size_t, int *))find_fn("getgrnam_r");
220
 
        static struct group grp;
221
 
        static char *buf;
222
 
        static int buflen = 1000;
223
 
        NSS_STATUS status;
224
 
 
225
 
        if (!_nss_getgrnam_r)
226
 
                return NULL;
227
 
 
228
 
        if (!buf) 
229
 
                buf = (char *)malloc(buflen);
230
 
again:  
231
 
        status = _nss_getgrnam_r(name, &grp, buf, buflen, &nss_errno);
232
 
        if (status == NSS_STATUS_TRYAGAIN) {
233
 
                buflen *= 2;
234
 
                buf = (char *)realloc(buf, buflen);
235
 
                if (!buf) {
236
 
                        return NULL;
237
 
                }
238
 
                goto again;
239
 
        }
240
 
        if (status == NSS_STATUS_NOTFOUND) {
241
 
                SAFE_FREE(buf);
242
 
                return NULL;
243
 
        }
244
 
        if (status != NSS_STATUS_SUCCESS) {
245
 
                report_nss_error("getgrnam", status);
246
 
                SAFE_FREE(buf);
247
 
                return NULL;
248
 
        }
249
 
        return &grp;
250
 
}
251
 
 
252
 
static struct group *nss_getgrgid(gid_t gid)
253
 
{
254
 
        NSS_STATUS (*_nss_getgrgid_r)(gid_t , struct group *, char *, 
255
 
                                      size_t , int *) =
256
 
                (NSS_STATUS (*)(gid_t, struct group *, char *,
257
 
                                size_t, int *))find_fn("getgrgid_r");
258
 
        static struct group grp;
259
 
        static char *buf;
260
 
        static int buflen = 1000;
261
 
        NSS_STATUS status;
262
 
        
263
 
        if (!_nss_getgrgid_r)
264
 
                return NULL;
265
 
 
266
 
        if (!buf) 
267
 
                buf = (char *)malloc(buflen);
268
 
 
269
 
again:  
270
 
        status = _nss_getgrgid_r(gid, &grp, buf, buflen, &nss_errno);
271
 
        if (status == NSS_STATUS_TRYAGAIN) {
272
 
                buflen *= 2;
273
 
                buf = (char *)realloc(buf, buflen);
274
 
                if (!buf) {
275
 
                        return NULL;
276
 
                }
277
 
                goto again;
278
 
        }
279
 
        if (status == NSS_STATUS_NOTFOUND) {
280
 
                SAFE_FREE(buf);
281
 
                return NULL;
282
 
        }
283
 
        if (status != NSS_STATUS_SUCCESS) {
284
 
                report_nss_error("getgrgid", status);
285
 
                SAFE_FREE(buf);
286
 
                return NULL;
287
 
        }
288
 
        return &grp;
289
 
}
290
 
 
291
 
static void nss_setgrent(void)
292
 
{
293
 
        NSS_STATUS (*_nss_setgrent)(void) =
294
 
                (NSS_STATUS (*)(void))find_fn("setgrent");
295
 
        NSS_STATUS status;
296
 
 
297
 
        if (!_nss_setgrent)
298
 
                return;
299
 
 
300
 
        status = _nss_setgrent();
301
 
        if (status != NSS_STATUS_SUCCESS) {
302
 
                report_nss_error("setgrent", status);
303
 
        }
304
 
}
305
 
 
306
 
static void nss_endgrent(void)
307
 
{
308
 
        NSS_STATUS (*_nss_endgrent)(void) =
309
 
                (NSS_STATUS (*)(void))find_fn("endgrent");
310
 
        NSS_STATUS status;
311
 
 
312
 
        if (!_nss_endgrent)
313
 
                return;
314
 
 
315
 
        status = _nss_endgrent();
316
 
        if (status != NSS_STATUS_SUCCESS) {
317
 
                report_nss_error("endgrent", status);
318
 
        }
319
 
}
320
 
 
321
 
static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *start, long int *size)
322
 
{
323
 
        NSS_STATUS (*_nss_initgroups)(char *, gid_t , long int *,
324
 
                                      long int *, gid_t **, long int , int *) = 
325
 
                (NSS_STATUS (*)(char *, gid_t, long int *,
326
 
                                long int *, gid_t **,
327
 
                                long int, int *))find_fn("initgroups_dyn");
328
 
        NSS_STATUS status;
329
 
 
330
 
        if (!_nss_initgroups) 
331
 
                return NSS_STATUS_UNAVAIL;
332
 
 
333
 
        status = _nss_initgroups(user, group, start, size, groups, 0, &nss_errno);
334
 
        if (status != NSS_STATUS_SUCCESS) {
335
 
                report_nss_error("initgroups", status);
336
 
        }
337
 
        return status;
338
 
}
339
 
 
340
 
static void print_passwd(struct passwd *pwd)
341
 
{
342
 
        printf("%s:%s:%lu:%lu:%s:%s:%s\n", 
343
 
               pwd->pw_name,
344
 
               pwd->pw_passwd,
345
 
               (unsigned long)pwd->pw_uid,
346
 
               (unsigned long)pwd->pw_gid,
347
 
               pwd->pw_gecos,
348
 
               pwd->pw_dir,
349
 
               pwd->pw_shell);
350
 
}
351
 
 
352
 
static void print_group(struct group *grp)
353
 
{
354
 
        int i;
355
 
        printf("%s:%s:%lu:",
356
 
               grp->gr_name,
357
 
               grp->gr_passwd,
358
 
               (unsigned long)grp->gr_gid);
359
 
        
360
 
        if (!grp->gr_mem[0]) {
361
 
                printf("\n");
362
 
                return;
363
 
        }
364
 
        
365
 
        for (i=0; grp->gr_mem[i+1]; i++) {
366
 
                printf("%s,", grp->gr_mem[i]);
367
 
        }
368
 
        printf("%s\n", grp->gr_mem[i]);
369
 
}
370
 
 
371
 
static void nss_test_initgroups(char *name, gid_t gid)
372
 
{
373
 
        long int size = 16;
374
 
        long int start = 1;
375
 
        gid_t *groups = NULL;
376
 
        int i;
377
 
        NSS_STATUS status;
378
 
 
379
 
        groups = (gid_t *)malloc(size);
380
 
        groups[0] = gid;
381
 
 
382
 
        status = nss_initgroups(name, gid, &groups, &start, &size);
383
 
        if (status == NSS_STATUS_UNAVAIL) {
384
 
                printf("No initgroups fn\n");
385
 
                return;
386
 
        }
387
 
 
388
 
        for (i=0; i<start-1; i++) {
389
 
                printf("%lu, ", (unsigned long)groups[i]);
390
 
        }
391
 
        printf("%lu\n", (unsigned long)groups[i]);
392
 
}
393
 
 
394
 
 
395
 
static void nss_test_users(void)
396
 
{
397
 
        struct passwd *pwd;
398
 
 
399
 
        nss_setpwent();
400
 
        /* loop over all users */
401
 
        while ((pwd = nss_getpwent())) {
402
 
                printf("Testing user %s\n", pwd->pw_name);
403
 
                printf("getpwent:   "); print_passwd(pwd);
404
 
                pwd = nss_getpwuid(pwd->pw_uid);
405
 
                if (!pwd) {
406
 
                        total_errors++;
407
 
                        printf("ERROR: can't getpwuid\n");
408
 
                        continue;
409
 
                }
410
 
                printf("getpwuid:   "); print_passwd(pwd);
411
 
                pwd = nss_getpwnam(pwd->pw_name);
412
 
                if (!pwd) {
413
 
                        total_errors++;
414
 
                        printf("ERROR: can't getpwnam\n");
415
 
                        continue;
416
 
                }
417
 
                printf("getpwnam:   "); print_passwd(pwd);
418
 
                printf("initgroups: "); nss_test_initgroups(pwd->pw_name, pwd->pw_gid);
419
 
                printf("\n");
420
 
        }
421
 
        nss_endpwent();
422
 
}
423
 
 
424
 
static void nss_test_groups(void)
425
 
{
426
 
        struct group *grp;
427
 
 
428
 
        nss_setgrent();
429
 
        /* loop over all groups */
430
 
        while ((grp = nss_getgrent())) {
431
 
                printf("Testing group %s\n", grp->gr_name);
432
 
                printf("getgrent: "); print_group(grp);
433
 
                grp = nss_getgrnam(grp->gr_name);
434
 
                if (!grp) {
435
 
                        total_errors++;
436
 
                        printf("ERROR: can't getgrnam\n");
437
 
                        continue;
438
 
                }
439
 
                printf("getgrnam: "); print_group(grp);
440
 
                grp = nss_getgrgid(grp->gr_gid);
441
 
                if (!grp) {
442
 
                        total_errors++;
443
 
                        printf("ERROR: can't getgrgid\n");
444
 
                        continue;
445
 
                }
446
 
                printf("getgrgid: "); print_group(grp);
447
 
                printf("\n");
448
 
        }
449
 
        nss_endgrent();
450
 
}
451
 
 
452
 
static void nss_test_errors(void)
453
 
{
454
 
        struct passwd *pwd;
455
 
        struct group *grp;
456
 
 
457
 
        pwd = getpwnam("nosuchname");
458
 
        if (pwd || last_error != NSS_STATUS_NOTFOUND) {
459
 
                total_errors++;
460
 
                printf("ERROR Non existant user gave error %d\n", last_error);
461
 
        }
462
 
 
463
 
        pwd = getpwuid(0xFFF0);
464
 
        if (pwd || last_error != NSS_STATUS_NOTFOUND) {
465
 
                total_errors++;
466
 
                printf("ERROR Non existant uid gave error %d\n", last_error);
467
 
        }
468
 
 
469
 
        grp = getgrnam("nosuchgroup");
470
 
        if (grp || last_error != NSS_STATUS_NOTFOUND) {
471
 
                total_errors++;
472
 
                printf("ERROR Non existant group gave error %d\n", last_error);
473
 
        }
474
 
 
475
 
        grp = getgrgid(0xFFF0);
476
 
        if (grp || last_error != NSS_STATUS_NOTFOUND) {
477
 
                total_errors++;
478
 
                printf("ERROR Non existant gid gave error %d\n", last_error);
479
 
        }
480
 
}
481
 
 
482
 
 int main(int argc, char *argv[])
483
 
{       
484
 
        if (argc > 1) so_path = argv[1];
485
 
        if (argc > 2) nss_name = argv[2];
486
 
 
487
 
        nss_test_users();
488
 
        nss_test_groups();
489
 
        nss_test_errors();
490
 
 
491
 
        printf("total_errors=%d\n", total_errors);
492
 
 
493
 
        return total_errors;
494
 
}