2 Unix SMB/CIFS implementation.
4 Generic Authentication Interface
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2006
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.
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.
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/>.
24 #include "system/network.h"
26 #include "../lib/util/tevent_ntstatus.h"
27 #include "librpc/rpc/dcerpc.h"
28 #include "auth/credentials/credentials.h"
29 #include "auth/gensec/gensec.h"
30 #include "lib/param/param.h"
31 #include "lib/util/tsort.h"
32 #include "lib/util/samba_modules.h"
34 /* the list of currently registered GENSEC backends */
35 static struct gensec_security_ops **generic_security_ops;
36 static int gensec_num_backends;
38 /* Return all the registered mechs. Don't modify the return pointer,
39 * but you may talloc_reference it if convient */
40 _PUBLIC_ struct gensec_security_ops **gensec_security_all(void)
42 return generic_security_ops;
45 bool gensec_security_ops_enabled(struct gensec_security_ops *ops, struct gensec_security *security)
47 return lpcfg_parm_bool(security->settings->lp_ctx, NULL, "gensec", ops->name, ops->enabled);
50 /* Sometimes we want to force only kerberos, sometimes we want to
51 * force it's avoidance. The old list could be either
52 * gensec_security_all(), or from cli_credentials_gensec_list() (ie,
53 * an existing list we have trimmed down) */
55 _PUBLIC_ struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx,
56 struct gensec_security_ops **old_gensec_list,
57 struct cli_credentials *creds)
59 struct gensec_security_ops **new_gensec_list;
60 int i, j, num_mechs_in;
61 enum credentials_use_kerberos use_kerberos = CRED_AUTO_USE_KERBEROS;
64 use_kerberos = cli_credentials_get_kerberos_state(creds);
67 if (use_kerberos == CRED_AUTO_USE_KERBEROS) {
68 if (!talloc_reference(mem_ctx, old_gensec_list)) {
71 return old_gensec_list;
74 for (num_mechs_in=0; old_gensec_list && old_gensec_list[num_mechs_in]; num_mechs_in++) {
78 new_gensec_list = talloc_array(mem_ctx, struct gensec_security_ops *, num_mechs_in + 1);
79 if (!new_gensec_list) {
84 for (i=0; old_gensec_list && old_gensec_list[i]; i++) {
87 for (oid_idx = 0; old_gensec_list[i]->oid && old_gensec_list[i]->oid[oid_idx]; oid_idx++) {
88 if (strcmp(old_gensec_list[i]->oid[oid_idx], GENSEC_OID_SPNEGO) == 0) {
89 new_gensec_list[j] = old_gensec_list[i];
94 switch (use_kerberos) {
95 case CRED_DONT_USE_KERBEROS:
96 if (old_gensec_list[i]->kerberos == false) {
97 new_gensec_list[j] = old_gensec_list[i];
101 case CRED_MUST_USE_KERBEROS:
102 if (old_gensec_list[i]->kerberos == true) {
103 new_gensec_list[j] = old_gensec_list[i];
108 /* Can't happen or invalid parameter */
112 new_gensec_list[j] = NULL;
114 return new_gensec_list;
117 struct gensec_security_ops **gensec_security_mechs(struct gensec_security *gensec_security,
120 struct gensec_security_ops **backends;
121 if (!gensec_security) {
122 backends = gensec_security_all();
123 if (!talloc_reference(mem_ctx, backends)) {
128 struct cli_credentials *creds = gensec_get_credentials(gensec_security);
129 if (gensec_security->settings->backends) {
130 backends = gensec_security->settings->backends;
132 backends = gensec_security_all();
135 if (!talloc_reference(mem_ctx, backends)) {
140 return gensec_use_kerberos_mechs(mem_ctx, backends, creds);
144 static const struct gensec_security_ops *gensec_security_by_authtype(struct gensec_security *gensec_security,
148 struct gensec_security_ops **backends;
149 const struct gensec_security_ops *backend;
150 TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
154 backends = gensec_security_mechs(gensec_security, mem_ctx);
155 for (i=0; backends && backends[i]; i++) {
156 if (!gensec_security_ops_enabled(backends[i], gensec_security))
158 if (backends[i]->auth_type == auth_type) {
159 backend = backends[i];
160 talloc_free(mem_ctx);
164 talloc_free(mem_ctx);
169 const struct gensec_security_ops *gensec_security_by_oid(struct gensec_security *gensec_security,
170 const char *oid_string)
173 struct gensec_security_ops **backends;
174 const struct gensec_security_ops *backend;
175 TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
179 backends = gensec_security_mechs(gensec_security, mem_ctx);
180 for (i=0; backends && backends[i]; i++) {
181 if (gensec_security != NULL &&
182 !gensec_security_ops_enabled(backends[i],
185 if (backends[i]->oid) {
186 for (j=0; backends[i]->oid[j]; j++) {
187 if (backends[i]->oid[j] &&
188 (strcmp(backends[i]->oid[j], oid_string) == 0)) {
189 backend = backends[i];
190 talloc_free(mem_ctx);
196 talloc_free(mem_ctx);
201 const struct gensec_security_ops *gensec_security_by_sasl_name(struct gensec_security *gensec_security,
202 const char *sasl_name)
205 struct gensec_security_ops **backends;
206 const struct gensec_security_ops *backend;
207 TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
211 backends = gensec_security_mechs(gensec_security, mem_ctx);
212 for (i=0; backends && backends[i]; i++) {
213 if (!gensec_security_ops_enabled(backends[i], gensec_security))
215 if (backends[i]->sasl_name
216 && (strcmp(backends[i]->sasl_name, sasl_name) == 0)) {
217 backend = backends[i];
218 talloc_free(mem_ctx);
222 talloc_free(mem_ctx);
227 static const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security,
231 struct gensec_security_ops **backends;
232 const struct gensec_security_ops *backend;
233 TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
237 backends = gensec_security_mechs(gensec_security, mem_ctx);
238 for (i=0; backends && backends[i]; i++) {
239 if (gensec_security != NULL &&
240 !gensec_security_ops_enabled(backends[i], gensec_security))
242 if (backends[i]->name
243 && (strcmp(backends[i]->name, name) == 0)) {
244 backend = backends[i];
245 talloc_free(mem_ctx);
249 talloc_free(mem_ctx);
254 * Return a unique list of security subsystems from those specified in
255 * the list of SASL names.
257 * Use the list of enabled GENSEC mechanisms from the credentials
258 * attached to the gensec_security, and return in our preferred order.
261 const struct gensec_security_ops **gensec_security_by_sasl_list(struct gensec_security *gensec_security,
263 const char **sasl_names)
265 const struct gensec_security_ops **backends_out;
266 struct gensec_security_ops **backends;
268 int num_backends_out = 0;
274 backends = gensec_security_mechs(gensec_security, mem_ctx);
276 backends_out = talloc_array(mem_ctx, const struct gensec_security_ops *, 1);
280 backends_out[0] = NULL;
282 /* Find backends in our preferred order, by walking our list,
283 * then looking in the supplied list */
284 for (i=0; backends && backends[i]; i++) {
285 if (gensec_security != NULL &&
286 !gensec_security_ops_enabled(backends[i], gensec_security))
288 for (sasl_idx = 0; sasl_names[sasl_idx]; sasl_idx++) {
289 if (!backends[i]->sasl_name ||
290 !(strcmp(backends[i]->sasl_name,
291 sasl_names[sasl_idx]) == 0)) {
295 for (k=0; backends_out[k]; k++) {
296 if (backends_out[k] == backends[i]) {
301 if (k < num_backends_out) {
302 /* already in there */
306 backends_out = talloc_realloc(mem_ctx, backends_out,
307 const struct gensec_security_ops *,
308 num_backends_out + 2);
313 backends_out[num_backends_out] = backends[i];
315 backends_out[num_backends_out] = NULL;
322 * Return a unique list of security subsystems from those specified in
323 * the OID list. That is, where two OIDs refer to the same module,
324 * return that module only once.
326 * Use the list of enabled GENSEC mechanisms from the credentials
327 * attached to the gensec_security, and return in our preferred order.
330 const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(struct gensec_security *gensec_security,
332 const char **oid_strings,
335 struct gensec_security_ops_wrapper *backends_out;
336 struct gensec_security_ops **backends;
337 int i, j, k, oid_idx;
338 int num_backends_out = 0;
344 backends = gensec_security_mechs(gensec_security, gensec_security);
346 backends_out = talloc_array(mem_ctx, struct gensec_security_ops_wrapper, 1);
350 backends_out[0].op = NULL;
351 backends_out[0].oid = NULL;
353 /* Find backends in our preferred order, by walking our list,
354 * then looking in the supplied list */
355 for (i=0; backends && backends[i]; i++) {
356 if (gensec_security != NULL &&
357 !gensec_security_ops_enabled(backends[i], gensec_security))
359 if (!backends[i]->oid) {
362 for (oid_idx = 0; oid_strings[oid_idx]; oid_idx++) {
363 if (strcmp(oid_strings[oid_idx], skip) == 0) {
367 for (j=0; backends[i]->oid[j]; j++) {
368 if (!backends[i]->oid[j] ||
369 !(strcmp(backends[i]->oid[j],
370 oid_strings[oid_idx]) == 0)) {
374 for (k=0; backends_out[k].op; k++) {
375 if (backends_out[k].op == backends[i]) {
380 if (k < num_backends_out) {
381 /* already in there */
385 backends_out = talloc_realloc(mem_ctx, backends_out,
386 struct gensec_security_ops_wrapper,
387 num_backends_out + 2);
392 backends_out[num_backends_out].op = backends[i];
393 backends_out[num_backends_out].oid = backends[i]->oid[j];
395 backends_out[num_backends_out].op = NULL;
396 backends_out[num_backends_out].oid = NULL;
404 * Return OIDS from the security subsystems listed
407 const char **gensec_security_oids_from_ops(struct gensec_security *gensec_security,
409 struct gensec_security_ops **ops,
415 const char **oid_list;
419 oid_list = talloc_array(mem_ctx, const char *, 1);
424 for (i=0; ops && ops[i]; i++) {
425 if (gensec_security != NULL &&
426 !gensec_security_ops_enabled(ops[i], gensec_security)) {
433 for (k = 0; ops[i]->oid[k]; k++) {
434 if (skip && strcmp(skip, ops[i]->oid[k])==0) {
436 oid_list = talloc_realloc(mem_ctx, oid_list, const char *, j + 2);
440 oid_list[j] = ops[i]->oid[k];
451 * Return OIDS from the security subsystems listed
454 const char **gensec_security_oids_from_ops_wrapped(TALLOC_CTX *mem_ctx,
455 const struct gensec_security_ops_wrapper *wops)
460 const char **oid_list;
464 oid_list = talloc_array(mem_ctx, const char *, 1);
469 for (i=0; wops[i].op; i++) {
470 if (!wops[i].op->oid) {
474 for (k = 0; wops[i].op->oid[k]; k++) {
475 oid_list = talloc_realloc(mem_ctx, oid_list, const char *, j + 2);
479 oid_list[j] = wops[i].op->oid[k];
489 * Return all the security subsystems currently enabled on a GENSEC context.
491 * This is taken from a list attached to the cli_credentials, and
492 * skips the OID in 'skip'. (Typically the SPNEGO OID)
496 const char **gensec_security_oids(struct gensec_security *gensec_security,
500 struct gensec_security_ops **ops
501 = gensec_security_mechs(gensec_security, mem_ctx);
502 return gensec_security_oids_from_ops(gensec_security, mem_ctx, ops, skip);
506 Start the GENSEC system, returning a context pointer.
507 @param mem_ctx The parent TALLOC memory context.
508 @param gensec_security Returned GENSEC context pointer.
509 @note The mem_ctx is only a parent and may be NULL.
510 @note, the auth context is moved to be a referenced pointer of the
511 @ gensec_security return
513 static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx,
514 struct gensec_settings *settings,
515 struct auth4_context *auth_context,
516 struct gensec_security **gensec_security)
518 (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security);
519 NT_STATUS_HAVE_NO_MEMORY(*gensec_security);
521 (*gensec_security)->max_update_size = UINT32_MAX;
523 SMB_ASSERT(settings->lp_ctx != NULL);
524 (*gensec_security)->settings = talloc_reference(*gensec_security, settings);
526 /* We need to reference this, not steal, as the caller may be
527 * python, which won't like it if we steal it's object away
529 (*gensec_security)->auth_context = talloc_reference(*gensec_security, auth_context);
535 * Start a GENSEC subcontext, with a copy of the properties of the parent
536 * @param mem_ctx The parent TALLOC memory context.
537 * @param parent The parent GENSEC context
538 * @param gensec_security Returned GENSEC context pointer.
539 * @note Used by SPNEGO in particular, for the actual implementation mechanism
542 _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx,
543 struct gensec_security *parent,
544 struct gensec_security **gensec_security)
546 (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security);
547 NT_STATUS_HAVE_NO_MEMORY(*gensec_security);
549 (**gensec_security) = *parent;
550 (*gensec_security)->ops = NULL;
551 (*gensec_security)->private_data = NULL;
553 (*gensec_security)->subcontext = true;
554 (*gensec_security)->want_features = parent->want_features;
555 (*gensec_security)->max_update_size = parent->max_update_size;
556 (*gensec_security)->dcerpc_auth_level = parent->dcerpc_auth_level;
557 (*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context);
558 (*gensec_security)->settings = talloc_reference(*gensec_security, parent->settings);
559 (*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context);
565 Start the GENSEC system, in client mode, returning a context pointer.
566 @param mem_ctx The parent TALLOC memory context.
567 @param gensec_security Returned GENSEC context pointer.
568 @note The mem_ctx is only a parent and may be NULL.
570 _PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx,
571 struct gensec_security **gensec_security,
572 struct gensec_settings *settings)
576 if (settings == NULL) {
577 DEBUG(0,("gensec_client_start: no settings given!\n"));
578 return NT_STATUS_INTERNAL_ERROR;
581 status = gensec_start(mem_ctx, settings, NULL, gensec_security);
582 if (!NT_STATUS_IS_OK(status)) {
585 (*gensec_security)->gensec_role = GENSEC_CLIENT;
593 Start the GENSEC system, in server mode, returning a context pointer.
594 @param mem_ctx The parent TALLOC memory context.
595 @param gensec_security Returned GENSEC context pointer.
596 @note The mem_ctx is only a parent and may be NULL.
598 _PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx,
599 struct gensec_settings *settings,
600 struct auth4_context *auth_context,
601 struct gensec_security **gensec_security)
606 DEBUG(0,("gensec_server_start: no settings given!\n"));
607 return NT_STATUS_INTERNAL_ERROR;
610 status = gensec_start(mem_ctx, settings, auth_context, gensec_security);
611 if (!NT_STATUS_IS_OK(status)) {
614 (*gensec_security)->gensec_role = GENSEC_SERVER;
619 NTSTATUS gensec_start_mech(struct gensec_security *gensec_security)
622 DEBUG(5, ("Starting GENSEC %smechanism %s\n",
623 gensec_security->subcontext ? "sub" : "",
624 gensec_security->ops->name));
625 switch (gensec_security->gensec_role) {
627 if (gensec_security->ops->client_start) {
628 status = gensec_security->ops->client_start(gensec_security);
629 if (!NT_STATUS_IS_OK(status)) {
630 DEBUG(gensec_security->subcontext?4:2, ("Failed to start GENSEC client mech %s: %s\n",
631 gensec_security->ops->name, nt_errstr(status)));
637 if (gensec_security->ops->server_start) {
638 status = gensec_security->ops->server_start(gensec_security);
639 if (!NT_STATUS_IS_OK(status)) {
640 DEBUG(1, ("Failed to start GENSEC server mech %s: %s\n",
641 gensec_security->ops->name, nt_errstr(status)));
647 return NT_STATUS_INVALID_PARAMETER;
651 * Start a GENSEC sub-mechanism with a specified mechansim structure, used in SPNEGO
655 NTSTATUS gensec_start_mech_by_ops(struct gensec_security *gensec_security,
656 const struct gensec_security_ops *ops)
658 gensec_security->ops = ops;
659 return gensec_start_mech(gensec_security);
664 * Start a GENSEC sub-mechanism by DCERPC allocated 'auth type' number
665 * @param gensec_security GENSEC context pointer.
666 * @param auth_type DCERPC auth type
667 * @param auth_level DCERPC auth level
670 _PUBLIC_ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security,
671 uint8_t auth_type, uint8_t auth_level)
673 gensec_security->ops = gensec_security_by_authtype(gensec_security, auth_type);
674 if (!gensec_security->ops) {
675 DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type));
676 return NT_STATUS_INVALID_PARAMETER;
678 gensec_security->dcerpc_auth_level = auth_level;
679 gensec_want_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE);
680 gensec_want_feature(gensec_security, GENSEC_FEATURE_ASYNC_REPLIES);
681 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
682 gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN);
683 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
684 gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN);
685 gensec_want_feature(gensec_security, GENSEC_FEATURE_SEAL);
686 } else if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
687 /* Default features */
689 DEBUG(2,("auth_level %d not supported in DCE/RPC authentication\n",
691 return NT_STATUS_INVALID_PARAMETER;
694 return gensec_start_mech(gensec_security);
697 _PUBLIC_ const char *gensec_get_name_by_authtype(struct gensec_security *gensec_security, uint8_t authtype)
699 const struct gensec_security_ops *ops;
700 ops = gensec_security_by_authtype(gensec_security, authtype);
708 _PUBLIC_ const char *gensec_get_name_by_oid(struct gensec_security *gensec_security,
709 const char *oid_string)
711 const struct gensec_security_ops *ops;
712 ops = gensec_security_by_oid(gensec_security, oid_string);
720 * Start a GENSEC sub-mechanism by OID, used in SPNEGO
722 * @note This should also be used when you wish to just start NLTMSSP (for example), as it uses a
723 * well-known #define to hook it in.
726 _PUBLIC_ NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security,
727 const char *mech_oid)
729 SMB_ASSERT(gensec_security != NULL);
731 gensec_security->ops = gensec_security_by_oid(gensec_security, mech_oid);
732 if (!gensec_security->ops) {
733 DEBUG(3, ("Could not find GENSEC backend for oid=%s\n", mech_oid));
734 return NT_STATUS_INVALID_PARAMETER;
736 return gensec_start_mech(gensec_security);
740 * Start a GENSEC sub-mechanism by a well know SASL name
744 _PUBLIC_ NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security,
745 const char *sasl_name)
747 gensec_security->ops = gensec_security_by_sasl_name(gensec_security, sasl_name);
748 if (!gensec_security->ops) {
749 DEBUG(3, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name));
750 return NT_STATUS_INVALID_PARAMETER;
752 return gensec_start_mech(gensec_security);
756 * Start a GENSEC sub-mechanism with the preferred option from a SASL name list
760 _PUBLIC_ NTSTATUS gensec_start_mech_by_sasl_list(struct gensec_security *gensec_security,
761 const char **sasl_names)
763 NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER;
764 TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
765 const struct gensec_security_ops **ops;
768 return NT_STATUS_NO_MEMORY;
770 ops = gensec_security_by_sasl_list(gensec_security, mem_ctx, sasl_names);
772 DEBUG(3, ("Could not find GENSEC backend for any of sasl_name = %s\n",
773 str_list_join(mem_ctx,
775 talloc_free(mem_ctx);
776 return NT_STATUS_INVALID_PARAMETER;
778 for (i=0; ops[i]; i++) {
779 nt_status = gensec_start_mech_by_ops(gensec_security, ops[i]);
780 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER)) {
784 talloc_free(mem_ctx);
789 * Start a GENSEC sub-mechanism by an internal name
793 _PUBLIC_ NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security,
796 gensec_security->ops = gensec_security_by_name(gensec_security, name);
797 if (!gensec_security->ops) {
798 DEBUG(3, ("Could not find GENSEC backend for name=%s\n", name));
799 return NT_STATUS_INVALID_PARAMETER;
801 return gensec_start_mech(gensec_security);
805 * Associate a credentials structure with a GENSEC context - talloc_reference()s it to the context
809 _PUBLIC_ NTSTATUS gensec_set_credentials(struct gensec_security *gensec_security, struct cli_credentials *credentials)
811 gensec_security->credentials = talloc_reference(gensec_security, credentials);
812 NT_STATUS_HAVE_NO_MEMORY(gensec_security->credentials);
813 gensec_want_feature(gensec_security, cli_credentials_get_gensec_features(gensec_security->credentials));
818 register a GENSEC backend.
820 The 'name' can be later used by other backends to find the operations
821 structure for this backend.
823 NTSTATUS gensec_register(const struct gensec_security_ops *ops)
825 if (gensec_security_by_name(NULL, ops->name) != NULL) {
826 /* its already registered! */
827 DEBUG(0,("GENSEC backend '%s' already registered\n",
829 return NT_STATUS_OBJECT_NAME_COLLISION;
832 generic_security_ops = talloc_realloc(talloc_autofree_context(),
833 generic_security_ops,
834 struct gensec_security_ops *,
835 gensec_num_backends+2);
836 if (!generic_security_ops) {
837 return NT_STATUS_NO_MEMORY;
840 generic_security_ops[gensec_num_backends] = discard_const_p(struct gensec_security_ops, ops);
841 gensec_num_backends++;
842 generic_security_ops[gensec_num_backends] = NULL;
844 DEBUG(3,("GENSEC backend '%s' registered\n",
851 return the GENSEC interface version, and the size of some critical types
852 This can be used by backends to either detect compilation errors, or provide
853 multiple implementations for different smbd compilation options in one module
855 const struct gensec_critical_sizes *gensec_interface_version(void)
857 static const struct gensec_critical_sizes critical_sizes = {
858 GENSEC_INTERFACE_VERSION,
859 sizeof(struct gensec_security_ops),
860 sizeof(struct gensec_security),
863 return &critical_sizes;
866 static int sort_gensec(struct gensec_security_ops **gs1, struct gensec_security_ops **gs2) {
867 return (*gs2)->priority - (*gs1)->priority;
870 int gensec_setting_int(struct gensec_settings *settings, const char *mechanism, const char *name, int default_value)
872 return lpcfg_parm_int(settings->lp_ctx, NULL, mechanism, name, default_value);
875 bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value)
877 return lpcfg_parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value);
881 initialise the GENSEC subsystem
883 _PUBLIC_ NTSTATUS gensec_init(void)
885 static bool initialized = false;
886 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
887 #ifdef STATIC_gensec_MODULES
888 STATIC_gensec_MODULES_PROTO;
889 init_module_fn static_init[] = { STATIC_gensec_MODULES };
891 init_module_fn *static_init = NULL;
893 init_module_fn *shared_init;
895 if (initialized) return NT_STATUS_OK;
898 shared_init = load_samba_modules(NULL, "gensec");
900 run_init_functions(static_init);
901 run_init_functions(shared_init);
903 talloc_free(shared_init);
905 TYPESAFE_QSORT(generic_security_ops, gensec_num_backends, sort_gensec);