OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [inet/] [rpc/] [rcmd.c] - Blame information for rev 1325

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/*
2
 * Copyright (c) 1983, 1993, 1994
3
 *      The Regents of the University of California.  All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. All advertising materials mentioning features or use of this software
14
 *    must display the following acknowledgement:
15
 *      This product includes software developed by the University of
16
 *      California, Berkeley and its contributors.
17
 * 4. Neither the name of the University nor the names of its contributors
18
 *    may be used to endorse or promote products derived from this software
19
 *    without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
32
 */
33
 
34
#if 0
35
static char sccsid[] = "@(#)rcmd.c      8.3 (Berkeley) 3/26/94";
36
#endif /* LIBC_SCCS and not lint */
37
 
38
#define __FORCE_GLIBC
39
#include <features.h>
40
 
41
#define __USE_GNU
42
#include <ctype.h>
43
#include <stdio.h>
44
#include <stdlib.h>
45
#include <string.h>
46
#include <errno.h>
47
#include <alloca.h>
48
#include <signal.h>
49
#include <fcntl.h>
50
#include <unistd.h>
51
#include <pwd.h>
52
#include <sys/param.h>
53
#include <sys/poll.h>
54
#include <sys/socket.h>
55
#include <sys/stat.h>
56
#include <netdb.h>
57
#include <netinet/in.h>
58
#include <arpa/inet.h>
59
 
60
#ifdef __UCLIBC_HAS_THREADS__
61
#undef __UCLIBC_HAS_THREADS__
62
#warning FIXME I am not reentrant yet...
63
#endif
64
 
65
 
66
/* some forward declarations */
67
static int __ivaliduser2(FILE *hostf, u_int32_t raddr,
68
                         const char *luser, const char *ruser, const char *rhost);
69
static int iruserok2 (u_int32_t raddr, int superuser, const char *ruser,
70
                      const char *luser, const char *rhost);
71
 
72
 
73
int rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
74
     char **ahost;
75
     u_short rport;
76
     const char *locuser, *remuser, *cmd;
77
     int *fd2p;
78
{
79
#ifdef __UCLIBC_HAS_THREADS__
80
        int herr;
81
        struct hostent hostbuf;
82
        size_t hstbuflen;
83
        char *tmphstbuf;
84
#endif
85
        struct hostent *hp;
86
        struct sockaddr_in sin, from;
87
        struct pollfd pfd[2];
88
        int32_t oldmask;
89
        pid_t pid;
90
        int s, lport, timo;
91
        char c;
92
 
93
        pid = getpid();
94
 
95
#ifdef __UCLIBC_HAS_THREADS__
96
        hstbuflen = 1024;
97
#ifdef __UCLIBC_HAS_MMU__
98
        tmphstbuf = alloca (hstbuflen);
99
#else
100
        tmphstbuf = malloc (hstbuflen);
101
#endif
102
 
103
        while (gethostbyname_r (*ahost, &hostbuf, tmphstbuf,
104
                    hstbuflen, &hp, &herr) != 0 || hp == NULL)
105
        {
106
            if (herr != NETDB_INTERNAL || errno != ERANGE)
107
            {
108
                __set_h_errno (herr);
109
#ifndef __UCLIBC_HAS_MMU__
110
                free(tmphstbuf);
111
#endif
112
                herror(*ahost);
113
                return -1;
114
            }
115
            else
116
            {
117
                /* Enlarge the buffer.  */
118
                hstbuflen *= 2;
119
#ifdef __UCLIBC_HAS_MMU__
120
                tmphstbuf = alloca (hstbuflen);
121
#else
122
                if (tmphstbuf) {
123
                    free(tmphstbuf);
124
                }
125
                tmphstbuf = malloc (hstbuflen);
126
#endif
127
            }
128
        }
129
#ifndef __UCLIBC_HAS_MMU__
130
        free(tmphstbuf);
131
#endif
132
#else /* call the non-reentrant version */
133
        if ((hp = gethostbyname(*ahost)) == NULL) {
134
            return -1;
135
        }
136
#endif
137
        pfd[0].events = POLLIN;
138
        pfd[1].events = POLLIN;
139
 
140
        *ahost = hp->h_name;
141
        oldmask = sigblock(sigmask(SIGURG)); /* __sigblock */
142
        for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
143
                s = rresvport(&lport);
144
                if (s < 0) {
145
                        if (errno == EAGAIN)
146
                            (void)fprintf(stderr,
147
                                          "rcmd: socket: All ports in use\n");
148
                        else
149
                            (void)fprintf(stderr, "rcmd: socket: %m\n");
150
                        sigsetmask(oldmask); /* sigsetmask */
151
                        return -1;
152
                }
153
                fcntl(s, F_SETOWN, pid); /* __fcntl */
154
                sin.sin_family = hp->h_addrtype;
155
                bcopy(hp->h_addr_list[0], &sin.sin_addr,
156
                      MIN (sizeof (sin.sin_addr), hp->h_length));
157
                sin.sin_port = rport;
158
                if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) /* __connect */
