s4-drs: Added drs_security_access_check function
authorNadezhda Ivanova <nivanova@samba.org>
Mon, 27 Sep 2010 04:14:45 +0000 (21:14 -0700)
committerAndrew Tridgell <tridge@samba.org>
Tue, 28 Sep 2010 18:36:40 +0000 (11:36 -0700)
It takes a security token, an ldb_context, and the desired CAR and checks
if the principal has this CAR granted

source4/rpc_server/drsuapi/dcesrv_drsuapi.h
source4/rpc_server/drsuapi/drsutil.c

index 818813ed57e4fa10c37b6661f2fa7db40b039497..1de347f9f1b69ceac140d81012ef17dcfcd9c07b 100644 (file)
@@ -69,3 +69,9 @@ WERROR drs_security_level_check(struct dcesrv_call_state *dce_call,
 
 void drsuapi_process_secret_attribute(struct drsuapi_DsReplicaAttribute *attr,
                                      struct drsuapi_DsReplicaMetaData *meta_data);
+
+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);
index f20082f6bb384530205fe89f244df8346d2cd0da..5b5e14aea425a7c815ac49d6ff139af1beab129f 100644 (file)
@@ -42,6 +42,34 @@ char *drs_ObjectIdentifier_to_string(TALLOC_CTX *mem_ctx,
        return ret;
 }
 
+struct ldb_dn *drs_ObjectIdentifier_to_dn(TALLOC_CTX *mem_ctx,
+                                         struct ldb_context *ldb,
+                                         struct drsuapi_DsReplicaObjectIdentifier *nc)
+{
+       char *guid = NULL, *sid = NULL, *ret = NULL;
+       struct ldb_dn *new_dn;
+       if (!GUID_all_zero(&nc->guid)) {
+               guid = GUID_string(mem_ctx, &nc->guid);
+               if (guid) {
+                       ret = talloc_asprintf_append(mem_ctx, "<GUID=%s>;", guid);
+               }
+       }
+       if (nc->sid.sid_rev_num != 0) {
+               sid = dom_sid_string(mem_ctx, &nc->sid);
+               if (sid) {
+                       ret = talloc_asprintf_append(ret, "<SID=%s>;", sid);
+               }
+       }
+       if (nc->dn) {
+               ret = talloc_asprintf_append(ret, "%s", nc->dn);
+       }
+       new_dn = ldb_dn_new(mem_ctx, ldb, ret);
+       talloc_free(guid);
+       talloc_free(sid);
+       talloc_free(ret);
+       return new_dn;
+}
+
 int drsuapi_search_with_extended_dn(struct ldb_context *ldb,
                                    TALLOC_CTX *mem_ctx,
                                    struct ldb_result **_res,
@@ -155,3 +183,33 @@ void drsuapi_process_secret_attribute(struct drsuapi_DsReplicaAttribute *attr,
                return;
        }
 }
+
+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);
+       int ret;
+       if (!dn) {
+               DEBUG(3,("drs_security_access_check: Null dn provided, access is denied\n"));
+               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\n", ext_right));
+                       security_token_debug(2, 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_ACCESS_DENIED;
+               return WERR_DS_DRA_INTERNAL_ERROR;
+       }
+       return WERR_OK;
+}