1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

CVE-2020-25722 pydsdb: Add API to return strings of known UF_ flags

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14753
(cherry picked from commit fb6c0b9e2a)
This commit is contained in:
Andrew Bartlett 2021-08-30 13:03:15 +12:00 committed by Jule Anger
parent 131f06517e
commit 39d90c85d4
6 changed files with 144 additions and 0 deletions

View File

@ -164,3 +164,53 @@ uint32_t ds_uf2prim_group_rid(uint32_t uf)
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;
}

View File

@ -31,5 +31,6 @@ uint32_t ds_uf2atype(uint32_t uf);
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__ */

View File

@ -18,6 +18,8 @@
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
@ -53,6 +55,9 @@
#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 |\

View File

@ -0,0 +1,57 @@
# 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)

View File

@ -88,6 +88,7 @@ planpythontestsuite("none", "samba.tests.s3registry")
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"),

View File

@ -33,6 +33,7 @@
#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
@ -1401,6 +1402,30 @@ static PyObject *py_dsdb_load_udv_v2(PyObject *self, PyObject *args)
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"},
@ -1480,6 +1505,11 @@ static PyMethodDef py_dsdb_methods[] = {
"_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}
};