159
                        break;
160
                (void)close(s); /* __close */
161
                if (errno == EADDRINUSE) {
162
                        lport--;
163
                        continue;
164
                }
165
                if (errno == ECONNREFUSED && timo <= 16) {
166
                        (void)sleep(timo); /* __sleep */
167
                        timo *= 2;
168
                        continue;
169
                }
170
                if (hp->h_addr_list[1] != NULL) {
171
                        int oerrno = errno;
172
 
173
                        (void)fprintf(stderr, "connect to address %s: ",
174
                            inet_ntoa(sin.sin_addr));
175
                        __set_errno (oerrno);
176
                        perror(0);
177
                        hp->h_addr_list++;
178
                        bcopy(hp->h_addr_list[0], &sin.sin_addr,
179
                              MIN (sizeof (sin.sin_addr), hp->h_length));
180
                        (void)fprintf(stderr, "Trying %s...\n",
181
                            inet_ntoa(sin.sin_addr));
182
                        continue;
183
                }
184
                (void)fprintf(stderr, "%s: %m\n", hp->h_name);
185
                sigsetmask(oldmask); /* __sigsetmask */
186
                return -1;
187
        }
188
        lport--;
189
        if (fd2p == 0) {
190
                write(s, "", 1); /* __write */
191
                lport = 0;
192
        } else {
193
                char num[8];
194
                int s2 = rresvport(&lport), s3;
195
                socklen_t len = sizeof(from);
196
 
197
                if (s2 < 0)
198
                        goto bad;
199
                listen(s2, 1);
200
                (void)snprintf(num, sizeof(num), "%d", lport); /* __snprintf */
201
                if (write(s, num, strlen(num)+1) != strlen(num)+1) {
202
                        (void)fprintf(stderr,
203
                                      "rcmd: write (setting up stderr): %m\n");
204
                        (void)close(s2); /* __close */
205
                        goto bad;
206
                }
207
                pfd[0].fd = s;
208
                pfd[1].fd = s2;
209
                __set_errno (0);
210
                if (poll (pfd, 2, -1) < 1 || (pfd[1].revents & POLLIN) == 0){
211
                    if (errno != 0)
212
                        (void)fprintf(stderr, "rcmd: poll (setting up stderr): %m\n");
213
                    else
214
                        (void)fprintf(stderr, "poll: protocol failure in circuit setup\n");
215
                        (void)close(s2);
216
                        goto bad;
217
                }
218
                s3 = accept(s2, (struct sockaddr *)&from, &len);
219
                (void)close(s2);
220
                if (s3 < 0) {
221
                        (void)fprintf(stderr,
222
                            "rcmd: accept: %m\n");
223
                        lport = 0;
224
                        goto bad;
225
                }
226
                *fd2p = s3;
227
                from.sin_port = ntohs((u_short)from.sin_port);
228
                if (from.sin_family != AF_INET ||
229
                    from.sin_port >= IPPORT_RESERVED ||
230
                    from.sin_port < IPPORT_RESERVED / 2) {
231
                        (void)fprintf(stderr,
232
                            "socket: protocol failure in circuit setup\n");
233
                        goto bad2;
234
                }
235
        }
