s4:drsuapi RPC server - fix "enum security_user_level" warning on Tru64
[nivanova/samba-autobuild/.git] / source4 / rpc_server / drsuapi / drsutil.c
index 752861cc26272c4877a326f0f242183a0676f945..4e35aa1bd6a3d3a27f09d75f090a5fe802973510 100644 (file)
 #include "includes.h"
 #include "rpc_server/dcerpc_server.h"
 #include "dsdb/samdb/samdb.h"
-#include "libcli/security/dom_sid.h"
-#include "rpc_server/drsuapi/dcesrv_drsuapi.h"
 #include "libcli/security/security.h"
+#include "libcli/security/session.h"
 #include "param/param.h"
-
-/*
-  format a drsuapi_DsReplicaObjectIdentifier naming context as a string
- */
-char *drs_ObjectIdentifier_to_string(TALLOC_CTX *mem_ctx,
-                                    struct drsuapi_DsReplicaObjectIdentifier *nc)
-{
-       char *guid, *sid, *ret;
-       guid = GUID_string(mem_ctx, &nc->guid);
-       sid  = dom_sid_string(mem_ctx, &nc->sid);
-       ret = talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
-                             guid, sid, nc->dn);
-       talloc_free(guid);
-       talloc_free(sid);
-       return ret;
-}
+#include "auth/session.h"
 
 int drsuapi_search_with_extended_dn(struct ldb_context *ldb,
                                    TALLOC_CTX *mem_ctx,
@@ -49,7 +33,6 @@ int drsuapi_search_with_extended_dn(struct ldb_context *ldb,
                                    struct ldb_dn *basedn,
                                    enum ldb_scope scope,
                                    const char * const *attrs,
-                                   const char *sort_attrib,
                                    const char *filter)
 {
        int ret;
@@ -83,31 +66,16 @@ int drsuapi_search_with_extended_dn(struct ldb_context *ldb,
                return ret;
        }
 
-       ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL);
+       ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_RECYCLED_OID, true, NULL);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
 
