Diff for /embedaddon/sudo/plugins/sudoers/pwutil.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2012/05/29 12:26:49 version 1.1.1.3, 2012/10/09 09:29:52
Line 1 Line 1
 /*  /*
 * Copyright (c) 1996, 1998-2005, 2007-2011 * Copyright (c) 1996, 1998-2005, 2007-2012
  *      Todd C. Miller <Todd.Miller@courtesan.com>   *      Todd C. Miller <Todd.Miller@courtesan.com>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
Line 224  make_pwitem(const struct passwd *pw, const char *name) Line 224  make_pwitem(const struct passwd *pw, const char *name)
 }  }
   
 void  void
pw_addref(struct passwd *pw)sudo_pw_addref(struct passwd *pw)
 {  {
    debug_decl(pw_addref, SUDO_DEBUG_NSS)    debug_decl(sudo_pw_addref, SUDO_DEBUG_NSS)
     ptr_to_item(pw)->refcnt++;      ptr_to_item(pw)->refcnt++;
     debug_return;      debug_return;
 }  }
   
 static void  static void
pw_delref_item(void *v)sudo_pw_delref_item(void *v)
 {  {
     struct cache_item *item = v;      struct cache_item *item = v;
    debug_decl(pw_delref_item, SUDO_DEBUG_NSS)    debug_decl(sudo_pw_delref_item, SUDO_DEBUG_NSS)
   
     if (--item->refcnt == 0)      if (--item->refcnt == 0)
         efree(item);          efree(item);
Line 244  pw_delref_item(void *v) Line 244  pw_delref_item(void *v)
 }  }
   
 void  void
pw_delref(struct passwd *pw)sudo_pw_delref(struct passwd *pw)
 {  {
    debug_decl(pw_delref, SUDO_DEBUG_NSS)    debug_decl(sudo_pw_delref, SUDO_DEBUG_NSS)
    pw_delref_item(ptr_to_item(pw));    sudo_pw_delref_item(ptr_to_item(pw));
     debug_return;      debug_return;
 }  }
   
Line 378  sudo_fakepwnamid(const char *user, uid_t uid, gid_t gi Line 378  sudo_fakepwnamid(const char *user, uid_t uid, gid_t gi
             /* Store by uid, overwriting cached version. */              /* Store by uid, overwriting cached version. */
             pwitem->cache.k.uid = pw->pw_uid;              pwitem->cache.k.uid = pw->pw_uid;
             if ((node = rbinsert(pwcache_byuid, &pwitem->cache)) != NULL) {              if ((node = rbinsert(pwcache_byuid, &pwitem->cache)) != NULL) {
                pw_delref_item(node->data);                sudo_pw_delref_item(node->data);
                 node->data = &pwitem->cache;                  node->data = &pwitem->cache;
             }              }
         } else {          } else {
             /* Store by name, overwriting cached version. */              /* Store by name, overwriting cached version. */
             pwitem->cache.k.name = pw->pw_name;              pwitem->cache.k.name = pw->pw_name;
             if ((node = rbinsert(pwcache_byname, &pwitem->cache)) != NULL) {              if ((node = rbinsert(pwcache_byname, &pwitem->cache)) != NULL) {
                pw_delref_item(node->data);                sudo_pw_delref_item(node->data);
                 node->data = &pwitem->cache;                  node->data = &pwitem->cache;
             }              }
         }          }
Line 426  sudo_freepwcache(void) Line 426  sudo_freepwcache(void)
     debug_decl(sudo_freepwcache, SUDO_DEBUG_NSS)      debug_decl(sudo_freepwcache, SUDO_DEBUG_NSS)
   
     if (pwcache_byuid != NULL) {      if (pwcache_byuid != NULL) {
        rbdestroy(pwcache_byuid, pw_delref_item);        rbdestroy(pwcache_byuid, sudo_pw_delref_item);
         pwcache_byuid = NULL;          pwcache_byuid = NULL;
     }      }
     if (pwcache_byname != NULL) {      if (pwcache_byname != NULL) {
        rbdestroy(pwcache_byname, pw_delref_item);        rbdestroy(pwcache_byname, sudo_pw_delref_item);
         pwcache_byname = NULL;          pwcache_byname = NULL;
     }      }
   
Line 598  again: Line 598  again:
             if (cp - (char *)grlitem + len > total) {              if (cp - (char *)grlitem + len > total) {
                 total += len + GROUPNAME_LEN;                  total += len + GROUPNAME_LEN;
                 efree(grlitem);                  efree(grlitem);
                gr_delref(grp);                sudo_gr_delref(grp);
                 goto again;                  goto again;
             }              }
             memcpy(cp, grp->gr_name, len);              memcpy(cp, grp->gr_name, len);
             grlist->groups[ngroups++] = cp;              grlist->groups[ngroups++] = cp;
             cp += len;              cp += len;
            gr_delref(grp);            sudo_gr_delref(grp);
         }          }
     }      }
     grlist->ngroups = ngroups;      grlist->ngroups = ngroups;
