*/
#include "rpc_server/lsa/lsa.h"
+#include "util/util_ldb.h"
+#include "libcli/ldap/ldap_ndr.h"
+#include "system/kerberos.h"
+#include "auth/kerberos/kerberos.h"
/*
this type allows us to distinguish handle types
*/
static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct lsa_Delete *r)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+
+/*
+ lsa_DeleteObject
+*/
+static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct lsa_DeleteObject *r)
{
struct dcesrv_handle *h;
int ret;
DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
+
if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
struct lsa_secret_state *secret_state = h->data;
- ret = samdb_delete(secret_state->sam_ldb, mem_ctx, secret_state->secret_dn);
+
+ /* Ensure user is permitted to delete this... */
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed delete things */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ ret = ldb_delete(secret_state->sam_ldb,
+ secret_state->secret_dn);
talloc_free(h);
if (ret != 0) {
return NT_STATUS_INVALID_HANDLE;
}
+ ZERO_STRUCTP(r->out.handle);
+
return NT_STATUS_OK;
} else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
struct lsa_trusted_domain_state *trusted_domain_state = h->data;
- ret = samdb_delete(trusted_domain_state->policy->sam_ldb, mem_ctx,
- trusted_domain_state->trusted_domain_dn);
+ ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
+ trusted_domain_state->trusted_domain_dn);
talloc_free(h);
if (ret != 0) {
return NT_STATUS_INVALID_HANDLE;
}
+ ZERO_STRUCTP(r->out.handle);
+
return NT_STATUS_OK;
} else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
struct lsa_RightSet *rights;
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+
+ ZERO_STRUCTP(r->out.handle);
}
return NT_STATUS_INVALID_HANDLE;
ZERO_STRUCT(domain_guid);
- switch (lp_server_role(global_loadparm)) {
+ switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
case ROLE_STANDALONE:
role = DS_ROLE_STANDALONE_SERVER;
break;
break;
}
- switch (lp_server_role(global_loadparm)) {
+ switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
case ROLE_STANDALONE:
- domain = talloc_strdup(mem_ctx, lp_workgroup(global_loadparm));
+ domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
W_ERROR_HAVE_NO_MEMORY(domain);
break;
case ROLE_DOMAIN_MEMBER:
- domain = talloc_strdup(mem_ctx, lp_workgroup(global_loadparm));
+ domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
W_ERROR_HAVE_NO_MEMORY(domain);
/* TODO: what is with dns_domain and forest and guid? */
break;
/*
lsa_CreateAccount
+
+ This call does not seem to have any long-term effects, hence no database operations
*/
static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct lsa_CreateAccount *r)
/* create the trusted_domain */
ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
- if (ret != LDB_SUCCESS) {
- DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
- ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
+ switch (ret) {
+ case LDB_SUCCESS:
+ break;
+ case LDB_ERR_ENTRY_ALREADY_EXISTS:
+ ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
+ DEBUG(0,("Failed to create trusted domain record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(trusted_domain_state->policy->sam_ldb)));
+ return NT_STATUS_DOMAIN_EXISTS;
+ case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+ ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
+ DEBUG(0,("Failed to create trusted domain record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(trusted_domain_state->policy->sam_ldb)));
+ return NT_STATUS_ACCESS_DENIED;
+ default:
+ ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
+ DEBUG(0,("Failed to create user record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(trusted_domain_state->policy->sam_ldb)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
{
NTSTATUS status;
struct lsa_OpenTrustedDomain open;
- struct lsa_Delete delete;
+ struct lsa_DeleteObject delete;
struct dcesrv_handle *h;
open.in.handle = r->in.handle;
talloc_steal(mem_ctx, h);
delete.in.handle = open.out.trustdom_handle;
- status = dcesrv_lsa_Delete(dce_call, mem_ctx, &delete);
+ delete.out.handle = open.out.trustdom_handle;
+ status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &delete);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
"trustDirection",
"trustType",
"trustAttributes",
+ "msDs-supportedEncryptionTypes",
NULL
};
ZERO_STRUCT(r->out.info->full_info);
return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
- case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
- ZERO_STRUCT(r->out.info->info_all);
- return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
+ case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
+ ZERO_STRUCT(r->out.info->info2_internal);
+ r->out.info->info2_internal.posix_offset.posix_offset
+ = samdb_result_uint(msg, "posixOffset", 0);
+ return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info2_internal.info_ex);
+
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+ r->out.info->enc_types.enc_types
+ = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
+ break;
- case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
- case LSA_TRUSTED_DOMAIN_INFO_11:
+ case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
+ case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
/* oops, we don't want to return the info after all */
talloc_free(r->out.info);
r->out.info = NULL;
if (count == -1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- if (count == 0 || r->in.max_size == 0) {
- return NT_STATUS_OK;
- }
/* convert to lsa_TrustInformation format */
entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
if (count == -1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- if (count == 0 || r->in.max_size == 0) {
- return NT_STATUS_OK;
- }
/* convert to lsa_DomainInformation format */
entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
return NT_STATUS_OK;
}
- ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
+ ret = ldb_modify(state->sam_ldb, msg);
if (ret != 0) {
if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
ZERO_STRUCTP(r->out.sec_handle);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed create secrets */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
policy_state = policy_handle->data;
if (!r->in.name.string) {
return NT_STATUS_INVALID_PARAMETER;
}
- secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
+ secret_state->sam_ldb = talloc_reference(secret_state,
+ secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
/* search for the secret record */
ret = gendb_search(secret_state->sam_ldb, mem_ctx,
ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
/* create the secret */
- ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
+ ret = ldb_add(secret_state->sam_ldb, msg);
if (ret != 0) {
DEBUG(0,("Failed to create secret record %s: %s\n",
ldb_dn_get_linearized(msg->dn),
return NT_STATUS_INVALID_PARAMETER;
}
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed to access secrets */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
secret_state = talloc(mem_ctx, struct lsa_secret_state);
if (!secret_state) {
return NT_STATUS_NO_MEMORY;
}
} else {
- secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
-
secret_state->global = false;
+ secret_state->sam_ldb = talloc_reference(secret_state,
+ secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
+
name = r->in.name.string;
if (strlen(name) < 1) {
return NT_STATUS_INVALID_PARAMETER;
}
if (!r->in.new_val) {
- /* This behaviour varies depending of if this is a local, or a global secret... */
- if (secret_state->global) {
- /* set old value mtime */
- if (samdb_msg_add_uint64(secret_state->sam_ldb,
- mem_ctx, msg, "lastSetTime", nt_now) != 0) {
- return NT_STATUS_NO_MEMORY;
- }
- } else {
- if (samdb_msg_add_delete(secret_state->sam_ldb,
- mem_ctx, msg, "currentValue")) {
- return NT_STATUS_NO_MEMORY;
- }
- if (samdb_msg_add_delete(secret_state->sam_ldb,
- mem_ctx, msg, "lastSetTime")) {
- return NT_STATUS_NO_MEMORY;
- }
+ /* set old value mtime */
+ if (samdb_msg_add_uint64(secret_state->sam_ldb,
+ mem_ctx, msg, "lastSetTime", nt_now) != 0) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (samdb_msg_add_delete(secret_state->sam_ldb,
+ mem_ctx, msg, "currentValue")) {
+ return NT_STATUS_NO_MEMORY;
}
}
}
DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
+ /* Ensure user is permitted to read this... */
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed to read secrets */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
secret_state = h->data;
/* pull all the user attributes */
}
-/*
- lsa_DeleteObject
-*/
-static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct lsa_DeleteObject *r)
-{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
-}
-
-
/*
lsa_EnumAccountsWithUserRight
*/
TALLOC_CTX *mem_ctx,
struct lsa_QueryDomainInformationPolicy *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ r->out.info = talloc(mem_ctx, union lsa_DomainInformationPolicy);
+ if (!r->out.info) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ switch (r->in.level) {
+ case LSA_DOMAIN_INFO_POLICY_EFS:
+ talloc_free(r->out.info);
+ r->out.info = NULL;
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ case LSA_DOMAIN_INFO_POLICY_KERBEROS:
+ {
+ struct lsa_DomainInfoKerberos *k = &r->out.info->kerberos_info;
+ struct smb_krb5_context *smb_krb5_context;
+ int ret = smb_krb5_init_context(mem_ctx,
+ dce_call->event_ctx,
+ dce_call->conn->dce_ctx->lp_ctx,
+ &smb_krb5_context);
+ if (ret != 0) {
+ talloc_free(r->out.info);
+ r->out.info = NULL;
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
+ k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
+ k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
+ k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
+ k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
+ talloc_free(smb_krb5_context);
+ return NT_STATUS_OK;
+ }
+ default:
+ talloc_free(r->out.info);
+ r->out.info = NULL;
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
}
/*