236
        (void)write(s, locuser, strlen(locuser)+1);
237
        (void)write(s, remuser, strlen(remuser)+1);
238
        (void)write(s, cmd, strlen(cmd)+1);
239
        if (read(s, &c, 1) != 1) {
240
                (void)fprintf(stderr,
241
                    "rcmd: %s: %m\n", *ahost);
242
                goto bad2;
243
        }
244
        if (c != 0) {
245
                while (read(s, &c, 1) == 1) {
246
                        (void)write(STDERR_FILENO, &c, 1);
247
                        if (c == '\n')
248
                                break;
249
                }
250
                goto bad2;
251
        }
252
        sigsetmask(oldmask);
253
        return s;
254
bad2:
255
        if (lport)
256
                (void)close(*fd2p);
257
bad:
258
        (void)close(s);
259
        sigsetmask(oldmask);
260
        return -1;
261
}
262
 
263
int rresvport(int *alport)
264
{
265
    struct sockaddr_in sin;
266
    int s;
267
 
268
    sin.sin_family = AF_INET;
269
    sin.sin_addr.s_addr = INADDR_ANY;
270
    s = socket(AF_INET, SOCK_STREAM, 0);
271
    if (s < 0)
272
        return -1;
273
    for (;;) {
274
        sin.sin_port = htons((u_short)*alport);
275
        if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
276
            return s;
277
        if (errno != EADDRINUSE) {
278
            (void)close(s);
279
            return -1;
280
        }
281
        (*alport)--;
282
        if (*alport == IPPORT_RESERVED/2) {
283
            (void)close(s);
284
            __set_errno (EAGAIN);               /* close */
285
            return -1;
286
        }
287
    }
288
 
289
    return -1;
290
}
291
 
292
int     __check_rhosts_file = 1;
293
char    *__rcmd_errstr;
294
 
295
int ruserok(rhost, superuser, ruser, luser)
296
        const char *rhost, *ruser, *luser;
297
        int superuser;
298
{
299
        struct hostent *hp;
300
        u_int32_t addr;
301
        char **ap;
302
#ifdef __UCLIBC_HAS_THREADS__
303
        size_t buflen;
304
        char *buffer;
305
        int herr;
306
        struct hostent hostbuf;
307
#endif
308
 
309
#ifdef __UCLIBC_HAS_THREADS__
310
        buflen = 1024;
311
#ifdef __UCLIBC_HAS_MMU__
312
        buffer = alloca (buflen);
313
#else
314
        buffer = malloc (buflen);
315
#endif
316
 
317
        while (gethostbyname_r (rhost, &hostbuf, buffer,
318
                    buflen, &hp, &herr) != 0 || hp == NULL)
319
        {
320
            if (herr != NETDB_INTERNAL || errno != ERANGE) {
321
#ifndef __UCLIBC_HAS_MMU__
322
                free(buffer);
323
#endif
324
                return -1;
325
            } else
326
            {
327
                /* Enlarge the buffer.  */
328
                buflen *= 2;
329
#ifdef __UCLIBC_HAS_MMU__
330
                buffer = alloca (buflen);
331
#else
332
                if (buffer) {
333
                    free(buffer);
334
                }
335
                buffer = malloc (buflen);
336
#endif
337
            }
338
        }
339
#ifndef __UCLIBC_HAS_MMU__
340
        free(buffer);
341
#endif
342
#else
343
        if ((hp = gethostbyname(rhost)) == NULL) {
344
                return -1;
345
        }
346
#endif
347
        for (ap = hp->h_addr_list; *ap; ++ap) {
348
                bcopy(*ap, &addr, sizeof(addr));
349
                if (iruserok2(addr, superuser, ruser, luser, rhost) == 0)
350
                        return 0;
351
        }
352
        return -1;
353
}
354
 