-       if (sort_attrib) {
-               struct ldb_server_sort_control **sort_control;
-               sort_control = talloc_array(req, struct ldb_server_sort_control *, 2);
-               if (sort_control == NULL) {
-                       talloc_free(tmp_ctx);
-                       return LDB_ERR_OPERATIONS_ERROR;
-               }
-               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 = 0;
-               sort_control[1] = NULL;
-
-               ret = ldb_request_add_control(req, LDB_CONTROL_SERVER_SORT_OID, true, sort_control);
-               if (ret != LDB_SUCCESS) {
-                       return ret;
-               }
+       ret = ldb_request_add_control(req, LDB_CONTROL_REVEAL_INTERNALS, false, NULL);
+       if (ret != LDB_SUCCESS) {
+               return ret;
        }
 
-
        ret = ldb_request(ldb, req);
        if (ret == LDB_SUCCESS) {
                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
@@ -118,17 +86,24 @@ int drsuapi_search_with_extended_dn(struct ldb_context *ldb,
        return ret;
 }
 
-WERROR drs_security_level_check(struct dcesrv_call_state *dce_call, const char* call)
+WERROR drs_security_level_check(struct dcesrv_call_state *dce_call,
+                               const char* call,
+                               enum security_user_level minimum_level,
+                               const struct dom_sid *domain_sid)
 {
-       if (lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, 
+       enum security_user_level level;
+
+       if (lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL,
                         "drs", "disable_sec_check", false)) {
                return WERR_OK;
        }
 
-       if (security_session_user_level(dce_call->conn->auth_state.session_info) <
-               SECURITY_DOMAIN_CONTROLLER) {
+       level = security_session_user_level(dce_call->conn->auth_state.session_info, domain_sid);
+       if (level < minimum_level) {
                if (call) {
-                       DEBUG(0,("%s refused for security token\n", call));
+                       DEBUG(0,("%s refused for security token (level=%u)\n",
+                                call, (unsigned)level));
+                       security_token_debug(0, 2, dce_call->conn->auth_state.session_info->security_token);
                }
                return WERR_DS_DRA_ACCESS_DENIED;
        }
@@ -144,17 +119,17 @@ void drsuapi_process_secret_attribute(struct drsuapi_DsReplicaAttribute *attr,
        }
 
        switch (attr->attid) {
-       case DRSUAPI_ATTRIBUTE_dBCSPwd:
-       case DRSUAPI_ATTRIBUTE_unicodePwd:
-       case DRSUAPI_ATTRIBUTE_ntPwdHistory:
-       case DRSUAPI_ATTRIBUTE_lmPwdHistory:
-       case DRSUAPI_ATTRIBUTE_supplementalCredentials:
-       case DRSUAPI_ATTRIBUTE_priorValue:
-       case DRSUAPI_ATTRIBUTE_currentValue:
-       case DRSUAPI_ATTRIBUTE_trustAuthOutgoing:
-       case DRSUAPI_ATTRIBUTE_trustAuthIncoming:
-       case DRSUAPI_ATTRIBUTE_initialAuthOutgoing:
-       case DRSUAPI_ATTRIBUTE_initialAuthIncoming:
+       case DRSUAPI_ATTID_dBCSPwd:
+       case DRSUAPI_ATTID_unicodePwd:
+       case DRSUAPI_ATTID_ntPwdHistory:
+       case DRSUAPI_ATTID_lmPwdHistory:
+       case DRSUAPI_ATTID_supplementalCredentials:
+       case DRSUAPI_ATTID_priorValue:
+       case DRSUAPI_ATTID_currentValue:
+       case DRSUAPI_ATTID_trustAuthOutgoing:
+       case DRSUAPI_ATTID_trustAuthIncoming:
+       case DRSUAPI_ATTID_initialAuthOutgoing:
+       case DRSUAPI_ATTID_initialAuthIncoming:
                /*set value to null*/
                attr->value_ctr.num_values = 0;
                talloc_free(attr->value_ctr.values);
@@ -164,5 +139,79 @@ void drsuapi_process_secret_attribute(struct drsuapi_DsReplicaAttribute *attr,
        default:
                return;
        }
-       return;
+}
+
+
+/*
+  check security on a DN, with logging of errors
+ */
+static WERROR drs_security_access_check_log(struct ldb_context *sam_ctx,
+                                           TALLOC_CTX *mem_ctx,
+                                           struct security_token *token,
+                                           struct ldb_dn *dn,
+                                           const char *ext_right)
+{
+       int ret;
+       if (!dn) {
+               DEBUG(3,("drs_security_access_check: Null dn provided, access is denied for %s\n",
+                             ext_right));
+               return WERR_DS_DRA_ACCESS_DENIED;
+       }
+       ret = dsdb_check_access_on_dn(sam_ctx,
+                                     mem_ctx,
+                                     dn,
+                                     token,
+                                     SEC_ADS_CONTROL_ACCESS,
+                                     ext_right);
+       if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
+               DEBUG(3,("%s refused for security token on %s\n",
+                        ext_right, ldb_dn_get_linearized(dn)));
+               security_token_debug(2, 0, token);
+               return WERR_DS_DRA_ACCESS_DENIED;
+       } else if (ret != LDB_SUCCESS) {
+               DEBUG(1,("Failed to perform access check on %s\n", ldb_dn_get_linearized(dn)));
+               return WERR_DS_DRA_INTERNAL_ERROR;
+       }
+       return WERR_OK;
+}
+
+
+/*
+  check security on a object identifier
+ */
+WERROR drs_security_access_check(struct ldb_context *sam_ctx,
+                                TALLOC_CTX *mem_ctx,
+                                struct security_token *token,
+                                struct drsuapi_DsReplicaObjectIdentifier *nc,
+                                const char *ext_right)
+{
+       struct ldb_dn *dn = drs_ObjectIdentifier_to_dn(mem_ctx, sam_ctx, nc);
+       WERROR werr;
+       werr = drs_security_access_check_log(sam_ctx, mem_ctx, token, dn, ext_right);
+       talloc_free(dn);
+       return werr;
+}
+
+/*
+  check security on the NC root of a object identifier
+ */
+WERROR drs_security_access_check_nc_root(struct ldb_context *sam_ctx,
+                                        TALLOC_CTX *mem_ctx,
+                                        struct security_token *token,
+                                        struct drsuapi_DsReplicaObjectIdentifier *nc,
+                                        const char *ext_right)
+{
+       struct ldb_dn *dn, *nc_root;
+       WERROR werr;
+       int ret;
+
+       dn = drs_ObjectIdentifier_to_dn(mem_ctx, sam_ctx, nc);
+       W_ERROR_HAVE_NO_MEMORY(dn);
+       ret = dsdb_find_nc_root(sam_ctx, dn, dn, &nc_root);
+       if (ret != LDB_SUCCESS) {
+               return WERR_DS_CANT_FIND_EXPECTED_NC;
+       }
+       werr = drs_security_access_check_log(sam_ctx, mem_ctx, token, nc_root, ext_right);
+       talloc_free(dn);
+       return werr;
 }