This patch takes the work the jerry did for beta2, and generalises it:
authorAndrew Bartlett <abartlet@samba.org>
Thu, 3 Jul 2003 14:36:42 +0000 (14:36 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 3 Jul 2003 14:36:42 +0000 (14:36 +0000)
 - The 'not implmented' checks are now done by all auth modules
 - the ntdomain/trustdomain/winbind modules are more presise as to
   what domain names they can and cannot handle
 - The become_root() calls are now around the winbind pipe opening only,
   not the entire auth call
 - The unix username is kept seperate from the NT username, removing the
   need for 'clean off the domain\' in parse_net.c
 - All sid->uid translations are now validated with getpwuid() to put a very
   basic stop to logins with 'half deleted' accounts.

Andrew Bartlett

source/auth/auth.c
source/auth/auth_builtin.c
source/auth/auth_domain.c
source/auth/auth_rhosts.c
source/auth/auth_server.c
source/auth/auth_util.c
source/auth/auth_winbind.c
source/include/auth.h
source/rpc_parse/parse_net.c
source/rpc_server/srv_netlog_nt.c
source/rpc_server/srv_pipe.c

index d99b00d4a73c3442ae64076ef1eb80641d63878c..9f109dc66e14ec711baa3a2398ea5a9e39ce7960 100644 (file)
@@ -203,8 +203,8 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
                                    const struct auth_usersupplied_info *user_info, 
                                    struct auth_serversupplied_info **server_info)
 {
-       
-       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+       /* if all the modules say 'not for me' this is reasonable */
+       NTSTATUS nt_status = NT_STATUS_NO_SUCH_USER;
        const char *pdb_username;
        auth_methods *auth_method;
        TALLOC_CTX *mem_ctx;
@@ -269,12 +269,8 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
                }
 
                talloc_destroy(mem_ctx);
-               
-               /* this sucks.  Somehow we have to know if an authentication module is 
-                  authoritative for a user.  Fixme!!!  --jerry */
-               
-               if ( NT_STATUS_IS_OK(nt_status) || 
-                       NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_WRONG_PASSWORD) )
+
+               if ( NT_STATUS_IS_OK(nt_status))
                {
                                break;                  
                }
