~ubuntu-branches/ubuntu/raring/shadow/raring-proposed

« back to all changes in this revision

Viewing changes to lib/gshadow.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2009-05-05 09:45:21 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090505094521-wpk2wn3q7957tlah
Tags: 1:4.1.3.1-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Ubuntu specific:
    + debian/login.defs: use SHA512 by default for password crypt routine.
  - debian/patches/stdout-encrypted-password.patch: chpasswd can report
    password hashes on stdout (debian bug 505640).
  - debian/login.pam: Enable SELinux support (debian bug 527106).
  - debian/securetty.linux: support Freescale MX-series (debian bug 527095).
* Add debian/patches/300_lastlog_failure: fixed upstream (debian bug 524873).
* Drop debian/patches/593_omit_lastchange_field_if_clock_is_misset: fixed
  upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright 1990 - 1994, Julianne Frances Haugh
 
2
 * Copyright (c) 1990 - 1994, Julianne Frances Haugh
 
3
 * Copyright (c) 1996 - 1998, Marek Michałkiewicz
 
4
 * Copyright (c) 2005       , Tomasz Kłoczko
 
5
 * Copyright (c) 2008       , Nicolas François
3
6
 * All rights reserved.
4
7
 *
5
8
 * Redistribution and use in source and binary forms, with or without
10
13
 * 2. Redistributions in binary form must reproduce the above copyright
11
14
 *    notice, this list of conditions and the following disclaimer in the
12
15
 *    documentation and/or other materials provided with the distribution.
13
 
 * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
14
 
 *    may be used to endorse or promote products derived from this software
15
 
 *    without specific prior written permission.
 
16
 * 3. The name of the copyright holders or contributors may not be used to
 
17
 *    endorse or promote products derived from this software without
 
18
 *    specific prior written permission.
16
19
 *
17
 
 * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
18
 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 
 * ARE DISCLAIMED.  IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
21
 
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 
 * SUCH DAMAGE.
 
20
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
21
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
22
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 
23
 * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
 
24
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
25
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
26
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
27
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
28
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
29
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
30
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
31
 */
29
32
 
30
33
#include <config.h>
32
35
/* Newer versions of Linux libc already have shadow support.  */
33
36
#if defined(SHADOWGRP) && !defined(HAVE_SHADOWGRP)      /*{ */
34
37
 
35
 
#ident "$Id: gshadow.c 1642 2008-01-05 13:56:21Z nekral-guest $"
 
38
#ident "$Id: gshadow.c 2205 2008-07-11 22:23:42Z nekral-guest $"
36
39
 
37
40
#include <stdio.h>
38
41
#include "prototypes.h"
48
51
#define FIELDS  4
49
52
 
50
53
#ifdef  USE_NIS
51
 
static int nis_used;
52
 
static int nis_ignore;
 
54
static bool nis_used;
 
55
static bool nis_ignore;
53
56
static enum { native, start, middle, native2 } nis_state;
54
 
static int nis_bound;
 
57
static bool nis_bound;
55
58
static char *nis_domain;
56
59
static char *nis_key;
57
60
static int nis_keylen;
62
65
#endif
63
66
 
64
67
#ifdef  USE_NIS
65
 
 
66
 
/*
67
 
 * __setsgNIS - turn on or off NIS searches
68
 
 */
69
 
 
70
 
void __setsgNIS (int flag)
71
 
{
72
 
        nis_ignore = !flag;
73
 
 
74
 
        if (nis_ignore)
75
 
                nis_used = 0;
76
 
}
77
 
 
78
68
/*
79
69
 * bind_nis - bind to NIS server
80
70
 */
84
74
        if (yp_get_default_domain (&nis_domain))
85
75
                return -1;
86
76
 
87
 
        nis_bound = 1;
 
77
        nis_bound = true;
88
78
        return 0;
89
79
}
90
80
#endif
96
86
 
