return prim_group_rid;
}
+
+#define FLAG(x) { .name = #x, .uf = x }
+struct {
+ const char *name;
+ uint32_t uf;
+} user_account_control_name_map[] = {
+ FLAG(UF_SCRIPT),
+ FLAG(UF_ACCOUNTDISABLE),
+ FLAG(UF_00000004),
+ FLAG(UF_HOMEDIR_REQUIRED),
+ FLAG(UF_LOCKOUT),
+ FLAG(UF_PASSWD_NOTREQD),
+ FLAG(UF_PASSWD_CANT_CHANGE),
+ FLAG(UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED),
+
+ FLAG(UF_TEMP_DUPLICATE_ACCOUNT),
+ FLAG(UF_NORMAL_ACCOUNT),
+ FLAG(UF_00000400),
+ FLAG(UF_INTERDOMAIN_TRUST_ACCOUNT),
+
+ FLAG(UF_WORKSTATION_TRUST_ACCOUNT),
+ FLAG(UF_SERVER_TRUST_ACCOUNT),
+ FLAG(UF_00004000),
+ FLAG(UF_00008000),
+
+ FLAG(UF_DONT_EXPIRE_PASSWD),
+ FLAG(UF_MNS_LOGON_ACCOUNT),
+ FLAG(UF_SMARTCARD_REQUIRED),
+ FLAG(UF_TRUSTED_FOR_DELEGATION),
+
+ FLAG(UF_NOT_DELEGATED),
+ FLAG(UF_USE_DES_KEY_ONLY),
+ FLAG(UF_DONT_REQUIRE_PREAUTH),
+ FLAG(UF_PASSWORD_EXPIRED),
+ FLAG(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION),
+ FLAG(UF_NO_AUTH_DATA_REQUIRED),
+ FLAG(UF_PARTIAL_SECRETS_ACCOUNT),
+ FLAG(UF_USE_AES_KEYS)
+};
+
+const char *dsdb_user_account_control_flag_bit_to_string(uint32_t uf)
+{
+ int i;
+ for (i=0; i < ARRAY_SIZE(user_account_control_name_map); i++) {
+ if (uf == user_account_control_name_map[i].uf) {
+ return user_account_control_name_map[i].name;
+ }
+ }
+ return NULL;
+}
uint32_t ds_gtype2atype(uint32_t gtype);
enum lsa_SidType ds_atype_map(uint32_t atype);
uint32_t ds_uf2prim_group_rid(uint32_t uf);
+const char *dsdb_user_account_control_flag_bit_to_string(uint32_t uf);
#endif /* __LIBDS_COMMON_FLAG_MAPPING_H__ */
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/* Please keep this list in sync with the flag_mapping.c and pydsdb.c */
+
/* User flags for "userAccountControl" */
#define UF_SCRIPT 0x00000001 /* NT or Lan Manager Login script must be executed */
#define UF_ACCOUNTDISABLE 0x00000002
#define UF_PARTIAL_SECRETS_ACCOUNT 0x04000000
#define UF_USE_AES_KEYS 0x08000000
+/* Please keep this list in sync with the flag_mapping.c and pydsdb.c */
+
+
#define UF_TRUST_ACCOUNT_MASK (\
UF_INTERDOMAIN_TRUST_ACCOUNT |\
UF_WORKSTATION_TRUST_ACCOUNT |\
--- /dev/null
+# Unix SMB/CIFS implementation. Tests for dsdb
+# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2021
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""Tests for samba.dsdb."""
+
+from samba.tests import TestCase, DynamicTestCase
+from samba.dsdb import user_account_control_flag_bit_to_string
+import samba
+
+
+@DynamicTestCase
+class DsdbFlagTests(TestCase):
+
+ @classmethod
+ def setUpDynamicTestCases(cls):
+
+ for x in dir(samba.dsdb):
+ if x.startswith("UF_"):
+ cls.generate_dynamic_test("test",
+ x,
+ x,
+ getattr(samba.dsdb, x))
+
+
+ def _test_with_args(self, uf_string, uf_bit):
+ self.assertEqual(user_account_control_flag_bit_to_string(uf_bit),
+ uf_string)
+
+
+ def test_not_a_flag(self):
+ self.assertRaises(KeyError,
+ user_account_control_flag_bit_to_string,
+ 0xabcdef)
+
+ def test_too_long(self):
+ self.assertRaises(OverflowError,
+ user_account_control_flag_bit_to_string,
+ 0xabcdefffff)
+
+ def test_way_too_long(self):
+ self.assertRaises(OverflowError,
+ user_account_control_flag_bit_to_string,
+ 0xabcdeffffffffffff)
planpythontestsuite("none", "samba.tests.s3windb")
planpythontestsuite("none", "samba.tests.s3idmapdb")
planpythontestsuite("none", "samba.tests.samba3sam")
+planpythontestsuite("none", "samba.tests.dsdb_api")
planpythontestsuite(
"none", "wafsamba.tests.test_suite",
extra_path=[os.path.join(samba4srcdir, "..", "buildtools"),
#include "lib/util/dlinklist.h"
#include "dsdb/kcc/garbage_collect_tombstones.h"
#include "dsdb/kcc/scavenge_dns_records.h"
+#include "libds/common/flag_mapping.h"
#undef strcasecmp
return pylist;
}
+static PyObject *py_dsdb_user_account_control_flag_bit_to_string(PyObject *self, PyObject *args)
+{
+ const char *str;
+ long long uf;
+ if (!PyArg_ParseTuple(args, "L", &uf)) {
+ return NULL;
+ }
+
+ if (uf > UINT32_MAX) {
+ return PyErr_Format(PyExc_OverflowError, "No UF_ flags are over UINT32_MAX");
+ }
+ if (uf < 0) {
+ return PyErr_Format(PyExc_KeyError, "No UF_ flags are less then zero");
+ }
+
+ str = dsdb_user_account_control_flag_bit_to_string(uf);
+ if (str == NULL) {
+ return PyErr_Format(PyExc_KeyError,
+ "No such UF_ flag 0x%08x",
+ (unsigned int)uf);
+ }
+ return PyUnicode_FromString(str);
+}
+
static PyMethodDef py_dsdb_methods[] = {
{ "_samdb_server_site_name", (PyCFunction)py_samdb_server_site_name,
METH_VARARGS, "Get the server site name as a string"},
"_dsdb_allocate_rid(samdb)"
" -> RID" },
{ "_dsdb_load_udv_v2", (PyCFunction)py_dsdb_load_udv_v2, METH_VARARGS, NULL },
+ { "user_account_control_flag_bit_to_string",
+ (PyCFunction)py_dsdb_user_account_control_flag_bit_to_string,
+ METH_VARARGS,
+ "user_account_control_flag_bit_to_string(bit)"
+ " -> string name" },
{0}
};