Changeset 28317


Ignore:
Timestamp:
2011-09-29T14:03:36+02:00 (5 years ago)
Author:
acoul
Message:

libs/libpam: make KanjiMonster happy

File:
1 edited

Legend:

Unmodified
Added
Removed
  • packages/libs/libpam/patches/005-fix_ruserok.patch

    r28316 r28317  
    11--- a/modules/pam_rhosts/pam_rhosts.c 
    22+++ b/modules/pam_rhosts/pam_rhosts.c 
    3 @@ -111,11 +111,13 @@ int pam_sm_authenticate (pam_handle_t *p 
    4        as_root = (lpwd->pw_uid == 0); 
    5      } 
     3@@ -34,8 +34,10 @@ 
    64  
    7 +#if    0 
    8  #ifdef HAVE_RUSEROK_AF 
    9      retval = ruserok_af (rhost, as_root, ruser, luser, PF_UNSPEC); 
    10  #else 
    11      retval = ruserok (rhost, as_root, ruser, luser); 
    12  #endif 
     5 #include <pwd.h> 
     6 #include <netdb.h> 
     7+#include <stdio.h> 
     8 #include <string.h> 
     9 #include <syslog.h> 
     10+#include <sys/stat.h> 
     11  
     12 #define PAM_SM_AUTH  /* only defines this management group */ 
     13  
     14@@ -43,6 +45,353 @@ 
     15 #include <security/pam_modutil.h> 
     16 #include <security/pam_ext.h> 
     17  
     18+int  __check_rhosts_file = 1; 
     19+ 
     20+/* Extremely paranoid file open function. */ 
     21+static FILE * 
     22+iruserfopen (const char *file, uid_t okuser) 
     23+{ 
     24+  struct stat st; 
     25+  char *cp = NULL; 
     26+  FILE *res = NULL; 
     27+ 
     28+  /* If not a regular file, if owned by someone other than user or 
     29+     root, if writeable by anyone but the owner, or if hardlinked 
     30+     anywhere, quit.  */ 
     31+  if (lstat (file, &st)) 
     32+    cp = "lstat failed"; 
     33+  else if (!S_ISREG (st.st_mode)) 
     34+    cp = "not regular file"; 
     35+  else 
     36+    { 
     37+      res = fopen (file, "r"); 
     38+      if (!res) 
     39+       cp = "cannot open"; 
     40+      else if (fstat (fileno (res), &st) < 0) 
     41+       cp = "fstat failed"; 
     42+      else if (st.st_uid && st.st_uid != okuser) 
     43+       cp = "bad owner"; 
     44+      else if (st.st_mode & (S_IWGRP|S_IWOTH)) 
     45+       cp = "writeable by other than owner"; 
     46+      else if (st.st_nlink > 1) 
     47+       cp = "hard linked somewhere"; 
     48+    } 
     49+ 
     50+  /* If there were any problems, quit.  */ 
     51+  if (cp != NULL) 
     52+    { 
     53+      if (res) 
     54+       fclose (res); 
     55+      return NULL; 
     56+    } 
     57+ 
     58+  return res; 
     59+} 
     60+ 
     61+/* 
     62+ * Returns 1 for blank lines (or only comment lines) and 0 otherwise 
     63+ */ 
     64+static int 
     65+__isempty(char *p) 
     66+{ 
     67+    while (*p && isspace (*p)) { 
     68+       ++p; 
     69+    } 
     70+ 
     71+    return (*p == '\0' || *p == '#') ? 1 : 0 ; 
     72+} 
     73+ 
     74+/* Returns 1 on positive match, 0 on no match, -1 on negative match.  */ 
     75+static int 
     76+__icheckhost (u_int32_t raddr, char *lhost, const char *rhost) 
     77+{ 
     78+       struct hostent *hp; 
     79+       u_int32_t laddr; 
     80+       int negate=1;    /* Multiply return with this to get -1 instead of 1 */ 
     81+       char **pp; 
     82+ 
     83+#ifdef __UCLIBC_HAS_REENTRANT_RPC__ 
     84+       int save_errno; 
     85+       size_t buflen; 
     86+       char *buffer; 
     87+       struct hostent hostbuf; 
     88+       int herr; 
    1389+#endif 
    14      if (retval != 0) { 
    15        if (!opt_silent || opt_debug) 
    16         pam_syslog(pamh, LOG_WARNING, "denied access to %s@%s as %s", 
     90+ 
     91+#ifdef HAVE_NETGROUP 
     92+       /* Check nis netgroup.  */ 
     93+       if (strncmp ("+@", lhost, 2) == 0) 
     94+               return innetgr (&lhost[2], rhost, NULL, NULL); 
     95+ 
     96+       if (strncmp ("-@", lhost, 2) == 0) 
     97+               return -innetgr (&lhost[2], rhost, NULL, NULL); 
     98+#endif /* HAVE_NETGROUP */ 
     99+ 
     100+       /* -host */ 
     101+       if (strncmp ("-", lhost,1) == 0) { 
     102+               negate = -1; 
     103+               lhost++; 
     104+       } else if (strcmp ("+",lhost) == 0) { 
     105+               return 1;                    /* asking for trouble, but ok.. */ 
     106+       } 
     107+ 
     108+       /* Try for raw ip address first. */ 
     109+       if (isdigit (*lhost) && (laddr = inet_addr (lhost)) != INADDR_NONE) 
     110+               return negate * (! (raddr ^ laddr)); 
     111+ 
     112+       /* Better be a hostname. */ 
     113+#ifdef __UCLIBC_HAS_REENTRANT_RPC__ 
     114+       buflen = 1024; 
     115+       buffer = malloc(buflen); 
     116+       save_errno = errno; 
     117+ 
     118+       while (gethostbyname_r (lhost, &hostbuf, buffer, buflen, &hp, &herr) 
     119+              != 0) { 
     120+           free(buffer); 
     121+           return (0); 
     122+       } 
     123+       free(buffer); 
     124+       __set_errno (save_errno); 
     125+#else 
     126+       hp = gethostbyname(lhost); 
     127+#endif /* __UCLIBC_HAS_REENTRANT_RPC__ */ 
     128+ 
     129+       if (hp == NULL) 
     130+               return 0; 
     131+ 
     132+       /* Spin through ip addresses. */ 
     133+       for (pp = hp->h_addr_list; *pp; ++pp) 
     134+               if (!memcmp (&raddr, *pp, sizeof (u_int32_t))) 
     135+                       return negate; 
     136+ 
     137+       /* No match. */ 
     138+       return (0); 
     139+} 
     140+ 
     141+/* Returns 1 on positive match, 0 on no match, -1 on negative match.  */ 
     142+static int 
     143+__icheckuser (const char *luser, const char *ruser) 
     144+{ 
     145+ 
     146+    /* 
     147+      luser is user entry from .rhosts/hosts.equiv file 
     148+      ruser is user id on remote host 
     149+      */ 
     150+ 
     151+#ifdef HAVE_NETGROUP 
     152+    /* [-+]@netgroup */ 
     153+    if (strncmp ("+@", luser, 2) == 0) 
     154+       return innetgr (&luser[2], NULL, ruser, NULL); 
     155+ 
     156+    if (strncmp ("-@", luser,2) == 0) 
     157+       return -innetgr (&luser[2], NULL, ruser, NULL); 
     158+#endif /* HAVE_NETGROUP */ 
     159+ 
     160+    /* -user */ 
     161+    if (strncmp ("-", luser, 1) == 0) 
     162+       return -(strcmp (&luser[1], ruser) == 0); 
     163+ 
     164+    /* + */ 
     165+    if (strcmp ("+", luser) == 0) 
     166+       return 1; 
     167+ 
     168+    /* simple string match */ 
     169+    return strcmp (ruser, luser) == 0; 
     170+} 
     171+ 
     172+/* 
     173+ * Returns 0 if positive match, -1 if _not_ ok. 
     174+ */ 
     175+static int 
     176+__ivaliduser2(FILE *hostf, u_int32_t raddr,    const char *luser, 
     177+                         const char *ruser, const char *rhost) 
     178+{ 
     179+    register const char *user; 
     180+    register char *p; 
     181+    int hcheck, ucheck; 
     182+    char *buf = NULL; 
     183+    size_t bufsize = 0; 
     184+    int retval = -1; 
     185+ 
     186+    while (getline (&buf, &bufsize, hostf) > 0) { 
     187+       buf[bufsize - 1] = '\0'; /* Make sure it's terminated.  */ 
     188+        p = buf; 
     189+ 
     190+       /* Skip empty or comment lines */ 
     191+       if (__isempty (p)) { 
     192+           continue; 
     193+       } 
     194+ 
     195+       /* Skip lines that are too long. */ 
     196+       if (strchr (p, '\n') == NULL) { 
     197+           int ch = getc_unlocked (hostf); 
     198+ 
     199+           while (ch != '\n' && ch != EOF) 
     200+             ch = getc_unlocked (hostf); 
     201+           continue; 
     202+       } 
     203+ 
     204+       for (;*p && !isspace(*p); ++p) { 
     205+           *p = tolower (*p); 
     206+       } 
     207+ 
     208+       /* Next we want to find the permitted name for the remote user.  */ 
     209+       if (*p == ' ' || *p == '\t') { 
     210+           /* <nul> terminate hostname and skip spaces */ 
     211+           for (*p++='\0'; *p && isspace (*p); ++p); 
     212+ 
     213+           user = p;                   /* this is the user's name */ 
     214+           while (*p && !isspace (*p)) 
     215+               ++p;                    /* find end of user's name */ 
     216+       } else 
     217+           user = p; 
     218+ 
     219+       *p = '\0';              /* <nul> terminate username (+host?) */ 
     220+ 
     221+       /* buf -> host(?) ; user -> username(?) */ 
     222+ 
     223+       /* First check host part */ 
     224+       hcheck = __icheckhost (raddr, buf, rhost); 
     225+ 
     226+       if (hcheck < 0) 
     227+           break; 
     228+ 
     229+       if (hcheck) { 
     230+           /* Then check user part */ 
     231+           if (! (*user)) 
     232+               user = luser; 
     233+ 
     234+           ucheck = __icheckuser (user, ruser); 
     235+ 
     236+           /* Positive 'host user' match? */ 
     237+           if (ucheck > 0) { 
     238+               retval = 0; 
     239+               break; 
     240+           } 
     241+ 
     242+           /* Negative 'host -user' match? */ 
     243+           if (ucheck < 0) 
     244+               break; 
     245+ 
     246+           /* Neither, go on looking for match */ 
     247+       } 
     248+    } 
     249+ 
     250+    free (buf); 
     251+ 
     252+    return retval; 
     253+} 
     254+ 
     255+static int 
     256+iruserok2 (u_int32_t raddr, int superuser, const char *ruser, const char *luser, 
     257+                  const char *rhost) 
     258+{ 
     259+       FILE *hostf = NULL; 
     260+       int isbad = -1; 
     261+ 
     262+       if (!superuser) 
     263+               hostf = iruserfopen (_PATH_HEQUIV, 0); 
     264+ 
     265+       if (hostf) { 
     266+               isbad = __ivaliduser2 (hostf, raddr, luser, ruser, rhost); 
     267+               fclose (hostf); 
     268+ 
     269+               if (!isbad) 
     270+                       return 0; 
     271+       } 
     272+ 
     273+       if (__check_rhosts_file || superuser) { 
     274+               char *pbuf; 
     275+               struct passwd *pwd; 
     276+               size_t dirlen; 
     277+               uid_t uid; 
     278+ 
     279+#ifdef __UCLIBC_HAS_REENTRANT_RPC__ 
     280+               size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX); 
     281+               struct passwd pwdbuf; 
     282+               char *buffer = stack_heap_alloc(buflen); 
     283+ 
     284+               if (getpwnam_r (luser, &pwdbuf, buffer, 
     285+                           buflen, &pwd) != 0 || pwd == NULL) 
     286+               { 
     287+                       stack_heap_free(buffer); 
     288+                       return -1; 
     289+               } 
     290+               stack_heap_free(buffer); 
     291+#else 
     292+               if ((pwd = getpwnam(luser)) == NULL) 
     293+                       return -1; 
     294+#endif 
     295+ 
     296+               dirlen = strlen (pwd->pw_dir); 
     297+               pbuf = malloc (dirlen + sizeof "/.rhosts"); 
     298+               strcpy (pbuf, pwd->pw_dir); 
     299+               strcat (pbuf, "/.rhosts"); 
     300+ 
     301+               /* Change effective uid while reading .rhosts.  If root and 
     302+                  reading an NFS mounted file system, can't read files that 
     303+                  are protected read/write owner only.  */ 
     304+               uid = geteuid (); 
     305+               seteuid (pwd->pw_uid); 
     306+               hostf = iruserfopen (pbuf, pwd->pw_uid); 
     307+               free(pbuf); 
     308+ 
     309+               if (hostf != NULL) { 
     310+                       isbad = __ivaliduser2 (hostf, raddr, luser, ruser, rhost); 
     311+                       fclose (hostf); 
     312+               } 
     313+ 
     314+               seteuid (uid); 
     315+               return isbad; 
     316+       } 
     317+       return -1; 
     318+} 
     319+ 
     320+int ruserok(const char *rhost, int superuser, const char *ruser, 
     321+                       const char *luser) 
     322+{ 
     323+        struct hostent *hp; 
     324+       u_int32_t addr; 
     325+       char **ap; 
     326+#ifdef __UCLIBC_HAS_REENTRANT_RPC__ 
     327+       size_t buflen; 
     328+       char *buffer; 
     329+       int herr; 
     330+       struct hostent hostbuf; 
     331+#endif 
     332+ 
     333+#ifdef __UCLIBC_HAS_REENTRANT_RPC__ 
     334+       buflen = 1024; 
     335+       buffer = stack_heap_alloc(buflen); 
     336+ 
     337+       while (gethostbyname_r (rhost, &hostbuf, buffer, 
     338+                   buflen, &hp, &herr) != 0 || hp == NULL) 
     339+       { 
     340+           if (herr != NETDB_INTERNAL || errno != ERANGE) { 
     341+               stack_heap_free(buffer); 
     342+               return -1; 
     343+           } else 
     344+           { 
     345+               /* Enlarge the buffer.  */ 
     346+               buflen *= 2; 
     347+               stack_heap_free(buffer); 
     348+               buffer = stack_heap_alloc(buflen); 
     349+           } 
     350+       } 
     351+       stack_heap_free(buffer); 
     352+#else 
     353+       if ((hp = gethostbyname(rhost)) == NULL) { 
     354+               return -1; 
     355+       } 
     356+#endif 
     357+       for (ap = hp->h_addr_list; *ap; ++ap) { 
     358+               memmove(&addr, *ap, sizeof(addr)); 
     359+               if (iruserok2(addr, superuser, ruser, luser, rhost) == 0) 
     360+                       return 0; 
     361+       } 
     362+       return -1; 
     363+} 
     364+ 
     365 PAM_EXTERN 
     366 int pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, 
     367                         const char **argv) 
Note: See TracChangeset for help on using the changeset viewer.