@@ -463,8 +459,13 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
                        break;
                case SEC_USER:
                        if (lp_encrypted_passwords()) { 
-                               DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n"));
-                               auth_method_list = str_list_make("guest sam", NULL);
+                               if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
+                                       DEBUG(5,("Making default auth method list for DC, security=user, encrypt passwords = yes\n"));
+                                       auth_method_list = str_list_make("guest sam winbind:trustdomain", NULL);
+                               } else {
+                                       DEBUG(5,("Making default auth method list for standalone security=user, encrypt passwords = yes\n"));
+                                       auth_method_list = str_list_make("guest sam", NULL);
+                               }
                        } else {
                                DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
                                auth_method_list = str_list_make("guest unix", NULL);
index 5a9b5534ab61b4e80db115f7911d9445420f2149..0358836793003718e57f25c2f90f5839844f8b49 100644 (file)
@@ -38,7 +38,8 @@ static NTSTATUS check_guest_security(const struct auth_context *auth_context,
                                     const auth_usersupplied_info *user_info, 
                                     auth_serversupplied_info **server_info)
 {
-       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+       /* mark this as 'not for me' */
+       NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
 
        if (!(user_info->internal_username.str 
              && *user_info->internal_username.str)) {
@@ -133,7 +134,7 @@ static NTSTATUS check_fixed_challenge_security(const struct auth_context *auth_c
                                               const auth_usersupplied_info *user_info, 
                                               auth_serversupplied_info **server_info)
 {
-       return NT_STATUS_UNSUCCESSFUL;
+       return NT_STATUS_NOT_IMPLEMENTED;
 }
 
 /****************************************************************************
index 80320d8266ce77ea9e20c6eb7c4f7d7578d43a97..56bd6b9acab36c67ddd5b64b5503fb4b4efec118 100644 (file)
@@ -266,7 +266,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
         * password file.
         */
 
-       if(is_myname(user_info->domain.str)) {
+       if(strequal(get_global_sam_name(), user_info->domain.str)) {
                DEBUG(3,("check_ntdomain_security: Requested domain was for this machine.\n"));
                return NT_STATUS_NOT_IMPLEMENTED;
        }
@@ -346,7 +346,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
         * Check that the requested domain is not our own machine name or domain name.
         */
 
-       if( is_myname(user_info->domain.str) || strequal(lp_workgroup(), user_info->domain.str) ) {
+       if( strequal(get_global_sam_name(), user_info->domain.str)) {
                DEBUG(3,("check_trustdomain_security: Requested domain [%s] was for this machine.\n",
                        user_info->domain.str));
                return NT_STATUS_NOT_IMPLEMENTED;
@@ -358,7 +358,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
           user is known to us and does not exist */
        
        if ( !is_trusted_domain( user_info->domain.str ) )
-               return NT_STATUS_NO_SUCH_USER;
+               return NT_STATUS_NOT_IMPLEMENTED;
 
        /*
         * Get the trusted account password for the trusted domain
index 8fec760e212532c30756e31d1ff332e31082bc65..e2c6f0b06ad284e07fb4d05627f132e8e663260b 100644 (file)
@@ -162,7 +162,7 @@ static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_contex
                                          const auth_usersupplied_info *user_info, 
                                          auth_serversupplied_info **server_info)
 {
-       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+       NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
        SAM_ACCOUNT *account = NULL;
        if (!NT_STATUS_IS_OK(nt_status = 
                             auth_get_sam_account(user_info->internal_username.str, 
@@ -174,7 +174,6 @@ static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_contex
                nt_status = make_server_info_sam(server_info, account);
        } else {
                pdb_free_sam(&account);
-               nt_status = NT_STATUS_LOGON_FAILURE;
        }
 
        return nt_status;
@@ -203,7 +202,7 @@ static NTSTATUS check_rhosts_security(const struct auth_context *auth_context,
                                      const auth_usersupplied_info *user_info, 
                                      auth_serversupplied_info **server_info)
 {
-       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+       NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
        SAM_ACCOUNT *account = NULL;
        pstring rhostsfile;
        const char *home;
@@ -223,12 +222,10 @@ static NTSTATUS check_rhosts_security(const struct auth_context *auth_context,
                        nt_status = make_server_info_sam(server_info, account);
                } else {
                        pdb_free_sam(&account);
-                       nt_status = NT_STATUS_LOGON_FAILURE;
                }
                unbecome_root();
        } else {
                pdb_free_sam(&account);
-               nt_status = NT_STATUS_LOGON_FAILURE;
        }
        
        return nt_status;
index 2a1e4a48d98d2e11763e5bea7695a693d08e4211..af0848e12a8bc9bc6b1dfa98301279d527de16ed 100644 (file)
@@ -222,7 +222,7 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context
        static fstring baduser; 
        static BOOL tested_password_server = False;
        static BOOL bad_password_server = False;
-       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+       NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
        BOOL locally_made_cli = False;
 
        /* 
@@ -233,7 +233,7 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context
 
        if(is_myname(user_info->domain.str)) {
                DEBUG(3,("check_smbserver_security: Requested domain was for this machine.\n"));
-               return NT_STATUS_LOGON_FAILURE;
+               return nt_status;
        }
 
        cli = my_private_data;
index 4e25d7fd340666b109611c6f1fa6f66ebfaa4a20..ea46d27e9e9de736ef1f250c0c97b05d5ee3cb41 100644 (file)
@@ -764,6 +764,7 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
                              SAM_ACCOUNT *sampass)
 {
        NTSTATUS nt_status;
+       struct passwd *pwd;
 
        if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info)))
                return nt_status;
@@ -773,16 +774,35 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
        if (!NT_STATUS_IS_OK(nt_status = sid_to_uid(pdb_get_user_sid(sampass), &((*server_info)->uid))))
                return nt_status;
 
-       if (!NT_STATUS_IS_OK(nt_status = sid_to_gid(pdb_get_group_sid(sampass), &((*server_info)->gid))))
+       if (!(pwd = getpwuid_alloc(((*server_info)->uid)))) {
+               fstring sid;
+               DEBUG(1, ("User %s in passdb (%s) maps to UID, but getpwuid(%u) fails!\n",
+                         pdb_get_username(sampass), 
+                         sid_to_string(sid, pdb_get_user_sid(sampass)),
+                         (unsigned)(*server_info)->uid));
+               free_server_info(server_info);
+               return NT_STATUS_NO_SUCH_USER;
+       }
+       (*server_info)->unix_name = smb_xstrdup(pwd->pw_name);
+       passwd_free(&pwd);
+
+       if (!NT_STATUS_IS_OK(nt_status = sid_to_gid(pdb_get_group_sid(sampass), 
+                                                   &((*server_info)->gid)))) {
+               free_server_info(server_info);
                return nt_status;
+       }
 
        if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass, 
-                                                        (*server_info)->uid, (*server_info)->gid)))
+                                                        (*server_info)->uid, 
+                                                        (*server_info)->gid))) {
+               free_server_info(server_info);
                return nt_status;
+       }
 
        (*server_info)->sam_fill_level = SAM_FILL_ALL;
-       DEBUG(5,("make_server_info_sam: made server info for user %s\n",
-                pdb_get_username((*server_info)->sam_account)));
+       DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
+                pdb_get_username(sampass),
+                (*server_info)->unix_name));
 
        return nt_status;
 }
@@ -809,6 +829,8 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, const struc
                return nt_status;
        }
 
+       (*server_info)->unix_name = smb_xstrdup(pwd->pw_name);
+
        (*server_info)->sam_fill_level = SAM_FILL_ALL;
        (*server_info)->uid = pwd->pw_uid;
        (*server_info)->gid = pwd->pw_gid;
@@ -852,8 +874,10 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
  Purely internal function for make_server_info_info3
  Fill the sam account from getpwnam
 ***************************************************************************/
-static NTSTATUS fill_sam_account(const char *domain,
+static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
+                                const char *domain,
                                 const char *username,
+                                char **found_username,
                                 uid_t *uid, gid_t *gid,
                                 SAM_ACCOUNT **sam_account)
 {
@@ -878,6 +902,8 @@ static NTSTATUS fill_sam_account(const char *domain,
        *uid = passwd->pw_uid;
        *gid = passwd->pw_gid;
 
+       *found_username = talloc_strdup(mem_ctx, passwd->pw_name);
+
        return pdb_init_sam_pw(sam_account, passwd);
 }
 
@@ -893,7 +919,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
                                NET_USER_INFO_3 *info3) 
 {
        NTSTATUS nt_status = NT_STATUS_OK;
-
+       char *found_username;
        const char *nt_domain;
        const char *nt_username;
 
@@ -958,13 +984,15 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
                gid = passwd->pw_gid;
  
                /* we should check this is the same name */
-
+               found_username = talloc_strdup(mem_ctx, passwd->pw_name);
+               
                passwd_free(&passwd);
        } else {
 
                /* User not from winbind - try and find them by getpwnam() */
-               nt_status = fill_sam_account(nt_domain,
+               nt_status = fill_sam_account(mem_ctx, nt_domain,
                                             internal_username,
+                                            &found_username,
                                             &uid, &gid,
                                             &sam_account);
 
@@ -972,8 +1000,9 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
                        DEBUG(3,("User %s does not exist, trying to add it\n",
                                 internal_username));
                        auth_add_user_script(nt_domain, internal_username);
-                       nt_status = fill_sam_account(nt_domain,
+                       nt_status = fill_sam_account(mem_ctx, nt_domain,
                                                     internal_username,
+                                                    &found_username,
                                                     &uid, &gid,
                                                     &sam_account);
                }
@@ -984,17 +1013,12 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
                return nt_status;
        }
                
-       if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
+       if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
                pdb_free_sam(&sam_account);
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_NO_MEMORY;
        }
 
-       if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
-               pdb_free_sam(&sam_account);
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-               
-       if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
+       if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
                pdb_free_sam(&sam_account);
                return NT_STATUS_NO_MEMORY;
        }
@@ -1004,7 +1028,18 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)), PDB_CHANGED)) {
+       if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
+               pdb_free_sam(&sam_account);
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
+               pdb_free_sam(&sam_account);
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+               
+       if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)), 
+                             PDB_CHANGED)) {
                pdb_free_sam(&sam_account);
                return NT_STATUS_NO_MEMORY;
        }
