s4:samldb LDB modules - only objectClass "computer" is allowed to embed all types...
authorMatthias Dieter Wallnöfer <mdw@samba.org>
Mon, 23 May 2011 10:51:06 +0000 (12:51 +0200)
committerMatthias Dieter Wallnöfer <mdw@samba.org>
Wed, 25 May 2011 06:57:35 +0000 (08:57 +0200)
Reviewed-by: abartlet
source4/dsdb/samdb/ldb_modules/samldb.c

index bf91d29709021f764f1a7a976d7208a1d1a1315e..fa0c4f631739cf8eb532438e59f8c40bf7c06480 100644 (file)
@@ -3,7 +3,7 @@
 
    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
    Copyright (C) Simo Sorce  2004-2008
-   Copyright (C) Matthias Dieter Wallnöfer 2009-2010
+   Copyright (C) Matthias Dieter Wallnöfer 2009-2011
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -897,6 +897,16 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac)
                                return LDB_ERR_OTHER;
                        }
 
+                       /* Workstation and (read-only) DC objects do need objectclass "computer" */
+                       if ((samdb_find_attribute(ldb, ac->msg,
+                                                 "objectclass", "computer") == NULL) &&
+                           (user_account_control &
+                            (UF_SERVER_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT))) {
+                               ldb_set_errstring(ldb,
+                                                 "samldb: Requested account type does need objectclass 'computer'!");
+                               return LDB_ERR_OBJECT_CLASS_VIOLATION;
+                       }
+
                        account_type = ds_uf2atype(user_account_control);
                        if (account_type == 0) {
                                ldb_set_errstring(ldb, "samldb: Unrecognized account type!");
@@ -1241,7 +1251,9 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
        struct ldb_message *tmp_msg;
        int ret;
        struct ldb_result *res;
-       const char *attrs[] = { "userAccountControl", NULL };
+       const char *attrs[] = { "userAccountControl", "objectClass", NULL };
+       unsigned int i;
+       bool is_computer = false;
 
        el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl",
                                         ac->req->operation);
@@ -1269,7 +1281,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
                return LDB_ERR_OTHER;
        }
 
-       /* Fetch the old "userAccountControl" */
+       /* Fetch the old "userAccountControl" and "objectClass" */
        ret = dsdb_module_search_dn(ac->module, ac, &res, ac->msg->dn, attrs,
                                    DSDB_FLAG_NEXT_MODULE, ac->req);
        if (ret != LDB_SUCCESS) {
@@ -1279,6 +1291,24 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
        if (old_user_account_control == 0) {
                return ldb_operr(ldb);
        }
+       el = ldb_msg_find_element(res->msgs[0], "objectClass");
+       if (el == NULL) {
+               return ldb_operr(ldb);
+       }
+
+       /* When we do not have objectclass "computer" we cannot switch to a (read-only) DC */
+       for (i = 0; i < el->num_values; i++) {
+               if (ldb_attr_cmp((char *)el->values[i].data, "computer") == 0) {
+                       is_computer = true;
+                       break;
+               }
+       }
+       if (!is_computer &&
+           (user_account_control & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT))) {
+               ldb_set_errstring(ldb,
+                                 "samldb: Requested account type does need objectclass 'computer'!");
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
 
        /*
         * The functions "ds_uf2atype" and "ds_uf2prim_group_rid" are used as