Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
17 edited
8 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/auth/auth.c

    r414 r745  
    1919
    2020#include "includes.h"
     21#include "auth.h"
     22#include "smbd/globals.h"
    2123
    2224#undef DBGC_CLASS
     
    2527static_decl_auth;
    2628
    27 static struct auth_init_function_entry *backends = NULL;
     29static struct auth_init_function_entry *auth_backends = NULL;
    2830
    2931static struct auth_init_function_entry *auth_find_backend_entry(const char *name);
     
    3133NTSTATUS smb_register_auth(int version, const char *name, auth_init_function init)
    3234{
    33         struct auth_init_function_entry *entry = backends;
     35        struct auth_init_function_entry *entry = auth_backends;
    3436
    3537        if (version != AUTH_INTERFACE_VERSION) {
     
    5557        entry->init = init;
    5658
    57         DLIST_ADD(backends, entry);
     59        DLIST_ADD(auth_backends, entry);
    5860        DEBUG(5,("Successfully added auth method '%s'\n", name));
    5961        return NT_STATUS_OK;
     
    6264static struct auth_init_function_entry *auth_find_backend_entry(const char *name)
    6365{
    64         struct auth_init_function_entry *entry = backends;
     66        struct auth_init_function_entry *entry = auth_backends;
    6567
    6668        while(entry) {
     
    7779****************************************************************************/
    7880
    79 static void get_ntlm_challenge(struct auth_context *auth_context,
     81static NTSTATUS get_ntlm_challenge(struct auth_context *auth_context,
    8082                               uint8_t chal[8])
    8183{
     
    8890                          auth_context->challenge_set_by));
    8991                memcpy(chal, auth_context->challenge.data, 8);
    90                 return;
     92                return NT_STATUS_OK;
    9193        }
    9294
     
    107109
    108110                challenge = auth_method->get_chal(auth_context, &auth_method->private_data,
    109                                         auth_context->mem_ctx);
     111                                                  auth_context);
    110112                if (!challenge.length) {
    111113                        DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n",
     
    123125
    124126                generate_random_buffer(tmp, sizeof(tmp));
    125                 auth_context->challenge = data_blob_talloc(auth_context->mem_ctx,
     127                auth_context->challenge = data_blob_talloc(auth_context,
    126128                                                           tmp, sizeof(tmp));
    127129
     
    139141
    140142        memcpy(chal, auth_context->challenge.data, 8);
     143        return NT_STATUS_OK;
    141144}
    142145
     
    214217
    215218        DEBUG(3, ("check_ntlm_password:  Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n",
    216                   user_info->client_domain, user_info->smb_name, user_info->wksta_name));
     219                  user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name));
    217220
    218221        DEBUG(3, ("check_ntlm_password:  mapped user is: [%s]\\[%s]@[%s]\n",
    219                   user_info->domain, user_info->internal_username, user_info->wksta_name));
     222                  user_info->mapped.domain_name, user_info->mapped.account_name, user_info->workstation_name));
    220223
    221224        if (auth_context->challenge.length != 8) {
     
    233236#ifdef DEBUG_PASSWORD
    234237        DEBUG(100, ("user_info has passwords of length %d and %d\n",
    235                     (int)user_info->lm_resp.length, (int)user_info->nt_resp.length));
     238                    (int)user_info->password.response.lanman.length, (int)user_info->password.response.nt.length));
    236239        DEBUG(100, ("lm:\n"));
    237         dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length);
     240        dump_data(100, user_info->password.response.lanman.data, user_info->password.response.lanman.length);
    238241        DEBUG(100, ("nt:\n"));
    239         dump_data(100, user_info->nt_resp.data, user_info->nt_resp.length);
     242        dump_data(100, user_info->password.response.nt.data, user_info->password.response.nt.length);
    240243#endif
    241244
    242245        /* This needs to be sorted:  If it doesn't match, what should we do? */
    243         if (!check_domain_match(user_info->smb_name, user_info->domain))
     246        if (!check_domain_match(user_info->client.account_name, user_info->mapped.domain_name))
    244247                return NT_STATUS_LOGON_FAILURE;
    245248
     
    247250                NTSTATUS result;
    248251
    249                 mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name, 
    250                                             user_info->domain, user_info->smb_name);
     252                mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name,
     253                                      user_info->mapped.domain_name, user_info->client.account_name);
    251254
    252255                result = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info);
     
    263266                if (NT_STATUS_IS_OK(nt_status)) {
    264267                        DEBUG(3, ("check_ntlm_password: %s authentication for user [%s] succeeded\n",
    265                                   auth_method->name, user_info->smb_name));
     268                                  auth_method->name, user_info->client.account_name));
    266269                } else {
    267270                        DEBUG(5, ("check_ntlm_password: %s authentication for user [%s] FAILED with error %s\n",
    268                                   auth_method->name, user_info->smb_name, nt_errstr(nt_status)));
     271                                  auth_method->name, user_info->client.account_name, nt_errstr(nt_status)));
    269272                }
    270273
     
    284287                        /* We might not be root if we are an RPC call */
    285288                        become_root();
    286                         nt_status = smb_pam_accountcheck(unix_username);
     289                        nt_status = smb_pam_accountcheck(
     290                                unix_username,
     291                                smbd_server_conn->client_id.name);
    287292                        unbecome_root();
    288293
     
    298303                if (NT_STATUS_IS_OK(nt_status)) {
    299304                        DEBUG((*server_info)->guest ? 5 : 2,
    300                               ("check_ntlm_password:  %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n", 
    301                                (*server_info)->guest ? "guest " : "", 
    302                                user_info->smb_name,
    303                                user_info->internal_username,
     305                              ("check_ntlm_password:  %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n",
     306                               (*server_info)->guest ? "guest " : "",
     307                               user_info->client.account_name,
     308                               user_info->mapped.account_name,
    304309                               unix_username));
    305310                }
     
    310315        /* failed authentication; check for guest lapping */
    311316
    312         DEBUG(2, ("check_ntlm_password:  Authentication for user [%s] -> [%s] FAILED with error %s\n", 
    313                   user_info->smb_name, user_info->internal_username,
     317        DEBUG(2, ("check_ntlm_password:  Authentication for user [%s] -> [%s] FAILED with error %s\n",
     318                  user_info->client.account_name, user_info->mapped.account_name,
    314319                  nt_errstr(nt_status)));
    315         ZERO_STRUCTP(server_info); 
     320        ZERO_STRUCTP(server_info);
    316321
    317322        return nt_status;
     
    322327***************************************************************************/
    323328
    324 static void free_auth_context(struct auth_context **auth_context)
    325 {
    326         auth_methods *auth_method;
    327 
    328         if (*auth_context) {
    329                 /* Free private data of context's authentication methods */
    330                 for (auth_method = (*auth_context)->auth_method_list; auth_method; auth_method = auth_method->next) {
    331                         TALLOC_FREE(auth_method->private_data);
    332                 }
    333 
    334                 talloc_destroy((*auth_context)->mem_ctx);
    335                 *auth_context = NULL;
    336         }
     329static int auth_context_destructor(void *ptr)
     330{
     331        struct auth_context *ctx = talloc_get_type(ptr, struct auth_context);
     332        struct auth_methods *am;
     333
     334
     335        /* Free private data of context's authentication methods */
     336        for (am = ctx->auth_method_list; am; am = am->next) {
     337                TALLOC_FREE(am->private_data);
     338        }
     339
     340        return 0;
    337341}
    338342
     
    341345***************************************************************************/
    342346
    343 static NTSTATUS make_auth_context(struct auth_context **auth_context)
    344 {
    345         TALLOC_CTX *mem_ctx;
    346 
    347         mem_ctx = talloc_init("authentication context");
    348 
    349         *auth_context = TALLOC_P(mem_ctx, struct auth_context);
    350         if (!*auth_context) {
     347static NTSTATUS make_auth_context(TALLOC_CTX *mem_ctx,
     348                                  struct auth_context **auth_context)
     349{
     350        struct auth_context *ctx;
     351
     352        ctx = talloc_zero(mem_ctx, struct auth_context);
     353        if (!ctx) {
    351354                DEBUG(0,("make_auth_context: talloc failed!\n"));
    352                 talloc_destroy(mem_ctx);
    353355                return NT_STATUS_NO_MEMORY;
    354356        }
    355         ZERO_STRUCTP(*auth_context);
    356 
    357         (*auth_context)->mem_ctx = mem_ctx;
    358         (*auth_context)->check_ntlm_password = check_ntlm_password;
    359         (*auth_context)->get_ntlm_challenge = get_ntlm_challenge;
    360         (*auth_context)->free = free_auth_context;
    361 
     357
     358        ctx->check_ntlm_password = check_ntlm_password;
     359        ctx->get_ntlm_challenge = get_ntlm_challenge;
     360
     361        talloc_set_destructor((TALLOC_CTX *)ctx, auth_context_destructor);
     362
     363        *auth_context = ctx;
    362364        return NT_STATUS_OK;
    363365}
     
    421423***************************************************************************/
    422424
    423 static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, char **text_list)
     425static NTSTATUS make_auth_context_text_list(TALLOC_CTX *mem_ctx,
     426                                            struct auth_context **auth_context,
     427                                            char **text_list)
    424428{
    425429        auth_methods *list = NULL;
     
    432436        }
    433437
    434         if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context)))
     438        nt_status = make_auth_context(mem_ctx, auth_context);
     439
     440        if (!NT_STATUS_IS_OK(nt_status)) {
    435441                return nt_status;
     442        }
    436443
    437444        for (;*text_list; text_list++) {
     
    450457***************************************************************************/
    451458
    452 NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
     459NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
     460                                     struct auth_context **auth_context)
    453461{
    454462        char **auth_method_list = NULL;
     
    521529        }
    522530
    523         nt_status = make_auth_context_text_list(auth_context,
     531        nt_status = make_auth_context_text_list(mem_ctx, auth_context,
    524532                                                auth_method_list);
    525533
     
    532540***************************************************************************/
    533541
    534 NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uchar chal[8])
     542NTSTATUS make_auth_context_fixed(TALLOC_CTX *mem_ctx,
     543                                 struct auth_context **auth_context,
     544                                 uchar chal[8])
    535545{
    536546        NTSTATUS nt_status;
    537         if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(auth_context))) {
     547        nt_status = make_auth_context_subsystem(mem_ctx, auth_context);
     548        if (!NT_STATUS_IS_OK(nt_status)) {
    538549                return nt_status;
    539550        }
    540551
    541         (*auth_context)->challenge = data_blob_talloc((*auth_context)->mem_ctx, chal, 8);
     552        (*auth_context)->challenge = data_blob_talloc(*auth_context, chal, 8);
    542553        (*auth_context)->challenge_set_by = "fixed";
    543554        return nt_status;
  • trunk/server/source3/auth/auth_builtin.c

    r414 r745  
    44   Copyright (C) Andrew Bartlett         2001-2002
    55   Copyright (C) Jelmer Vernooij              2002
    6    
     6
    77   This program is free software; you can redistribute it and/or modify
    88   it under the terms of the GNU General Public License as published by
    99   the Free Software Foundation; either version 3 of the License, or
    1010   (at your option) any later version.
    11    
     11
    1212   This program is distributed in the hope that it will be useful,
    1313   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1515   GNU General Public License for more details.
    16    
     16
    1717   You should have received a copy of the GNU General Public License
    1818   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2020
    2121#include "includes.h"
     22#include "auth.h"
    2223
    2324#undef DBGC_CLASS
     
    3536                                     void *my_private_data,
    3637                                     TALLOC_CTX *mem_ctx,
    37                                      const auth_usersupplied_info *user_info,
    38                                      auth_serversupplied_info **server_info)
     38                                     const struct auth_usersupplied_info *user_info,
     39                                     struct auth_serversupplied_info **server_info)
    3940{
    4041        /* mark this as 'not for me' */
    4142        NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
    4243
    43         if (!(user_info->internal_username
    44               && *user_info->internal_username)) {
     44        DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
     45
     46        if (!(user_info->mapped.account_name
     47              && *user_info->mapped.account_name)) {
    4548                nt_status = make_server_info_guest(NULL, server_info);
    4649        }
     
    5356static NTSTATUS auth_init_guest(struct auth_context *auth_context, const char *options, auth_methods **auth_method)
    5457{
    55         if (!make_auth_methods(auth_context, auth_method))
     58        struct auth_methods *result;
     59
     60        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     61        if (result == NULL) {
    5662                return NT_STATUS_NO_MEMORY;
     63        }
     64        result->auth = check_guest_security;
     65        result->name = "guest";
    5766
    58         (*auth_method)->auth = check_guest_security;
    59         (*auth_method)->name = "guest";
     67        *auth_method = result;
    6068        return NT_STATUS_OK;
    6169}
     
    7886                                                void *my_private_data,
    7987                                                TALLOC_CTX *mem_ctx,
    80                                                 const auth_usersupplied_info *user_info,
    81                                                 auth_serversupplied_info **server_info)
     88                                                const struct auth_usersupplied_info *user_info,
     89                                                struct auth_serversupplied_info **server_info)
    8290{
    8391        NTSTATUS nt_status;
    8492        fstring user;
    8593        long error_num;
    86         fstrcpy(user, user_info->smb_name);
    87        
     94
     95        DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
     96
     97        fstrcpy(user, user_info->client.account_name);
     98
    8899        if (strnequal("NT_STATUS", user, strlen("NT_STATUS"))) {
    89100                strupper_m(user);
     
    93104        strlower_m(user);
    94105        error_num = strtoul(user, NULL, 16);
    95        
     106
    96107        DEBUG(5,("check_name_to_ntstatus_security: Error for user %s was %lx\n", user, error_num));
    97108
    98109        nt_status = NT_STATUS(error_num);
    99        
     110
    100111        return nt_status;
    101112}
     
    105116static NTSTATUS auth_init_name_to_ntstatus(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
    106117{
    107         if (!make_auth_methods(auth_context, auth_method))
     118        struct auth_methods *result;
     119
     120        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     121        if (result == NULL) {
    108122                return NT_STATUS_NO_MEMORY;
     123        }
     124        result->auth = check_name_to_ntstatus_security;
     125        result->name = "name_to_ntstatus";
    109126
    110         (*auth_method)->auth = check_name_to_ntstatus_security;
    111         (*auth_method)->name = "name_to_ntstatus";
     127        *auth_method = result;
    112128        return NT_STATUS_OK;
    113129}
     
    131147                                               void *my_private_data,
    132148                                               TALLOC_CTX *mem_ctx,
    133                                                const auth_usersupplied_info *user_info,
    134                                                auth_serversupplied_info **server_info)
     149                                               const struct auth_usersupplied_info *user_info,
     150                                               struct auth_serversupplied_info **server_info)
    135151{
    136152        return NT_STATUS_NOT_IMPLEMENTED;
     
    150166
    151167
    152 /** Module initailisation function */
     168/** Module initialisation function */
    153169
    154170static NTSTATUS auth_init_fixed_challenge(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
    155171{
    156         if (!make_auth_methods(auth_context, auth_method))
     172        struct auth_methods *result;
     173
     174        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     175        if (result == NULL) {
    157176                return NT_STATUS_NO_MEMORY;
     177        }
     178        result->auth = check_fixed_challenge_security;
     179        result->get_chal = auth_get_fixed_challenge;
     180        result->name = "fixed_challenge";
    158181
    159         (*auth_method)->auth = check_fixed_challenge_security;
    160         (*auth_method)->get_chal = auth_get_fixed_challenge;
    161         (*auth_method)->name = "fixed_challenge";
     182        *auth_method = result;
    162183        return NT_STATUS_OK;
    163184}
  • trunk/server/source3/auth/auth_compat.c

    r414 r745  
    1919
    2020#include "includes.h"
     21#include "auth.h"
    2122
    2223extern struct auth_context *negprot_global_auth_context;
     
    3132
    3233/****************************************************************************
    33 check if a username/password is OK assuming the password is a 24 byte
    34 SMB hash
     34check if a username/password is OK assuming the password is in plaintext
    3535return True if the password is correct, False otherwise
    3636****************************************************************************/
    3737
    38 NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_password, auth_serversupplied_info **server_info)
     38NTSTATUS check_plaintext_password(const char *smb_name,
     39                                  DATA_BLOB plaintext_blob,
     40                                  struct auth_serversupplied_info **server_info)
    3941{
    4042        struct auth_context *plaintext_auth_context = NULL;
    41         auth_usersupplied_info *user_info = NULL;
     43        struct auth_usersupplied_info *user_info = NULL;
    4244        uint8_t chal[8];
    4345        NTSTATUS nt_status;
    44         if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
     46
     47        nt_status = make_auth_context_subsystem(talloc_tos(),
     48                                                &plaintext_auth_context);
     49        if (!NT_STATUS_IS_OK(nt_status)) {
    4550                return nt_status;
    4651        }
     
    5156        if (!make_user_info_for_reply(&user_info,
    5257                                      smb_name, lp_workgroup(), chal,
    53                                       plaintext_password)) {
     58                                      plaintext_blob)) {
    5459                return NT_STATUS_NO_MEMORY;
    5560        }
     
    5863                                                                user_info, server_info);
    5964
    60         (plaintext_auth_context->free)(&plaintext_auth_context);
     65        TALLOC_FREE(plaintext_auth_context);
    6166        free_user_info(&user_info);
    6267        return nt_status;
     
    6772                               const char *domain,
    6873                               DATA_BLOB lm_pwd,
    69                                DATA_BLOB nt_pwd,
    70                                DATA_BLOB plaintext_password,
    71                                bool encrypted)
     74                               DATA_BLOB nt_pwd)
    7275
    7376{
    7477        NTSTATUS nt_status;
    75         auth_serversupplied_info *server_info = NULL;
    76         if (encrypted) {
    77                 auth_usersupplied_info *user_info = NULL;
    78                 if (actx == NULL) {
    79                         return NT_STATUS_INTERNAL_ERROR;
    80                 }
    81                 make_user_info_for_reply_enc(&user_info, smb_name,
    82                                              domain,
    83                                              lm_pwd,
    84                                              nt_pwd);
    85                 nt_status = actx->check_ntlm_password(actx, user_info, &server_info);
    86                 free_user_info(&user_info);
    87         } else {
    88                 nt_status = check_plaintext_password(smb_name, plaintext_password, &server_info);
    89         }               
     78        struct auth_serversupplied_info *server_info = NULL;
     79        struct auth_usersupplied_info *user_info = NULL;
     80        if (actx == NULL) {
     81                return NT_STATUS_INTERNAL_ERROR;
     82        }
     83        make_user_info_for_reply_enc(&user_info, smb_name,
     84                                     domain,
     85                                     lm_pwd,
     86                                     nt_pwd);
     87        nt_status = actx->check_ntlm_password(actx, user_info, &server_info);
     88        free_user_info(&user_info);
    9089        TALLOC_FREE(server_info);
    9190        return nt_status;
     
    112111                 */
    113112                if (session_workgroup) {
    114                         if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, null_password, password_blob, null_password, encrypted))) {
     113                        if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, null_password, password_blob))) {
    115114                                return True;
    116115                        }
    117                         if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, password_blob, null_password, null_password, encrypted))) {
     116                        if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, password_blob, null_password))) {
    118117                                return True;
    119118                        }
    120119                }
    121120
    122                 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) {
     121                if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, password_blob))) {
    123122                        return True;
    124123                }
    125124
    126                 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) {
     125                if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), password_blob, null_password))) {
    127126                        return True;
    128127                }
    129128        } else {
    130                 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) {
     129                struct auth_serversupplied_info *server_info = NULL;
     130                NTSTATUS nt_status = check_plaintext_password(smb_name, password_blob, &server_info);
     131                TALLOC_FREE(server_info);
     132                if (NT_STATUS_IS_OK(nt_status)) {
    131133                        return True;
    132134                }
  • trunk/server/source3/auth/auth_domain.c

    r596 r745  
    44   Copyright (C) Andrew Tridgell 1992-1998
    55   Copyright (C) Andrew Bartlett 2001
    6    
     6
    77   This program is free software; you can redistribute it and/or modify
    88   it under the terms of the GNU General Public License as published by
    99   the Free Software Foundation; either version 3 of the License, or
    1010   (at your option) any later version.
    11    
     11
    1212   This program is distributed in the hope that it will be useful,
    1313   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1515   GNU General Public License for more details.
    16    
     16
    1717   You should have received a copy of the GNU General Public License
    1818   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2020
    2121#include "includes.h"
     22#include "auth.h"
    2223#include "../libcli/auth/libcli_auth.h"
     24#include "../librpc/gen_ndr/ndr_netlogon.h"
     25#include "rpc_client/cli_pipe.h"
     26#include "rpc_client/cli_netlogon.h"
     27#include "secrets.h"
     28#include "passdb.h"
     29#include "libsmb/libsmb.h"
    2330
    2431#undef DBGC_CLASS
     
    111118                                                const char *dc_name,
    112119                                                struct sockaddr_storage *dc_ss,
    113                                                 struct rpc_pipe_client **pipe_ret,
    114                                                 bool *retry)
     120                                                struct rpc_pipe_client **pipe_ret)
    115121{
    116122        NTSTATUS result;
     
    139145                return NT_STATUS_NO_LOGON_SERVERS;
    140146        }
    141        
     147
    142148        /* Attempt connection */
    143         *retry = True;
    144149        result = cli_full_connection(cli, global_myname(), dc_name, dc_ss, 0,
    145                 "IPC$", "IPC", "", "", "", 0, Undefined, retry);
     150                "IPC$", "IPC", "", "", "", 0, Undefined);
    146151
    147152        if (!NT_STATUS_IS_OK(result)) {
     
    252257
    253258static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
    254                                         const auth_usersupplied_info *user_info,
     259                                        const struct auth_usersupplied_info *user_info,
    255260                                        const char *domain,
    256261                                        uchar chal[8],
    257                                         auth_serversupplied_info **server_info,
     262                                        struct auth_serversupplied_info **server_info,
    258263                                        const char *dc_name,
    259264                                        struct sockaddr_storage *dc_ss)
     
    265270        NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
    266271        int i;
    267         bool retry = True;
    268272
    269273        /*
     
    276280
    277281        /* rety loop for robustness */
    278        
    279         for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++) {
     282
     283        for (i = 0; !NT_STATUS_IS_OK(nt_status) && (i < 3); i++) {
    280284                nt_status = connect_to_domain_password_server(&cli,
    281285                                                        domain,
    282286                                                        dc_name,
    283287                                                        dc_ss,
    284                                                         &netlogon_pipe,
    285                                                         &retry);
     288                                                        &netlogon_pipe);
    286289        }
    287290
     
    305308        nt_status = rpccli_netlogon_sam_network_logon(netlogon_pipe,
    306309                                                      mem_ctx,
    307                                                       user_info->logon_parameters,/* flags such as 'allow workstation logon' */
    308                                                       dc_name,                    /* server name */
    309                                                       user_info->smb_name,        /* user name logging on. */
    310                                                       user_info->client_domain,   /* domain name */
    311                                                       user_info->wksta_name,      /* workstation name */
    312                                                       chal,                       /* 8 byte challenge. */
    313                                                       3,                          /* validation level */
    314                                                       user_info->lm_resp,        /* lanman 24 byte response */
    315                                                       user_info->nt_resp,         /* nt 24 byte response */
    316                                                       &info3);                    /* info3 out */
     310                                                      user_info->logon_parameters,         /* flags such as 'allow workstation logon' */
     311                                                      dc_name,                             /* server name */
     312                                                      user_info->client.account_name,      /* user name logging on. */
     313                                                      user_info->client.domain_name,       /* domain name */
     314                                                      user_info->workstation_name,         /* workstation name */
     315                                                      chal,                                /* 8 byte challenge. */
     316                                                      3,                                   /* validation level */
     317                                                      user_info->password.response.lanman, /* lanman 24 byte response */
     318                                                      user_info->password.response.nt,     /* nt 24 byte response */
     319                                                      &info3);                             /* info3 out */
    317320
    318321        /* Let go as soon as possible so we avoid any potential deadlocks
    319322           with winbind lookup up users or groups. */
    320            
     323
    321324        TALLOC_FREE(mutex);
    322325
     
    324327                DEBUG(0,("domain_client_validate: unable to validate password "
    325328                         "for user %s in domain %s to Domain controller %s. "
    326                          "Error was %s.\n", user_info->smb_name,
    327                          user_info->client_domain, dc_name,
     329                         "Error was %s.\n", user_info->client.account_name,
     330                         user_info->client.domain_name, dc_name,
    328331                         nt_errstr(nt_status)));
    329332
     
    334337        } else {
    335338                nt_status = make_server_info_info3(mem_ctx,
    336                                                 user_info->smb_name,
    337                                                 domain,
    338                                                 server_info,
    339                                                 info3);
     339                                                   user_info->client.account_name,
     340                                                   domain,
     341                                                   server_info,
     342                                                   info3);
    340343
    341344                if (NT_STATUS_IS_OK(nt_status)) {
    342345                        (*server_info)->nss_token |= user_info->was_mapped;
    343 
    344                         if ( ! (*server_info)->guest) {
    345                                 /* if a real user check pam account restrictions */
    346                                 /* only really perfomed if "obey pam restriction" is true */
    347                                 nt_status = smb_pam_accountcheck((*server_info)->unix_name);
    348                                 if (  !NT_STATUS_IS_OK(nt_status)) {
    349                                         DEBUG(1, ("PAM account restriction prevents user login\n"));
    350                                         cli_shutdown(cli);
    351                                         TALLOC_FREE(info3);
    352                                         return nt_status;
    353                                 }
    354                         }
    355                 }
    356 
    357                 netsamlogon_cache_store(user_info->smb_name, info3);
    358                 TALLOC_FREE(info3);
     346                        netsamlogon_cache_store(user_info->client.account_name, info3);
     347                        TALLOC_FREE(info3);
     348                }
    359349        }
    360350
     
    374364                                        void *my_private_data,
    375365                                        TALLOC_CTX *mem_ctx,
    376                                         const auth_usersupplied_info *user_info,
    377                                         auth_serversupplied_info **server_info)
     366                                        const struct auth_usersupplied_info *user_info,
     367                                        struct auth_serversupplied_info **server_info)
    378368{
    379369        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
     
    393383        }
    394384
     385        DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
     386
    395387        /*
    396388         * Check that the requested domain is not our own machine name.
     
    399391         */
    400392
    401         if(strequal(get_global_sam_name(), user_info->domain)) {
     393        if(strequal(get_global_sam_name(), user_info->mapped.domain_name)) {
    402394                DEBUG(3,("check_ntdomain_security: Requested domain was for this machine.\n"));
    403395                return NT_STATUS_NOT_IMPLEMENTED;
     
    408400        if ( !get_dc_name(domain, NULL, dc_name, &dc_ss) ) {
    409401                DEBUG(5,("check_ntdomain_security: unable to locate a DC for domain %s\n",
    410                         user_info->domain));
     402                        user_info->mapped.domain_name));
    411403                return NT_STATUS_NO_LOGON_SERVERS;
    412404        }
    413        
     405
    414406        nt_status = domain_client_validate(mem_ctx,
    415407                                        user_info,
     
    419411                                        dc_name,
    420412                                        &dc_ss);
    421                
     413
    422414        return nt_status;
    423415}
     
    426418static NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
    427419{
    428         if (!make_auth_methods(auth_context, auth_method)) {
     420        struct auth_methods *result;
     421
     422        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     423        if (result == NULL) {
    429424                return NT_STATUS_NO_MEMORY;
    430425        }
    431 
    432         (*auth_method)->name = "ntdomain";
    433         (*auth_method)->auth = check_ntdomain_security;
     426        result->name = "ntdomain";
     427        result->auth = check_ntdomain_security;
     428
     429        *auth_method = result;
    434430        return NT_STATUS_OK;
    435431}
     
    443439                                           void *my_private_data,
    444440                                           TALLOC_CTX *mem_ctx,
    445                                            const auth_usersupplied_info *user_info,
    446                                            auth_serversupplied_info **server_info)
     441                                           const struct auth_usersupplied_info *user_info,
     442                                           struct auth_serversupplied_info **server_info)
    447443{
    448444        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
     
    457453        }
    458454
     455        DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
     456
    459457        /*
    460458         * Check that the requested domain is not our own machine name or domain name.
    461459         */
    462460
    463         if( strequal(get_global_sam_name(), user_info->domain)) {
     461        if( strequal(get_global_sam_name(), user_info->mapped.domain_name)) {
    464462                DEBUG(3,("check_trustdomain_security: Requested domain [%s] was for this machine.\n",
    465                         user_info->domain));
     463                        user_info->mapped.domain_name));
    466464                return NT_STATUS_NOT_IMPLEMENTED;
    467465        }
     
    471469           The logic is that if we know nothing about the domain, that
    472470           user is not known to us and does not exist */
    473        
    474         if ( !is_trusted_domain( user_info->domain ) )
     471
     472        if ( !is_trusted_domain( user_info->mapped.domain_name ) )
    475473                return NT_STATUS_NOT_IMPLEMENTED;
    476474
     
    480478         */
    481479
    482         if (!pdb_get_trusteddom_pw(user_info->domain, &trust_password,
     480        if (!pdb_get_trusteddom_pw(user_info->mapped.domain_name, &trust_password,
    483481                                   NULL, NULL)) {
    484482                DEBUG(0, ("check_trustdomain_security: could not fetch trust "
    485483                          "account password for domain %s\n",
    486                           user_info->domain));
     484                          user_info->mapped.domain_name));
    487485                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    488486        }
    489487
    490488#ifdef DEBUG_PASSWORD
    491         DEBUG(100, ("Trust password for domain %s is %s\n", user_info->domain,
     489        DEBUG(100, ("Trust password for domain %s is %s\n", user_info->mapped.domain_name,
    492490                    trust_password));
    493491#endif
     
    505503        /* use get_dc_name() for consistency even through we know that it will be
    506504           a netbios name */
    507            
    508         if ( !get_dc_name(user_info->domain, NULL, dc_name, &dc_ss) ) {
     505
     506        if ( !get_dc_name(user_info->mapped.domain_name, NULL, dc_name, &dc_ss) ) {
    509507                DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
    510                         user_info->domain));
     508                        user_info->mapped.domain_name));
    511509                return NT_STATUS_NO_LOGON_SERVERS;
    512510        }
    513        
     511
    514512        nt_status = domain_client_validate(mem_ctx,
    515                                         user_info,
    516                                         user_info->domain,
    517                                         (uchar *)auth_context->challenge.data,
    518                                         server_info,
    519                                         dc_name,
    520                                         &dc_ss);
     513                                           user_info,
     514                                           user_info->mapped.domain_name,
     515                                           (uchar *)auth_context->challenge.data,
     516                                           server_info,
     517                                           dc_name,
     518                                           &dc_ss);
    521519
    522520        return nt_status;
     
    526524static NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
    527525{
    528         if (!make_auth_methods(auth_context, auth_method)) {
     526        struct auth_methods *result;
     527
     528        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     529        if (result == NULL) {
    529530                return NT_STATUS_NO_MEMORY;
    530531        }
    531 
    532         (*auth_method)->name = "trustdomain";
    533         (*auth_method)->auth = check_trustdomain_security;
     532        result->name = "trustdomain";
     533        result->auth = check_trustdomain_security;
     534
     535        *auth_method = result;
    534536        return NT_STATUS_OK;
    535537}
  • trunk/server/source3/auth/auth_netlogond.c

    r596 r745  
    1919
    2020#include "includes.h"
     21#include "auth.h"
    2122#include "../libcli/auth/libcli_auth.h"
     23#include "../librpc/gen_ndr/ndr_netlogon.h"
     24#include "librpc/gen_ndr/ndr_schannel.h"
     25#include "rpc_client/cli_pipe.h"
     26#include "rpc_client/cli_netlogon.h"
     27#include "secrets.h"
     28#include "tldap.h"
     29#include "tldap_util.h"
    2230
    2331#undef DBGC_CLASS
    2432#define DBGC_CLASS DBGC_AUTH
     33
     34static bool secrets_store_local_schannel_creds(
     35        const struct netlogon_creds_CredentialState *creds)
     36{
     37        DATA_BLOB blob;
     38        enum ndr_err_code ndr_err;
     39        bool ret;
     40
     41        ndr_err = ndr_push_struct_blob(
     42                &blob, talloc_tos(), creds,
     43                (ndr_push_flags_fn_t)ndr_push_netlogon_creds_CredentialState);
     44        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     45                DEBUG(10, ("ndr_push_netlogon_creds_CredentialState failed: "
     46                           "%s\n", ndr_errstr(ndr_err)));
     47                return false;
     48        }
     49        ret = secrets_store(SECRETS_LOCAL_SCHANNEL_KEY,
     50                            blob.data, blob.length);
     51        data_blob_free(&blob);
     52        return ret;
     53}
     54
     55static struct netlogon_creds_CredentialState *
     56secrets_fetch_local_schannel_creds(TALLOC_CTX *mem_ctx)
     57{
     58        struct netlogon_creds_CredentialState *creds;
     59        enum ndr_err_code ndr_err;
     60        DATA_BLOB blob;
     61
     62        blob.data = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY,
     63                                             &blob.length);
     64        if (blob.data == NULL) {
     65                DEBUG(10, ("secrets_fetch failed\n"));
     66                return NULL;
     67        }
     68
     69        creds = talloc(mem_ctx, struct netlogon_creds_CredentialState);
     70        if (creds == NULL) {
     71                DEBUG(10, ("talloc failed\n"));
     72                SAFE_FREE(blob.data);
     73                return NULL;
     74        }
     75        ndr_err = ndr_pull_struct_blob(
     76                &blob, creds, creds,
     77                (ndr_pull_flags_fn_t)ndr_pull_netlogon_creds_CredentialState);
     78        SAFE_FREE(blob.data);
     79        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     80                DEBUG(10, ("ndr_pull_netlogon_creds_CredentialState failed: "
     81                           "%s\n", ndr_errstr(ndr_err)));
     82                TALLOC_FREE(creds);
     83                return NULL;
     84        }
     85
     86        return creds;
     87}
    2588
    2689static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx,
    2790                                   const struct auth_context *auth_context,
    2891                                   const char *ncalrpc_sockname,
    29                                    uint8_t schannel_key[16],
    30                                    const auth_usersupplied_info *user_info,
     92                                   struct netlogon_creds_CredentialState *creds,
     93                                   const struct auth_usersupplied_info *user_info,
    3194                                   struct netr_SamInfo3 **pinfo3,
    3295                                   NTSTATUS *schannel_bind_result)
    3396{
    3497        struct rpc_pipe_client *p = NULL;
    35         struct cli_pipe_auth_data *auth = NULL;
     98        struct pipe_auth_data *auth = NULL;
    3699        struct netr_SamInfo3 *info3 = NULL;
    37100        NTSTATUS status;
     
    47110        }
    48111
    49         /*
    50          * We have to fake a struct dcinfo, so that
    51          * rpccli_netlogon_sam_network_logon_ex can decrypt the session keys.
    52          */
    53 
    54         p->dc = netlogon_creds_client_init_session_key(p, schannel_key);
    55         if (p->dc == NULL) {
    56                 DEBUG(0, ("talloc failed\n"));
    57                 TALLOC_FREE(p);
    58                 return NT_STATUS_NO_MEMORY;
    59         }
     112        p->dc = creds;
    60113
    61114        status = rpccli_schannel_bind_data(p, lp_workgroup(),
     
    79132        status = rpccli_netlogon_sam_network_logon_ex(
    80133                p, p,
    81                 user_info->logon_parameters,/* flags such as 'allow
    82                                              * workstation logon' */
    83                 global_myname(),            /* server name */
    84                 user_info->smb_name,        /* user name logging on. */
    85                 user_info->client_domain,   /* domain name */
    86                 user_info->wksta_name,      /* workstation name */
     134                user_info->logon_parameters,           /* flags such as 'allow
     135                                                        * workstation logon' */
     136                global_myname(),                       /* server name */
     137                user_info->client.account_name,        /* user name logging on. */
     138                user_info->client.domain_name,         /* domain name */
     139                user_info->workstation_name,           /* workstation name */
    87140                (uchar *)auth_context->challenge.data, /* 8 byte challenge. */
    88                 3,                          /* validation level */
    89                 user_info->lm_resp,         /* lanman 24 byte response */
    90                 user_info->nt_resp,         /* nt 24 byte response */
    91                 &info3);                    /* info3 out */
     141                3,                                     /* validation level */
     142                user_info->password.response.lanman,   /* lanman 24 byte response */
     143                user_info->password.response.nt,       /* nt 24 byte response */
     144                &info3);                               /* info3 out */
    92145
    93146        DEBUG(10, ("rpccli_netlogon_sam_network_logon_ex returned %s\n",
     
    105158}
    106159
    107 static char *mymachinepw(TALLOC_CTX *mem_ctx)
    108 {
    109         fstring pwd;
    110         const char *script;
    111         char *to_free = NULL;
    112         ssize_t nread;
    113         int ret, fd;
    114 
    115         script = lp_parm_const_string(
    116                 GLOBAL_SECTION_SNUM, "auth_netlogond", "machinepwscript",
    117                 NULL);
    118 
    119         if (script == NULL) {
    120                 to_free = talloc_asprintf(talloc_tos(), "%s/%s",
    121                                           get_dyn_SBINDIR(), "mymachinepw");
    122                 script = to_free;
    123         }
    124         if (script == NULL) {
    125                 return NULL;
    126         }
    127 
    128         ret = smbrun(script, &fd);
    129         DEBUG(ret ? 0 : 3, ("mymachinepw: Running the command `%s' gave %d\n",
    130                             script, ret));
    131         TALLOC_FREE(to_free);
    132 
    133         if (ret != 0) {
    134                 return NULL;
    135         }
    136 
    137         nread = read(fd, pwd, sizeof(pwd)-1);
    138         close(fd);
    139 
    140         if (nread <= 0) {
    141                 DEBUG(3, ("mymachinepwd: Could not read password\n"));
    142                 return NULL;
    143         }
    144 
    145         pwd[nread] = '\0';
    146 
    147         if (pwd[nread-1] == '\n') {
    148                 pwd[nread-1] = '\0';
    149         }
    150 
    151         return talloc_strdup(mem_ctx, pwd);
     160static NTSTATUS get_ldapi_ctx(TALLOC_CTX *mem_ctx, struct tldap_context **pld)
     161{
     162        struct tldap_context *ld;
     163        struct sockaddr_un addr;
     164        char *sockaddr;
     165        int fd;
     166        NTSTATUS status;
     167        int res;
     168
     169        sockaddr = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
     170                                   lp_private_dir());
     171        if (sockaddr == NULL) {
     172                DEBUG(10, ("talloc failed\n"));
     173                return NT_STATUS_NO_MEMORY;
     174        }
     175
     176        ZERO_STRUCT(addr);
     177        addr.sun_family = AF_UNIX;
     178        strncpy(addr.sun_path, sockaddr, sizeof(addr.sun_path));
     179        TALLOC_FREE(sockaddr);
     180
     181        status = open_socket_out((struct sockaddr_storage *)(void *)&addr,
     182                                 0, 0, &fd);
     183        if (!NT_STATUS_IS_OK(status)) {
     184                DEBUG(10, ("Could not connect to %s: %s\n", addr.sun_path,
     185                           nt_errstr(status)));
     186                return status;
     187        }
     188        set_blocking(fd, false);
     189
     190        ld = tldap_context_create(mem_ctx, fd);
     191        if (ld == NULL) {
     192                close(fd);
     193                return NT_STATUS_NO_MEMORY;
     194        }
     195        res = tldap_fetch_rootdse(ld);
     196        if (res != TLDAP_SUCCESS) {
     197                DEBUG(10, ("tldap_fetch_rootdse failed: %s\n",
     198                           tldap_errstr(talloc_tos(), ld, res)));
     199                TALLOC_FREE(ld);
     200                return NT_STATUS_LDAP(res);
     201        }
     202        *pld = ld;
     203        return NT_STATUS_OK;;
     204}
     205
     206static NTSTATUS mymachinepw(uint8_t pwd[16])
     207{
     208        TALLOC_CTX *frame = talloc_stackframe();
     209        struct tldap_context *ld = NULL;
     210        struct tldap_message *rootdse, **msg;
     211        const char *attrs[1] = { "unicodePwd" };
     212        char *default_nc, *myname;
     213        int rc, num_msg;
     214        DATA_BLOB pwdblob;
     215        NTSTATUS status;
     216
     217        status = get_ldapi_ctx(talloc_tos(), &ld);
     218        if (!NT_STATUS_IS_OK(status)) {
     219                goto fail;
     220        }
     221        rootdse = tldap_rootdse(ld);
     222        if (rootdse == NULL) {
     223                DEBUG(10, ("Could not get rootdse\n"));
     224                status = NT_STATUS_INTERNAL_ERROR;
     225                goto fail;
     226        }
     227        default_nc = tldap_talloc_single_attribute(
     228                rootdse, "defaultNamingContext", talloc_tos());
     229        if (default_nc == NULL) {
     230                DEBUG(10, ("Could not get defaultNamingContext\n"));
     231                status = NT_STATUS_NO_MEMORY;
     232                goto fail;
     233        }
     234        DEBUG(10, ("default_nc = %s\n", default_nc));
     235
     236        myname = talloc_asprintf_strupper_m(talloc_tos(), "%s$",
     237                                            global_myname());
     238        if (myname == NULL) {
     239                DEBUG(10, ("talloc failed\n"));
     240                status = NT_STATUS_NO_MEMORY;
     241                goto fail;
     242        }
     243
     244        rc = tldap_search_fmt(
     245                ld, default_nc, TLDAP_SCOPE_SUB, attrs, ARRAY_SIZE(attrs), 0,
     246                talloc_tos(), &msg,
     247                "(&(sAMAccountName=%s)(objectClass=computer))", myname);
     248        if (rc != TLDAP_SUCCESS) {
     249                DEBUG(10, ("Could not retrieve our account: %s\n",
     250                           tldap_errstr(talloc_tos(), ld, rc)));
     251                status = NT_STATUS_LDAP(rc);
     252                goto fail;
     253        }
     254        num_msg = talloc_array_length(msg);
     255        if (num_msg != 1) {
     256                DEBUG(10, ("Got %d accounts, expected one\n", num_msg));
     257                status = NT_STATUS_INTERNAL_DB_CORRUPTION;
     258                goto fail;
     259        }
     260        if (!tldap_get_single_valueblob(msg[0], "unicodePwd", &pwdblob)) {
     261                char *dn = NULL;
     262                tldap_entry_dn(msg[0], &dn);
     263                DEBUG(10, ("No unicodePwd attribute in %s\n",
     264                           dn ? dn : "<unknown DN>"));
     265                status = NT_STATUS_INTERNAL_DB_CORRUPTION;
     266                goto fail;
     267        }
     268        if (pwdblob.length != 16) {
     269                DEBUG(10, ("Password hash hash has length %d, expected 16\n",
     270                           (int)pwdblob.length));
     271                status = NT_STATUS_INTERNAL_DB_CORRUPTION;
     272                goto fail;
     273        }
     274        memcpy(pwd, pwdblob.data, 16);
     275
     276fail:
     277        TALLOC_FREE(frame);
     278        return status;
    152279}
    153280
     
    155282                                         void *my_private_data,
    156283                                         TALLOC_CTX *mem_ctx,
    157                                          const auth_usersupplied_info *user_info,
    158                                          auth_serversupplied_info **server_info)
     284                                         const struct auth_usersupplied_info *user_info,
     285                                         struct auth_serversupplied_info **server_info)
    159286{
    160287        TALLOC_CTX *frame = talloc_stackframe();
    161288        struct netr_SamInfo3 *info3 = NULL;
    162289        struct rpc_pipe_client *p = NULL;
    163         struct cli_pipe_auth_data *auth = NULL;
     290        struct pipe_auth_data *auth = NULL;
    164291        uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
    165         char *plaintext_machinepw = NULL;
    166292        uint8_t machine_password[16];
    167         uint8_t schannel_key[16];
     293        struct netlogon_creds_CredentialState *creds;
    168294        NTSTATUS schannel_bind_result, status;
    169295        struct named_mutex *mutex = NULL;
    170296        const char *ncalrpcsock;
    171297
     298        DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
     299
    172300        ncalrpcsock = lp_parm_const_string(
    173301                GLOBAL_SECTION_SNUM, "auth_netlogond", "socket", NULL);
     
    183311        }
    184312
    185         if (!secrets_fetch_local_schannel_key(schannel_key)) {
     313        creds = secrets_fetch_local_schannel_creds(talloc_tos());
     314        if (creds == NULL) {
    186315                goto new_key;
    187316        }
    188317
    189318        status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock,
    190                                     schannel_key, user_info, &info3,
     319                                    creds, user_info, &info3,
    191320                                    &schannel_bind_result);
    192321
     
    237366        }
    238367
    239         plaintext_machinepw = mymachinepw(talloc_tos());
    240         if (plaintext_machinepw == NULL) {
    241                 status = NT_STATUS_NO_MEMORY;
    242                 goto done;
    243         }
    244 
    245         E_md4hash(plaintext_machinepw, machine_password);
    246 
    247         TALLOC_FREE(plaintext_machinepw);
     368        status = mymachinepw(machine_password);
     369        if (!NT_STATUS_IS_OK(status)) {
     370                DEBUG(10, ("mymachinepw failed: %s\n", nt_errstr(status)));
     371                goto done;
     372        }
     373
     374        DEBUG(10, ("machinepw "));
     375        dump_data(10, machine_password, 16);
    248376
    249377        status = rpccli_netlogon_setup_creds(
     
    257385        }
    258386
    259         memcpy(schannel_key, p->dc->session_key, 16);
    260         secrets_store_local_schannel_key(schannel_key);
    261 
    262         TALLOC_FREE(p);
     387        secrets_store_local_schannel_creds(p->dc);
    263388
    264389        /*
     
    268393
    269394        status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock,
    270                                     schannel_key, user_info, &info3,
     395                                    p->dc, user_info, &info3,
    271396                                    &schannel_bind_result);
    272397
     398        TALLOC_FREE(p);
     399
    273400        DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status)));
    274401
     
    279406 okay:
    280407
    281         status = make_server_info_info3(mem_ctx, user_info->smb_name,
    282                                         user_info->domain, server_info,
     408        status = make_server_info_info3(mem_ctx, user_info->client.account_name,
     409                                        user_info->mapped.domain_name, server_info,
    283410                                        info3);
    284411        if (!NT_STATUS_IS_OK(status)) {
     
    301428                                    auth_methods **auth_method)
    302429{
    303         if (!make_auth_methods(auth_context, auth_method)) {
     430        struct auth_methods *result;
     431
     432        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     433        if (result == NULL) {
    304434                return NT_STATUS_NO_MEMORY;
    305435        }
    306 
    307         (*auth_method)->name = "netlogond";
    308         (*auth_method)->auth = check_netlogond_security;
     436        result->name = "netlogond";
     437        result->auth = check_netlogond_security;
     438
     439        *auth_method = result;
    309440        return NT_STATUS_OK;
    310441}
  • trunk/server/source3/auth/auth_ntlmssp.c

    r596 r745  
    2222
    2323#include "includes.h"
     24#include "auth.h"
     25#include "../libcli/auth/ntlmssp.h"
     26#include "ntlmssp_wrap.h"
     27#include "../librpc/gen_ndr/netlogon.h"
     28#include "smbd/smbd.h"
     29
     30NTSTATUS auth_ntlmssp_steal_session_info(TALLOC_CTX *mem_ctx,
     31                                        struct auth_ntlmssp_state *auth_ntlmssp_state,
     32                                        struct auth_serversupplied_info **session_info)
     33{
     34        /* Free the current server_info user_session_key and reset it from the
     35         * current ntlmssp_state session_key */
     36        data_blob_free(&auth_ntlmssp_state->server_info->user_session_key);
     37        /* Set up the final session key for the connection */
     38        auth_ntlmssp_state->server_info->user_session_key =
     39                data_blob_talloc(
     40                        auth_ntlmssp_state->server_info,
     41                        auth_ntlmssp_state->ntlmssp_state->session_key.data,
     42                        auth_ntlmssp_state->ntlmssp_state->session_key.length);
     43        if (auth_ntlmssp_state->ntlmssp_state->session_key.length &&
     44            !auth_ntlmssp_state->server_info->user_session_key.data) {
     45                *session_info = NULL;
     46                return NT_STATUS_NO_MEMORY;
     47        }
     48        /* Steal session_info away from auth_ntlmssp_state */
     49        *session_info = talloc_move(mem_ctx, &auth_ntlmssp_state->server_info);
     50        return NT_STATUS_OK;
     51}
    2452
    2553/**
     
    2856 */
    2957
    30 static void auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
    31                                        uint8_t chal[8])
    32 {
    33         AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
    34                 (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
     58static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
     59                                           uint8_t chal[8])
     60{
     61        struct auth_ntlmssp_state *auth_ntlmssp_state =
     62                (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
    3563        auth_ntlmssp_state->auth_context->get_ntlm_challenge(
    3664                auth_ntlmssp_state->auth_context, chal);
     65        return NT_STATUS_OK;
    3766}
    3867
     
    4473static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
    4574{
    46         AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
    47                 (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
     75        struct auth_ntlmssp_state *auth_ntlmssp_state =
     76                (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
    4877        struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
    4978
     
    5786static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
    5887{
    59         AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
    60                 (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
     88        struct auth_ntlmssp_state *auth_ntlmssp_state =
     89                (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
    6190        struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
    6291
    6392        SMB_ASSERT(challenge->length == 8);
    6493
    65         auth_context->challenge = data_blob_talloc(auth_context->mem_ctx,
     94        auth_context->challenge = data_blob_talloc(auth_context,
    6695                                                   challenge->data, challenge->length);
    6796
     
    80109 */
    81110
    82 static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
    83 {
    84         AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
    85                 (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
    86         auth_usersupplied_info *user_info = NULL;
     111static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx,
     112                                            DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
     113{
     114        struct auth_ntlmssp_state *auth_ntlmssp_state =
     115                (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
     116        struct auth_usersupplied_info *user_info = NULL;
    87117        NTSTATUS nt_status;
    88118        bool username_was_mapped;
     
    91121           we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
    92122
    93         set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->workstation, True);
     123        set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->client.netbios_name, True);
    94124
    95125        /* setup the string used by %U */
     
    97127        sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user);
    98128
    99         reload_services(True);
     129        reload_services(smbd_messaging_context(), -1, True);
    100130
    101131        nt_status = make_user_info_map(&user_info,
    102132                                       auth_ntlmssp_state->ntlmssp_state->user,
    103133                                       auth_ntlmssp_state->ntlmssp_state->domain,
    104                                        auth_ntlmssp_state->ntlmssp_state->workstation,
     134                                       auth_ntlmssp_state->ntlmssp_state->client.netbios_name,
    105135                                       auth_ntlmssp_state->ntlmssp_state->lm_resp.data ? &auth_ntlmssp_state->ntlmssp_state->lm_resp : NULL,
    106136                                       auth_ntlmssp_state->ntlmssp_state->nt_resp.data ? &auth_ntlmssp_state->ntlmssp_state->nt_resp : NULL,
    107137                                       NULL, NULL, NULL,
    108                                        True);
     138                                       AUTH_PASSWORD_RESPONSE);
     139
     140        if (!NT_STATUS_IS_OK(nt_status)) {
     141                return nt_status;
     142        }
    109143
    110144        user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
    111 
    112         if (!NT_STATUS_IS_OK(nt_status)) {
    113                 return nt_status;
    114         }
    115145
    116146        nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context,
     
    127157        auth_ntlmssp_state->server_info->nss_token |= username_was_mapped;
    128158
    129         if (auth_ntlmssp_state->server_info->ptok == NULL) {
    130                 nt_status = create_local_token(auth_ntlmssp_state->server_info);
    131                 if (!NT_STATUS_IS_OK(nt_status)) {
    132                         DEBUG(10, ("create_local_token failed: %s\n",
    133                                    nt_errstr(nt_status)));
    134                         return nt_status;
    135                 }
    136         }
    137 
     159        nt_status = create_local_token(auth_ntlmssp_state->server_info);
     160
     161        if (!NT_STATUS_IS_OK(nt_status)) {
     162                DEBUG(10, ("create_local_token failed: %s\n",
     163                        nt_errstr(nt_status)));
     164                return nt_status;
     165        }
     166
     167        /* Clear out the session keys, and pass them to the caller.
     168         * They will not be used in this form again - instead the
     169         * NTLMSSP code will decide on the final correct session key,
     170         * and put it back here at the end of
     171         * auth_ntlmssp_steal_server_info */
    138172        if (auth_ntlmssp_state->server_info->user_session_key.length) {
    139173                DEBUG(10, ("Got NT session key of length %u\n",
    140174                        (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length));
    141                 *user_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,
    142                                                    auth_ntlmssp_state->server_info->user_session_key.data,
    143                                                    auth_ntlmssp_state->server_info->user_session_key.length);
     175                *user_session_key = auth_ntlmssp_state->server_info->user_session_key;
     176                talloc_steal(mem_ctx, auth_ntlmssp_state->server_info->user_session_key.data);
     177                auth_ntlmssp_state->server_info->user_session_key = data_blob_null;
    144178        }
    145179        if (auth_ntlmssp_state->server_info->lm_session_key.length) {
    146180                DEBUG(10, ("Got LM session key of length %u\n",
    147181                        (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length));
    148                 *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,
    149                                                    auth_ntlmssp_state->server_info->lm_session_key.data,
    150                                                    auth_ntlmssp_state->server_info->lm_session_key.length);
     182                *lm_session_key = auth_ntlmssp_state->server_info->lm_session_key;
     183                talloc_steal(mem_ctx, auth_ntlmssp_state->server_info->lm_session_key.data);
     184                auth_ntlmssp_state->server_info->lm_session_key = data_blob_null;
    151185        }
    152186        return nt_status;
    153187}
    154188
    155 NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
     189static int auth_ntlmssp_state_destructor(void *ptr);
     190
     191NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state **auth_ntlmssp_state)
    156192{
    157193        NTSTATUS nt_status;
    158         TALLOC_CTX *mem_ctx;
    159 
    160         mem_ctx = talloc_init("AUTH NTLMSSP context");
    161        
    162         *auth_ntlmssp_state = TALLOC_ZERO_P(mem_ctx, AUTH_NTLMSSP_STATE);
    163         if (!*auth_ntlmssp_state) {
     194        bool is_standalone;
     195        const char *netbios_name;
     196        const char *netbios_domain;
     197        const char *dns_name;
     198        char *dns_domain;
     199        struct auth_ntlmssp_state *ans;
     200        struct auth_context *auth_context;
     201
     202        if ((enum server_types)lp_server_role() == ROLE_STANDALONE) {
     203                is_standalone = true;
     204        } else {
     205                is_standalone = false;
     206        }
     207
     208        netbios_name = global_myname();
     209        netbios_domain = lp_workgroup();
     210        /* This should be a 'netbios domain -> DNS domain' mapping */
     211        dns_domain = get_mydnsdomname(talloc_tos());
     212        if (dns_domain) {
     213                strlower_m(dns_domain);
     214        }
     215        dns_name = get_mydnsfullname();
     216
     217        ans = talloc_zero(NULL, struct auth_ntlmssp_state);
     218        if (!ans) {
    164219                DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
    165                 talloc_destroy(mem_ctx);
    166220                return NT_STATUS_NO_MEMORY;
    167221        }
    168222
    169         ZERO_STRUCTP(*auth_ntlmssp_state);
    170 
    171         (*auth_ntlmssp_state)->mem_ctx = mem_ctx;
    172 
    173         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(&(*auth_ntlmssp_state)->ntlmssp_state))) {
    174                 return nt_status;
    175         }
    176 
    177         if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&(*auth_ntlmssp_state)->auth_context))) {
    178                 return nt_status;
    179         }
    180 
    181         (*auth_ntlmssp_state)->ntlmssp_state->auth_context = (*auth_ntlmssp_state);
    182         (*auth_ntlmssp_state)->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
    183         (*auth_ntlmssp_state)->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
    184         (*auth_ntlmssp_state)->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
    185         (*auth_ntlmssp_state)->ntlmssp_state->check_password = auth_ntlmssp_check_password;
    186         (*auth_ntlmssp_state)->ntlmssp_state->server_role = (enum server_types)lp_server_role();
    187 
    188         return NT_STATUS_OK;
    189 }
    190 
    191 void auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
    192 {
    193         TALLOC_CTX *mem_ctx;
    194 
    195         if (*auth_ntlmssp_state == NULL) {
    196                 return;
    197         }
    198 
    199         mem_ctx = (*auth_ntlmssp_state)->mem_ctx;
    200         if ((*auth_ntlmssp_state)->ntlmssp_state) {
    201                 ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state);
    202         }
    203         if ((*auth_ntlmssp_state)->auth_context) {
    204                 ((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context);
    205         }
    206         if ((*auth_ntlmssp_state)->server_info) {
    207                 TALLOC_FREE((*auth_ntlmssp_state)->server_info);
    208         }
    209         talloc_destroy(mem_ctx);
    210         *auth_ntlmssp_state = NULL;
    211 }
    212 
    213 NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state,
    214                              const DATA_BLOB request, DATA_BLOB *reply)
    215 {
    216         return ntlmssp_update(auth_ntlmssp_state->ntlmssp_state, request, reply);
    217 }
     223        nt_status = ntlmssp_server_start(ans,
     224                                         is_standalone,
     225                                         netbios_name,
     226                                         netbios_domain,
     227                                         dns_name,
     228                                         dns_domain,
     229                                         &ans->ntlmssp_state);
     230        if (!NT_STATUS_IS_OK(nt_status)) {
     231                return nt_status;
     232        }
     233
     234        nt_status = make_auth_context_subsystem(talloc_tos(), &auth_context);
     235        if (!NT_STATUS_IS_OK(nt_status)) {
     236                return nt_status;
     237        }
     238        ans->auth_context = talloc_steal(ans, auth_context);
     239
     240        ans->ntlmssp_state->callback_private = ans;
     241        ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
     242        ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
     243        ans->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
     244        ans->ntlmssp_state->check_password = auth_ntlmssp_check_password;
     245
     246        talloc_set_destructor((TALLOC_CTX *)ans, auth_ntlmssp_state_destructor);
     247
     248        *auth_ntlmssp_state = ans;
     249        return NT_STATUS_OK;
     250}
     251
     252static int auth_ntlmssp_state_destructor(void *ptr)
     253{
     254        struct auth_ntlmssp_state *ans;
     255
     256        ans = talloc_get_type(ptr, struct auth_ntlmssp_state);
     257
     258        TALLOC_FREE(ans->server_info);
     259        TALLOC_FREE(ans->ntlmssp_state);
     260        return 0;
     261}
  • trunk/server/source3/auth/auth_sam.c

    r480 r745  
    2222
    2323#include "includes.h"
    24 #include "../libcli/auth/libcli_auth.h"
     24#include "auth.h"
    2525
    2626#undef DBGC_CLASS
    2727#define DBGC_CLASS DBGC_AUTH
    2828
    29 /****************************************************************************
    30  Do a specific test for an smb password being correct, given a smb_password and
    31  the lanman and NT responses.
    32 ****************************************************************************/
    33 
    34 static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
    35                                 TALLOC_CTX *mem_ctx,
    36                                 const char *username,
    37                                 uint32_t acct_ctrl,
    38                                 const uint8_t *lm_pw,
    39                                 const uint8_t *nt_pw,
    40                                 const auth_usersupplied_info *user_info,
    41                                 DATA_BLOB *user_sess_key,
    42                                 DATA_BLOB *lm_sess_key)
     29static NTSTATUS auth_sam_ignoredomain_auth(const struct auth_context *auth_context,
     30                                           void *my_private_data,
     31                                           TALLOC_CTX *mem_ctx,
     32                                           const struct auth_usersupplied_info *user_info,
     33                                           struct auth_serversupplied_info **server_info)
    4334{
    44         struct samr_Password _lm_hash, _nt_hash, _client_lm_hash, _client_nt_hash;
    45         struct samr_Password *lm_hash = NULL;
    46         struct samr_Password *nt_hash = NULL;
    47         struct samr_Password *client_lm_hash = NULL;
    48         struct samr_Password *client_nt_hash = NULL;
    49 
    50         *user_sess_key = data_blob_null;
    51         *lm_sess_key = data_blob_null;
    52 
    53         if (acct_ctrl & ACB_PWNOTREQ) {
    54                 if (lp_null_passwords()) {
    55                         DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", username));
    56                         return NT_STATUS_OK;
    57                 } else {
    58                         DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", username));
    59                         return NT_STATUS_LOGON_FAILURE;
    60                 }               
    61         }
    62 
    63         if (lm_pw) {
    64                 memcpy(_lm_hash.hash, lm_pw, sizeof(_lm_hash.hash));
    65                 lm_hash = &_lm_hash;
    66         }
    67         if (nt_pw) {
    68                 memcpy(_nt_hash.hash, nt_pw, sizeof(_nt_hash.hash));
    69                 nt_hash = &_nt_hash;
    70         }
    71         if (user_info->lm_interactive_pwd.data && sizeof(_client_lm_hash.hash) == user_info->lm_interactive_pwd.length) {
    72                 memcpy(_client_lm_hash.hash, user_info->lm_interactive_pwd.data, sizeof(_lm_hash.hash));
    73                 client_lm_hash = &_client_lm_hash;
    74         }
    75         if (user_info->nt_interactive_pwd.data && sizeof(_client_nt_hash.hash) == user_info->nt_interactive_pwd.length) {
    76                 memcpy(_client_nt_hash.hash, user_info->nt_interactive_pwd.data, sizeof(_nt_hash.hash));
    77                 client_nt_hash = &_client_nt_hash;
    78         }
    79 
    80         if (client_lm_hash || client_nt_hash) {
    81                 if (!nt_pw) {
    82                         return NT_STATUS_WRONG_PASSWORD;
    83                 }
    84                 *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
    85                 if (!user_sess_key->data) {
    86                         return NT_STATUS_NO_MEMORY;
    87                 }
    88                 SMBsesskeygen_ntv1(nt_pw, user_sess_key->data);
    89                 return hash_password_check(mem_ctx, lp_lanman_auth(),
    90                                            client_lm_hash,
    91                                            client_nt_hash,
    92                                            username,
    93                                            lm_hash,
    94                                            nt_hash);
    95         } else {
    96                 return ntlm_password_check(mem_ctx, lp_lanman_auth(),
    97                                            lp_ntlm_auth(),
    98                                            user_info->logon_parameters,
    99                                            &auth_context->challenge,
    100                                            &user_info->lm_resp, &user_info->nt_resp,
    101                                            username,
    102                                            user_info->smb_name,
    103                                            user_info->client_domain,
    104                                            lm_hash,
    105                                            nt_hash,
    106                                            user_sess_key, lm_sess_key);
    107         }
    108 }
    109 
    110 /****************************************************************************
    111  Check if a user is allowed to logon at this time. Note this is the
    112  servers local time, as logon hours are just specified as a weekly
    113  bitmask.
    114 ****************************************************************************/
    115 
    116 static bool logon_hours_ok(struct samu *sampass)
    117 {
    118         /* In logon hours first bit is Sunday from 12AM to 1AM */
    119         const uint8 *hours;
    120         struct tm *utctime;
    121         time_t lasttime;
    122         const char *asct;
    123         uint8 bitmask, bitpos;
    124 
    125         hours = pdb_get_hours(sampass);
    126         if (!hours) {
    127                 DEBUG(5,("logon_hours_ok: No hours restrictions for user %s\n",pdb_get_username(sampass)));
    128                 return True;
    129         }
    130 
    131         lasttime = time(NULL);
    132         utctime = gmtime(&lasttime);
    133         if (!utctime) {
    134                 DEBUG(1, ("logon_hours_ok: failed to get gmtime. Failing logon for user %s\n",
    135                         pdb_get_username(sampass) ));
    136                 return False;
    137         }
    138 
    139         /* find the corresponding byte and bit */
    140         bitpos = (utctime->tm_wday * 24 + utctime->tm_hour) % 168;
    141         bitmask = 1 << (bitpos % 8);
    142 
    143         if (! (hours[bitpos/8] & bitmask)) {
    144                 struct tm *t = localtime(&lasttime);
    145                 if (!t) {
    146                         asct = "INVALID TIME";
    147                 } else {
    148                         asct = asctime(t);
    149                         if (!asct) {
    150                                 asct = "INVALID TIME";
    151                         }
    152                 }
    153 
    154                 DEBUG(1, ("logon_hours_ok: Account for user %s not allowed to "
    155                           "logon at this time (%s).\n",
    156                           pdb_get_username(sampass), asct ));
    157                 return False;
    158         }
    159 
    160         asct = asctime(utctime);
    161         DEBUG(5,("logon_hours_ok: user %s allowed to logon at this time (%s)\n",
    162                 pdb_get_username(sampass), asct ? asct : "UNKNOWN TIME" ));
    163 
    164         return True;
    165 }
    166 
    167 /****************************************************************************
    168  Do a specific test for a struct samu being valid for this connection
    169  (ie not disabled, expired and the like).
    170 ****************************************************************************/
    171 
    172 static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
    173                                struct samu *sampass,
    174                                const auth_usersupplied_info *user_info)
    175 {
    176         uint32  acct_ctrl = pdb_get_acct_ctrl(sampass);
    177         char *workstation_list;
    178         time_t kickoff_time;
    179 
    180         DEBUG(4,("sam_account_ok: Checking SMB password for user %s\n",pdb_get_username(sampass)));
    181 
    182         /* Quit if the account was disabled. */
    183         if (acct_ctrl & ACB_DISABLED) {
    184                 DEBUG(1,("sam_account_ok: Account for user '%s' was disabled.\n", pdb_get_username(sampass)));
    185                 return NT_STATUS_ACCOUNT_DISABLED;
    186         }
    187 
    188         /* Quit if the account was locked out. */
    189         if (acct_ctrl & ACB_AUTOLOCK) {
    190                 DEBUG(1,("sam_account_ok: Account for user %s was locked out.\n", pdb_get_username(sampass)));
    191                 return NT_STATUS_ACCOUNT_LOCKED_OUT;
    192         }
    193 
    194         /* Quit if the account is not allowed to logon at this time. */
    195         if (! logon_hours_ok(sampass)) {
    196                 return NT_STATUS_INVALID_LOGON_HOURS;
    197         }
    198 
    199         /* Test account expire time */
    200 
    201         kickoff_time = pdb_get_kickoff_time(sampass);
    202         if (kickoff_time != 0 && time(NULL) > kickoff_time) {
    203                 DEBUG(1,("sam_account_ok: Account for user '%s' has expired.\n", pdb_get_username(sampass)));
    204                 DEBUG(3,("sam_account_ok: Account expired at '%ld' unix time.\n", (long)kickoff_time));
    205                 return NT_STATUS_ACCOUNT_EXPIRED;
    206         }
    207 
    208         if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP) && !(pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) {
    209                 time_t must_change_time = pdb_get_pass_must_change_time(sampass);
    210                 time_t last_set_time = pdb_get_pass_last_set_time(sampass);
    211 
    212                 /* check for immediate expiry "must change at next logon"
    213                  * for a user account. */
    214                 if (((acct_ctrl & (ACB_WSTRUST|ACB_SVRTRUST)) == 0) && (last_set_time == 0)) {
    215                         DEBUG(1,("sam_account_ok: Account for user '%s' password must change!\n", pdb_get_username(sampass)));
    216                         return NT_STATUS_PASSWORD_MUST_CHANGE;
    217                 }
    218 
    219                 /* check for expired password */
    220                 if (must_change_time < time(NULL) && must_change_time != 0) {
    221                         DEBUG(1,("sam_account_ok: Account for user '%s' password expired!\n", pdb_get_username(sampass)));
    222                         DEBUG(1,("sam_account_ok: Password expired at '%s' (%ld) unix time.\n", http_timestring(talloc_tos(), must_change_time), (long)must_change_time));
    223                         return NT_STATUS_PASSWORD_EXPIRED;
    224                 }
    225         }
    226 
    227         /* Test workstation. Workstation list is comma separated. */
    228 
    229         workstation_list = talloc_strdup(mem_ctx, pdb_get_workstations(sampass));
    230         if (!workstation_list)
    231                 return NT_STATUS_NO_MEMORY;
    232 
    233         if (*workstation_list) {
    234                 bool invalid_ws = True;
    235                 char *tok = NULL;
    236                 const char *s = workstation_list;
    237                 char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name);
    238 
    239                 if (machine_name == NULL)
    240                         return NT_STATUS_NO_MEMORY;
    241 
    242                 while (next_token_talloc(mem_ctx, &s, &tok, ",")) {
    243                         DEBUG(10,("sam_account_ok: checking for workstation match %s and %s\n",
    244                                   tok, user_info->wksta_name));
    245                         if(strequal(tok, user_info->wksta_name)) {
    246                                 invalid_ws = False;
    247                                 break;
    248                         }
    249                         if (tok[0] == '+') {
    250                                 DEBUG(10,("sam_account_ok: checking for workstation %s in group: %s\n",
    251                                         machine_name, tok + 1));
    252                                 if (user_in_group(machine_name, tok + 1)) {
    253                                         invalid_ws = False;
    254                                         break;
    255                                 }
    256                         }
    257                         TALLOC_FREE(tok);
    258                 }
    259                 TALLOC_FREE(tok);
    260                 TALLOC_FREE(machine_name);
    261 
    262                 if (invalid_ws)
    263                         return NT_STATUS_INVALID_WORKSTATION;
    264         }
    265 
    266         if (acct_ctrl & ACB_DOMTRUST) {
    267                 DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", pdb_get_username(sampass)));
    268                 return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
    269         }
    270 
    271         if (acct_ctrl & ACB_SVRTRUST) {
    272                 if (!(user_info->logon_parameters & MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT)) {
    273                         DEBUG(2,("sam_account_ok: Server trust account %s denied by server\n", pdb_get_username(sampass)));
    274                         return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT;
    275                 }
    276         }
    277 
    278         if (acct_ctrl & ACB_WSTRUST) {
    279                 if (!(user_info->logon_parameters & MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT)) {
    280                         DEBUG(2,("sam_account_ok: Wksta trust account %s denied by server\n", pdb_get_username(sampass)));
    281                         return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
    282                 }
    283         }
    284         return NT_STATUS_OK;
    285 }
    286 
    287 /**
    288  * Check whether the given password is one of the last two
    289  * password history entries. If so, the bad pwcount should
    290  * not be incremented even thought the actual password check
    291  * failed.
    292  */
    293 static bool need_to_increment_bad_pw_count(
    294         const struct auth_context *auth_context,
    295         struct samu* sampass,
    296         const auth_usersupplied_info *user_info)
    297 {
    298         uint8_t i;
    299         const uint8_t *pwhistory;
    300         uint32_t pwhistory_len;
    301         uint32_t policy_pwhistory_len;
    302         uint32_t acct_ctrl;
    303         const char *username;
    304         TALLOC_CTX *mem_ctx = talloc_stackframe();
    305         bool result = true;
    306 
    307         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY,
    308                                &policy_pwhistory_len);
    309         if (policy_pwhistory_len == 0) {
    310                 goto done;
    311         }
    312 
    313         pwhistory = pdb_get_pw_history(sampass, &pwhistory_len);
    314         if (!pwhistory || pwhistory_len == 0) {
    315                 goto done;
    316         }
    317 
    318         acct_ctrl = pdb_get_acct_ctrl(sampass);
    319         username = pdb_get_username(sampass);
    320 
    321         for (i=1; i < MIN(MIN(3, policy_pwhistory_len), pwhistory_len); i++) {
    322                 static const uint8_t zero16[SALTED_MD5_HASH_LEN];
    323                 const uint8_t *salt;
    324                 const uint8_t *nt_pw;
    325                 NTSTATUS status;
    326                 DATA_BLOB user_sess_key = data_blob_null;
    327                 DATA_BLOB lm_sess_key = data_blob_null;
    328 
    329                 salt = &pwhistory[i*PW_HISTORY_ENTRY_LEN];
    330                 nt_pw = salt + PW_HISTORY_SALT_LEN;
    331 
    332                 if (memcmp(zero16, nt_pw, NT_HASH_LEN) == 0) {
    333                         /* skip zero password hash */
    334                         continue;
    335                 }
    336 
    337                 if (memcmp(zero16, salt, PW_HISTORY_SALT_LEN) != 0) {
    338                         /* skip nonzero salt (old format entry) */
    339                         continue;
    340                 }
    341 
    342                 status = sam_password_ok(auth_context, mem_ctx,
    343                                          username, acct_ctrl, NULL, nt_pw,
    344                                          user_info, &user_sess_key, &lm_sess_key);
    345                 if (NT_STATUS_IS_OK(status)) {
    346                         result = false;
    347                         break;
    348                 }
    349         }
    350 
    351 done:
    352         TALLOC_FREE(mem_ctx);
    353         return result;
    354 }
    355 
    356 /****************************************************************************
    357 check if a username/password is OK assuming the password is a 24 byte
    358 SMB hash supplied in the user_info structure
    359 return an NT_STATUS constant.
    360 ****************************************************************************/
    361 
    362 static NTSTATUS check_sam_security(const struct auth_context *auth_context,
    363                                    void *my_private_data,
    364                                    TALLOC_CTX *mem_ctx,
    365                                    const auth_usersupplied_info *user_info,
    366                                    auth_serversupplied_info **server_info)
    367 {
    368         struct samu *sampass=NULL;
    369         bool ret;
    370         NTSTATUS nt_status;
    371         NTSTATUS update_login_attempts_status;
    372         DATA_BLOB user_sess_key = data_blob_null;
    373         DATA_BLOB lm_sess_key = data_blob_null;
    374         bool updated_autolock = False, updated_badpw = False;
    375         const char *username;
    376         const uint8_t *nt_pw;
    377         const uint8_t *lm_pw;
    378 
    37935        if (!user_info || !auth_context) {
    38036                return NT_STATUS_UNSUCCESSFUL;
    38137        }
    382 
    383         /* the returned struct gets kept on the server_info, by means
    384            of a steal further down */
    385 
    386         sampass = samu_new(mem_ctx);
    387         if (sampass == NULL) {
    388                 return NT_STATUS_NO_MEMORY;
    389         }
    390 
    391         /* get the account information */
    392 
    393         become_root();
    394         ret = pdb_getsampwnam(sampass, user_info->internal_username);
    395         unbecome_root();
    396 
    397         if (ret == False) {
    398                 DEBUG(3,("check_sam_security: Couldn't find user '%s' in "
    399                          "passdb.\n", user_info->internal_username));
    400                 TALLOC_FREE(sampass);
    401                 return NT_STATUS_NO_SUCH_USER;
    402         }
    403 
    404         username = pdb_get_username(sampass);
    405         nt_pw = pdb_get_nt_passwd(sampass);
    406         lm_pw = pdb_get_lanman_passwd(sampass);
    407 
    408         /* see if autolock flag needs to be updated */
    409         if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL)
    410                 pdb_update_autolock_flag(sampass, &updated_autolock);
    411         /* Quit if the account was locked out. */
    412         if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) {
    413                 DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", username));
    414                 return NT_STATUS_ACCOUNT_LOCKED_OUT;
    415         }
    416 
    417         nt_status = sam_password_ok(auth_context, mem_ctx,
    418                                     username, pdb_get_acct_ctrl(sampass), lm_pw, nt_pw,
    419                                     user_info, &user_sess_key, &lm_sess_key);
    420 
    421         /* Notify passdb backend of login success/failure. If not
    422            NT_STATUS_OK the backend doesn't like the login */
    423 
    424         update_login_attempts_status = pdb_update_login_attempts(sampass, NT_STATUS_IS_OK(nt_status));
    425 
    426         if (!NT_STATUS_IS_OK(nt_status)) {
    427                 bool increment_bad_pw_count = false;
    428 
    429                 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) &&
    430                     pdb_get_acct_ctrl(sampass) & ACB_NORMAL &&
    431                     NT_STATUS_IS_OK(update_login_attempts_status))
    432                 {
    433                         increment_bad_pw_count =
    434                                 need_to_increment_bad_pw_count(auth_context,
    435                                                                sampass,
    436                                                                user_info);
    437                 }
    438 
    439                 if (increment_bad_pw_count) {
    440                         pdb_increment_bad_password_count(sampass);
    441                         updated_badpw = True;
    442                 } else {
    443                         pdb_update_bad_password_count(sampass,
    444                                                       &updated_badpw);
    445                 }
    446                 if (updated_autolock || updated_badpw){
    447                         NTSTATUS status;
    448 
    449                         become_root();
    450                         status = pdb_update_sam_account(sampass);
    451                         unbecome_root();
    452 
    453                         if (!NT_STATUS_IS_OK(status)) {
    454                                 DEBUG(1, ("Failed to modify entry: %s\n",
    455                                           nt_errstr(status)));
    456                         }
    457                 }
    458                 goto done;
    459         }
    460 
    461         if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) &&
    462             (pdb_get_bad_password_count(sampass) > 0)){
    463                 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
    464                 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
    465                 updated_badpw = True;
    466         }
    467 
    468         if (updated_autolock || updated_badpw){
    469                 NTSTATUS status;
    470 
    471                 become_root();
    472                 status = pdb_update_sam_account(sampass);
    473                 unbecome_root();
    474 
    475                 if (!NT_STATUS_IS_OK(status)) {
    476                         DEBUG(1, ("Failed to modify entry: %s\n",
    477                                   nt_errstr(status)));
    478                 }
    479         }
    480 
    481         nt_status = sam_account_ok(mem_ctx, sampass, user_info);
    482 
    483         if (!NT_STATUS_IS_OK(nt_status)) {
    484                 goto done;
    485         }
    486 
    487         become_root();
    488         nt_status = make_server_info_sam(server_info, sampass);
    489         unbecome_root();
    490         sampass = NULL;
    491 
    492         if (!NT_STATUS_IS_OK(nt_status)) {
    493                 DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status)));
    494                 goto done;
    495         }
    496 
    497         (*server_info)->user_session_key =
    498                 data_blob_talloc(*server_info, user_sess_key.data,
    499                                  user_sess_key.length);
    500         data_blob_free(&user_sess_key);
    501 
    502         (*server_info)->lm_session_key =
    503                 data_blob_talloc(*server_info, lm_sess_key.data,
    504                                  lm_sess_key.length);
    505         data_blob_free(&lm_sess_key);
    506 
    507         (*server_info)->nss_token |= user_info->was_mapped;
    508 
    509 done:
    510         TALLOC_FREE(sampass);
    511         data_blob_free(&user_sess_key);
    512         data_blob_free(&lm_sess_key);
    513         return nt_status;
     38        return check_sam_security(&auth_context->challenge, mem_ctx,
     39                                  user_info, server_info);
    51440}
    51541
     
    51743static NTSTATUS auth_init_sam_ignoredomain(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
    51844{
    519         if (!make_auth_methods(auth_context, auth_method)) {
     45        struct auth_methods *result;
     46
     47        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     48        if (result == NULL) {
    52049                return NT_STATUS_NO_MEMORY;
    52150        }
     51        result->auth = auth_sam_ignoredomain_auth;
     52        result->name = "sam_ignoredomain";
    52253
    523         (*auth_method)->auth = check_sam_security;     
    524         (*auth_method)->name = "sam_ignoredomain";
     54        *auth_method = result;
    52555        return NT_STATUS_OK;
    52656}
     
    53161****************************************************************************/
    53262
    533 static NTSTATUS check_samstrict_security(const struct auth_context *auth_context,
    534                                          void *my_private_data,
    535                                         TALLOC_CTX *mem_ctx,
    536                                          const auth_usersupplied_info *user_info,
    537                                         auth_serversupplied_info **server_info)
     63static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context,
     64                                    void *my_private_data,
     65                                    TALLOC_CTX *mem_ctx,
     66                                    const struct auth_usersupplied_info *user_info,
     67                                    struct auth_serversupplied_info **server_info)
    53868{
    53969        bool is_local_name, is_my_domain;
     
    54373        }
    54474
    545         is_local_name = is_myname(user_info->domain);
    546         is_my_domain  = strequal(user_info->domain, lp_workgroup());
     75        DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
     76
     77        is_local_name = is_myname(user_info->mapped.domain_name);
     78        is_my_domain  = strequal(user_info->mapped.domain_name, lp_workgroup());
    54779
    54880        /* check whether or not we service this domain/workgroup name */
     
    55385                        if ( !is_local_name ) {
    55486                                DEBUG(6,("check_samstrict_security: %s is not one of my local names (%s)\n",
    555                                         user_info->domain, (lp_server_role() == ROLE_DOMAIN_MEMBER
     87                                        user_info->mapped.domain_name, (lp_server_role() == ROLE_DOMAIN_MEMBER
    55688                                        ? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") ));
    55789                                return NT_STATUS_NOT_IMPLEMENTED;
     
    56193                        if ( !is_local_name && !is_my_domain ) {
    56294                                DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n",
    563                                         user_info->domain));
     95                                        user_info->mapped.domain_name));
    56496                                return NT_STATUS_NOT_IMPLEMENTED;
    56597                        }
     
    568100        }
    569101
    570         return check_sam_security(auth_context, my_private_data, mem_ctx, user_info, server_info);
     102        return check_sam_security(&auth_context->challenge, mem_ctx,
     103                                  user_info, server_info);
    571104}
    572105
     
    574107static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
    575108{
    576         if (!make_auth_methods(auth_context, auth_method)) {
     109        struct auth_methods *result;
     110
     111        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     112        if (result == NULL) {
    577113                return NT_STATUS_NO_MEMORY;
    578114        }
     115        result->auth = auth_samstrict_auth;
     116        result->name = "sam";
    579117
    580         (*auth_method)->auth = check_samstrict_security;
    581         (*auth_method)->name = "sam";
     118        *auth_method = result;
    582119        return NT_STATUS_OK;
    583120}
  • trunk/server/source3/auth/auth_script.c

    r414 r745  
    55
    66   Copyright (C) Jeremy Allison 2005.
    7    
     7
    88   This program is free software; you can redistribute it and/or modify
    99   it under the terms of the GNU General Public License as published by
    1010   the Free Software Foundation; either version 3 of the License, or
    1111   (at your option) any later version.
    12    
     12
    1313   This program is distributed in the hope that it will be useful,
    1414   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616   GNU General Public License for more details.
    17    
     17
    1818   You should have received a copy of the GNU General Public License
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2121
    2222#include "includes.h"
     23#include "auth.h"
    2324
    2425#undef malloc
     
    4142                                        void *my_private_data,
    4243                                        TALLOC_CTX *mem_ctx,
    43                                         const auth_usersupplied_info *user_info,
    44                                         auth_serversupplied_info **server_info)
     44                                        const struct auth_usersupplied_info *user_info,
     45                                        struct auth_serversupplied_info **server_info)
    4546{
    4647        const char *script = lp_parm_const_string( GLOBAL_SECTION_SNUM, "auth_script", "script", NULL);
     
    6364        }               
    6465
    65         secret_str_len = strlen(user_info->domain) + 1 +
    66                         strlen(user_info->smb_name) + 1 +
     66        secret_str_len = strlen(user_info->mapped.domain_name) + 1 +
     67                        strlen(user_info->client.account_name) + 1 +
    6768                        16 + 1 + /* 8 bytes of challenge going to 16 */
    6869                        48 + 1 + /* 24 bytes of challenge going to 48 */
     
    7475        }
    7576
    76         safe_strcpy( secret_str, user_info->domain, secret_str_len - 1);
     77        safe_strcpy( secret_str, user_info->mapped.domain_name, secret_str_len - 1);
    7778        safe_strcat( secret_str, "\n", secret_str_len - 1);
    78         safe_strcat( secret_str, user_info->smb_name, secret_str_len - 1);
     79        safe_strcat( secret_str, user_info->client.account_name, secret_str_len - 1);
    7980        safe_strcat( secret_str, "\n", secret_str_len - 1);
    8081
     
    8586        safe_strcat( secret_str, "\n", secret_str_len - 1);
    8687
    87         if (user_info->lm_resp.data) {
     88        if (user_info->password.response.lanman.data) {
    8889                for (i = 0; i < 24; i++) {
    89                         slprintf(&hex_str[i*2], 3, "%02X", user_info->lm_resp.data[i]);
     90                        slprintf(&hex_str[i*2], 3, "%02X", user_info->password.response.lanman.data[i]);
    9091                }
    9192                safe_strcat( secret_str, hex_str, secret_str_len - 1);
     
    9394        safe_strcat( secret_str, "\n", secret_str_len - 1);
    9495
    95         if (user_info->nt_resp.data) {
     96        if (user_info->password.response.nt.data) {
    9697                for (i = 0; i < 24; i++) {
    97                         slprintf(&hex_str[i*2], 3, "%02X", user_info->nt_resp.data[i]);
     98                        slprintf(&hex_str[i*2], 3, "%02X", user_info->password.response.nt.data[i]);
    9899                }
    99100                safe_strcat( secret_str, hex_str, secret_str_len - 1);
     
    110111        if (ret) {
    111112                DEBUG(1,("script_check_user_credentials: failed to authenticate %s\\%s\n",
    112                         user_info->domain, user_info->smb_name ));
     113                        user_info->mapped.domain_name, user_info->client.account_name ));
    113114                /* auth failed. */
    114115                return NT_STATUS_NO_SUCH_USER;
     
    122123static NTSTATUS auth_init_script(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
    123124{
    124         if (!make_auth_methods(auth_context, auth_method)) {
     125        struct auth_methods *result;
     126
     127        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     128        if (result == NULL) {
    125129                return NT_STATUS_NO_MEMORY;
    126130        }
    127 
    128         (*auth_method)->name = "script";
    129         (*auth_method)->auth = script_check_user_credentials;
     131        result->name = "script";
     132        result->auth = script_check_user_credentials;
    130133
    131134        if (param && *param) {
     
    136139                        return NT_STATUS_UNSUCCESSFUL;
    137140                }
    138                 (*auth_method)->private_data = (void *)priv;
     141                result->private_data = (void *)priv;
    139142        }
     143
     144        *auth_method = result;
    140145        return NT_STATUS_OK;
    141146}
  • trunk/server/source3/auth/auth_server.c

    r414 r745  
    99   the Free Software Foundation; either version 3 of the License, or
    1010   (at your option) any later version.
    11    
     11
    1212   This program is distributed in the hope that it will be useful,
    1313   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1515   GNU General Public License for more details.
    16    
     16
    1717   You should have received a copy of the GNU General Public License
    1818   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2020
    2121#include "includes.h"
     22#include "auth.h"
     23#include "system/passwd.h"
     24#include "smbd/smbd.h"
     25#include "libsmb/libsmb.h"
    2226
    2327#undef DBGC_CLASS
     
    136140        */
    137141
    138         if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 0, "", 0,
    139                                                ""))) {
     142        status = cli_session_setup(cli, "", "", 0, "", 0, "");
     143        if (!NT_STATUS_IS_OK(status)) {
    140144                TALLOC_FREE(mutex);
    141145                DEBUG(0,("%s rejected the initial session setup (%s)\n",
    142                          desthost, cli_errstr(cli)));
     146                         desthost, nt_errstr(status)));
    143147                cli_shutdown(cli);
    144148                return NULL;
     
    207211                interval.tv_usec = 0;
    208212
    209                 if (event_add_idle(smbd_event_context(), result, interval,
     213                if (event_add_idle(server_event_context(), result, interval,
    210214                                   "server_security_keepalive",
    211215                                   send_server_keepalive,
     
    229233{
    230234        struct cli_state *cli = server_cryptkey(mem_ctx);
    231        
     235
    232236        if (cli) {
    233237                DEBUG(3,("using password server validation\n"));
     
    237241                           unless 'encrypt passwords = no' */
    238242                        DEBUG(5,("make_auth_info_server: Server is unencrypted, no challenge available..\n"));
    239                        
     243
    240244                        /* However, it is still a perfectly fine connection
    241245                           to pass that unencrypted password over */
     
    256260                /* The return must be allocated on the caller's mem_ctx, as our own will be
    257261                   destoyed just after the call. */
    258                 return data_blob_talloc(auth_context->mem_ctx, cli->secblob.data,8);
     262                return data_blob_talloc((TALLOC_CTX *)auth_context, cli->secblob.data,8);
    259263        } else {
    260264                return data_blob_null;
     
    271275                                         void *my_private_data,
    272276                                         TALLOC_CTX *mem_ctx,
    273                                          const auth_usersupplied_info *user_info,
    274                                          auth_serversupplied_info **server_info)
    275 {
    276         struct server_security_state *state = talloc_get_type_abort(
    277                 my_private_data, struct server_security_state);
    278         struct cli_state *cli;
     277                                         const struct auth_usersupplied_info *user_info,
     278                                         struct auth_serversupplied_info **server_info)
     279{
     280        struct server_security_state *state = NULL;
     281        struct cli_state *cli = NULL;
    279282        static bool tested_password_server = False;
    280283        static bool bad_password_server = False;
     
    282285        bool locally_made_cli = False;
    283286
     287        DEBUG(10, ("check_smbserver_security: Check auth for: [%s]\n",
     288                user_info->mapped.account_name));
     289
     290        if (my_private_data == NULL) {
     291                DEBUG(10,("check_smbserver_security: "
     292                        "password server is not connected\n"));
     293                return NT_STATUS_LOGON_FAILURE;
     294        }
     295
     296        state = talloc_get_type_abort(my_private_data, struct server_security_state);
    284297        cli = state->cli;
    285        
     298
    286299        if (cli) {
    287300        } else {
     
    294307                return NT_STATUS_LOGON_FAILURE;
    295308        } 
    296        
     309
    297310        if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
    298                 if (user_info->encrypted) {
     311                if (user_info->password_state != AUTH_PASSWORD_PLAIN) {
    299312                        DEBUG(1,("password server %s is plaintext, but we are encrypted. This just can't work :-(\n", cli->desthost));
    300313                        return NT_STATUS_LOGON_FAILURE;         
     
    325338                memset(badpass, 0x1f, sizeof(badpass));
    326339
    327                 if((user_info->nt_resp.length == sizeof(badpass)) &&
    328                    !memcmp(badpass, user_info->nt_resp.data, sizeof(badpass))) {
     340                if((user_info->password.response.nt.length == sizeof(badpass)) &&
     341                   !memcmp(badpass, user_info->password.response.nt.data, sizeof(badpass))) {
    329342                        /*
    330343                         * Very unlikely, our random bad password is the same as the users
     
    347360                                                      (char *)badpass,
    348361                                                      sizeof(badpass),
    349                                                       user_info->domain))) {
     362                                                      user_info->mapped.domain_name))) {
    350363
    351364                        /*
     
    390403         * not guest enabled, we can try with the real password.
    391404         */
    392 
    393         if (!user_info->encrypted) {
     405        switch (user_info->password_state) {
     406        case AUTH_PASSWORD_PLAIN:
    394407                /* Plaintext available */
    395408                nt_status = cli_session_setup(
    396                         cli, user_info->smb_name,
    397                         (char *)user_info->plaintext_password.data,
    398                         user_info->plaintext_password.length,
    399                         NULL, 0, user_info->domain);
    400 
    401         } else {
     409                        cli, user_info->client.account_name,
     410                        user_info->password.plaintext,
     411                        strlen(user_info->password.plaintext),
     412                        NULL, 0, user_info->mapped.domain_name);
     413                break;
     414
     415        /* currently the hash values include a challenge-response as well */
     416        case AUTH_PASSWORD_HASH:
     417        case AUTH_PASSWORD_RESPONSE:
    402418                nt_status = cli_session_setup(
    403                         cli, user_info->smb_name,
    404                         (char *)user_info->lm_resp.data,
    405                         user_info->lm_resp.length,
    406                         (char *)user_info->nt_resp.data,
    407                         user_info->nt_resp.length,
    408                         user_info->domain);
     419                        cli, user_info->client.account_name,
     420                        (char *)user_info->password.response.lanman.data,
     421                        user_info->password.response.lanman.length,
     422                        (char *)user_info->password.response.nt.data,
     423                        user_info->password.response.nt.length,
     424                        user_info->mapped.domain_name);
     425                break;
     426        default:
     427                DEBUG(0,("user_info constructed for user '%s' was invalid - password_state=%u invalid.\n",user_info->mapped.account_name, user_info->password_state));
     428                nt_status = NT_STATUS_INTERNAL_ERROR;
    409429        }
    410430
     
    415435
    416436        /* if logged in as guest then reject */
    417         if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) {
     437        if (cli->is_guestlogin) {
    418438                DEBUG(1,("password server %s gave us guest only\n", cli->desthost));
    419439                nt_status = NT_STATUS_LOGON_FAILURE;
     
    423443
    424444        if (NT_STATUS_IS_OK(nt_status)) {
    425                 fstring real_username;
    426                 struct passwd *pass;
    427 
    428                 if ( (pass = smb_getpwnam( NULL, user_info->internal_username,
    429                         real_username, True )) != NULL )
     445                char *real_username = NULL;
     446                struct passwd *pass = NULL;
     447
     448                if ( (pass = smb_getpwnam(talloc_tos(), user_info->mapped.account_name,
     449                        &real_username, True )) != NULL )
    430450                {
    431                         /* if a real user check pam account restrictions */
    432                         /* only really perfomed if "obey pam restriction" is true */
    433                         nt_status = smb_pam_accountcheck(pass->pw_name);
    434                         if (  !NT_STATUS_IS_OK(nt_status)) {
    435                                 DEBUG(1, ("PAM account restriction prevents user login\n"));
    436                         } else {
    437 
    438                                 nt_status = make_server_info_pw(server_info, pass->pw_name, pass);
    439                         }
     451                        nt_status = make_server_info_pw(server_info, pass->pw_name, pass);
    440452                        TALLOC_FREE(pass);
     453                        TALLOC_FREE(real_username);
    441454                }
    442455                else
     
    455468static NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
    456469{
    457         if (!make_auth_methods(auth_context, auth_method)) {
     470        struct auth_methods *result;
     471
     472        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     473        if (result == NULL) {
    458474                return NT_STATUS_NO_MEMORY;
    459475        }
    460         (*auth_method)->name = "smbserver";
    461         (*auth_method)->auth = check_smbserver_security;
    462         (*auth_method)->get_chal = auth_get_challenge_server;
     476        result->name = "smbserver";
     477        result->auth = check_smbserver_security;
     478        result->get_chal = auth_get_challenge_server;
     479
     480        *auth_method = result;
    463481        return NT_STATUS_OK;
    464482}
  • trunk/server/source3/auth/auth_unix.c

    r414 r745  
    33   Password and authentication handling
    44   Copyright (C) Andrew Bartlett              2001
    5    
     5
    66   This program is free software; you can redistribute it and/or modify
    77   it under the terms of the GNU General Public License as published by
    88   the Free Software Foundation; either version 3 of the License, or
    99   (at your option) any later version.
    10    
     10
    1111   This program is distributed in the hope that it will be useful,
    1212   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1313   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1414   GNU General Public License for more details.
    15    
     15
    1616   You should have received a copy of the GNU General Public License
    1717   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    1919
    2020#include "includes.h"
     21#include "auth.h"
     22#include "system/passwd.h"
     23#include "smbd/globals.h"
    2124
    2225#undef DBGC_CLASS
    2326#define DBGC_CLASS DBGC_AUTH
    24 
    25 /**
    26  * update the encrypted smbpasswd file from the plaintext username and password
    27  * 
    28  *  this ugly hack needs to die, but not quite yet, I think people still use it...
    29  **/
    30 static bool update_smbpassword_file(const char *user, const char *password)
    31 {
    32         struct samu     *sampass;
    33         bool            ret;
    34        
    35         if ( !(sampass = samu_new( NULL )) ) {
    36                 return False;
    37         }
    38        
    39         become_root();
    40         ret = pdb_getsampwnam(sampass, user);
    41         unbecome_root();
    42 
    43         if(ret == False) {
    44                 DEBUG(0,("pdb_getsampwnam returned NULL\n"));
    45                 TALLOC_FREE(sampass);
    46                 return False;
    47         }
    48 
    49         /*
    50          * Remove the account disabled flag - we are updating the
    51          * users password from a login.
    52          */
    53         if (!pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED, PDB_CHANGED)) {
    54                 TALLOC_FREE(sampass);
    55                 return False;
    56         }
    57 
    58         if (!pdb_set_plaintext_passwd (sampass, password)) {
    59                 TALLOC_FREE(sampass);
    60                 return False;
    61         }
    62 
    63         /* Now write it into the file. */
    64         become_root();
    65 
    66         ret = NT_STATUS_IS_OK(pdb_update_sam_account (sampass));
    67 
    68         unbecome_root();
    69 
    70         if (ret) {
    71                 DEBUG(3,("pdb_update_sam_account returned %d\n",ret));
    72         }
    73 
    74         TALLOC_FREE(sampass);
    75         return ret;
    76 }
    77 
    7827
    7928/** Check a plaintext username/password
     
    8635                             void *my_private_data,
    8736                             TALLOC_CTX *mem_ctx,
    88                              const auth_usersupplied_info *user_info,
    89                              auth_serversupplied_info **server_info)
     37                             const struct auth_usersupplied_info *user_info,
     38                             struct auth_serversupplied_info **server_info)
    9039{
    9140        NTSTATUS nt_status;
    9241        struct passwd *pass = NULL;
    9342
     43        DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
     44
    9445        become_root();
    95         pass = Get_Pwnam_alloc(talloc_tos(), user_info->internal_username);
     46        pass = Get_Pwnam_alloc(talloc_tos(), user_info->mapped.account_name);
    9647
    97        
    9848        /** @todo This call assumes a ASCII password, no charset transformation is
    9949            done.  We may need to revisit this **/
    10050        nt_status = pass_check(pass,
    101                                 pass ? pass->pw_name : user_info->internal_username,
    102                                 (char *)user_info->plaintext_password.data,
    103                                 user_info->plaintext_password.length-1,
    104                                 lp_update_encrypted() ?
    105                                 update_smbpassword_file : NULL,
    106                                 True);
    107        
     51                                pass ? pass->pw_name : user_info->mapped.account_name,
     52                               smbd_server_conn->client_id.name,
     53                                user_info->password.plaintext,
     54                                true);
     55
    10856        unbecome_root();
    10957
    11058        if (NT_STATUS_IS_OK(nt_status)) {
    11159                if (pass) {
    112                         /* if a real user check pam account restrictions */
    113                         /* only really perfomed if "obey pam restriction" is true */
    114                         nt_status = smb_pam_accountcheck(pass->pw_name);
    115                         if (  !NT_STATUS_IS_OK(nt_status)) {
    116                                 DEBUG(1, ("PAM account restriction prevents user login\n"));
    117                         } else {
    118                                 make_server_info_pw(server_info, pass->pw_name, pass);
    119                         }
     60                        make_server_info_pw(server_info, pass->pw_name, pass);
    12061                } else {
    12162                        /* we need to do somthing more useful here */
     
    13172static NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
    13273{
    133         if (!make_auth_methods(auth_context, auth_method)) {
     74        struct auth_methods *result;
     75
     76        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     77        if (result == NULL) {
    13478                return NT_STATUS_NO_MEMORY;
    13579        }
     80        result->name = "unix";
     81        result->auth = check_unix_security;
    13682
    137         (*auth_method)->name = "unix";
    138         (*auth_method)->auth = check_unix_security;
     83        *auth_method = result;
    13984        return NT_STATUS_OK;
    14085}
  • trunk/server/source3/auth/auth_util.c

    r596 r745  
    1212   the Free Software Foundation; either version 3 of the License, or
    1313   (at your option) any later version.
    14    
     14
    1515   This program is distributed in the hope that it will be useful,
    1616   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1717   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1818   GNU General Public License for more details.
    19    
     19
    2020   You should have received a copy of the GNU General Public License
    2121   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2323
    2424#include "includes.h"
    25 #include "smbd/globals.h"
     25#include "auth.h"
    2626#include "../libcli/auth/libcli_auth.h"
     27#include "../lib/crypto/arcfour.h"
     28#include "rpc_client/init_lsa.h"
     29#include "../libcli/security/security.h"
     30#include "../lib/util/util_pw.h"
     31#include "lib/winbind_util.h"
     32#include "passdb.h"
    2733
    2834#undef DBGC_CLASS
    2935#define DBGC_CLASS DBGC_AUTH
    30 
    31 /****************************************************************************
    32  Ensure primary group SID is always at position 0 in a
    33  auth_serversupplied_info struct.
    34 ****************************************************************************/
    35 
    36 static void sort_sid_array_for_smbd(auth_serversupplied_info *result,
    37                                 const DOM_SID *pgroup_sid)
    38 {
    39         unsigned int i;
    40 
    41         if (!result->sids) {
    42                 return;
    43         }
    44 
    45         if (sid_compare(&result->sids[0], pgroup_sid)==0) {
    46                 return;
    47         }
    48 
    49         for (i = 1; i < result->num_sids; i++) {
    50                 if (sid_compare(pgroup_sid,
    51                                 &result->sids[i]) == 0) {
    52                         sid_copy(&result->sids[i], &result->sids[0]);
    53                         sid_copy(&result->sids[0], pgroup_sid);
    54                         return;
    55                 }
    56         }
    57 }
    5836
    5937/****************************************************************************
     
    10583
    10684/****************************************************************************
    107  Create an auth_usersupplied_data structure
    108 ****************************************************************************/
    109 
    110 static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
    111                                const char *smb_name,
    112                                const char *internal_username,
    113                                const char *client_domain,
    114                                const char *domain,
    115                                const char *wksta_name,
    116                                DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
    117                                DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
    118                                DATA_BLOB *plaintext,
    119                                bool encrypted)
    120 {
    121 
    122         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
    123 
    124         *user_info = SMB_MALLOC_P(auth_usersupplied_info);
    125         if (*user_info == NULL) {
    126                 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
    127                 return NT_STATUS_NO_MEMORY;
    128         }
    129 
    130         ZERO_STRUCTP(*user_info);
    131 
    132         DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
    133 
    134         (*user_info)->smb_name = SMB_STRDUP(smb_name);
    135         if ((*user_info)->smb_name == NULL) {
    136                 free_user_info(user_info);
    137                 return NT_STATUS_NO_MEMORY;
    138         }
    139        
    140         (*user_info)->internal_username = SMB_STRDUP(internal_username);
    141         if ((*user_info)->internal_username == NULL) {
    142                 free_user_info(user_info);
    143                 return NT_STATUS_NO_MEMORY;
    144         }
    145 
    146         (*user_info)->domain = SMB_STRDUP(domain);
    147         if ((*user_info)->domain == NULL) {
    148                 free_user_info(user_info);
    149                 return NT_STATUS_NO_MEMORY;
    150         }
    151 
    152         (*user_info)->client_domain = SMB_STRDUP(client_domain);
    153         if ((*user_info)->client_domain == NULL) {
    154                 free_user_info(user_info);
    155                 return NT_STATUS_NO_MEMORY;
    156         }
    157 
    158         (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
    159         if ((*user_info)->wksta_name == NULL) {
    160                 free_user_info(user_info);
    161                 return NT_STATUS_NO_MEMORY;
    162         }
    163 
    164         DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
    165 
    166         if (lm_pwd)
    167                 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
    168         if (nt_pwd)
    169                 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
    170         if (lm_interactive_pwd)
    171                 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
    172         if (nt_interactive_pwd)
    173                 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
    174 
    175         if (plaintext)
    176                 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
    177 
    178         (*user_info)->encrypted = encrypted;
    179 
    180         (*user_info)->logon_parameters = 0;
    181 
    182         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
    183 
    184         return NT_STATUS_OK;
    185 }
    186 
    187 /****************************************************************************
    18885 Create an auth_usersupplied_data structure after appropriate mapping.
    18986****************************************************************************/
    19087
    191 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
     88NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
    19289                            const char *smb_name,
    19390                            const char *client_domain,
    194                             const char *wksta_name,
     91                            const char *workstation_name,
    19592                            DATA_BLOB *lm_pwd,
    19693                            DATA_BLOB *nt_pwd,
    197                             DATA_BLOB *lm_interactive_pwd,
    198                             DATA_BLOB *nt_interactive_pwd,
    199                             DATA_BLOB *plaintext,
    200                             bool encrypted)
    201 {
    202         struct smbd_server_connection *sconn = smbd_server_conn;
     94                            const struct samr_Password *lm_interactive_pwd,
     95                            const struct samr_Password *nt_interactive_pwd,
     96                            const char *plaintext,
     97                            enum auth_password_state password_state)
     98{
    20399        const char *domain;
    204100        NTSTATUS result;
    205101        bool was_mapped;
    206         fstring internal_username;
    207         fstrcpy(internal_username, smb_name);
    208         was_mapped = map_username(sconn, internal_username);
     102        char *internal_username = NULL;
     103
     104        was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
     105        if (!internal_username) {
     106                return NT_STATUS_NO_MEMORY;
     107        }
    209108
    210109        DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
    211                  client_domain, smb_name, wksta_name));
     110                 client_domain, smb_name, workstation_name));
    212111
    213112        domain = client_domain;
     
    230129                DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
    231130                          "workstation [%s]\n",
    232                           client_domain, domain, smb_name, wksta_name));
     131                          client_domain, domain, smb_name, workstation_name));
    233132        }
    234133
     
    238137
    239138        result = make_user_info(user_info, smb_name, internal_username,
    240                               client_domain, domain, wksta_name,
     139                              client_domain, domain, workstation_name,
    241140                              lm_pwd, nt_pwd,
    242141                              lm_interactive_pwd, nt_interactive_pwd,
    243                               plaintext, encrypted);
     142                              plaintext, password_state);
    244143        if (NT_STATUS_IS_OK(result)) {
     144                /* We have tried mapping */
     145                (*user_info)->mapped_state = True;
     146                /* did we actually map the user to a different name? */
    245147                (*user_info)->was_mapped = was_mapped;
    246148        }
     
    253155****************************************************************************/
    254156
    255 bool make_user_info_netlogon_network(auth_usersupplied_info **user_info,
     157bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
    256158                                     const char *smb_name,
    257159                                     const char *client_domain,
    258                                      const char *wksta_name,
     160                                     const char *workstation_name,
    259161                                     uint32 logon_parameters,
    260162                                     const uchar *lm_network_pwd,
     
    270172        status = make_user_info_map(user_info,
    271173                                    smb_name, client_domain,
    272                                     wksta_name,
     174                                    workstation_name,
    273175                                    lm_pwd_len ? &lm_blob : NULL,
    274176                                    nt_pwd_len ? &nt_blob : NULL,
    275177                                    NULL, NULL, NULL,
    276                                     True);
     178                                    AUTH_PASSWORD_RESPONSE);
    277179
    278180        if (NT_STATUS_IS_OK(status)) {
     
    291193****************************************************************************/
    292194
    293 bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
     195bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
    294196                                         const char *smb_name,
    295197                                         const char *client_domain,
    296                                          const char *wksta_name,
     198                                         const char *workstation_name,
    297199                                         uint32 logon_parameters,
    298200                                         const uchar chal[8],
     
    301203                                         const uchar *dc_sess_key)
    302204{
    303         unsigned char lm_pwd[16];
    304         unsigned char nt_pwd[16];
     205        struct samr_Password lm_pwd;
     206        struct samr_Password nt_pwd;
    305207        unsigned char local_lm_response[24];
    306208        unsigned char local_nt_response[24];
    307209        unsigned char key[16];
    308        
     210
    309211        memcpy(key, dc_sess_key, 16);
    310        
     212
    311213        if (lm_interactive_pwd)
    312                 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
     214                memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
    313215
    314216        if (nt_interactive_pwd)
    315                 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
    316        
     217                memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
     218
    317219#ifdef DEBUG_PASSWORD
    318220        DEBUG(100,("key:"));
    319221        dump_data(100, key, sizeof(key));
    320        
     222
    321223        DEBUG(100,("lm owf password:"));
    322         dump_data(100, lm_pwd, sizeof(lm_pwd));
    323        
     224        dump_data(100, lm_pwd.hash, sizeof(lm_pwd.hash));
     225
    324226        DEBUG(100,("nt owf password:"));
    325         dump_data(100, nt_pwd, sizeof(nt_pwd));
     227        dump_data(100, nt_pwd.hash, sizeof(nt_pwd.hash));
    326228#endif
    327        
     229
    328230        if (lm_interactive_pwd)
    329                 arcfour_crypt(lm_pwd, key, sizeof(lm_pwd));
    330        
     231                arcfour_crypt(lm_pwd.hash, key, sizeof(lm_pwd.hash));
     232
    331233        if (nt_interactive_pwd)
    332                 arcfour_crypt(nt_pwd, key, sizeof(nt_pwd));
    333        
     234                arcfour_crypt(nt_pwd.hash, key, sizeof(nt_pwd.hash));
     235
    334236#ifdef DEBUG_PASSWORD
    335237        DEBUG(100,("decrypt of lm owf password:"));
    336         dump_data(100, lm_pwd, sizeof(lm_pwd));
    337        
     238        dump_data(100, lm_pwd.hash, sizeof(lm_pwd));
     239
    338240        DEBUG(100,("decrypt of nt owf password:"));
    339         dump_data(100, nt_pwd, sizeof(nt_pwd));
     241        dump_data(100, nt_pwd.hash, sizeof(nt_pwd));
    340242#endif
    341        
     243
    342244        if (lm_interactive_pwd)
    343                 SMBOWFencrypt(lm_pwd, chal,
     245                SMBOWFencrypt(lm_pwd.hash, chal,
    344246                              local_lm_response);
    345247
    346248        if (nt_interactive_pwd)
    347                 SMBOWFencrypt(nt_pwd, chal,
     249                SMBOWFencrypt(nt_pwd.hash, chal,
    348250                              local_nt_response);
    349        
     251
    350252        /* Password info paranoia */
    351253        ZERO_STRUCT(key);
     
    357259                DATA_BLOB local_nt_blob;
    358260
    359                 DATA_BLOB lm_interactive_blob;
    360                 DATA_BLOB nt_interactive_blob;
    361                
    362261                if (lm_interactive_pwd) {
    363262                        local_lm_blob = data_blob(local_lm_response,
    364263                                                  sizeof(local_lm_response));
    365                         lm_interactive_blob = data_blob(lm_pwd,
    366                                                         sizeof(lm_pwd));
    367                         ZERO_STRUCT(lm_pwd);
    368264                }
    369                
     265
    370266                if (nt_interactive_pwd) {
    371267                        local_nt_blob = data_blob(local_nt_response,
    372268                                                  sizeof(local_nt_response));
    373                         nt_interactive_blob = data_blob(nt_pwd,
    374                                                         sizeof(nt_pwd));
    375                         ZERO_STRUCT(nt_pwd);
    376269                }
    377270
    378271                nt_status = make_user_info_map(
    379272                        user_info,
    380                         smb_name, client_domain, wksta_name,
     273                        smb_name, client_domain, workstation_name,
    381274                        lm_interactive_pwd ? &local_lm_blob : NULL,
    382275                        nt_interactive_pwd ? &local_nt_blob : NULL,
    383                         lm_interactive_pwd ? &lm_interactive_blob : NULL,
    384                         nt_interactive_pwd ? &nt_interactive_blob : NULL,
    385                         NULL, True);
     276                        lm_interactive_pwd ? &lm_pwd : NULL,
     277                        nt_interactive_pwd ? &nt_pwd : NULL,
     278                        NULL, AUTH_PASSWORD_HASH);
    386279
    387280                if (NT_STATUS_IS_OK(nt_status)) {
     
    392285                data_blob_free(&local_lm_blob);
    393286                data_blob_free(&local_nt_blob);
    394                 data_blob_free(&lm_interactive_blob);
    395                 data_blob_free(&nt_interactive_blob);
    396287                return ret;
    397288        }
     
    403294****************************************************************************/
    404295
    405 bool make_user_info_for_reply(auth_usersupplied_info **user_info,
     296bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
    406297                              const char *smb_name,
    407298                              const char *client_domain,
     
    413304        DATA_BLOB local_nt_blob;
    414305        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    415                        
     306        char *plaintext_password_string;
    416307        /*
    417308         * Not encrypted - do so.
    418309         */
    419        
     310
    420311        DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
    421312                 "format.\n"));
    422        
    423         if (plaintext_password.data) {
     313        if (plaintext_password.data && plaintext_password.length) {
    424314                unsigned char local_lm_response[24];
    425                
     315
    426316#ifdef DEBUG_PASSWORD
    427317                DEBUG(10,("Unencrypted password (len %d):\n",
     
    434324                            (const uchar*)chal, local_lm_response);
    435325                local_lm_blob = data_blob(local_lm_response, 24);
    436                
     326
    437327                /* We can't do an NT hash here, as the password needs to be
    438328                   case insensitive */
    439329                local_nt_blob = data_blob_null;
    440                
    441330        } else {
    442331                local_lm_blob = data_blob_null;
    443332                local_nt_blob = data_blob_null;
    444333        }
    445        
     334
     335        plaintext_password_string = talloc_strndup(talloc_tos(),
     336                                                   (const char *)plaintext_password.data,
     337                                                   plaintext_password.length);
     338        if (!plaintext_password_string) {
     339                return False;
     340        }
     341
    446342        ret = make_user_info_map(
    447343                user_info, smb_name, client_domain,
     
    450346                local_nt_blob.data ? &local_nt_blob : NULL,
    451347                NULL, NULL,
    452                 plaintext_password.data ? &plaintext_password : NULL,
    453                 False);
    454        
     348                plaintext_password_string,
     349                AUTH_PASSWORD_PLAIN);
     350
     351        if (plaintext_password_string) {
     352                memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
     353                talloc_free(plaintext_password_string);
     354        }
     355
    455356        data_blob_free(&local_lm_blob);
    456357        return NT_STATUS_IS_OK(ret) ? True : False;
     
    461362****************************************************************************/
    462363
    463 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
     364NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
    464365                                      const char *smb_name,
    465366                                      const char *client_domain,
     
    472373                                  nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
    473374                                  NULL, NULL, NULL,
    474                                   True);
     375                                  AUTH_PASSWORD_RESPONSE);
    475376}
    476377
     
    479380****************************************************************************/
    480381
    481 bool make_user_info_guest(auth_usersupplied_info **user_info)
     382bool make_user_info_guest(struct auth_usersupplied_info **user_info)
    482383{
    483384        NTSTATUS nt_status;
     
    490391                                   NULL, NULL,
    491392                                   NULL,
    492                                    True);
    493                              
     393                                   AUTH_PASSWORD_RESPONSE);
     394
    494395        return NT_STATUS_IS_OK(nt_status) ? True : False;
    495396}
    496397
    497 static int server_info_dtor(auth_serversupplied_info *server_info)
    498 {
    499         TALLOC_FREE(server_info->sam_account);
    500         ZERO_STRUCTP(server_info);
    501         return 0;
    502 }
    503 
    504 /***************************************************************************
    505  Make a server_info struct. Free with TALLOC_FREE().
    506 ***************************************************************************/
    507 
    508 static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
    509 {
    510         struct auth_serversupplied_info *result;
    511 
    512         result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
    513         if (result == NULL) {
    514                 DEBUG(0, ("talloc failed\n"));
    515                 return NULL;
    516         }
    517 
    518         talloc_set_destructor(result, server_info_dtor);
    519 
    520         /* Initialise the uid and gid values to something non-zero
    521            which may save us from giving away root access if there
    522            is a bug in allocating these fields. */
    523 
    524         result->utok.uid = -1;
    525         result->utok.gid = -1;
    526         return result;
    527 }
    528 
    529 static char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
    530 {
    531         fstring tmp;
    532 
    533         alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
    534         return talloc_strdup(mem_ctx, tmp);
    535 }
    536 
    537 /***************************************************************************
    538  Is the incoming username our own machine account ?
    539  If so, the connection is almost certainly from winbindd.
    540 ***************************************************************************/
    541 
    542 static bool is_our_machine_account(const char *username)
    543 {
    544         bool ret;
    545         char *truncname = NULL;
    546         size_t ulen = strlen(username);
    547 
    548         if (ulen == 0 || username[ulen-1] != '$') {
    549                 return false;
    550         }
    551         truncname = SMB_STRDUP(username);
    552         if (!truncname) {
    553                 return false;
    554         }
    555         truncname[ulen-1] = '\0';
    556         ret = strequal(truncname, global_myname());
    557         SAFE_FREE(truncname);
    558         return ret;
    559 }
    560 
    561 /***************************************************************************
    562  Make (and fill) a user_info struct from a struct samu
    563 ***************************************************************************/
    564 
    565 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
    566                               struct samu *sampass)
    567 {
    568         struct passwd *pwd;
    569         gid_t *gids;
    570         auth_serversupplied_info *result;
    571         const char *username = pdb_get_username(sampass);
    572         NTSTATUS status;
    573 
    574         if ( !(result = make_server_info(NULL)) ) {
    575                 return NT_STATUS_NO_MEMORY;
    576         }
    577 
    578         if ( !(pwd = Get_Pwnam_alloc(result, username)) ) {
    579                 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
    580                           pdb_get_username(sampass)));
    581                 TALLOC_FREE(result);
    582                 return NT_STATUS_NO_SUCH_USER;
    583         }
    584 
    585         result->sam_account = sampass;
    586         result->unix_name = pwd->pw_name;
    587         /* Ensure that we keep pwd->pw_name, because we will free pwd below */
    588         talloc_steal(result, pwd->pw_name);
    589         result->utok.gid = pwd->pw_gid;
    590         result->utok.uid = pwd->pw_uid;
    591 
    592         TALLOC_FREE(pwd);
    593 
    594         result->sanitized_username = sanitize_username(result,
    595                                                        result->unix_name);
    596         if (result->sanitized_username == NULL) {
    597                 TALLOC_FREE(result);
    598                 return NT_STATUS_NO_MEMORY;
    599         }
    600 
    601         if (IS_DC && is_our_machine_account(username)) {
    602                 /*
    603                  * Ensure for a connection from our own
    604                  * machine account (from winbindd on a DC)
    605                  * there are no supplementary groups.
    606                  * Prevents loops in calling gid_to_sid().
    607                  */
    608                 result->sids = NULL;
    609                 gids = NULL;
    610                 result->num_sids = 0;
    611 
    612                 /*
    613                  * This is a hack of monstrous proportions.
    614                  * If we know it's winbindd talking to us,
    615                  * we know we must never recurse into it,
    616                  * so turn off contacting winbindd for this
    617                  * entire process. This will get fixed when
    618                  * winbindd doesn't need to talk to smbd on
    619                  * a PDC. JRA.
    620                  */
    621 
    622                 (void)winbind_off();
    623 
    624                 DEBUG(10, ("make_server_info_sam: our machine account %s "
    625                         "setting supplementary group list empty and "
    626                         "turning off winbindd requests.\n",
    627                         username));
    628         } else {
    629                 status = pdb_enum_group_memberships(result, sampass,
    630                                             &result->sids, &gids,
    631                                             &result->num_sids);
    632 
    633                 if (!NT_STATUS_IS_OK(status)) {
    634                         DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
    635                                    nt_errstr(status)));
    636                         result->sam_account = NULL; /* Don't free on error exit. */
    637                         TALLOC_FREE(result);
    638                         return status;
    639                 }
    640         }
    641 
    642         /* For now we throw away the gids and convert via sid_to_gid
    643          * later. This needs fixing, but I'd like to get the code straight and
    644          * simple first. */
    645          
    646         TALLOC_FREE(gids);
    647 
    648         DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
    649                  pdb_get_username(sampass), result->unix_name));
    650 
    651         *server_info = result;
    652         /* Ensure that the sampass will be freed with the result */
    653         talloc_steal(result, sampass);
    654 
    655         return NT_STATUS_OK;
    656 }
    657 
    658 static NTSTATUS log_nt_token(NT_USER_TOKEN *token)
     398static NTSTATUS log_nt_token(struct security_token *token)
    659399{
    660400        TALLOC_CTX *frame = talloc_stackframe();
     
    673413                group_sidstr = talloc_asprintf(
    674414                        frame, "%s %s", group_sidstr,
    675                         sid_string_talloc(frame, &token->user_sids[i]));
     415                        sid_string_talloc(frame, &token->sids[i]));
    676416        }
    677417
    678418        command = talloc_string_sub(
    679419                frame, lp_log_nt_token_command(),
    680                 "%s", sid_string_talloc(frame, &token->user_sids[0]));
     420                "%s", sid_string_talloc(frame, &token->sids[0]));
    681421        command = talloc_string_sub(frame, command, "%t", group_sidstr);
    682422
     
    698438
    699439/*
    700  * Create the token to use from server_info->sam_account and
     440 * Create the token to use from server_info->info3 and
    701441 * server_info->sids (the info3/sam groups). Find the unix gids.
    702442 */
    703443
    704 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
    705 {
     444NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
     445{
     446        struct security_token *t;
    706447        NTSTATUS status;
    707448        size_t i;
    708449        struct dom_sid tmp_sid;
     450        struct wbcUnixId *ids;
    709451
    710452        /*
     
    722464                                                    &server_info->utok.gid,
    723465                                                    &server_info->unix_name,
    724                                                     &server_info->ptok);
     466                                                    &server_info->security_token);
    725467
    726468        } else {
    727                 server_info->ptok = create_local_nt_token(
    728                         server_info,
    729                         pdb_get_user_sid(server_info->sam_account),
    730                         server_info->guest,
    731                         server_info->num_sids, server_info->sids);
    732                 status = server_info->ptok ?
    733                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
     469                status = create_local_nt_token_from_info3(server_info,
     470                                                          server_info->guest,
     471                                                          server_info->info3,
     472                                                          &server_info->extra,
     473                                                          &server_info->security_token);
    734474        }
    735475
     
    743483        server_info->utok.groups = NULL;
    744484
     485        t = server_info->security_token;
     486
     487        ids = TALLOC_ARRAY(talloc_tos(), struct wbcUnixId,
     488                           t->num_sids);
     489        if (ids == NULL) {
     490                return NT_STATUS_NO_MEMORY;
     491        }
     492
     493        if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) {
     494                TALLOC_FREE(ids);
     495                return NT_STATUS_NO_MEMORY;
     496        }
     497
    745498        /* Start at index 1, where the groups start. */
    746499
    747         for (i=1; i<server_info->ptok->num_sids; i++) {
    748                 gid_t gid;
    749                 DOM_SID *sid = &server_info->ptok->user_sids[i];
    750 
    751                 if (!sid_to_gid(sid, &gid)) {
     500        for (i=1; i<t->num_sids; i++) {
     501
     502                if (ids[i].type != WBC_ID_TYPE_GID) {
    752503                        DEBUG(10, ("Could not convert SID %s to gid, "
    753                                    "ignoring it\n", sid_string_dbg(sid)));
     504                                   "ignoring it\n",
     505                                   sid_string_dbg(&t->sids[i])));
    754506                        continue;
    755507                }
    756                 add_gid_to_array_unique(server_info, gid,
    757                                         &server_info->utok.groups,
    758                                         &server_info->utok.ngroups);
     508                if (!add_gid_to_array_unique(server_info, ids[i].id.gid,
     509                                             &server_info->utok.groups,
     510                                             &server_info->utok.ngroups)) {
     511                        return NT_STATUS_NO_MEMORY;
     512                }
    759513        }
    760514
     
    772526         */
    773527
    774         if (!uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid)) {
    775                 DEBUG(1,("create_local_token: Failed to create SID "
    776                         "for uid %u!\n", (unsigned int)server_info->utok.uid));
    777         }
    778         add_sid_to_array_unique(server_info->ptok, &tmp_sid,
    779                                 &server_info->ptok->user_sids,
    780                                 &server_info->ptok->num_sids);
     528        uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid);
     529
     530        add_sid_to_array_unique(server_info->security_token, &tmp_sid,
     531                                &server_info->security_token->sids,
     532                                &server_info->security_token->num_sids);
    781533
    782534        for ( i=0; i<server_info->utok.ngroups; i++ ) {
    783                 if (!gid_to_unix_groups_sid( server_info->utok.groups[i], &tmp_sid ) ) {
    784                         DEBUG(1,("create_local_token: Failed to create SID "
    785                                 "for gid %u!\n", (unsigned int)server_info->utok.groups[i]));
    786                         continue;
    787                 }
    788                 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
    789                                         &server_info->ptok->user_sids,
    790                                         &server_info->ptok->num_sids);
    791         }
    792 
    793         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
     535                gid_to_unix_groups_sid(server_info->utok.groups[i], &tmp_sid);
     536                add_sid_to_array_unique(server_info->security_token, &tmp_sid,
     537                                        &server_info->security_token->sids,
     538                                        &server_info->security_token->num_sids);
     539        }
     540
     541        security_token_debug(DBGC_AUTH, 10, server_info->security_token);
    794542        debug_unix_user_token(DBGC_AUTH, 10,
    795543                              server_info->utok.uid,
     
    798546                              server_info->utok.groups);
    799547
    800         status = log_nt_token(server_info->ptok);
     548        status = log_nt_token(server_info->security_token);
    801549        return status;
    802 }
    803 
    804 /*
    805  * Create an artificial NT token given just a username. (Initially intended
    806  * for force user)
    807  *
    808  * We go through lookup_name() to avoid problems we had with 'winbind use
    809  * default domain'.
    810  *
    811  * We have 3 cases:
    812  *
    813  * unmapped unix users: Go directly to nss to find the user's group.
    814  *
    815  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
    816  *
    817  * If the user is provided by winbind, the primary gid is set to "domain
    818  * users" of the user's domain. For an explanation why this is necessary, see
    819  * the thread starting at
    820  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
    821  */
    822 
    823 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
    824                                     bool is_guest,
    825                                     uid_t *uid, gid_t *gid,
    826                                     char **found_username,
    827                                     struct nt_user_token **token)
    828 {
    829         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
    830         TALLOC_CTX *tmp_ctx;
    831         DOM_SID user_sid;
    832         enum lsa_SidType type;
    833         gid_t *gids;
    834         DOM_SID *group_sids;
    835         DOM_SID unix_group_sid;
    836         size_t num_group_sids;
    837         size_t num_gids;
    838         size_t i;
    839 
    840         tmp_ctx = talloc_new(NULL);
    841         if (tmp_ctx == NULL) {
    842                 DEBUG(0, ("talloc_new failed\n"));
    843                 return NT_STATUS_NO_MEMORY;
    844         }
    845 
    846         if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
    847                          NULL, NULL, &user_sid, &type)) {
    848                 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
    849                 goto done;
    850         }
    851 
    852         if (type != SID_NAME_USER) {
    853                 DEBUG(1, ("%s is a %s, not a user\n", username,
    854                           sid_type_lookup(type)));
    855                 goto done;
    856         }
    857 
    858         if (sid_check_is_in_our_domain(&user_sid)) {
    859                 bool ret;
    860 
    861                 /* This is a passdb user, so ask passdb */
    862 
    863                 struct samu *sam_acct = NULL;
    864 
    865                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
    866                         result = NT_STATUS_NO_MEMORY;
    867                         goto done;
    868                 }
    869 
    870                 become_root();
    871                 ret = pdb_getsampwsid(sam_acct, &user_sid);
    872                 unbecome_root();
    873 
    874                 if (!ret) {
    875                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
    876                                   sid_string_dbg(&user_sid), username));
    877                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
    878                         goto unix_user;
    879                 }
    880 
    881                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
    882                                                     &group_sids, &gids,
    883                                                     &num_group_sids);
    884                 if (!NT_STATUS_IS_OK(result)) {
    885                         DEBUG(1, ("enum_group_memberships failed for %s (%s): "
    886                                   "%s\n", username, sid_string_dbg(&user_sid),
    887                                   nt_errstr(result)));
    888                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
    889                         goto unix_user;
    890                 }
    891 
    892                 /* see the smb_panic() in pdb_default_enum_group_memberships */
    893                 SMB_ASSERT(num_group_sids > 0);
    894 
    895                 *gid = gids[0];
    896 
    897                 /* Ensure we're returning the found_username on the right context. */
    898                 *found_username = talloc_strdup(mem_ctx,
    899                                                 pdb_get_username(sam_acct));
    900 
    901                 /*
    902                  * If the SID from lookup_name() was the guest sid, passdb knows
    903                  * about the mapping of guest sid to lp_guestaccount()
    904                  * username and will return the unix_pw info for a guest
    905                  * user. Use it if it's there, else lookup the *uid details
    906                  * using Get_Pwnam_alloc(). See bug #6291 for details. JRA.
    907                  */
    908 
    909                 /* We must always assign the *uid. */
    910                 if (sam_acct->unix_pw == NULL) {
    911                         struct passwd *pwd = Get_Pwnam_alloc(sam_acct, *found_username );
    912                         if (!pwd) {
    913                                 DEBUG(10, ("Get_Pwnam_alloc failed for %s\n",
    914                                         *found_username));
    915                                 result = NT_STATUS_NO_SUCH_USER;
    916                                 goto done;
    917                         }
    918                         result = samu_set_unix(sam_acct, pwd );
    919                         if (!NT_STATUS_IS_OK(result)) {
    920                                 DEBUG(10, ("samu_set_unix failed for %s\n",
    921                                         *found_username));
    922                                 result = NT_STATUS_NO_SUCH_USER;
    923                                 goto done;
    924                         }
    925                 }
    926                 *uid = sam_acct->unix_pw->pw_uid;
    927 
    928         } else  if (sid_check_is_in_unix_users(&user_sid)) {
    929 
    930                 /* This is a unix user not in passdb. We need to ask nss
    931                  * directly, without consulting passdb */
    932 
    933                 struct passwd *pass;
    934 
    935                 /*
    936                  * This goto target is used as a fallback for the passdb
    937                  * case. The concrete bug report is when passdb gave us an
    938                  * unmapped gid.
    939                  */
    940 
    941         unix_user:
    942 
    943                 if (!sid_to_uid(&user_sid, uid)) {
    944                         DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n",
    945                                   username, sid_string_dbg(&user_sid)));
    946                         result = NT_STATUS_NO_SUCH_USER;
    947                         goto done;
    948                 }
    949 
    950                 uid_to_unix_users_sid(*uid, &user_sid);
    951 
    952                 pass = getpwuid_alloc(tmp_ctx, *uid);
    953                 if (pass == NULL) {
    954                         DEBUG(1, ("getpwuid(%u) for user %s failed\n",
    955                                   (unsigned int)*uid, username));
    956                         goto done;
    957                 }
    958 
    959                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
    960                                          &gids, &num_group_sids)) {
    961                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
    962                                   username));
    963                         goto done;
    964                 }
    965 
    966                 if (num_group_sids) {
    967                         group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
    968                         if (group_sids == NULL) {
    969                                 DEBUG(1, ("TALLOC_ARRAY failed\n"));
    970                                 result = NT_STATUS_NO_MEMORY;
    971                                 goto done;
    972                         }
    973                 } else {
    974                         group_sids = NULL;
    975                 }
    976 
    977                 for (i=0; i<num_group_sids; i++) {
    978                         gid_to_sid(&group_sids[i], gids[i]);
    979                 }
    980 
    981                 /* In getgroups_unix_user we always set the primary gid */
    982                 SMB_ASSERT(num_group_sids > 0);
    983 
    984                 *gid = gids[0];
    985 
    986                 /* Ensure we're returning the found_username on the right context. */
    987                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
    988         } else {
    989 
    990                 /* This user is from winbind, force the primary gid to the
    991                  * user's "domain users" group. Under certain circumstances
    992                  * (user comes from NT4), this might be a loss of
    993                  * information. But we can not rely on winbind getting the
    994                  * correct info. AD might prohibit winbind looking up that
    995                  * information. */
    996 
    997                 uint32 dummy;
    998 
    999                 /* We must always assign the *uid. */
    1000                 if (!sid_to_uid(&user_sid, uid)) {
    1001                         DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n",
    1002                                   username, sid_string_dbg(&user_sid)));
    1003                         result = NT_STATUS_NO_SUCH_USER;
    1004                         goto done;
    1005                 }
    1006 
    1007                 num_group_sids = 1;
    1008                 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
    1009                 if (group_sids == NULL) {
    1010                         DEBUG(1, ("TALLOC_ARRAY failed\n"));
    1011                         result = NT_STATUS_NO_MEMORY;
    1012                         goto done;
    1013                 }
    1014 
    1015                 sid_copy(&group_sids[0], &user_sid);
    1016                 sid_split_rid(&group_sids[0], &dummy);
    1017                 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
    1018 
    1019                 if (!sid_to_gid(&group_sids[0], gid)) {
    1020                         DEBUG(1, ("sid_to_gid(%s) failed\n",
    1021                                   sid_string_dbg(&group_sids[0])));
    1022                         goto done;
    1023                 }
    1024 
    1025                 gids = gid;
    1026 
    1027                 /* Ensure we're returning the found_username on the right context. */
    1028                 *found_username = talloc_strdup(mem_ctx, username);
    1029         }
    1030 
    1031         /* Add the "Unix Group" SID for each gid to catch mapped groups
    1032            and their Unix equivalent.  This is to solve the backwards
    1033            compatibility problem of 'valid users = +ntadmin' where
    1034            ntadmin has been paired with "Domain Admins" in the group
    1035            mapping table.  Otherwise smb.conf would need to be changed
    1036            to 'valid user = "Domain Admins"'.  --jerry */
    1037 
    1038         num_gids = num_group_sids;
    1039         for ( i=0; i<num_gids; i++ ) {
    1040                 gid_t high, low;
    1041 
    1042                 /* don't pickup anything managed by Winbind */
    1043 
    1044                 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
    1045                         continue;
    1046 
    1047                 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
    1048                         DEBUG(1,("create_token_from_username: Failed to create SID "
    1049                                 "for gid %u!\n", (unsigned int)gids[i]));
    1050                         continue;
    1051                 }
    1052                 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
    1053                                                  &group_sids, &num_group_sids);
    1054                 if (!NT_STATUS_IS_OK(result)) {
    1055                         goto done;
    1056                 }
    1057         }
    1058 
    1059         /* Ensure we're creating the nt_token on the right context. */
    1060         *token = create_local_nt_token(mem_ctx, &user_sid,
    1061                                        is_guest, num_group_sids, group_sids);
    1062 
    1063         if ((*token == NULL) || (*found_username == NULL)) {
    1064                 result = NT_STATUS_NO_MEMORY;
    1065                 goto done;
    1066         }
    1067 
    1068         result = NT_STATUS_OK;
    1069  done:
    1070         TALLOC_FREE(tmp_ctx);
    1071         return result;
    1072 }
    1073 
    1074 /***************************************************************************
    1075  Build upon create_token_from_username:
    1076 
    1077  Expensive helper function to figure out whether a user given its name is
    1078  member of a particular group.
    1079 ***************************************************************************/
    1080 
    1081 bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
    1082 {
    1083         NTSTATUS status;
    1084         uid_t uid;
    1085         gid_t gid;
    1086         char *found_username;
    1087         struct nt_user_token *token;
    1088         bool result;
    1089 
    1090         TALLOC_CTX *mem_ctx;
    1091 
    1092         mem_ctx = talloc_new(NULL);
    1093         if (mem_ctx == NULL) {
    1094                 DEBUG(0, ("talloc_new failed\n"));
    1095                 return False;
    1096         }
    1097 
    1098         status = create_token_from_username(mem_ctx, username, False,
    1099                                             &uid, &gid, &found_username,
    1100                                             &token);
    1101 
    1102         if (!NT_STATUS_IS_OK(status)) {
    1103                 DEBUG(10, ("could not create token for %s\n", username));
    1104                 return False;
    1105         }
    1106 
    1107         result = nt_token_check_sid(group_sid, token);
    1108 
    1109         TALLOC_FREE(mem_ctx);
    1110         return result;
    1111        
    1112 }
    1113 
    1114 bool user_in_group(const char *username, const char *groupname)
    1115 {
    1116         TALLOC_CTX *mem_ctx;
    1117         DOM_SID group_sid;
    1118         bool ret;
    1119 
    1120         mem_ctx = talloc_new(NULL);
    1121         if (mem_ctx == NULL) {
    1122                 DEBUG(0, ("talloc_new failed\n"));
    1123                 return False;
    1124         }
    1125 
    1126         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
    1127                           NULL, NULL, &group_sid, NULL);
    1128         TALLOC_FREE(mem_ctx);
    1129 
    1130         if (!ret) {
    1131                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
    1132                 return False;
    1133         }
    1134 
    1135         return user_in_group_sid(username, &group_sid);
    1136550}
    1137551
     
    1141555***************************************************************************/
    1142556
    1143 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
     557NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
    1144558                             char *unix_username,
    1145559                             struct passwd *pwd)
     
    1147561        NTSTATUS status;
    1148562        struct samu *sampass = NULL;
    1149         gid_t *gids;
    1150563        char *qualified_name = NULL;
    1151564        TALLOC_CTX *mem_ctx = NULL;
    1152         DOM_SID u_sid;
     565        struct dom_sid u_sid;
    1153566        enum lsa_SidType type;
    1154         auth_serversupplied_info *result;
    1155        
    1156         if ( !(sampass = samu_new( NULL )) ) {
    1157                 return NT_STATUS_NO_MEMORY;
    1158         }
    1159        
    1160         status = samu_set_unix( sampass, pwd );
    1161         if (!NT_STATUS_IS_OK(status)) {
    1162                 return status;
    1163         }
    1164 
    1165         result = make_server_info(NULL);
    1166         if (result == NULL) {
    1167                 TALLOC_FREE(sampass);
    1168                 return NT_STATUS_NO_MEMORY;
    1169         }
    1170 
    1171         result->sam_account = sampass;
    1172 
    1173         result->unix_name = talloc_strdup(result, unix_username);
    1174         result->sanitized_username = sanitize_username(result, unix_username);
    1175 
    1176         if ((result->unix_name == NULL)
    1177             || (result->sanitized_username == NULL)) {
    1178                 TALLOC_FREE(sampass);
    1179                 TALLOC_FREE(result);
    1180                 return NT_STATUS_NO_MEMORY;
    1181         }
    1182 
    1183         result->utok.uid = pwd->pw_uid;
    1184         result->utok.gid = pwd->pw_gid;
    1185 
    1186         status = pdb_enum_group_memberships(result, sampass,
    1187                                             &result->sids, &gids,
    1188                                             &result->num_sids);
    1189 
    1190         if (!NT_STATUS_IS_OK(status)) {
    1191                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
    1192                            nt_errstr(status)));
    1193                 TALLOC_FREE(result);
    1194                 return status;
    1195         }
     567        struct auth_serversupplied_info *result;
    1196568
    1197569        /*
     
    1210582        mem_ctx = talloc_init("make_server_info_pw_tmp");
    1211583        if (!mem_ctx) {
    1212                 TALLOC_FREE(result);
    1213584                return NT_STATUS_NO_MEMORY;
    1214585        }
     
    1218589                                        unix_username );
    1219590        if (!qualified_name) {
    1220                 TALLOC_FREE(result);
    1221591                TALLOC_FREE(mem_ctx);
    1222592                return NT_STATUS_NO_MEMORY;
     
    1226596                                                NULL, NULL,
    1227597                                                &u_sid, &type)) {
    1228                 TALLOC_FREE(result);
    1229598                TALLOC_FREE(mem_ctx);
    1230599                return NT_STATUS_NO_SUCH_USER;
     
    1234603
    1235604        if (type != SID_NAME_USER) {
    1236                 TALLOC_FREE(result);
    1237605                return NT_STATUS_NO_SUCH_USER;
    1238606        }
    1239607
    1240         status = add_sid_to_array_unique(result, &u_sid,
    1241                                          &result->sids,
    1242                                          &result->num_sids);
     608        if ( !(sampass = samu_new( NULL )) ) {
     609                return NT_STATUS_NO_MEMORY;
     610        }
     611
     612        status = samu_set_unix( sampass, pwd );
    1243613        if (!NT_STATUS_IS_OK(status)) {
     614                return status;
     615        }
     616
     617        /* In pathological cases the above call can set the account
     618         * name to the DOMAIN\username form. Reset the account name
     619         * using unix_username */
     620        pdb_set_username(sampass, unix_username, PDB_SET);
     621
     622        /* set the user sid to be the calculated u_sid */
     623        pdb_set_user_sid(sampass, &u_sid, PDB_SET);
     624
     625        result = make_server_info(NULL);
     626        if (result == NULL) {
     627                TALLOC_FREE(sampass);
     628                return NT_STATUS_NO_MEMORY;
     629        }
     630
     631        status = samu_to_SamInfo3(result, sampass, global_myname(),
     632                                  &result->info3, &result->extra);
     633        TALLOC_FREE(sampass);
     634        if (!NT_STATUS_IS_OK(status)) {
     635                DEBUG(10, ("Failed to convert samu to info3: %s\n",
     636                           nt_errstr(status)));
    1244637                TALLOC_FREE(result);
    1245638                return status;
    1246639        }
    1247640
    1248         /* For now we throw away the gids and convert via sid_to_gid
    1249          * later. This needs fixing, but I'd like to get the code straight and
    1250          * simple first. */
    1251         TALLOC_FREE(gids);
     641        result->unix_name = talloc_strdup(result, unix_username);
     642        result->sanitized_username = sanitize_username(result, unix_username);
     643
     644        if ((result->unix_name == NULL)
     645            || (result->sanitized_username == NULL)) {
     646                TALLOC_FREE(result);
     647                return NT_STATUS_NO_MEMORY;
     648        }
     649
     650        result->utok.uid = pwd->pw_uid;
     651        result->utok.gid = pwd->pw_gid;
    1252652
    1253653        *server_info = result;
    1254654
     655        return NT_STATUS_OK;
     656}
     657
     658static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
     659                                struct netr_SamInfo3 *info3)
     660{
     661        const char *guest_account = lp_guestaccount();
     662        struct dom_sid domain_sid;
     663        struct passwd *pwd;
     664        const char *tmp;
     665
     666        pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
     667        if (pwd == NULL) {
     668                DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
     669                         "account [%s]!\n", guest_account));
     670                return NT_STATUS_NO_SUCH_USER;
     671        }
     672
     673        /* Set acount name */
     674        tmp = talloc_strdup(mem_ctx, pwd->pw_name);
     675        if (tmp == NULL) {
     676                return NT_STATUS_NO_MEMORY;
     677        }
     678        init_lsa_String(&info3->base.account_name, tmp);
     679
     680        /* Set domain name */
     681        tmp = talloc_strdup(mem_ctx, get_global_sam_name());
     682        if (tmp == NULL) {
     683                return NT_STATUS_NO_MEMORY;
     684        }
     685        init_lsa_StringLarge(&info3->base.domain, tmp);
     686
     687        /* Domain sid */
     688        sid_copy(&domain_sid, get_global_sam_sid());
     689
     690        info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
     691        if (info3->base.domain_sid == NULL) {
     692                return NT_STATUS_NO_MEMORY;
     693        }
     694
     695        /* Guest rid */
     696        info3->base.rid = DOMAIN_RID_GUEST;
     697
     698        /* Primary gid */
     699        info3->base.primary_gid = BUILTIN_RID_GUESTS;
     700
     701        TALLOC_FREE(pwd);
    1255702        return NT_STATUS_OK;
    1256703}
     
    1262709***************************************************************************/
    1263710
    1264 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
    1265 {
     711static NTSTATUS make_new_server_info_guest(struct auth_serversupplied_info **server_info)
     712{
     713        static const char zeros[16] = {0};
     714        const char *guest_account = lp_guestaccount();
     715        const char *domain = global_myname();
     716        struct netr_SamInfo3 info3;
     717        TALLOC_CTX *tmp_ctx;
    1266718        NTSTATUS status;
    1267         struct samu *sampass = NULL;
    1268         DOM_SID guest_sid;
    1269         bool ret;
    1270         char zeros[16];
    1271719        fstring tmp;
    1272720
    1273         if ( !(sampass = samu_new( NULL )) ) {
    1274                 return NT_STATUS_NO_MEMORY;
    1275         }
    1276 
    1277         sid_copy(&guest_sid, get_global_sam_sid());
    1278         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
    1279 
    1280         become_root();
    1281         ret = pdb_getsampwsid(sampass, &guest_sid);
    1282         unbecome_root();
    1283 
    1284         if (!ret) {
    1285                 TALLOC_FREE(sampass);
    1286                 return NT_STATUS_NO_SUCH_USER;
    1287         }
    1288 
    1289         status = make_server_info_sam(server_info, sampass);
     721        tmp_ctx = talloc_stackframe();
     722        if (tmp_ctx == NULL) {
     723                return NT_STATUS_NO_MEMORY;
     724        }
     725
     726        ZERO_STRUCT(info3);
     727
     728        status = get_guest_info3(tmp_ctx, &info3);
    1290729        if (!NT_STATUS_IS_OK(status)) {
    1291                 TALLOC_FREE(sampass);
    1292                 return status;
    1293         }
    1294        
     730                goto done;
     731        }
     732
     733        status = make_server_info_info3(tmp_ctx,
     734                                        guest_account,
     735                                        domain,
     736                                        server_info,
     737                                        &info3);
     738        if (!NT_STATUS_IS_OK(status)) {
     739                goto done;
     740        }
     741
    1295742        (*server_info)->guest = True;
    1296743
     
    1299746                DEBUG(10, ("create_local_token failed: %s\n",
    1300747                           nt_errstr(status)));
    1301                 return status;
     748                goto done;
    1302749        }
    1303750
    1304751        /* annoying, but the Guest really does have a session key, and it is
    1305752           all zeros! */
    1306         ZERO_STRUCT(zeros);
    1307753        (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
    1308754        (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
    1309755
    1310         alpha_strcpy(tmp, pdb_get_username(sampass), ". _-$", sizeof(tmp));
     756        alpha_strcpy(tmp, (*server_info)->info3->base.account_name.string,
     757                     ". _-$", sizeof(tmp));
    1311758        (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp);
     759
     760        status = NT_STATUS_OK;
     761done:
     762        TALLOC_FREE(tmp_ctx);
     763        return NT_STATUS_OK;
     764}
     765
     766/***************************************************************************
     767 Make (and fill) a auth_session_info struct for a system user login.
     768 This *must* succeed for smbd to start.
     769***************************************************************************/
     770
     771static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
     772                                            struct auth_serversupplied_info **session_info)
     773{
     774        struct passwd *pwd;
     775        NTSTATUS status;
     776
     777        pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
     778        if (pwd == NULL) {
     779                return NT_STATUS_NO_SUCH_USER;
     780        }
     781
     782        status = make_serverinfo_from_username(mem_ctx,
     783                                             pwd->pw_name,
     784                                             false,
     785                                             session_info);
     786        TALLOC_FREE(pwd);
     787        if (!NT_STATUS_IS_OK(status)) {
     788                return status;
     789        }
     790
     791        (*session_info)->system = true;
     792
     793        status = add_sid_to_array_unique((*session_info)->security_token->sids,
     794                                         &global_sid_System,
     795                                         &(*session_info)->security_token->sids,
     796                                         &(*session_info)->security_token->num_sids);
     797        if (!NT_STATUS_IS_OK(status)) {
     798                TALLOC_FREE((*session_info));
     799                return status;
     800        }
    1312801
    1313802        return NT_STATUS_OK;
     
    1350839        }
    1351840
    1352         *presult = result;
     841        *presult = talloc_steal(mem_ctx, result);
    1353842        return NT_STATUS_OK;
    1354843}
     
    1356845
    1357846struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
    1358                                                  const auth_serversupplied_info *src)
    1359 {
    1360         auth_serversupplied_info *dst;
     847                                                 const struct auth_serversupplied_info *src)
     848{
     849        struct auth_serversupplied_info *dst;
    1361850
    1362851        dst = make_server_info(mem_ctx);
     
    1366855
    1367856        dst->guest = src->guest;
     857        dst->system = src->system;
    1368858        dst->utok.uid = src->utok.uid;
    1369859        dst->utok.gid = src->utok.gid;
     
    1377867        }
    1378868
    1379         if (src->ptok) {
    1380                 dst->ptok = dup_nt_token(dst, src->ptok);
    1381                 if (!dst->ptok) {
     869        if (src->security_token) {
     870                dst->security_token = dup_nt_token(dst, src->security_token);
     871                if (!dst->security_token) {
    1382872                        TALLOC_FREE(dst);
    1383873                        return NULL;
    1384874                }
    1385875        }
    1386        
     876
    1387877        dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
    1388878                                                src->user_session_key.length);
     
    1391881                                                src->lm_session_key.length);
    1392882
    1393         dst->sam_account = samu_new(NULL);
    1394         if (!dst->sam_account) {
     883        dst->info3 = copy_netr_SamInfo3(dst, src->info3);
     884        if (!dst->info3) {
    1395885                TALLOC_FREE(dst);
    1396886                return NULL;
    1397887        }
    1398 
    1399         if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
    1400                 TALLOC_FREE(dst);
    1401                 return NULL;
    1402         }
    1403        
    1404         dst->pam_handle = NULL;
     888        dst->extra = src->extra;
     889
    1405890        dst->unix_name = talloc_strdup(dst, src->unix_name);
    1406891        if (!dst->unix_name) {
     
    1423908 */
    1424909
    1425 bool server_info_set_session_key(struct auth_serversupplied_info *info,
     910bool session_info_set_session_key(struct auth_serversupplied_info *info,
    1426911                                 DATA_BLOB session_key)
    1427912{
     
    1434919}
    1435920
    1436 static auth_serversupplied_info *guest_info = NULL;
     921static struct auth_serversupplied_info *guest_info = NULL;
    1437922
    1438923bool init_guest_info(void)
     
    1445930
    1446931NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
    1447                                 auth_serversupplied_info **server_info)
     932                                struct auth_serversupplied_info **server_info)
    1448933{
    1449934        *server_info = copy_serverinfo(mem_ctx, guest_info);
     
    1451936}
    1452937
     938static struct auth_serversupplied_info *system_info = NULL;
     939
     940NTSTATUS init_system_info(void)
     941{
     942        if (system_info != NULL)
     943                return NT_STATUS_OK;
     944
     945        return make_new_session_info_system(NULL, &system_info);
     946}
     947
     948NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
     949                                struct auth_serversupplied_info **session_info)
     950{
     951        if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
     952        *session_info = copy_serverinfo(mem_ctx, system_info);
     953        return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
     954}
     955
     956const struct auth_serversupplied_info *get_session_info_system(void)
     957{
     958    return system_info;
     959}
     960
    1453961bool copy_current_user(struct current_user *dst, struct current_user *src)
    1454962{
    1455963        gid_t *groups;
    1456         NT_USER_TOKEN *nt_token;
     964        struct security_token *nt_token;
    1457965
    1458966        groups = (gid_t *)memdup(src->ut.groups,
     
    1480988/***************************************************************************
    1481989 Purely internal function for make_server_info_info3
    1482  Fill the sam account from getpwnam
    1483990***************************************************************************/
    1484 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
    1485                                  const char *domain,
    1486                                  const char *username,
    1487                                  char **found_username,
    1488                                  uid_t *uid, gid_t *gid,
    1489                                  struct samu *account,
    1490                                  bool *username_was_mapped)
    1491 {
    1492         struct smbd_server_connection *sconn = smbd_server_conn;
    1493         NTSTATUS nt_status;
    1494         fstring dom_user, lower_username;
    1495         fstring real_username;
     991
     992static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
     993                              const char *username, char **found_username,
     994                              struct passwd **pwd,
     995                              bool *username_was_mapped)
     996{
     997        char *orig_dom_user = NULL;
     998        char *dom_user = NULL;
     999        char *lower_username = NULL;
     1000        char *real_username = NULL;
    14961001        struct passwd *passwd;
    14971002
    1498         fstrcpy( lower_username, username );
     1003        lower_username = talloc_strdup(mem_ctx, username);
     1004        if (!lower_username) {
     1005                return NT_STATUS_NO_MEMORY;
     1006        }
    14991007        strlower_m( lower_username );
    15001008
    1501         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
    1502                 lower_username);
    1503 
    1504         /* Get the passwd struct.  Try to create the account is necessary. */
    1505 
    1506         *username_was_mapped = map_username(sconn, dom_user);
    1507 
    1508         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
     1009        orig_dom_user = talloc_asprintf(mem_ctx,
     1010                                "%s%c%s",
     1011                                domain,
     1012                                *lp_winbind_separator(),
     1013                                lower_username);
     1014        if (!orig_dom_user) {
     1015                return NT_STATUS_NO_MEMORY;
     1016        }
     1017
     1018        /* Get the passwd struct.  Try to create the account if necessary. */
     1019
     1020        *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
     1021        if (!dom_user) {
     1022                return NT_STATUS_NO_MEMORY;
     1023        }
     1024
     1025        passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, True );
     1026        if (!passwd) {
     1027                DEBUG(3, ("Failed to find authenticated user %s via "
     1028                          "getpwnam(), denying access.\n", dom_user));
    15091029                return NT_STATUS_NO_SUCH_USER;
    1510 
    1511         *uid = passwd->pw_uid;
    1512         *gid = passwd->pw_gid;
     1030        }
     1031
     1032        if (!real_username) {
     1033                return NT_STATUS_NO_MEMORY;
     1034        }
     1035
     1036        *pwd = passwd;
    15131037
    15141038        /* This is pointless -- there is no suport for differing
     
    15171041           why I hate the 'winbind use default domain' parameter?   
    15181042                                         --jerry              */
    1519            
     1043
    15201044        *found_username = talloc_strdup( mem_ctx, real_username );
    1521        
    1522         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
    1523 
    1524         nt_status = samu_set_unix( account, passwd );
    1525        
    1526         TALLOC_FREE(passwd);
    1527        
    1528         return nt_status;
     1045
     1046        return NT_STATUS_OK;
    15291047}
    15301048
     
    15341052 the username if we fallback to the username only.
    15351053 ****************************************************************************/
    1536  
    1537 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
    1538                              fstring save_username, bool create )
     1054
     1055struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
     1056                             char **p_save_username, bool create )
    15391057{
    15401058        struct passwd *pw = NULL;
    1541         char *p;
    1542         fstring username;
    1543        
     1059        char *p = NULL;
     1060        char *username = NULL;
     1061
    15441062        /* we only save a copy of the username it has been mangled
    15451063           by winbindd use default domain */
    1546            
    1547         save_username[0] = '\0';
    1548            
     1064        *p_save_username = NULL;
     1065
    15491066        /* don't call map_username() here since it has to be done higher
    1550            up the stack so we don't call it mutliple times */
    1551 
    1552         fstrcpy( username, domuser );
    1553        
     1067           up the stack so we don't call it multiple times */
     1068
     1069        username = talloc_strdup(mem_ctx, domuser);
     1070        if (!username) {
     1071                return NULL;
     1072        }
     1073
    15541074        p = strchr_m( username, *lp_winbind_separator() );
    1555        
     1075
    15561076        /* code for a DOMAIN\user string */
    1557        
     1077
    15581078        if ( p ) {
    1559                 fstring strip_username;
    1560 
    15611079                pw = Get_Pwnam_alloc( mem_ctx, domuser );
    1562                 if ( pw ) {     
     1080                if ( pw ) {
    15631081                        /* make sure we get the case of the username correct */
    15641082                        /* work around 'winbind use default domain = yes' */
     
    15661084                        if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
    15671085                                char *domain;
    1568                                
     1086
    15691087                                /* split the domain and username into 2 strings */
    15701088                                *p = '\0';
    15711089                                domain = username;
    15721090
    1573                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
     1091                                *p_save_username = talloc_asprintf(mem_ctx,
     1092                                                                "%s%c%s",
     1093                                                                domain,
     1094                                                                *lp_winbind_separator(),
     1095                                                                pw->pw_name);
     1096                                if (!*p_save_username) {
     1097                                        TALLOC_FREE(pw);
     1098                                        return NULL;
     1099                                }
     1100                        } else {
     1101                                *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
    15741102                        }
    1575                         else
    1576                                 fstrcpy( save_username, pw->pw_name );
    1577 
    1578                         /* whew -- done! */             
     1103
     1104                        /* whew -- done! */
    15791105                        return pw;
    15801106                }
     
    15841110
    15851111                p++;
    1586                 fstrcpy( strip_username, p );
    1587                 fstrcpy( username, strip_username );
    1588         }
    1589        
     1112                username = talloc_strdup(mem_ctx, p);
     1113                if (!username) {
     1114                        return NULL;
     1115                }
     1116        }
     1117
    15901118        /* just lookup a plain username */
    1591        
     1119
    15921120        pw = Get_Pwnam_alloc(mem_ctx, username);
    1593                
     1121
    15941122        /* Create local user if requested but only if winbindd
    15951123           is not running.  We need to protect against cases
    15961124           where winbindd is failing and then prematurely
    15971125           creating users in /etc/passwd */
    1598        
     1126
    15991127        if ( !pw && create && !winbind_ping() ) {
    16001128                /* Don't add a machine account. */
     
    16051133                pw = Get_Pwnam_alloc(mem_ctx, username);
    16061134        }
    1607        
     1135
    16081136        /* one last check for a valid passwd struct */
    1609        
    1610         if ( pw )
    1611                 fstrcpy( save_username, pw->pw_name );
    1612 
     1137
     1138        if (pw) {
     1139                *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
     1140        }
    16131141        return pw;
    16141142}
     
    16211149                                const char *sent_nt_username,
    16221150                                const char *domain,
    1623                                 auth_serversupplied_info **server_info,
     1151                                struct auth_serversupplied_info **server_info,
    16241152                                struct netr_SamInfo3 *info3)
    16251153{
    1626         char zeros[16];
     1154        static const char zeros[16] = {0, };
    16271155
    16281156        NTSTATUS nt_status = NT_STATUS_OK;
     
    16301158        const char *nt_domain;
    16311159        const char *nt_username;
    1632         struct samu *sam_account = NULL;
    1633         DOM_SID user_sid;
    1634         DOM_SID group_sid;
    16351160        bool username_was_mapped;
    1636 
    1637         uid_t uid = (uid_t)-1;
    1638         gid_t gid = (gid_t)-1;
    1639 
    1640         auth_serversupplied_info *result;
     1161        struct passwd *pwd;
     1162        struct auth_serversupplied_info *result;
     1163        struct dom_sid *group_sid;
     1164        struct netr_SamInfo3 *i3;
    16411165
    16421166        /*
     
    16461170        */
    16471171
    1648         sid_copy(&user_sid, info3->base.domain_sid);
    1649         if (!sid_append_rid(&user_sid, info3->base.rid)) {
    1650                 return NT_STATUS_INVALID_PARAMETER;
    1651         }
    1652        
    1653         sid_copy(&group_sid, info3->base.domain_sid);
    1654         if (!sid_append_rid(&group_sid, info3->base.primary_gid)) {
    1655                 return NT_STATUS_INVALID_PARAMETER;
    1656         }
    1657 
    16581172        nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
    16591173        if (!nt_username) {
     
    16691183                nt_domain = domain;
    16701184        }
    1671        
    1672         /* try to fill the SAM account..  If getpwnam() fails, then try the
    1673            add user script (2.2.x behavior).
     1185
     1186        /* If getpwnam() fails try the add user script (2.2.x behavior).
    16741187
    16751188           We use the _unmapped_ username here in an attempt to provide
     
    16811194           that is how the current code is designed.  Making the change here
    16821195           is the least disruptive place.  -- jerry */
    1683            
    1684         if ( !(sam_account = samu_new( NULL )) ) {
    1685                 return NT_STATUS_NO_MEMORY;
    1686         }
    16871196
    16881197        /* this call will try to create the user if necessary */
    16891198
    1690         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
    1691                                      &found_username, &uid, &gid, sam_account,
     1199        nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
     1200                                     &found_username, &pwd,
    16921201                                     &username_was_mapped);
    16931202
    1694        
    1695         /* if we still don't have a valid unix account check for
    1696           'map to guest = bad uid' */
    1697          
    16981203        if (!NT_STATUS_IS_OK(nt_status)) {
    1699                 TALLOC_FREE( sam_account );
    1700                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
    1701                         make_server_info_guest(NULL, server_info);
    1702                         return NT_STATUS_OK;
    1703                 }
    17041204                return nt_status;
    1705         }
    1706                
    1707         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
    1708                 TALLOC_FREE(sam_account);
    1709                 return NT_STATUS_NO_MEMORY;
    1710         }
    1711 
    1712         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
    1713                 TALLOC_FREE(sam_account);
    1714                 return NT_STATUS_NO_MEMORY;
    1715         }
    1716 
    1717         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
    1718                 TALLOC_FREE(sam_account);
    1719                 return NT_STATUS_NO_MEMORY;
    1720         }
    1721 
    1722         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
    1723                 TALLOC_FREE(sam_account);
    1724                 return NT_STATUS_UNSUCCESSFUL;
    1725         }
    1726 
    1727         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
    1728                 TALLOC_FREE(sam_account);
    1729                 return NT_STATUS_UNSUCCESSFUL;
    1730         }
    1731 
    1732         if (!pdb_set_fullname(sam_account,
    1733                               info3->base.full_name.string,
    1734                               PDB_CHANGED)) {
    1735                 TALLOC_FREE(sam_account);
    1736                 return NT_STATUS_NO_MEMORY;
    1737         }
    1738 
    1739         if (!pdb_set_logon_script(sam_account,
    1740                                   info3->base.logon_script.string,
    1741                                   PDB_CHANGED)) {
    1742                 TALLOC_FREE(sam_account);
    1743                 return NT_STATUS_NO_MEMORY;
    1744         }
    1745 
    1746         if (!pdb_set_profile_path(sam_account,
    1747                                   info3->base.profile_path.string,
    1748                                   PDB_CHANGED)) {
    1749                 TALLOC_FREE(sam_account);
    1750                 return NT_STATUS_NO_MEMORY;
    1751         }
    1752 
    1753         if (!pdb_set_homedir(sam_account,
    1754                              info3->base.home_directory.string,
    1755                              PDB_CHANGED)) {
    1756                 TALLOC_FREE(sam_account);
    1757                 return NT_STATUS_NO_MEMORY;
    1758         }
    1759 
    1760         if (!pdb_set_dir_drive(sam_account,
    1761                                info3->base.home_drive.string,
    1762                                PDB_CHANGED)) {
    1763                 TALLOC_FREE(sam_account);
    1764                 return NT_STATUS_NO_MEMORY;
    1765         }
    1766 
    1767         if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {
    1768                 TALLOC_FREE(sam_account);
    1769                 return NT_STATUS_NO_MEMORY;
    1770         }
    1771 
    1772         if (!pdb_set_pass_last_set_time(
    1773                     sam_account,
    1774                     nt_time_to_unix(info3->base.last_password_change),
    1775                     PDB_CHANGED)) {
    1776                 TALLOC_FREE(sam_account);
    1777                 return NT_STATUS_NO_MEMORY;
    1778         }
    1779 
    1780         if (!pdb_set_pass_can_change_time(
    1781                     sam_account,
    1782                     nt_time_to_unix(info3->base.allow_password_change),
    1783                     PDB_CHANGED)) {
    1784                 TALLOC_FREE(sam_account);
    1785                 return NT_STATUS_NO_MEMORY;
    1786         }
    1787 
    1788         if (!pdb_set_pass_must_change_time(
    1789                     sam_account,
    1790                     nt_time_to_unix(info3->base.force_password_change),
    1791                     PDB_CHANGED)) {
    1792                 TALLOC_FREE(sam_account);
    1793                 return NT_STATUS_NO_MEMORY;
    17941205        }
    17951206
     
    17971208        if (result == NULL) {
    17981209                DEBUG(4, ("make_server_info failed!\n"));
    1799                 TALLOC_FREE(sam_account);
    1800                 return NT_STATUS_NO_MEMORY;
    1801         }
    1802 
    1803         /* save this here to _net_sam_logon() doesn't fail (it assumes a
    1804            valid struct samu) */
    1805                    
    1806         result->sam_account = sam_account;
     1210                return NT_STATUS_NO_MEMORY;
     1211        }
     1212
    18071213        result->unix_name = talloc_strdup(result, found_username);
    18081214
     
    18141220        }
    18151221
     1222        /* copy in the info3 */
     1223        result->info3 = i3 = copy_netr_SamInfo3(result, info3);
     1224        if (result->info3 == NULL) {
     1225                TALLOC_FREE(result);
     1226                return NT_STATUS_NO_MEMORY;
     1227        }
     1228
    18161229        /* Fill in the unix info we found on the way */
    1817 
    1818         result->utok.uid = uid;
    1819         result->utok.gid = gid;
    1820 
    1821         /* Create a 'combined' list of all SIDs we might want in the SD */
    1822 
    1823         result->num_sids = 0;
    1824         result->sids = NULL;
    1825 
    1826         nt_status = sid_array_from_info3(result, info3,
    1827                                          &result->sids,
    1828                                          &result->num_sids,
    1829                                          false, false);
     1230        result->utok.uid = pwd->pw_uid;
     1231        result->utok.gid = pwd->pw_gid;
     1232
     1233        /* We can't just trust that the primary group sid sent us is something
     1234         * we can really use. Obtain the useable sid, and store the original
     1235         * one as an additional group if it had to be replaced */
     1236        nt_status = get_primary_group_sid(mem_ctx, found_username,
     1237                                          &pwd, &group_sid);
    18301238        if (!NT_STATUS_IS_OK(nt_status)) {
    18311239                TALLOC_FREE(result);
     
    18331241        }
    18341242
    1835         /* Ensure the primary group sid is at position 0. */
    1836         sort_sid_array_for_smbd(result, &group_sid);
    1837 
    1838         result->login_server = talloc_strdup(result,
    1839                                              info3->base.logon_server.string);
     1243        /* store and check if it is the same we got originally */
     1244        sid_peek_rid(group_sid, &i3->base.primary_gid);
     1245        if (i3->base.primary_gid != info3->base.primary_gid) {
     1246                uint32_t n = i3->base.groups.count;
     1247                /* not the same, store the original as an additional group */
     1248                i3->base.groups.rids =
     1249                        talloc_realloc(i3, i3->base.groups.rids,
     1250                                        struct samr_RidWithAttribute, n + 1);
     1251                if (i3->base.groups.rids == NULL) {
     1252                        TALLOC_FREE(result);
     1253                        return NT_STATUS_NO_MEMORY;
     1254                }
     1255                i3->base.groups.rids[n].rid = info3->base.primary_gid;
     1256                i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
     1257                i3->base.groups.count = n + 1;
     1258        }
    18401259
    18411260        /* ensure we are never given NULL session keys */
    1842 
    1843         ZERO_STRUCT(zeros);
    18441261
    18451262        if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
     
    18741291                                          const char *domain,
    18751292                                          const struct wbcAuthUserInfo *info,
    1876                                           auth_serversupplied_info **server_info)
    1877 {
    1878         char zeros[16];
    1879 
    1880         NTSTATUS nt_status = NT_STATUS_OK;
    1881         char *found_username = NULL;
    1882         const char *nt_domain;
    1883         const char *nt_username;
    1884         struct samu *sam_account = NULL;
    1885         DOM_SID user_sid;
    1886         DOM_SID group_sid;
    1887         bool username_was_mapped;
    1888         uint32_t i;
    1889 
    1890         uid_t uid = (uid_t)-1;
    1891         gid_t gid = (gid_t)-1;
    1892 
    1893         auth_serversupplied_info *result;
    1894 
    1895         result = make_server_info(NULL);
    1896         if (result == NULL) {
    1897                 DEBUG(4, ("make_server_info failed!\n"));
    1898                 return NT_STATUS_NO_MEMORY;
    1899         }
    1900 
    1901         /*
    1902            Here is where we should check the list of
    1903            trusted domains, and verify that the SID
    1904            matches.
    1905         */
    1906 
    1907         memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
    1908         memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
    1909 
    1910         if (info->account_name) {
    1911                 nt_username = talloc_strdup(result, info->account_name);
    1912         } else {
    1913                 /* If the server didn't give us one, just use the one we sent
    1914                  * them */
    1915                 nt_username = talloc_strdup(result, sent_nt_username);
    1916         }
    1917         if (!nt_username) {
    1918                 TALLOC_FREE(result);
    1919                 return NT_STATUS_NO_MEMORY;
    1920         }
    1921 
    1922         if (info->domain_name) {
    1923                 nt_domain = talloc_strdup(result, info->domain_name);
    1924         } else {
    1925                 /* If the server didn't give us one, just use the one we sent
    1926                  * them */
    1927                 nt_domain = talloc_strdup(result, domain);
    1928         }
    1929         if (!nt_domain) {
    1930                 TALLOC_FREE(result);
    1931                 return NT_STATUS_NO_MEMORY;
    1932         }
    1933 
    1934         /* try to fill the SAM account..  If getpwnam() fails, then try the
    1935            add user script (2.2.x behavior).
    1936 
    1937            We use the _unmapped_ username here in an attempt to provide
    1938            consistent username mapping behavior between kerberos and NTLM[SSP]
    1939            authentication in domain mode security.  I.E. Username mapping
    1940            should be applied to the fully qualified username
    1941            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
    1942            called map_username() unnecessarily in make_user_info_map() but
    1943            that is how the current code is designed.  Making the change here
    1944            is the least disruptive place.  -- jerry */
    1945 
    1946         if ( !(sam_account = samu_new( result )) ) {
    1947                 TALLOC_FREE(result);
    1948                 return NT_STATUS_NO_MEMORY;
    1949         }
    1950 
    1951         /* this call will try to create the user if necessary */
    1952 
    1953         nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
    1954                                      &found_username, &uid, &gid, sam_account,
    1955                                      &username_was_mapped);
    1956 
    1957         /* if we still don't have a valid unix account check for
    1958           'map to guest = bad uid' */
    1959 
    1960         if (!NT_STATUS_IS_OK(nt_status)) {
    1961                 TALLOC_FREE( result );
    1962                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
    1963                         make_server_info_guest(NULL, server_info);
    1964                         return NT_STATUS_OK;
    1965                 }
    1966                 return nt_status;
    1967         }
    1968 
    1969         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
    1970                 TALLOC_FREE(result);
    1971                 return NT_STATUS_NO_MEMORY;
    1972         }
    1973 
    1974         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
    1975                 TALLOC_FREE(result);
    1976                 return NT_STATUS_NO_MEMORY;
    1977         }
    1978 
    1979         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
    1980                 TALLOC_FREE(result);
    1981                 return NT_STATUS_NO_MEMORY;
    1982         }
    1983 
    1984         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
    1985                 TALLOC_FREE(result);
    1986                 return NT_STATUS_UNSUCCESSFUL;
    1987         }
    1988 
    1989         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
    1990                 TALLOC_FREE(result);
    1991                 return NT_STATUS_UNSUCCESSFUL;
    1992         }
    1993 
    1994         if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
    1995                 TALLOC_FREE(result);
    1996                 return NT_STATUS_NO_MEMORY;
    1997         }
    1998 
    1999         if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
    2000                 TALLOC_FREE(result);
    2001                 return NT_STATUS_NO_MEMORY;
    2002         }
    2003 
    2004         if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
    2005                 TALLOC_FREE(result);
    2006                 return NT_STATUS_NO_MEMORY;
    2007         }
    2008 
    2009         if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
    2010                 TALLOC_FREE(result);
    2011                 return NT_STATUS_NO_MEMORY;
    2012         }
    2013 
    2014         if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
    2015                 TALLOC_FREE(result);
    2016                 return NT_STATUS_NO_MEMORY;
    2017         }
    2018 
    2019         if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
    2020                 TALLOC_FREE(result);
    2021                 return NT_STATUS_NO_MEMORY;
    2022         }
    2023 
    2024         if (!pdb_set_pass_last_set_time(
    2025                     sam_account,
    2026                     info->pass_last_set_time,
    2027                     PDB_CHANGED)) {
    2028                 TALLOC_FREE(result);
    2029                 return NT_STATUS_NO_MEMORY;
    2030         }
    2031 
    2032         if (!pdb_set_pass_can_change_time(
    2033                     sam_account,
    2034                     info->pass_can_change_time,
    2035                     PDB_CHANGED)) {
    2036                 TALLOC_FREE(result);
    2037                 return NT_STATUS_NO_MEMORY;
    2038         }
    2039 
    2040         if (!pdb_set_pass_must_change_time(
    2041                     sam_account,
    2042                     info->pass_must_change_time,
    2043                     PDB_CHANGED)) {
    2044                 TALLOC_FREE(result);
    2045                 return NT_STATUS_NO_MEMORY;
    2046         }
    2047 
    2048         /* save this here to _net_sam_logon() doesn't fail (it assumes a
    2049            valid struct samu) */
    2050 
    2051         result->sam_account = sam_account;
    2052         result->unix_name = talloc_strdup(result, found_username);
    2053 
    2054         result->sanitized_username = sanitize_username(result,
    2055                                                        result->unix_name);
    2056         result->login_server = talloc_strdup(result, info->logon_server);
    2057 
    2058         if ((result->unix_name == NULL)
    2059             || (result->sanitized_username == NULL)
    2060             || (result->login_server == NULL)) {
    2061                 TALLOC_FREE(result);
    2062                 return NT_STATUS_NO_MEMORY;
    2063         }
    2064 
    2065         /* Fill in the unix info we found on the way */
    2066 
    2067         result->utok.uid = uid;
    2068         result->utok.gid = gid;
    2069 
    2070         /* Create a 'combined' list of all SIDs we might want in the SD */
    2071 
    2072         result->num_sids = info->num_sids - 2;
    2073         result->sids = talloc_array(result, DOM_SID, result->num_sids);
    2074         if (result->sids == NULL) {
    2075                 TALLOC_FREE(result);
    2076                 return NT_STATUS_NO_MEMORY;
    2077         }
    2078 
    2079         for (i=0; i < result->num_sids; i++) {
    2080                 memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
    2081         }
    2082 
    2083         /* Ensure the primary group sid is at position 0. */
    2084         sort_sid_array_for_smbd(result, &group_sid);
    2085 
    2086         /* ensure we are never given NULL session keys */
    2087 
    2088         ZERO_STRUCT(zeros);
    2089 
    2090         if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
    2091                 result->user_session_key = data_blob_null;
    2092         } else {
    2093                 result->user_session_key = data_blob_talloc(
    2094                         result, info->user_session_key,
    2095                         sizeof(info->user_session_key));
    2096         }
    2097 
    2098         if (memcmp(info->lm_session_key, zeros, 8) == 0) {
    2099                 result->lm_session_key = data_blob_null;
    2100         } else {
    2101                 result->lm_session_key = data_blob_talloc(
    2102                         result, info->lm_session_key,
    2103                         sizeof(info->lm_session_key));
    2104         }
    2105 
    2106         result->nss_token |= username_was_mapped;
    2107 
    2108         *server_info = result;
    2109 
    2110         return NT_STATUS_OK;
    2111 }
    2112 
    2113 /***************************************************************************
    2114  Free a user_info struct
    2115 ***************************************************************************/
    2116 
    2117 void free_user_info(auth_usersupplied_info **user_info)
    2118 {
    2119         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
    2120         if (*user_info != NULL) {
    2121                 if ((*user_info)->smb_name) {
    2122                         DEBUG(10,("structure was created for %s\n",
    2123                                   (*user_info)->smb_name));
    2124                 }
    2125                 SAFE_FREE((*user_info)->smb_name);
    2126                 SAFE_FREE((*user_info)->internal_username);
    2127                 SAFE_FREE((*user_info)->client_domain);
    2128                 SAFE_FREE((*user_info)->domain);
    2129                 SAFE_FREE((*user_info)->wksta_name);
    2130                 data_blob_free(&(*user_info)->lm_resp);
    2131                 data_blob_free(&(*user_info)->nt_resp);
    2132                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
    2133                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
    2134                 data_blob_clear_free(&(*user_info)->plaintext_password);
    2135                 ZERO_STRUCT(**user_info);
    2136         }
    2137         SAFE_FREE(*user_info);
    2138 }
    2139 
    2140 /***************************************************************************
    2141  Make an auth_methods struct
    2142 ***************************************************************************/
    2143 
    2144 bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
    2145 {
    2146         if (!auth_context) {
    2147                 smb_panic("no auth_context supplied to "
    2148                           "make_auth_methods()!\n");
    2149         }
    2150 
    2151         if (!auth_method) {
    2152                 smb_panic("make_auth_methods: pointer to auth_method pointer "
    2153                           "is NULL!\n");
    2154         }
    2155 
    2156         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
    2157         if (!*auth_method) {
    2158                 DEBUG(0,("make_auth_method: malloc failed!\n"));
    2159                 return False;
    2160         }
    2161         ZERO_STRUCTP(*auth_method);
    2162        
    2163         return True;
     1293                                          struct auth_serversupplied_info **server_info)
     1294{
     1295        struct netr_SamInfo3 *info3;
     1296
     1297        info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
     1298        if (!info3) {
     1299                return NT_STATUS_NO_MEMORY;
     1300        }
     1301
     1302        return make_server_info_info3(mem_ctx,
     1303                                      sent_nt_username, domain,
     1304                                      server_info, info3);
    21641305}
    21651306
     
    21741315bool is_trusted_domain(const char* dom_name)
    21751316{
    2176         DOM_SID trustdom_sid;
     1317        struct dom_sid trustdom_sid;
    21771318        bool ret;
    21781319
     
    22201361                   and running. We need to update the trustdom_cache
    22211362                   ourselves */
    2222                
     1363
    22231364                update_trustdom_cache();
    22241365        }
  • trunk/server/source3/auth/auth_wbc.c

    r414 r745  
    3939
    4040#include "includes.h"
     41#include "auth.h"
     42#include "nsswitch/libwbclient/wbclient.h"
    4143
    4244#undef DBGC_CLASS
     
    4850                                       void *my_private_data,
    4951                                       TALLOC_CTX *mem_ctx,
    50                                        const auth_usersupplied_info *user_info,
    51                                        auth_serversupplied_info **server_info)
     52                                       const struct auth_usersupplied_info *user_info,
     53                                       struct auth_serversupplied_info **server_info)
    5254{
    5355        NTSTATUS nt_status;
     
    6062                return NT_STATUS_INVALID_PARAMETER;
    6163        }
     64
     65        ZERO_STRUCT(params);
     66
    6267        /* Send off request */
    6368
    64         params.account_name     = user_info->smb_name;
    65         params.domain_name      = user_info->domain;
    66         params.workstation_name = user_info->wksta_name;
     69        DEBUG(10, ("Check auth for: [%s]", user_info->mapped.account_name));
     70
     71        params.account_name     = user_info->client.account_name;
     72        params.domain_name      = user_info->mapped.domain_name;
     73        params.workstation_name = user_info->workstation_name;
    6774
    6875        params.flags            = 0;
     
    7077
    7178        /* Handle plaintext */
    72         if (!user_info->encrypted) {
     79        switch (user_info->password_state) {
     80        case AUTH_PASSWORD_PLAIN:
     81        {
    7382                DEBUG(3,("Checking plaintext password for %s.\n",
    74                          user_info->internal_username));
     83                         user_info->mapped.account_name));
    7584                params.level = WBC_AUTH_USER_LEVEL_PLAIN;
    7685
    77                 params.password.plaintext = (char *)user_info->plaintext_password.data;
    78         } else {
     86                params.password.plaintext = user_info->password.plaintext;
     87                break;
     88        }
     89        case AUTH_PASSWORD_RESPONSE:
     90        case AUTH_PASSWORD_HASH:
     91        {
    7992                DEBUG(3,("Checking encrypted password for %s.\n",
    80                          user_info->internal_username));
     93                         user_info->mapped.account_name));
    8194                params.level = WBC_AUTH_USER_LEVEL_RESPONSE;
    8295
     
    8598                    sizeof(params.password.response.challenge));
    8699
    87                 params.password.response.nt_length = user_info->nt_resp.length;
    88                 params.password.response.nt_data = user_info->nt_resp.data;
    89                 params.password.response.lm_length = user_info->lm_resp.length;
    90                 params.password.response.lm_data = user_info->lm_resp.data;
     100                if (user_info->password.response.nt.length != 0) {
     101                        params.password.response.nt_length =
     102                                user_info->password.response.nt.length;
     103                        params.password.response.nt_data =
     104                                user_info->password.response.nt.data;
     105                }
     106                if (user_info->password.response.lanman.length != 0) {
     107                        params.password.response.lm_length =
     108                                user_info->password.response.lanman.length;
     109                        params.password.response.lm_data =
     110                                user_info->password.response.lanman.data;
     111                }
     112                break;
     113        }
     114        default:
     115                DEBUG(0,("user_info constructed for user '%s' was invalid - password_state=%u invalid.\n",user_info->mapped.account_name, user_info->password_state));
     116                return NT_STATUS_INTERNAL_ERROR;
     117#if 0 /* If ever implemented in libwbclient */
     118        case AUTH_PASSWORD_HASH:
     119        {
     120                DEBUG(3,("Checking logon (hash) password for %s.\n",
     121                         user_info->mapped.account_name));
     122                params.level = WBC_AUTH_USER_LEVEL_HASH;
    91123
     124                if (user_info->password.hash.nt) {
     125                        memcpy(params.password.hash.nt_hash, user_info->password.hash.nt, sizeof(* user_info->password.hash.nt));
     126                } else {
     127                        memset(params.password.hash.nt_hash, '\0', sizeof(params.password.hash.nt_hash));
     128                }
     129
     130                if (user_info->password.hash.lanman) {
     131                        memcpy(params.password.hash.lm_hash, user_info->password.hash.lanman, sizeof(* user_info->password.hash.lanman));
     132                } else {
     133                        memset(params.password.hash.lm_hash, '\0', sizeof(params.password.hash.lm_hash));
     134                }
     135
     136        }
     137#endif
    92138        }
    93139
     
    119165
    120166        nt_status = make_server_info_wbcAuthUserInfo(mem_ctx,
    121                                                      user_info->smb_name,
    122                                                      user_info->domain,
     167                                                     user_info->client.account_name,
     168                                                     user_info->mapped.domain_name,
    123169                                                     info, server_info);
    124170        wbcFreeMemory(info);
     
    135181static NTSTATUS auth_init_wbc(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
    136182{
    137         if (!make_auth_methods(auth_context, auth_method)) {
     183        struct auth_methods *result;
     184
     185        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     186        if (result == NULL) {
    138187                return NT_STATUS_NO_MEMORY;
    139188        }
     189        result->name = "wbc";
     190        result->auth = check_wbc_security;
    140191
    141         (*auth_method)->name = "wbc";
    142         (*auth_method)->auth = check_wbc_security;
    143 
     192        *auth_method = result;
    144193        return NT_STATUS_OK;
    145194}
  • trunk/server/source3/auth/auth_winbind.c

    r414 r745  
    66   Copyright (C) Tim Potter 2000
    77   Copyright (C) Andrew Bartlett 2001 - 2002
    8    
     8
    99   This program is free software; you can redistribute it and/or modify
    1010   it under the terms of the GNU General Public License as published by
    1111   the Free Software Foundation; either version 3 of the License, or
    1212   (at your option) any later version.
    13    
     13
    1414   This program is distributed in the hope that it will be useful,
    1515   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1616   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1717   GNU General Public License for more details.
    18    
     18
    1919   You should have received a copy of the GNU General Public License
    2020   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2222
    2323#include "includes.h"
     24#include "auth.h"
     25#include "nsswitch/libwbclient/wbclient.h"
    2426
    2527#undef DBGC_CLASS
     
    3133                                       void *my_private_data,
    3234                                       TALLOC_CTX *mem_ctx,
    33                                        const auth_usersupplied_info *user_info,
    34                                        auth_serversupplied_info **server_info)
     35                                       const struct auth_usersupplied_info *user_info,
     36                                       struct auth_serversupplied_info **server_info)
    3537{
    3638        NTSTATUS nt_status;
     
    4042        struct wbcAuthErrorInfo *err = NULL;
    4143
     44        ZERO_STRUCT(params);
     45
    4246        if (!user_info) {
    4347                return NT_STATUS_INVALID_PARAMETER;
    4448        }
    4549
     50        DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
     51
    4652        if (!auth_context) {
    4753                DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n",
    48                          user_info->internal_username));
     54                         user_info->mapped.account_name));
    4955                return NT_STATUS_INVALID_PARAMETER;
    5056        }               
    5157
    52         if (strequal(user_info->domain, get_global_sam_name())) {
     58        if (strequal(user_info->mapped.domain_name, get_global_sam_name())) {
    5359                DEBUG(3,("check_winbind_security: Not using winbind, requested domain [%s] was for this SAM.\n",
    54                         user_info->domain));
     60                        user_info->mapped.domain_name));
    5561                return NT_STATUS_NOT_IMPLEMENTED;
    5662        }
     
    5864        /* Send off request */
    5965
    60         params.account_name     = user_info->smb_name;
    61         params.domain_name      = user_info->domain;
    62         params.workstation_name = user_info->wksta_name;
     66        params.account_name     = user_info->client.account_name;
     67        params.domain_name      = user_info->mapped.domain_name;
     68        params.workstation_name = user_info->workstation_name;
    6369
    6470        params.flags            = 0;
     
    7177               sizeof(params.password.response.challenge));
    7278
    73         params.password.response.nt_length      = user_info->nt_resp.length;
    74         params.password.response.nt_data        = user_info->nt_resp.data;
    75         params.password.response.lm_length      = user_info->lm_resp.length;
    76         params.password.response.lm_data        = user_info->lm_resp.data;
     79        if (user_info->password.response.nt.length != 0) {
     80                params.password.response.nt_length =
     81                        user_info->password.response.nt.length;
     82                params.password.response.nt_data =
     83                        user_info->password.response.nt.data;
     84        }
     85        if (user_info->password.response.lanman.length != 0) {
     86                params.password.response.lm_length =
     87                        user_info->password.response.lanman.length;
     88                params.password.response.lm_data =
     89                        user_info->password.response.lanman.data;
     90        }
    7791
    7892        /* we are contacting the privileged pipe */
     
    97111                        return auth_method->auth(auth_context, auth_method->private_data,
    98112                                mem_ctx, user_info, server_info);
    99                 else
    100                         /* log an error since this should not happen */
    101                         DEBUG(0,("check_winbind_security: ERROR!  my_private_data == NULL!\n"));
     113                return NT_STATUS_LOGON_FAILURE;
    102114        }
    103115
     
    113125
    114126        nt_status = make_server_info_wbcAuthUserInfo(mem_ctx,
    115                                                      user_info->smb_name,
    116                                                      user_info->domain,
     127                                                     user_info->client.account_name,
     128                                                     user_info->mapped.domain_name,
    117129                                                     info, server_info);
    118130        wbcFreeMemory(info);
     
    129141static NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
    130142{
    131         if (!make_auth_methods(auth_context, auth_method)) {
     143        struct auth_methods *result;
     144
     145        result = TALLOC_ZERO_P(auth_context, struct auth_methods);
     146        if (result == NULL) {
    132147                return NT_STATUS_NO_MEMORY;
    133148        }
    134 
    135         (*auth_method)->name = "winbind";
    136         (*auth_method)->auth = check_winbind_security;
     149        result->name = "winbind";
     150        result->auth = check_winbind_security;
    137151
    138152        if (param && *param) {
     
    143157                        return NT_STATUS_UNSUCCESSFUL;
    144158                }
    145                 (*auth_method)->private_data = (void *)priv;
     159                result->private_data = (void *)priv;
    146160        }
     161
     162        *auth_method = result;
    147163        return NT_STATUS_OK;
    148164}
  • trunk/server/source3/auth/pampass.c

    r414 r745  
    66   Copyright (C) Andrew Bartlett 2001
    77   Copyright (C) Jeremy Allison 2001
    8    
     8
    99   This program is free software; you can redistribute it and/or modify
    1010   it under the terms of the GNU General Public License as published by
    1111   the Free Software Foundation; either version 3 of the License, or
    1212   (at your option) any later version.
    13    
     13
    1414   This program is distributed in the hope that it will be useful,
    1515   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1616   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1717   GNU General Public License for more details.
    18    
     18
    1919   You should have received a copy of the GNU General Public License
    2020   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2828
    2929#include "includes.h"
     30#include "auth.h"
     31#include "../libcli/auth/pam_errors.h"
    3032
    3133#undef DBGC_CLASS
     
    6062typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_response **, void *appdata_ptr);
    6163
    62 /*
    63  *  Macros to help make life easy
    64  */
    65 #define COPY_STRING(s) (s) ? SMB_STRDUP(s) : NULL
    66 #define COPY_FSTRING(s) (s[0]) ? SMB_STRDUP(s) : NULL
     64static char *smb_pam_copy_string(const char *s)
     65{
     66        if (s == NULL) {
     67                return NULL;
     68        }
     69        return SMB_STRDUP(s);
     70}
     71
     72static char *smb_pam_copy_fstring(const char *s)
     73{
     74        if (s[0] == '\0') {
     75                return NULL;
     76        }
     77        return SMB_STRDUP(s);
     78}
    6779
    6880/*******************************************************************
     
    7688                DEBUG(dbglvl, ("smb_pam_error_handler: PAM: %s : %s\n",
    7789                                msg, pam_strerror(pamh, pam_error)));
    78                
    7990                return False;
    8091        }
     
    145156                        case PAM_PROMPT_ECHO_ON:
    146157                                reply[replies].resp_retcode = PAM_SUCCESS;
    147                                 reply[replies].resp = COPY_STRING(udp->PAM_username);
     158                                reply[replies].resp = smb_pam_copy_string(
     159                                        udp->PAM_username);
    148160                                /* PAM frees resp */
    149161                                break;
     
    151163                        case PAM_PROMPT_ECHO_OFF:
    152164                                reply[replies].resp_retcode = PAM_SUCCESS;
    153                                 reply[replies].resp = COPY_STRING(udp->PAM_password);
     165                                reply[replies].resp = smb_pam_copy_string(
     166                                        udp->PAM_password);
    154167                                /* PAM frees resp */
    155168                                break;
     
    281294        bool found;
    282295        *resp = NULL;
    283        
     296
    284297        DEBUG(10,("smb_pam_passchange_conv: starting converstation for %d messages\n", num_msg));
    285298
     
    326339                                        pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword);
    327340#ifdef DEBUG_PASSWORD
    328                                         DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We actualy sent: %s\n", current_reply));
     341                                        DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We actually sent: %s\n", current_reply));
    329342#endif
    330343                                        reply[replies].resp_retcode = PAM_SUCCESS;
    331                                         reply[replies].resp = COPY_FSTRING(current_reply);
     344                                        reply[replies].resp = smb_pam_copy_fstring(
     345                                                current_reply);
    332346                                        found = True;
    333347                                        break;
     
    357371                                        pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword);
    358372                                        reply[replies].resp_retcode = PAM_SUCCESS;
    359                                         reply[replies].resp = COPY_FSTRING(current_reply);
     373                                        reply[replies].resp = smb_pam_copy_fstring(
     374                                                current_reply);
    360375#ifdef DEBUG_PASSWORD
    361                                         DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We actualy sent: %s\n", current_reply));
     376                                        DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We actually sent: %s\n", current_reply));
    362377#endif
    363378                                        found = True;
     
    366381                        }
    367382                        /* PAM frees resp */
    368                        
     383
    369384                        if (!found) {
    370385                                DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg));
     
    383398                        reply[replies].resp = NULL;
    384399                        break;
    385                        
     400
    386401                default:
    387402                        /* Must be an error of some sort... */
     
    391406                }
    392407        }
    393                
     408
    394409        free_pw_chat(pw_chat);
    395410        if (reply)
     
    444459
    445460        smb_free_pam_conv(smb_pam_conv_ptr);
    446        
     461
    447462        if( pamh != NULL ) {
    448463                pam_error = pam_end(pamh, 0);
     
    463478{
    464479        int pam_error;
    465 #ifdef PAM_RHOST
    466         const char *our_rhost;
    467         char addr[INET6_ADDRSTRLEN];
    468 #endif
    469480
    470481        *pamh = (pam_handle_t *)NULL;
     
    478489        }
    479490
    480 #ifdef PAM_RHOST
    481         if (rhost == NULL) {
    482                 our_rhost = client_name(get_client_fd());
    483                 if (strequal(our_rhost,"UNKNOWN"))
    484                         our_rhost = client_addr(get_client_fd(),addr,sizeof(addr));
    485         } else {
    486                 our_rhost = rhost;
    487         }
    488 
    489         DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", our_rhost));
    490         pam_error = pam_set_item(*pamh, PAM_RHOST, our_rhost);
     491#if HAVE_PAM_RHOST
     492        DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", rhost));
     493        pam_error = pam_set_item(*pamh, PAM_RHOST, rhost);
    491494        if(!smb_pam_error_handler(*pamh, pam_error, "set rhost failed", 0)) {
    492495                smb_pam_end(*pamh, pconv);
     
    495498        }
    496499#endif
    497 #ifdef PAM_TTY
     500#if HAVE_PAM_TTY
    498501        DEBUG(4,("smb_pam_start: PAM: setting tty\n"));
    499502        pam_error = pam_set_item(*pamh, PAM_TTY, "samba");
     
    520523         *      auth required /lib/security/pam_pwdb.so nullok shadow audit
    521524         */
    522        
     525
    523526        DEBUG(4,("smb_pam_auth: PAM: Authenticate User: %s\n", user));
    524527        pam_error = pam_authenticate(pamh, PAM_SILENT | lp_null_passwords() ? 0 : PAM_DISALLOW_NULL_AUTHTOK);
     
    640643        int pam_error;
    641644
    642 #ifdef PAM_TTY
     645#if HAVE_PAM_TTY
    643646        DEBUG(4,("smb_internal_pam_session: PAM: tty set to: %s\n", tty));
    644647        pam_error = pam_set_item(pamh, PAM_TTY, tty);
     
    774777 */
    775778
    776 NTSTATUS smb_pam_accountcheck(const char * user)
     779NTSTATUS smb_pam_accountcheck(const char *user, const char *rhost)
    777780{
    778781        NTSTATUS nt_status = NT_STATUS_ACCOUNT_DISABLED;
     
    788791                return NT_STATUS_NO_MEMORY;
    789792
    790         if (!smb_pam_start(&pamh, user, NULL, pconv))
     793        if (!smb_pam_start(&pamh, user, rhost, pconv))
    791794                return NT_STATUS_ACCOUNT_DISABLED;
    792795
     
    802805 */
    803806
    804 NTSTATUS smb_pam_passcheck(const char * user, const char * password)
     807NTSTATUS smb_pam_passcheck(const char * user, const char * rhost,
     808                           const char * password)
    805809{
    806810        pam_handle_t *pamh = NULL;
     
    817821                return NT_STATUS_LOGON_FAILURE;
    818822
    819         if (!smb_pam_start(&pamh, user, NULL, pconv))
     823        if (!smb_pam_start(&pamh, user, rhost, pconv))
    820824                return NT_STATUS_LOGON_FAILURE;
    821825
     
    846850 */
    847851
    848 bool smb_pam_passchange(const char * user, const char * oldpassword, const char * newpassword)
     852bool smb_pam_passchange(const char *user, const char *rhost,
     853                        const char *oldpassword, const char *newpassword)
    849854{
    850855        /* Appropriate quantities of root should be obtained BEFORE calling this function */
     
    855860                return False;
    856861
    857         if(!smb_pam_start(&pamh, user, NULL, pconv))
     862        if(!smb_pam_start(&pamh, user, rhost, pconv))
    858863                return False;
    859864
     
    870875
    871876/* If PAM not used, no PAM restrictions on accounts. */
    872 NTSTATUS smb_pam_accountcheck(const char * user)
     877NTSTATUS smb_pam_accountcheck(const char *user, const char *rhost)
    873878{
    874879        return NT_STATUS_OK;
  • trunk/server/source3/auth/pass_check.c

    r414 r745  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   Password checking
    44   Copyright (C) Andrew Tridgell 1992-1998
    5    
     5
    66   This program is free software; you can redistribute it and/or modify
    77   it under the terms of the GNU General Public License as published by
    88   the Free Software Foundation; either version 3 of the License, or
    99   (at your option) any later version.
    10    
     10
    1111   This program is distributed in the hope that it will be useful,
    1212   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1313   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1414   GNU General Public License for more details.
    15    
     15
    1616   You should have received a copy of the GNU General Public License
    1717   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2222
    2323#include "includes.h"
     24#include "system/passwd.h"
     25#include "auth.h"
    2426
    2527#undef DBGC_CLASS
    2628#define DBGC_CLASS DBGC_AUTH
     29
     30/* what is the longest significant password available on your system?
     31 Knowing this speeds up password searches a lot */
     32#ifndef PASSWORD_LENGTH
     33#define PASSWORD_LENGTH 8
     34#endif
    2735
    2836/* these are kept here to keep the string_combinations function simple */
     
    493501it assumes the string starts lowercased
    494502****************************************************************************/
    495 static NTSTATUS string_combinations2(char *s, int offset, NTSTATUS (*fn) (const char *),
    496                                  int N)
     503static NTSTATUS string_combinations2(char *s, int offset,
     504                                     NTSTATUS (*fn)(const char *s,
     505                                                    void *private_data),
     506                                     int N, void *private_data)
    497507{
    498508        int len = strlen(s);
     
    505515
    506516        if (N <= 0 || offset >= len)
    507                 return (fn(s));
     517                return (fn(s, private_data));
    508518
    509519        for (i = offset; i < (len - (N - 1)); i++) {
    510520                char c = s[i];
    511                 if (!islower_ascii(c))
     521                if (!islower_m(c))
    512522                        continue;
    513                 s[i] = toupper_ascii(c);
    514                 if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, i + 1, fn, N - 1),NT_STATUS_WRONG_PASSWORD)) {
    515                         return (nt_status);
     523                s[i] = toupper_m(c);
     524                nt_status = string_combinations2(s, i + 1, fn, N - 1,
     525                                                 private_data);
     526                if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
     527                        return nt_status;
    516528                }
    517529                s[i] = c;
     
    527539it assumes the string starts lowercased
    528540****************************************************************************/
    529 static NTSTATUS string_combinations(char *s, NTSTATUS (*fn) (const char *), int N)
     541static NTSTATUS string_combinations(char *s,
     542                                    NTSTATUS (*fn)(const char *s,
     543                                                   void *private_data),
     544                                    int N, void *private_data)
    530545{
    531546        int n;
    532547        NTSTATUS nt_status;
    533         for (n = 1; n <= N; n++)
    534                 if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, 0, fn, n), NT_STATUS_WRONG_PASSWORD))
     548        for (n = 1; n <= N; n++) {
     549                nt_status = string_combinations2(s, 0, fn, n, private_data);
     550                if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
    535551                        return nt_status;
     552                }
     553        }
    536554        return NT_STATUS_WRONG_PASSWORD;
    537555}
     
    541559core of password checking routine
    542560****************************************************************************/
    543 static NTSTATUS password_check(const char *password)
     561static NTSTATUS password_check(const char *password, void *private_data)
    544562{
    545563#ifdef WITH_PAM
    546         return smb_pam_passcheck(get_this_user(), password);
     564        const char *rhost = (const char *)private_data;
     565        return smb_pam_passcheck(get_this_user(), rhost, password);
    547566#else
    548567
     
    560579
    561580#ifdef OSF1_ENH_SEC
    562        
     581
    563582        ret = (strcmp(osf1_bigcrypt(password, get_this_salt()),
    564583                      get_this_crypted()) == 0);
     
    573592                return NT_STATUS_WRONG_PASSWORD;
    574593        }
    575        
     594
    576595#endif /* OSF1_ENH_SEC */
    577        
     596
    578597#ifdef ULTRIX_AUTH
    579598        ret = (strcmp((char *)crypt16(password, get_this_salt()), get_this_crypted()) == 0);
     
    583602                return NT_STATUS_WRONG_PASSWORD;
    584603        }
    585        
     604
    586605#endif /* ULTRIX_AUTH */
    587        
     606
    588607#ifdef LINUX_BIGCRYPT
    589608        ret = (linux_bigcrypt(password, get_this_salt(), get_this_crypted()));
     
    594613        }
    595614#endif /* LINUX_BIGCRYPT */
    596        
     615
    597616#if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
    598        
     617
    599618        /*
    600619         * Some systems have bigcrypt in the C library but might not
     
    614633        }
    615634#else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
    616        
     635
    617636#ifdef HAVE_BIGCRYPT
    618637        ret = (strcmp(bigcrypt(password, get_this_salt()), get_this_crypted()) == 0);
     
    623642        }
    624643#endif /* HAVE_BIGCRYPT */
    625        
     644
    626645#ifndef HAVE_CRYPT
    627646        DEBUG(1, ("Warning - no crypt available\n"));
     
    648667****************************************************************************/
    649668
    650 NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *password,
    651                     int pwlen, bool (*fn) (const char *, const char *), bool run_cracker)
     669NTSTATUS pass_check(const struct passwd *pass,
     670                    const char *user,
     671                    const char *rhost,
     672                    const char *password,
     673                    bool run_cracker)
    652674{
    653675        char *pass2 = NULL;
     
    663685                return NT_STATUS_LOGON_FAILURE;
    664686
    665         if (((!*password) || (!pwlen)) && !lp_null_passwords())
     687        if ((!*password) && !lp_null_passwords())
    666688                return NT_STATUS_LOGON_FAILURE;
    667689
     
    677699        }
    678700
    679         DEBUG(4, ("pass_check: Checking (PAM) password for user %s (l=%d)\n", user, pwlen));
     701        DEBUG(4, ("pass_check: Checking (PAM) password for user %s\n", user));
    680702
    681703#else /* Not using PAM */
    682704
    683         DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen));
     705        DEBUG(4, ("pass_check: Checking password for user %s\n", user));
    684706
    685707        if (!pass) {
     
    819841
    820842        /* try it as it came to us */
    821         nt_status = password_check(password);
     843        nt_status = password_check(password, (void *)rhost);
    822844        if NT_STATUS_IS_OK(nt_status) {
    823                 if (fn) {
    824                         fn(user, password);
    825                 }
    826845                return (nt_status);
    827846        } else if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
     
    850869        if (strhasupper(pass2)) {
    851870                strlower_m(pass2);
    852                 if NT_STATUS_IS_OK(nt_status = password_check(pass2)) {
    853                         if (fn)
    854                                 fn(user, pass2);
     871                nt_status = password_check(pass2, (void *)rhost);
     872                if (NT_STATUS_IS_OK(nt_status)) {
    855873                        return (nt_status);
    856874                }
     
    864882        /* last chance - all combinations of up to level chars upper! */
    865883        strlower_m(pass2);
    866  
    867         if (NT_STATUS_IS_OK(nt_status = string_combinations(pass2, password_check, level))) {
    868                 if (fn)
    869                         fn(user, pass2);
     884
     885        nt_status = string_combinations(pass2, password_check, level,
     886                                        (void *)rhost);
     887        if (NT_STATUS_IS_OK(nt_status)) {
    870888                return nt_status;
    871889        }
    872        
     890
    873891        return NT_STATUS_WRONG_PASSWORD;
    874892}
  • trunk/server/source3/auth/token_util.c

    r414 r745  
    2626
    2727#include "includes.h"
     28#include "auth.h"
     29#include "secrets.h"
     30#include "memcache.h"
     31#include "../librpc/gen_ndr/netlogon.h"
     32#include "../libcli/security/security.h"
     33#include "../lib/util/util_pw.h"
     34#include "passdb.h"
     35#include "lib/privileges.h"
    2836
    2937/****************************************************************************
    30  Check for a SID in an NT_USER_TOKEN
     38 Check for a SID in an struct security_token
    3139****************************************************************************/
    3240
    33 bool nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
    34 {
    35         int i;
    36 
     41bool nt_token_check_sid ( const struct dom_sid *sid, const struct security_token *token )
     42{
    3743        if ( !sid || !token )
    3844                return False;
    3945
    40         for ( i=0; i<token->num_sids; i++ ) {
    41                 if ( sid_equal( sid, &token->user_sids[i] ) )
    42                         return True;
    43         }
    44 
    45         return False;
    46 }
    47 
    48 bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
    49 {
    50         DOM_SID domain_sid;
     46        return security_token_has_sid(token, sid);
     47}
     48
     49bool nt_token_check_domain_rid( struct security_token *token, uint32 rid )
     50{
     51        struct dom_sid domain_sid;
    5152
    5253        /* if we are a domain member, the get the domain SID, else for
     
    7374 This is similar to running under the context of the LOCAL_SYSTEM account
    7475 in Windows.  This is a read-only token.  Do not modify it or free() it.
    75  Create a copy if your need to change it.
     76 Create a copy if you need to change it.
    7677******************************************************************************/
    7778
    78 NT_USER_TOKEN *get_root_nt_token( void )
    79 {
    80         struct nt_user_token *token, *for_cache;
    81         DOM_SID u_sid, g_sid;
     79struct security_token *get_root_nt_token( void )
     80{
     81        struct security_token *token, *for_cache;
     82        struct dom_sid u_sid, g_sid;
    8283        struct passwd *pw;
    8384        void *cache_data;
     
    8990        if (cache_data != NULL) {
    9091                return talloc_get_type_abort(
    91                         cache_data, struct nt_user_token);
     92                        cache_data, struct security_token);
    9293        }
    9394
     
    106107        gid_to_sid(&g_sid, pw->pw_gid);
    107108
    108         token = create_local_nt_token(talloc_autofree_context(), &u_sid, False,
     109        token = create_local_nt_token(talloc_tos(), &u_sid, False,
    109110                                      1, &global_sid_Builtin_Administrators);
    110111
    111         token->privileges = se_disk_operators;
     112        security_token_set_privilege(token, SEC_PRIV_DISK_OPERATOR);
    112113
    113114        for_cache = token;
     
    125126 */
    126127
    127 NTSTATUS add_aliases(const DOM_SID *domain_sid,
    128                      struct nt_user_token *token)
     128NTSTATUS add_aliases(const struct dom_sid *domain_sid,
     129                     struct security_token *token)
    129130{
    130131        uint32 *aliases;
     
    141142
    142143        status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
    143                                             token->user_sids,
     144                                            token->sids,
    144145                                            token->num_sids,
    145146                                            &aliases, &num_aliases);
     
    152153
    153154        for (i=0; i<num_aliases; i++) {
    154                 DOM_SID alias_sid;
     155                struct dom_sid alias_sid;
    155156                sid_compose(&alias_sid, domain_sid, aliases[i]);
    156157                status = add_sid_to_array_unique(token, &alias_sid,
    157                                                  &token->user_sids,
     158                                                 &token->sids,
    158159                                                 &token->num_sids);
    159160                if (!NT_STATUS_IS_OK(status)) {
     
    171172*******************************************************************/
    172173
    173 static NTSTATUS add_builtin_administrators(struct nt_user_token *token,
    174                                            const DOM_SID *dom_sid)
    175 {
    176         DOM_SID domadm;
     174static NTSTATUS add_builtin_administrators(struct security_token *token,
     175                                           const struct dom_sid *dom_sid)
     176{
     177        struct dom_sid domadm;
    177178        NTSTATUS status;
    178179
     
    190191                sid_copy(&domadm, dom_sid);
    191192        }
    192         sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS );
     193        sid_append_rid( &domadm, DOMAIN_RID_ADMINS );
    193194
    194195        /* Add Administrators if the user beloongs to Domain Admins */
     
    197198                status = add_sid_to_array(token,
    198199                                          &global_sid_Builtin_Administrators,
    199                                           &token->user_sids, &token->num_sids);
     200                                          &token->sids, &token->num_sids);
    200201        if (!NT_STATUS_IS_OK(status)) {
    201202                        return status;
     
    206207}
    207208
    208 /**
    209  * Create the requested BUILTIN if it doesn't already exist.  This requires
    210  * winbindd to be running.
    211  *
    212  * @param[in] rid BUILTIN rid to create
    213  * @return Normal NTSTATUS return.
    214  */
    215 static NTSTATUS create_builtin(uint32 rid)
    216 {
    217         NTSTATUS status = NT_STATUS_OK;
    218         DOM_SID sid;
    219         gid_t gid;
    220 
    221         if (!sid_compose(&sid, &global_sid_Builtin, rid)) {
    222                 return NT_STATUS_NO_SUCH_ALIAS;
    223         }
    224 
    225         if (!sid_to_gid(&sid, &gid)) {
    226                 if (!lp_winbind_nested_groups() || !winbind_ping()) {
    227                         return NT_STATUS_PROTOCOL_UNREACHABLE;
    228                 }
    229                 status = pdb_create_builtin_alias(rid);
    230         }
    231         return status;
    232 }
    233 
    234 /**
    235  * Add sid as a member of builtin_sid.
    236  *
    237  * @param[in] builtin_sid       An existing builtin group.
    238  * @param[in] dom_sid           sid to add as a member of builtin_sid.
    239  * @return Normal NTSTATUS return
    240  */
    241 static NTSTATUS add_sid_to_builtin(const DOM_SID *builtin_sid,
    242                                    const DOM_SID *dom_sid)
    243 {
    244         NTSTATUS status = NT_STATUS_OK;
    245 
    246         if (!dom_sid || !builtin_sid) {
    247                 return NT_STATUS_INVALID_PARAMETER;
    248         }
    249 
    250         status = pdb_add_aliasmem(builtin_sid, dom_sid);
    251 
    252         if (NT_STATUS_EQUAL(status, NT_STATUS_MEMBER_IN_ALIAS)) {
    253                 DEBUG(5, ("add_sid_to_builtin %s is already a member of %s\n",
    254                           sid_string_dbg(dom_sid),
    255                           sid_string_dbg(builtin_sid)));
    256                 return NT_STATUS_OK;
    257         }
    258 
    259         if (!NT_STATUS_IS_OK(status)) {
    260                 DEBUG(4, ("add_sid_to_builtin %s could not be added to %s: "
    261                           "%s\n", sid_string_dbg(dom_sid),
    262                           sid_string_dbg(builtin_sid), nt_errstr(status)));
    263         }
    264         return status;
    265 }
    266 
    267 /*******************************************************************
    268 *******************************************************************/
    269 
    270 NTSTATUS create_builtin_users(const DOM_SID *dom_sid)
    271 {
     209static NTSTATUS finalize_local_nt_token(struct security_token *result,
     210                                        bool is_guest);
     211
     212NTSTATUS create_local_nt_token_from_info3(TALLOC_CTX *mem_ctx,
     213                                          bool is_guest,
     214                                          struct netr_SamInfo3 *info3,
     215                                          struct extra_auth_info *extra,
     216                                          struct security_token **ntok)
     217{
     218        struct security_token *usrtok = NULL;
    272219        NTSTATUS status;
    273         DOM_SID dom_users;
    274 
    275         status = create_builtin(BUILTIN_ALIAS_RID_USERS);
    276         if ( !NT_STATUS_IS_OK(status) ) {
    277                 DEBUG(5,("create_builtin_users: Failed to create Users\n"));
    278                 return status;
    279         }
    280 
    281         /* add domain users */
    282         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
    283                 && sid_compose(&dom_users, dom_sid, DOMAIN_GROUP_RID_USERS))
    284         {
    285                 status = add_sid_to_builtin(&global_sid_Builtin_Users,
    286                                             &dom_users);
    287         }
    288 
    289         return status;
    290 }
    291 
    292 /*******************************************************************
    293 *******************************************************************/
    294 
    295 NTSTATUS create_builtin_administrators(const DOM_SID *dom_sid)
    296 {
    297         NTSTATUS status;
    298         DOM_SID dom_admins, root_sid;
    299         fstring root_name;
    300         enum lsa_SidType type;
    301         TALLOC_CTX *ctx;
    302         bool ret;
    303 
    304         status = create_builtin(BUILTIN_ALIAS_RID_ADMINS);
    305         if ( !NT_STATUS_IS_OK(status) ) {
    306                 DEBUG(5,("create_builtin_administrators: Failed to create Administrators\n"));
    307                 return status;
    308         }
    309 
    310         /* add domain admins */
    311         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
    312                 && sid_compose(&dom_admins, dom_sid, DOMAIN_GROUP_RID_ADMINS))
    313         {
    314                 status = add_sid_to_builtin(&global_sid_Builtin_Administrators,
    315                                             &dom_admins);
    316                 if (!NT_STATUS_IS_OK(status)) {
    317                         return status;
    318                 }
    319         }
    320 
    321         /* add root */
    322         if ( (ctx = talloc_init("create_builtin_administrators")) == NULL ) {
     220        int i;
     221
     222        DEBUG(10, ("Create local NT token for %s\n",
     223                   info3->base.account_name.string));
     224
     225        usrtok = talloc_zero(mem_ctx, struct security_token);
     226        if (!usrtok) {
     227                DEBUG(0, ("talloc failed\n"));
    323228                return NT_STATUS_NO_MEMORY;
    324229        }
    325         fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
    326         ret = lookup_name(ctx, root_name, LOOKUP_NAME_DOMAIN, NULL, NULL,
    327                           &root_sid, &type);
    328         TALLOC_FREE( ctx );
    329 
    330         if ( ret ) {
    331                 status = add_sid_to_builtin(&global_sid_Builtin_Administrators,
    332                                             &root_sid);
    333         }
    334 
    335         return status;
    336 }
    337 
    338 
    339 /*******************************************************************
    340  Create a NT token for the user, expanding local aliases
    341 *******************************************************************/
    342 
    343 struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
    344                                             const DOM_SID *user_sid,
    345                                             bool is_guest,
    346                                             int num_groupsids,
    347                                             const DOM_SID *groupsids)
    348 {
    349         struct nt_user_token *result = NULL;
    350         int i;
    351         NTSTATUS status;
    352         gid_t gid;
    353         DOM_SID dom_sid;
    354 
    355         DEBUG(10, ("Create local NT token for %s\n",
    356                    sid_string_dbg(user_sid)));
    357 
    358         if (!(result = TALLOC_ZERO_P(mem_ctx, struct nt_user_token))) {
    359                 DEBUG(0, ("talloc failed\n"));
    360                 return NULL;
    361         }
    362 
    363         /* Add the user and primary group sid */
    364 
    365         status = add_sid_to_array(result, user_sid,
    366                                   &result->user_sids, &result->num_sids);
    367         if (!NT_STATUS_IS_OK(status)) {
    368                 return NULL;
    369         }
    370 
    371         /* For guest, num_groupsids may be zero. */
    372         if (num_groupsids) {
    373                 status = add_sid_to_array(result, &groupsids[0],
    374                                           &result->user_sids,
    375                                           &result->num_sids);
    376                 if (!NT_STATUS_IS_OK(status)) {
    377                         return NULL;
    378                 }
    379         }
    380 
    381         /* Add in BUILTIN sids */
    382 
    383         status = add_sid_to_array(result, &global_sid_World,
    384                                   &result->user_sids, &result->num_sids);
    385         if (!NT_STATUS_IS_OK(status)) {
    386                 return NULL;
    387         }
    388         status = add_sid_to_array(result, &global_sid_Network,
    389                                   &result->user_sids, &result->num_sids);
    390         if (!NT_STATUS_IS_OK(status)) {
    391                 return NULL;
    392         }
    393 
    394         if (is_guest) {
    395                 status = add_sid_to_array(result, &global_sid_Builtin_Guests,
    396                                           &result->user_sids,
    397                                           &result->num_sids);
    398                 if (!NT_STATUS_IS_OK(status)) {
    399                         return NULL;
    400                 }
     230
     231        /* Add the user and primary group sid FIRST */
     232        /* check if the user rid is the special "Domain Guests" rid.
     233         * If so pick the first sid for the extra sids instead as it
     234         * is a local fake account */
     235        usrtok->sids = talloc_array(usrtok, struct dom_sid, 2);
     236        if (!usrtok->sids) {
     237                TALLOC_FREE(usrtok);
     238                return NT_STATUS_NO_MEMORY;
     239        }
     240        usrtok->num_sids = 2;
     241
     242        /* USER SID */
     243        if (info3->base.rid == (uint32_t)(-1)) {
     244                /* this is a signal the user was fake and generated,
     245                 * the actual SID we want to use is stored in the extra
     246                 * sids */
     247                if (is_null_sid(&extra->user_sid)) {
     248                        /* we couldn't find the user sid, bail out */
     249                        DEBUG(3, ("Invalid user SID\n"));
     250                        TALLOC_FREE(usrtok);
     251                        return NT_STATUS_UNSUCCESSFUL;
     252                }
     253                sid_copy(&usrtok->sids[0], &extra->user_sid);
    401254        } else {
    402                 status = add_sid_to_array(result,
    403                                           &global_sid_Authenticated_Users,
    404                                           &result->user_sids,
    405                                           &result->num_sids);
    406                 if (!NT_STATUS_IS_OK(status)) {
    407                         return NULL;
    408                 }
     255                sid_copy(&usrtok->sids[0], info3->base.domain_sid);
     256                sid_append_rid(&usrtok->sids[0], info3->base.rid);
     257        }
     258
     259        /* GROUP SID */
     260        if (info3->base.primary_gid == (uint32_t)(-1)) {
     261                /* this is a signal the user was fake and generated,
     262                 * the actual SID we want to use is stored in the extra
     263                 * sids */
     264                if (is_null_sid(&extra->pgid_sid)) {
     265                        /* we couldn't find the user sid, bail out */
     266                        DEBUG(3, ("Invalid group SID\n"));
     267                        TALLOC_FREE(usrtok);
     268                        return NT_STATUS_UNSUCCESSFUL;
     269                }
     270                sid_copy(&usrtok->sids[1], &extra->pgid_sid);
     271        } else {
     272                sid_copy(&usrtok->sids[1], info3->base.domain_sid);
     273                sid_append_rid(&usrtok->sids[1],
     274                                info3->base.primary_gid);
    409275        }
    410276
     
    415281         * first group sid as primary above. */
    416282
     283        for (i = 0; i < info3->base.groups.count; i++) {
     284                struct dom_sid tmp_sid;
     285
     286                sid_copy(&tmp_sid, info3->base.domain_sid);
     287                sid_append_rid(&tmp_sid, info3->base.groups.rids[i].rid);
     288
     289                status = add_sid_to_array_unique(usrtok, &tmp_sid,
     290                                                 &usrtok->sids,
     291                                                 &usrtok->num_sids);
     292                if (!NT_STATUS_IS_OK(status)) {
     293                        DEBUG(3, ("Failed to add SID to nt token\n"));
     294                        TALLOC_FREE(usrtok);
     295                        return status;
     296                }
     297        }
     298
     299        /* now also add extra sids if they are not the special user/group
     300         * sids */
     301        for (i = 0; i < info3->sidcount; i++) {
     302                status = add_sid_to_array_unique(usrtok,
     303                                                 info3->sids[i].sid,
     304                                                 &usrtok->sids,
     305                                                 &usrtok->num_sids);
     306                if (!NT_STATUS_IS_OK(status)) {
     307                        DEBUG(3, ("Failed to add SID to nt token\n"));
     308                        TALLOC_FREE(usrtok);
     309                        return status;
     310                }
     311        }
     312
     313        status = finalize_local_nt_token(usrtok, is_guest);
     314        if (!NT_STATUS_IS_OK(status)) {
     315                DEBUG(3, ("Failed to finalize nt token\n"));
     316                TALLOC_FREE(usrtok);
     317                return status;
     318        }
     319
     320        *ntok = usrtok;
     321        return NT_STATUS_OK;
     322}
     323
     324/*******************************************************************
     325 Create a NT token for the user, expanding local aliases
     326*******************************************************************/
     327
     328struct security_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
     329                                            const struct dom_sid *user_sid,
     330                                            bool is_guest,
     331                                            int num_groupsids,
     332                                            const struct dom_sid *groupsids)
     333{
     334        struct security_token *result = NULL;
     335        int i;
     336        NTSTATUS status;
     337
     338        DEBUG(10, ("Create local NT token for %s\n",
     339                   sid_string_dbg(user_sid)));
     340
     341        if (!(result = TALLOC_ZERO_P(mem_ctx, struct security_token))) {
     342                DEBUG(0, ("talloc failed\n"));
     343                return NULL;
     344        }
     345
     346        /* Add the user and primary group sid */
     347
     348        status = add_sid_to_array(result, user_sid,
     349                                  &result->sids, &result->num_sids);
     350        if (!NT_STATUS_IS_OK(status)) {
     351                TALLOC_FREE(result);
     352                return NULL;
     353        }
     354
     355        /* For guest, num_groupsids may be zero. */
     356        if (num_groupsids) {
     357                status = add_sid_to_array(result, &groupsids[0],
     358                                          &result->sids,
     359                                          &result->num_sids);
     360                if (!NT_STATUS_IS_OK(status)) {
     361                        TALLOC_FREE(result);
     362                        return NULL;
     363                }
     364        }
     365
     366        /* Now the SIDs we got from authentication. These are the ones from
     367         * the info3 struct or from the pdb_enum_group_memberships, depending
     368         * on who authenticated the user.
     369         * Note that we start the for loop at "1" here, we already added the
     370         * first group sid as primary above. */
     371
    417372        for (i=1; i<num_groupsids; i++) {
    418373                status = add_sid_to_array_unique(result, &groupsids[i],
    419                                                  &result->user_sids,
     374                                                 &result->sids,
    420375                                                 &result->num_sids);
    421376                if (!NT_STATUS_IS_OK(status)) {
     377                        TALLOC_FREE(result);
    422378                        return NULL;
     379                }
     380        }
     381
     382        status = finalize_local_nt_token(result, is_guest);
     383        if (!NT_STATUS_IS_OK(status)) {
     384                TALLOC_FREE(result);
     385                return NULL;
     386        }
     387
     388        return result;
     389}
     390
     391static NTSTATUS finalize_local_nt_token(struct security_token *result,
     392                                        bool is_guest)
     393{
     394        struct dom_sid dom_sid;
     395        gid_t gid;
     396        NTSTATUS status;
     397
     398        /* Add in BUILTIN sids */
     399
     400        status = add_sid_to_array(result, &global_sid_World,
     401                                  &result->sids, &result->num_sids);
     402        if (!NT_STATUS_IS_OK(status)) {
     403                return status;
     404        }
     405        status = add_sid_to_array(result, &global_sid_Network,
     406                                  &result->sids, &result->num_sids);
     407        if (!NT_STATUS_IS_OK(status)) {
     408                return status;
     409        }
     410
     411        if (is_guest) {
     412                status = add_sid_to_array(result, &global_sid_Builtin_Guests,
     413                                          &result->sids,
     414                                          &result->num_sids);
     415                if (!NT_STATUS_IS_OK(status)) {
     416                        return status;
     417                }
     418        } else {
     419                status = add_sid_to_array(result,
     420                                          &global_sid_Authenticated_Users,
     421                                          &result->sids,
     422                                          &result->num_sids);
     423                if (!NT_STATUS_IS_OK(status)) {
     424                        return status;
    423425                }
    424426        }
     
    491493                if (!NT_STATUS_IS_OK(status)) {
    492494                        unbecome_root();
    493                         TALLOC_FREE(result);
    494                         return NULL;
     495                        return status;
    495496                }
    496497
     
    501502                if (!NT_STATUS_IS_OK(status)) {
    502503                        unbecome_root();
    503                         TALLOC_FREE(result);
    504                         return NULL;
     504                        return status;
    505505                }
    506506
     
    508508        }
    509509
    510 
    511         get_privileges_for_sids(&result->privileges, result->user_sids,
     510        /* Add privileges based on current user sids */
     511
     512        get_privileges_for_sids(&result->privilege_mask, result->sids,
    512513                                result->num_sids);
    513         return result;
    514 }
    515 
    516 /****************************************************************************
    517  prints a NT_USER_TOKEN to debug output.
    518 ****************************************************************************/
    519 
    520 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
    521 {
    522         size_t     i;
    523 
    524         if (!token) {
    525                 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
    526                 return;
    527         }
    528 
    529         DEBUGC(dbg_class, dbg_lev,
    530                ("NT user token of user %s\n",
    531                 sid_string_dbg(&token->user_sids[0]) ));
    532         DEBUGADDC(dbg_class, dbg_lev,
    533                   ("contains %lu SIDs\n", (unsigned long)token->num_sids));
    534         for (i = 0; i < token->num_sids; i++)
    535                 DEBUGADDC(dbg_class, dbg_lev,
    536                           ("SID[%3lu]: %s\n", (unsigned long)i,
    537                            sid_string_dbg(&token->user_sids[i])));
    538 
    539         dump_se_priv( dbg_class, dbg_lev, &token->privileges );
     514
     515        return NT_STATUS_OK;
    540516}
    541517
     
    559535}
    560536
     537/*
     538 * Create an artificial NT token given just a username. (Initially intended
     539 * for force user)
     540 *
     541 * We go through lookup_name() to avoid problems we had with 'winbind use
     542 * default domain'.
     543 *
     544 * We have 3 cases:
     545 *
     546 * unmapped unix users: Go directly to nss to find the user's group.
     547 *
     548 * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
     549 *
     550 * If the user is provided by winbind, the primary gid is set to "domain
     551 * users" of the user's domain. For an explanation why this is necessary, see
     552 * the thread starting at
     553 * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
     554 */
     555
     556NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
     557                                    bool is_guest,
     558                                    uid_t *uid, gid_t *gid,
     559                                    char **found_username,
     560                                    struct security_token **token)
     561{
     562        NTSTATUS result = NT_STATUS_NO_SUCH_USER;
     563        TALLOC_CTX *tmp_ctx = talloc_stackframe();
     564        struct dom_sid user_sid;
     565        enum lsa_SidType type;
     566        gid_t *gids;
     567        struct dom_sid *group_sids;
     568        struct dom_sid unix_group_sid;
     569        uint32_t num_group_sids;
     570        uint32_t num_gids;
     571        uint32_t i;
     572
     573        if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
     574                         NULL, NULL, &user_sid, &type)) {
     575                DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
     576                goto done;
     577        }
     578
     579        if (type != SID_NAME_USER) {
     580                DEBUG(1, ("%s is a %s, not a user\n", username,
     581                          sid_type_lookup(type)));
     582                goto done;
     583        }
     584
     585        if (sid_check_is_in_our_domain(&user_sid)) {
     586                bool ret;
     587                uint32_t pdb_num_group_sids;
     588                /* This is a passdb user, so ask passdb */
     589
     590                struct samu *sam_acct = NULL;
     591
     592                if ( !(sam_acct = samu_new( tmp_ctx )) ) {
     593                        result = NT_STATUS_NO_MEMORY;
     594                        goto done;
     595                }
     596
     597                become_root();
     598                ret = pdb_getsampwsid(sam_acct, &user_sid);
     599                unbecome_root();
     600
     601                if (!ret) {
     602                        DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
     603                                  sid_string_dbg(&user_sid), username));
     604                        DEBUGADD(1, ("Fall back to unix user %s\n", username));
     605                        goto unix_user;
     606                }
     607
     608                result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
     609                                                    &group_sids, &gids,
     610                                                    &pdb_num_group_sids);
     611                if (!NT_STATUS_IS_OK(result)) {
     612                        DEBUG(1, ("enum_group_memberships failed for %s (%s): "
     613                                  "%s\n", username, sid_string_dbg(&user_sid),
     614                                  nt_errstr(result)));
     615                        DEBUGADD(1, ("Fall back to unix user %s\n", username));
     616                        goto unix_user;
     617                }
     618                num_group_sids = pdb_num_group_sids;
     619
     620                /* see the smb_panic() in pdb_default_enum_group_memberships */
     621                SMB_ASSERT(num_group_sids > 0);
     622
     623                *gid = gids[0];
     624
     625                /* Ensure we're returning the found_username on the right context. */
     626                *found_username = talloc_strdup(mem_ctx,
     627                                                pdb_get_username(sam_acct));
     628
     629                /*
     630                 * If the SID from lookup_name() was the guest sid, passdb knows
     631                 * about the mapping of guest sid to lp_guestaccount()
     632                 * username and will return the unix_pw info for a guest
     633                 * user. Use it if it's there, else lookup the *uid details
     634                 * using Get_Pwnam_alloc(). See bug #6291 for details. JRA.
     635                 */
     636
     637                /* We must always assign the *uid. */
     638                if (sam_acct->unix_pw == NULL) {
     639                        struct passwd *pwd = Get_Pwnam_alloc(sam_acct, *found_username );
     640                        if (!pwd) {
     641                                DEBUG(10, ("Get_Pwnam_alloc failed for %s\n",
     642                                        *found_username));
     643                                result = NT_STATUS_NO_SUCH_USER;
     644                                goto done;
     645                        }
     646                        result = samu_set_unix(sam_acct, pwd );
     647                        if (!NT_STATUS_IS_OK(result)) {
     648                                DEBUG(10, ("samu_set_unix failed for %s\n",
     649                                        *found_username));
     650                                result = NT_STATUS_NO_SUCH_USER;
     651                                goto done;
     652                        }
     653                }
     654                *uid = sam_acct->unix_pw->pw_uid;
     655
     656        } else  if (sid_check_is_in_unix_users(&user_sid)) {
     657                uint32_t getgroups_num_group_sids;
     658                /* This is a unix user not in passdb. We need to ask nss
     659                 * directly, without consulting passdb */
     660
     661                struct passwd *pass;
     662
     663                /*
     664                 * This goto target is used as a fallback for the passdb
     665                 * case. The concrete bug report is when passdb gave us an
     666                 * unmapped gid.
     667                 */
     668
     669        unix_user:
     670
     671                if (!sid_to_uid(&user_sid, uid)) {
     672                        DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n",
     673                                  username, sid_string_dbg(&user_sid)));
     674                        result = NT_STATUS_NO_SUCH_USER;
     675                        goto done;
     676                }
     677
     678                uid_to_unix_users_sid(*uid, &user_sid);
     679
     680                pass = getpwuid_alloc(tmp_ctx, *uid);
     681                if (pass == NULL) {
     682                        DEBUG(1, ("getpwuid(%u) for user %s failed\n",
     683                                  (unsigned int)*uid, username));
     684                        goto done;
     685                }
     686
     687                if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
     688                                         &gids, &getgroups_num_group_sids)) {
     689                        DEBUG(1, ("getgroups_unix_user for user %s failed\n",
     690                                  username));
     691                        goto done;
     692                }
     693                num_group_sids = getgroups_num_group_sids;
     694
     695                if (num_group_sids) {
     696                        group_sids = TALLOC_ARRAY(tmp_ctx, struct dom_sid, num_group_sids);
     697                        if (group_sids == NULL) {
     698                                DEBUG(1, ("TALLOC_ARRAY failed\n"));
     699                                result = NT_STATUS_NO_MEMORY;
     700                                goto done;
     701                        }
     702                } else {
     703                        group_sids = NULL;
     704                }
     705
     706                for (i=0; i<num_group_sids; i++) {
     707                        gid_to_sid(&group_sids[i], gids[i]);
     708                }
     709
     710                /* In getgroups_unix_user we always set the primary gid */
     711                SMB_ASSERT(num_group_sids > 0);
     712
     713                *gid = gids[0];
     714
     715                /* Ensure we're returning the found_username on the right context. */
     716                *found_username = talloc_strdup(mem_ctx, pass->pw_name);
     717        } else {
     718
     719                /* This user is from winbind, force the primary gid to the
     720                 * user's "domain users" group. Under certain circumstances
     721                 * (user comes from NT4), this might be a loss of
     722                 * information. But we can not rely on winbind getting the
     723                 * correct info. AD might prohibit winbind looking up that
     724                 * information. */
     725
     726                /* We must always assign the *uid. */
     727                if (!sid_to_uid(&user_sid, uid)) {
     728                        DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n",
     729                                  username, sid_string_dbg(&user_sid)));
     730                        result = NT_STATUS_NO_SUCH_USER;
     731                        goto done;
     732                }
     733
     734                num_group_sids = 1;
     735                group_sids = TALLOC_ARRAY(tmp_ctx, struct dom_sid, num_group_sids);
     736                if (group_sids == NULL) {
     737                        DEBUG(1, ("TALLOC_ARRAY failed\n"));
     738                        result = NT_STATUS_NO_MEMORY;
     739                        goto done;
     740                }
     741
     742                sid_copy(&group_sids[0], &user_sid);
     743                sid_split_rid(&group_sids[0], NULL);
     744                sid_append_rid(&group_sids[0], DOMAIN_RID_USERS);
     745
     746                if (!sid_to_gid(&group_sids[0], gid)) {
     747                        DEBUG(1, ("sid_to_gid(%s) failed\n",
     748                                  sid_string_dbg(&group_sids[0])));
     749                        goto done;
     750                }
     751
     752                gids = gid;
     753
     754                /* Ensure we're returning the found_username on the right context. */
     755                *found_username = talloc_strdup(mem_ctx, username);
     756        }
     757
     758        /* Add the "Unix Group" SID for each gid to catch mapped groups
     759           and their Unix equivalent.  This is to solve the backwards
     760           compatibility problem of 'valid users = +ntadmin' where
     761           ntadmin has been paired with "Domain Admins" in the group
     762           mapping table.  Otherwise smb.conf would need to be changed
     763           to 'valid user = "Domain Admins"'.  --jerry */
     764
     765        num_gids = num_group_sids;
     766        for ( i=0; i<num_gids; i++ ) {
     767                gid_t high, low;
     768
     769                /* don't pickup anything managed by Winbind */
     770
     771                if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
     772                        continue;
     773
     774                gid_to_unix_groups_sid(gids[i], &unix_group_sid);
     775
     776                result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
     777                                                 &group_sids, &num_group_sids);
     778                if (!NT_STATUS_IS_OK(result)) {
     779                        goto done;
     780                }
     781        }
     782
     783        /* Ensure we're creating the nt_token on the right context. */
     784        *token = create_local_nt_token(mem_ctx, &user_sid,
     785                                       is_guest, num_group_sids, group_sids);
     786
     787        if ((*token == NULL) || (*found_username == NULL)) {
     788                result = NT_STATUS_NO_MEMORY;
     789                goto done;
     790        }
     791
     792        result = NT_STATUS_OK;
     793 done:
     794        TALLOC_FREE(tmp_ctx);
     795        return result;
     796}
     797
     798/***************************************************************************
     799 Build upon create_token_from_username:
     800
     801 Expensive helper function to figure out whether a user given its name is
     802 member of a particular group.
     803***************************************************************************/
     804
     805bool user_in_group_sid(const char *username, const struct dom_sid *group_sid)
     806{
     807        NTSTATUS status;
     808        uid_t uid;
     809        gid_t gid;
     810        char *found_username;
     811        struct security_token *token;
     812        bool result;
     813        TALLOC_CTX *mem_ctx = talloc_stackframe();
     814
     815        status = create_token_from_username(mem_ctx, username, False,
     816                                            &uid, &gid, &found_username,
     817                                            &token);
     818
     819        if (!NT_STATUS_IS_OK(status)) {
     820                DEBUG(10, ("could not create token for %s\n", username));
     821                TALLOC_FREE(mem_ctx);
     822                return False;
     823        }
     824
     825        result = security_token_has_sid(token, group_sid);
     826
     827        TALLOC_FREE(mem_ctx);
     828        return result;
     829}
     830
     831bool user_in_group(const char *username, const char *groupname)
     832{
     833        TALLOC_CTX *mem_ctx = talloc_stackframe();
     834        struct dom_sid group_sid;
     835        bool ret;
     836
     837        ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
     838                          NULL, NULL, &group_sid, NULL);
     839        TALLOC_FREE(mem_ctx);
     840
     841        if (!ret) {
     842                DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
     843                return False;
     844        }
     845
     846        return user_in_group_sid(username, &group_sid);
     847}
     848
    561849/* END */
Note: See TracChangeset for help on using the changeset viewer.