NTSTATUS status;
size_t i;
+ struct dom_sid *filter_sids;
+ size_t num_filter_sids;
mem_ctx = talloc_new(NULL);
if (mem_ctx == NULL) {
server_info->n_groups = 0;
server_info->groups = NULL;
+ if (!secrets_groupfilter_fetch(mem_ctx, &filter_sids,
+ &num_filter_sids)) {
+ num_filter_sids = 0;
+ }
+
/* Start at index 1, where the groups start. */
for (i=1; i<server_info->ptok->num_sids; i++) {
gid_t gid;
DOM_SID *sid = &server_info->ptok->user_sids[i];
+ size_t sidindex;
+
+ /*
+ * 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(sid, filter_sids, num_filter_sids,
+ sizeof(struct dom_sid),
+ sid_compare_sort) == NULL) {
+ DEBUG(10, ("Filtering out SID %s\n",
+ sid_string_dbg(sid)));
+ continue;
+ }
+ }
if (!sid_to_gid(sid, &gid)) {
DEBUG(10, ("Could not convert SID %s to gid, "
}
debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
+ debug_unix_user_token(DBGC_AUTH, 10, server_info->uid,
+ server_info->gid, server_info->n_groups,
+ server_info->groups);
status = log_nt_token(mem_ctx, server_info->ptok);
#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 {
return sid_compare_auth(sid1, sid2);
}
+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, res;
+
+ 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;
+}
+
/*****************************************************************
See if 2 SIDs are in the same domain
this just compares the leading sub-auths
return secret;
}
+bool secrets_groupfilter_fetch(TALLOC_CTX *mem_ctx, struct dom_sid **psids,
+ size_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(int argc, const char **argv)
+{
+ struct dom_sid sid;
+ struct dom_sid *sids;
+ size_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(int argc, const char **argv)
+{
+ struct dom_sid sid;
+ struct dom_sid *sids;
+ size_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(int argc, const char **argv)
+{
+ struct dom_sid *sids;
+ size_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(int argc, const char **argv)
+{
+ int ret = -1;
+ struct functable2 func[] = {
+ {
+ "addsid",
+ net_groupfilter_addsid,
+ "Add a SID to the groupfilter"
+ },
+ {
+ "delsid",
+ net_groupfilter_delsid,
+ "Delete a SID from the groupfilter"
+ },
+ {
+ "list",
+ net_groupfilter_list,
+ "List groupfilter SIDs"
+ },
+ { NULL, NULL, NULL }
+ };
+
+ return net_run_function2(argc, argv, "net groupfilter", func);
+}
+
/****************************************************************************
****************************************************************************/
{"USERSIDLIST", net_usersidlist},
{"CONF", net_conf},
{"REGISTRY", net_registry},
+ {"GROUPFILTER", net_groupfilter},
#ifdef WITH_FAKE_KASERVER
{"AFS", net_afs},
#endif