Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/source4/dsdb/common
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/dsdb/common/dsdb_access.c

    r740 r988  
    6565
    6666        sd_element = ldb_msg_find_element(acl_res, "nTSecurityDescriptor");
    67         if (!sd_element) {
    68                 *sd = NULL;
    69                 return LDB_SUCCESS;
     67        if (sd_element == NULL) {
     68                return ldb_error(ldb, LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS,
     69                                 "nTSecurityDescriptor is missing");
    7070        }
    7171        *sd = talloc(mem_ctx, struct security_descriptor);
     
    9494        struct dom_sid *sid = NULL;
    9595        struct object_tree *root = NULL;
    96         struct object_tree *new_node = NULL;
    9796        NTSTATUS status;
    9897        uint32_t access_granted;
     
    103102                return ldb_operr(ldb);
    104103        }
    105         /* Theoretically we pass the check if the object has no sd */
    106         if (!sd) {
    107                 return LDB_SUCCESS;
    108         }
     104
    109105        sid = samdb_result_dom_sid(mem_ctx, acl_res->msgs[0], "objectSid");
    110106        if (guid) {
    111                 if (!insert_in_object_tree(mem_ctx, guid, access_mask, &root,
    112                                            &new_node)) {
     107                if (!insert_in_object_tree(mem_ctx, guid, access_mask, NULL,
     108                                           &root)) {
    113109                        return ldb_operr(ldb);
    114110                }
     
    125121                               true,
    126122                               10);
     123                ldb_asprintf_errstring(ldb,
     124                                       "dsdb_access: Access check failed on %s",
     125                                       ldb_dn_get_linearized(dn));
    127126                return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
    128127        }
     
    150149                NULL
    151150        };
    152         NTSTATUS status = GUID_from_string(ext_right, &guid);
    153         if (!NT_STATUS_IS_OK(status)) {
    154                 return LDB_ERR_OPERATIONS_ERROR;
     151
     152        if (ext_right != NULL) {
     153                NTSTATUS status = GUID_from_string(ext_right, &guid);
     154                if (!NT_STATUS_IS_OK(status)) {
     155                        return LDB_ERR_OPERATIONS_ERROR;
     156                }
    155157        }
    156158
    157         ret = dsdb_search_dn(ldb, mem_ctx, &acl_res, dn, acl_attrs, DSDB_SEARCH_SHOW_DELETED);
     159        /*
     160         * We need AS_SYSTEM in order to get the nTSecurityDescriptor attribute.
     161         * Also the result of this search not controlled by the client
     162         * nor is the result exposed to the client.
     163         */
     164        ret = dsdb_search_dn(ldb, mem_ctx, &acl_res, dn, acl_attrs,
     165                             DSDB_FLAG_AS_SYSTEM | DSDB_SEARCH_SHOW_RECYCLED);
    158166        if (ret != LDB_SUCCESS) {
    159167                DEBUG(10,("access_check: failed to find object %s\n", ldb_dn_get_linearized(dn)));
     
    166174                                                dn,
    167175                                                access_mask,
    168                                                 &guid);
     176                                                ext_right ? &guid : NULL);
    169177}
    170178
  • vendor/current/source4/dsdb/common/dsdb_dn.c

    r740 r988  
    7777        struct dsdb_dn *dsdb_dn;
    7878        struct ldb_dn *dn;
    79         const char *data;
    8079        size_t len;
    8180        TALLOC_CTX *tmp_ctx;
     
    8887
    8988        enum dsdb_dn_format dn_format = dsdb_dn_oid_to_format(dn_oid);
     89
     90        if (dn_blob == NULL || dn_blob->data == NULL || dn_blob->length == 0) {
     91                return NULL;
     92        }
     93
    9094        switch (dn_format) {
    9195        case DSDB_INVALID_DN:
     
    114118        }
    115119
    116         if (dn_blob && dn_blob->data
    117             && (strlen((const char*)dn_blob->data) != dn_blob->length)) {
     120        if (strlen((const char*)dn_blob->data) != dn_blob->length) {
    118121                /* The RDN must not contain a character with value 0x0 */
    119122                return NULL;
    120123        }
    121                
    122         if (!dn_blob->data || dn_blob->length == 0) {
    123                 return NULL;
    124         }
    125                
     124
    126125        tmp_ctx = talloc_new(mem_ctx);
    127126        if (tmp_ctx == NULL) {
    128127                return NULL;
    129128        }
    130                
    131         data = (const char *)dn_blob->data;
    132129
    133130        len = dn_blob->length - 2;
     
    215212        dsdb_dn = dsdb_dn_construct(mem_ctx, dn, bval, dn_oid);
    216213               
     214        talloc_free(tmp_ctx);
    217215        return dsdb_dn;
    218216
  • vendor/current/source4/dsdb/common/dsdb_dn.h

    r740 r988  
    1 enum dsdb_dn_format {
    2         DSDB_NORMAL_DN,
    3         DSDB_BINARY_DN,
    4         DSDB_STRING_DN,
    5         DSDB_INVALID_DN
    6 };
    7 
    81struct dsdb_dn {
    92        struct ldb_dn *dn;
     
    169#define DSDB_SYNTAX_STRING_DN   "1.2.840.113556.1.4.904"
    1710#define DSDB_SYNTAX_OR_NAME     "1.2.840.113556.1.4.1221"
     11#define DSDB_SYNTAX_ACCESS_POINT        "1.3.6.1.4.1.1466.115.121.1.2"
    1812
    1913
  • vendor/current/source4/dsdb/common/tests/dsdb_dn.c

    r740 r988  
    7878                       "compare of binary+dn an dn should have failed");
    7979
     80        /* Test compare (false) with different binary prefix */
     81        dn1 = data_blob_string_const("B:6:abcdef:dc=samba,dc=org");
     82        dn2 = data_blob_string_const("B:4:abcd:dc=samba,dc=org");
     83        torture_assert(torture,
     84                       syntax->comparison_fn(ldb, mem_ctx, &dn1, &dn2) != 0,
     85                       "compare of binary+dn an dn should have failed");
     86
    8087        /* Test DN+String behaviour */
    8188        torture_assert(torture, syntax = ldb_samba_syntax_by_name(ldb, DSDB_SYNTAX_STRING_DN),
     
    108115                       "compare of string+dn an dn should have failed");
    109116
     117        /* Test compare (false) with different string prefix */
     118        dn1 = data_blob_string_const("S:6:abcdef:dc=samba,dc=org");
     119        dn2 = data_blob_string_const("S:6:abcXYZ:dc=samba,dc=org");
     120        torture_assert(torture,
     121                       syntax->comparison_fn(ldb, mem_ctx, &dn1, &dn2) != 0,
     122                       "compare of string+dn an dn should have failed");
     123
    110124        talloc_free(mem_ctx);
    111125        return true;
  • vendor/current/source4/dsdb/common/util.c

    r740 r988  
    361361                return NULL;
    362362        }
    363         ok = sid_blob_parse(*v, sid);
     363        ok = sid_parse(v->data, v->length, sid);
    364364        if (!ok) {
    365365                talloc_free(sid);
     
    506506        maxPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn,
    507507                                       "maxPwdAge", NULL);
    508         if (maxPwdAge == 0) {
     508        if (maxPwdAge == 0 || maxPwdAge == -0x8000000000000000ULL) {
    509509                return 0x7FFFFFFFFFFFFFFFULL;
    510510        } else {
     
    559559}
    560560
    561 NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct ldb_message *msg,
    562                                 struct samr_Password **lm_pwd, struct samr_Password **nt_pwd)
     561NTSTATUS samdb_result_passwords_from_history(TALLOC_CTX *mem_ctx,
     562                                             struct loadparm_context *lp_ctx,
     563                                             struct ldb_message *msg,
     564                                             unsigned int idx,
     565                                             struct samr_Password **lm_pwd,
     566                                             struct samr_Password **nt_pwd)
    563567{
    564568        struct samr_Password *lmPwdHash, *ntPwdHash;
     569
     570        if (nt_pwd) {
     571                unsigned int num_nt;
     572                num_nt = samdb_result_hashes(mem_ctx, msg, "ntPwdHistory", &ntPwdHash);
     573                if (num_nt <= idx) {
     574                        *nt_pwd = NULL;
     575                } else {
     576                        *nt_pwd = &ntPwdHash[idx];
     577                }
     578        }
     579        if (lm_pwd) {
     580                /* Ensure that if we have turned off LM
     581                 * authentication, that we never use the LM hash, even
     582                 * if we store it */
     583                if (lpcfg_lanman_auth(lp_ctx)) {
     584                        unsigned int num_lm;
     585                        num_lm = samdb_result_hashes(mem_ctx, msg, "lmPwdHistory", &lmPwdHash);
     586                        if (num_lm <= idx) {
     587                                *lm_pwd = NULL;
     588                        } else {
     589                                *lm_pwd = &lmPwdHash[idx];
     590                        }
     591                } else {
     592                        *lm_pwd = NULL;
     593                }
     594        }
     595        return NT_STATUS_OK;
     596}
     597
     598NTSTATUS samdb_result_passwords_no_lockout(TALLOC_CTX *mem_ctx,
     599                                           struct loadparm_context *lp_ctx,
     600                                           struct ldb_message *msg,
     601                                           struct samr_Password **lm_pwd,
     602                                           struct samr_Password **nt_pwd)
     603{
     604        struct samr_Password *lmPwdHash, *ntPwdHash;
     605
    565606        if (nt_pwd) {
    566607                unsigned int num_nt;
     
    595636}
    596637
     638NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx,
     639                                struct loadparm_context *lp_ctx,
     640                                struct ldb_message *msg,
     641                                struct samr_Password **lm_pwd,
     642                                struct samr_Password **nt_pwd)
     643{
     644        uint16_t acct_flags;
     645
     646        acct_flags = samdb_result_acct_flags(msg,
     647                                             "msDS-User-Account-Control-Computed");
     648        /* Quit if the account was locked out. */
     649        if (acct_flags & ACB_AUTOLOCK) {
     650                DEBUG(3,("samdb_result_passwords: Account for user %s was locked out.\n",
     651                         ldb_dn_get_linearized(msg->dn)));
     652                return NT_STATUS_ACCOUNT_LOCKED_OUT;
     653        }
     654
     655        return samdb_result_passwords_no_lockout(mem_ctx, lp_ctx, msg,
     656                                                 lm_pwd, nt_pwd);
     657}
     658
    597659/*
    598660  pull a samr_LogonHours structutre from a result set.
     
    626688  pull a set of account_flags from a result set.
    627689
    628   This requires that the attributes:
    629    pwdLastSet
    630    userAccountControl
    631   be included in 'msg'
     690  Naturally, this requires that userAccountControl and
     691  (if not null) the attributes 'attr' be already
     692  included in msg
    632693*/
    633 uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
    634                                  struct ldb_message *msg, struct ldb_dn *domain_dn)
     694uint32_t samdb_result_acct_flags(struct ldb_message *msg, const char *attr)
    635695{
    636696        uint32_t userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
     697        uint32_t attr_flags = 0;
    637698        uint32_t acct_flags = ds_uf2acb(userAccountControl);
    638         NTTIME must_change_time;
    639         NTTIME now;
    640 
    641         must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx,
    642                                                               domain_dn, msg);
    643 
    644         /* Test account expire time */
    645         unix_to_nt_time(&now, time(NULL));
    646         /* check for expired password */
    647         if (must_change_time < now) {
    648                 acct_flags |= ACB_PW_EXPIRED;
    649         }
     699        if (attr) {
     700                attr_flags = ldb_msg_find_attr_as_uint(msg, attr, UF_ACCOUNTDISABLE);
     701                if (attr_flags == UF_ACCOUNTDISABLE) {
     702                        DEBUG(0, ("Attribute %s not found, disabling account %s!\n", attr,
     703                                  ldb_dn_get_linearized(msg->dn)));
     704                }
     705                acct_flags |= ds_uf2acb(attr_flags);
     706        }
     707
    650708        return acct_flags;
    651709}
    652710
    653 struct lsa_BinaryString samdb_result_parameters(TALLOC_CTX *mem_ctx,
    654                                                 struct ldb_message *msg,
    655                                                 const char *attr)
    656 {
    657         struct lsa_BinaryString s;
     711NTSTATUS samdb_result_parameters(TALLOC_CTX *mem_ctx,
     712                                 struct ldb_message *msg,
     713                                 const char *attr,
     714                                 struct lsa_BinaryString *s)
     715{
     716        int i;
    658717        const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
    659718
    660         ZERO_STRUCT(s);
     719        ZERO_STRUCTP(s);
    661720
    662721        if (!val) {
    663                 return s;
    664         }
    665 
    666         s.array = talloc_array(mem_ctx, uint16_t, val->length/2);
    667         if (!s.array) {
    668                 return s;
    669         }
    670         s.length = s.size = val->length;
    671         memcpy(s.array, val->data, val->length);
    672 
    673         return s;
     722                return NT_STATUS_OK;
     723        }
     724
     725        if ((val->length % 2) != 0) {
     726                /*
     727                 * If the on-disk data is not even in length, we know
     728                 * it is corrupt, and can not be safely pushed.  We
     729                 * would either truncate, send either a un-initilaised
     730                 * byte or send a forced zero byte
     731                 */
     732                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     733        }
     734
     735        s->array = talloc_array(mem_ctx, uint16_t, val->length/2);
     736        if (!s->array) {
     737                return NT_STATUS_NO_MEMORY;
     738        }
     739        s->length = s->size = val->length;
     740
     741        /* The on-disk format is the 'network' format, being UTF16LE (sort of) */
     742        for (i = 0; i < s->length / 2; i++) {
     743                s->array[i] = SVAL(val->data, i * 2);
     744        }
     745
     746        return NT_STATUS_OK;
    674747}
    675748
     
    702775int samdb_find_or_add_attribute(struct ldb_context *ldb, struct ldb_message *msg, const char *name, const char *set_value)
    703776{
     777        int ret;
    704778        struct ldb_message_element *el;
    705779
     
    709783        }
    710784
    711         return ldb_msg_add_string(msg, name, set_value);
     785        ret = ldb_msg_add_string(msg, name, set_value);
     786        if (ret != LDB_SUCCESS) {
     787                return ret;
     788        }
     789        msg->elements[msg->num_elements - 1].flags = LDB_FLAG_MOD_ADD;
     790        return LDB_SUCCESS;
    712791}
    713792
     
    716795*/
    717796int samdb_msg_add_dom_sid(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
    718                          const char *attr_name, struct dom_sid *sid)
     797                          const char *attr_name, const struct dom_sid *sid)
    719798{
    720799        struct ldb_val v;
     
    9791058                             const char *attr_name, struct lsa_BinaryString *parameters)
    9801059{
     1060        int i;
    9811061        struct ldb_val val;
     1062        if ((parameters->length % 2) != 0) {
     1063                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
     1064        }
     1065
     1066        val.data = talloc_array(mem_ctx, uint8_t, parameters->length);
     1067        if (val.data == NULL) {
     1068                return LDB_ERR_OPERATIONS_ERROR;
     1069        }
    9821070        val.length = parameters->length;
    983         val.data = (uint8_t *)parameters->array;
    984         return ldb_msg_add_value(msg, attr_name, &val, NULL);
    985 }
    986 
    987 /*
    988   sets a general value element to a message
    989 */
    990 int samdb_msg_set_value(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
    991                         const char *attr_name, const struct ldb_val *val)
    992 {
    993         struct ldb_message_element *el;
    994 
    995         el = ldb_msg_find_element(msg, attr_name);
    996         if (el) {
    997                 el->num_values = 0;
    998         }
    999         return ldb_msg_add_value(msg, attr_name, val, NULL);
    1000 }
    1001 
    1002 /*
    1003   set a string element in a message
    1004 */
    1005 int samdb_msg_set_string(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
    1006                          const char *attr_name, const char *str)
    1007 {
    1008         struct ldb_message_element *el;
    1009 
    1010         el = ldb_msg_find_element(msg, attr_name);
    1011         if (el) {
    1012                 el->num_values = 0;
    1013         }
    1014         return ldb_msg_add_string(msg, attr_name, str);
    1015 }
    1016 
    1017 /*
    1018  * sets a signed integer in a message
    1019  */
    1020 int samdb_msg_set_int(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
    1021                       struct ldb_message *msg, const char *attr_name, int v)
    1022 {
    1023         struct ldb_message_element *el;
    1024 
    1025         el = ldb_msg_find_element(msg, attr_name);
    1026         if (el) {
    1027                 el->num_values = 0;
    1028         }
    1029         return samdb_msg_add_int(sam_ldb, mem_ctx, msg, attr_name, v);
     1071        for (i = 0; i < parameters->length / 2; i++) {
     1072                /*
     1073                 * The on-disk format needs to be in the 'network'
     1074                 * format, parmeters->array is a uint16_t array of
     1075                 * length parameters->length / 2
     1076                 */
     1077                SSVAL(val.data, i * 2, parameters->array[i]);
     1078        }
     1079        return ldb_msg_add_steal_value(msg, attr_name, &val);
    10301080}
    10311081
     
    10581108 * Handle ldb_request in transaction
    10591109 */
    1060 static int dsdb_autotransaction_request(struct ldb_context *sam_ldb,
    1061                                         struct ldb_request *req)
     1110int dsdb_autotransaction_request(struct ldb_context *sam_ldb,
     1111                                 struct ldb_request *req)
    10621112{
    10631113        int ret;
     
    12531303        struct ldb_dn *ntds_settings_dn_old;
    12541304
    1255         /* see if we have a cached copy */
     1305        /* see if we have a forced copy from provision */
    12561306        ntds_settings_dn_old = talloc_get_type(ldb_get_opaque(ldb,
    1257                                                               "cache.ntds_settings_dn"), struct ldb_dn);
     1307                                                              "forced.ntds_settings_dn"), struct ldb_dn);
    12581308
    12591309        tmp_ctx = talloc_new(ldb);
     
    12671317        }
    12681318
    1269         /* cache the domain_sid in the ldb */
    1270         if (ldb_set_opaque(ldb, "cache.ntds_settings_dn", ntds_settings_dn_new) != LDB_SUCCESS) {
     1319        /* set the DN in the ldb to avoid lookups during provision */
     1320        if (ldb_set_opaque(ldb, "forced.ntds_settings_dn", ntds_settings_dn_new) != LDB_SUCCESS) {
    12711321                goto failed;
    12721322        }
     
    12871337  work out the ntds settings dn for the current open ldb
    12881338*/
    1289 struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
     1339struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
    12901340{
    12911341        TALLOC_CTX *tmp_ctx;
     
    12961346
    12971347        /* see if we have a cached copy */
    1298         settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, "cache.ntds_settings_dn");
     1348        settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, "forced.ntds_settings_dn");
    12991349        if (settings_dn) {
    1300                 return settings_dn;
    1301         }
    1302 
    1303         tmp_ctx = talloc_new(ldb);
     1350                return ldb_dn_copy(mem_ctx, settings_dn);
     1351        }
     1352
     1353        tmp_ctx = talloc_new(mem_ctx);
    13041354        if (tmp_ctx == NULL) {
    13051355                goto failed;
     
    13071357
    13081358        ret = ldb_search(ldb, tmp_ctx, &root_res, ldb_dn_new(tmp_ctx, ldb, ""), LDB_SCOPE_BASE, root_attrs, NULL);
    1309         if (ret) {
     1359        if (ret != LDB_SUCCESS) {
    13101360                DEBUG(1,("Searching for dsServiceName in rootDSE failed: %s\n",
    13111361                         ldb_errstring(ldb)));
     
    13191369        settings_dn = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, root_res->msgs[0], "dsServiceName");
    13201370
    1321         /* cache the domain_sid in the ldb */
    1322         if (ldb_set_opaque(ldb, "cache.ntds_settings_dn", settings_dn) != LDB_SUCCESS) {
    1323                 goto failed;
    1324         }
    1325 
    1326         talloc_steal(ldb, settings_dn);
     1371        /* note that we do not cache the DN here, as that would mean
     1372         * we could not handle server renames at runtime. Only
     1373         * provision sets up forced.ntds_settings_dn */
     1374
     1375        talloc_steal(mem_ctx, settings_dn);
    13271376        talloc_free(tmp_ctx);
    13281377
     
    13491398        invocation_id = (struct GUID *)ldb_get_opaque(ldb, "cache.invocation_id");
    13501399        if (invocation_id) {
     1400                SMB_ASSERT(!GUID_all_zero(invocation_id));
    13511401                return invocation_id;
    13521402        }
     
    13571407        }
    13581408
    1359         ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
     1409        ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL);
    13601410        if (ret) {
    13611411                goto failed;
     
    13721422
    13731423        *invocation_id = samdb_result_guid(res->msgs[0], "invocationId");
     1424        if (GUID_all_zero(invocation_id)) {
     1425                if (ldb_msg_find_ldb_val(res->msgs[0], "invocationId")) {
     1426                        DEBUG(0, ("Failed to find our own NTDS Settings invocationId in the ldb!\n")); 
     1427                } else {
     1428                        DEBUG(0, ("Failed to find parse own NTDS Settings invocationId from the ldb!\n"));
     1429                }
     1430                goto failed;
     1431        }
    13741432
    13751433        /* cache the domain_sid in the ldb */
     
    14091467        }
    14101468
     1469        SMB_ASSERT(!GUID_all_zero(invocation_id_in));
    14111470        *invocation_id_new = *invocation_id_in;
    14121471
     
    14501509        }
    14511510
    1452         ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
     1511        ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL);
    14531512        if (ret) {
    14541513                goto failed;
     
    15251584struct ldb_dn *samdb_server_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
    15261585{
    1527         return ldb_dn_get_parent(mem_ctx, samdb_ntds_settings_dn(ldb));
     1586        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     1587        struct ldb_dn *dn;
     1588        if (!tmp_ctx) {
     1589                return NULL;
     1590        }
     1591        dn = ldb_dn_get_parent(mem_ctx, samdb_ntds_settings_dn(ldb, tmp_ctx));
     1592        talloc_free(tmp_ctx);
     1593        return dn;
     1594       
    15281595}
    15291596
     
    16271694        attrs[1] = NULL;
    16281695
    1629         ret = dsdb_search(ldb, mem_ctx, &res, base, LDB_SCOPE_BASE, attrs, DSDB_SEARCH_ONE_ONLY, NULL);
    1630         if (ret != LDB_SUCCESS) {
     1696        ret = dsdb_search(ldb, mem_ctx, &res, base, LDB_SCOPE_BASE, attrs, DSDB_SEARCH_ONE_ONLY|DSDB_SEARCH_SHOW_EXTENDED_DN, NULL);
     1697        if (ret != LDB_SUCCESS) {
     1698                ldb_asprintf_errstring(ldb, "Cannot find DN %s to get attribute %s for reference dn: %s",
     1699                                       ldb_dn_get_linearized(base), attribute, ldb_errstring(ldb));
    16311700                return ret;
    16321701        }
     
    16471716        talloc_free(res);
    16481717        return LDB_SUCCESS;
     1718}
     1719
     1720/*
     1721  find if a DN (must have GUID component!) is our ntdsDsa
     1722 */
     1723int samdb_dn_is_our_ntdsa(struct ldb_context *ldb, struct ldb_dn *dn, bool *is_ntdsa)
     1724{
     1725        NTSTATUS status;
     1726        struct GUID dn_guid;
     1727        const struct GUID *our_ntds_guid;
     1728        status = dsdb_get_extended_dn_guid(dn, &dn_guid, "GUID");
     1729        if (!NT_STATUS_IS_OK(status)) {
     1730                return LDB_ERR_OPERATIONS_ERROR;
     1731        }
     1732
     1733        our_ntds_guid = samdb_ntds_objectGUID(ldb);
     1734        if (!our_ntds_guid) {
     1735                DEBUG(0, ("Failed to find our NTDS Settings GUID for comparison with %s - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb)));
     1736                return LDB_ERR_OPERATIONS_ERROR;
     1737        }
     1738
     1739        *is_ntdsa = GUID_equal(&dn_guid, our_ntds_guid);
     1740        return LDB_SUCCESS;
     1741}
     1742
     1743/*
     1744  find a 'reference' DN that points at another object and indicate if it is our ntdsDsa
     1745 */
     1746int samdb_reference_dn_is_our_ntdsa(struct ldb_context *ldb, struct ldb_dn *base,
     1747                                    const char *attribute, bool *is_ntdsa)
     1748{
     1749        int ret;
     1750        struct ldb_dn *referenced_dn;
     1751        TALLOC_CTX *tmp_ctx = talloc_new(ldb);
     1752        if (tmp_ctx == NULL) {
     1753                return LDB_ERR_OPERATIONS_ERROR;
     1754        }
     1755        ret = samdb_reference_dn(ldb, tmp_ctx, base, attribute, &referenced_dn);
     1756        if (ret != LDB_SUCCESS) {
     1757                DEBUG(0, ("Failed to find object %s for attribute %s - %s\n", ldb_dn_get_linearized(base), attribute, ldb_errstring(ldb)));
     1758                return ret;
     1759        }
     1760
     1761        ret = samdb_dn_is_our_ntdsa(ldb, referenced_dn, is_ntdsa);
     1762       
     1763        talloc_free(tmp_ctx);
     1764        return ret;
    16491765}
    16501766
     
    17631879                allow_list[0] = l_subnet_name;
    17641880
    1765                 if (allow_access(mem_ctx, NULL, allow_list, "", ip_address)) {
     1881                if (socket_allow_access(mem_ctx, NULL, allow_list, "", ip_address)) {
    17661882                        sites_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx,
    17671883                                                           res->msgs[i],
     
    18151931bool samdb_is_pdc(struct ldb_context *ldb)
    18161932{
    1817         const char *dom_attrs[] = { "fSMORoleOwner", NULL };
    18181933        int ret;
    1819         struct ldb_result *dom_res;
    1820         TALLOC_CTX *tmp_ctx;
    18211934        bool is_pdc;
    1822         struct ldb_dn *pdc;
    1823 
    1824         tmp_ctx = talloc_new(ldb);
    1825         if (tmp_ctx == NULL) {
    1826                 DEBUG(1, ("talloc_new failed in samdb_is_pdc"));
    1827                 return false;
    1828         }
    1829 
    1830         ret = ldb_search(ldb, tmp_ctx, &dom_res, ldb_get_default_basedn(ldb), LDB_SCOPE_BASE, dom_attrs, NULL);
    1831         if (ret != LDB_SUCCESS) {
    1832                 DEBUG(1,("Searching for fSMORoleOwner in %s failed: %s\n",
     1935
     1936        ret = samdb_reference_dn_is_our_ntdsa(ldb, ldb_get_default_basedn(ldb), "fsmoRoleOwner",
     1937                                              &is_pdc);
     1938        if (ret != LDB_SUCCESS) {
     1939                DEBUG(1,("Failed to find if we are the PDC for this ldb: Searching for fSMORoleOwner in %s failed: %s\n",
    18331940                         ldb_dn_get_linearized(ldb_get_default_basedn(ldb)),
    18341941                         ldb_errstring(ldb)));
    1835                 goto failed;
    1836         }
    1837         if (dom_res->count != 1) {
    1838                 goto failed;
    1839         }
    1840 
    1841         pdc = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, dom_res->msgs[0], "fSMORoleOwner");
    1842 
    1843         if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), pdc) == 0) {
    1844                 is_pdc = true;
    1845         } else {
    1846                 is_pdc = false;
    1847         }
    1848 
    1849         talloc_free(tmp_ctx);
     1942                return false;
     1943        }
    18501944
    18511945        return is_pdc;
    1852 
    1853 failed:
    1854         DEBUG(1,("Failed to find if we are the PDC for this ldb\n"));
    1855         talloc_free(tmp_ctx);
    1856         return false;
    18571946}
    18581947
     
    18621951bool samdb_is_gc(struct ldb_context *ldb)
    18631952{
    1864         const char *attrs[] = { "options", NULL };
    18651953        uint32_t options;
    1866         int ret;
    1867         struct ldb_result *res;
    1868         TALLOC_CTX *tmp_ctx;
    1869 
    1870         tmp_ctx = talloc_new(ldb);
    1871         if (tmp_ctx == NULL) {
    1872                 DEBUG(1, ("talloc_new failed in samdb_is_pdc"));
     1954        if (samdb_ntds_options(ldb, &options) != LDB_SUCCESS) {
    18731955                return false;
    18741956        }
    1875 
    1876         /* Query cn=ntds settings,.... */
    1877         ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
    1878         if (ret != LDB_SUCCESS) {
    1879                 talloc_free(tmp_ctx);
    1880                 return false;
    1881         }
    1882         if (res->count != 1) {
    1883                 talloc_free(tmp_ctx);
    1884                 return false;
    1885         }
    1886 
    1887         options = ldb_msg_find_attr_as_uint(res->msgs[0], "options", 0);
    1888         talloc_free(tmp_ctx);
    1889 
    1890         /* if options attribute has the 0x00000001 flag set, then enable the global catlog */
    1891         if (options & DS_NTDSDSA_OPT_IS_GC) {
    1892                 return true;
    1893         }
    1894         return false;
     1957        return (options & DS_NTDSDSA_OPT_IS_GC) != 0;
    18951958}
    18961959
     
    19492012 * Result codes from "enum samr_ValidationStatus" (consider "samr.idl")
    19502013 */
    1951 enum samr_ValidationStatus samdb_check_password(const DATA_BLOB *password,
     2014enum samr_ValidationStatus samdb_check_password(const DATA_BLOB *utf8_blob,
    19522015                                                const uint32_t pwdProperties,
    19532016                                                const uint32_t minPwdLength)
    19542017{
     2018        const char *utf8_pw = (const char *)utf8_blob->data;
     2019        size_t utf8_len = strlen_m(utf8_pw);
     2020
    19552021        /* checks if the "minPwdLength" property is satisfied */
    1956         if (minPwdLength > password->length)
     2022        if (minPwdLength > utf8_len) {
    19572023                return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
     2024        }
    19582025
    19592026        /* checks the password complexity */
    1960         if (((pwdProperties & DOMAIN_PASSWORD_COMPLEX) != 0)
    1961                         && (password->data != NULL)
    1962                         && (!check_password_quality((const char *) password->data)))
     2027        if (!(pwdProperties & DOMAIN_PASSWORD_COMPLEX)) {
     2028                return SAMR_VALIDATION_STATUS_SUCCESS;
     2029        }
     2030
     2031        if (utf8_len == 0) {
    19632032                return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
     2033        }
     2034
     2035        if (!check_password_quality(utf8_pw)) {
     2036                return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
     2037        }
    19642038
    19652039        return SAMR_VALIDATION_STATUS_SUCCESS;
     
    20062080 *   NT_STATUS_WRONG_PASSWORD, NT_STATUS_PASSWORD_RESTRICTION
    20072081 */
    2008 NTSTATUS samdb_set_password(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
     2082static NTSTATUS samdb_set_password_internal(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
    20092083                            struct ldb_dn *user_dn, struct ldb_dn *domain_dn,
    20102084                            const DATA_BLOB *new_password,
     
    20142088                            const struct samr_Password *ntOldHash,
    20152089                            enum samPwdChangeReason *reject_reason,
    2016                             struct samr_DomInfo1 **_dominfo)
     2090                            struct samr_DomInfo1 **_dominfo,
     2091                            bool permit_interdomain_trust)
    20172092{
    20182093        struct ldb_message *msg;
     
    20212096        struct dsdb_control_password_change_status *pwd_stat = NULL;
    20222097        int ret;
     2098        bool hash_values = false;
    20232099        NTSTATUS status = NT_STATUS_OK;
    20242100
     
    20562132                        el->flags = LDB_FLAG_MOD_REPLACE;
    20572133                }
     2134                hash_values = true;
    20582135        } else {
    20592136                /* the password wasn't specified correctly */
     
    20932170                }
    20942171        }
     2172        if (hash_values) {
     2173                ret = ldb_request_add_control(req,
     2174                                              DSDB_CONTROL_PASSWORD_HASH_VALUES_OID,
     2175                                              true, NULL);
     2176                if (ret != LDB_SUCCESS) {
     2177                        talloc_free(req);
     2178                        talloc_free(msg);
     2179                        return NT_STATUS_NO_MEMORY;
     2180                }
     2181        }
     2182        if (permit_interdomain_trust) {
     2183                ret = ldb_request_add_control(req,
     2184                                              DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID,
     2185                                              false, NULL);
     2186                if (ret != LDB_SUCCESS) {
     2187                        talloc_free(req);
     2188                        talloc_free(msg);
     2189                        return NT_STATUS_NO_MEMORY;
     2190                }
     2191        }
    20952192        ret = ldb_request_add_control(req,
    2096                                       DSDB_CONTROL_PASSWORD_HASH_VALUES_OID,
     2193                                      DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
    20972194                                      true, NULL);
    20982195        if (ret != LDB_SUCCESS) {
     
    21012198                return NT_STATUS_NO_MEMORY;
    21022199        }
    2103         ret = ldb_request_add_control(req,
    2104                                       DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
    2105                                       true, NULL);
    2106         if (ret != LDB_SUCCESS) {
    2107                 talloc_free(req);
    2108                 talloc_free(msg);
    2109                 return NT_STATUS_NO_MEMORY;
    2110         }
    21112200
    21122201        ret = dsdb_autotransaction_request(ldb, req);
    21132202
    21142203        if (req->context != NULL) {
    2115                 pwd_stat = talloc_steal(mem_ctx,
    2116                                         ((struct ldb_control *)req->context)->data);
     2204                struct ldb_control *control = talloc_get_type_abort(req->context,
     2205                                                                    struct ldb_control);
     2206                pwd_stat = talloc_get_type_abort(control->data,
     2207                                                 struct dsdb_control_password_change_status);
     2208                talloc_steal(mem_ctx, pwd_stat);
    21172209        }
    21182210
     
    21712263                /* don't let the caller know if an account doesn't exist */
    21722264                status = NT_STATUS_WRONG_PASSWORD;
     2265        } else if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
     2266                status = NT_STATUS_ACCESS_DENIED;
    21732267        } else if (ret != LDB_SUCCESS) {
     2268                DEBUG(1, ("Failed to set password on %s: %s\n",
     2269                          ldb_dn_get_linearized(msg->dn),
     2270                          ldb_errstring(ldb)));
    21742271                status = NT_STATUS_UNSUCCESSFUL;
    21752272        }
    21762273
    21772274        return status;
     2275}
     2276
     2277NTSTATUS samdb_set_password(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
     2278                            struct ldb_dn *user_dn, struct ldb_dn *domain_dn,
     2279                            const DATA_BLOB *new_password,
     2280                            const struct samr_Password *lmNewHash,
     2281                            const struct samr_Password *ntNewHash,
     2282                            const struct samr_Password *lmOldHash,
     2283                            const struct samr_Password *ntOldHash,
     2284                            enum samPwdChangeReason *reject_reason,
     2285                            struct samr_DomInfo1 **_dominfo)
     2286{
     2287        return samdb_set_password_internal(ldb, mem_ctx,
     2288                            user_dn, domain_dn,
     2289                            new_password,
     2290                            lmNewHash, ntNewHash,
     2291                            lmOldHash, ntOldHash,
     2292                            reject_reason, _dominfo,
     2293                            false); /* reject trusts */
    21782294}
    21792295
     
    21982314NTSTATUS samdb_set_password_sid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
    21992315                                const struct dom_sid *user_sid,
     2316                                const uint32_t *new_version, /* optional for trusts */
    22002317                                const DATA_BLOB *new_password,
    22012318                                const struct samr_Password *lmNewHash,
     
    22062323                                struct samr_DomInfo1 **_dominfo)
    22072324{
     2325        TALLOC_CTX *frame = talloc_stackframe();
    22082326        NTSTATUS nt_status;
    2209         struct ldb_dn *user_dn;
     2327        const char * const user_attrs[] = {
     2328                "userAccountControl",
     2329                "sAMAccountName",
     2330                NULL
     2331        };
     2332        struct ldb_message *user_msg = NULL;
    22102333        int ret;
     2334        uint32_t uac = 0;
    22112335
    22122336        ret = ldb_transaction_start(ldb);
    22132337        if (ret != LDB_SUCCESS) {
    22142338                DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(ldb)));
     2339                TALLOC_FREE(frame);
    22152340                return NT_STATUS_TRANSACTION_ABORTED;
    22162341        }
    22172342
    2218         user_dn = samdb_search_dn(ldb, mem_ctx, NULL,
    2219                                   "(&(objectSid=%s)(objectClass=user))",
    2220                                   ldap_encode_ndr_dom_sid(mem_ctx, user_sid));
    2221         if (!user_dn) {
     2343        ret = dsdb_search_one(ldb, frame, &user_msg, ldb_get_default_basedn(ldb),
     2344                              LDB_SCOPE_SUBTREE, user_attrs, 0,
     2345                              "(&(objectSid=%s)(objectClass=user))",
     2346                              ldap_encode_ndr_dom_sid(frame, user_sid));
     2347        if (ret != LDB_SUCCESS) {
    22222348                ldb_transaction_cancel(ldb);
    2223                 DEBUG(3, ("samdb_set_password_sid: SID %s not found in samdb, returning NO_SUCH_USER\n",
    2224                           dom_sid_string(mem_ctx, user_sid)));
     2349                DEBUG(3, ("samdb_set_password_sid: SID[%s] not found in samdb %s - %s, "
     2350                          "returning NO_SUCH_USER\n",
     2351                          dom_sid_string(frame, user_sid),
     2352                          ldb_strerror(ret), ldb_errstring(ldb)));
     2353                TALLOC_FREE(frame);
    22252354                return NT_STATUS_NO_SUCH_USER;
    22262355        }
    22272356
    2228         nt_status = samdb_set_password(ldb, mem_ctx,
    2229                                        user_dn, NULL,
    2230                                        new_password,
    2231                                        lmNewHash, ntNewHash,
    2232                                        lmOldHash, ntOldHash,
    2233                                        reject_reason, _dominfo);
     2357        uac = ldb_msg_find_attr_as_uint(user_msg, "userAccountControl", 0);
     2358        if (!(uac & UF_ACCOUNT_TYPE_MASK)) {
     2359                ldb_transaction_cancel(ldb);
     2360                DEBUG(1, ("samdb_set_password_sid: invalid "
     2361                          "userAccountControl[0x%08X] for SID[%s] DN[%s], "
     2362                          "returning NO_SUCH_USER\n",
     2363                          (unsigned)uac, dom_sid_string(frame, user_sid),
     2364                          ldb_dn_get_linearized(user_msg->dn)));
     2365                TALLOC_FREE(frame);
     2366                return NT_STATUS_NO_SUCH_USER;
     2367        }
     2368
     2369        if (uac & UF_INTERDOMAIN_TRUST_ACCOUNT) {
     2370                const char * const tdo_attrs[] = {
     2371                        "trustAuthIncoming",
     2372                        "trustDirection",
     2373                        NULL
     2374                };
     2375                struct ldb_message *tdo_msg = NULL;
     2376                const char *account_name = NULL;
     2377                uint32_t trust_direction;
     2378                uint32_t i;
     2379                const struct ldb_val *old_val = NULL;
     2380                struct trustAuthInOutBlob old_blob = {};
     2381                uint32_t old_version = 0;
     2382                struct AuthenticationInformation *old_version_a = NULL;
     2383                uint32_t _new_version = 0;
     2384                struct trustAuthInOutBlob new_blob = {};
     2385                struct ldb_val new_val = {};
     2386                struct timeval tv = timeval_current();
     2387                NTTIME now = timeval_to_nttime(&tv);
     2388                enum ndr_err_code ndr_err;
     2389
     2390                if (new_password == NULL && ntNewHash == NULL) {
     2391                        ldb_transaction_cancel(ldb);
     2392                        DEBUG(1, ("samdb_set_password_sid: "
     2393                                  "no new password provided "
     2394                                  "sAMAccountName for SID[%s] DN[%s], "
     2395                                  "returning INVALID_PARAMETER\n",
     2396                                  dom_sid_string(frame, user_sid),
     2397                                  ldb_dn_get_linearized(user_msg->dn)));
     2398                        TALLOC_FREE(frame);
     2399                        return NT_STATUS_INVALID_PARAMETER;
     2400                }
     2401
     2402                if (new_password != NULL && ntNewHash != NULL) {
     2403                        ldb_transaction_cancel(ldb);
     2404                        DEBUG(1, ("samdb_set_password_sid: "
     2405                                  "two new passwords provided "
     2406                                  "sAMAccountName for SID[%s] DN[%s], "
     2407                                  "returning INVALID_PARAMETER\n",
     2408                                  dom_sid_string(frame, user_sid),
     2409                                  ldb_dn_get_linearized(user_msg->dn)));
     2410                        TALLOC_FREE(frame);
     2411                        return NT_STATUS_INVALID_PARAMETER;
     2412                }
     2413
     2414                if (new_password != NULL && (new_password->length % 2)) {
     2415                        ldb_transaction_cancel(ldb);
     2416                        DEBUG(2, ("samdb_set_password_sid: "
     2417                                  "invalid utf16 length (%zu) "
     2418                                  "sAMAccountName for SID[%s] DN[%s], "
     2419                                  "returning WRONG_PASSWORD\n",
     2420                                  new_password->length,
     2421                                  dom_sid_string(frame, user_sid),
     2422                                  ldb_dn_get_linearized(user_msg->dn)));
     2423                        TALLOC_FREE(frame);
     2424                        return NT_STATUS_WRONG_PASSWORD;
     2425                }
     2426
     2427                if (new_password != NULL && new_password->length >= 500) {
     2428                        ldb_transaction_cancel(ldb);
     2429                        DEBUG(2, ("samdb_set_password_sid: "
     2430                                  "utf16 password too long (%zu) "
     2431                                  "sAMAccountName for SID[%s] DN[%s], "
     2432                                  "returning WRONG_PASSWORD\n",
     2433                                  new_password->length,
     2434                                  dom_sid_string(frame, user_sid),
     2435                                  ldb_dn_get_linearized(user_msg->dn)));
     2436                        TALLOC_FREE(frame);
     2437                        return NT_STATUS_WRONG_PASSWORD;
     2438                }
     2439
     2440                account_name = ldb_msg_find_attr_as_string(user_msg,
     2441                                                        "sAMAccountName", NULL);
     2442                if (account_name == NULL) {
     2443                        ldb_transaction_cancel(ldb);
     2444                        DEBUG(1, ("samdb_set_password_sid: missing "
     2445                                  "sAMAccountName for SID[%s] DN[%s], "
     2446                                  "returning NO_SUCH_USER\n",
     2447                                  dom_sid_string(frame, user_sid),
     2448                                  ldb_dn_get_linearized(user_msg->dn)));
     2449                        TALLOC_FREE(frame);
     2450                        return NT_STATUS_NO_SUCH_USER;
     2451                }
     2452
     2453                nt_status = dsdb_trust_search_tdo_by_type(ldb,
     2454                                                          SEC_CHAN_DOMAIN,
     2455                                                          account_name,
     2456                                                          tdo_attrs,
     2457                                                          frame, &tdo_msg);
     2458                if (!NT_STATUS_IS_OK(nt_status)) {
     2459                        ldb_transaction_cancel(ldb);
     2460                        DEBUG(1, ("samdb_set_password_sid: dsdb_trust_search_tdo "
     2461                                  "failed(%s) for sAMAccountName[%s] SID[%s] DN[%s], "
     2462                                  "returning INTERNAL_DB_CORRUPTION\n",
     2463                                  nt_errstr(nt_status), account_name,
     2464                                  dom_sid_string(frame, user_sid),
     2465                                  ldb_dn_get_linearized(user_msg->dn)));
     2466                        TALLOC_FREE(frame);
     2467                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
     2468                }
     2469
     2470                trust_direction = ldb_msg_find_attr_as_int(tdo_msg,
     2471                                                           "trustDirection", 0);
     2472                if (!(trust_direction & LSA_TRUST_DIRECTION_INBOUND)) {
     2473                        ldb_transaction_cancel(ldb);
     2474                        DEBUG(1, ("samdb_set_password_sid: direction[0x%08X] is "
     2475                                  "not inbound for sAMAccountName[%s] "
     2476                                  "DN[%s] TDO[%s], "
     2477                                  "returning INTERNAL_DB_CORRUPTION\n",
     2478                                  (unsigned)trust_direction,
     2479                                  account_name,
     2480                                  ldb_dn_get_linearized(user_msg->dn),
     2481                                  ldb_dn_get_linearized(tdo_msg->dn)));
     2482                        TALLOC_FREE(frame);
     2483                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
     2484                }
     2485
     2486                old_val = ldb_msg_find_ldb_val(tdo_msg, "trustAuthIncoming");
     2487                if (old_val != NULL) {
     2488                        ndr_err = ndr_pull_struct_blob(old_val, frame, &old_blob,
     2489                                        (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
     2490                        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     2491                                ldb_transaction_cancel(ldb);
     2492                                DEBUG(1, ("samdb_set_password_sid: "
     2493                                          "failed(%s) to parse "
     2494                                          "trustAuthOutgoing sAMAccountName[%s] "
     2495                                          "DN[%s] TDO[%s], "
     2496                                          "returning INTERNAL_DB_CORRUPTION\n",
     2497                                          ndr_map_error2string(ndr_err),
     2498                                          account_name,
     2499                                          ldb_dn_get_linearized(user_msg->dn),
     2500                                          ldb_dn_get_linearized(tdo_msg->dn)));
     2501
     2502                                TALLOC_FREE(frame);
     2503                                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     2504                        }
     2505                }
     2506
     2507                for (i = old_blob.current.count; i > 0; i--) {
     2508                        struct AuthenticationInformation *a =
     2509                                &old_blob.current.array[i - 1];
     2510
     2511                        switch (a->AuthType) {
     2512                        case TRUST_AUTH_TYPE_NONE:
     2513                                if (i == old_blob.current.count) {
     2514                                        /*
     2515                                         * remove TRUST_AUTH_TYPE_NONE at the
     2516                                         * end
     2517                                         */
     2518                                        old_blob.current.count--;
     2519                                }
     2520                                break;
     2521
     2522                        case TRUST_AUTH_TYPE_VERSION:
     2523                                old_version_a = a;
     2524                                old_version = a->AuthInfo.version.version;
     2525                                break;
     2526
     2527                        case TRUST_AUTH_TYPE_CLEAR:
     2528                                break;
     2529
     2530                        case TRUST_AUTH_TYPE_NT4OWF:
     2531                                break;
     2532                        }
     2533                }
     2534
     2535                if (new_version == NULL) {
     2536                        _new_version = 0;
     2537                        new_version = &_new_version;
     2538                }
     2539
     2540                if (old_version_a != NULL && *new_version != (old_version + 1)) {
     2541                        old_version_a->LastUpdateTime = now;
     2542                        old_version_a->AuthType = TRUST_AUTH_TYPE_NONE;
     2543                }
     2544
     2545                new_blob.count = MAX(old_blob.current.count, 2);
     2546                new_blob.current.array = talloc_zero_array(frame,
     2547                                                struct AuthenticationInformation,
     2548                                                new_blob.count);
     2549                if (new_blob.current.array == NULL) {
     2550                        ldb_transaction_cancel(ldb);
     2551                        TALLOC_FREE(frame);
     2552                        return NT_STATUS_NO_MEMORY;
     2553                }
     2554                new_blob.previous.array = talloc_zero_array(frame,
     2555                                                struct AuthenticationInformation,
     2556                                                new_blob.count);
     2557                if (new_blob.current.array == NULL) {
     2558                        ldb_transaction_cancel(ldb);
     2559                        TALLOC_FREE(frame);
     2560                        return NT_STATUS_NO_MEMORY;
     2561                }
     2562
     2563                for (i = 0; i < old_blob.current.count; i++) {
     2564                        struct AuthenticationInformation *o =
     2565                                &old_blob.current.array[i];
     2566                        struct AuthenticationInformation *p =
     2567                                &new_blob.previous.array[i];
     2568
     2569                        *p = *o;
     2570                        new_blob.previous.count++;
     2571                }
     2572                for (; i < new_blob.count; i++) {
     2573                        struct AuthenticationInformation *pi =
     2574                                &new_blob.previous.array[i];
     2575
     2576                        if (i == 0) {
     2577                                /*
     2578                                 * new_blob.previous is still empty so
     2579                                 * we'll do new_blob.previous = new_blob.current
     2580                                 * below.
     2581                                 */
     2582                                break;
     2583                        }
     2584
     2585                        pi->LastUpdateTime = now;
     2586                        pi->AuthType = TRUST_AUTH_TYPE_NONE;
     2587                        new_blob.previous.count++;
     2588                }
     2589
     2590                for (i = 0; i < new_blob.count; i++) {
     2591                        struct AuthenticationInformation *ci =
     2592                                &new_blob.current.array[i];
     2593
     2594                        ci->LastUpdateTime = now;
     2595                        switch (i) {
     2596                        case 0:
     2597                                if (ntNewHash != NULL) {
     2598                                        ci->AuthType = TRUST_AUTH_TYPE_NT4OWF;
     2599                                        ci->AuthInfo.nt4owf.password = *ntNewHash;
     2600                                        break;
     2601                                }
     2602
     2603                                ci->AuthType = TRUST_AUTH_TYPE_CLEAR;
     2604                                ci->AuthInfo.clear.size = new_password->length;
     2605                                ci->AuthInfo.clear.password = new_password->data;
     2606                                break;
     2607                        case 1:
     2608                                ci->AuthType = TRUST_AUTH_TYPE_VERSION;
     2609                                ci->AuthInfo.version.version = *new_version;
     2610                                break;
     2611                        default:
     2612                                ci->AuthType = TRUST_AUTH_TYPE_NONE;
     2613                                break;
     2614                        }
     2615
     2616                        new_blob.current.count++;
     2617                }
     2618
     2619                if (new_blob.previous.count == 0) {
     2620                        TALLOC_FREE(new_blob.previous.array);
     2621                        new_blob.previous = new_blob.current;
     2622                }
     2623
     2624                ndr_err = ndr_push_struct_blob(&new_val, frame, &new_blob,
     2625                                (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
     2626                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     2627                        ldb_transaction_cancel(ldb);
     2628                        DEBUG(1, ("samdb_set_password_sid: "
     2629                                  "failed(%s) to generate "
     2630                                  "trustAuthOutgoing sAMAccountName[%s] "
     2631                                  "DN[%s] TDO[%s], "
     2632                                  "returning UNSUCCESSFUL\n",
     2633                                  ndr_map_error2string(ndr_err),
     2634                                  account_name,
     2635                                  ldb_dn_get_linearized(user_msg->dn),
     2636                                  ldb_dn_get_linearized(tdo_msg->dn)));
     2637                        TALLOC_FREE(frame);
     2638                        return NT_STATUS_UNSUCCESSFUL;
     2639                }
     2640
     2641                tdo_msg->num_elements = 0;
     2642                TALLOC_FREE(tdo_msg->elements);
     2643
     2644                ret = ldb_msg_add_empty(tdo_msg, "trustAuthIncoming",
     2645                                        LDB_FLAG_MOD_REPLACE, NULL);
     2646                if (ret != LDB_SUCCESS) {
     2647                        ldb_transaction_cancel(ldb);
     2648                        TALLOC_FREE(frame);
     2649                        return NT_STATUS_NO_MEMORY;
     2650                }
     2651                ret = ldb_msg_add_value(tdo_msg, "trustAuthIncoming",
     2652                                        &new_val, NULL);
     2653                if (ret != LDB_SUCCESS) {
     2654                        ldb_transaction_cancel(ldb);
     2655                        TALLOC_FREE(frame);
     2656                        return NT_STATUS_NO_MEMORY;
     2657                }
     2658
     2659                ret = ldb_modify(ldb, tdo_msg);
     2660                if (ret != LDB_SUCCESS) {
     2661                        nt_status = dsdb_ldb_err_to_ntstatus(ret);
     2662                        ldb_transaction_cancel(ldb);
     2663                        DEBUG(1, ("samdb_set_password_sid: "
     2664                                  "failed to replace "
     2665                                  "trustAuthOutgoing sAMAccountName[%s] "
     2666                                  "DN[%s] TDO[%s], "
     2667                                  "%s - %s\n",
     2668                                  account_name,
     2669                                  ldb_dn_get_linearized(user_msg->dn),
     2670                                  ldb_dn_get_linearized(tdo_msg->dn),
     2671                                  nt_errstr(nt_status), ldb_errstring(ldb)));
     2672                        TALLOC_FREE(frame);
     2673                        return nt_status;
     2674                }
     2675        }
     2676
     2677        nt_status = samdb_set_password_internal(ldb, mem_ctx,
     2678                                                user_msg->dn, NULL,
     2679                                                new_password,
     2680                                                lmNewHash, ntNewHash,
     2681                                                lmOldHash, ntOldHash,
     2682                                                reject_reason, _dominfo,
     2683                                                true); /* permit trusts */
    22342684        if (!NT_STATUS_IS_OK(nt_status)) {
    22352685                ldb_transaction_cancel(ldb);
    2236                 talloc_free(user_dn);
     2686                TALLOC_FREE(frame);
    22372687                return nt_status;
    22382688        }
     
    22412691        if (ret != LDB_SUCCESS) {
    22422692                DEBUG(0,("Failed to commit transaction to change password on %s: %s\n",
    2243                          ldb_dn_get_linearized(user_dn),
     2693                         ldb_dn_get_linearized(user_msg->dn),
    22442694                         ldb_errstring(ldb)));
    2245                 talloc_free(user_dn);
     2695                TALLOC_FREE(frame);
    22462696                return NT_STATUS_TRANSACTION_ABORTED;
    22472697        }
    22482698
    2249         talloc_free(user_dn);
     2699        TALLOC_FREE(frame);
    22502700        return NT_STATUS_OK;
    22512701}
     
    23242774        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    23252775        const char *binary_encoded;
    2326         const char **split_realm;
     2776        const char * const *split_realm;
    23272777        struct ldb_dn *dn;
    23282778
     
    23312781        }
    23322782
    2333         split_realm = (const char **)str_list_make(tmp_ctx, dns_domain, ".");
     2783        split_realm = (const char * const *)str_list_make(tmp_ctx, dns_domain, ".");
    23342784        if (!split_realm) {
    23352785                talloc_free(tmp_ctx);
     
    23552805        return dn;
    23562806}
     2807
     2808
     2809/*
     2810  Find the DNS equivalent of a DN, in dotted DNS form
     2811*/
     2812char *samdb_dn_to_dns_domain(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
     2813{
     2814        int i, num_components = ldb_dn_get_comp_num(dn);
     2815        char *dns_name = talloc_strdup(mem_ctx, "");
     2816        if (dns_name == NULL) {
     2817                return NULL;
     2818        }
     2819
     2820        for (i=0; i<num_components; i++) {
     2821                const struct ldb_val *v = ldb_dn_get_component_val(dn, i);
     2822                char *s;
     2823                if (v == NULL) {
     2824                        talloc_free(dns_name);
     2825                        return NULL;
     2826                }
     2827                s = talloc_asprintf_append_buffer(dns_name, "%*.*s.",
     2828                                                  (int)v->length, (int)v->length, (char *)v->data);
     2829                if (s == NULL) {
     2830                        talloc_free(dns_name);
     2831                        return NULL;
     2832                }
     2833                dns_name = s;
     2834        }
     2835
     2836        /* remove the last '.' */
     2837        if (dns_name[0] != 0) {
     2838                dns_name[strlen(dns_name)-1] = 0;
     2839        }
     2840
     2841        return dns_name;
     2842}
     2843
     2844/*
     2845  Find the DNS _msdcs name for a given NTDS GUID. The resulting DNS
     2846  name is based on the forest DNS name
     2847*/
     2848char *samdb_ntds_msdcs_dns_name(struct ldb_context *samdb,
     2849                                TALLOC_CTX *mem_ctx,
     2850                                const struct GUID *ntds_guid)
     2851{
     2852        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     2853        const char *guid_str;
     2854        struct ldb_dn *forest_dn;
     2855        const char *dnsforest;
     2856        char *ret;
     2857
     2858        guid_str = GUID_string(tmp_ctx, ntds_guid);
     2859        if (guid_str == NULL) {
     2860                talloc_free(tmp_ctx);
     2861                return NULL;
     2862        }
     2863        forest_dn = ldb_get_root_basedn(samdb);
     2864        if (forest_dn == NULL) {
     2865                talloc_free(tmp_ctx);
     2866                return NULL;
     2867        }
     2868        dnsforest = samdb_dn_to_dns_domain(tmp_ctx, forest_dn);
     2869        if (dnsforest == NULL) {
     2870                talloc_free(tmp_ctx);
     2871                return NULL;
     2872        }
     2873        ret = talloc_asprintf(mem_ctx, "%s._msdcs.%s", guid_str, dnsforest);
     2874        talloc_free(tmp_ctx);
     2875        return ret;
     2876}
     2877
    23572878
    23582879/*
     
    24152936int dsdb_find_dn_by_guid(struct ldb_context *ldb,
    24162937                         TALLOC_CTX *mem_ctx,
    2417                          const struct GUID *guid, struct ldb_dn **dn)
     2938                         const struct GUID *guid,
     2939                         uint32_t dsdb_flags,
     2940                         struct ldb_dn **dn)
    24182941{
    24192942        int ret;
     
    24292952                          DSDB_SEARCH_SEARCH_ALL_PARTITIONS |
    24302953                          DSDB_SEARCH_SHOW_EXTENDED_DN |
    2431                           DSDB_SEARCH_ONE_ONLY,
     2954                          DSDB_SEARCH_ONE_ONLY | dsdb_flags,
    24322955                          "objectGUID=%s", guid_str);
    24332956        talloc_free(guid_str);
     
    25983121        unsigned int i;
    25993122        struct ldb_message_element *el;
     3123        int ret;
    26003124
    26013125        *r = NULL;
    26023126        *count = 0;
    26033127
    2604         if (ldb_search(sam_ctx, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, NULL) != LDB_SUCCESS ||
    2605             res->count < 1) {
    2606                 DEBUG(0,("dsdb_loadreps: failed to read partition object\n"));
     3128        ret = dsdb_search_dn(sam_ctx, tmp_ctx, &res, dn, attrs, 0);
     3129        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     3130                /* partition hasn't been replicated yet */
     3131                return WERR_OK;
     3132        }
     3133        if (ret != LDB_SUCCESS) {
     3134                DEBUG(0,("dsdb_loadreps: failed to read partition object: %s\n", ldb_errstring(sam_ctx)));
    26073135                talloc_free(tmp_ctx);
    26083136                return WERR_DS_DRA_INTERNAL_ERROR;
     
    26783206        }
    26793207
    2680         if (ldb_modify(sam_ctx, msg) != LDB_SUCCESS) {
     3208        if (dsdb_modify(sam_ctx, msg, 0) != LDB_SUCCESS) {
    26813209                DEBUG(0,("Failed to store %s - %s\n", attr, ldb_errstring(sam_ctx)));
    26823210                goto failed;
     
    29103438
    29113439/*
     3440 * return NTDSSiteSettings options. See MS-ADTS 7.1.1.2.2.1.1
     3441 * flags are DS_NTDSSETTINGS_OPT_*
     3442 */
     3443int samdb_ntds_site_settings_options(struct ldb_context *ldb_ctx,
     3444                                        uint32_t *options)
     3445{
     3446        int rc;
     3447        TALLOC_CTX *tmp_ctx;
     3448        struct ldb_result *res;
     3449        struct ldb_dn *site_dn;
     3450        const char *attrs[] = { "options", NULL };
     3451
     3452        tmp_ctx = talloc_new(ldb_ctx);
     3453        if (tmp_ctx == NULL)
     3454                goto failed;
     3455
     3456        /* Retrieve the site dn for the ldb that we
     3457         * have open.  This is our local site.
     3458         */
     3459        site_dn = samdb_server_site_dn(ldb_ctx, tmp_ctx);
     3460        if (site_dn == NULL)
     3461                goto failed;
     3462
     3463        /* Perform a one level (child) search from the local
     3464         * site distinguided name.   We're looking for the
     3465         * "options" attribute within the nTDSSiteSettings
     3466         * object
     3467         */
     3468        rc = ldb_search(ldb_ctx, tmp_ctx, &res, site_dn,
     3469                        LDB_SCOPE_ONELEVEL, attrs,
     3470                        "objectClass=nTDSSiteSettings");
     3471
     3472        if (rc != LDB_SUCCESS || res->count != 1)
     3473                goto failed;
     3474
     3475        *options = ldb_msg_find_attr_as_uint(res->msgs[0], "options", 0);
     3476
     3477        talloc_free(tmp_ctx);
     3478
     3479        return LDB_SUCCESS;
     3480
     3481failed:
     3482        DEBUG(1,("Failed to find our NTDS Site Settings options in ldb!\n"));
     3483        talloc_free(tmp_ctx);
     3484        return LDB_ERR_NO_SUCH_OBJECT;
     3485}
     3486
     3487/*
    29123488  return NTDS options flags. See MS-ADTS 7.1.1.2.2.1.2.1.1
    29133489
     
    29263502        }
    29273503
    2928         ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
     3504        ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL);
    29293505        if (ret != LDB_SUCCESS) {
    29303506                goto failed;
     
    29533529        struct ldb_result *res;
    29543530
    2955         ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
     3531        ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL);
    29563532        if (ret != LDB_SUCCESS) {
    29573533                goto failed;
     
    29843560        /* "tolower()" and "toupper()" should also work properly on 0x00 */
    29853561        tokens[0][0] = tolower(tokens[0][0]);
    2986         for (i = 1; i < str_list_length((const char **)tokens); i++)
     3562        for (i = 1; i < str_list_length((const char * const *)tokens); i++)
    29873563                tokens[i][0] = toupper(tokens[i][0]);
    29883564
    29893565        ret = talloc_strdup(mem_ctx, tokens[0]);
    2990         for (i = 1; i < str_list_length((const char **)tokens); i++)
     3566        for (i = 1; i < str_list_length((const char * const *)tokens); i++)
    29913567                ret = talloc_asprintf_append_buffer(ret, "%s", tokens[i]);
    29923568
     
    31933769bool dsdb_dn_is_upgraded_link_val(struct ldb_val *val)
    31943770{
    3195         return memmem(val->data, val->length, "<RMD_ADDTIME=", 13) != NULL;
     3771        return memmem(val->data, val->length, "<RMD_VERSION=", 13) != NULL;
    31963772}
    31973773
     
    32573833        ret = ldb_search(samdb, tmp_ctx, &root_res,
    32583834                         ldb_dn_new(tmp_ctx, samdb, ""), LDB_SCOPE_BASE, root_attrs, NULL);
    3259         if (ret != LDB_SUCCESS) {
     3835        if (ret != LDB_SUCCESS || root_res->count == 0) {
    32603836                DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(samdb)));
    32613837                talloc_free(tmp_ctx);
     
    34023978        unsigned int i;
    34033979        int ret;
    3404         uint64_t highest_usn;
     3980        uint64_t highest_usn = 0;
    34053981        const struct GUID *our_invocation_id;
    3406         struct timeval now = timeval_current();
     3982        static const struct timeval tv1970;
     3983        NTTIME nt1970 = timeval_to_nttime(&tv1970);
    34073984
    34083985        ret = ldb_search(samdb, mem_ctx, &r, dn, LDB_SCOPE_BASE, attrs, NULL);
     
    34454022        }
    34464023
    3447         ret = dsdb_load_partition_usn(samdb, dn, &highest_usn, NULL);
     4024        ret = ldb_sequence_number(samdb, LDB_SEQ_HIGHEST_SEQ, &highest_usn);
    34484025        if (ret != LDB_SUCCESS) {
    34494026                /* nothing to add - this can happen after a vampire */
     
    34554032                if (GUID_equal(our_invocation_id, &(*cursors)[i].source_dsa_invocation_id)) {
    34564033                        (*cursors)[i].highest_usn = highest_usn;
    3457                         (*cursors)[i].last_sync_success = timeval_to_nttime(&now);
     4034                        (*cursors)[i].last_sync_success = nt1970;
    34584035                        TYPESAFE_QSORT(*cursors, *count, drsuapi_DsReplicaCursor2_compare);
    34594036                        return LDB_SUCCESS;
     
    34684045        (*cursors)[*count].source_dsa_invocation_id = *our_invocation_id;
    34694046        (*cursors)[*count].highest_usn = highest_usn;
    3470         (*cursors)[*count].last_sync_success = timeval_to_nttime(&now);
     4047        (*cursors)[*count].last_sync_success = nt1970;
    34714048        (*count)++;
    34724049
     
    35364113        }
    35374114
     4115        if (dsdb_flags & DSDB_SEARCH_NO_GLOBAL_CATALOG) {
     4116                ret = ldb_request_add_control(req,
     4117                                              DSDB_CONTROL_NO_GLOBAL_CATALOG,
     4118                                              false, NULL);
     4119                if (ret != LDB_SUCCESS) {
     4120                        return ret;
     4121                }
     4122        }
     4123
    35384124        if (dsdb_flags & DSDB_SEARCH_SHOW_DELETED) {
    35394125                ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL);
     
    35514137
    35524138        if (dsdb_flags & DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT) {
    3553                 ret = ldb_request_add_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID, true, NULL);
     4139                ret = ldb_request_add_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID, false, NULL);
    35544140                if (ret != LDB_SUCCESS) {
    35554141                        return ret;
     
    36074193        if (dsdb_flags & DSDB_PROVISION) {
    36084194                ret = ldb_request_add_control(req, LDB_CONTROL_PROVISION_OID, false, NULL);
     4195                if (ret != LDB_SUCCESS) {
     4196                        return ret;
     4197                }
     4198        }
     4199
     4200        /* This is a special control to bypass the password_hash module for use in pdb_samba4 for Samba3 upgrades */
     4201        if (dsdb_flags & DSDB_BYPASS_PASSWORD_HASH) {
     4202                ret = ldb_request_add_control(req, DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID, true, NULL);
     4203                if (ret != LDB_SUCCESS) {
     4204                        return ret;
     4205                }
     4206        }
     4207
     4208        if (dsdb_flags & DSDB_PASSWORD_BYPASS_LAST_SET) {
     4209                /*
     4210                 * This must not be critical, as it will only be
     4211                 * handled (and need to be handled) if the other
     4212                 * attributes in the request bring password_hash into
     4213                 * action
     4214                 */
     4215                ret = ldb_request_add_control(req, DSDB_CONTROL_PASSWORD_BYPASS_LAST_SET_OID, false, NULL);
     4216                if (ret != LDB_SUCCESS) {
     4217                        return ret;
     4218                }
     4219        }
     4220
     4221        if (dsdb_flags & DSDB_MODIFY_PARTIAL_REPLICA) {
     4222                ret = ldb_request_add_control(req, DSDB_CONTROL_PARTIAL_REPLICA, false, NULL);
    36094223                if (ret != LDB_SUCCESS) {
    36104224                        return ret;
     
    36764290
    36774291/*
     4292  a delete with a set of flags
     4293*/
     4294int dsdb_delete(struct ldb_context *ldb, struct ldb_dn *dn,
     4295                uint32_t dsdb_flags)
     4296{
     4297        struct ldb_request *req;
     4298        int ret;
     4299
     4300        ret = ldb_build_del_req(&req, ldb, ldb,
     4301                                dn,
     4302                                NULL,
     4303                                NULL,
     4304                                ldb_op_default_callback,
     4305                                NULL);
     4306
     4307        if (ret != LDB_SUCCESS) return ret;
     4308
     4309        ret = dsdb_request_add_controls(req, dsdb_flags);
     4310        if (ret != LDB_SUCCESS) {
     4311                talloc_free(req);
     4312                return ret;
     4313        }
     4314
     4315        ret = dsdb_autotransaction_request(ldb, req);
     4316
     4317        talloc_free(req);
     4318        return ret;
     4319}
     4320
     4321/*
    36784322  like dsdb_modify() but set all the element flags to
    36794323  LDB_FLAG_MOD_REPLACE
     
    36974341int dsdb_search_dn(struct ldb_context *ldb,
    36984342                   TALLOC_CTX *mem_ctx,
    3699                    struct ldb_result **_res,
     4343                   struct ldb_result **_result,
    37004344                   struct ldb_dn *basedn,
    37014345                   const char * const *attrs,
     
    37424386        }
    37434387
    3744         *_res = res;
     4388        *_result = res;
    37454389        return LDB_SUCCESS;
    37464390}
     
    37524396int dsdb_search_by_dn_guid(struct ldb_context *ldb,
    37534397                           TALLOC_CTX *mem_ctx,
    3754                            struct ldb_result **_res,
     4398                           struct ldb_result **_result,
    37554399                           const struct GUID *guid,
    37564400                           const char * const *attrs,
     
    37674411        }
    37684412
    3769         ret = dsdb_search_dn(ldb, mem_ctx, _res, dn, attrs, dsdb_flags);
     4413        ret = dsdb_search_dn(ldb, mem_ctx, _result, dn, attrs, dsdb_flags);
    37704414        talloc_free(tmp_ctx);
    37714415        return ret;
     
    37774421int dsdb_search(struct ldb_context *ldb,
    37784422                TALLOC_CTX *mem_ctx,
    3779                 struct ldb_result **_res,
     4423                struct ldb_result **_result,
    37804424                struct ldb_dn *basedn,
    37814425                enum ldb_scope scope,
     
    37904434        char *expression = NULL;
    37914435        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     4436
     4437        /* cross-partitions searches with a basedn break multi-domain support */
     4438        SMB_ASSERT(basedn == NULL || (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) == 0);
    37924439
    37934440        res = talloc_zero(tmp_ctx, struct ldb_result);
     
    38524499        }
    38534500
    3854         *_res = talloc_steal(mem_ctx, res);
     4501        *_result = talloc_steal(mem_ctx, res);
    38554502        talloc_free(tmp_ctx);
    38564503
     
    40094656        account_dn = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, msg, "serverReference");
    40104657        if (account_dn == NULL) {
    4011                 DEBUG(1,(__location__ ": Failed to find account_dn for DSA with objectGUID %s, sid %s\n",
    4012                          GUID_string(tmp_ctx, dsa_guid), dom_sid_string(tmp_ctx, sid)));
     4658                DEBUG(1,(__location__ ": Failed to find account dn "
     4659                         "(serverReference) for %s, parent of DSA with "
     4660                         "objectGUID %s, sid %s\n",
     4661                         ldb_dn_get_linearized(msg->dn),
     4662                         GUID_string(tmp_ctx, dsa_guid),
     4663                         dom_sid_string(tmp_ctx, sid)));
    40134664                talloc_free(tmp_ctx);
    40144665                return ldb_operr(ldb);
     
    42174868}
    42184869
     4870
     4871/*
     4872  map an ldb error code to an approximate NTSTATUS code
     4873 */
     4874NTSTATUS dsdb_ldb_err_to_ntstatus(int err)
     4875{
     4876        switch (err) {
     4877        case LDB_SUCCESS:
     4878                return NT_STATUS_OK;
     4879
     4880        case LDB_ERR_PROTOCOL_ERROR:
     4881                return NT_STATUS_DEVICE_PROTOCOL_ERROR;
     4882
     4883        case LDB_ERR_TIME_LIMIT_EXCEEDED:
     4884                return NT_STATUS_IO_TIMEOUT;
     4885
     4886        case LDB_ERR_SIZE_LIMIT_EXCEEDED:
     4887                return NT_STATUS_BUFFER_TOO_SMALL;
     4888
     4889        case LDB_ERR_COMPARE_FALSE:
     4890        case LDB_ERR_COMPARE_TRUE:
     4891                return NT_STATUS_REVISION_MISMATCH;
     4892
     4893        case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED:
     4894                return NT_STATUS_NOT_SUPPORTED;
     4895
     4896        case LDB_ERR_STRONG_AUTH_REQUIRED:
     4897        case LDB_ERR_CONFIDENTIALITY_REQUIRED:
     4898        case LDB_ERR_SASL_BIND_IN_PROGRESS:
     4899        case LDB_ERR_INAPPROPRIATE_AUTHENTICATION:
     4900        case LDB_ERR_INVALID_CREDENTIALS:
     4901        case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
     4902        case LDB_ERR_UNWILLING_TO_PERFORM:
     4903                return NT_STATUS_ACCESS_DENIED;
     4904
     4905        case LDB_ERR_NO_SUCH_OBJECT:
     4906                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
     4907
     4908        case LDB_ERR_REFERRAL:
     4909        case LDB_ERR_NO_SUCH_ATTRIBUTE:
     4910                return NT_STATUS_NOT_FOUND;
     4911
     4912        case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION:
     4913                return NT_STATUS_NOT_SUPPORTED;
     4914
     4915        case LDB_ERR_ADMIN_LIMIT_EXCEEDED:
     4916                return NT_STATUS_BUFFER_TOO_SMALL;
     4917
     4918        case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE:
     4919        case LDB_ERR_INAPPROPRIATE_MATCHING:
     4920        case LDB_ERR_CONSTRAINT_VIOLATION:
     4921        case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
     4922        case LDB_ERR_INVALID_DN_SYNTAX:
     4923        case LDB_ERR_NAMING_VIOLATION:
     4924        case LDB_ERR_OBJECT_CLASS_VIOLATION:
     4925        case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF:
     4926        case LDB_ERR_NOT_ALLOWED_ON_RDN:
     4927                return NT_STATUS_INVALID_PARAMETER;
     4928
     4929        case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
     4930        case LDB_ERR_ENTRY_ALREADY_EXISTS:
     4931                return NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS;
     4932
     4933        case LDB_ERR_BUSY:
     4934                return NT_STATUS_NETWORK_BUSY;
     4935
     4936        case LDB_ERR_ALIAS_PROBLEM:
     4937        case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM:
     4938        case LDB_ERR_UNAVAILABLE:
     4939        case LDB_ERR_LOOP_DETECT:
     4940        case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED:
     4941        case LDB_ERR_AFFECTS_MULTIPLE_DSAS:
     4942        case LDB_ERR_OTHER:
     4943        case LDB_ERR_OPERATIONS_ERROR:
     4944                break;
     4945        }
     4946        return NT_STATUS_UNSUCCESSFUL;
     4947}
     4948
     4949
     4950/*
     4951  create a new naming context that will hold a partial replica
     4952 */
     4953int dsdb_create_partial_replica_NC(struct ldb_context *ldb,  struct ldb_dn *dn)
     4954{
     4955        TALLOC_CTX *tmp_ctx = talloc_new(ldb);
     4956        struct ldb_message *msg;
     4957        int ret;
     4958
     4959        msg = ldb_msg_new(tmp_ctx);
     4960        if (msg == NULL) {
     4961                talloc_free(tmp_ctx);
     4962                return ldb_oom(ldb);
     4963        }
     4964
     4965        msg->dn = dn;
     4966        ret = ldb_msg_add_string(msg, "objectClass", "top");
     4967        if (ret != LDB_SUCCESS) {
     4968                talloc_free(tmp_ctx);
     4969                return ldb_oom(ldb);
     4970        }
     4971
     4972        /* [MS-DRSR] implies that we should only add the 'top'
     4973         * objectclass, but that would cause lots of problems with our
     4974         * objectclass code as top is not structural, so we add
     4975         * 'domainDNS' as well to keep things sane. We're expecting
     4976         * this new NC to be of objectclass domainDNS after
     4977         * replication anyway
     4978         */
     4979        ret = ldb_msg_add_string(msg, "objectClass", "domainDNS");
     4980        if (ret != LDB_SUCCESS) {
     4981                talloc_free(tmp_ctx);
     4982                return ldb_oom(ldb);
     4983        }
     4984
     4985        ret = ldb_msg_add_fmt(msg, "instanceType", "%u",
     4986                              INSTANCE_TYPE_IS_NC_HEAD|
     4987                              INSTANCE_TYPE_NC_ABOVE|
     4988                              INSTANCE_TYPE_UNINSTANT);
     4989        if (ret != LDB_SUCCESS) {
     4990                talloc_free(tmp_ctx);
     4991                return ldb_oom(ldb);
     4992        }
     4993
     4994        ret = dsdb_add(ldb, msg, DSDB_MODIFY_PARTIAL_REPLICA);
     4995        if (ret != LDB_SUCCESS && ret != LDB_ERR_ENTRY_ALREADY_EXISTS) {
     4996                DEBUG(0,("Failed to create new NC for %s - %s (%s)\n",
     4997                         ldb_dn_get_linearized(dn),
     4998                         ldb_errstring(ldb), ldb_strerror(ret)));
     4999                talloc_free(tmp_ctx);
     5000                return ret;
     5001        }
     5002
     5003        DEBUG(1,("Created new NC for %s\n", ldb_dn_get_linearized(dn)));
     5004
     5005        talloc_free(tmp_ctx);
     5006        return LDB_SUCCESS;
     5007}
     5008
     5009/**
     5010  build a GUID from a string
     5011*/
     5012_PUBLIC_ NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid)
     5013{
     5014        NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
     5015        uint32_t time_low;
     5016        uint32_t time_mid, time_hi_and_version;
     5017        uint32_t clock_seq[2];
     5018        uint32_t node[6];
     5019        int i;
     5020
     5021        if (s == NULL) {
     5022                return NT_STATUS_INVALID_PARAMETER;
     5023        }
     5024
     5025        if (11 == sscanf(s, "%08x-%04x%04x-%02x%02x%02x%02x-%02x%02x%02x%02x",
     5026                         &time_low, &time_mid, &time_hi_and_version,
     5027                         &clock_seq[0], &clock_seq[1],
     5028                         &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
     5029                status = NT_STATUS_OK;
     5030        }
     5031
     5032        if (!NT_STATUS_IS_OK(status)) {
     5033                return status;
     5034        }
     5035
     5036        guid->time_low = time_low;
     5037        guid->time_mid = time_mid;
     5038        guid->time_hi_and_version = time_hi_and_version;
     5039        guid->clock_seq[0] = clock_seq[0];
     5040        guid->clock_seq[1] = clock_seq[1];
     5041        for (i=0;i<6;i++) {
     5042                guid->node[i] = node[i];
     5043        }
     5044
     5045        return NT_STATUS_OK;
     5046}
     5047
     5048_PUBLIC_ char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
     5049{
     5050        return talloc_asprintf(mem_ctx,
     5051                               "%08x-%04x%04x-%02x%02x%02x%02x-%02x%02x%02x%02x",
     5052                               guid->time_low, guid->time_mid,
     5053                               guid->time_hi_and_version,
     5054                               guid->clock_seq[0],
     5055                               guid->clock_seq[1],
     5056                               guid->node[0], guid->node[1],
     5057                               guid->node[2], guid->node[3],
     5058                               guid->node[4], guid->node[5]);
     5059}
     5060
     5061/*
     5062 * Return the effective badPwdCount
     5063 *
     5064 * This requires that the user_msg have (if present):
     5065 *  - badPasswordTime
     5066 *  - badPwdCount
     5067 *
     5068 * This also requires that the domain_msg have (if present):
     5069 *  - lockOutObservationWindow
     5070 */
     5071static int dsdb_effective_badPwdCount(struct ldb_message *user_msg,
     5072                                      int64_t lockOutObservationWindow,
     5073                                      NTTIME now)
     5074{
     5075        int64_t badPasswordTime;
     5076        badPasswordTime = ldb_msg_find_attr_as_int64(user_msg, "badPasswordTime", 0);
     5077
     5078        if (badPasswordTime - lockOutObservationWindow >= now) {
     5079                return ldb_msg_find_attr_as_int(user_msg, "badPwdCount", 0);
     5080        } else {
     5081                return 0;
     5082        }
     5083}
     5084
     5085/*
     5086 * Return the effective badPwdCount
     5087 *
     5088 * This requires that the user_msg have (if present):
     5089 *  - badPasswordTime
     5090 *  - badPwdCount
     5091 *
     5092 */
     5093int samdb_result_effective_badPwdCount(struct ldb_context *sam_ldb,
     5094                                       TALLOC_CTX *mem_ctx,
     5095                                       struct ldb_dn *domain_dn,
     5096                                       struct ldb_message *user_msg)
     5097{
     5098        struct timeval tv_now = timeval_current();
     5099        NTTIME now = timeval_to_nttime(&tv_now);
     5100        int64_t lockOutObservationWindow = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn,
     5101                                                              "lockOutObservationWindow", NULL);
     5102        return dsdb_effective_badPwdCount(user_msg, lockOutObservationWindow, now);
     5103}
     5104
     5105/*
     5106 * Prepare an update to the badPwdCount and associated attributes.
     5107 *
     5108 * This requires that the user_msg have (if present):
     5109 *  - objectSid
     5110 *  - badPasswordTime
     5111 *  - badPwdCount
     5112 *
     5113 * This also requires that the domain_msg have (if present):
     5114 *  - pwdProperties
     5115 *  - lockoutThreshold
     5116 *  - lockOutObservationWindow
     5117 */
     5118NTSTATUS dsdb_update_bad_pwd_count(TALLOC_CTX *mem_ctx,
     5119                                   struct ldb_context *sam_ctx,
     5120                                   struct ldb_message *user_msg,
     5121                                   struct ldb_message *domain_msg,
     5122                                   struct ldb_message **_mod_msg)
     5123{
     5124        int i, ret, badPwdCount;
     5125        int64_t lockoutThreshold, lockOutObservationWindow;
     5126        struct dom_sid *sid;
     5127        struct timeval tv_now = timeval_current();
     5128        NTTIME now = timeval_to_nttime(&tv_now);
     5129        NTSTATUS status;
     5130        uint32_t pwdProperties, rid = 0;
     5131        struct ldb_message *mod_msg;
     5132
     5133        sid = samdb_result_dom_sid(mem_ctx, user_msg, "objectSid");
     5134
     5135        pwdProperties = ldb_msg_find_attr_as_uint(domain_msg,
     5136                                                  "pwdProperties", -1);
     5137        if (sid && !(pwdProperties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)) {
     5138                status = dom_sid_split_rid(NULL, sid, NULL, &rid);
     5139                if (!NT_STATUS_IS_OK(status)) {
     5140                        /*
     5141                         * This can't happen anyway, but always try
     5142                         * and update the badPwdCount on failure
     5143                         */
     5144                        rid = 0;
     5145                }
     5146        }
     5147        TALLOC_FREE(sid);
     5148
     5149        /*
     5150         * Work out if we are doing password lockout on the domain.
     5151         * Also, the built in administrator account is exempt:
     5152         * http://msdn.microsoft.com/en-us/library/windows/desktop/aa375371%28v=vs.85%29.aspx
     5153         */
     5154        lockoutThreshold = ldb_msg_find_attr_as_int(domain_msg,
     5155                                                    "lockoutThreshold", 0);
     5156        if (lockoutThreshold == 0 || (rid == DOMAIN_RID_ADMINISTRATOR)) {
     5157                DEBUG(5, ("Not updating badPwdCount on %s after wrong password\n",
     5158                          ldb_dn_get_linearized(user_msg->dn)));
     5159                return NT_STATUS_OK;
     5160        }
     5161
     5162        mod_msg = ldb_msg_new(mem_ctx);
     5163        if (mod_msg == NULL) {
     5164                return NT_STATUS_NO_MEMORY;
     5165        }
     5166        mod_msg->dn = ldb_dn_copy(mod_msg, user_msg->dn);
     5167        if (mod_msg->dn == NULL) {
     5168                TALLOC_FREE(mod_msg);
     5169                return NT_STATUS_NO_MEMORY;
     5170        }
     5171
     5172        lockOutObservationWindow = ldb_msg_find_attr_as_int64(domain_msg,
     5173                                                              "lockOutObservationWindow", 0);
     5174
     5175        badPwdCount = dsdb_effective_badPwdCount(user_msg, lockOutObservationWindow, now);
     5176
     5177        badPwdCount++;
     5178
     5179        ret = samdb_msg_add_int(sam_ctx, mod_msg, mod_msg, "badPwdCount", badPwdCount);
     5180        if (ret != LDB_SUCCESS) {
     5181                TALLOC_FREE(mod_msg);
     5182                return NT_STATUS_NO_MEMORY;
     5183        }
     5184        ret = samdb_msg_add_int64(sam_ctx, mod_msg, mod_msg, "badPasswordTime", now);
     5185        if (ret != LDB_SUCCESS) {
     5186                TALLOC_FREE(mod_msg);
     5187                return NT_STATUS_NO_MEMORY;
     5188        }
     5189
     5190        if (badPwdCount >= lockoutThreshold) {
     5191                ret = samdb_msg_add_int64(sam_ctx, mod_msg, mod_msg, "lockoutTime", now);
     5192                if (ret != LDB_SUCCESS) {
     5193                        TALLOC_FREE(mod_msg);
     5194                        return NT_STATUS_NO_MEMORY;
     5195                }
     5196                DEBUG(5, ("Locked out user %s after %d wrong passwords\n",
     5197                          ldb_dn_get_linearized(user_msg->dn), badPwdCount));
     5198        } else {
     5199                DEBUG(5, ("Updated badPwdCount on %s after %d wrong passwords\n",
     5200                          ldb_dn_get_linearized(user_msg->dn), badPwdCount));
     5201        }
     5202
     5203        /* mark all the message elements as LDB_FLAG_MOD_REPLACE */
     5204        for (i=0; i< mod_msg->num_elements; i++) {
     5205                mod_msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
     5206        }
     5207
     5208        *_mod_msg = mod_msg;
     5209        return NT_STATUS_OK;
     5210}
     5211
     5212/**
     5213 * Sets defaults for a User object
     5214 * List of default attributes set:
     5215 *      accountExpires, badPasswordTime, badPwdCount,
     5216 *      codePage, countryCode, lastLogoff, lastLogon
     5217 *      logonCount, pwdLastSet
     5218 */
     5219int dsdb_user_obj_set_defaults(struct ldb_context *ldb, struct ldb_message *usr_obj)
     5220{
     5221        int i, ret;
     5222        const struct attribute_values {
     5223                const char *name;
     5224                const char *value;
     5225        } map[] = {
     5226                {
     5227                        .name = "accountExpires",
     5228                        .value = "9223372036854775807"
     5229                },
     5230                {
     5231                        .name = "badPasswordTime",
     5232                        .value = "0"
     5233                },
     5234                {
     5235                        .name = "badPwdCount",
     5236                        .value = "0"
     5237                },
     5238                {
     5239                        .name = "codePage",
     5240                        .value = "0"
     5241                },
     5242                {
     5243                        .name = "countryCode",
     5244                        .value = "0"
     5245                },
     5246                {
     5247                        .name = "lastLogoff",
     5248                        .value = "0"
     5249                },
     5250                {
     5251                        .name = "lastLogon",
     5252                        .value = "0"
     5253                },
     5254                {
     5255                        .name = "logonCount",
     5256                        .value = "0"
     5257                },
     5258                {
     5259                        .name = "pwdLastSet",
     5260                        .value = "0"
     5261                }
     5262        };
     5263
     5264        for (i = 0; i < ARRAY_SIZE(map); i++) {
     5265                ret = samdb_find_or_add_attribute(ldb, usr_obj,
     5266                                                  map[i].name, map[i].value);
     5267                if (ret != LDB_SUCCESS) {
     5268                        return ret;
     5269                }
     5270        }
     5271
     5272        return LDB_SUCCESS;
     5273}
     5274
     5275/**
     5276 * Sets 'sAMAccountType on user object based on userAccountControl
     5277 * @param ldb Current ldb_context
     5278 * @param usr_obj ldb_message representing User object
     5279 * @param user_account_control Value for userAccountControl flags
     5280 * @param account_type_p Optional pointer to account_type to return
     5281 * @return LDB_SUCCESS or LDB_ERR* code on failure
     5282 */
     5283int dsdb_user_obj_set_account_type(struct ldb_context *ldb, struct ldb_message *usr_obj,
     5284                                   uint32_t user_account_control, uint32_t *account_type_p)
     5285{
     5286        int ret;
     5287        uint32_t account_type;
     5288        struct ldb_message_element *el;
     5289
     5290        account_type = ds_uf2atype(user_account_control);
     5291        if (account_type == 0) {
     5292                ldb_set_errstring(ldb, "dsdb: Unrecognized account type!");
     5293                return LDB_ERR_UNWILLING_TO_PERFORM;
     5294        }
     5295        ret = samdb_msg_add_uint(ldb, usr_obj, usr_obj,
     5296                                 "sAMAccountType",
     5297                                 account_type);
     5298        if (ret != LDB_SUCCESS) {
     5299                return ret;
     5300        }
     5301        el = ldb_msg_find_element(usr_obj, "sAMAccountType");
     5302        el->flags = LDB_FLAG_MOD_REPLACE;
     5303
     5304        if (account_type_p) {
     5305                *account_type_p = account_type;
     5306        }
     5307
     5308        return LDB_SUCCESS;
     5309}
     5310
     5311/**
     5312 * Determine and set primaryGroupID based on userAccountControl value
     5313 * @param ldb Current ldb_context
     5314 * @param usr_obj ldb_message representing User object
     5315 * @param user_account_control Value for userAccountControl flags
     5316 * @param group_rid_p Optional pointer to group RID to return
     5317 * @return LDB_SUCCESS or LDB_ERR* code on failure
     5318 */
     5319int dsdb_user_obj_set_primary_group_id(struct ldb_context *ldb, struct ldb_message *usr_obj,
     5320                                       uint32_t user_account_control, uint32_t *group_rid_p)
     5321{
     5322        int ret;
     5323        uint32_t rid;
     5324        struct ldb_message_element *el;
     5325
     5326        rid = ds_uf2prim_group_rid(user_account_control);
     5327
     5328        ret = samdb_msg_add_uint(ldb, usr_obj, usr_obj,
     5329                                 "primaryGroupID", rid);
     5330        if (ret != LDB_SUCCESS) {
     5331                return ret;
     5332        }
     5333        el = ldb_msg_find_element(usr_obj, "primaryGroupID");
     5334        el->flags = LDB_FLAG_MOD_REPLACE;
     5335
     5336        if (group_rid_p) {
     5337                *group_rid_p = rid;
     5338        }
     5339
     5340        return LDB_SUCCESS;
     5341}
  • vendor/current/source4/dsdb/common/util.h

    r740 r988  
    2020*/
    2121
     22#ifndef __DSDB_COMMON_UTIL_H__
     23#define __DSDB_COMMON_UTIL_H__
     24
    2225/*
    2326   flags for dsdb_request_add_controls(). For the module functions,
     
    3639#define DSDB_SEARCH_SHOW_RECYCLED             0x0400
    3740#define DSDB_PROVISION                        0x0800
     41#define DSDB_BYPASS_PASSWORD_HASH             0x1000
     42#define DSDB_SEARCH_NO_GLOBAL_CATALOG         0x2000
     43#define DSDB_MODIFY_PARTIAL_REPLICA           0x4000
     44#define DSDB_PASSWORD_BYPASS_LAST_SET         0x8000
    3845
    3946bool is_attr_in_list(const char * const * attrs, const char *attr);
    4047
    4148#define DSDB_SECRET_ATTRIBUTES_EX(sep) \
     49        "pekList" sep \
     50        "msDS-ExecuteScriptPassword" sep \
    4251        "currentValue" sep \
    4352        "dBCSPwd" sep \
     
    5059        "trustAuthIncoming" sep \
    5160        "trustAuthOutgoing" sep \
    52         "unicodePwd"
     61        "unicodePwd" sep \
     62        "clearTextPassword"
    5363
    5464#define DSDB_SECRET_ATTRIBUTES_COMMA ,
    5565#define DSDB_SECRET_ATTRIBUTES DSDB_SECRET_ATTRIBUTES_EX(DSDB_SECRET_ATTRIBUTES_COMMA)
     66
     67struct GUID;
     68
     69char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid);
     70NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid);
     71
     72#endif /* __DSDB_COMMON_UTIL_H__ */
  • vendor/current/source4/dsdb/common/util_groups.c

    r740 r988  
    127127        }
    128128
     129        /*
     130         * We have the problem with the caller creating a <SID=S-....>
     131         * DN for ForeignSecurityPrincipals as they also have
     132         * duplicate objects with the SAME SID under CN=Configuration.
     133         * This causes a SID= DN to fail with NO_SUCH_OBJECT on Samba
     134         * and on Windows.  So, we allow this to fail, and
     135         * double-check if we can find it with a search in the main
     136         * domain partition.
     137         */
     138        if (ret == LDB_ERR_NO_SUCH_OBJECT && only_childs) {
     139                char *sid_string = dom_sid_string(tmp_ctx,
     140                                                  &sid);
     141                if (!sid_string) {
     142                        talloc_free(tmp_ctx);
     143                        return NT_STATUS_OK;
     144                }
     145
     146                ret = dsdb_search(sam_ctx, tmp_ctx, &res,
     147                                  ldb_get_default_basedn(sam_ctx),
     148                                  LDB_SCOPE_SUBTREE,
     149                                  attrs, DSDB_SEARCH_SHOW_EXTENDED_DN,
     150                                  "(&(objectClass=foreignSecurityPrincipal)(objectSID=%s))",
     151                                  sid_string);
     152        }
     153
    129154        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    130155                talloc_free(tmp_ctx);
     
    150175                *res_sids = talloc_realloc(res_sids_ctx, *res_sids,
    151176                        struct dom_sid, *num_res_sids + 1);
    152                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*res_sids, tmp_ctx);
     177                if (*res_sids == NULL) {
     178                        TALLOC_FREE(tmp_ctx);
     179                        return NT_STATUS_NO_MEMORY;
     180                }
    153181                (*res_sids)[*num_res_sids] = sid;
    154182                ++(*num_res_sids);
  • vendor/current/source4/dsdb/common/util_samr.c

    r740 r988  
    3737                       const char *account_name,
    3838                       uint32_t acct_flags,
     39                       const struct dom_sid *forced_sid,
    3940                       struct dom_sid **sid,
    4041                       struct ldb_dn **dn)
     
    7071                         ldb_errstring(ldb)));
    7172                talloc_free(tmp_ctx);
    72                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     73                return NT_STATUS_LOCK_NOT_GRANTED;
    7374        }
    7475
     
    109110                container = "CN=Users";
    110111                obj_class = "user";
    111 
     112                user_account_control = UF_NORMAL_ACCOUNT;
    112113        } else if (acct_flags == ACB_WSTRUST) {
    113114                if (cn_name[cn_name_len - 1] != '$') {
     
    118119                container = "CN=Computers";
    119120                obj_class = "computer";
     121                user_account_control = UF_WORKSTATION_TRUST_ACCOUNT;
    120122
    121123        } else if (acct_flags == ACB_SVRTRUST) {
     
    127129                container = "OU=Domain Controllers";
    128130                obj_class = "computer";
     131                user_account_control = UF_SERVER_TRUST_ACCOUNT;
     132        } else if (acct_flags == ACB_DOMTRUST) {
     133                DEBUG(3, ("Invalid account flags specified:  cannot create domain trusts via this interface (must use LSA CreateTrustedDomain calls\n"));
     134                ldb_transaction_cancel(ldb);
     135                talloc_free(tmp_ctx);
     136                return NT_STATUS_INVALID_PARAMETER;
    129137        } else {
     138                DEBUG(3, ("Invalid account flags specified 0x%08X, must be exactly one of \n"
     139                          "ACB_NORMAL (0x%08X) ACB_WSTRUST (0x%08X) or ACB_SVRTRUST (0x%08X)\n",
     140                          acct_flags,
     141                          ACB_NORMAL, ACB_WSTRUST, ACB_SVRTRUST));
    130142                ldb_transaction_cancel(ldb);
    131143                talloc_free(tmp_ctx);
    132144                return NT_STATUS_INVALID_PARAMETER;
    133145        }
     146
     147        user_account_control |= UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD;
    134148
    135149        /* add core elements to the ldb_message for the user */
     
    143157        ldb_msg_add_string(msg, "sAMAccountName", account_name);
    144158        ldb_msg_add_string(msg, "objectClass", obj_class);
     159        samdb_msg_add_uint(ldb, tmp_ctx, msg,
     160                           "userAccountControl",
     161                           user_account_control);
     162
     163        /* This is only here for migrations using pdb_samba4, the
     164         * caller and the samldb are responsible for ensuring it makes
     165         * sense */
     166        if (forced_sid) {
     167                ret = samdb_msg_add_dom_sid(ldb, msg, msg, "objectSID", forced_sid);
     168                if (ret != LDB_SUCCESS) {
     169                        ldb_transaction_cancel(ldb);
     170                        talloc_free(tmp_ctx);
     171                        return NT_STATUS_INTERNAL_ERROR;
     172                }
     173        }
    145174
    146175        /* create the user */
     
    195224        }
    196225
    197         /* Change the account control to be the correct account type.
    198          * The default is for a workstation account */
    199         user_account_control = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
    200         user_account_control = (user_account_control &
    201                                 ~(UF_NORMAL_ACCOUNT |
    202                                   UF_INTERDOMAIN_TRUST_ACCOUNT |
    203                                   UF_WORKSTATION_TRUST_ACCOUNT |
    204                                   UF_SERVER_TRUST_ACCOUNT));
    205         user_account_control |= ds_acb2uf(acct_flags);
    206 
    207         talloc_free(msg);
    208         msg = ldb_msg_new(tmp_ctx);
    209         if (msg == NULL) {
    210                 ldb_transaction_cancel(ldb);
    211                 talloc_free(tmp_ctx);
    212                 return NT_STATUS_NO_MEMORY;
    213         }
    214 
    215         msg->dn = account_dn;
    216 
    217         if (samdb_msg_add_uint(ldb, tmp_ctx, msg,
    218                                "userAccountControl",
    219                                user_account_control) != LDB_SUCCESS) {
    220                 ldb_transaction_cancel(ldb);
    221                 talloc_free(tmp_ctx);
    222                 return NT_STATUS_NO_MEMORY;
    223         }
    224 
    225         /* modify the samdb record */
    226         ret = dsdb_replace(ldb, msg, 0);
    227         if (ret != LDB_SUCCESS) {
    228                 DEBUG(0,("Failed to modify account record %s to set userAccountControl: %s\n",
    229                          ldb_dn_get_linearized(msg->dn),
    230                          ldb_errstring(ldb)));
    231                 ldb_transaction_cancel(ldb);
    232                 talloc_free(tmp_ctx);
    233 
    234                 /* we really need samdb.c to return NTSTATUS */
    235                 return NT_STATUS_UNSUCCESSFUL;
    236         }
    237 
    238226        ret = ldb_transaction_commit(ldb);
    239227        if (ret != LDB_SUCCESS) {
     
    245233        }
    246234        *dn = talloc_steal(mem_ctx, account_dn);
    247         *sid = talloc_steal(mem_ctx, account_sid);
     235        if (sid) {
     236                *sid = talloc_steal(mem_ctx, account_sid);
     237        }
    248238        talloc_free(tmp_ctx);
    249239        return NT_STATUS_OK;
     
    343333        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
    344334
     335        if (ldb_transaction_start(ldb) != LDB_SUCCESS) {
     336                DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(ldb)));
     337                return NT_STATUS_INTERNAL_ERROR;
     338        }
     339
    345340        /* Check if alias already exists */
    346341        name = samdb_search_string(ldb, tmp_ctx, NULL,
     
    351346        if (name != NULL) {
    352347                talloc_free(tmp_ctx);
     348                ldb_transaction_cancel(ldb);
    353349                return NT_STATUS_ALIAS_EXISTS;
    354350        }
     
    357353        if (msg == NULL) {
    358354                talloc_free(tmp_ctx);
     355                ldb_transaction_cancel(ldb);
    359356                return NT_STATUS_NO_MEMORY;
    360357        }
     
    365362        if (!msg->dn) {
    366363                talloc_free(tmp_ctx);
     364                ldb_transaction_cancel(ldb);
    367365                return NT_STATUS_NO_MEMORY;
    368366        }
     
    379377        case LDB_ERR_ENTRY_ALREADY_EXISTS:
    380378                talloc_free(tmp_ctx);
     379                ldb_transaction_cancel(ldb);
    381380                return NT_STATUS_ALIAS_EXISTS;
    382381        case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
    383382                talloc_free(tmp_ctx);
     383                ldb_transaction_cancel(ldb);
    384384                return NT_STATUS_ACCESS_DENIED;
    385385        default:
     
    388388                         ldb_errstring(ldb)));
    389389                talloc_free(tmp_ctx);
     390                ldb_transaction_cancel(ldb);
    390391                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    391392        }
     
    395396                                         msg->dn, "objectSid", NULL);
    396397
     398        if (ldb_transaction_commit(ldb) != LDB_SUCCESS) {
     399                DEBUG(0, ("Failed to commit transaction in dsdb_add_domain_alias(): %s\n",
     400                          ldb_errstring(ldb)));
     401                return NT_STATUS_INTERNAL_ERROR;
     402        }
     403
    397404        *dn = talloc_steal(mem_ctx, msg->dn);
    398405        *sid = talloc_steal(mem_ctx, alias_sid);
    399406        talloc_free(tmp_ctx);
     407
    400408
    401409        return NT_STATUS_OK;
Note: See TracChangeset for help on using the changeset viewer.