@@ -1040,6 +1075,8 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
                   
        (*server_info)->sam_account = sam_account;
 
+       (*server_info)->unix_name = smb_xstrdup(found_username);
+
        /* Fill in the unix info we found on the way */
 
        (*server_info)->sam_fill_level = SAM_FILL_ALL;
@@ -1050,7 +1087,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
           returned to the caller. */
        
        if (!NT_STATUS_IS_OK(nt_status 
-                            = get_user_groups_from_local_sam(pdb_get_username(sam_account), 
+                            = get_user_groups_from_local_sam((*server_info)->unix_name,
                                                              uid, gid, 
                                                              &n_lgroupSIDs, 
                                                              &lgroupSIDs, 
@@ -1070,6 +1107,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
        if (!all_group_SIDs) {
                DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
                SAFE_FREE(lgroupSIDs);
+               free_server_info(server_info);
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -1085,6 +1123,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
                        DEBUG(3,("could not append additional group rid 0x%x\n",
                                info3->gids[i].g_rid));                 
                        SAFE_FREE(lgroupSIDs);
+                       free_server_info(server_info);
                        return nt_status;
                }
        }
@@ -1110,6 +1149,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
                            all_group_SIDs, False, &token))) {
                DEBUG(4,("create_nt_user_token failed\n"));
                SAFE_FREE(all_group_SIDs);
+               free_server_info(server_info);
                return nt_status;
        }
 
