From 835e1564943b3a8a0c8cbdc55db5f0d070ba8f17 Mon Sep 17 00:00:00 2001 From: Garming Sam Date: Fri, 1 Feb 2019 14:11:18 +1300 Subject: [PATCH] dnsserver: Return access denied to the caller if the user was not a DNS admin This is not a proper fix to match Windows, but at the very least, it should be more obvious to users (using samba-tool for instance), that the user needs to be given more access or that they should use the administrator. Windows seems to deny access altogether by returning a fault after they have bound to the pipe and actually sent an operation. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13771 Signed-off-by: Garming Sam Reviewed-by: Andrew Bartlett --- source4/rpc_server/dnsserver/dnsdb.c | 32 ++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/source4/rpc_server/dnsserver/dnsdb.c b/source4/rpc_server/dnsserver/dnsdb.c index 81af5f1ceef..9ee50d8ff39 100644 --- a/source4/rpc_server/dnsserver/dnsdb.c +++ b/source4/rpc_server/dnsserver/dnsdb.c @@ -273,7 +273,8 @@ failed: /* Increment serial number and update timestamp */ static unsigned int dnsserver_update_soa(TALLOC_CTX *mem_ctx, struct ldb_context *samdb, - struct dnsserver_zone *z) + struct dnsserver_zone *z, + WERROR *werr) { const char * const attrs[] = { "dnsRecord", NULL }; struct ldb_result *res; @@ -282,6 +283,8 @@ static unsigned int dnsserver_update_soa(TALLOC_CTX *mem_ctx, enum ndr_err_code ndr_err; int ret, i, serial = -1; + *werr = WERR_INTERNAL_DB_ERROR; + ret = ldb_search(samdb, mem_ctx, &res, z->zone_dn, LDB_SCOPE_ONELEVEL, attrs, "(&(objectClass=dnsNode)(name=@))"); if (ret != LDB_SUCCESS || res->count == 0) { @@ -309,6 +312,7 @@ static unsigned int dnsserver_update_soa(TALLOC_CTX *mem_ctx, ndr_err = ndr_push_struct_blob(&el->values[i], mem_ctx, &rec, (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + *werr = WERR_NOT_ENOUGH_MEMORY; return -1; } break; @@ -319,10 +323,15 @@ static unsigned int dnsserver_update_soa(TALLOC_CTX *mem_ctx, el->flags = LDB_FLAG_MOD_REPLACE; ret = ldb_modify(samdb, res->msgs[0]); if (ret != LDB_SUCCESS) { + if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { + *werr = WERR_ACCESS_DENIED; + } return -1; } } + *werr = WERR_OK; + return serial; } @@ -444,9 +453,9 @@ WERROR dnsserver_db_add_record(TALLOC_CTX *mem_ctx, rec->rank |= DNS_RANK_ROOT_HINT; } - serial = dnsserver_update_soa(mem_ctx, samdb, z); + serial = dnsserver_update_soa(mem_ctx, samdb, z, &werr); if (serial < 0) { - return WERR_INTERNAL_DB_ERROR; + return werr; } rec->dwSerial = serial; @@ -608,9 +617,9 @@ WERROR dnsserver_db_update_record(TALLOC_CTX *mem_ctx, /* If updating SOA record, use specified serial, otherwise increment */ if (arec->wType != DNS_TYPE_SOA) { - serial = dnsserver_update_soa(mem_ctx, samdb, z); + serial = dnsserver_update_soa(mem_ctx, samdb, z, &werr); if (serial < 0) { - return WERR_INTERNAL_DB_ERROR; + return werr; } arec->dwSerial = serial; } @@ -647,9 +656,9 @@ WERROR dnsserver_db_delete_record(TALLOC_CTX *mem_ctx, int serial; WERROR werr; - serial = dnsserver_update_soa(mem_ctx, samdb, z); + serial = dnsserver_update_soa(mem_ctx, samdb, z, &werr); if (serial < 0) { - return WERR_INTERNAL_DB_ERROR; + return werr; } werr = dns_to_dnsp_convert(mem_ctx, del_record, &rec, false); @@ -998,6 +1007,11 @@ static WERROR dnsserver_db_do_create_zone(TALLOC_CTX *tmp_ctx, if (ret != LDB_SUCCESS) { DEBUG(0, ("dnsserver: Failed to create zone (%s): %s\n", z->name, ldb_errstring(samdb))); + + if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { + return WERR_ACCESS_DENIED; + } + return WERR_INTERNAL_DB_ERROR; } @@ -1131,6 +1145,10 @@ WERROR dnsserver_db_delete_zone(struct ldb_context *samdb, ret = dsdb_delete(samdb, zone->zone_dn, DSDB_TREE_DELETE); if (ret != LDB_SUCCESS) { ldb_transaction_cancel(samdb); + + if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { + return WERR_ACCESS_DENIED; + } return WERR_INTERNAL_DB_ERROR; } -- 2.34.1