Beispiel #1
0
struct group *pr_auth_getgrent(pool *p) {
  cmd_rec *cmd = NULL;
  modret_t *mr = NULL;
  struct group *res = NULL;

  cmd = make_cmd(p, 0);
  mr = dispatch_auth(cmd, "getgrent", NULL);

  if (MODRET_ISHANDLED(mr) && MODRET_HASDATA(mr))
    res = mr->data;

  if (cmd->tmp_pool) {
    destroy_pool(cmd->tmp_pool);
    cmd->tmp_pool = NULL;
  }

  /* Sanity check */
  if (res == NULL)
    return NULL;

  /* Make sure the GID is not -1 */
  if (res->gr_gid == (gid_t) -1) {
    pr_log_pri(PR_LOG_ERR, "error: GID of -1 not allowed");
    return NULL;
  }

  return res;
}
Beispiel #2
0
struct group *pr_auth_getgrgid(pool *p, gid_t gid) {
  cmd_rec *cmd = NULL;
  modret_t *mr = NULL;
  struct group *res = NULL;

  cmd = make_cmd(p, 1, (void *) &gid);
  mr = dispatch_auth(cmd, "getgrgid", NULL);

  if (MODRET_ISHANDLED(mr) && MODRET_HASDATA(mr))
    res = mr->data;

  if (cmd->tmp_pool) {
    destroy_pool(cmd->tmp_pool);
    cmd->tmp_pool = NULL;
  }

  /* Sanity check */
  if (res == NULL) {
    errno = ENOENT;
    return NULL;
  }

  /* Make sure the GID is not -1 */
  if (res->gr_gid == (gid_t) -1) {
    pr_log_pri(PR_LOG_ERR, "error: GID of -1 not allowed");
    return NULL;
  }

  pr_log_debug(DEBUG10, "retrieved group '%s' for GID %lu",
    res->gr_name, (unsigned long) gid);
  return res;
}
Beispiel #3
0
struct passwd *pr_auth_getpwent(pool *p) {
  cmd_rec *cmd = NULL;
  modret_t *mr = NULL;
  struct passwd *res = NULL;

  cmd = make_cmd(p, 0);
  mr = dispatch_auth(cmd, "getpwent", NULL);

  if (MODRET_ISHANDLED(mr) &&
      MODRET_HASDATA(mr)) {
    res = mr->data;
  }

  if (cmd->tmp_pool) {
    destroy_pool(cmd->tmp_pool);
    cmd->tmp_pool = NULL;
  }

  /* Sanity check */
  if (res == NULL)
    return NULL;

  /* Make sure the UID and GID are not -1 */
  if (res->pw_uid == (uid_t) -1) {
    pr_log_pri(PR_LOG_WARNING, "error: UID of -1 not allowed");
    return NULL;
  }

  if (res->pw_gid == (gid_t) -1) {
    pr_log_pri(PR_LOG_WARNING, "error: GID of -1 not allowed");
    return NULL;
  }

  return res;
}
Beispiel #4
0
const char *pr_auth_gid2name(pool *p, gid_t gid) {
  cmd_rec *cmd = NULL;
  modret_t *mr = NULL;
  static char namebuf[64];
  char *res = NULL;
  int have_name = FALSE;

  memset(namebuf, '\0', sizeof(namebuf));

  gidcache_create();

  if ((auth_caching & PR_AUTH_CACHE_FL_GID2NAME) &&
       gid_tab) {
    void *v = NULL;
 
    v = pr_table_kget(gid_tab, (const void *) &gid, sizeof(gid_t), NULL);
    if (v) {
      sstrncpy(namebuf, v, sizeof(namebuf));

      pr_trace_msg(trace_channel, 8,
        "using name '%s' from gidcache for GID %lu", namebuf,
        (unsigned long) gid);

      res = namebuf;
      return res;

    } else {
      pr_trace_msg(trace_channel, 9,
        "no value found in gidcache for GID %lu: %s", (unsigned long) gid,
        strerror(errno));
    }
  }

  cmd = make_cmd(p, 1, (void *) &gid);
  mr = dispatch_auth(cmd, "gid2name", NULL);

  if (MODRET_ISHANDLED(mr) &&
      MODRET_HASDATA(mr)) {
    res = mr->data;
    sstrncpy(namebuf, res, sizeof(namebuf));
    res = namebuf;

    gidcache_add(gid, res);
    have_name = TRUE;
  }

  if (cmd->tmp_pool) {
    destroy_pool(cmd->tmp_pool);
    cmd->tmp_pool = NULL;
  }

  if (!have_name) {
    snprintf(namebuf, sizeof(namebuf)-1, "%lu", (unsigned long) gid);
  }

  res = namebuf;
  return res;
}
Beispiel #5
0
struct passwd *pr_auth_getpwuid(pool *p, uid_t uid) {
  cmd_rec *cmd = NULL;
  modret_t *mr = NULL;
  struct passwd *res = NULL;

