コード例 #1
0
ファイル: proxy_id.c プロジェクト: lejonet/sssd
static struct dp_reply_std
proxy_account_info(TALLOC_CTX *mem_ctx,
                   struct proxy_id_ctx *ctx,
                   struct be_acct_req *data,
                   struct be_ctx *be_ctx,
                   struct sss_domain_info *domain)
{
    struct dp_reply_std reply;
    struct sysdb_ctx *sysdb;
    uid_t uid;
    gid_t gid;
    errno_t ret;
    char *endptr;

    sysdb = domain->sysdb;

    /* For now we support only core attrs. */
    if (data->attr_type != BE_ATTR_CORE) {
        dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL, "Invalid attr type");
        return reply;
    }

    /* Proxy provider does not support security ID lookups. */
    if (data->filter_type == BE_FILTER_SECID) {
        dp_reply_std_set(&reply, DP_ERR_FATAL, ENOSYS,
                         "Security lookups are not supported");
        return reply;
    }

    switch (data->entry_type & BE_REQ_TYPE_MASK) {
    case BE_REQ_USER: /* user */
        switch (data->filter_type) {
        case BE_FILTER_ENUM:
            ret = enum_users(mem_ctx, ctx, sysdb, domain);
            break;

        case BE_FILTER_NAME:
            ret = get_pw_name(ctx, domain, data->filter_value);
            break;

        case BE_FILTER_IDNUM:
            uid = (uid_t) strtouint32(data->filter_value, &endptr, 10);
            if (errno || *endptr || (data->filter_value == endptr)) {
                dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                                 "Invalid attr type");
                return reply;
            }
            ret = get_pw_uid(ctx, domain, uid);
            break;
        default:
            dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                             "Invalid filter type");
            return reply;
        }
        break;

    case BE_REQ_GROUP: /* group */
        switch (data->filter_type) {
        case BE_FILTER_ENUM:
            ret = enum_groups(mem_ctx, ctx, sysdb, domain);
            break;
        case BE_FILTER_NAME:
            ret = get_gr_name(ctx, sysdb, domain, data->filter_value);
            break;
        case BE_FILTER_IDNUM:
            gid = (gid_t) strtouint32(data->filter_value, &endptr, 10);
            if (errno || *endptr || (data->filter_value == endptr)) {
                dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                                 "Invalid attr type");
                return reply;
            }
            ret = get_gr_gid(mem_ctx, ctx, sysdb, domain, gid, 0);
            break;
        default:
            dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                             "Invalid filter type");
            return reply;
        }
        break;

    case BE_REQ_INITGROUPS: /* init groups for user */
        if (data->filter_type != BE_FILTER_NAME) {
            dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                             "Invalid filter type");
            return reply;
        }
        if (ctx->ops.initgroups_dyn == NULL) {
            dp_reply_std_set(&reply, DP_ERR_FATAL, ENODEV,
                             "Initgroups call not supported");
            return reply;
        }
        ret = get_initgr(mem_ctx, ctx, sysdb, domain, data->filter_value);
        break;

    case BE_REQ_NETGROUP:
        if (data->filter_type != BE_FILTER_NAME) {
            dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                             "Invalid filter type");
            return reply;
        }
        if (ctx->ops.setnetgrent == NULL || ctx->ops.getnetgrent_r == NULL ||
            ctx->ops.endnetgrent == NULL) {
            dp_reply_std_set(&reply, DP_ERR_FATAL, ENODEV,
                             "Netgroups are not supported");
            return reply;
        }

        ret = get_netgroup(ctx, domain, data->filter_value);
        break;

    case BE_REQ_SERVICES:
        switch (data->filter_type) {
        case BE_FILTER_NAME:
            if (ctx->ops.getservbyname_r == NULL) {
                dp_reply_std_set(&reply, DP_ERR_FATAL, ENODEV,
                                 "Services are not supported");
                return reply;
            }
            ret = get_serv_byname(ctx, domain,
                                  data->filter_value,
                                  data->extra_value);
            break;
        case BE_FILTER_IDNUM:
            if (ctx->ops.getservbyport_r == NULL) {
                dp_reply_std_set(&reply, DP_ERR_FATAL, ENODEV,
                                 "Services are not supported");
                return reply;
            }
            ret = get_serv_byport(ctx, domain,
                                  data->filter_value,
                                  data->extra_value);
            break;
        case BE_FILTER_ENUM:
            if (!ctx->ops.setservent
                    || !ctx->ops.getservent_r
                    || !ctx->ops.endservent) {
                dp_reply_std_set(&reply, DP_ERR_FATAL, ENODEV,
                                 "Services are not supported");
                return reply;
            }
            ret = enum_services(ctx, sysdb, domain);
            break;
        default:
            dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                             "Invalid filter type");
            return reply;
        }
        break;

    default: /*fail*/
        dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                         "Invalid filter type");
        return reply;
    }

    if (ret) {
        if (ret == ENXIO) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "proxy returned UNAVAIL error, going offline!\n");
            be_mark_offline(be_ctx);
        }

        dp_reply_std_set(&reply, DP_ERR_FATAL, ret, NULL);
        return reply;
    }

    dp_reply_std_set(&reply, DP_ERR_OK, EOK, NULL);
    return reply;
}
コード例 #2
0
int
main (int argc, char **argv)
{
  int print_domlist = 0;
  domlist_t domlist[32];
  char *opt, *p;
  int print_current = 0;
  int print_builtin = 1;
  char *print_unix = NULL;
  const char *sep_char = (const char *) cygwin_internal (CW_GETNSSSEP);
  DWORD id_offset = 0x10000, off;
  int c, i;
  char *disp_groupname = NULL;
  //BOOL in_domain;
  int optional_args = 0;

  if (!isatty (1))
    setmode (1, O_BINARY);

  /* Use locale from environment.  If not set or set to "C", use UTF-8. */
  setlocale (LC_CTYPE, "");
  if (!strcmp (setlocale (LC_CTYPE, NULL), "C"))
    setlocale (LC_CTYPE, "en_US.UTF-8");
  fetch_current_pgrp_sid ();

  if (argc == 1)
    {
      int enums = ENUM_PRIMARY | ENUM_LOCAL | ENUM_BUILTIN;
      uintptr_t ticket = cygwin_internal (CW_SETENT, TRUE, enums, NULL);
      if (ticket)
	{
	  struct group *grp;

	  while ((grp = (struct group *) cygwin_internal (CW_GETENT, TRUE,
							  ticket)))
	    printf ("%s:%s:%u:\n", grp->gr_name, grp->gr_passwd, grp->gr_gid);
	  cygwin_internal (CW_ENDENT, TRUE, ticket);
	}
      return 0;
    }

  unsetenv ("POSIXLY_CORRECT"); /* To get optional arg processing right. */
  while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
    switch (c)
      {
      case 'd':
      case 'D':
      case 'l':
      case 'L':
	if (print_domlist >= 32)
	  {
	    fprintf (stderr, "%s: Can not enumerate from more than 32 "
			     "domains and machines.\n",
			     program_invocation_short_name);
	    return 1;
	  }
	domlist[print_domlist].domain = (c == 'd' || c == 'D');
	opt = optarg ?:
	      argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL;
	if (argv[optind] && opt == argv[optind])
	  ++optional_args;
	for (i = 0; i < print_domlist; ++i)
	  if (domlist[i].domain == domlist[print_domlist].domain
	      && ((!domlist[i].str && !opt)
		  || (domlist[i].str && opt
		      && (off = strlen (domlist[i].str))
		      && !strncmp (domlist[i].str, opt, off)
		      && (!opt[off] || opt[off] == ','))))
	    {
	      fprintf (stderr, "%s: Duplicate %s '%s'.  Skipping...\n",
		       program_invocation_short_name,
		       domlist[i].domain ? "domain" : "machine",
		       domlist[i].str);
	      goto skip;
	    }
	domlist[print_domlist].str = opt;
	if (opt && (p = strchr (opt, ',')))
	  {
	    if (p == opt)
	      {
		fprintf (stderr, "%s: Malformed machine,offset string '%s'.  "
			 "Skipping...\n", program_invocation_short_name, opt);
		break;
	      }
	    *p = '\0';
	  }
	domlist[print_domlist++].with_dom = (c == 'L');
skip:
	break;
      case 'S':
	sep_char = optarg;
	if (strlen (sep_char) > 1)
	  {
	    fprintf (stderr, "%s: Only one ASCII character allowed as "
			     "domain\\user separator character.\n",
			     program_invocation_short_name);
	    return 1;
	  }
	if (*sep_char == ':')
	  {
	    fprintf (stderr, "%s: Colon not allowed as domain\\user separator "
			     "character.\n", program_invocation_short_name);
	    return 1;
	  }
	break;
      case 'U':
	print_unix = optarg;
	break;
      case 'c':
      case 'C':
	print_current = 1;
	break;
      case 'o':
	id_offset = strtol (optarg, NULL, 10);
	break;
      case 'b':
	print_builtin = 0;
	break;
      case 's':
	break;
      case 'u':
	break;
      case 'g':
	disp_groupname = optarg;
	break;
      case 'h':
	usage (stdout);
	return 0;
      case 'V':
	print_version ();
	return 0;
      default:
	fprintf (stderr, "Try `%s --help' for more information.\n", argv[0]);
	return 1;
      }

  optind += optional_args;
  if (argv[optind])
    {
      fprintf (stderr,
	       "mkgroup: non-option command line argument `%s' is not allowed.\n"
	       "Try `mkgroup --help' for more information.\n", argv[optind]);
      exit (1);
    }

  struct group *pgrp = NULL;
  if (print_current)
    pgrp = (struct group *) cygwin_internal (CW_GETGRSID, TRUE, curr_pgrp.psid);

  int enums = ENUM_NONE;
  WCHAR tdoms[print_domlist * 258];
  PWCHAR t = tdoms;
  if (!disp_groupname && print_builtin && print_domlist)
    enums |= ENUM_BUILTIN;
  for (i = 0; i < print_domlist; ++i)
    {
      if (domlist[i].domain)
	{
	  if (domlist[i].str)
	    {
	      enums |= ENUM_TDOMS;
	      t += mbstowcs (t, domlist[i].str, 257);
	      *t++ = L'\0';
	    }
	  else
	    enums |= ENUM_PRIMARY;
	}
      else if (!domlist[i].str)
	enums |= ENUM_LOCAL;
    }
  if (t > tdoms)
    *t++ = L'\0';
  if (enums)
    {
      uintptr_t ticket = cygwin_internal (CW_SETENT, TRUE, enums,
					  t > tdoms ? tdoms : NULL);
      if (ticket)
	{
	  struct group *grp;
	  const char *nss_sep = (const char *) cygwin_internal (CW_GETNSSSEP);

	  while ((grp = (struct group *)
			cygwin_internal (CW_GETENT, TRUE, ticket)))
	    {
	      if (disp_groupname
		  && strcasecmp (disp_groupname, grp->gr_name) != 0
		  && (!(p = strchr (grp->gr_name, nss_sep[0]))
		      || strcasecmp (disp_groupname, p + 1) != 0))
		continue;
	      printf ("%s:%s:%u:\n", grp->gr_name, grp->gr_passwd,
				     grp->gr_gid);
	      if (pgrp && !strcmp (grp->gr_passwd, pgrp->gr_passwd))
		got_curr_pgrp = TRUE;
	    }
	  cygwin_internal (CW_ENDENT, TRUE, ticket);
	}
    }

  if (print_current && !got_curr_pgrp)
    printf ("%s:%s:%u:\n", pgrp->gr_name, pgrp->gr_passwd, pgrp->gr_gid);

  off = 0xfd000000;
  for (i = 0; i < print_domlist; ++i)
    {
      if (domlist[i].domain || !domlist[i].str)
	continue;
      if (!enum_local_groups (domlist + i, sep_char, off, disp_groupname,
			      print_builtin, print_current))
	{
	  enum_groups (domlist + i, sep_char, off, disp_groupname,
		       print_current);
	  if (!domlist[i].domain && domlist[i].str && print_unix)
	    enum_unix_groups (domlist + i, sep_char, 0xff000000, print_unix);
	  off += id_offset;
	}
    }

  return 0;
}
コード例 #3
0
ファイル: proxy_id.c プロジェクト: AbhishekKumarSingh/sssd
void proxy_get_account_info(struct be_req *breq)
{
    struct be_ctx *be_ctx = be_req_get_be_ctx(breq);
    struct be_acct_req *ar;
    struct proxy_id_ctx *ctx;
    struct sysdb_ctx *sysdb;
    struct sss_domain_info *domain;
    uid_t uid;
    gid_t gid;
    int ret;
    char *endptr;

    ar = talloc_get_type(be_req_get_data(breq), struct be_acct_req);
    ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data,
                          struct proxy_id_ctx);
    sysdb = be_ctx->domain->sysdb;
    domain = be_ctx->domain;

    if (be_is_offline(be_ctx)) {
        return be_req_terminate(breq, DP_ERR_OFFLINE, EAGAIN, "Offline");
    }

    /* for now we support only core attrs */
    if (ar->attr_type != BE_ATTR_CORE) {
        return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid attr type");
    }

    /* proxy provider does not support security ID lookups */
    if (ar->filter_type == BE_FILTER_SECID) {
        return be_req_terminate(breq, DP_ERR_FATAL, ENOSYS,
                                "Invalid filter type");
    }

    switch (ar->entry_type & BE_REQ_TYPE_MASK) {
    case BE_REQ_USER: /* user */
        switch (ar->filter_type) {
        case BE_FILTER_ENUM:
            ret = enum_users(breq, ctx, sysdb, domain);
            break;

        case BE_FILTER_NAME:
            ret = get_pw_name(breq, ctx, sysdb, domain, ar->filter_value);
            break;

        case BE_FILTER_IDNUM:
            uid = (uid_t) strtouint32(ar->filter_value, &endptr, 10);
            if (errno || *endptr || (ar->filter_value == endptr)) {
                return be_req_terminate(breq, DP_ERR_FATAL,
                                   EINVAL, "Invalid attr type");
            }
            ret = get_pw_uid(breq, ctx, sysdb, domain, uid);
            break;
        default:
            return be_req_terminate(breq, DP_ERR_FATAL,
                               EINVAL, "Invalid filter type");
        }
        break;

    case BE_REQ_GROUP: /* group */
        switch (ar->filter_type) {
        case BE_FILTER_ENUM:
            ret = enum_groups(breq, ctx, sysdb, domain);
            break;
        case BE_FILTER_NAME:
            ret = get_gr_name(breq, ctx, sysdb, domain, ar->filter_value);
            break;
        case BE_FILTER_IDNUM:
            gid = (gid_t) strtouint32(ar->filter_value, &endptr, 10);
            if (errno || *endptr || (ar->filter_value == endptr)) {
                return be_req_terminate(breq, DP_ERR_FATAL,
                                   EINVAL, "Invalid attr type");
            }
            ret = get_gr_gid(breq, ctx, sysdb, domain, gid, 0);
            break;
        default:
            return be_req_terminate(breq, DP_ERR_FATAL,
                               EINVAL, "Invalid filter type");
        }
        break;

    case BE_REQ_INITGROUPS: /* init groups for user */
        if (ar->filter_type != BE_FILTER_NAME) {
            return be_req_terminate(breq, DP_ERR_FATAL,
                               EINVAL, "Invalid filter type");
        }
        if (ctx->ops.initgroups_dyn == NULL) {
            return be_req_terminate(breq, DP_ERR_FATAL,
                               ENODEV, "Initgroups call not supported");
        }
        ret = get_initgr(breq, ctx, sysdb, domain, ar->filter_value);
        break;

    case BE_REQ_NETGROUP:
        if (ar->filter_type != BE_FILTER_NAME) {
            return be_req_terminate(breq, DP_ERR_FATAL,
                               EINVAL, "Invalid filter type");
        }
        if (ctx->ops.setnetgrent == NULL || ctx->ops.getnetgrent_r == NULL ||
            ctx->ops.endnetgrent == NULL) {
            return be_req_terminate(breq, DP_ERR_FATAL,
                               ENODEV, "Netgroups are not supported");
        }

        ret = get_netgroup(ctx, sysdb, domain, ar->filter_value);
        break;

    case BE_REQ_SERVICES:
        switch (ar->filter_type) {
        case BE_FILTER_NAME:
            if (ctx->ops.getservbyname_r == NULL) {
                return be_req_terminate(breq, DP_ERR_FATAL,
                                   ENODEV, "Services are not supported");
            }
            ret = get_serv_byname(ctx, sysdb, domain,
                                  ar->filter_value,
                                  ar->extra_value);
            break;
        case BE_FILTER_IDNUM:
            if (ctx->ops.getservbyport_r == NULL) {
                return be_req_terminate(breq, DP_ERR_FATAL,
                                   ENODEV, "Services are not supported");
            }
            ret = get_serv_byport(ctx, sysdb, domain,
                                  ar->filter_value,
                                  ar->extra_value);
            break;
        case BE_FILTER_ENUM:
            if (!ctx->ops.setservent
                    || !ctx->ops.getservent_r
                    || !ctx->ops.endservent) {
                return be_req_terminate(breq, DP_ERR_FATAL,
                                   ENODEV, "Services are not supported");
            }
            ret = enum_services(ctx, sysdb, domain);
            break;
        default:
            return be_req_terminate(breq, DP_ERR_FATAL,
                               EINVAL, "Invalid filter type");
        }
        break;

    default: /*fail*/
        return be_req_terminate(breq, DP_ERR_FATAL,
                           EINVAL, "Invalid request type");
    }

    if (ret) {
        if (ret == ENXIO) {
            DEBUG(2, ("proxy returned UNAVAIL error, going offline!\n"));
            be_mark_offline(be_ctx);
        }
        be_req_terminate(breq, DP_ERR_FATAL, ret, NULL);
        return;
    }
    be_req_terminate(breq, DP_ERR_OK, EOK, NULL);
}