LCOV - code coverage report
Current view: top level - source3/auth - auth_sam.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 86 124 69.4 %
Date: 2024-04-21 15:09:00 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       13421 : 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       13421 :         if (!user_info || !auth_context) {
      37           0 :                 return NT_STATUS_UNSUCCESSFUL;
      38             :         }
      39             : 
      40       13421 :         if (user_info->mapped.account_name == NULL ||
      41       13421 :             user_info->mapped.account_name[0] == '\0')
      42             :         {
      43          10 :                 return NT_STATUS_NOT_IMPLEMENTED;
      44             :         }
      45             : 
      46       13411 :         DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
      47             :                   user_info->mapped.domain_name,
      48             :                   user_info->mapped.account_name);
      49             : 
      50       13411 :         return check_sam_security(&auth_context->challenge, mem_ctx,
      51             :                                   user_info, server_info);
      52             : }
      53             : 
      54             : /* module initialisation */
      55       77047 : static NTSTATUS auth_init_sam_ignoredomain(
      56             :         struct auth_context *auth_context,
      57             :         const char *param,
      58             :         struct auth_methods **auth_method)
      59             : {
      60           0 :         struct auth_methods *result;
      61             : 
      62       77047 :         result = talloc_zero(auth_context, struct auth_methods);
      63       77047 :         if (result == NULL) {
      64           0 :                 return NT_STATUS_NO_MEMORY;
      65             :         }
      66       77047 :         result->auth = auth_sam_ignoredomain_auth;
      67       77047 :         result->name = "sam_ignoredomain";
      68             : 
      69       77047 :         *auth_method = result;
      70       77047 :         return NT_STATUS_OK;
      71             : }
      72             : 
      73             : 
      74             : /****************************************************************************
      75             : Check SAM security (above) but with a few extra checks.
      76             : ****************************************************************************/
      77             : 
      78       11515 : 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       11515 :         const char *effective_domain = NULL;
      85           0 :         bool is_local_name, is_my_domain;
      86             : 
      87       11515 :         if (!user_info || !auth_context) {
      88           0 :                 return NT_STATUS_LOGON_FAILURE;
      89             :         }
      90       11515 :         effective_domain = user_info->mapped.domain_name;
      91             : 
      92       11515 :         if (user_info->mapped.account_name == NULL ||
      93       11515 :             user_info->mapped.account_name[0] == '\0')
      94             :         {
      95          10 :                 return NT_STATUS_NOT_IMPLEMENTED;
      96             :         }
      97             : 
      98       11505 :         if (lp_server_role() == ROLE_DOMAIN_MEMBER) {
      99        1267 :                 const char *p = NULL;
     100             : 
     101        1267 :                 p = strchr_m(user_info->mapped.account_name, '@');
     102        1267 :                 if (p != NULL) {
     103             :                         /*
     104             :                          * This needs to go to the DC,
     105             :                          * even if @ is the last character
     106             :                          */
     107          70 :                         return NT_STATUS_NOT_IMPLEMENTED;
     108             :                 }
     109             :         }
     110             : 
     111       11435 :         if (effective_domain == NULL) {
     112           0 :                 effective_domain = "";
     113             :         }
     114             : 
     115       11435 :         DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
     116             :                   effective_domain,
     117             :                   user_info->mapped.account_name);
     118             : 
     119             : 
     120       11435 :         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       11435 :         is_local_name = is_myname(effective_domain);
     129       11435 :         is_my_domain  = strequal(effective_domain, lp_workgroup());
     130             : 
     131             :         /* check whether or not we service this domain/workgroup name */
     132             : 
     133       11435 :         switch ( lp_server_role() ) {
     134        1197 :                 case ROLE_STANDALONE:
     135             :                 case ROLE_DOMAIN_MEMBER:
     136        1197 :                         if ( !is_local_name ) {
     137         272 :                                 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         272 :                                 return NT_STATUS_NOT_IMPLEMENTED;
     141             :                         }
     142             : 
     143         925 :                         break;
     144       10238 :                 case ROLE_DOMAIN_PDC:
     145             :                 case ROLE_DOMAIN_BDC:
     146             :                 case ROLE_IPA_DC:
     147       10238 :                         if (!is_local_name && !is_my_domain) {
     148             :                                /* If we are running on a DC that has PASSDB module with domain
     149             :                                 * information, check if DNS forest name is matching the domain
     150             :                                 * name. This is the case of IPA domain controller when
     151             :                                 * trusted AD DCs attempt to authenticate IPA users using
     152             :                                 * the forest root domain (which is the only domain in IPA).
     153             :                                 */
     154        2049 :                                 struct pdb_domain_info *dom_info = NULL;
     155             : 
     156        2049 :                                 dom_info = pdb_get_domain_info(mem_ctx);
     157        2049 :                                 if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
     158           0 :                                         is_my_domain = strequal(user_info->mapped.domain_name,
     159           0 :                                                                 dom_info->dns_forest);
     160             :                                 }
     161             : 
     162        2049 :                                 TALLOC_FREE(dom_info);
     163        2049 :                                 if (!is_my_domain) {
     164        2049 :                                         DEBUG(6,("check_samstrict_security: %s is not one "
     165             :                                                  "of my local names or domain name (DC)\n",
     166             :                                                  effective_domain));
     167        2049 :                                         return NT_STATUS_NOT_IMPLEMENTED;
     168             :                                 }
     169             :                         }
     170             : 
     171        8189 :                         break;
     172           0 :                 default: /* name is ok */
     173           0 :                         break;
     174             :         }
     175             : 
     176        9114 :         return check_sam_security(&auth_context->challenge, mem_ctx,
     177             :                                   user_info, server_info);
     178             : }
     179             : 
     180             : /* module initialisation */
     181       45808 : static NTSTATUS auth_init_sam(
     182             :         struct auth_context *auth_context,
     183             :         const char *param,
     184             :         struct auth_methods **auth_method)
     185             : {
     186           0 :         struct auth_methods *result;
     187             : 
     188       45808 :         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
     189           0 :             && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
     190           0 :                 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the auth_sam module. \n"));
     191           0 :                 DEBUGADD(0, ("You should not set 'auth methods' when running the AD DC.\n"));
     192           0 :                 exit(1);
     193             :         }
     194             : 
     195       45808 :         result = talloc_zero(auth_context, struct auth_methods);
     196       45808 :         if (result == NULL) {
     197           0 :                 return NT_STATUS_NO_MEMORY;
     198             :         }
     199       45808 :         result->auth = auth_samstrict_auth;
     200       45808 :         result->name = "sam";
     201       45808 :         *auth_method = result;
     202       45808 :         return NT_STATUS_OK;
     203             : }
     204             : 
     205         304 : static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context,
     206             :                                         void *my_private_data,
     207             :                                         TALLOC_CTX *mem_ctx,
     208             :                                         const struct auth_usersupplied_info *user_info,
     209             :                                         struct auth_serversupplied_info **server_info)
     210             : {
     211         304 :         const char *effective_domain = NULL;
     212           0 :         bool is_my_domain;
     213             : 
     214         304 :         if (!user_info || !auth_context) {
     215           0 :                 return NT_STATUS_LOGON_FAILURE;
     216             :         }
     217         304 :         effective_domain = user_info->mapped.domain_name;
     218             : 
     219         304 :         if (user_info->mapped.account_name == NULL ||
     220         304 :             user_info->mapped.account_name[0] == '\0')
     221             :         {
     222           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
     223             :         }
     224             : 
     225         304 :         if (effective_domain == NULL) {
     226           0 :                 effective_domain = "";
     227             :         }
     228             : 
     229         304 :         DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
     230             :                   effective_domain,
     231             :                   user_info->mapped.account_name);
     232             : 
     233             :         /* check whether or not we service this domain/workgroup name */
     234             : 
     235         304 :         switch (lp_server_role()) {
     236         304 :         case ROLE_DOMAIN_PDC:
     237             :         case ROLE_DOMAIN_BDC:
     238             :         case ROLE_IPA_DC:
     239         304 :                 break;
     240           0 :         default:
     241           0 :                 DBG_ERR("Invalid server role\n");
     242           0 :                 return NT_STATUS_INVALID_SERVER_STATE;
     243             :         }
     244             : 
     245         304 :         if (strequal(effective_domain, "") || strequal(effective_domain, ".")) {
     246             :                 /*
     247             :                  * An empty domain name or '.' should be handled
     248             :                  * as the local SAM name.
     249             :                  */
     250           0 :                 effective_domain = lp_workgroup();
     251             :         }
     252             : 
     253         304 :         is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup());
     254         304 :         if (!is_my_domain) {
     255             :                /* If we are running on a DC that has PASSDB module with domain
     256             :                 * information, check if DNS forest name is matching the domain
     257             :                 * name. This is the case of IPA domain controller when
     258             :                 * trusted AD DCs attempt to authenticate IPA users using
     259             :                 * the forest root domain (which is the only domain in IPA).
     260             :                 */
     261           0 :                 struct pdb_domain_info *dom_info = NULL;
     262           0 :                 dom_info = pdb_get_domain_info(mem_ctx);
     263             : 
     264           0 :                 if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
     265           0 :                         is_my_domain = strequal(user_info->mapped.domain_name,
     266           0 :                                                 dom_info->dns_forest);
     267             :                 }
     268             : 
     269           0 :                 TALLOC_FREE(dom_info);
     270             :         }
     271             : 
     272         304 :         if (!is_my_domain) {
     273           0 :                 DBG_INFO("%s is not our domain name (DC for %s)\n",
     274             :                          effective_domain, lp_workgroup());
     275           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
     276             :         }
     277             : 
     278         304 :         return check_sam_security(&auth_context->challenge, mem_ctx,
     279             :                                   user_info, server_info);
     280             : }
     281             : 
     282             : /* module initialisation */
     283         304 : static NTSTATUS auth_init_sam_netlogon3(
     284             :         struct auth_context *auth_context,
     285             :         const char *param,
     286             :         struct auth_methods **auth_method)
     287             : {
     288           0 :         struct auth_methods *result;
     289             : 
     290         304 :         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
     291           0 :             && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
     292           0 :                 DEBUG(0, ("server role = 'active directory domain controller' "
     293             :                           "not compatible with running the auth_sam module.\n"));
     294           0 :                 DEBUGADD(0, ("You should not set 'auth methods' when "
     295             :                              "running the AD DC.\n"));
     296           0 :                 exit(1);
     297             :         }
     298             : 
     299         304 :         result = talloc_zero(auth_context, struct auth_methods);
     300         304 :         if (result == NULL) {
     301           0 :                 return NT_STATUS_NO_MEMORY;
     302             :         }
     303         304 :         result->auth = auth_sam_netlogon3_auth;
     304         304 :         result->name = "sam_netlogon3";
     305         304 :         *auth_method = result;
     306         304 :         return NT_STATUS_OK;
     307             : }
     308             : 
     309       31355 : NTSTATUS auth_sam_init(TALLOC_CTX *mem_ctx)
     310             : {
     311       31355 :         smb_register_auth(AUTH_INTERFACE_VERSION, "sam", auth_init_sam);
     312       31355 :         smb_register_auth(AUTH_INTERFACE_VERSION, "sam_ignoredomain", auth_init_sam_ignoredomain);
     313       31355 :         smb_register_auth(AUTH_INTERFACE_VERSION, "sam_netlogon3", auth_init_sam_netlogon3);
     314       31355 :         return NT_STATUS_OK;
     315             : }

Generated by: LCOV version 1.14