  cmd = make_cmd(p, 1, (void *) &uid);
  mr = dispatch_auth(cmd, "getpwuid", NULL);

  if (MODRET_ISHANDLED(mr) &&
      MODRET_HASDATA(mr)) {
    res = mr->data;
  }

  if (cmd->tmp_pool) {
    destroy_pool(cmd->tmp_pool);
    cmd->tmp_pool = NULL;
  }

  /* Sanity check */
  if (res == NULL) {
    errno = ENOENT;
    return NULL;
  }

  /* Make sure the UID and GID are not -1 */
  if (res->pw_uid == (uid_t) -1) {
    pr_log_pri(PR_LOG_WARNING, "error: UID of -1 not allowed");
    return NULL;
  }

  if (res->pw_gid == (gid_t) -1) {
    pr_log_pri(PR_LOG_WARNING, "error: GID of -1 not allowed");
    return NULL;
  }

  pr_log_debug(DEBUG10, "retrieved user '%s' for UID %lu",
    res->pw_name, (unsigned long) uid);
  return res;
}
Beispiel #6
0
struct group *pr_auth_getgrnam(pool *p, const char *name) {
  cmd_rec *cmd = NULL;
  modret_t *mr = NULL;
  struct group *res = NULL;

  cmd = make_cmd(p, 1, name);
  mr = dispatch_auth(cmd, "getgrnam", NULL);

  if (MODRET_ISHANDLED(mr) &&
      MODRET_HASDATA(mr)) {
    res = mr->data;
  }

  if (cmd->tmp_pool) {
    destroy_pool(cmd->tmp_pool);
    cmd->tmp_pool = NULL;
  }

  /* Sanity check */
  if (res == NULL) {
    errno = ENOENT;
    return NULL;
  }

  /* Make sure the GID is not -1 */
  if (res->gr_gid == (gid_t) -1) {
    pr_log_pri(PR_LOG_WARNING, "error: GID of -1 not allowed");
    return NULL;
  }

  gidcache_add(res->gr_gid, name);

  pr_log_debug(DEBUG10, "retrieved GID %lu for group '%s'",
    (unsigned long) res->gr_gid, name);
  return res;
}
Beispiel #7
0
int pr_auth_check(pool *p, const char *cpw, const char *name, const char *pw) {
  cmd_rec *cmd = NULL;
  modret_t *mr = NULL;
  module *m = NULL;
  int res = PR_AUTH_BADPWD;

  cmd = make_cmd(p, 3, cpw, name, pw);

  /* First, check for any of the modules in the "authenticating only" list
   * of modules.  This is usually only mod_auth_pam, but other modules
   * might also add themselves (e.g. mod_radius under certain conditions).
   */
  if (auth_module_list) {
    struct auth_module_elt *elt;

    for (elt = (struct auth_module_elt *) auth_module_list->xas_list; elt;
        elt = elt->next) {

      m = pr_module_get(elt->name);
      if (m) {
        mr = dispatch_auth(cmd, "check", &m);

        if (MODRET_ISHANDLED(mr)) {
          pr_trace_msg(trace_channel, 4,
            "module '%s' used for authenticating user '%s'", elt->name, name);

          res = MODRET_HASDATA(mr) ? PR_AUTH_RFC2228_OK : PR_AUTH_OK;

          if (cmd->tmp_pool) {
            destroy_pool(cmd->tmp_pool);
            cmd->tmp_pool = NULL;
          }

          return res;
        }

        if (MODRET_ISERROR(mr)) {
          res = MODRET_ERROR(mr);

          if (cmd->tmp_pool) {
            destroy_pool(cmd->tmp_pool);
            cmd->tmp_pool = NULL;
          }

          return res;
        }

        m = NULL;
      }
    }
  }

  if (auth_tab) {

    /* Fetch the specific module to be used for authenticating this user. */
    void *v = pr_table_get(auth_tab, name, NULL);
    if (v) {
      m = *((module **) v);

      pr_trace_msg(trace_channel, 4,
        "using module 'mod_%s.c' from authcache to authenticate user '%s'",
        m->name, name);
    }
  }

  mr = dispatch_auth(cmd, "check", m ? &m : NULL);

  if (MODRET_ISHANDLED(mr))
    res = MODRET_HASDATA(mr) ? PR_AUTH_RFC2228_OK : PR_AUTH_OK;

  if (cmd->tmp_pool) {
    destroy_pool(cmd->tmp_pool);
    cmd->tmp_pool = NULL;
  }

  return res;
}
Beispiel #8
0
struct passwd *pr_auth_getpwnam(pool *p, const char *name) {
  cmd_rec *cmd = NULL;
  modret_t *mr = NULL;
  struct passwd *res = NULL;
  module *m = NULL;

  cmd = make_cmd(p, 1, name);
  mr = dispatch_auth(cmd, "getpwnam", &m);

