dnsserver: Return access denied to the caller if the user was not a DNS admin
[samba.git] / source4 / rpc_server / dnsserver / dnsdb.c
index 81af5f1ceefcd62abf90645345b8048ca7ca7133..9ee50d8ff3950168032a3c23062c1cd25a423e74 100644 (file)
@@ -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;
        }