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; }
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; }
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); }