Line 617  again: Line 617  again:
 }  }
   
 void  void
gr_addref(struct group *gr)sudo_gr_addref(struct group *gr)
 {  {
    debug_decl(gr_addref, SUDO_DEBUG_NSS)    debug_decl(sudo_gr_addref, SUDO_DEBUG_NSS)
     ptr_to_item(gr)->refcnt++;      ptr_to_item(gr)->refcnt++;
     debug_return;      debug_return;
 }  }
   
 static void  static void
gr_delref_item(void *v)sudo_gr_delref_item(void *v)
 {  {
     struct cache_item *item = v;      struct cache_item *item = v;
    debug_decl(gr_delref_item, SUDO_DEBUG_NSS)    debug_decl(sudo_gr_delref_item, SUDO_DEBUG_NSS)
   
     if (--item->refcnt == 0)      if (--item->refcnt == 0)
         efree(item);          efree(item);
Line 637  gr_delref_item(void *v) Line 637  gr_delref_item(void *v)
 }  }
   
 void  void
gr_delref(struct group *gr)sudo_gr_delref(struct group *gr)
 {  {
    debug_decl(gr_delref, SUDO_DEBUG_NSS)    debug_decl(sudo_gr_delref, SUDO_DEBUG_NSS)
    gr_delref_item(ptr_to_item(gr));    sudo_gr_delref_item(ptr_to_item(gr));
     debug_return;      debug_return;
 }  }
   
Line 748  sudo_fakegrnam(const char *group) Line 748  sudo_fakegrnam(const char *group)
             /* Store by gid, overwriting cached version. */              /* Store by gid, overwriting cached version. */
             gritem->cache.k.gid = gr->gr_gid;              gritem->cache.k.gid = gr->gr_gid;
             if ((node = rbinsert(grcache_bygid, &gritem->cache)) != NULL) {              if ((node = rbinsert(grcache_bygid, &gritem->cache)) != NULL) {
                gr_delref_item(node->data);                sudo_gr_delref_item(node->data);
                 node->data = &gritem->cache;                  node->data = &gritem->cache;
             }              }
         } else {          } else {
             /* Store by name, overwriting cached version. */              /* Store by name, overwriting cached version. */
             gritem->cache.k.name = gr->gr_name;              gritem->cache.k.name = gr->gr_name;
             if ((node = rbinsert(grcache_byname, &gritem->cache)) != NULL) {              if ((node = rbinsert(grcache_byname, &gritem->cache)) != NULL) {
                gr_delref_item(node->data);                sudo_gr_delref_item(node->data);
                 node->data = &gritem->cache;                  node->data = &gritem->cache;
             }              }
         }          }
Line 765  sudo_fakegrnam(const char *group) Line 765  sudo_fakegrnam(const char *group)
 }  }
   
 void  void
grlist_addref(struct group_list *grlist)sudo_grlist_addref(struct group_list *grlist)
 {  {
    debug_decl(gr_addref, SUDO_DEBUG_NSS)    debug_decl(sudo_gr_addref, SUDO_DEBUG_NSS)
     ptr_to_item(grlist)->refcnt++;      ptr_to_item(grlist)->refcnt++;
     debug_return;      debug_return;
 }  }
   
 static void  static void
grlist_delref_item(void *v)sudo_grlist_delref_item(void *v)
 {  {
     struct cache_item *item = v;      struct cache_item *item = v;
    debug_decl(gr_delref_item, SUDO_DEBUG_NSS)    debug_decl(sudo_gr_delref_item, SUDO_DEBUG_NSS)
   
     if (--item->refcnt == 0)      if (--item->refcnt == 0)
         efree(item);          efree(item);
Line 785  grlist_delref_item(void *v) Line 785  grlist_delref_item(void *v)
 }  }
   
 void  void
grlist_delref(struct group_list *grlist)sudo_grlist_delref(struct group_list *grlist)
 {  {
    debug_decl(gr_delref, SUDO_DEBUG_NSS)    debug_decl(sudo_gr_delref, SUDO_DEBUG_NSS)
    grlist_delref_item(ptr_to_item(grlist));    sudo_grlist_delref_item(ptr_to_item(grlist));
     debug_return;      debug_return;
 }  }
   
Line 814  sudo_freegrcache(void) Line 814  sudo_freegrcache(void)
     debug_decl(sudo_freegrcache, SUDO_DEBUG_NSS)      debug_decl(sudo_freegrcache, SUDO_DEBUG_NSS)
   
     if (grcache_bygid != NULL) {      if (grcache_bygid != NULL) {
        rbdestroy(grcache_bygid, gr_delref_item);        rbdestroy(grcache_bygid, sudo_gr_delref_item);
         grcache_bygid = NULL;          grcache_bygid = NULL;
     }      }
     if (grcache_byname != NULL) {      if (grcache_byname != NULL) {
        rbdestroy(grcache_byname, gr_delref_item);        rbdestroy(grcache_byname, sudo_gr_delref_item);
         grcache_byname = NULL;          grcache_byname = NULL;
     }      }
     if (grlist_cache != NULL) {      if (grlist_cache != NULL) {
        rbdestroy(grlist_cache, grlist_delref_item);        rbdestroy(grlist_cache, sudo_grlist_delref_item);
         grlist_cache = NULL;          grlist_cache = NULL;
     }      }
   