97
87
        while (s != NULL && *s != '\0') {
98
88
                size = (nelem + 1) * sizeof (ptr);
99
 
                if ((ptr = realloc (*list, size)) != NULL) {
100
 
                        ptr[nelem++] = s;
 
89
                ptr = realloc (*list, size);
 
90
                if (NULL != ptr) {
 
91
                        ptr[nelem] = s;
 
92
                        nelem++;
101
93
                        *list = ptr;
102
94
                        *nlist = nelem;
103
 
                        if ((s = strchr (s, ',')))
104
 
                                *s++ = '\0';
 
95
                        s = strchr (s, ',');
 
96
                        if (NULL != s) {
 
97
                                *s = '\0';
 
98
                                s++;
 
99
                        }
105
100
                }
106
101
        }
107
102
        size = (nelem + 1) * sizeof (ptr);
108
 
        if ((ptr = realloc (*list, size)) != NULL) {
109
 
                ptr[nelem] = '\0';
 
103
        ptr = realloc (*list, size);
 
104
        if (NULL != ptr) {
 
105
                ptr[nelem] = NULL;
110
106
                *list = ptr;
111
107
        }
112
108
        return ptr;
117
113
#ifdef  USE_NIS
118
114
        nis_state = native;
119
115
#endif
120
 
        if (shadow)
 
116
        if (NULL != shadow) {
121
117
                rewind (shadow);
122
 
        else
 
118
        } else {
123
119
                shadow = fopen (SGROUP_FILE, "r");
 
120
        }
124
121
}
125
122
 
126
123
void endsgent (void)
127
124
{
128
 
        if (shadow)
 
125
        if (NULL != shadow) {
129
126
                (void) fclose (shadow);
 
127
        }
130
128
 
131
129
        shadow = (FILE *) 0;
132
130
}
137
135
        char *cp;
138
136
        int i;
139
137
 
140
 
        strncpy (sgrbuf, string, (int) sizeof sgrbuf - 1);
 
138
        strncpy (sgrbuf, string, sizeof sgrbuf - 1);
141
139
        sgrbuf[sizeof sgrbuf - 1] = '\0';
142
140
 
143
 
        if ((cp = strrchr (sgrbuf, '\n')))
 
141
        cp = strrchr (sgrbuf, '\n');
 
142
        if (NULL != cp) {
144
143
                *cp = '\0';
 
144
        }
145
145
 
146
146
        /*
147
147
         * There should be exactly 4 colon separated fields.  Find
148
148
         * all 4 of them and save the starting addresses in fields[].
149
149
         */
150
150
 
151
 
        for (cp = sgrbuf, i = 0; i < FIELDS && cp; i++) {
 
151
        for (cp = sgrbuf, i = 0; (i < FIELDS) && (NULL != cp); i++) {
152
152
                fields[i] = cp;
153
 
                if ((cp = strchr (cp, ':')))
 
153
                cp = strchr (cp, ':');
 
154
                if (NULL != cp) {
154
155
                        *cp++ = '\0';
 
156
                }
155
157
        }
156
158
 
157
159
        /*
159
161
         * the line is invalid.
160
162
         */
161
163
 
162
 
        if (cp || i != FIELDS)
 
164
        if ((NULL != cp) || (i != FIELDS))
163
165
#ifdef  USE_NIS
164
 
                if (!IS_NISCHAR (fields[0][0]))
 
166
                if (!IS_NISCHAR (fields[0][0])) {
165
167
                        return 0;
166
 
                else
167
 
                        nis_used = 1;
 
168
                } else {
 
169
                        nis_used = true;
 
170
                }
168
171
#else
169
172
                return 0;
170
173
#endif
171
174
 
172
175
        sgroup.sg_name = fields[0];
173
176
        sgroup.sg_passwd = fields[1];
174
 
        if (nadmins) {
 
177
        if (0 != nadmins) {
175
178
                nadmins = 0;
176
179
                free (admins);
177
180
                admins = NULL;
178
181
        }
179
 
        if (nmembers) {
 
182
        if (0 != nmembers) {
180
183
                nmembers = 0;
181
184
                free (members);
182
185
                members = NULL;
199
202
        char buf[sizeof sgrbuf];
200
203
        char *cp;
201
204
 
202
 
        if (!fp)
 
205
        if (NULL == fp) {
203
206
                return (0);
 
207
        }
204
208
 
205
209
#ifdef  USE_NIS
206
 
        while (fgetsx (buf, sizeof buf, fp) != (char *) 0)
 
210
        while (fgetsx (buf, (int) sizeof buf, fp) != (char *) 0)
207
211
#else
208
 
        if (fgetsx (buf, sizeof buf, fp) != (char *) 0)
 
212
        if (fgetsx (buf, (int) sizeof buf, fp) != (char *) 0)
209
213
#endif
210
214
        {
211
 
                if ((cp = strchr (buf, '\n')))
 
215
                cp = strchr (buf, '\n');
 
216
                if (NULL != cp) {
212
217
                        *cp = '\0';
 
218
                }
213
219
#ifdef  USE_NIS
214
 
                if (nis_ignore && IS_NISCHAR (buf[0]))
 
220
                if (nis_ignore && IS_NISCHAR (buf[0])) {
215
221
                        continue;
 
222
                }
216
223
#endif
217
224
                return (sgetsgent (buf));
218
225
        }
226
233
struct sgrp *getsgent (void)
227
234
{
228
235
#ifdef  USE_NIS
229
 
        int nis_1_group = 0;
 
236
        bool nis_1_group = false;
230
237
        struct sgrp *val;
231
238
        char buf[BUFSIZ];
232
239
#endif
233
 
        if (!shadow)
 
240
        if (NULL == shadow) {
234
241
                setsgent ();
 
242
        }
235
243
 
236
244
#ifdef  USE_NIS
237
245
      again:
246
254
                 * NULL right away if there is none.
247
255
                 */
248
256
 
249
 
                if (!(val = fgetsgent (shadow)))
 
257
                val = fgetsgent (shadow);
 
258
                if (NULL == val) {
250
259
                        return 0;
 
260
                }
251
261
 
252
262
                /*
253
263
                 * If this entry began with a NIS escape character, we have
256
266
                 */
257
267
 
258
268
                if (IS_NISCHAR (val->sg_name[0])) {
259
 
                        if (val->sg_name[1])
260
 
                                nis_1_group = 1;
261
 
                        else
 
269
                        if ('\0' != val->sg_name[1]) {
 
270
                                nis_1_group = true;
 
271
                        } else {
262
272
                                nis_state = start;
 
273
                        }
263
274
                }
264
275
 
265
276
                /*
267
278
                 * use a NIS map, it must be a regular local group.
268
279
                 */
269
280
 
270
 
                if (nis_1_group == 0 && nis_state != start)
 
281
                if (!nis_1_group && (nis_state != start)) {
271
282
                        return val;
 
283
                }
272
284
 
273
285
                /*
274
286
                 * If this is an escape to use an NIS map, switch over to
275
287
                 * that bunch of code.
276
288
                 */
277
289
 
278
 
                if (nis_state == start)
 
290
                if (nis_state == start) {
279
291
                        goto again;
 
292
                }
280
293
 
281
294
                /*
282
295
                 * NEEDSWORK.  Here we substitute pieces-parts of this entry.
284
297
 
285
298
                return 0;
286
299
        } else {
287
 
                if (nis_bound == 0) {
 
300
                if (!nis_bound) {
288
301
                        if (bind_nis ()) {
289
302
                                nis_state = native2;
290
303
                                goto again;
336
349
                 * Search the gshadow.byname map for this group.
337
350
                 */
338
351
 
339
 
                if (!nis_bound)
 
352
                if (!nis_bound) {
340
353
                        bind_nis ();
 
354
                }
341
355
 
342
356
                if (nis_bound) {
343
357
                        char *cp;
345
359
                        if (yp_match (nis_domain, "gshadow.byname", name,
346
360
                                      strlen (name), &nis_val,
347
361
                                      &nis_vallen) == 0) {
348
 
                                if (cp = strchr (nis_val, '\n'))
 
362
                                cp = strchr (nis_val, '\n');
 
363
                                if (NULL != cp) {
349
364
                                        *cp = '\0';
 
365
                                }
350
366
 
351
367
                                nis_state = middle;
352
 
                                if (sgrp = sgetsgent (nis_val)) {
 
368
                                sgrp = sgetsgent (nis_val);
 
369
                                if (NULL != sgrp) {
353
370
                                        strcpy (save_name, sgrp->sg_name);
354
371
                                        nis_key = save_name;
355
372
                                        nis_keylen = strlen (save_name);
362
379
#endif
363
380
#ifdef  USE_NIS
364
381
        if (nis_used) {
365
 
                nis_ignore++;
366
 
                nis_disabled++;
 
382
                nis_ignore = true;
 
383
                nis_disabled = true;
367
384
        }
368
385
#endif
369
386
        while ((sgrp = getsgent ()) != (struct sgrp *) 0) {
370
 
                if (strcmp (name, sgrp->sg_name) == 0)
 
387
                if (strcmp (name, sgrp->sg_name) == 0) {
371
388
                        break;
 
389
                }
372
390
        }
373
391
#ifdef  USE_NIS
374
 
        nis_ignore--;
 
392
        nis_ignore = false;
375
393
#endif
376
 
        if (sgrp)
377
 
                return sgrp;
378
 
        return (0);
 
394
        return sgrp;
379
395
}
380
396
 
381
397
/*
392
408
        int i;
393
409
        size_t size;
394
410
 
395
 
        if (!fp || !sgrp)
 
411
        if ((NULL == fp) || (NULL == sgrp)) {
396
412
                return -1;
 
413
        }
397
414
 
398
415
        /* calculate the required buffer size */
399
416
        size = strlen (sgrp->sg_name) + strlen (sgrp->sg_passwd) + 10;
400
 
        for (i = 0; sgrp->sg_adm && sgrp->sg_adm[i]; i++)
 
417
        for (i = 0; (NULL != sgrp->sg_adm) && (NULL != sgrp->sg_adm[i]); i++) {
401
418
                size += strlen (sgrp->sg_adm[i]) + 1;
402
 
        for (i = 0; sgrp->sg_mem && sgrp->sg_mem[i]; i++)
 
419
        }
 
420
        for (i = 0; (NULL != sgrp->sg_mem) && (NULL != sgrp->sg_mem[i]); i++) {
403
421
                size += strlen (sgrp->sg_mem[i]) + 1;
 
422
        }
404
423
 
405
424
        buf = malloc (size);
406
 
        if (!buf)
 
425
        if (NULL == buf) {
407
426
                return -1;
 
427
        }
408
428
        cp = buf;
409
429
 
410
430
        /*
424
444
         * with a ",".
425
445
         */
426
446
 
427
 
        for (i = 0; sgrp->sg_adm[i]; i++) {
428
 
                if (i > 0)
 
447
        for (i = 0; NULL != sgrp->sg_adm[i]; i++) {
 
448
                if (i > 0) {
429
449
                        *cp++ = ',';
 
450
                }
430
451
 
431
452
                strcpy (cp, sgrp->sg_adm[i]);
432
453
                cp += strlen (cp);
437
458
         * Now do likewise with the group members.
438
459
         */
439
460
 
440
 
        for (i = 0; sgrp->sg_mem[i]; i++) {
441
 
                if (i > 0)
442
 
                        *cp++ = ',';
 
461
        for (i = 0; NULL != sgrp->sg_mem[i]; i++) {
 
462
                if (i > 0) {
 
463
                        *cp = ',';
 
464
                        cp++;
 
465
                }
443
466
 
444
467
                strcpy (cp, sgrp->sg_mem[i]);
445
468
                cp += strlen (cp);
446
469
        }
447
 
        *cp++ = '\n';
 
470
        *cp = '\n';
 
471
        cp++;
448
472
        *cp = '\0';
449
473
 
450
474
        /*