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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/auth/sam.c

    r740 r988  
    4242        "msDS-SupportedEncryptionTypes",        \
    4343        "supplementalCredentials",              \
     44        "msDS-AllowedToDelegateTo",             \
    4445                                                \
    4546        /* passwords */                         \
     
    4748        "unicodePwd",                           \
    4849                                                \
    49         "userAccountControl",                   \
     50        "userAccountControl",                   \
     51        "msDS-User-Account-Control-Computed",   \
    5052        "objectSid",                            \
    5153                                                \
     
    6567
    6668        "logonHours",
     69
     70        /*
     71         * To allow us to zero the badPwdCount and lockoutTime on
     72         * successful logon, without database churn
     73         */
     74        "lockoutTime",
    6775
    6876        /* check 'allowed workstations' */
     
    7684        "homeDrive",
    7785        "lastLogon",
     86        "lastLogonTimestamp",
    7887        "lastLogoff",
    7988        "accountExpires",
     
    8291        "primaryGroupID",
    8392        "memberOf",
     93        "badPasswordTime",
     94        "lmPwdHistory",
     95        "ntPwdHistory",
    8496        NULL,
    8597};
     
    165177        NTTIME acct_expiry;
    166178        NTTIME must_change_time;
    167 
    168         NTTIME now;
     179        struct timeval tv_now = timeval_current();
     180        NTTIME now = timeval_to_nttime(&tv_now);
     181
    169182        DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", name_for_logs));
    170183
    171         acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
     184        acct_flags = samdb_result_acct_flags(msg, "msDS-User-Account-Control-Computed");
    172185       
    173186        acct_expiry = samdb_result_account_expires(msg);
     
    193206
    194207        /* Test account expire time */
    195         unix_to_nt_time(&now, time(NULL));
    196208        if (now > acct_expiry) {
    197209                DEBUG(2,("authsam_account_ok: Account for user '%s' has expired.\n", name_for_logs));
     
    221233                bool invalid_ws = true;
    222234                int i;
    223                 const char **workstations = (const char **)str_list_make(mem_ctx, workstation_list, ",");
    224                
     235                char **workstations = str_list_make(mem_ctx, workstation_list, ",");
     236
    225237                for (i = 0; workstations && workstations[i]; i++) {
    226238                        DEBUG(10,("sam_account_ok: checking for workstation match '%s' and '%s'\n",
     
    298310
    299311        tmp_ctx = talloc_new(user_info_dc);
    300         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc, user_info_dc);
     312        if (user_info_dc == NULL) {
     313                TALLOC_FREE(user_info_dc);
     314                return NT_STATUS_NO_MEMORY;
     315        }
    301316
    302317        sids = talloc_array(user_info_dc, struct dom_sid, 2);
    303         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, user_info_dc);
     318        if (sids == NULL) {
     319                TALLOC_FREE(user_info_dc);
     320                return NT_STATUS_NO_MEMORY;
     321        }
    304322
    305323        num_sids = 2;
    306324
    307325        account_sid = samdb_result_dom_sid(user_info_dc, msg, "objectSid");
    308         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid, user_info_dc);
     326        if (account_sid == NULL) {
     327                TALLOC_FREE(user_info_dc);
     328                return NT_STATUS_NO_MEMORY;
     329        }
    309330
    310331        status = dom_sid_split_rid(tmp_ctx, account_sid, &domain_sid, NULL);
     
    322343         * on SamLogon validation info */
    323344        filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(!(groupType:1.2.840.113556.1.4.803:=%u))(groupType:1.2.840.113556.1.4.803:=%u))", GROUP_TYPE_BUILTIN_LOCAL_GROUP, GROUP_TYPE_SECURITY_ENABLED);
    324         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(filter, user_info_dc);
     345        if (filter == NULL) {
     346                TALLOC_FREE(user_info_dc);
     347                return NT_STATUS_NO_MEMORY;
     348        }
    325349
    326350        primary_group_string = dom_sid_string(tmp_ctx, &sids[PRIMARY_GROUP_SID_INDEX]);
    327         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_string, user_info_dc);
     351        if (primary_group_string == NULL) {
     352                TALLOC_FREE(user_info_dc);
     353                return NT_STATUS_NO_MEMORY;
     354        }
    328355
    329356        primary_group_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", primary_group_string);
    330         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_dn, user_info_dc);
     357        if (primary_group_dn == NULL) {
     358                TALLOC_FREE(user_info_dc);
     359                return NT_STATUS_NO_MEMORY;
     360        }
    331361
    332362        primary_group_blob = data_blob_string_const(primary_group_dn);
     
    372402
    373403        info->domain_name = talloc_strdup(info, domain_name);
    374         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->domain_name,
    375                 user_info_dc);
     404        if (info->domain_name == NULL) {
     405                TALLOC_FREE(user_info_dc);
     406                return NT_STATUS_NO_MEMORY;
     407        }
    376408
    377409        str = ldb_msg_find_attr_as_string(msg, "displayName", "");
    378410        info->full_name = talloc_strdup(info, str);
    379         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->full_name, user_info_dc);
     411        if (info->full_name == NULL) {
     412                TALLOC_FREE(user_info_dc);
     413                return NT_STATUS_NO_MEMORY;
     414        }
    380415
    381416        str = ldb_msg_find_attr_as_string(msg, "scriptPath", "");
    382417        info->logon_script = talloc_strdup(info, str);
    383         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_script,
    384                 user_info_dc);
     418        if (info->logon_script == NULL) {
     419                TALLOC_FREE(user_info_dc);
     420                return NT_STATUS_NO_MEMORY;
     421        }
    385422
    386423        str = ldb_msg_find_attr_as_string(msg, "profilePath", "");
    387424        info->profile_path = talloc_strdup(info, str);
    388         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->profile_path,
    389                 user_info_dc);
     425        if (info->profile_path == NULL) {
     426                TALLOC_FREE(user_info_dc);
     427                return NT_STATUS_NO_MEMORY;
     428        }
    390429
    391430        str = ldb_msg_find_attr_as_string(msg, "homeDirectory", "");
    392431        info->home_directory = talloc_strdup(info, str);
    393         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_directory,
    394                 user_info_dc);
     432        if (info->home_directory == NULL) {
     433                TALLOC_FREE(user_info_dc);
     434                return NT_STATUS_NO_MEMORY;
     435        }
    395436
    396437        str = ldb_msg_find_attr_as_string(msg, "homeDrive", "");
    397438        info->home_drive = talloc_strdup(info, str);
    398         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_drive, user_info_dc);
     439        if (info->home_drive == NULL) {
     440                TALLOC_FREE(user_info_dc);
     441                return NT_STATUS_NO_MEMORY;
     442        }
    399443
    400444        info->logon_server = talloc_strdup(info, netbios_name);
    401         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_server,
    402                 user_info_dc);
     445        if (info->logon_server == NULL) {
     446                TALLOC_FREE(user_info_dc);
     447                return NT_STATUS_NO_MEMORY;
     448        }
    403449
    404450        info->last_logon = samdb_result_nttime(msg, "lastLogon", 0);
     
    417463                0);
    418464
    419         info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx,
    420                                                           msg, domain_dn);
     465        info->acct_flags = samdb_result_acct_flags(msg, "msDS-User-Account-Control-Computed");
    421466
    422467        user_info_dc->user_session_key = data_blob_talloc(user_info_dc,
     
    424469                                                         user_sess_key.length);
    425470        if (user_sess_key.data) {
    426                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->user_session_key.data,
    427                                                   user_info_dc);
     471                if (user_info_dc->user_session_key.data == NULL) {
     472                        TALLOC_FREE(user_info_dc);
     473                        return NT_STATUS_NO_MEMORY;
     474                }
    428475        }
    429476        user_info_dc->lm_session_key = data_blob_talloc(user_info_dc,
     
    431478                                                       lm_sess_key.length);
    432479        if (lm_sess_key.data) {
    433                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->lm_session_key.data,
    434                                                   user_info_dc);
     480                if (user_info_dc->lm_session_key.data == NULL) {
     481                        TALLOC_FREE(user_info_dc);
     482                        return NT_STATUS_NO_MEMORY;
     483                }
    435484        }
    436485
     
    442491                                                   struct dom_sid,
    443492                                                   user_info_dc->num_sids+1);
    444                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc);
     493                if (user_info_dc->sids == NULL) {
     494                        TALLOC_FREE(user_info_dc);
     495                        return NT_STATUS_NO_MEMORY;
     496                }
    445497                user_info_dc->sids[user_info_dc->num_sids] = global_sid_Enterprise_DCs;
    446498                user_info_dc->num_sids++;
     
    454506                                                   struct dom_sid,
    455507                                                   user_info_dc->num_sids+1);
    456                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc);
     508                if (user_info_dc->sids == NULL) {
     509                        TALLOC_FREE(user_info_dc);
     510                        return NT_STATUS_NO_MEMORY;
     511                }
    457512                user_info_dc->sids[user_info_dc->num_sids] = *domain_sid;
    458513                sid_append_rid(&user_info_dc->sids[user_info_dc->num_sids],
     
    493548        /* pull the user attributes */
    494549        ret = dsdb_search_one(sam_ctx, tmp_ctx, msg, user_dn,
    495                               LDB_SCOPE_BASE, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)");
     550                              LDB_SCOPE_BASE, attrs,
     551                              DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_NO_GLOBAL_CATALOG,
     552                              "(objectClass=*)");
    496553        if (ret != LDB_SUCCESS) {
    497554                talloc_free(tmp_ctx);
     
    540597                /* pull the user attributes */
    541598                ret = dsdb_search_one(sam_ctx, tmp_ctx, &msg, user_dn,
    542                                       LDB_SCOPE_BASE, user_attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)");
     599                                      LDB_SCOPE_BASE, user_attrs,
     600                                      DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_NO_GLOBAL_CATALOG,
     601                                      "(objectClass=*)");
    543602                if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    544603                        talloc_free(tmp_ctx);
     
    586645        return NT_STATUS_OK;
    587646}
     647
     648NTSTATUS authsam_update_bad_pwd_count(struct ldb_context *sam_ctx,
     649                                      struct ldb_message *msg,
     650                                      struct ldb_dn *domain_dn)
     651{
     652        const char *attrs[] = { "lockoutThreshold",
     653                                "lockOutObservationWindow",
     654                                "lockoutDuration",
     655                                "pwdProperties",
     656                                NULL };
     657        int ret;
     658        NTSTATUS status;
     659        struct ldb_result *domain_res;
     660        struct ldb_message *msg_mod = NULL;
     661        TALLOC_CTX *mem_ctx;
     662
     663        mem_ctx = talloc_new(msg);
     664        if (mem_ctx == NULL) {
     665                return NT_STATUS_NO_MEMORY;
     666        }
     667
     668        ret = dsdb_search_dn(sam_ctx, mem_ctx, &domain_res, domain_dn, attrs, 0);
     669        if (ret != LDB_SUCCESS) {
     670                TALLOC_FREE(mem_ctx);
     671                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     672        }
     673
     674        status = dsdb_update_bad_pwd_count(mem_ctx, sam_ctx,
     675                                           msg, domain_res->msgs[0], &msg_mod);
     676        if (!NT_STATUS_IS_OK(status)) {
     677                TALLOC_FREE(mem_ctx);
     678                return status;
     679        }
     680
     681        if (msg_mod != NULL) {
     682                ret = dsdb_modify(sam_ctx, msg_mod, 0);
     683                if (ret != LDB_SUCCESS) {
     684                        DEBUG(0, ("Failed to update badPwdCount, badPasswordTime or set lockoutTime on %s: %s\n",
     685                                  ldb_dn_get_linearized(msg_mod->dn), ldb_errstring(sam_ctx)));
     686                        TALLOC_FREE(mem_ctx);
     687                        return NT_STATUS_INTERNAL_ERROR;
     688                }
     689        }
     690
     691        TALLOC_FREE(mem_ctx);
     692        return NT_STATUS_OK;
     693}
     694
     695
     696static NTSTATUS authsam_update_lastlogon_timestamp(struct ldb_context *sam_ctx,
     697                                            struct ldb_message *msg_mod,
     698                                            struct ldb_dn *domain_dn,
     699                                            NTTIME old_timestamp,
     700                                            NTTIME now)
     701{
     702        /*
     703         * We only set lastLogonTimestamp if the current value is older than
     704         * now - msDS-LogonTimeSyncInterval days.
     705         *
     706         * msDS-LogonTimeSyncInterval is an int32_t number of days, while
     707         * lastLogonTimestamp is in the 64 bit 100ns NTTIME format.
     708         *
     709         * The docs say: "the initial update, after the domain functional
     710         * level is raised to DS_BEHAVIOR_WIN2003 or higher, is calculated as
     711         * 14 days minus a random percentage of 5 days", but we aren't doing
     712         * that. The blogosphere seems to think that this randomised update
     713         * happens everytime, but [MS-ADA1] doesn't agree.
     714         *
     715         * Dochelp referred us to the following blog post:
     716         * http://blogs.technet.com/b/askds/archive/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works.aspx
     717         *
     718         * en msDS-LogonTimeSyncInterval is zero, the lastLogonTimestamp is
     719         * not changed.
     720         */
     721        static const char *attrs[] = { "msDS-LogonTimeSyncInterval",
     722                                        NULL };
     723        int ret;
     724        struct ldb_result *domain_res = NULL;
     725        TALLOC_CTX *mem_ctx = NULL;
     726        int32_t sync_interval;
     727        NTTIME sync_interval_nt;
     728
     729        mem_ctx = talloc_new(msg_mod);
     730        if (mem_ctx == NULL) {
     731                return NT_STATUS_NO_MEMORY;
     732        }
     733
     734        ret = dsdb_search_dn(sam_ctx, mem_ctx, &domain_res, domain_dn, attrs,
     735                             0);
     736        if (ret != LDB_SUCCESS || domain_res->count != 1) {
     737                TALLOC_FREE(mem_ctx);
     738                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     739        }
     740
     741        sync_interval = ldb_msg_find_attr_as_int(domain_res->msgs[0],
     742                                                 "msDS-LogonTimeSyncInterval",
     743                                                 14);
     744        DEBUG(5, ("sync interval is %d\n", sync_interval));
     745        if (sync_interval == 0){
     746                /*
     747                 * Setting msDS-LogonTimeSyncInterval to zero is how you ask
     748                 * that nothing happens here.
     749                 */
     750                TALLOC_FREE(mem_ctx);
     751                return NT_STATUS_OK;
     752        }
     753        else if (sync_interval >= 5){
     754                /*
     755                 * Subtract "a random percentage of 5" days. Presumably this
     756                 * percentage is between 0 and 100, and modulus is accurate
     757                 * enough.
     758                 */
     759                uint32_t r = generate_random() % 6;
     760                sync_interval -= r;
     761                DEBUG(5, ("randomised sync interval is %d (-%d)\n", sync_interval, r));
     762        }
     763        /* In the case where sync_interval < 5 there is no randomisation */
     764
     765        sync_interval_nt = sync_interval * 24LL * 3600LL * 10000000LL;
     766
     767        DEBUG(5, ("old timestamp is %lld, threshold %lld, diff %lld\n",
     768                  (long long int)old_timestamp,
     769                  (long long int)(now - sync_interval_nt),
     770                  (long long int)(old_timestamp - now + sync_interval_nt)));
     771
     772        if (old_timestamp > now){
     773                DEBUG(0, ("lastLogonTimestamp is in the future! (%lld > %lld)\n",
     774                          (long long int)old_timestamp, (long long int)now));
     775                /* then what? */
     776
     777        } else if (old_timestamp < now - sync_interval_nt){
     778                DEBUG(5, ("updating lastLogonTimestamp to %lld\n",
     779                          (long long int)now));
     780
     781                /* The time has come to update lastLogonTimestamp */
     782                ret = samdb_msg_add_int64(sam_ctx, msg_mod, msg_mod,
     783                                          "lastLogonTimestamp", now);
     784
     785                if (ret != LDB_SUCCESS) {
     786                        TALLOC_FREE(mem_ctx);
     787                        return NT_STATUS_NO_MEMORY;
     788                }
     789        }
     790        TALLOC_FREE(mem_ctx);
     791        return NT_STATUS_OK;
     792}
     793
     794
     795
     796/* Reset the badPwdCount to zero and update the lastLogon time. */
     797NTSTATUS authsam_logon_success_accounting(struct ldb_context *sam_ctx,
     798                                          const struct ldb_message *msg,
     799                                          struct ldb_dn *domain_dn,
     800                                          bool interactive_or_kerberos)
     801{
     802        int ret;
     803        NTSTATUS status;
     804        int badPwdCount;
     805        int64_t lockoutTime;
     806        struct ldb_message *msg_mod;
     807        TALLOC_CTX *mem_ctx;
     808        struct timeval tv_now;
     809        NTTIME now;
     810        NTTIME lastLogonTimestamp;
     811        NTTIME lastLogon;
     812
     813        lockoutTime = ldb_msg_find_attr_as_int64(msg, "lockoutTime", 0);
     814        badPwdCount = ldb_msg_find_attr_as_int(msg, "badPwdCount", 0);
     815        lastLogonTimestamp = \
     816                ldb_msg_find_attr_as_int64(msg, "lastLogonTimestamp", 0);
     817        lastLogon = ldb_msg_find_attr_as_int64(msg, "lastLogon", 0);
     818
     819        DEBUG(5, ("lastLogonTimestamp is %lld\n",
     820                  (long long int)lastLogonTimestamp));
     821
     822        mem_ctx = talloc_new(msg);
     823        if (mem_ctx == NULL) {
     824                return NT_STATUS_NO_MEMORY;
     825        }
     826        msg_mod = ldb_msg_new(mem_ctx);
     827        if (msg_mod == NULL) {
     828                TALLOC_FREE(mem_ctx);
     829                return NT_STATUS_NO_MEMORY;
     830        }
     831        msg_mod->dn = msg->dn;
     832
     833        if (lockoutTime != 0) {
     834                /*
     835                 * This implies "badPwdCount" = 0, see samldb_lockout_time()
     836                 */
     837                ret = samdb_msg_add_int(sam_ctx, msg_mod, msg_mod, "lockoutTime", 0);
     838                if (ret != LDB_SUCCESS) {
     839                        TALLOC_FREE(mem_ctx);
     840                        return NT_STATUS_NO_MEMORY;
     841                }
     842        } else if (badPwdCount != 0) {
     843                ret = samdb_msg_add_int(sam_ctx, msg_mod, msg_mod, "badPwdCount", 0);
     844                if (ret != LDB_SUCCESS) {
     845                        TALLOC_FREE(mem_ctx);
     846                        return NT_STATUS_NO_MEMORY;
     847                }
     848        }
     849
     850        tv_now = timeval_current();
     851        now = timeval_to_nttime(&tv_now);
     852
     853        if (interactive_or_kerberos || lastLogon == 0 ||
     854            (badPwdCount != 0 && lockoutTime == 0)) {
     855                ret = samdb_msg_add_int64(sam_ctx, msg_mod, msg_mod,
     856                                          "lastLogon", now);
     857                if (ret != LDB_SUCCESS) {
     858                        TALLOC_FREE(mem_ctx);
     859                        return NT_STATUS_NO_MEMORY;
     860                }
     861        }
     862        status = authsam_update_lastlogon_timestamp(sam_ctx, msg_mod, domain_dn,
     863                                                    lastLogonTimestamp, now);
     864        if (!NT_STATUS_IS_OK(status)) {
     865                TALLOC_FREE(mem_ctx);
     866                return NT_STATUS_NO_MEMORY;
     867        }
     868
     869        if (msg_mod->num_elements > 0) {
     870                ret = dsdb_replace(sam_ctx, msg_mod, 0);
     871                if (ret != LDB_SUCCESS) {
     872                        DEBUG(0, ("Failed to set badPwdCount and lockoutTime "
     873                                  "to 0 and/or  lastlogon to now (%lld) "
     874                                  "%s: %s\n", (long long int)now,
     875                                  ldb_dn_get_linearized(msg_mod->dn),
     876                                  ldb_errstring(sam_ctx)));
     877                        TALLOC_FREE(mem_ctx);
     878                        return NT_STATUS_INTERNAL_ERROR;
     879                }
     880        }
     881        TALLOC_FREE(mem_ctx);
     882        return NT_STATUS_OK;
     883}
Note: See TracChangeset for help on using the changeset viewer.