355
 
356
/* Extremely paranoid file open function. */
357
static FILE *
358
iruserfopen (char *file, uid_t okuser)
359
{
360
  struct stat st;
361
  char *cp = NULL;
362
  FILE *res = NULL;
363
 
364
  /* If not a regular file, if owned by someone other than user or
365
     root, if writeable by anyone but the owner, or if hardlinked
366
     anywhere, quit.  */
367
  cp = NULL;
368
  if (lstat (file, &st))
369
    cp = "lstat failed";
370
  else if (!S_ISREG (st.st_mode))
371
    cp = "not regular file";
372
  else
373
    {
374
      res = fopen (file, "r");
375
      if (!res)
376
        cp = "cannot open";
377
      else if (fstat (fileno (res), &st) < 0)
378
        cp = "fstat failed";
379
      else if (st.st_uid && st.st_uid != okuser)
380
        cp = "bad owner";
381
      else if (st.st_mode & (S_IWGRP|S_IWOTH))
382
        cp = "writeable by other than owner";
383
      else if (st.st_nlink > 1)
384
        cp = "hard linked somewhere";
385
    }
386
 
387
  /* If there were any problems, quit.  */
388
  if (cp != NULL)
389
    {
390
      __rcmd_errstr = cp;
391
      if (res)
392
        fclose (res);
393
      return NULL;
394
    }
395
 
396
  return res;
397
}
398
 
399
 
400
/*
401
 * New .rhosts strategy: We are passed an ip address. We spin through
402
 * hosts.equiv and .rhosts looking for a match. When the .rhosts only
403
 * has ip addresses, we don't have to trust a nameserver.  When it
404
 * contains hostnames, we spin through the list of addresses the nameserver
405
 * gives us and look for a match.
406
 *
407
 * Returns 0 if ok, -1 if not ok.
408
 */
409
static int
410
iruserok2 (raddr, superuser, ruser, luser, rhost)
411
     u_int32_t raddr;
412
     int superuser;
413
     const char *ruser, *luser, *rhost;
414
{
415
        FILE *hostf = NULL;
416
        int isbad = -1;
417
 
418
        if (!superuser)
419
                hostf = iruserfopen (_PATH_HEQUIV, 0);
420
 
421
        if (hostf) {
422
                isbad = __ivaliduser2 (hostf, raddr, luser, ruser, rhost);
423
                fclose (hostf);
424
 
425
                if (!isbad)
426
                        return 0;
427
        }
428
 
429
        if (__check_rhosts_file || superuser) {
430
                char *pbuf;
431
                struct passwd *pwd;
432
                size_t dirlen;
433
                uid_t uid;
434
 
435
#ifdef __UCLIBC_HAS_THREADS__
436
                size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
437
                struct passwd pwdbuf;
438
#ifdef __UCLIBC_HAS_MMU__
439
                char *buffer = alloca (buflen);
440
#else
441
                char *buffer = malloc (buflen);
442
#endif
443
 
444
                if (getpwnam_r (luser, &pwdbuf, buffer,
445
                            buflen, &pwd) != 0 || pwd == NULL)
446
                {
447
#ifndef __UCLIBC_HAS_MMU__
448
                        free(buffer);
449
#endif
450
                        return -1;
451
                }
452
#ifndef __UCLIBC_HAS_MMU__
453
                free(buffer);
454
#endif
455
#else
456
                if ((pwd = getpwnam(luser)) == NULL)
457
                        return -1;
458
#endif
459
 
460
                dirlen = strlen (pwd->pw_dir);
461
                pbuf = malloc (dirlen + sizeof "/.rhosts");
462
                strcpy (pbuf, pwd->pw_dir);
463
                strcat (pbuf, "/.rhosts");
464
 
465
                /* Change effective uid while reading .rhosts.  If root and
466
                   reading an NFS mounted file system, can't read files that
467
                   are protected read/write owner only.  */
468
                uid = geteuid ();
469
                seteuid (pwd->pw_uid);
470
                hostf = iruserfopen (pbuf, pwd->pw_uid);
471
                free(pbuf);
472
 
473
                if (hostf != NULL) {
474
                        isbad = __ivaliduser2 (hostf, raddr, luser, ruser, rhost);
475
                        fclose (hostf);
476
                }
477
 
478
                seteuid (uid);
479
                return isbad;
480
        }
481
        return -1;
482
}
483
 
