summaryrefslogtreecommitdiff
path: root/source4/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source4/rpc_server')
-rw-r--r--source4/rpc_server/common/common.h4
-rw-r--r--source4/rpc_server/dcerpc_server.c7
-rw-r--r--source4/rpc_server/drsuapi/addentry.c5
-rw-r--r--source4/rpc_server/drsuapi/dcesrv_drsuapi.c15
-rw-r--r--source4/rpc_server/drsuapi/dcesrv_drsuapi.h2
-rw-r--r--source4/rpc_server/drsuapi/drsutil.c6
-rw-r--r--source4/rpc_server/drsuapi/getncchanges.c149
-rw-r--r--source4/rpc_server/drsuapi/updaterefs.c103
-rw-r--r--source4/rpc_server/lsa/dcesrv_lsa.c71
-rw-r--r--source4/rpc_server/lsa/lsa.h1
-rw-r--r--source4/rpc_server/lsa/lsa_init.c7
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c14
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c82
-rw-r--r--source4/rpc_server/samr/samr_password.c39
-rw-r--r--source4/rpc_server/spoolss/dcesrv_spoolss.c6
-rw-r--r--source4/rpc_server/srvsvc/srvsvc_ntvfs.c4
16 files changed, 329 insertions, 186 deletions
diff --git a/source4/rpc_server/common/common.h b/source4/rpc_server/common/common.h
index 17c2a7db02..ba023e1fd8 100644
--- a/source4/rpc_server/common/common.h
+++ b/source4/rpc_server/common/common.h
@@ -26,6 +26,8 @@
struct share_config;
struct dcesrv_context;
struct dcesrv_context;
+struct dcesrv_call_state;
+struct ndr_interface_table;
struct dcerpc_server_info {
const char *domain_name;
@@ -34,8 +36,6 @@ struct dcerpc_server_info {
uint32_t version_build;
};
-struct ndr_interface_table;
-struct dcesrv_call_state;
#include "rpc_server/common/proto.h"
#endif /* _DCERPC_SERVER_COMMON_H_ */
diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c
index df0c2e7345..75c5035459 100644
--- a/source4/rpc_server/dcerpc_server.c
+++ b/source4/rpc_server/dcerpc_server.c
@@ -336,13 +336,10 @@ NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
return NT_STATUS_NO_USER_SESSION_KEY;
}
-NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p,
+NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *c,
DATA_BLOB *session_key)
{
- /* this took quite a few CPU cycles to find ... */
- session_key->data = discard_const_p(uint8_t, "SystemLibraryDTC");
- session_key->length = 16;
- return NT_STATUS_OK;
+ return dcerpc_generic_session_key(NULL, session_key);
}
/*
diff --git a/source4/rpc_server/drsuapi/addentry.c b/source4/rpc_server/drsuapi/addentry.c
index 7bf8f39592..dbaf627130 100644
--- a/source4/rpc_server/drsuapi/addentry.c
+++ b/source4/rpc_server/drsuapi/addentry.c
@@ -82,7 +82,7 @@ static WERROR drsuapi_add_SPNs(struct drsuapi_bind_state *b_state,
ntds_guid_str = GUID_string(res, &ntds_guid);
- dom_string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
+ dom_string = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
/*
* construct a modify request to add the new SPNs to
@@ -180,6 +180,7 @@ WERROR dcesrv_drsuapi_DsAddEntry(struct dcesrv_call_state *dce_call, TALLOC_CTX
if (!W_ERROR_IS_OK(status)) {
r->out.ctr->ctr3.error->info1.status = status;
ldb_transaction_cancel(b_state->sam_ctx);
+ DEBUG(0,(__location__ ": DsAddEntry failed - %s\n", win_errstr(status)));
return status;
}
@@ -198,11 +199,13 @@ WERROR dcesrv_drsuapi_DsAddEntry(struct dcesrv_call_state *dce_call, TALLOC_CTX
if (!W_ERROR_IS_OK(status)) {
r->out.ctr->ctr3.error->info1.status = status;
ldb_transaction_cancel(b_state->sam_ctx);
+ DEBUG(0,(__location__ ": DsAddEntry add SPNs failed - %s\n", win_errstr(status)));
return status;
}
ret = ldb_transaction_commit(b_state->sam_ctx);
if (ret != LDB_SUCCESS) {
+ DEBUG(0,(__location__ ": DsAddEntry commit failed\n"));
return WERR_DS_DRA_INTERNAL_ERROR;
}
diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
index 9903f08746..9f903716dc 100644
--- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
+++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
@@ -27,6 +27,7 @@
#include "dsdb/samdb/samdb.h"
#include "rpc_server/drsuapi/dcesrv_drsuapi.h"
#include "libcli/security/security.h"
+#include "auth/auth.h"
/*
drsuapi_DsBind
@@ -47,6 +48,8 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
uint32_t pid;
uint32_t repl_epoch;
int ret;
+ struct auth_session_info *auth_info;
+ WERROR werr;
r->out.bind_info = NULL;
ZERO_STRUCTP(r->out.bind_handle);
@@ -54,10 +57,20 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
b_state = talloc_zero(mem_ctx, struct drsuapi_bind_state);
W_ERROR_HAVE_NO_MEMORY(b_state);
+ /* if this is a DC connecting, give them system level access */
+ werr = drs_security_level_check(dce_call, NULL);
+ if (W_ERROR_IS_OK(werr)) {
+ DEBUG(2,(__location__ ": doing DsBind with system_session\n"));
+ auth_info = system_session(b_state, dce_call->conn->dce_ctx->lp_ctx);
+ } else {
+ auth_info = dce_call->conn->auth_state.session_info;
+ }
+
/*
* connect to the samdb
*/
- b_state->sam_ctx = samdb_connect(b_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
+ b_state->sam_ctx = samdb_connect(b_state, dce_call->event_ctx,
+ dce_call->conn->dce_ctx->lp_ctx, auth_info);
if (!b_state->sam_ctx) {
return WERR_FOOBAR;
}
diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.h b/source4/rpc_server/drsuapi/dcesrv_drsuapi.h
index 82899c8432..e42d9569e7 100644
--- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.h
+++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.h
@@ -39,6 +39,8 @@ struct drsuapi_bind_state {
/* prototypes of internal functions */
+WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx,
+ struct drsuapi_DsReplicaUpdateRefsRequest1 *req);
WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct drsuapi_DsReplicaUpdateRefs *r);
WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
diff --git a/source4/rpc_server/drsuapi/drsutil.c b/source4/rpc_server/drsuapi/drsutil.c
index 84bb5ffc01..752861cc26 100644
--- a/source4/rpc_server/drsuapi/drsutil.c
+++ b/source4/rpc_server/drsuapi/drsutil.c
@@ -98,7 +98,7 @@ int drsuapi_search_with_extended_dn(struct ldb_context *ldb,
sort_control[0] = talloc(req, struct ldb_server_sort_control);
sort_control[0]->attributeName = sort_attrib;
sort_control[0]->orderingRule = NULL;
- sort_control[0]->reverse = 1;
+ sort_control[0]->reverse = 0;
sort_control[1] = NULL;
ret = ldb_request_add_control(req, LDB_CONTROL_SERVER_SORT_OID, true, sort_control);
@@ -127,7 +127,9 @@ WERROR drs_security_level_check(struct dcesrv_call_state *dce_call, const char*
if (security_session_user_level(dce_call->conn->auth_state.session_info) <
SECURITY_DOMAIN_CONTROLLER) {
- DEBUG(0,("DsReplicaGetInfo refused for security token\n"));
+ if (call) {
+ DEBUG(0,("%s refused for security token\n", call));
+ }
return WERR_DS_DRA_ACCESS_DENIED;
}
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
index 2bfdf5280a..90ddab083c 100644
--- a/source4/rpc_server/drsuapi/getncchanges.c
+++ b/source4/rpc_server/drsuapi/getncchanges.c
@@ -66,7 +66,7 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
if (instance_type & INSTANCE_TYPE_IS_NC_HEAD) {
struct ldb_result *res;
int ret;
- char *dnstr = ldb_dn_get_linearized(msg->dn);
+ const char *dnstr = ldb_dn_get_linearized(msg->dn);
msg->dn = ldb_dn_new(msg, sam_ctx, dnstr);
/* we need to re-search the msg, to avoid the
* broken dual message problems with our
@@ -141,8 +141,10 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
instanceType then don't include it */
if (md.ctr.ctr1.array[i].local_usn < highest_usn &&
md.ctr.ctr1.array[i].attid != DRSUAPI_ATTRIBUTE_instanceType) continue;
+
/* don't include the rDN */
if (md.ctr.ctr1.array[i].attid == rdn_sa->attributeID_id) continue;
+
obj->meta_data_ctr->meta_data[n].originating_change_time = md.ctr.ctr1.array[i].originating_change_time;
obj->meta_data_ctr->meta_data[n].version = md.ctr.ctr1.array[i].version;
obj->meta_data_ctr->meta_data[n].originating_invocation_id = md.ctr.ctr1.array[i].originating_invocation_id;
@@ -205,12 +207,10 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
sa->lDAPDisplayName, win_errstr(werr)));
return werr;
}
- /* if DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING is set
+ /* if DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING is set
* check if attribute is secret and send a null value
- * TODO: check if we can make this in the database layer
*/
- if ((replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING)
- == DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING) {
+ if (replica_flags & DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING) {
drsuapi_process_secret_attribute(&obj->object.attribute_ctr.attributes[i],
&obj->meta_data_ctr->meta_data[i]);
}
@@ -322,13 +322,14 @@ static WERROR get_nc_changes_udv(struct ldb_context *sam_ctx,
struct drsuapi_getncchanges_state {
struct ldb_result *site_res;
uint32_t num_sent;
- struct ldb_context *sam_ctx;
struct ldb_dn *ncRoot_dn;
uint32_t min_usn;
};
/*
drsuapi_DsGetNCChanges
+
+ see MS-DRSR 4.1.10.5.2 for basic logic of this function
*/
WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct drsuapi_DsGetNCChanges *r)
@@ -346,6 +347,8 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
struct dcesrv_handle *h;
struct drsuapi_bind_state *b_state;
struct drsuapi_getncchanges_state *getnc_state;
+ struct drsuapi_DsGetNCChangesRequest8 *req8;
+ uint32_t options;
DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
b_state = h->data;
@@ -360,25 +363,43 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
r->out.ctr->ctr6.more_data = false;
r->out.ctr->ctr6.uptodateness_vector = NULL;
- /* Check request revision. */
+ /* a RODC doesn't allow for any replication */
+ if (samdb_rodc(ldb_get_opaque(b_state->sam_ctx, "loadparm"))) {
+ DEBUG(0,(__location__ ": DsGetNCChanges attempt on RODC\n"));
+ return WERR_DS_DRA_SOURCE_DISABLED;
+ }
+
+ /* Check request revision.
+ TODO: Adding mappings to req8 from the other levels
+ */
if (r->in.level != 8) {
+ DEBUG(0,(__location__ ": Request for DsGetNCChanges with unsupported level %u\n",
+ r->in.level));
return WERR_REVISION_MISMATCH;
}
+ req8 = &r->in.req->req8;
+
/* Perform access checks. */
- if (r->in.req->req8.naming_context == NULL) {
+ ncRoot = req8->naming_context;
+ if (ncRoot == NULL) {
+ DEBUG(0,(__location__ ": Request for DsGetNCChanges with no NC\n"));
return WERR_DS_DRA_INVALID_PARAMETER;
}
- ncRoot = r->in.req->req8.naming_context;
- if (ncRoot == NULL) {
- return WERR_DS_DRA_BAD_NC;
+ if (samdb_ntds_options(b_state->sam_ctx, &options) != LDB_SUCCESS) {
+ return WERR_DS_DRA_INTERNAL_ERROR;
+ }
+
+ if ((options & DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL) &&
+ !(req8->replica_flags & DRSUAPI_DRS_SYNC_FORCED)) {
+ return WERR_DS_DRA_SOURCE_DISABLED;
}
- if ((r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET)
- == DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET) {
+
+ if (req8->replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET) {
/* Ignore the _in_ uptpdateness vector*/
- r->in.req->req8.uptodateness_vector = NULL;
+ req8->uptodateness_vector = NULL;
}
werr = drs_security_level_check(dce_call, "DsGetNCChanges");
@@ -393,18 +414,6 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
return WERR_NOMEM;
}
b_state->getncchanges_state = getnc_state;
-
-
- /*
- * connect to the samdb. TODO: We need to check that the caller
- * has the rights to do this. This exposes all attributes,
- * including all passwords.
- */
- getnc_state->sam_ctx = samdb_connect(getnc_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
- system_session(getnc_state, dce_call->conn->dce_ctx->lp_ctx));
- if (!getnc_state->sam_ctx) {
- return WERR_FOOBAR;
- }
}
/* we need the session key for encrypting password attributes */
@@ -414,41 +423,65 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
return WERR_DS_DRA_INTERNAL_ERROR;
}
+ /* we don't yet support extended operations */
+ if (req8->extended_op != DRSUAPI_EXOP_NONE) {
+ DEBUG(0,(__location__ ": Request for DsGetNCChanges extended op 0x%x\n",
+ (unsigned)req8->extended_op));
+ return WERR_DS_DRA_NOT_SUPPORTED;
+ }
+
+ /*
+ TODO: MS-DRSR section 4.1.10.1.1
+ Work out if this is the start of a new cycle */
+
if (getnc_state->site_res == NULL) {
char* search_filter;
enum ldb_scope scope = LDB_SCOPE_SUBTREE;
- getnc_state->min_usn = r->in.req->req8.highwatermark.highest_usn;
+ getnc_state->min_usn = req8->highwatermark.highest_usn;
/* Construct response. */
search_filter = talloc_asprintf(mem_ctx,
"(uSNChanged>=%llu)",
(unsigned long long)(getnc_state->min_usn+1));
-
- if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_CRITICAL_ONLY) {
+
+ if (req8->replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_CRITICAL_ONLY) {
search_filter = talloc_asprintf(mem_ctx,
"(&%s(isCriticalSystemObject=TRUE))",
search_filter);
}
- getnc_state->ncRoot_dn = ldb_dn_new(getnc_state, getnc_state->sam_ctx, ncRoot->dn);
- if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_ASYNC_REP) {
+ getnc_state->ncRoot_dn = ldb_dn_new(getnc_state, b_state->sam_ctx, ncRoot->dn);
+ if (req8->replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_ASYNC_REP) {
scope = LDB_SCOPE_BASE;
}
DEBUG(6,(__location__ ": getncchanges on %s using filter %s\n",
ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter));
- ret = drsuapi_search_with_extended_dn(getnc_state->sam_ctx, getnc_state, &getnc_state->site_res,
+ ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, getnc_state, &getnc_state->site_res,
getnc_state->ncRoot_dn, scope, attrs,
- "distinguishedName",
+ "uSNChanged",
search_filter);
if (ret != LDB_SUCCESS) {
return WERR_DS_DRA_INTERNAL_ERROR;
}
+ } else {
+ /* check that this request is for the same NC as the previous one */
+ struct ldb_dn *dn;
+ dn = ldb_dn_new(getnc_state, b_state->sam_ctx, ncRoot->dn);
+ if (!dn) {
+ return WERR_NOMEM;
+ }
+ if (ldb_dn_compare(dn, getnc_state->ncRoot_dn) != 0) {
+ DEBUG(0,(__location__ ": DsGetNCChanges 2nd replication on different DN %s %s\n",
+ ldb_dn_get_linearized(dn),
+ ldb_dn_get_linearized(getnc_state->ncRoot_dn)));
+ return WERR_DS_DRA_BAD_NC;
+ }
}
/* Prefix mapping */
- schema = dsdb_get_schema(getnc_state->sam_ctx);
+ schema = dsdb_get_schema(b_state->sam_ctx);
if (!schema) {
DEBUG(0,("No schema in sam_ctx\n"));
return WERR_DS_DRA_INTERNAL_ERROR;
@@ -457,7 +490,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
r->out.ctr->ctr6.naming_context = talloc(mem_ctx, struct drsuapi_DsReplicaObjectIdentifier);
*r->out.ctr->ctr6.naming_context = *ncRoot;
- if (dsdb_find_guid_by_dn(getnc_state->sam_ctx, getnc_state->ncRoot_dn,
+ if (dsdb_find_guid_by_dn(b_state->sam_ctx, getnc_state->ncRoot_dn,
&r->out.ctr->ctr6.naming_context->guid) != LDB_SUCCESS) {
DEBUG(0,(__location__ ": Failed to find GUID of ncRoot_dn %s\n",
ldb_dn_get_linearized(getnc_state->ncRoot_dn)));
@@ -465,23 +498,23 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
}
/* find the SID if there is one */
- dsdb_find_sid_by_dn(getnc_state->sam_ctx, getnc_state->ncRoot_dn, &r->out.ctr->ctr6.naming_context->sid);
+ dsdb_find_sid_by_dn(b_state->sam_ctx, getnc_state->ncRoot_dn, &r->out.ctr->ctr6.naming_context->sid);
dsdb_get_oid_mappings_drsuapi(schema, true, mem_ctx, &ctr);
r->out.ctr->ctr6.mapping_ctr = *ctr;
- r->out.ctr->ctr6.source_dsa_guid = *(samdb_ntds_objectGUID(getnc_state->sam_ctx));
- r->out.ctr->ctr6.source_dsa_invocation_id = *(samdb_ntds_invocation_id(getnc_state->sam_ctx));
+ r->out.ctr->ctr6.source_dsa_guid = *(samdb_ntds_objectGUID(b_state->sam_ctx));
+ r->out.ctr->ctr6.source_dsa_invocation_id = *(samdb_ntds_invocation_id(b_state->sam_ctx));
- r->out.ctr->ctr6.old_highwatermark = r->in.req->req8.highwatermark;
- r->out.ctr->ctr6.new_highwatermark = r->in.req->req8.highwatermark;
+ r->out.ctr->ctr6.old_highwatermark = req8->highwatermark;
+ r->out.ctr->ctr6.new_highwatermark = req8->highwatermark;
r->out.ctr->ctr6.first_object = NULL;
currentObject = &r->out.ctr->ctr6.first_object;
for(i=getnc_state->num_sent;
i<getnc_state->site_res->count &&
- (r->out.ctr->ctr6.object_count < r->in.req->req8.max_object_count);
+ (r->out.ctr->ctr6.object_count < req8->max_object_count);
i++) {
int uSN;
struct drsuapi_DsReplicaObjectListItemEx *obj;
@@ -493,9 +526,9 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
}
werr = get_nc_changes_build_object(obj, getnc_state->site_res->msgs[i],
- getnc_state->sam_ctx, getnc_state->ncRoot_dn,
+ b_state->sam_ctx, getnc_state->ncRoot_dn,
schema, &session_key, getnc_state->min_usn,
- r->in.req->req8.replica_flags);
+ req8->replica_flags);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}
@@ -518,6 +551,29 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
r->out.ctr->ctr6.nc_object_count = getnc_state->site_res->count;
+ /* the client can us to call UpdateRefs on its behalf to
+ re-establish monitoring of the NC */
+ if ((req8->replica_flags & DRSUAPI_DRS_ADD_REF) &&
+ !GUID_all_zero(&req8->destination_dsa_guid)) {
+ struct drsuapi_DsReplicaUpdateRefsRequest1 ureq;
+ ureq.naming_context = ncRoot;
+ ureq.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "%s._msdcs.%s",
+ GUID_string(mem_ctx, &req8->destination_dsa_guid),
+ lp_realm(dce_call->conn->dce_ctx->lp_ctx));
+ if (!ureq.dest_dsa_dns_name) {
+ return WERR_NOMEM;
+ }
+ ureq.dest_dsa_guid = req8->destination_dsa_guid;
+ ureq.options = DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE |
+ DRSUAPI_DS_REPLICA_UPDATE_ASYNCHRONOUS_OPERATION |
+ DRSUAPI_DS_REPLICA_UPDATE_GETCHG_CHECK;
+ werr = drsuapi_UpdateRefs(b_state, mem_ctx, &ureq);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,(__location__ ": Failed UpdateRefs in DsGetNCChanges - %s\n",
+ win_errstr(werr)));
+ }
+ }
+
if (i < getnc_state->site_res->count) {
r->out.ctr->ctr6.more_data = true;
} else {
@@ -528,7 +584,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
r->out.ctr->ctr6.new_highwatermark.highest_usn = r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn;
- werr = get_nc_changes_udv(getnc_state->sam_ctx, getnc_state->ncRoot_dn,
+ werr = get_nc_changes_udv(b_state->sam_ctx, getnc_state->ncRoot_dn,
r->out.ctr->ctr6.uptodateness_vector);
if (!W_ERROR_IS_OK(werr)) {
return werr;
@@ -538,8 +594,9 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
b_state->getncchanges_state = NULL;
}
- DEBUG(3,("DsGetNCChanges with uSNChanged >= %llu on %s gave %u objects\n",
- (unsigned long long)(r->in.req->req8.highwatermark.highest_usn+1),
+ DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu flags 0x%08x on %s gave %u objects\n",
+ (unsigned long long)(req8->highwatermark.highest_usn+1),
+ req8->replica_flags,
ncRoot->dn, r->out.ctr->ctr6.object_count));
return WERR_OK;
diff --git a/source4/rpc_server/drsuapi/updaterefs.c b/source4/rpc_server/drsuapi/updaterefs.c
index e12be6f058..60a70c5032 100644
--- a/source4/rpc_server/drsuapi/updaterefs.c
+++ b/source4/rpc_server/drsuapi/updaterefs.c
@@ -35,16 +35,29 @@ struct repsTo {
add a replication destination for a given partition GUID
*/
static WERROR uref_add_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
- struct ldb_dn *dn, struct repsFromTo1 *dest)
+ struct ldb_dn *dn, struct repsFromTo1 *dest,
+ uint32_t options)
{
struct repsTo reps;
WERROR werr;
+ int i;
werr = dsdb_loadreps(sam_ctx, mem_ctx, dn, "repsTo", &reps.r, &reps.count);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}
+ for (i=0; i<reps.count; i++) {
+ if (GUID_compare(&dest->source_dsa_obj_guid,
+ &reps.r[i].ctr.ctr1.source_dsa_obj_guid) == 0) {
+ if (options & DRSUAPI_DS_REPLICA_UPDATE_GETCHG_CHECK) {
+ return WERR_OK;
+ } else {
+ return WERR_DS_DRA_REF_ALREADY_EXISTS;
+ }
+ }
+ }
+
reps.r = talloc_realloc(mem_ctx, reps.r, struct repsFromToBlob, reps.count+1);
if (reps.r == NULL) {
return WERR_DS_DRA_INTERNAL_ERROR;
@@ -66,11 +79,13 @@ static WERROR uref_add_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
delete a replication destination for a given partition GUID
*/
static WERROR uref_del_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
- struct ldb_dn *dn, struct GUID *dest_guid)
+ struct ldb_dn *dn, struct GUID *dest_guid,
+ uint32_t options)
{
struct repsTo reps;
WERROR werr;
int i;
+ bool found = false;
werr = dsdb_loadreps(sam_ctx, mem_ctx, dn, "repsTo", &reps.r, &reps.count);
if (!W_ERROR_IS_OK(werr)) {
@@ -83,6 +98,7 @@ static WERROR uref_del_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
memmove(&reps.r[i], &reps.r[i+1], sizeof(reps.r[i])*(reps.count-(i+1)));
}
reps.count--;
+ found = true;
}
}
@@ -91,60 +107,42 @@ static WERROR uref_del_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
return werr;
}
+ if (!found && !(options & DRSUAPI_DS_REPLICA_UPDATE_GETCHG_CHECK)) {
+ return WERR_DS_DRA_REF_NOT_FOUND;
+ }
+
return WERR_OK;
}
/*
- drsuapi_DsReplicaUpdateRefs
+ drsuapi_DsReplicaUpdateRefs - a non RPC version callable from getncchanges
*/
-WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct drsuapi_DsReplicaUpdateRefs *r)
+WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx,
+ struct drsuapi_DsReplicaUpdateRefsRequest1 *req)
{
- struct drsuapi_DsReplicaUpdateRefsRequest1 *req;
- struct ldb_context *sam_ctx;
WERROR werr;
struct ldb_dn *dn;
- werr = drs_security_level_check(dce_call, "DsReplicaUpdateRefs");
- if (!W_ERROR_IS_OK(werr)) {
- return werr;
- }
-
- if (r->in.level != 1) {
- DEBUG(0,("DrReplicUpdateRefs - unsupported level %u\n", r->in.level));
- return WERR_DS_DRA_INVALID_PARAMETER;
- }
-
- req = &r->in.req.req1;
DEBUG(4,("DsReplicaUpdateRefs for host '%s' with GUID %s options 0x%08x nc=%s\n",
req->dest_dsa_dns_name, GUID_string(mem_ctx, &req->dest_dsa_guid),
req->options,
drs_ObjectIdentifier_to_string(mem_ctx, req->naming_context)));
- /* TODO: We need to authenticate this operation pretty carefully */
- sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
- system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
- if (!sam_ctx) {
- return WERR_DS_DRA_INTERNAL_ERROR;
- }
-
- dn = ldb_dn_new(mem_ctx, sam_ctx, req->naming_context->dn);
+ dn = ldb_dn_new(mem_ctx, b_state->sam_ctx, req->naming_context->dn);
if (dn == NULL) {
- talloc_free(sam_ctx);
return WERR_DS_INVALID_DN_SYNTAX;
}
- if (ldb_transaction_start(sam_ctx) != LDB_SUCCESS) {
+ if (ldb_transaction_start(b_state->sam_ctx) != LDB_SUCCESS) {
DEBUG(0,(__location__ ": Failed to start transaction on samdb\n"));
- talloc_free(sam_ctx);
return WERR_DS_DRA_INTERNAL_ERROR;
}
if (req->options & DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE) {
- werr = uref_del_dest(sam_ctx, mem_ctx, dn, &req->dest_dsa_guid);
+ werr = uref_del_dest(b_state->sam_ctx, mem_ctx, dn, &req->dest_dsa_guid, req->options);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("Failed to delete repsTo for %s\n",
- GUID_string(dce_call, &req->dest_dsa_guid)));
+ GUID_string(mem_ctx, &req->dest_dsa_guid)));
goto failed;
}
}
@@ -161,24 +159,53 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA
dest.source_dsa_obj_guid = req->dest_dsa_guid;
dest.replica_flags = req->options;
- werr = uref_add_dest(sam_ctx, mem_ctx, dn, &dest);
+ werr = uref_add_dest(b_state->sam_ctx, mem_ctx, dn, &dest, req->options);
if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("Failed to delete repsTo for %s\n",
- GUID_string(dce_call, &dest.source_dsa_obj_guid)));
+ DEBUG(0,("Failed to add repsTo for %s\n",
+ GUID_string(mem_ctx, &dest.source_dsa_obj_guid)));
goto failed;
}
}
- if (ldb_transaction_commit(sam_ctx) != LDB_SUCCESS) {
+ if (ldb_transaction_commit(b_state->sam_ctx) != LDB_SUCCESS) {
DEBUG(0,(__location__ ": Failed to commit transaction on samdb\n"));
return WERR_DS_DRA_INTERNAL_ERROR;
}
- talloc_free(sam_ctx);
return WERR_OK;
failed:
- ldb_transaction_cancel(sam_ctx);
- talloc_free(sam_ctx);
+ ldb_transaction_cancel(b_state->sam_ctx);
return werr;
}
+
+/*
+ drsuapi_DsReplicaUpdateRefs
+*/
+WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct drsuapi_DsReplicaUpdateRefs *r)
+{
+ struct dcesrv_handle *h;
+ struct drsuapi_bind_state *b_state;
+ struct drsuapi_DsReplicaUpdateRefsRequest1 *req;
+ WERROR werr;
+
+ DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
+ b_state = h->data;
+
+ werr = drs_security_level_check(dce_call, "DsReplicaUpdateRefs");
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ if (r->in.level != 1) {
+ DEBUG(0,("DrReplicUpdateRefs - unsupported level %u\n", r->in.level));
+ return WERR_DS_DRA_INVALID_PARAMETER;
+ }
+
+ req = &r->in.req.req1;
+
+ return drsuapi_UpdateRefs(b_state, mem_ctx, req);
+}
+
+
diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c
index 3d6352af46..0e6a55ec2f 100644
--- a/source4/rpc_server/lsa/dcesrv_lsa.c
+++ b/source4/rpc_server/lsa/dcesrv_lsa.c
@@ -80,7 +80,7 @@ static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
- NT_STATUS_NOT_OK_RETURN(status);
+ NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx);
@@ -694,7 +694,7 @@ static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALL
/* NOTE: This call must only return accounts that have at least
one privilege set
*/
- ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
+ ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
"(&(objectSid=*)(privilege=*))");
if (ret < 0) {
return NT_STATUS_NO_SUCH_USER;
@@ -1830,7 +1830,7 @@ static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
return NT_STATUS_NO_MEMORY;
}
- ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
+ ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
"objectSid=%s", sidstr);
if (ret != 1) {
return NT_STATUS_OK;
@@ -1886,7 +1886,7 @@ static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
return NT_STATUS_NO_MEMORY;
}
- ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
+ ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
"(&(objectSid=%s)(privilege=*))", sidstr);
if (ret == 0) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -1897,7 +1897,7 @@ static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
if (ret == -1) {
DEBUG(3, ("searching for account rights for SID: %s failed: %s",
dom_sid_string(mem_ctx, r->in.sid),
- ldb_errstring(state->sam_ldb)));
+ ldb_errstring(state->pdb)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -1932,15 +1932,17 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_
struct dom_sid *sid,
const struct lsa_RightSet *rights)
{
- const char *sidstr;
+ const char *sidstr, *sidndrstr;
struct ldb_message *msg;
struct ldb_message_element *el;
int i, ret;
struct lsa_EnumAccountRights r2;
+ char *dnstr;
- sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
- if (sidstr == NULL) {
- return NT_STATUS_NO_MEMORY;
+ if (security_session_user_level(dce_call->conn->auth_state.session_info) <
+ SECURITY_ADMINISTRATOR) {
+ DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
+ return NT_STATUS_ACCESS_DENIED;
}
msg = ldb_msg_new(mem_ctx);
@@ -1948,24 +1950,17 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_
return NT_STATUS_NO_MEMORY;
}
- msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
- NULL, "objectSid=%s", sidstr);
- if (msg->dn == NULL) {
- NTSTATUS status;
- if (ldb_flag == LDB_FLAG_MOD_DELETE) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
- status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
- sid, &msg->dn);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- return NT_STATUS_NO_SUCH_USER;
- }
+ sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg);
- if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
- return NT_STATUS_NO_MEMORY;
- }
+ sidstr = dom_sid_string(msg, sid);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg);
+
+ dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg);
+
+ msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
+ NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg);
if (ldb_flag == LDB_FLAG_MOD_ADD) {
NTSTATUS status;
@@ -1982,6 +1977,7 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_
for (i=0;i<rights->count;i++) {
if (sec_privilege_id(rights->names[i].string) == -1) {
+ talloc_free(msg);
return NT_STATUS_NO_SUCH_PRIVILEGE;
}
@@ -1998,26 +1994,41 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_
ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
if (ret != LDB_SUCCESS) {
+ talloc_free(msg);
return NT_STATUS_NO_MEMORY;
}
}
el = ldb_msg_find_element(msg, "privilege");
if (!el) {
+ talloc_free(msg);
return NT_STATUS_OK;
}
- ret = ldb_modify(state->sam_ldb, msg);
+ el->flags = ldb_flag;
+
+ ret = ldb_modify(state->pdb, msg);
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
+ talloc_free(msg);
+ return NT_STATUS_NO_MEMORY;
+ }
+ samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA");
+ ret = ldb_add(state->pdb, msg);
+ }
if (ret != 0) {
if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ talloc_free(msg);
+ return NT_STATUS_OK;
}
DEBUG(3, ("Could not %s attributes from %s: %s",
ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
- ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
+ ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
+ talloc_free(msg);
return NT_STATUS_UNEXPECTED_IO_ERROR;
}
+ talloc_free(msg);
return NT_STATUS_OK;
}
@@ -2880,7 +2891,7 @@ static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *d
return NT_STATUS_NO_SUCH_PRIVILEGE;
}
- ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
+ ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
"privilege=%s", privname);
if (ret == -1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
diff --git a/source4/rpc_server/lsa/lsa.h b/source4/rpc_server/lsa/lsa.h
index ffdf96d091..53fe102630 100644
--- a/source4/rpc_server/lsa/lsa.h
+++ b/source4/rpc_server/lsa/lsa.h
@@ -40,6 +40,7 @@
struct lsa_policy_state {
struct dcesrv_handle *handle;
struct ldb_context *sam_ldb;
+ struct ldb_context *pdb;
uint32_t access_mask;
struct ldb_dn *domain_dn;
struct ldb_dn *forest_dn;
diff --git a/source4/rpc_server/lsa/lsa_init.c b/source4/rpc_server/lsa/lsa_init.c
index ae565a3ff1..dd7d46b41d 100644
--- a/source4/rpc_server/lsa/lsa_init.c
+++ b/source4/rpc_server/lsa/lsa_init.c
@@ -21,6 +21,7 @@
*/
#include "rpc_server/lsa/lsa.h"
+#include "dsdb/samdb/samdb_proto.h"
NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct lsa_policy_state **_state)
@@ -48,6 +49,12 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
+ /* and the privilege database */
+ state->pdb = privilege_connect(state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
+ if (state->pdb == NULL) {
+ return NT_STATUS_INVALID_SYSTEM_SERVICE;
+ }
+
/* work out the domain_dn - useful for so many calls its worth
fetching here */
state->domain_dn = ldb_get_default_basedn(state->sam_ldb);
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 1a45711c57..f763069a3b 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -643,7 +643,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal
sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
NT_STATUS_HAVE_NO_MEMORY(sam6);
sam6->base = *sam;
- sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
+ sam6->forest.string = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
sam->account_name.string, sam6->forest.string);
NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
@@ -1096,7 +1096,7 @@ static NTSTATUS fill_one_domain_info(TALLOC_CTX *mem_ctx,
if (is_local) {
info->domainname.string = lp_sam_name(lp_ctx);
- info->dns_domainname.string = lp_realm(lp_ctx);
+ info->dns_domainname.string = lp_dnsdomain(lp_ctx);
info->domain_guid = samdb_result_guid(res, "objectGUID");
info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
} else {
@@ -1432,15 +1432,15 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA
*/
info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
- lp_realm(dce_call->conn->dce_ctx->lp_ctx));
+ lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx));
W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
W_ERROR_HAVE_NO_MEMORY(info->dc_address);
info->dc_address_type = DS_ADDRESS_TYPE_INET;
info->domain_guid = samdb_result_guid(res[0], "objectGUID");
- info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
- info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
- info->dc_flags = DS_DNS_FOREST |
+ info->domain_name = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
+ info->forest_name = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
+ info->dc_flags = DS_DNS_FOREST_ROOT |
DS_DNS_DOMAIN |
DS_DNS_CONTROLLER |
DS_SERVER_WRITABLE |
@@ -1614,7 +1614,7 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
/* TODO: add filtering by trust_flags, and correct trust_type
and attributes */
trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
- trusts->array[0].dns_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
+ trusts->array[0].dns_name = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
trusts->array[0].trust_flags =
NETR_TRUST_FLAG_TREEROOT |
NETR_TRUST_FLAG_IN_FOREST |
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 6dda06a6b8..6c5f5b845f 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -949,7 +949,7 @@ static NTSTATUS dcesrv_samr_SetDomainInfo(struct dcesrv_call_state *dce_call, TA
/* modify the samdb record */
ret = ldb_modify(sam_ctx, msg);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
DEBUG(1,("Failed to modify record %s: %s\n",
ldb_dn_get_linearized(d_state->domain_dn),
ldb_errstring(sam_ctx)));
@@ -1234,7 +1234,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
*/
ret = ldb_transaction_start(d_state->sam_ctx);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
DEBUG(0,("Failed to start a transaction for user creation: %s\n",
ldb_errstring(d_state->sam_ctx)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -1389,7 +1389,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
/* modify the samdb record */
ret = samdb_replace(a_state->sam_ctx, mem_ctx, msg);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
DEBUG(0,("Failed to modify account record %s to set userAccountControl: %s\n",
ldb_dn_get_linearized(msg->dn),
ldb_errstring(d_state->sam_ctx)));
@@ -1400,7 +1400,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
}
ret = ldb_transaction_commit(d_state->sam_ctx);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
ldb_dn_get_linearized(msg->dn),
ldb_errstring(d_state->sam_ctx)));
@@ -2193,7 +2193,7 @@ static NTSTATUS dcesrv_samr_SetGroupInfo(struct dcesrv_call_state *dce_call, TAL
/* modify the samdb record */
ret = ldb_modify(g_state->sam_ctx, msg);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
/* we really need samdb.c to return NTSTATUS */
return NT_STATUS_UNSUCCESSFUL;
}
@@ -2224,8 +2224,9 @@ static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, T
d_state = a_state->domain_state;
membersid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
- if (membersid == NULL)
+ if (membersid == NULL) {
return NT_STATUS_NO_MEMORY;
+ }
/* In native mode, AD can also nest domain groups. Not sure yet
* whether this is also available via RPC. */
@@ -2234,7 +2235,7 @@ static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, T
"(&(objectSid=%s)(objectclass=user))",
ldap_encode_ndr_dom_sid(mem_ctx, membersid));
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -2258,9 +2259,11 @@ static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, T
mod->dn = talloc_reference(mem_ctx, a_state->account_dn);
- if (samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member",
- memberdn) != 0)
+ ret = samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member",
+ memberdn);
+ if (ret != LDB_SUCCESS) {
return NT_STATUS_UNSUCCESSFUL;
+ }
ret = ldb_modify(a_state->sam_ctx, mod);
switch (ret) {
@@ -2273,7 +2276,6 @@ static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, T
default:
return NT_STATUS_UNSUCCESSFUL;
}
-
}
@@ -2294,7 +2296,7 @@ static NTSTATUS dcesrv_samr_DeleteDomainGroup(struct dcesrv_call_state *dce_call
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;
}
@@ -2336,7 +2338,7 @@ static NTSTATUS dcesrv_samr_DeleteGroupMember(struct dcesrv_call_state *dce_call
"(&(objectSid=%s)(objectclass=user))",
ldap_encode_ndr_dom_sid(mem_ctx, membersid));
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -2360,8 +2362,9 @@ static NTSTATUS dcesrv_samr_DeleteGroupMember(struct dcesrv_call_state *dce_call
mod->dn = talloc_reference(mem_ctx, a_state->account_dn);
- if (samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member",
- memberdn) != 0) {
+ ret = samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member",
+ memberdn);
+ if (ret != LDB_SUCCESS) {
return NT_STATUS_NO_MEMORY;
}
@@ -2643,7 +2646,7 @@ static NTSTATUS dcesrv_samr_SetAliasInfo(struct dcesrv_call_state *dce_call, TAL
/* 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;
}
@@ -2732,12 +2735,15 @@ static NTSTATUS dcesrv_samr_AddAliasMember(struct dcesrv_call_state *dce_call, T
mod->dn = talloc_reference(mem_ctx, a_state->account_dn);
- if (samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member",
- ldb_dn_alloc_linearized(mem_ctx, memberdn)) != 0)
+ ret = samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member",
+ ldb_dn_alloc_linearized(mem_ctx, memberdn));
+ if (ret != LDB_SUCCESS) {
return NT_STATUS_UNSUCCESSFUL;
+ }
- if (ldb_modify(a_state->sam_ctx, mod) != 0)
+ if (ldb_modify(a_state->sam_ctx, mod) != LDB_SUCCESS) {
return NT_STATUS_UNSUCCESSFUL;
+ }
return NT_STATUS_OK;
}
@@ -2754,6 +2760,7 @@ static NTSTATUS dcesrv_samr_DeleteAliasMember(struct dcesrv_call_state *dce_call
struct samr_domain_state *d_state;
struct ldb_message *mod;
const char *memberdn;
+ int ret;
DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
@@ -2774,11 +2781,12 @@ static NTSTATUS dcesrv_samr_DeleteAliasMember(struct dcesrv_call_state *dce_call
mod->dn = talloc_reference(mem_ctx, a_state->account_dn);
- if (samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member",
- memberdn) != 0)
+ ret = samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member",
+ memberdn);
+ if (ret != LDB_SUCCESS)
return NT_STATUS_UNSUCCESSFUL;
- if (ldb_modify(a_state->sam_ctx, mod) != 0)
+ if (ldb_modify(a_state->sam_ctx, mod) != LDB_SUCCESS)
return NT_STATUS_UNSUCCESSFUL;
return NT_STATUS_OK;
@@ -2947,7 +2955,7 @@ static NTSTATUS dcesrv_samr_DeleteUser(struct dcesrv_call_state *dce_call, TALLO
a_state = h->data;
ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
DEBUG(1, ("Failed to delete user: %s: %s\n",
ldb_dn_get_linearized(a_state->account_dn),
ldb_errstring(a_state->sam_ctx)));
@@ -3603,14 +3611,16 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
}
/* modify the samdb record */
- ret = ldb_modify(a_state->sam_ctx, msg);
- if (ret != 0) {
- 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;
@@ -4175,10 +4185,14 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
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;
}
@@ -4188,8 +4202,8 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
"pwdProperties", 1);
talloc_free(msgs);
-
talloc_free(sam_ctx);
+
return NT_STATUS_OK;
}
@@ -4342,7 +4356,11 @@ static NTSTATUS dcesrv_samr_SetDsrmPassword(struct dcesrv_call_state *dce_call,
static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct samr_ValidatePassword *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ /* 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"));
+ (*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep);
+ return NT_STATUS_OK;
}
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index 450af82895..1e6eb47e86 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -177,8 +177,9 @@ NTSTATUS dcesrv_samr_ChangePasswordUser(struct dcesrv_call_state *dce_call,
/*
samr_OemChangePasswordUser2
*/
-NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct samr_OemChangePasswordUser2 *r)
+NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
+ TALLOC_CTX *mem_ctx,
+ struct samr_OemChangePasswordUser2 *r)
{
NTSTATUS status;
DATA_BLOB new_password, new_unicode_password;
@@ -335,8 +336,8 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
samr_ChangePasswordUser3
*/
NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
- TALLOC_CTX *mem_ctx,
- struct samr_ChangePasswordUser3 *r)
+ TALLOC_CTX *mem_ctx,
+ struct samr_ChangePasswordUser3 *r)
{
NTSTATUS status;
DATA_BLOB new_password;
@@ -348,8 +349,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
struct samr_Password *nt_pwd, *lm_pwd;
DATA_BLOB nt_pwd_blob;
struct samr_DomInfo1 *dominfo = NULL;
- struct samr_ChangeReject *reject = NULL;
- enum samr_RejectReason reason = SAMR_REJECT_OTHER;
+ struct userPwdChangeFailureInformation *reject = NULL;
+ enum samPwdChangeReason reason = SAM_PWD_CHANGE_NO_ERROR;
uint8_t new_nt_hash[16], new_lm_hash[16];
struct samr_Password nt_verifier, lm_verifier;
@@ -465,6 +466,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
true, /* this is a user password change */
&reason,
&dominfo);
+
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
@@ -494,18 +496,16 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
failed:
ldb_transaction_cancel(sam_ctx);
- talloc_free(sam_ctx);
- reject = talloc(mem_ctx, struct samr_ChangeReject);
- *r->out.dominfo = dominfo;
- *r->out.reject = reject;
+ reject = talloc(mem_ctx, struct userPwdChangeFailureInformation);
+ if (reject != NULL) {
+ ZERO_STRUCTP(reject);
+ reject->extendedFailureReason = reason;
- if (reject == NULL) {
- return status;
+ *r->out.reject = reject;
}
- ZERO_STRUCTP(reject);
- reject->reason = reason;
+ *r->out.dominfo = dominfo;
return status;
}
@@ -516,12 +516,13 @@ failed:
easy - just a subset of samr_ChangePasswordUser3
*/
-NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct samr_ChangePasswordUser2 *r)
+NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call,
+ TALLOC_CTX *mem_ctx,
+ struct samr_ChangePasswordUser2 *r)
{
struct samr_ChangePasswordUser3 r2;
struct samr_DomInfo1 *dominfo = NULL;
- struct samr_ChangeReject *reject = NULL;
+ struct userPwdChangeFailureInformation *reject = NULL;
r2.in.server = r->in.server;
r2.in.account = r->in.account;
@@ -584,7 +585,8 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
*/
NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call,
struct ldb_context *sam_ctx,
- struct ldb_dn *account_dn, struct ldb_dn *domain_dn,
+ struct ldb_dn *account_dn,
+ struct ldb_dn *domain_dn,
TALLOC_CTX *mem_ctx,
struct ldb_message *msg,
struct samr_CryptPasswordEx *pwbuf)
@@ -627,4 +629,3 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call,
NULL, NULL);
}
-
diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c
index d380b10d8e..0e071dc74c 100644
--- a/source4/rpc_server/spoolss/dcesrv_spoolss.c
+++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c
@@ -150,6 +150,7 @@ static WERROR dcesrv_spoolss_check_server_name(struct dcesrv_call_state *dce_cal
bool ret;
struct socket_address *myaddr;
const char **aliases;
+ const char *dnsdomain;
int i;
/* NULL is ok */
@@ -186,12 +187,13 @@ static WERROR dcesrv_spoolss_check_server_name(struct dcesrv_call_state *dce_cal
/* DNS NAME is ok
* TODO: we need to check if aliases are also ok
*/
- if (lp_realm(dce_call->conn->dce_ctx->lp_ctx)) {
+ dnsdomain = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
+ if (dnsdomain != NULL) {
char *str;
str = talloc_asprintf(mem_ctx, "%s.%s",
lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
- lp_realm(dce_call->conn->dce_ctx->lp_ctx));
+ dnsdomain);
W_ERROR_HAVE_NO_MEMORY(str);
ret = strequal(str, server_name);
diff --git a/source4/rpc_server/srvsvc/srvsvc_ntvfs.c b/source4/rpc_server/srvsvc/srvsvc_ntvfs.c
index f1cb35bdd8..15bd749ad1 100644
--- a/source4/rpc_server/srvsvc/srvsvc_ntvfs.c
+++ b/source4/rpc_server/srvsvc/srvsvc_ntvfs.c
@@ -128,7 +128,9 @@ NTSTATUS srvsvc_create_ntvfs_context(struct dcesrv_call_state *dce_call,
NT_STATUS_HAVE_NO_MEMORY(ntvfs_req);
/* Invoke NTVFS connection hook */
- status = ntvfs_connect(ntvfs_req, scfg->name);
+ /* FIXME: Here is the right parameter missing!
+ * status = ntvfs_connect(ntvfs_req, <TODO>); */
+ status = NT_STATUS_UNSUCCESSFUL; /* return this for now */
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("srvsvc_create_ntvfs_context: NTVFS ntvfs_connect() failed!\n"));
return status;