#include "../lib/util/util_pw.h"
#include "lib/winbind_util.h"
#include "passdb.h"
+#include "secrets.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH
size_t i;
struct dom_sid tmp_sid;
struct wbcUnixId *ids;
+ struct dom_sid *filter_sids;
+ uint32_t num_filter_sids;
/*
* If winbind is not around, we can not make much use of the SIDs the
return NT_STATUS_NO_MEMORY;
}
+ if (!secrets_groupfilter_fetch(talloc_tos(), &filter_sids,
+ &num_filter_sids)) {
+ num_filter_sids = 0;
+ }
+
/* Start at index 1, where the groups start. */
for (i=1; i<t->num_sids; i++) {
+ /*
+ * For secondary groups, potentially apply a group
+ * filter for hosts with a silly groups-per-user limit
+ * such as for example Solaris
+ */
+
+ if ((i > 1) && (num_filter_sids != 0)) {
+ /*
+ * We have a SID filter in secrets.tdb, only
+ * convert the SIDs in that filter to GIDs.
+ */
+ if (bsearch(&t->sids[i], filter_sids, num_filter_sids,
+ sizeof(struct dom_sid),
+ sid_compare_sort) == NULL) {
+ DEBUG(10, ("Filtering out SID %s\n",
+ sid_string_dbg(&t->sids[i])));
+ continue;
+ }
+ }
+
if (ids[i].type != WBC_ID_TYPE_GID) {
DEBUG(10, ("Could not convert SID %s to gid, "
"ignoring it\n",
}
}
+ TALLOC_FREE(filter_sids);
+
/*
* Add the "Unix Group" SID for each gid to catch mapped groups
* and their Unix equivalent. This is to solve the backwards
uint32_t *num_user_sids,
bool include_user_group_rid,
bool skip_ressource_groups);
+int sid_compare_sort(const void *p1, const void *p2);
/* The following definitions come from lib/util_sock.c */
#define SECRETS_AUTH_DOMAIN "SECRETS/AUTH_DOMAIN"
#define SECRETS_AUTH_PASSWORD "SECRETS/AUTH_PASSWORD"
+#define SECRETS_GROUPFILTER_KEY "SECRETS/GROUPFILTER"
+
/* structure for storing machine account password
(ie. when samba server is member of a domain */
struct machine_acct_pass {
bool secrets_store_generic(const char *owner, const char *key, const char *secret);
char *secrets_fetch_generic(const char *owner, const char *key);
bool secrets_delete_generic(const char *owner, const char *key);
+bool secrets_groupfilter_fetch(TALLOC_CTX *mem_ctx, struct dom_sid **psids,
+ uint32_t *pnum_sids);
#endif /* _SECRETS_H */
return True;
}
+int sid_compare_sort(const void *p1, const void *p2)
+{
+ const struct dom_sid *sid1 = (const struct dom_sid *)p1;
+ const struct dom_sid *sid2 = (const struct dom_sid *)p2;
+ int i;
+
+ if (sid1->sid_rev_num != sid2->sid_rev_num) {
+ return sid1->sid_rev_num - sid2->sid_rev_num;
+ }
+
+ for (i = 0; i < 6; i++) {
+ if (sid1->id_auth[i] != sid2->id_auth[i]) {
+ return sid1->id_auth[i] - sid2->id_auth[i];
+ }
+ }
+
+ if (sid1->num_auths != sid2->num_auths) {
+ return sid1->num_auths - sid2->num_auths;
+ }
+
+ for (i = 0; i<sid1->num_auths; i++) {
+ if (sid1->sub_auths[i] != sid2->sub_auths[i]) {
+ return sid1->sub_auths[i] - sid2->sub_auths[i];
+ }
+ }
+
+ return 0;
+}
+
/*****************************************************************
Returns true if SID is internal (and non-mappable).
*****************************************************************/
return secret;
}
+bool secrets_groupfilter_fetch(TALLOC_CTX *mem_ctx, struct dom_sid **psids,
+ uint32_t *pnum_sids)
+{
+ void *buf;
+ size_t buflen;
+ struct dom_sid *sids;
+ size_t num_sids;
+
+ buf = secrets_fetch(SECRETS_GROUPFILTER_KEY, &buflen);
+
+ if (buf == NULL) {
+ *psids = NULL;
+ *pnum_sids = 0;
+ return true;
+ }
+
+ if ((buflen % sizeof(struct dom_sid)) != 0) {
+ d_fprintf(stderr, "Invalid array size in secrets.tdb\n");
+ }
+
+ num_sids = buflen / sizeof(struct dom_sid);
+ sids = TALLOC_MEMDUP(
+ talloc_tos(), buf, num_sids * sizeof(struct dom_sid));
+ SAFE_FREE(buf);
+ if (sids == NULL) {
+ d_fprintf(stderr, "Could not allocate SIDs\n");
+ return false;
+ }
+
+ *psids = sids;
+ *pnum_sids = num_sids;
+ return true;
+}
return 0;
}
+static int net_groupfilter_addsid(struct net_context *c, int argc,
+ const char **argv)
+{
+ struct dom_sid sid;
+ struct dom_sid *sids;
+ uint32_t num_sids;
+
+ if (argc != 1) {
+ d_fprintf(stderr, "usage: net groupfilter addsid <SID>\n");
+ return -1;
+ }
+
+ if (!string_to_sid(&sid, argv[0])) {
+ d_fprintf(stderr, "Could not convert '%s' to SID\n", argv[0]);
+ return -1;
+ }
+
+ if (!secrets_groupfilter_fetch(talloc_tos(), &sids, &num_sids)) {
+ d_fprintf(stderr, "Could not fetch sid list\n");
+ return -1;
+ }
+
+ if (!NT_STATUS_IS_OK(add_sid_to_array_unique(talloc_tos(), &sid,
+ &sids, &num_sids))) {
+ d_fprintf(stderr, "add_sid_to_array_unique failed\n");
+ TALLOC_FREE(sids);
+ return -1;
+ }
+
+ qsort(sids, num_sids, sizeof(struct dom_sid), sid_compare_sort);
+
+ if (!secrets_store(SECRETS_GROUPFILTER_KEY, sids,
+ num_sids * sizeof(struct dom_sid))) {
+ d_fprintf(stderr, "secrets_store failed\n");
+ TALLOC_FREE(sids);
+ return -1;
+ }
+
+ TALLOC_FREE(sids);
+
+ return 0;
+}
+
+static int net_groupfilter_delsid(struct net_context *c, int argc,
+ const char **argv)
+{
+ struct dom_sid sid;
+ struct dom_sid *sids;
+ uint32_t num_sids;
+ bool res;
+
+ if (argc != 1) {
+ d_fprintf(stderr, "usage: net groupfilter delsid <SID>\n");
+ return -1;
+ }
+
+ if (!string_to_sid(&sid, argv[0])) {
+ d_fprintf(stderr, "Could not convert '%s' to SID\n", argv[0]);
+ return -1;
+ }
+
+ if (!secrets_groupfilter_fetch(talloc_tos(), &sids, &num_sids)) {
+ d_fprintf(stderr, "Could not fetch sid list\n");
+ return -1;
+ }
+
+ del_sid_from_array(&sid, &sids, &num_sids);
+
+ if (num_sids == 0) {
+ res = secrets_delete(SECRETS_GROUPFILTER_KEY);
+ } else {
+ res = secrets_store(SECRETS_GROUPFILTER_KEY, sids,
+ num_sids * sizeof(struct dom_sid));
+ }
+
+ if (!res) {
+ d_fprintf(stderr, "secrets_store failed\n");
+ TALLOC_FREE(sids);
+ return -1;
+ }
+
+ TALLOC_FREE(sids);
+
+ return 0;
+}
+
+static int net_groupfilter_list(struct net_context *c, int argc,
+ const char **argv)
+{
+ struct dom_sid *sids;
+ uint32_t num_sids;
+ int i;
+
+ if (!secrets_groupfilter_fetch(talloc_tos(), &sids, &num_sids)) {
+ d_fprintf(stderr, "Could not fetch sid list\n");
+ return -1;
+ }
+
+ for (i=0; i<num_sids; i++) {
+ d_printf("%s\n", sid_string_tos(&sids[i]));
+ }
+
+ TALLOC_FREE(sids);
+
+ return 0;
+}
+
+static int net_groupfilter(struct net_context *c, int argc,
+ const char **argv)
+{
+ struct functable func[] = {
+ {
+ "addsid",
+ net_groupfilter_addsid,
+ NET_TRANSPORT_LOCAL,
+ "Add a SID to the groupfilter",
+ ""
+ },
+ {
+ "delsid",
+ net_groupfilter_delsid,
+ NET_TRANSPORT_LOCAL,
+ "Delete a SID from the groupfilter",
+ ""
+ },
+ {
+ "list",
+ net_groupfilter_list,
+ NET_TRANSPORT_LOCAL,
+ "List groupfilter SIDs",
+ ""
+ },
+ { NULL, NULL, 0, NULL, NULL }
+ };
+
+ return net_run_function(c, argc, argv, "net groupfilter", func);
+}
+
/* main function table */
static struct functable net_func[] = {
{
N_(" Use 'net help serverid' to get more information about "
"'net serverid' commands.")
},
+ { "groupfilter",
+ net_groupfilter,
+ NET_TRANSPORT_LOCAL,
+ "Edit the groupfilter sidlist",
+ " "
+ },
#ifdef WITH_FAKE_KASERVER
{ "afs",