ZERO_STRUCTP(r->out.connect_handle);
- c_state = talloc(dce_call->conn, struct samr_connect_state);
+ c_state = talloc(mem_ctx, struct samr_connect_state);
if (!c_state) {
return NT_STATUS_NO_MEMORY;
}
return NT_STATUS_INVALID_PARAMETER;
}
- d_state = talloc(c_state, struct samr_domain_state);
+ d_state = talloc(mem_ctx, struct samr_domain_state);
if (!d_state) {
return NT_STATUS_NO_MEMORY;
}
}
/* No users in BUILTIN, and the LOCAL group types are only in builtin, and the global group type is never in BUILTIN */
- info->num_users = samdb_search_count(state->sam_ctx, mem_ctx, state->domain_dn,
+ info->num_users = samdb_search_count(state->sam_ctx, state->domain_dn,
"(objectClass=user)");
- info->num_groups = samdb_search_count(state->sam_ctx, mem_ctx, state->domain_dn,
- "(&(objectClass=group)(sAMAccountType=%u))",
- ATYPE_GLOBAL_GROUP);
- info->num_aliases = samdb_search_count(state->sam_ctx, mem_ctx, state->domain_dn,
- "(&(objectClass=group)(sAMAccountType=%u))",
- ATYPE_LOCAL_GROUP);
+ info->num_groups = samdb_search_count(state->sam_ctx, state->domain_dn,
+ "(&(objectClass=group)(groupType=%u))",
+ GTYPE_SECURITY_GLOBAL_GROUP);
+ info->num_aliases = samdb_search_count(state->sam_ctx, state->domain_dn,
+ "(&(objectClass=group)(groupType=%u))",
+ GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
return NT_STATUS_OK;
}
break;
}
case 9:
+ {
attrs = NULL;
- break;
+ break;
+ }
case 11:
{
static const char * const attrs2[] = { "oEMInformation",
attrs = attrs2;
break;
}
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
}
/* some levels don't need a search */
case 13:
return dcesrv_samr_info_DomInfo13(d_state, mem_ctx, dom_msgs,
&info->info13);
+ default:
+ return NT_STATUS_INVALID_INFO_CLASS;
}
-
- return NT_STATUS_INVALID_INFO_CLASS;
}
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- a_state = talloc(d_state, struct samr_account_state);
+ a_state = talloc(mem_ctx, struct samr_account_state);
if (!a_state) {
return NT_STATUS_NO_MEMORY;
}
}
/* add core elements to the ldb_message for the user */
- msg->dn = ldb_dn_copy(mem_ctx, d_state->domain_dn);
+ msg->dn = ldb_dn_copy(msg, d_state->domain_dn);
if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,%s", cn_name, container)) {
ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_FOOBAR;
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- a_state = talloc(d_state, struct samr_account_state);
+ a_state = talloc(mem_ctx, struct samr_account_state);
if (!a_state) {
ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_NO_MEMORY;
a_state->account_dn = talloc_steal(a_state, msg->dn);
/* retrieve the sid and account control bits for the user just created */
- ret = gendb_search_dn(d_state->sam_ctx, a_state,
+ ret = gendb_search_dn(d_state->sam_ctx, mem_ctx,
msg->dn, &msgs, attrs);
if (ret != 1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- a_state = talloc(d_state, struct samr_account_state);
+ a_state = talloc(mem_ctx, struct samr_account_state);
if (!a_state) {
return NT_STATUS_NO_MEMORY;
}
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- a_state = talloc(d_state, struct samr_account_state);
+ a_state = talloc(mem_ctx, struct samr_account_state);
if (!a_state) {
return NT_STATUS_NO_MEMORY;
}
return NT_STATUS_UNSUCCESSFUL;
}
+ talloc_free(h);
ZERO_STRUCTP(r->out.group_handle);
return NT_STATUS_OK;
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- a_state = talloc(d_state, struct samr_account_state);
+ a_state = talloc(mem_ctx, struct samr_account_state);
if (!a_state) {
return NT_STATUS_NO_MEMORY;
}
/* modify the samdb record */
ret = ldb_modify(a_state->sam_ctx, msg);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
/* we really need samdb.c to return NTSTATUS */
return NT_STATUS_UNSUCCESSFUL;
}
a_state = h->data;
ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return NT_STATUS_UNSUCCESSFUL;
}
+ talloc_free(h);
ZERO_STRUCTP(r->out.alias_handle);
return NT_STATUS_OK;
return NT_STATUS_UNSUCCESSFUL;
}
+ talloc_free(h);
ZERO_STRUCTP(r->out.user_handle);
return NT_STATUS_OK;
attrs = attrs2;
break;
}
+ case 18:
+ {
+ return NT_STATUS_NOT_SUPPORTED;
+ }
case 20:
{
static const char * const attrs2[] = {"userParameters",
attrs = attrs2;
break;
}
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ {
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
}
/* pull all the user attributes */
}
/* modify the samdb record */
- ret = ldb_modify(a_state->sam_ctx, msg);
- if (ret != LDB_SUCCESS) {
- DEBUG(1,("Failed to modify record %s: %s\n",
- ldb_dn_get_linearized(a_state->account_dn),
- ldb_errstring(a_state->sam_ctx)));
-
- /* we really need samdb.c to return NTSTATUS */
- return NT_STATUS_UNSUCCESSFUL;
+ if (msg->num_elements > 0) {
+ ret = ldb_modify(a_state->sam_ctx, msg);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1,("Failed to modify record %s: %s\n",
+ ldb_dn_get_linearized(a_state->account_dn),
+ ldb_errstring(a_state->sam_ctx)));
+
+ /* we really need samdb.c to return NTSTATUS */
+ return NT_STATUS_UNSUCCESSFUL;
+ }
}
return NT_STATUS_OK;
}
if (samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod,
- "member", memberdn) != 0)
+ "member", memberdn) != LDB_SUCCESS)
return NT_STATUS_NO_MEMORY;
- if (ldb_modify(d_state->sam_ctx, mod) != 0)
+ if (ldb_modify(d_state->sam_ctx, mod) != LDB_SUCCESS)
return NT_STATUS_UNSUCCESSFUL;
talloc_free(mod);
ZERO_STRUCTP(r->out.info);
- sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
+ sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
+ dce_call->conn->dce_ctx->lp_ctx,
+ dce_call->conn->auth_state.session_info);
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
ret = gendb_search_dn(sam_ctx,
mem_ctx, NULL, &msgs, attrs);
if (ret <= 0) {
+ talloc_free(sam_ctx);
+
return NT_STATUS_NO_SUCH_DOMAIN;
}
if (ret > 1) {
talloc_free(msgs);
+ talloc_free(sam_ctx);
+
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
"pwdProperties", 1);
talloc_free(msgs);
- talloc_free(sam_ctx);
+ talloc_unlink(mem_ctx, sam_ctx);
return NT_STATUS_OK;
}
/*
- samr_ValidatePassword
+ samr_ValidatePassword
+
+ For now the call checks the password complexity (if active) and the minimum
+ password length on level 2 and 3. Level 1 is ignored for now.
*/
-static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct samr_ValidatePassword *r)
+static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call,
+ TALLOC_CTX *mem_ctx,
+ struct samr_ValidatePassword *r)
{
- /* just say it's OK for now - we need to hook this into our
- password strength code later */
- DEBUG(0,(__location__ ": Faking samr_ValidatePassword reply\n"));
+ struct samr_GetDomPwInfo r2;
+ struct samr_PwInfo pwInfo;
+ DATA_BLOB password;
+ enum samr_ValidationStatus res;
+ NTSTATUS status;
+
(*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep);
+
+ r2.in.domain_name = NULL;
+ r2.out.info = &pwInfo;
+ status = dcesrv_samr_GetDomPwInfo(dce_call, mem_ctx, &r2);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ switch (r->in.level) {
+ case NetValidateAuthentication:
+ /* we don't support this yet */
+ return NT_STATUS_NOT_SUPPORTED;
+ break;
+ case NetValidatePasswordChange:
+ password = data_blob_const(r->in.req->req2.password.string,
+ r->in.req->req2.password.length);
+ res = samdb_check_password(&password,
+ pwInfo.password_properties,
+ pwInfo.min_password_length);
+ (*r->out.rep)->ctr2.status = res;
+ break;
+ case NetValidatePasswordReset:
+ password = data_blob_const(r->in.req->req3.password.string,
+ r->in.req->req3.password.length);
+ res = samdb_check_password(&password,
+ pwInfo.password_properties,
+ pwInfo.min_password_length);
+ (*r->out.rep)->ctr3.status = res;
+ break;
+ default:
+ return NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+
return NT_STATUS_OK;
}