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:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • 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        }
Note: See TracChangeset for help on using the changeset viewer.