@@ -1161,6 +1201,7 @@ void free_server_info(auth_serversupplied_info **server_info)
                /* call pam_end here, unless we know we are keeping it */
                delete_nt_token( &(*server_info)->ptok );
                SAFE_FREE((*server_info)->groups);
+               SAFE_FREE((*server_info)->unix_name);
                ZERO_STRUCT(**server_info);
        }
        SAFE_FREE(*server_info);
index 6ae8685b113372aeec926e38c9163945851eafa0..856b8f5a82b011bc5d740d06298c522bcdb71fc5 100644 (file)
@@ -72,9 +72,14 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
        if (!auth_context) {
                DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n", 
                         user_info->internal_username.str));            
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_INVALID_PARAMETER;
        }               
 
+       if (strequal(user_info->domain.str, get_global_sam_name())) {
+               DEBUG(3,("check_winbind_security: Not using winbind, requested domain was for this SAM.\n"));
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
        /* Send off request */
 
        ZERO_STRUCT(request);
@@ -100,8 +105,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
               request.data.auth_crap.lm_resp_len);
        memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data, 
               request.data.auth_crap.nt_resp_len);
-       
+
+       /* we are contacting the privileged pipe */
+       become_root();
        result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
+       unbecome_root();
 
        if ( result == NSS_STATUS_UNAVAIL )  {
                struct auth_methods *auth_method = my_private_data;
@@ -129,7 +137,7 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
                        }
                }
        } else if (NT_STATUS_IS_OK(nt_status)) {
-               nt_status = NT_STATUS_UNSUCCESSFUL;
+               nt_status = NT_STATUS_NO_LOGON_SERVERS;
        }
 
         return nt_status;
index eb80e3c5b4ae666a7c8164130575525e408bdd34..6b42418be8d4d3dce1d1f22509c017225068d95f 100644 (file)
@@ -96,6 +96,8 @@ typedef struct auth_serversupplied_info
        SAM_ACCOUNT *sam_account;
        
        void *pam_handle;
+
+       char *unix_name;
        
 } auth_serversupplied_info;
 
index 43bd8cd20e15ba66556f8666e997142b60879916..f977549a0709fcd9db239cac03fc7052e32197c0 100644 (file)
@@ -1283,7 +1283,6 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
        /* need to count the number of space-delimited sids */
        unsigned int i;
        int num_other_sids = 0;
-       char *username;
        
        NTTIME          logon_time, logoff_time, kickoff_time,
                        pass_last_set_time, pass_can_change_time,
@@ -1295,21 +1294,7 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
        int len_logon_srv    = strlen(logon_srv);
        int len_logon_dom    = strlen(logon_dom);
 
-
-       /* do some cleanup on the user name here to deal with users from a 
-          trusted domain logging onto a client in our domain.  If we are running 
-          winbindd, the trusted users will be of the form DOMAIN\user so strip 
-          out the domain portion.  I noticed then when looking at an SMBsessionsetup&X.
-          The client was sending GLASS\Administrator as the username and GLASS as the 
-          domain name -- jerry */
-          
-       if ( (username = strchr( user_name, *lp_winbind_separator() )) != NULL )
-               username++;
-       else
-               username = user_name;
-               
-               
-       len_user_name    = strlen(username    );
+       len_user_name    = strlen(user_name    );
        len_full_name    = strlen(full_name   );
        len_home_dir     = strlen(home_dir    );
        len_dir_drive    = strlen(dir_drive   );
@@ -1372,7 +1357,7 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
        usr->num_other_sids = num_other_sids;
        usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0; 
        
-       init_unistr2(&usr->uni_user_name, username, len_user_name);
+       init_unistr2(&usr->uni_user_name, user_name, len_user_name);
        init_unistr2(&usr->uni_full_name, full_name, len_full_name);
        init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
        init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
index 0dcdf391583edbbf7e34ea05a6c96d58245b61e1..c4a87d2e26d324af67a1a0fa57118be74bb52adc 100644 (file)
@@ -650,10 +650,8 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
        } /* end switch */
        
        if ( NT_STATUS_IS_OK(status) ) {
-               become_root();
                status = auth_context->check_ntlm_password(auth_context, 
                        user_info, &server_info);
-               unbecome_root();
        }
 
        (auth_context->free)(&auth_context);    
index 6a9e591f6486cc91c61d04d91bb1b4c9821047be..f7663204b2e69a6ca9dbcc6a50dcb1193f3c23bc 100644 (file)
@@ -464,7 +464,7 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name ));
        }
 
        fstrcpy(p->user_name, user_name);
-       fstrcpy(p->pipe_user_name, pdb_get_username(server_info->sam_account));
+       fstrcpy(p->pipe_user_name, server_info->unix_name);
        fstrcpy(p->domain, domain);
        fstrcpy(p->wks, wks);