484
/* This is the exported version.  */
485
int iruserok (u_int32_t raddr, int superuser, const char * ruser, const char * luser)
486
{
487
        return iruserok2 (raddr, superuser, ruser, luser, "-");
488
}
489
 
490
 
491
/*
492
 * XXX
493
 * Don't make static, used by lpd(8).
494
 *
495
 * This function is not used anymore. It is only present because lpd(8)
496
 * calls it (!?!). We simply call __invaliduser2() with an illegal rhost
497
 * argument. This means that netgroups won't work in .rhost/hosts.equiv
498
 * files. If you want lpd to work with netgroups, fix lpd to use ruserok()
499
 * or PAM.
500
 * Returns 0 if ok, -1 if not ok.
501
 */
502
int
503
__ivaliduser(FILE *hostf, u_int32_t raddr, const char *luser, const char *ruser)
504
{
505
        return __ivaliduser2(hostf, raddr, luser, ruser, "-");
506
}
507
 
508
 
509
/* Returns 1 on positive match, 0 on no match, -1 on negative match.  */
510
static int
511
__icheckhost (u_int32_t raddr, char *lhost, const char *rhost)
512
{
513
        struct hostent *hp;
514
        u_int32_t laddr;
515
        int negate=1;    /* Multiply return with this to get -1 instead of 1 */
516
        char **pp;
517
 
518
#ifdef __UCLIBC_HAS_THREADS__
519
        int save_errno;
520
        size_t buflen;
521
        char *buffer;
522
        struct hostent hostbuf;
523
        int herr;
524
#endif
525
 
526
#ifdef HAVE_NETGROUP
527
        /* Check nis netgroup.  */
528
        if (strncmp ("+@", lhost, 2) == 0)
529
                return innetgr (&lhost[2], rhost, NULL, NULL);
530
 
531
        if (strncmp ("-@", lhost, 2) == 0)
532
                return -innetgr (&lhost[2], rhost, NULL, NULL);
533
#endif /* HAVE_NETGROUP */
534
 
535
        /* -host */
536
        if (strncmp ("-", lhost,1) == 0) {
537
                negate = -1;
538
                lhost++;
539
        } else if (strcmp ("+",lhost) == 0) {
540
                return 1;                    /* asking for trouble, but ok.. */
541
        }
542
 
543
        /* Try for raw ip address first. */
544
        if (isdigit (*lhost) && (laddr = inet_addr (lhost)) != INADDR_NONE)
545
                return negate * (! (raddr ^ laddr));
546
 
547
        /* Better be a hostname. */
548
#ifdef __UCLIBC_HAS_THREADS__
549
        buflen = 1024;
550
        buffer = malloc(buflen);
551
        save_errno = errno;
552
 
553
        while (gethostbyname_r (lhost, &hostbuf, buffer, buflen, &hp, &herr)
554
               != 0) {
555
            free(buffer);
556
            return (0);
557
        }
558
        free(buffer);
559
        __set_errno (save_errno);
560
#else
561
        hp = gethostbyname(lhost);
562
#endif /* __UCLIBC_HAS_THREADS__ */
563
 
564
        if (hp == NULL)
565
                return 0;
566
 
567
        /* Spin through ip addresses. */
568
        for (pp = hp->h_addr_list; *pp; ++pp)
569
                if (!memcmp (&raddr, *pp, sizeof (u_int32_t)))
570
                        return negate;
571
 
572
        /* No match. */
573
        return (0);
574
}
575
 
