LCOV - code coverage report
Current view: top level - auth/gensec - gensec_start.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 444 511 86.9 %
Date: 2024-05-31 13:13:24 Functions: 35 36 97.2 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Generic Authentication Interface
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2006
       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 "system/network.h"
      25             : #include "tevent.h"
      26             : #include "../lib/util/tevent_ntstatus.h"
      27             : #include "librpc/gen_ndr/dcerpc.h"
      28             : #include "auth/credentials/credentials.h"
      29             : #include "auth/gensec/gensec.h"
      30             : #include "auth/gensec/gensec_internal.h"
      31             : #include "lib/param/param.h"
      32             : #include "lib/param/loadparm.h"
      33             : #include "lib/util/tsort.h"
      34             : #include "lib/util/samba_modules.h"
      35             : #include "lib/util/base64.h"
      36             : 
      37             : #undef DBGC_CLASS
      38             : #define DBGC_CLASS DBGC_AUTH
      39             : 
      40             : #undef strcasecmp
      41             : 
      42             : /* the list of currently registered GENSEC backends */
      43             : static const struct gensec_security_ops **generic_security_ops;
      44             : static int gensec_num_backends;
      45             : 
      46     3568026 : bool gensec_security_ops_enabled(const struct gensec_security_ops *ops, struct gensec_security *security)
      47             : {
      48     3659322 :         bool ok = lpcfg_parm_bool(security->settings->lp_ctx,
      49             :                                   NULL,
      50             :                                   "gensec",
      51     3568026 :                                   ops->name,
      52     3568026 :                                   ops->enabled);
      53             : 
      54     4230131 :         if (ops->weak_crypto &&
      55      662105 :             lpcfg_weak_crypto(security->settings->lp_ctx) != SAMBA_WEAK_CRYPTO_ALLOWED) {
      56           6 :                 ok = false;
      57             :         }
      58             : 
      59     3568026 :         return ok;
      60             : }
      61             : 
      62             : /* Sometimes we want to force only kerberos, sometimes we want to
      63             :  * force it's avoidance.  The old list could be either
      64             :  * gensec_security_all(), or from cli_credentials_gensec_list() (ie,
      65             :  * an existing list we have trimmed down)
      66             :  *
      67             :  * The intended logic is:
      68             :  *
      69             :  * if we are in the default AUTO have kerberos:
      70             :  * - take a reference to the master list
      71             :  * otherwise
      72             :  * - always add spnego then:
      73             :  * - if we 'MUST' have kerberos:
      74             :  *   only add kerberos mechs
      75             :  * - if we 'DONT' want kerberos':
      76             :  *   only add non-kerberos mechs
      77             :  *
      78             :  * Once we get things like NegoEx or moonshot, this will of course get
      79             :  * more complex.
      80             :  */
      81             : 
      82     1790409 : static const struct gensec_security_ops **gensec_use_kerberos_mechs(
      83             :                 TALLOC_CTX *mem_ctx,
      84             :                 const struct gensec_security_ops * const *old_gensec_list,
      85             :                 enum credentials_use_kerberos use_kerberos,
      86             :                 bool keep_schannel)
      87             : {
      88       28153 :         const struct gensec_security_ops **new_gensec_list;
      89       28153 :         int i, j, num_mechs_in;
      90             : 
      91    18626960 :         for (num_mechs_in=0; old_gensec_list && old_gensec_list[num_mechs_in]; num_mechs_in++) {
      92             :                 /* noop */
      93      265202 :         }
      94             : 
      95     1790409 :         new_gensec_list = talloc_array(mem_ctx,
      96             :                                        const struct gensec_security_ops *,
      97             :                                        num_mechs_in + 1);
      98     1790409 :         if (!new_gensec_list) {
      99           0 :                 return NULL;
     100             :         }
     101             : 
     102     1762256 :         j = 0;
     103    18626960 :         for (i=0; old_gensec_list && old_gensec_list[i]; i++) {
     104    16836551 :                 bool keep = false;
     105             : 
     106             :                 /*
     107             :                  * We want to keep SPNEGO and other backends
     108             :                  */
     109    16836551 :                 keep = old_gensec_list[i]->glue;
     110             : 
     111    16836551 :                 if (old_gensec_list[i]->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
     112     1523914 :                         keep = keep_schannel;
     113             :                 }
     114             : 
     115    16836551 :                 switch (use_kerberos) {
     116    15033573 :                 case CRED_USE_KERBEROS_DESIRED:
     117    15033573 :                         keep = true;
     118    15033573 :                         break;
     119             : 
     120     1238900 :                 case CRED_USE_KERBEROS_DISABLED:
     121     1238900 :                         if (old_gensec_list[i]->kerberos == false) {
     122      908614 :                                 keep = true;
     123             :                         }
     124             : 
     125     1225894 :                         break;
     126             : 
     127      324314 :                 case CRED_USE_KERBEROS_REQUIRED:
     128      324314 :                         if (old_gensec_list[i]->kerberos == true) {
     129      109919 :                                 keep = true;
     130             :                         }
     131             : 
     132      311882 :                         break;
     133           0 :                 default:
     134             :                         /* Can't happen or invalid parameter */
     135           0 :                         return NULL;
     136             :                 }
     137             : 
     138    16583986 :                 if (!keep) {
     139      483972 :                         continue;
     140             :                 }
     141             : 
     142    16352579 :                 new_gensec_list[j] = old_gensec_list[i];
     143    16352579 :                 j++;
     144             :         }
     145     1790409 :         new_gensec_list[j] = NULL;
     146             : 
     147     1790409 :         return new_gensec_list;
     148             : }
     149             : 
     150     1790409 : _PUBLIC_ const struct gensec_security_ops **gensec_security_mechs(
     151             :                                 struct gensec_security *gensec_security,
     152             :                                 TALLOC_CTX *mem_ctx)
     153             : {
     154     1790409 :         const struct gensec_security_ops * const *backends =
     155             :                 generic_security_ops;
     156     1790409 :         enum credentials_use_kerberos use_kerberos = CRED_USE_KERBEROS_DESIRED;
     157     1790409 :         bool keep_schannel = false;
     158             : 
     159     1790409 :         if (gensec_security != NULL) {
     160      572282 :                 struct cli_credentials *creds = NULL;
     161             : 
     162      572282 :                 creds = gensec_get_credentials(gensec_security);
     163      572282 :                 if (creds != NULL) {
     164      572278 :                         use_kerberos = cli_credentials_get_kerberos_state(creds);
     165      572278 :                         if (cli_credentials_get_netlogon_creds(creds) != NULL) {
     166        5663 :                                 keep_schannel = true;
     167             :                         }
     168             : 
     169             :                         /*
     170             :                          * Even if Kerberos is set to REQUIRED, keep the
     171             :                          * schannel auth mechanism so that machine accounts are
     172             :                          * able to authenticate via netlogon.
     173             :                          */
     174      572278 :                         if (gensec_security->gensec_role == GENSEC_SERVER) {
     175      353202 :                                 keep_schannel = true;
     176             :                         }
     177             :                 }
     178             : 
     179      572282 :                 if (gensec_security->settings->backends) {
     180      211969 :                         backends = gensec_security->settings->backends;
     181             :                 }
     182             :         }
     183             : 
     184     1790409 :         return gensec_use_kerberos_mechs(mem_ctx, backends,
     185             :                                          use_kerberos, keep_schannel);
     186             : 
     187             : }
     188             : 
     189      369524 : _PUBLIC_ const struct gensec_security_ops *gensec_security_by_oid(
     190             :                                 struct gensec_security *gensec_security,
     191             :                                 const char *oid_string)
     192             : {
     193        3264 :         int i, j;
     194        3264 :         const struct gensec_security_ops **backends;
     195        3264 :         const struct gensec_security_ops *backend;
     196      369524 :         TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
     197      369524 :         if (!mem_ctx) {
     198           0 :                 return NULL;
     199             :         }
     200      369524 :         backends = gensec_security_mechs(gensec_security, mem_ctx);
     201     1144317 :         for (i=0; backends && backends[i]; i++) {
     202     1144187 :                 if (gensec_security != NULL &&
     203      246169 :                                 !gensec_security_ops_enabled(backends[i],
     204             :                                                                                          gensec_security))
     205         240 :                     continue;
     206     1140669 :                 if (backends[i]->oid) {
     207     1508500 :                         for (j=0; backends[i]->oid[j]; j++) {
     208     1022553 :                                 if (backends[i]->oid[j] &&
     209     1022553 :                                     (strcmp(backends[i]->oid[j], oid_string) == 0)) {
     210      369380 :                                         backend = backends[i];
     211      369380 :                                         talloc_free(mem_ctx);
     212      369380 :                                         return backend;
     213             :                                 }
     214             :                         }
     215             :                 }
     216             :         }
     217         144 :         talloc_free(mem_ctx);
     218             : 
     219         144 :         return NULL;
     220             : }
     221             : 
     222       53477 : _PUBLIC_ const struct gensec_security_ops *gensec_security_by_sasl_name(
     223             :                                 struct gensec_security *gensec_security,
     224             :                                 const char *sasl_name)
     225             : {
     226         244 :         int i;
     227         244 :         const struct gensec_security_ops **backends;
     228         244 :         const struct gensec_security_ops *backend;
     229       53477 :         TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
     230       53477 :         if (!mem_ctx) {
     231           0 :                 return NULL;
     232             :         }
     233       53477 :         backends = gensec_security_mechs(gensec_security, mem_ctx);
     234       54519 :         for (i=0; backends && backends[i]; i++) {
     235       54517 :                 if (gensec_security != NULL &&
     236       54273 :                     !gensec_security_ops_enabled(backends[i], gensec_security)) {
     237         260 :                         continue;
     238             :                 }
     239       54013 :                 if (backends[i]->sasl_name
     240       53741 :                     && (strcmp(backends[i]->sasl_name, sasl_name) == 0)) {
     241       53475 :                         backend = backends[i];
     242       53475 :                         talloc_free(mem_ctx);
     243       53475 :                         return backend;
     244             :                 }
     245             :         }
     246           2 :         talloc_free(mem_ctx);
     247             : 
     248           2 :         return NULL;
     249             : }
     250             : 
     251      259874 : _PUBLIC_ const struct gensec_security_ops *gensec_security_by_auth_type(
     252             :                                 struct gensec_security *gensec_security,
     253             :                                 uint32_t auth_type)
     254             : {
     255         854 :         int i;
     256         854 :         const struct gensec_security_ops **backends;
     257         854 :         const struct gensec_security_ops *backend;
     258         854 :         TALLOC_CTX *mem_ctx;
     259             : 
     260      259874 :         if (auth_type == DCERPC_AUTH_TYPE_NONE) {
     261           0 :                 return NULL;
     262             :         }
     263             : 
     264      259874 :         mem_ctx = talloc_new(gensec_security);
     265      259874 :         if (!mem_ctx) {
     266           0 :                 return NULL;
     267             :         }
     268      259874 :         backends = gensec_security_mechs(gensec_security, mem_ctx);
     269     1725298 :         for (i=0; backends && backends[i]; i++) {
     270     1729164 :                 if (gensec_security != NULL &&
     271       59508 :                     !gensec_security_ops_enabled(backends[i], gensec_security)) {
     272       11304 :                         continue;
     273             :                 }
     274     1713062 :                 if (backends[i]->auth_type == auth_type) {
     275      259796 :                         backend = backends[i];
     276      259796 :                         talloc_free(mem_ctx);
     277      259796 :                         return backend;
     278             :                 }
     279             :         }
     280          78 :         talloc_free(mem_ctx);
     281             : 
     282          78 :         return NULL;
     283             : }
     284             : 
     285      737158 : const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security,
     286             :                                                           const char *name)
     287             : {
     288       17192 :         int i;
     289       17192 :         const struct gensec_security_ops **backends;
     290       17192 :         const struct gensec_security_ops *backend;
     291      737158 :         TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
     292      737158 :         if (!mem_ctx) {
     293           0 :                 return NULL;
     294             :         }
     295      737158 :         backends = gensec_security_mechs(gensec_security, mem_ctx);
     296     5138192 :         for (i=0; backends && backends[i]; i++) {
     297     4445808 :                 if (gensec_security != NULL &&
     298        7101 :                                 !gensec_security_ops_enabled(backends[i], gensec_security))
     299        1356 :                     continue;
     300     4444452 :                 if (backends[i]->name
     301     4444452 :                     && (strcmp(backends[i]->name, name) == 0)) {
     302       61966 :                         backend = backends[i];
     303       61966 :                         talloc_free(mem_ctx);
     304       61966 :                         return backend;
     305             :                 }
     306             :         }
     307      675192 :         talloc_free(mem_ctx);
     308      675192 :         return NULL;
     309             : }
     310             : 
     311       53971 : static const char **gensec_security_sasl_names_from_ops(
     312             :         struct gensec_security *gensec_security,
     313             :         TALLOC_CTX *mem_ctx,
     314             :         const struct gensec_security_ops * const *ops)
     315             : {
     316       53971 :         const char **sasl_names = NULL;
     317       53971 :         size_t i, sasl_names_count = 0;
     318             : 
     319       53971 :         if (ops == NULL) {
     320           0 :                 return NULL;
     321             :         }
     322             : 
     323       53971 :         sasl_names = talloc_array(mem_ctx, const char *, 1);
     324       53971 :         if (sasl_names == NULL) {
     325           0 :                 return NULL;
     326             :         }
     327             : 
     328      809565 :         for (i = 0; ops[i] != NULL; i++) {
     329      755594 :                 enum gensec_role role = GENSEC_SERVER;
     330      755594 :                 const char **tmp = NULL;
     331             : 
     332      755594 :                 if (ops[i]->sasl_name == NULL) {
     333      485739 :                         continue;
     334             :                 }
     335             : 
     336      269855 :                 if (gensec_security != NULL) {
     337      269855 :                         if (!gensec_security_ops_enabled(ops[i],
     338             :                                                          gensec_security)) {
     339       53971 :                                 continue;
     340             :                         }
     341             : 
     342      215884 :                         role = gensec_security->gensec_role;
     343             :                 }
     344             : 
     345      215884 :                 switch (role) {
     346           0 :                 case GENSEC_CLIENT:
     347           0 :                         if (ops[i]->client_start == NULL) {
     348           0 :                                 continue;
     349             :                         }
     350           0 :                         break;
     351      215884 :                 case GENSEC_SERVER:
     352      215884 :                         if (ops[i]->server_start == NULL) {
     353       53971 :                                 continue;
     354             :                         }
     355      161181 :                         break;
     356             :                 }
     357             : 
     358      161913 :                 tmp = talloc_realloc(mem_ctx,
     359             :                                      sasl_names,
     360             :                                      const char *,
     361             :                                      sasl_names_count + 2);
     362      161913 :                 if (tmp == NULL) {
     363           0 :                         TALLOC_FREE(sasl_names);
     364           0 :                         return NULL;
     365             :                 }
     366      161913 :                 sasl_names = tmp;
     367             : 
     368      161913 :                 sasl_names[sasl_names_count] = ops[i]->sasl_name;
     369      161913 :                 sasl_names_count++;
     370             :         }
     371       53971 :         sasl_names[sasl_names_count] = NULL;
     372             : 
     373       53971 :         return sasl_names;
     374             : }
     375             : 
     376             : /**
     377             :  * @brief Get the sasl names from the gensec security context.
     378             :  *
     379             :  * @param[in]  gensec_security The gensec security context.
     380             :  *
     381             :  * @param[in]  mem_ctx The memory context to allocate memory on.
     382             :  *
     383             :  * @return An allocated array with sasl names, NULL on error.
     384             :  */
     385             : _PUBLIC_
     386       53971 : const char **gensec_security_sasl_names(struct gensec_security *gensec_security,
     387             :                                         TALLOC_CTX *mem_ctx)
     388             : {
     389       53971 :         const struct gensec_security_ops **ops = NULL;
     390             : 
     391       53971 :         ops = gensec_security_mechs(gensec_security, mem_ctx);
     392             : 
     393       53971 :         return gensec_security_sasl_names_from_ops(gensec_security,
     394             :                                                    mem_ctx,
     395             :                                                    ops);
     396             : }
     397             : 
     398             : /**
     399             :  * Return a unique list of security subsystems from those specified in
     400             :  * the list of SASL names.
     401             :  *
     402             :  * Use the list of enabled GENSEC mechanisms from the credentials
     403             :  * attached to the gensec_security, and return in our preferred order.
     404             :  */
     405             : 
     406         330 : static const struct gensec_security_ops **gensec_security_by_sasl_list(
     407             :         struct gensec_security *gensec_security,
     408             :         TALLOC_CTX *mem_ctx,
     409             :         const char **sasl_names)
     410             : {
     411           0 :         const struct gensec_security_ops **backends_out;
     412           0 :         const struct gensec_security_ops **backends;
     413           0 :         int i, k, sasl_idx;
     414         330 :         int num_backends_out = 0;
     415             : 
     416         330 :         if (!sasl_names) {
     417           0 :                 return NULL;
     418             :         }
     419             : 
     420         330 :         backends = gensec_security_mechs(gensec_security, mem_ctx);
     421             : 
     422         330 :         backends_out = talloc_array(mem_ctx, const struct gensec_security_ops *, 1);
     423         330 :         if (!backends_out) {
     424           0 :                 return NULL;
     425             :         }
     426         330 :         backends_out[0] = NULL;
     427             : 
     428             :         /* Find backends in our preferred order, by walking our list,
     429             :          * then looking in the supplied list */
     430        2232 :         for (i=0; backends && backends[i]; i++) {
     431        1902 :                 if (gensec_security != NULL &&
     432        1902 :                                 !gensec_security_ops_enabled(backends[i], gensec_security))
     433           2 :                     continue;
     434        3800 :                 for (sasl_idx = 0; sasl_names[sasl_idx]; sasl_idx++) {
     435        1900 :                         if (!backends[i]->sasl_name ||
     436         641 :                             !(strcmp(backends[i]->sasl_name,
     437         641 :                                      sasl_names[sasl_idx]) == 0)) {
     438        1570 :                                 continue;
     439             :                         }
     440             : 
     441         330 :                         for (k=0; backends_out[k]; k++) {
     442           0 :                                 if (backends_out[k] == backends[i]) {
     443           0 :                                         break;
     444             :                                 }
     445             :                         }
     446             : 
     447         330 :                         if (k < num_backends_out) {
     448             :                                 /* already in there */
     449           0 :                                 continue;
     450             :                         }
     451             : 
     452         330 :                         backends_out = talloc_realloc(mem_ctx, backends_out,
     453             :                                                       const struct gensec_security_ops *,
     454             :                                                       num_backends_out + 2);
     455         330 :                         if (!backends_out) {
     456           0 :                                 return NULL;
     457             :                         }
     458             : 
     459         330 :                         backends_out[num_backends_out] = backends[i];
     460         330 :                         num_backends_out++;
     461         330 :                         backends_out[num_backends_out] = NULL;
     462             :                 }
     463             :         }
     464         330 :         return backends_out;
     465             : }
     466             : 
     467             : /**
     468             :  * Return a unique list of security subsystems from those specified in
     469             :  * the OID list.  That is, where two OIDs refer to the same module,
     470             :  * return that module only once.
     471             :  *
     472             :  * Use the list of enabled GENSEC mechanisms from the credentials
     473             :  * attached to the gensec_security, and return in our preferred order.
     474             :  */
     475             : 
     476      192776 : _PUBLIC_ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(
     477             :                                         struct gensec_security *gensec_security,
     478             :                                         TALLOC_CTX *mem_ctx,
     479             :                                         const char * const *oid_strings,
     480             :                                         const char *skip)
     481             : {
     482        3704 :         struct gensec_security_ops_wrapper *backends_out;
     483        3704 :         const struct gensec_security_ops **backends;
     484        3704 :         int i, j, k, oid_idx;
     485      192776 :         int num_backends_out = 0;
     486             : 
     487      192776 :         if (!oid_strings) {
     488           0 :                 return NULL;
     489             :         }
     490             : 
     491      192776 :         backends = gensec_security_mechs(gensec_security, gensec_security);
     492             : 
     493      192776 :         backends_out = talloc_array(mem_ctx, struct gensec_security_ops_wrapper, 1);
     494      192776 :         if (!backends_out) {
     495           0 :                 return NULL;
     496             :         }
     497      192776 :         backends_out[0].op = NULL;
     498      192776 :         backends_out[0].oid = NULL;
     499             : 
     500             :         /* Find backends in our preferred order, by walking our list,
     501             :          * then looking in the supplied list */
     502     2022401 :         for (i=0; backends && backends[i]; i++) {
     503     1877874 :                 if (gensec_security != NULL &&
     504     1829625 :                                 !gensec_security_ops_enabled(backends[i], gensec_security))
     505      197444 :                     continue;
     506     1632181 :                 if (!backends[i]->oid) {
     507     1129592 :                         continue;
     508             :                 }
     509     1613989 :                 for (oid_idx = 0; oid_strings[oid_idx]; oid_idx++) {
     510     1111400 :                         if (strcmp(oid_strings[oid_idx], skip) == 0) {
     511           0 :                                 continue;
     512             :                         }
     513             : 
     514     2552761 :                         for (j=0; backends[i]->oid[j]; j++) {
     515     1469327 :                                 if (!backends[i]->oid[j] ||
     516     1441361 :                                     !(strcmp(backends[i]->oid[j],
     517     1403671 :                                             oid_strings[oid_idx]) == 0)) {
     518     1043165 :                                         continue;
     519             :                                 }
     520             : 
     521      493906 :                                 for (k=0; backends_out[k].op; k++) {
     522      205424 :                                         if (backends_out[k].op == backends[i]) {
     523      106482 :                                                 break;
     524             :                                         }
     525             :                                 }
     526             : 
     527      398196 :                                 if (k < num_backends_out) {
     528             :                                         /* already in there */
     529      109714 :                                         continue;
     530             :                                 }
     531             : 
     532      288482 :                                 backends_out = talloc_realloc(mem_ctx, backends_out,
     533             :                                                               struct gensec_security_ops_wrapper,
     534             :                                                               num_backends_out + 2);
     535      288482 :                                 if (!backends_out) {
     536           0 :                                         return NULL;
     537             :                                 }
     538             : 
     539      288482 :                                 backends_out[num_backends_out].op = backends[i];
     540      288482 :                                 backends_out[num_backends_out].oid = backends[i]->oid[j];
     541      288482 :                                 num_backends_out++;
     542      288482 :                                 backends_out[num_backends_out].op = NULL;
     543      288482 :                                 backends_out[num_backends_out].oid = NULL;
     544             :                         }
     545             :                 }
     546             :         }
     547      189072 :         return backends_out;
     548             : }
     549             : 
     550             : /**
     551             :  * Return OIDS from the security subsystems listed
     552             :  */
     553             : 
     554      123129 : static const char **gensec_security_oids_from_ops(
     555             :         struct gensec_security *gensec_security,
     556             :         TALLOC_CTX *mem_ctx,
     557             :         const struct gensec_security_ops * const *ops,
     558             :         const char *skip)
     559             : {
     560        2651 :         int i;
     561      123129 :         int j = 0;
     562        2651 :         int k;
     563        2651 :         const char **oid_list;
     564      123129 :         if (!ops) {
     565           0 :                 return NULL;
     566             :         }
     567      123129 :         oid_list = talloc_array(mem_ctx, const char *, 1);
     568      123129 :         if (!oid_list) {
     569           0 :                 return NULL;
     570             :         }
     571             : 
     572     1222354 :         for (i=0; ops && ops[i]; i++) {
     573     1132732 :                 if (gensec_security != NULL &&
     574     1099225 :                         !gensec_security_ops_enabled(ops[i], gensec_security)) {
     575      107384 :                         continue;
     576             :                 }
     577      991841 :                 if (!ops[i]->oid) {
     578      675260 :                         continue;
     579             :                 }
     580             : 
     581      710952 :                 for (k = 0; ops[i]->oid[k]; k++) {
     582      394371 :                         if (skip && strcmp(skip, ops[i]->oid[k])==0) {
     583             :                         } else {
     584      271242 :                                 oid_list = talloc_realloc(mem_ctx, oid_list, const char *, j + 2);
     585      271242 :                                 if (!oid_list) {
     586           0 :                                         return NULL;
     587             :                                 }
     588      271242 :                                 oid_list[j] = ops[i]->oid[k];
     589      271242 :                                 j++;
     590             :                         }
     591             :                 }
     592             :         }
     593      123129 :         oid_list[j] = NULL;
     594      123129 :         return oid_list;
     595             : }
     596             : 
     597             : 
     598             : /**
     599             :  * Return OIDS from the security subsystems listed
     600             :  */
     601             : 
     602       84184 : _PUBLIC_ const char **gensec_security_oids_from_ops_wrapped(TALLOC_CTX *mem_ctx,
     603             :                                 const struct gensec_security_ops_wrapper *wops)
     604             : {
     605        1520 :         int i;
     606       84184 :         int j = 0;
     607        1520 :         int k;
     608        1520 :         const char **oid_list;
     609       84184 :         if (!wops) {
     610           0 :                 return NULL;
     611             :         }
     612       84184 :         oid_list = talloc_array(mem_ctx, const char *, 1);
     613       84184 :         if (!oid_list) {
     614           0 :                 return NULL;
     615             :         }
     616             : 
     617      205489 :         for (i=0; wops[i].op; i++) {
     618      121305 :                 if (!wops[i].op->oid) {
     619           0 :                         continue;
     620             :                 }
     621             : 
     622      283478 :                 for (k = 0; wops[i].op->oid[k]; k++) {
     623      162173 :                         oid_list = talloc_realloc(mem_ctx, oid_list, const char *, j + 2);
     624      162173 :                         if (!oid_list) {
     625           0 :                                 return NULL;
     626             :                         }
     627      162173 :                         oid_list[j] = wops[i].op->oid[k];
     628      162173 :                         j++;
     629             :                 }
     630             :         }
     631       84184 :         oid_list[j] = NULL;
     632       84184 :         return oid_list;
     633             : }
     634             : 
     635             : 
     636             : /**
     637             :  * Return all the security subsystems currently enabled on a GENSEC context.
     638             :  *
     639             :  * This is taken from a list attached to the cli_credentials, and
     640             :  * skips the OID in 'skip'.  (Typically the SPNEGO OID)
     641             :  *
     642             :  */
     643             : 
     644      123129 : _PUBLIC_ const char **gensec_security_oids(struct gensec_security *gensec_security,
     645             :                                            TALLOC_CTX *mem_ctx,
     646             :                                            const char *skip)
     647             : {
     648        2651 :         const struct gensec_security_ops **ops;
     649             : 
     650      123129 :         ops = gensec_security_mechs(gensec_security, mem_ctx);
     651             : 
     652      123129 :         return gensec_security_oids_from_ops(gensec_security, mem_ctx, ops, skip);
     653             : }
     654             : 
     655      515570 : static int gensec_security_destructor(struct gensec_security *gctx)
     656             : {
     657      515570 :         if (gctx->parent_security != NULL) {
     658         169 :                 if (gctx->parent_security->child_security == gctx) {
     659         169 :                         gctx->parent_security->child_security = NULL;
     660             :                 }
     661         169 :                 gctx->parent_security = NULL;
     662             :         }
     663             : 
     664      515570 :         if (gctx->child_security != NULL) {
     665      130180 :                 if (gctx->child_security->parent_security == gctx) {
     666      130180 :                         gctx->child_security->parent_security = NULL;
     667             :                 }
     668      130180 :                 gctx->child_security = NULL;
     669             :         }
     670             : 
     671      515570 :         return 0;
     672             : }
     673             : 
     674             : /**
     675             :   Start the GENSEC system, returning a context pointer.
     676             :   @param mem_ctx The parent TALLOC memory context.
     677             :   @param gensec_security Returned GENSEC context pointer.
     678             :   @note  The mem_ctx is only a parent and may be NULL.
     679             :   @note, the auth context is moved to be a referenced pointer of the
     680             :   @ gensec_security return
     681             : */
     682      298419 : static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx,
     683             :                              struct gensec_settings *settings,
     684             :                              struct auth4_context *auth_context,
     685             :                              struct gensec_security **gensec_security)
     686             : {
     687      298419 :         (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security);
     688      298419 :         NT_STATUS_HAVE_NO_MEMORY(*gensec_security);
     689             : 
     690      298419 :         (*gensec_security)->max_update_size = 0;
     691             : 
     692      298419 :         SMB_ASSERT(settings->lp_ctx != NULL);
     693      298419 :         (*gensec_security)->settings = talloc_reference(*gensec_security, settings);
     694             : 
     695             :         /* We need to reference this, not steal, as the caller may be
     696             :          * python, which won't like it if we steal it's object away
     697             :          * from it */
     698      298419 :         (*gensec_security)->auth_context = talloc_reference(*gensec_security, auth_context);
     699             : 
     700      298419 :         talloc_set_destructor((*gensec_security), gensec_security_destructor);
     701      298419 :         return NT_STATUS_OK;
     702             : }
     703             : 
     704             : /**
     705             :  * Start a GENSEC subcontext, with a copy of the properties of the parent
     706             :  * @param mem_ctx The parent TALLOC memory context.
     707             :  * @param parent The parent GENSEC context
     708             :  * @param gensec_security Returned GENSEC context pointer.
     709             :  * @note Used by SPNEGO in particular, for the actual implementation mechanism
     710             :  */
     711             : 
     712      218666 : _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx,
     713             :                                  struct gensec_security *parent,
     714             :                                  struct gensec_security **gensec_security)
     715             : {
     716      218666 :         if (parent->child_security != NULL) {
     717           0 :                 return NT_STATUS_INTERNAL_ERROR;
     718             :         }
     719             : 
     720      218666 :         (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security);
     721      218666 :         NT_STATUS_HAVE_NO_MEMORY(*gensec_security);
     722             : 
     723      218666 :         (**gensec_security) = *parent;
     724      218666 :         (*gensec_security)->ops = NULL;
     725      218666 :         (*gensec_security)->private_data = NULL;
     726      218666 :         (*gensec_security)->update_busy_ptr = NULL;
     727             : 
     728      218666 :         (*gensec_security)->subcontext = true;
     729      218666 :         (*gensec_security)->want_features = parent->want_features;
     730      218666 :         (*gensec_security)->max_update_size = parent->max_update_size;
     731      218666 :         (*gensec_security)->dcerpc_auth_level = parent->dcerpc_auth_level;
     732      218666 :         (*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context);
     733      218666 :         (*gensec_security)->settings = talloc_reference(*gensec_security, parent->settings);
     734      218666 :         (*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context);
     735      218666 :         (*gensec_security)->channel_bindings = talloc_reference(*gensec_security, parent->channel_bindings);
     736             : 
     737      218666 :         talloc_set_destructor((*gensec_security), gensec_security_destructor);
     738      218666 :         return NT_STATUS_OK;
     739             : }
     740             : 
     741      130996 : _PUBLIC_ NTSTATUS gensec_child_ready(struct gensec_security *parent,
     742             :                                      struct gensec_security *child)
     743             : {
     744      130996 :         if (parent->child_security != NULL) {
     745           0 :                 return NT_STATUS_INTERNAL_ERROR;
     746             :         }
     747             : 
     748      130996 :         if (child->parent_security != NULL) {
     749           0 :                 return NT_STATUS_INTERNAL_ERROR;
     750             :         }
     751             : 
     752      130996 :         parent->child_security = child;
     753      130996 :         child->parent_security = parent;
     754      130996 :         return NT_STATUS_OK;
     755             : }
     756             : 
     757             : /**
     758             :   Start the GENSEC system, in client mode, returning a context pointer.
     759             :   @param mem_ctx The parent TALLOC memory context.
     760             :   @param gensec_security Returned GENSEC context pointer.
     761             :   @note  The mem_ctx is only a parent and may be NULL.
     762             : */
     763      118142 : _PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx,
     764             :                              struct gensec_security **gensec_security,
     765             :                              struct gensec_settings *settings)
     766             : {
     767        1742 :         NTSTATUS status;
     768             : 
     769      118142 :         if (settings == NULL) {
     770           0 :                 DEBUG(0,("gensec_client_start: no settings given!\n"));
     771           0 :                 return NT_STATUS_INTERNAL_ERROR;
     772             :         }
     773             : 
     774      118142 :         status = gensec_start(mem_ctx, settings, NULL, gensec_security);
     775      118142 :         if (!NT_STATUS_IS_OK(status)) {
     776           0 :                 return status;
     777             :         }
     778      118142 :         (*gensec_security)->gensec_role = GENSEC_CLIENT;
     779             : 
     780      118142 :         return status;
     781             : }
     782             : 
     783             : 
     784             : 
     785             : /**
     786             :   Start the GENSEC system, in server mode, returning a context pointer.
     787             :   @param mem_ctx The parent TALLOC memory context.
     788             :   @param gensec_security Returned GENSEC context pointer.
     789             :   @note  The mem_ctx is only a parent and may be NULL.
     790             : */
     791      180277 : _PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx,
     792             :                                       struct gensec_settings *settings,
     793             :                                       struct auth4_context *auth_context,
     794             :                                       struct gensec_security **gensec_security)
     795             : {
     796        2921 :         NTSTATUS status;
     797             : 
     798      180277 :         if (!settings) {
     799           0 :                 DEBUG(0,("gensec_server_start: no settings given!\n"));
     800           0 :                 return NT_STATUS_INTERNAL_ERROR;
     801             :         }
     802             : 
     803      180277 :         status = gensec_start(mem_ctx, settings, auth_context, gensec_security);
     804      180277 :         if (!NT_STATUS_IS_OK(status)) {
     805           0 :                 return status;
     806             :         }
     807      180277 :         (*gensec_security)->gensec_role = GENSEC_SERVER;
     808             : 
     809      180277 :         return status;
     810             : }
     811             : 
     812      420662 : static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security)
     813             : {
     814        8072 :         NTSTATUS status;
     815             : 
     816             :         /*
     817             :          * Callers sometimes just reuse a context, we should
     818             :          * clear the internal state before starting it again.
     819             :          */
     820      420662 :         talloc_unlink(gensec_security, gensec_security->private_data);
     821      420662 :         gensec_security->private_data = NULL;
     822             : 
     823      420662 :         if (gensec_security->child_security != NULL) {
     824             :                 /*
     825             :                  * The talloc_unlink(.., gensec_security->private_data)
     826             :                  * should have cleared this via
     827             :                  * gensec_security_destructor().
     828             :                  */
     829           0 :                 return NT_STATUS_INTERNAL_ERROR;
     830             :         }
     831             : 
     832      420662 :         if (gensec_security->credentials) {
     833      420660 :                 const char *forced_mech = cli_credentials_get_forced_sasl_mech(gensec_security->credentials);
     834      420660 :                 if (forced_mech &&
     835           0 :                     (gensec_security->ops->sasl_name == NULL ||
     836           0 :                      strcasecmp(forced_mech, gensec_security->ops->sasl_name) != 0)) {
     837           0 :                         DEBUG(5, ("GENSEC mechanism %s (%s) skipped, as it "
     838             :                                   "did not match forced mechanism %s\n",
     839             :                                   gensec_security->ops->name,
     840             :                                   gensec_security->ops->sasl_name,
     841             :                                   forced_mech));
     842           0 :                         return NT_STATUS_INVALID_PARAMETER;
     843             :                 }
     844             :         }
     845      420662 :         DEBUG(5, ("Starting GENSEC %smechanism %s\n",
     846             :                   gensec_security->subcontext ? "sub" : "",
     847             :                   gensec_security->ops->name));
     848      420662 :         switch (gensec_security->gensec_role) {
     849      173004 :         case GENSEC_CLIENT:
     850      173004 :                 if (gensec_security->ops->client_start) {
     851      173004 :                         status = gensec_security->ops->client_start(gensec_security);
     852      173004 :                         if (!NT_STATUS_IS_OK(status)) {
     853       24499 :                                 DEBUG(gensec_security->subcontext?4:2, ("Failed to start GENSEC client mech %s: %s\n",
     854             :                                           gensec_security->ops->name, nt_errstr(status)));
     855             :                         }
     856      173004 :                         return status;
     857             :                 }
     858           0 :                 break;
     859      247658 :         case GENSEC_SERVER:
     860      247658 :                 if (gensec_security->ops->server_start) {
     861      247658 :                         status = gensec_security->ops->server_start(gensec_security);
     862      247658 :                         if (!NT_STATUS_IS_OK(status)) {
     863          10 :                                 DEBUG(1, ("Failed to start GENSEC server mech %s: %s\n",
     864             :                                           gensec_security->ops->name, nt_errstr(status)));
     865             :                         }
     866      247658 :                         return status;
     867             :                 }
     868           0 :                 break;
     869             :         }
     870           0 :         return NT_STATUS_INVALID_PARAMETER;
     871             : }
     872             : 
     873             : /**
     874             :  * Start a GENSEC sub-mechanism with a specified mechanism structure, used in SPNEGO
     875             :  *
     876             :  */
     877             : 
     878      218994 : NTSTATUS gensec_start_mech_by_ops(struct gensec_security *gensec_security,
     879             :                                   const struct gensec_security_ops *ops)
     880             : {
     881      218994 :         gensec_security->ops = ops;
     882      218994 :         return gensec_start_mech(gensec_security);
     883             : }
     884             : 
     885             : 
     886             : /**
     887             :  * Start a GENSEC sub-mechanism by DCERPC allocated 'auth type' number
     888             :  * @param gensec_security GENSEC context pointer.
     889             :  * @param auth_type DCERPC auth type
     890             :  * @param auth_level DCERPC auth level
     891             :  */
     892             : 
     893       18902 : _PUBLIC_ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security,
     894             :                                        uint8_t auth_type, uint8_t auth_level)
     895             : {
     896       18902 :         gensec_security->ops = gensec_security_by_auth_type(gensec_security, auth_type);
     897       18902 :         if (!gensec_security->ops) {
     898          39 :                 DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type));
     899          39 :                 return NT_STATUS_INVALID_PARAMETER;
     900             :         }
     901       18863 :         gensec_security->dcerpc_auth_level = auth_level;
     902             :         /*
     903             :          * We need to reset sign/seal in order to reset it.
     904             :          * We may got some default features inherited by the credentials
     905             :          */
     906       18863 :         gensec_security->want_features &= ~GENSEC_FEATURE_SIGN;
     907       18863 :         gensec_security->want_features &= ~GENSEC_FEATURE_SEAL;
     908       18863 :         gensec_want_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE);
     909       18863 :         gensec_want_feature(gensec_security, GENSEC_FEATURE_ASYNC_REPLIES);
     910       18863 :         if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
     911        6473 :                 if (gensec_security->gensec_role == GENSEC_CLIENT) {
     912        3313 :                         gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN);
     913             :                 }
     914       12390 :         } else if (auth_level == DCERPC_AUTH_LEVEL_PACKET) {
     915             :                 /*
     916             :                  * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
     917             :                  * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
     918             :                  */
     919         408 :                 if (gensec_security->gensec_role == GENSEC_CLIENT) {
     920         255 :                         gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN);
     921             :                 }
     922       11982 :         } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
     923       10536 :                 gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN);
     924       10536 :                 gensec_want_feature(gensec_security, GENSEC_FEATURE_SEAL);
     925        1446 :         } else if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
     926             :                 /* Default features */
     927             :         } else {
     928           3 :                 DEBUG(2,("auth_level %d not supported in DCE/RPC authentication\n",
     929             :                          auth_level));
     930           3 :                 return NT_STATUS_INVALID_PARAMETER;
     931             :         }
     932             : 
     933       18860 :         return gensec_start_mech(gensec_security);
     934             : }
     935             : 
     936         160 : _PUBLIC_ const char *gensec_get_name_by_authtype(struct gensec_security *gensec_security, uint8_t authtype)
     937             : {
     938           0 :         const struct gensec_security_ops *ops;
     939         160 :         ops = gensec_security_by_auth_type(gensec_security, authtype);
     940         160 :         if (ops) {
     941         121 :                 return ops->name;
     942             :         }
     943          39 :         return NULL;
     944             : }
     945             : 
     946             : 
     947          76 : _PUBLIC_ const char *gensec_get_name_by_oid(struct gensec_security *gensec_security,
     948             :                                                                                         const char *oid_string)
     949             : {
     950           0 :         const struct gensec_security_ops *ops;
     951          76 :         ops = gensec_security_by_oid(gensec_security, oid_string);
     952          76 :         if (ops) {
     953           4 :                 return ops->name;
     954             :         }
     955          72 :         return oid_string;
     956             : }
     957             : 
     958             : /**
     959             :  * Start a GENSEC sub-mechanism by OID, used in SPNEGO
     960             :  *
     961             :  * @note This should also be used when you wish to just start NLTMSSP (for example), as it uses a
     962             :  *       well-known #define to hook it in.
     963             :  */
     964             : 
     965      127970 : _PUBLIC_ NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security,
     966             :                                   const char *mech_oid)
     967             : {
     968      127970 :         SMB_ASSERT(gensec_security != NULL);
     969             : 
     970      127970 :         gensec_security->ops = gensec_security_by_oid(gensec_security, mech_oid);
     971      127970 :         if (!gensec_security->ops) {
     972          72 :                 DEBUG(3, ("Could not find GENSEC backend for oid=%s\n", mech_oid));
     973          72 :                 return NT_STATUS_INVALID_PARAMETER;
     974             :         }
     975      127898 :         return gensec_start_mech(gensec_security);
     976             : }
     977             : 
     978             : /**
     979             :  * Start a GENSEC sub-mechanism by a well known SASL name
     980             :  *
     981             :  */
     982             : 
     983       53477 : _PUBLIC_ NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security,
     984             :                                         const char *sasl_name)
     985             : {
     986       53477 :         gensec_security->ops = gensec_security_by_sasl_name(gensec_security, sasl_name);
     987       53477 :         if (!gensec_security->ops) {
     988           2 :                 DEBUG(3, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name));
     989           2 :                 return NT_STATUS_INVALID_PARAMETER;
     990             :         }
     991       53475 :         return gensec_start_mech(gensec_security);
     992             : }
     993             : 
     994             : /**
     995             :  * Start a GENSEC sub-mechanism with the preferred option from a SASL name list
     996             :  *
     997             :  */
     998             : 
     999         330 : _PUBLIC_ NTSTATUS gensec_start_mech_by_sasl_list(struct gensec_security *gensec_security,
    1000             :                                                  const char **sasl_names)
    1001             : {
    1002         330 :         NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER;
    1003         330 :         TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
    1004           0 :         const struct gensec_security_ops **ops;
    1005           0 :         int i;
    1006         330 :         if (!mem_ctx) {
    1007           0 :                 return NT_STATUS_NO_MEMORY;
    1008             :         }
    1009         330 :         ops = gensec_security_by_sasl_list(gensec_security, mem_ctx, sasl_names);
    1010         330 :         if (!ops || !*ops) {
    1011           0 :                 DEBUG(3, ("Could not find GENSEC backend for any of sasl_name = %s\n",
    1012             :                           str_list_join(mem_ctx,
    1013             :                                         sasl_names, ' ')));
    1014           0 :                 talloc_free(mem_ctx);
    1015           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1016             :         }
    1017         330 :         for (i=0; ops[i]; i++) {
    1018         330 :                 nt_status = gensec_start_mech_by_ops(gensec_security, ops[i]);
    1019         330 :                 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER)) {
    1020         330 :                         break;
    1021             :                 }
    1022             :         }
    1023         330 :         talloc_free(mem_ctx);
    1024         330 :         return nt_status;
    1025             : }
    1026             : 
    1027             : /**
    1028             :  * Start a GENSEC sub-mechanism by an internal name
    1029             :  *
    1030             :  */
    1031             : 
    1032        1439 : _PUBLIC_ NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security,
    1033             :                                         const char *name)
    1034             : {
    1035        1439 :         gensec_security->ops = gensec_security_by_name(gensec_security, name);
    1036        1439 :         if (!gensec_security->ops) {
    1037           4 :                 DEBUG(3, ("Could not find GENSEC backend for name=%s\n", name));
    1038           4 :                 return NT_STATUS_INVALID_PARAMETER;
    1039             :         }
    1040        1435 :         return gensec_start_mech(gensec_security);
    1041             : }
    1042             : 
    1043             : /**
    1044             :  * Associate a credentials structure with a GENSEC context - talloc_reference()s it to the context
    1045             :  *
    1046             :  */
    1047             : 
    1048      298757 : _PUBLIC_ NTSTATUS gensec_set_credentials(struct gensec_security *gensec_security, struct cli_credentials *credentials)
    1049             : {
    1050      298757 :         gensec_security->credentials = talloc_reference(gensec_security, credentials);
    1051      298757 :         NT_STATUS_HAVE_NO_MEMORY(gensec_security->credentials);
    1052      298757 :         gensec_want_feature(gensec_security, cli_credentials_get_gensec_features(gensec_security->credentials));
    1053      298757 :         return NT_STATUS_OK;
    1054             : }
    1055             : 
    1056             : /*
    1057             :   register a GENSEC backend.
    1058             : 
    1059             :   The 'name' can be later used by other backends to find the operations
    1060             :   structure for this backend.
    1061             : */
    1062      675188 : _PUBLIC_ NTSTATUS gensec_register(TALLOC_CTX *ctx,
    1063             :                         const struct gensec_security_ops *ops)
    1064             : {
    1065      675188 :         if (gensec_security_by_name(NULL, ops->name) != NULL) {
    1066             :                 /* its already registered! */
    1067           0 :                 DEBUG(0,("GENSEC backend '%s' already registered\n",
    1068             :                          ops->name));
    1069           0 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
    1070             :         }
    1071             : 
    1072      675188 :         generic_security_ops = talloc_realloc(ctx,
    1073             :                                               generic_security_ops,
    1074             :                                               const struct gensec_security_ops *,
    1075             :                                               gensec_num_backends+2);
    1076      675188 :         if (!generic_security_ops) {
    1077           0 :                 return NT_STATUS_NO_MEMORY;
    1078             :         }
    1079             : 
    1080      675188 :         generic_security_ops[gensec_num_backends] = ops;
    1081      675188 :         gensec_num_backends++;
    1082      675188 :         generic_security_ops[gensec_num_backends] = NULL;
    1083             : 
    1084      675188 :         DEBUG(3,("GENSEC backend '%s' registered\n",
    1085             :                  ops->name));
    1086             : 
    1087      675188 :         return NT_STATUS_OK;
    1088             : }
    1089             : 
    1090             : /*
    1091             :   return the GENSEC interface version, and the size of some critical types
    1092             :   This can be used by backends to either detect compilation errors, or provide
    1093             :   multiple implementations for different smbd compilation options in one module
    1094             : */
    1095           0 : _PUBLIC_ const struct gensec_critical_sizes *gensec_interface_version(void)
    1096             : {
    1097           0 :         static const struct gensec_critical_sizes critical_sizes = {
    1098             :                 GENSEC_INTERFACE_VERSION,
    1099             :                 sizeof(struct gensec_security_ops),
    1100             :                 sizeof(struct gensec_security),
    1101             :         };
    1102             : 
    1103           0 :         return &critical_sizes;
    1104             : }
    1105             : 
    1106     1478049 : static int sort_gensec(const struct gensec_security_ops **gs1, const struct gensec_security_ops **gs2) {
    1107     1478049 :         return NUMERIC_CMP((*gs2)->priority, (*gs1)->priority);
    1108             : }
    1109             : 
    1110      181167 : int gensec_setting_int(struct gensec_settings *settings, const char *mechanism, const char *name, int default_value)
    1111             : {
    1112      181167 :         return lpcfg_parm_int(settings->lp_ctx, NULL, mechanism, name, default_value);
    1113             : }
    1114             : 
    1115     1596416 : bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value)
    1116             : {
    1117     1596416 :         return lpcfg_parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value);
    1118             : }
    1119             : 
    1120             : /*
    1121             :   initialise the GENSEC subsystem
    1122             : */
    1123      202346 : _PUBLIC_ NTSTATUS gensec_init(void)
    1124             : {
    1125        2737 :         static bool initialized = false;
    1126             : #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
    1127             : #ifdef STATIC_gensec_MODULES
    1128        2737 :         STATIC_gensec_MODULES_PROTO;
    1129      202346 :         init_module_fn static_init[] = { STATIC_gensec_MODULES };
    1130             : #else
    1131             :         init_module_fn *static_init = NULL;
    1132             : #endif
    1133        2737 :         init_module_fn *shared_init;
    1134             : 
    1135      202346 :         if (initialized) return NT_STATUS_OK;
    1136       53161 :         initialized = true;
    1137             : 
    1138       53161 :         shared_init = load_samba_modules(NULL, "gensec");
    1139             : 
    1140       53161 :         run_init_functions(NULL, static_init);
    1141       53161 :         run_init_functions(NULL, shared_init);
    1142             : 
    1143       53161 :         talloc_free(shared_init);
    1144             : 
    1145       53161 :         TYPESAFE_QSORT(generic_security_ops, gensec_num_backends, sort_gensec);
    1146             : 
    1147       53161 :         return NT_STATUS_OK;
    1148             : }

Generated by: LCOV version 1.14