LCOV - code coverage report
Current view: top level - source3/auth - auth_sam.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 86 119 72.3 %
Date: 2021-09-23 10:06:22 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Password and authentication handling
       4             :    Copyright (C) Andrew Tridgell              1992-2000
       5             :    Copyright (C) Luke Kenneth Casson Leighton 1996-2000
       6             :    Copyright (C) Andrew Bartlett              2001-2003
       7             :    Copyright (C) Gerald Carter                2003
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "auth.h"
      25             : #include "passdb.h"
      26             : 
      27             : #undef DBGC_CLASS
      28             : #define DBGC_CLASS DBGC_AUTH
      29             : 
      30       10803 : static NTSTATUS auth_sam_ignoredomain_auth(const struct auth_context *auth_context,
      31             :                                            void *my_private_data,
      32             :                                            TALLOC_CTX *mem_ctx,
      33             :                                            const struct auth_usersupplied_info *user_info,
      34             :                                            struct auth_serversupplied_info **server_info)
      35             : {
      36       10803 :         if (!user_info || !auth_context) {
      37           0 :                 return NT_STATUS_UNSUCCESSFUL;
      38             :         }
      39             : 
      40       21588 :         if (user_info->mapped.account_name == NULL ||
      41       10803 :             user_info->mapped.account_name[0] == '\0')
      42             :         {
      43           9 :                 return NT_STATUS_NOT_IMPLEMENTED;
      44             :         }
      45             : 
      46       10794 :         DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
      47             :                   user_info->mapped.domain_name,
      48             :                   user_info->mapped.account_name);
      49             : 
      50       10794 :         return check_sam_security(&auth_context->challenge, mem_ctx,
      51             :                                   user_info, server_info);
      52             : }
      53             : 
      54             : /* module initialisation */
      55       58385 : static NTSTATUS auth_init_sam_ignoredomain(
      56             :         struct auth_context *auth_context,
      57             :         const char *param,
      58             :         struct auth_methods **auth_method)
      59             : {
      60             :         struct auth_methods *result;
      61             : 
      62       58385 :         result = talloc_zero(auth_context, struct auth_methods);
      63       58385 :         if (result == NULL) {
      64           0 :                 return NT_STATUS_NO_MEMORY;
      65             :         }
      66       58385 :         result->auth = auth_sam_ignoredomain_auth;
      67       58385 :         result->name = "sam_ignoredomain";
      68             : 
      69       58385 :         *auth_method = result;
      70       58385 :         return NT_STATUS_OK;
      71             : }
      72             : 
      73             : 
      74             : /****************************************************************************
      75             : Check SAM security (above) but with a few extra checks.
      76             : ****************************************************************************/
      77             : 
      78        9969 : static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context,
      79             :                                     void *my_private_data,
      80             :                                     TALLOC_CTX *mem_ctx,
      81             :                                     const struct auth_usersupplied_info *user_info,
      82             :                                     struct auth_serversupplied_info **server_info)
      83             : {
      84        9969 :         const char *effective_domain = NULL;
      85             :         bool is_local_name, is_my_domain;
      86             : 
      87        9969 :         if (!user_info || !auth_context) {
      88           0 :                 return NT_STATUS_LOGON_FAILURE;
      89             :         }
      90        9969 :         effective_domain = user_info->mapped.domain_name;
      91             : 
      92       19701 :         if (user_info->mapped.account_name == NULL ||
      93        9969 :             user_info->mapped.account_name[0] == '\0')
      94             :         {
      95           8 :                 return NT_STATUS_NOT_IMPLEMENTED;
      96             :         }
      97             : 
      98        9961 :         if (lp_server_role() == ROLE_DOMAIN_MEMBER) {
      99         971 :                 const char *p = NULL;
     100             : 
     101         971 :                 p = strchr_m(user_info->mapped.account_name, '@');
     102         971 :                 if (p != NULL) {
     103             :                         /*
     104             :                          * This needs to go to the DC,
     105             :                          * even if @ is the last character
     106             :                          */
     107          60 :                         return NT_STATUS_NOT_IMPLEMENTED;
     108             :                 }
     109             :         }
     110             : 
     111        9901 :         if (effective_domain == NULL) {
     112           0 :                 effective_domain = "";
     113             :         }
     114             : 
     115        9901 :         DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
     116             :                   effective_domain,
     117             :                   user_info->mapped.account_name);
     118             : 
     119             : 
     120        9901 :         if (strequal(effective_domain, "") || strequal(effective_domain, ".")) {
     121             :                 /*
     122             :                  * An empty domain name or '.' should be handled
     123             :                  * as the local SAM name.
     124             :                  */
     125         130 :                 effective_domain = lp_netbios_name();
     126             :         }
     127             : 
     128        9901 :         is_local_name = is_myname(effective_domain);
     129        9901 :         is_my_domain  = strequal(effective_domain, lp_workgroup());
     130             : 
     131             :         /* check whether or not we service this domain/workgroup name */
     132             : 
     133        9901 :         switch ( lp_server_role() ) {
     134         911 :                 case ROLE_STANDALONE:
     135             :                 case ROLE_DOMAIN_MEMBER:
     136         911 :                         if ( !is_local_name ) {
     137         174 :                                 DEBUG(6,("check_samstrict_security: %s is not one of my local names (%s)\n",
     138             :                                         effective_domain, (lp_server_role() == ROLE_DOMAIN_MEMBER
     139             :                                         ? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") ));
     140         174 :                                 return NT_STATUS_NOT_IMPLEMENTED;
     141             :                         }
     142             : 
     143         737 :                         break;
     144        8990 :                 case ROLE_DOMAIN_PDC:
     145             :                 case ROLE_DOMAIN_BDC:
     146        8990 :                         if (!is_local_name && !is_my_domain) {
     147             :                                /* If we are running on a DC that has PASSDB module with domain
     148             :                                 * information, check if DNS forest name is matching the domain
     149             :                                 * name. This is the case of FreeIPA domain controller when
     150             :                                 * trusted AD DCs attempt to authenticate FreeIPA users using
     151             :                                 * the forest root domain (which is the only domain in FreeIPA).
     152             :                                 */
     153        1529 :                                 struct pdb_domain_info *dom_info = NULL;
     154             : 
     155        1529 :                                 dom_info = pdb_get_domain_info(mem_ctx);
     156        1529 :                                 if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
     157           0 :                                         is_my_domain = strequal(user_info->mapped.domain_name,
     158           0 :                                                                 dom_info->dns_forest);
     159             :                                 }
     160             : 
     161        1529 :                                 TALLOC_FREE(dom_info);
     162        1529 :                                 if (!is_my_domain) {
     163        1529 :                                         DEBUG(6,("check_samstrict_security: %s is not one "
     164             :                                                  "of my local names or domain name (DC)\n",
     165             :                                                  effective_domain));
     166        1529 :                                         return NT_STATUS_NOT_IMPLEMENTED;
     167             :                                 }
     168             :                         }
     169             : 
     170        7461 :                         break;
     171           0 :                 default: /* name is ok */
     172           0 :                         break;
     173             :         }
     174             : 
     175        8198 :         return check_sam_security(&auth_context->challenge, mem_ctx,
     176             :                                   user_info, server_info);
     177             : }
     178             : 
     179             : /* module initialisation */
     180       25872 : static NTSTATUS auth_init_sam(
     181             :         struct auth_context *auth_context,
     182             :         const char *param,
     183             :         struct auth_methods **auth_method)
     184             : {
     185             :         struct auth_methods *result;
     186             : 
     187       25872 :         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
     188           0 :             && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
     189           0 :                 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the auth_sam module. \n"));
     190           0 :                 DEBUGADD(0, ("You should not set 'auth methods' when running the AD DC.\n"));
     191           0 :                 exit(1);
     192             :         }
     193             : 
     194       25872 :         result = talloc_zero(auth_context, struct auth_methods);
     195       25872 :         if (result == NULL) {
     196           0 :                 return NT_STATUS_NO_MEMORY;
     197             :         }
     198       25872 :         result->auth = auth_samstrict_auth;
     199       25872 :         result->name = "sam";
     200       25872 :         *auth_method = result;
     201       25872 :         return NT_STATUS_OK;
     202             : }
     203             : 
     204         558 : static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context,
     205             :                                         void *my_private_data,
     206             :                                         TALLOC_CTX *mem_ctx,
     207             :                                         const struct auth_usersupplied_info *user_info,
     208             :                                         struct auth_serversupplied_info **server_info)
     209             : {
     210         558 :         const char *effective_domain = NULL;
     211             :         bool is_my_domain;
     212             : 
     213         558 :         if (!user_info || !auth_context) {
     214           0 :                 return NT_STATUS_LOGON_FAILURE;
     215             :         }
     216         558 :         effective_domain = user_info->mapped.domain_name;
     217             : 
     218        1116 :         if (user_info->mapped.account_name == NULL ||
     219         558 :             user_info->mapped.account_name[0] == '\0')
     220             :         {
     221           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
     222             :         }
     223             : 
     224         558 :         if (effective_domain == NULL) {
     225           0 :                 effective_domain = "";
     226             :         }
     227             : 
     228         558 :         DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
     229             :                   effective_domain,
     230             :                   user_info->mapped.account_name);
     231             : 
     232             :         /* check whether or not we service this domain/workgroup name */
     233             : 
     234         558 :         switch (lp_server_role()) {
     235         558 :         case ROLE_DOMAIN_PDC:
     236             :         case ROLE_DOMAIN_BDC:
     237         558 :                 break;
     238           0 :         default:
     239           0 :                 DBG_ERR("Invalid server role\n");
     240           0 :                 return NT_STATUS_INVALID_SERVER_STATE;
     241             :         }
     242             : 
     243         558 :         if (strequal(effective_domain, "") || strequal(effective_domain, ".")) {
     244             :                 /*
     245             :                  * An empty domain name or '.' should be handled
     246             :                  * as the local SAM name.
     247             :                  */
     248           0 :                 effective_domain = lp_workgroup();
     249             :         }
     250             : 
     251         558 :         is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup());
     252         558 :         if (!is_my_domain) {
     253             :                /* If we are running on a DC that has PASSDB module with domain
     254             :                 * information, check if DNS forest name is matching the domain
     255             :                 * name. This is the case of FreeIPA domain controller when
     256             :                 * trusted AD DCs attempt to authenticate FreeIPA users using
     257             :                 * the forest root domain (which is the only domain in FreeIPA).
     258             :                 */
     259           0 :                 struct pdb_domain_info *dom_info = NULL;
     260           0 :                 dom_info = pdb_get_domain_info(mem_ctx);
     261             : 
     262           0 :                 if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
     263           0 :                         is_my_domain = strequal(user_info->mapped.domain_name,
     264           0 :                                                 dom_info->dns_forest);
     265             :                 }
     266             : 
     267           0 :                 TALLOC_FREE(dom_info);
     268             :         }
     269             : 
     270         558 :         if (!is_my_domain) {
     271           0 :                 DBG_INFO("%s is not our domain name (DC for %s)\n",
     272             :                          effective_domain, lp_workgroup());
     273           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
     274             :         }
     275             : 
     276         558 :         return check_sam_security(&auth_context->challenge, mem_ctx,
     277             :                                   user_info, server_info);
     278             : }
     279             : 
     280             : /* module initialisation */
     281         558 : static NTSTATUS auth_init_sam_netlogon3(
     282             :         struct auth_context *auth_context,
     283             :         const char *param,
     284             :         struct auth_methods **auth_method)
     285             : {
     286             :         struct auth_methods *result;
     287             : 
     288         558 :         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
     289           0 :             && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
     290           0 :                 DEBUG(0, ("server role = 'active directory domain controller' "
     291             :                           "not compatible with running the auth_sam module.\n"));
     292           0 :                 DEBUGADD(0, ("You should not set 'auth methods' when "
     293             :                              "running the AD DC.\n"));
     294           0 :                 exit(1);
     295             :         }
     296             : 
     297         558 :         result = talloc_zero(auth_context, struct auth_methods);
     298         558 :         if (result == NULL) {
     299           0 :                 return NT_STATUS_NO_MEMORY;
     300             :         }
     301         558 :         result->auth = auth_sam_netlogon3_auth;
     302         558 :         result->name = "sam_netlogon3";
     303         558 :         *auth_method = result;
     304         558 :         return NT_STATUS_OK;
     305             : }
     306             : 
     307       26751 : NTSTATUS auth_sam_init(TALLOC_CTX *mem_ctx)
     308             : {
     309       26751 :         smb_register_auth(AUTH_INTERFACE_VERSION, "sam", auth_init_sam);
     310       26751 :         smb_register_auth(AUTH_INTERFACE_VERSION, "sam_ignoredomain", auth_init_sam_ignoredomain);
     311       26751 :         smb_register_auth(AUTH_INTERFACE_VERSION, "sam_netlogon3", auth_init_sam_netlogon3);
     312       26751 :         return NT_STATUS_OK;
     313             : }

Generated by: LCOV version 1.13