  if (MODRET_ISHANDLED(mr) &&
      MODRET_HASDATA(mr))
    res = mr->data;

  if (cmd->tmp_pool) {
    destroy_pool(cmd->tmp_pool);
    cmd->tmp_pool = NULL;
  }

  /* Sanity check */
  if (res == NULL) {
    errno = ENOENT;
    return NULL;
  }

  /* Make sure the UID and GID are not -1 */
  if (res->pw_uid == (uid_t) -1) {
    pr_log_pri(PR_LOG_ERR, "error: UID of -1 not allowed");
    return NULL;
  }

  if (res->pw_gid == (gid_t) -1) {
    pr_log_pri(PR_LOG_ERR, "error: GID of -1 not allowed");
    return NULL;
  }

  if ((auth_caching & PR_AUTH_CACHE_FL_AUTH_MODULE) &&
      !auth_tab &&
      auth_pool) {
    auth_tab = pr_table_alloc(auth_pool, 0);
  }

  if (m &&
      auth_tab) {
    int count = 0;
    void *value = NULL;

    value = palloc(auth_pool, sizeof(module *));
    *((module **) value) = m;

    count = pr_table_exists(auth_tab, name);
    if (count <= 0) {
      if (pr_table_add(auth_tab, pstrdup(auth_pool, name), value,
          sizeof(module *)) < 0) {
        pr_trace_msg(trace_channel, 3,
          "error adding module 'mod_%s.c' for user '%s' to the authcache: %s",
          m->name, name, strerror(errno));

      } else {
        pr_trace_msg(trace_channel, 5,
          "stashed module 'mod_%s.c' for user '%s' in the authcache",
          m->name, name);
      }

    } else {
      if (pr_table_set(auth_tab, pstrdup(auth_pool, name), value,
          sizeof(module *)) < 0) {
        pr_trace_msg(trace_channel, 3,
          "error setting module 'mod_%s.c' for user '%s' in the authcache: %s",
          m->name, name, strerror(errno));

      } else {
        pr_trace_msg(trace_channel, 5,
          "stashed module 'mod_%s.c' for user '%s' in the authcache",
          m->name, name);
      }
    }
  }

  uidcache_add(res->pw_uid, name);

  /* Get the (possibly rewritten) home directory. */
  res->pw_dir = pr_auth_get_home(p, res->pw_dir);

  pr_log_debug(DEBUG10, "retrieved UID %lu for user '%s'",
    (unsigned long) res->pw_uid, name);
  return res;
}
Beispiel #9
0
int pr_auth_getgroups(pool *p, const char *name, array_header **group_ids,
    array_header **group_names) {

  cmd_rec *cmd = NULL;
  modret_t *mr = NULL;
  int res = -1;

  /* Allocate memory for the array_headers of GIDs and group names. */
  if (group_ids)
    *group_ids = make_array(permanent_pool, 2, sizeof(gid_t));

  if (group_names)
    *group_names = make_array(permanent_pool, 2, sizeof(char *));

  cmd = make_cmd(p, 3, name, group_ids ? *group_ids : NULL,
    group_names ? *group_names : NULL);

  mr = dispatch_auth(cmd, "getgroups", NULL);

  if (MODRET_ISHANDLED(mr) && MODRET_HASDATA(mr)) {
    res = *((int *) mr->data);

    /* Note: the number of groups returned should, barring error,
     * always be at least 1, as per getgroups(2) behavior.  This one
     * ID is present because it is the primary group membership set in
     * struct passwd, from /etc/passwd.  This will need to be documented
     * for the benefit of auth_getgroup() implementors.
     */

    if (group_ids) {
      register unsigned int i;
      char *strgids = "";
      gid_t *gids = (*group_ids)->elts;

      for (i = 0; i < (*group_ids)->nelts; i++) {
        char buf[64];
        snprintf(buf, sizeof(buf)-1, "%lu", (unsigned long) gids[i]);
        buf[sizeof(buf)-1] = '\0';

        strgids = pstrcat(p, strgids, i != 0 ? ", " : "", buf, NULL);
      }

      pr_log_debug(DEBUG10, "retrieved group %s: %s",
        (*group_ids)->nelts == 1 ? "ID" : "IDs", strgids);
    }

    if (group_names) {
      register unsigned int i;
      char *strgroups = ""; 
      char **groups = (*group_names)->elts;

      for (i = 0; i < (*group_names)->nelts; i++)
        strgroups = pstrcat(p, strgroups, i != 0 ? ", " : "", groups[i], NULL);
    
      pr_log_debug(DEBUG10, "retrieved group %s: %s",
        (*group_names)->nelts == 1 ? "name" : "names", strgroups);
    }
  }

  if (cmd->tmp_pool) {
    destroy_pool(cmd->tmp_pool);
    cmd->tmp_pool = NULL;
  }

  return res;
}