Copyright (C) Volker Lendecke 2004
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006
Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
-
+
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/>.
*/
return samdb_result_string(res[0], attr_name, NULL);
}
-
/*
search the sam for a single string attribute in exactly 1 record
uint32_t acct_flags = samdb_uf2acb(userAccountControl);
NTTIME must_change_time;
NTTIME now;
-
+
must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx,
domain_dn, msg);
-
+
/* Test account expire time */
unix_to_nt_time(&now, time(NULL));
/* check for expired password */
if (el) {
return LDB_SUCCESS;
}
-
+
return samdb_msg_add_string(ldb, msg, msg, name, set_value);
}
if (ret != LDB_SUCCESS) {
goto failed;
}
-
+
if (res->count != 1) {
goto failed;
}
int ret;
struct ldb_result *root_res;
struct ldb_dn *settings_dn;
-
+
/* see if we have a cached copy */
settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, "cache.settings_dn");
if (settings_dn) {
if (tmp_ctx == NULL) {
goto failed;
}
-
ret = ldb_search(ldb, tmp_ctx, &root_res, ldb_dn_new(tmp_ctx, ldb, ""), LDB_SCOPE_BASE, root_attrs, NULL);
if (ret) {
int ret;
struct ldb_result *res;
struct GUID *invocation_id;
-
+
/* see if we have a cached copy */
invocation_id = (struct GUID *)ldb_get_opaque(ldb, "cache.invocation_id");
if (invocation_id) {
int ret;
struct ldb_result *res;
struct GUID *ntds_guid;
-
+
/* see if we have a cached copy */
ntds_guid = (struct GUID *)ldb_get_opaque(ldb, "cache.ntds_guid");
if (ntds_guid) {
TALLOC_CTX *tmp_ctx;
struct GUID *ntds_guid_new;
struct GUID *ntds_guid_old;
-
+
/* see if we have a cached copy */
ntds_guid_old = (struct GUID *)ldb_get_opaque(ldb, "cache.ntds_guid");
local_ctx = talloc_new(mem_ctx);
if (local_ctx == NULL) return LDB_ERR_OPERATIONS_ERROR;
-
+
while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) {
ret = ldb_search(ldb, local_ctx, &res, sdn, LDB_SCOPE_BASE, attrs,
"(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))");
if (restrictions && new_password) {
char *new_pass;
-
+
/* check the various password restrictions */
if (restrictions && minPwdLength > utf16_len_n(new_password->data, new_password->length) / 2) {
if (reject_reason) {
/* Create the NT hash */
mdfour(local_ntNewHash.hash, new_password->data, new_password->length);
-
+
ntNewHash = &local_ntNewHash;
/* Only check complexity if we can convert it at all. Assuming unconvertable passwords are 'strong' */
CH_UTF16, CH_UNIX,
new_password->data, new_password->length,
(void **)&new_pass, NULL, false)) {
-
-
+
/* possibly check password complexity */
if (restrictions && (pwdProperties & DOMAIN_PASSWORD_COMPLEX) &&
!samdb_password_complexity_ok(new_pass)) {
}
return NT_STATUS_PASSWORD_RESTRICTION;
}
-
+
/* compute the new lm hashes (for checking history - case insenitivly!) */
if (E_deshash(new_pass, local_lmNewHash.hash)) {
lmNewHash = &local_lmNewHash;
}
-
}
}
}
return NT_STATUS_PASSWORD_RESTRICTION;
}
-
+
/* can this user change password? */
if (userAccountControl & UF_PASSWD_CANT_CHANGE) {
if (reject_reason) {
}
return NT_STATUS_PASSWORD_RESTRICTION;
}
-
+
/* yes, this is a minus. The ages are in negative 100nsec units! */
if (pwdLastSet - minPwdAge > now_nt) {
if (reject_reason) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
}
-
+
/* check the password history */
sambaLMPwdHistory_len = MIN(sambaLMPwdHistory_len, pwdHistoryLength);
sambaNTPwdHistory_len = MIN(sambaNTPwdHistory_len, pwdHistoryLength);
-
+
for (i=0; lmNewHash && i<sambaLMPwdHistory_len;i++) {
if (memcmp(lmNewHash->hash, sambaLMPwdHistory[i].hash, 16) == 0) {
if (reject_reason) {
} else {
CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "dBCSPwd"));
}
-
+
if (ntNewHash) {
CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "unicodePwd", ntNewHash));
} else {
ldb_transaction_cancel(ctx);
return nt_status;
}
-
+
/* modify the samdb record */
ret = samdb_replace(ctx, mem_ctx, msg);
if (ret != 0) {
struct ldb_dn *basedn;
const char *sidstr;
int ret;
-
+
sidstr = dom_sid_string(mem_ctx, sid);
NT_STATUS_HAVE_NO_MEMORY(sidstr);
-
+
/* We might have to create a ForeignSecurityPrincipal, even if this user
* is in our own domain */
-
+
msg = ldb_msg_new(mem_ctx);
if (msg == NULL) {
return NT_STATUS_NO_MEMORY;
}
-
+
/* TODO: Hmmm. This feels wrong. How do I find the base dn to
* put the ForeignSecurityPrincipals? d_state->domain_dn does
* not work, this is wrong for the Builtin domain, there's no
* cn=For...,cn=Builtin,dc={BASEDN}. -- vl
*/
-
+
basedn = samdb_search_dn(sam_ctx, mem_ctx, NULL,
"(&(objectClass=container)(cn=ForeignSecurityPrincipals))");
-
+
if (basedn == NULL) {
DEBUG(0, ("Failed to find DN for "
"ForeignSecurityPrincipal container\n"));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
-
+
/* add core elements to the ldb_message for the alias */
msg->dn = ldb_dn_copy(mem_ctx, basedn);
if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s", sidstr))
return NT_STATUS_NO_MEMORY;
-
+
samdb_msg_add_string(sam_ctx, mem_ctx, msg,
"objectClass",
"foreignSecurityPrincipal");
-
+
/* create the alias */
ret = ldb_add(sam_ctx, msg);
if (ret != 0) {
const char *binary_encoded;
const char **split_realm;
struct ldb_dn *dn;
-
+
if (!tmp_ctx) {
return NULL;
}
-
+
split_realm = (const char **)str_list_make(tmp_ctx, dns_domain, ".");
if (!split_realm) {
talloc_free(tmp_ctx);
if (ret_domain != 0) {
return NULL;
}
-
+
if (res_domain_ref->count == 0) {
ret_domain = ldb_search(ldb, mem_ctx,
&res_domain_ref,
if (ret_domain != 0) {
return NULL;
}
-
+
if (res_domain_ref->count == 1) {
return res_domain_ref->msgs[0]->dn;
}
return NULL;
}
-
+
if (res_domain_ref->count > 1) {
DEBUG(0,("Found %d records matching domain [%s]\n",
ret_domain, domain_name));
return NULL;
}
-
+
return samdb_result_dn(ldb, mem_ctx, res_domain_ref->msgs[0], "nCName", NULL);
}
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
-
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
struct ldb_val new_val;
TALLOC_CTX *mem_ctx = talloc_new(NULL);
PyObject *ret;
-
+
new_val = *val;
ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
-
+
talloc_free(mem_ctx);
-
+
return ret;
}
{
struct ldb_result *res;
int i;
-
+
if (obj == Py_None)
return NULL;
return NULL;
ldb_ctx = PyLdb_AsLdbContext(py_ldb);
-
+
ret = ldb_dn_new(ldb_ctx, ldb_ctx, str);
/* ldb_dn_new() doesn't accept NULL as memory context, so
we do it this way... */
static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
{
PyObject *cb;
-
+
if (!PyArg_ParseTuple(args, "O", &cb))
return NULL;
Py_INCREF(cb);
/* FIXME: Where do we DECREF cb ? */
PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self));
-
+
Py_RETURN_NONE;
}
if (options == NULL)
return -1;
}
-
+
if (url != NULL) {
ret = ldb_connect(ldb, url, flags, options);
if (ret != LDB_SUCCESS) {
if (options == NULL)
return NULL;
}
-
+
ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options);
talloc_free(options);
} else {
msg = PyLdbMessage_AsMessage(py_msg);
}
-
+
ret = ldb_add(PyLdb_AsLdbContext(self), msg);
PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
return NULL;
-
+
mem_ctx = talloc_new(NULL);
-
+
old_val.data = (uint8_t *)PyString_AsString(val);
old_val.length = PyString_Size(val);
-
+
a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name);
if (a == NULL) {
Py_RETURN_NONE;
}
-
+
if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
talloc_free(mem_ctx);
Py_RETURN_NONE;
}
ret = ldb_request(ldb_ctx, req);
-
+
if (ret == LDB_SUCCESS) {
ret = ldb_wait(req->handle, LDB_WAIT_ALL);
}
if (!PyArg_ParseTuple(args, "O", &py_message))
return NULL;
-
+
req = talloc_zero(NULL, struct ldb_request);
req->operation = LDB_MODIFY;
req->op.mod.message = PyLdbMessage_AsMessage(py_message);
-
+
mod = PyLdbModule_AsModule(self);
ret = mod->ops->modify(mod, req);
if (!PyArg_ParseTuple(args, "O", &py_dn))
return NULL;
-
+
req = talloc_zero(NULL, struct ldb_request);
req->operation = LDB_DELETE;
req->op.del.dn = PyLdbDn_AsDn(py_dn);
-
+
ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req);
PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
return NULL;
-
+
req = talloc_zero(NULL, struct ldb_request);
req->operation = LDB_RENAME;
req->op.rename.olddn = PyLdbDn_AsDn(py_dn1);
req->op.rename.newdn = PyLdbDn_AsDn(py_dn2);
-
+
ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req);
PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
PyErr_NoMemory();
return NULL;
}
-
+
ret->mem_ctx = talloc_new(NULL);
ret->tree = talloc_reference(ret->mem_ctx, tree);
return (PyObject *)ret;