Line 841  sudo_endgrent(void) Line 841  sudo_endgrent(void)
 }  }
   
 struct group_list *  struct group_list *
get_group_list(struct passwd *pw)sudo_get_grlist(struct passwd *pw)
 {  {
     struct cache_item key, *item;      struct cache_item key, *item;
     struct rbnode *node;      struct rbnode *node;
     size_t len;      size_t len;
     GETGROUPS_T *gids;      GETGROUPS_T *gids;
     int ngids;      int ngids;
    debug_decl(get_group_list, SUDO_DEBUG_NSS)    debug_decl(sudo_get_grlist, SUDO_DEBUG_NSS)
   
     key.k.name = pw->pw_name;      key.k.name = pw->pw_name;
     if ((node = rbfind(grlist_cache, &key)) != NULL) {      if ((node = rbfind(grlist_cache, &key)) != NULL) {
Line 857  get_group_list(struct passwd *pw) Line 857  get_group_list(struct passwd *pw)
     }      }
     /*      /*
      * Cache group db entry if it exists or a negative response if not.       * Cache group db entry if it exists or a negative response if not.
        * Use gids list from front-end if possible, otherwise getgrouplist().
      */       */
       if (pw == sudo_user.pw && sudo_user.gids != NULL) {
           gids = user_gids;
           ngids = user_ngids;
           user_gids = NULL;
           user_ngids = 0;
       } else {
 #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX)  #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX)
    ngids = (int)sysconf(_SC_NGROUPS_MAX) * 2;        ngids = (int)sysconf(_SC_NGROUPS_MAX) * 2;
    if (ngids < 0)        if (ngids < 0)
 #endif  #endif
        ngids = NGROUPS_MAX * 2;            ngids = NGROUPS_MAX * 2;
    gids = emalloc2(ngids, sizeof(GETGROUPS_T)); 
    if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) { 
        efree(gids); 
         gids = emalloc2(ngids, sizeof(GETGROUPS_T));          gids = emalloc2(ngids, sizeof(GETGROUPS_T));
         if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) {          if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) {
             efree(gids);              efree(gids);
            debug_return_ptr(NULL);            gids = emalloc2(ngids, sizeof(GETGROUPS_T));
             if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) {
                 efree(gids);
                 debug_return_ptr(NULL);
             }
         }          }
     }      }
     if (ngids > 0) {      if (ngids > 0) {
Line 896  done: Line 904  done:
     debug_return_ptr(item->d.grlist);      debug_return_ptr(item->d.grlist);
 }  }
   
 void  
 set_group_list(const char *user, GETGROUPS_T *gids, int ngids)  
 {  
     struct cache_item key, *item;  
     struct rbnode *node;  
     debug_decl(set_group_list, SUDO_DEBUG_NSS)  
   
     /*  
      * Cache group db entry if it doesn't already exist  
      */  
     key.k.name = (char *) user;  
     if ((node = rbfind(grlist_cache, &key)) == NULL) {  
         if ((item = make_grlist_item(user, gids, ngids)) == NULL)  
             errorx(1, "unable to parse group list for %s", user);  
         if (rbinsert(grlist_cache, item) != NULL)  
             errorx(1, "unable to cache group list for %s, already exists",  
                 user);  
     }  
     debug_return;  
 }  
   
 bool  bool
 user_in_group(struct passwd *pw, const char *group)  user_in_group(struct passwd *pw, const char *group)
 {  {
Line 926  user_in_group(struct passwd *pw, const char *group) Line 913  user_in_group(struct passwd *pw, const char *group)
     bool matched = false;      bool matched = false;
     debug_decl(user_in_group, SUDO_DEBUG_NSS)      debug_decl(user_in_group, SUDO_DEBUG_NSS)
   
    if ((grlist = get_group_list(pw)) != NULL) {    if ((grlist = sudo_get_grlist(pw)) != NULL) {
         /*          /*
          * If it could be a sudo-style group ID check gids first.           * If it could be a sudo-style group ID check gids first.
          */           */
Line 964  user_in_group(struct passwd *pw, const char *group) Line 951  user_in_group(struct passwd *pw, const char *group)
         }          }
 done:  done:
         if (grp != NULL)          if (grp != NULL)
            gr_delref(grp);            sudo_gr_delref(grp);
        grlist_delref(grlist);        sudo_grlist_delref(grlist);
     }      }
     debug_return_bool(matched);      debug_return_bool(matched);
 }  }

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>