576
/* Returns 1 on positive match, 0 on no match, -1 on negative match.  */
577
static int
578
__icheckuser (const char *luser, const char *ruser)
579
{
580
 
581
    /*
582
      luser is user entry from .rhosts/hosts.equiv file
583
      ruser is user id on remote host
584
      */
585
 
586
#ifdef HAVE_NETGROUP
587
    /* [-+]@netgroup */
588
    if (strncmp ("+@", luser, 2) == 0)
589
        return innetgr (&luser[2], NULL, ruser, NULL);
590
 
591
    if (strncmp ("-@", luser,2) == 0)
592
        return -innetgr (&luser[2], NULL, ruser, NULL);
593
#endif /* HAVE_NETGROUP */
594
 
595
    /* -user */
596
    if (strncmp ("-", luser, 1) == 0)
597
        return -(strcmp (&luser[1], ruser) == 0);
598
 
599
    /* + */
600
    if (strcmp ("+", luser) == 0)
601
        return 1;
602
 
603
    /* simple string match */
604
    return strcmp (ruser, luser) == 0;
605
}
606
 
607
/*
608
 * Returns 1 for blank lines (or only comment lines) and 0 otherwise
609
 */
610
static int
611
__isempty(char *p)
612
{
613
    while (*p && isspace (*p)) {
614
        ++p;
615
    }
616
 
617
    return (*p == '\0' || *p == '#') ? 1 : 0 ;
618
}
619
 
620
/*
621
 * Returns 0 if positive match, -1 if _not_ ok.
622
 */
623
static int
624
__ivaliduser2(hostf, raddr, luser, ruser, rhost)
625
        FILE *hostf;
626
        u_int32_t raddr;
627
        const char *luser, *ruser, *rhost;
628
{
629
    register const char *user;
630
    register char *p;
631
    int hcheck, ucheck;
632
    char *buf = NULL;
633
    size_t bufsize = 0;
634
    int retval = -1;
635
 
636
    while (getline (&buf, &bufsize, hostf) > 0) {
637
        buf[bufsize - 1] = '\0'; /* Make sure it's terminated.  */
638
        p = buf;
639
 
640
        /* Skip empty or comment lines */
641
        if (__isempty (p)) {
642
            continue;
643
        }
644
 
645
        /* Skip lines that are too long. */
646
        if (strchr (p, '\n') == NULL) {
647
            int ch = getc_unlocked (hostf);
648
 
649
            while (ch != '\n' && ch != EOF)
650
              ch = getc_unlocked (hostf);
651
            continue;
652
        }
653
 
654
        for (;*p && !isspace(*p); ++p) {
655
            *p = tolower (*p);
656
        }
657
 
658
        /* Next we want to find the permitted name for the remote user.  */
659
        if (*p == ' ' || *p == '\t') {
660
            /* <nul> terminate hostname and skip spaces */
661
            for (*p++='\0'; *p && isspace (*p); ++p);
662
 
663
            user = p;                   /* this is the user's name */
664
            while (*p && !isspace (*p))
665
                ++p;                    /* find end of user's name */
666
        } else
667
            user = p;
668
 
669
        *p = '\0';              /* <nul> terminate username (+host?) */
670
 
671
        /* buf -> host(?) ; user -> username(?) */
672
 
673
        /* First check host part */
674
        hcheck = __icheckhost (raddr, buf, rhost);
675
 
676
        if (hcheck < 0)
677
            break;
678
 
679
        if (hcheck) {
680
            /* Then check user part */
681
            if (! (*user))
682
                user = luser;
683
 
684
            ucheck = __icheckuser (user, ruser);
685
 
686
            /* Positive 'host user' match? */
687
            if (ucheck > 0) {
688
                retval = 0;
689
                break;
690
            }
691
 
692
            /* Negative 'host -user' match? */
693
            if (ucheck < 0)
694
                break;
695
 
696
            /* Neither, go on looking for match */
697
        }
698
    }
699
 
700
    if (buf != NULL)
701
      free (buf);
702
 
703
    return retval;
704
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.