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
*,
80 if (!new_gensec_list
) {
85 for (i
=0; old_gensec_list
&& old_gensec_list
[i
]; i
++) {
88 for (oid_idx
= 0; old_gensec_list
[i
]->oid
&& old_gensec_list
[i
]->oid
[oid_idx
]; oid_idx
++) {
89 if (strcmp(old_gensec_list
[i
]->oid
[oid_idx
], GENSEC_OID_SPNEGO
) == 0) {
90 new_gensec_list
[j
] = old_gensec_list
[i
];
95 switch (use_kerberos
) {
96 case CRED_DONT_USE_KERBEROS
:
97 if (old_gensec_list
[i
]->kerberos
== false) {
98 new_gensec_list
[j
] = old_gensec_list
[i
];
102 case CRED_MUST_USE_KERBEROS
:
103 if (old_gensec_list
[i
]->kerberos
== true) {
104 new_gensec_list
[j
] = old_gensec_list
[i
];
109 /* Can't happen or invalid parameter */
113 new_gensec_list
[j
] = NULL
;
115 return new_gensec_list
;
118 _PUBLIC_
struct gensec_security_ops
**gensec_security_mechs(
119 struct gensec_security
*gensec_security
,
122 struct gensec_security_ops
**backends
;
123 if (!gensec_security
) {
124 backends
= gensec_security_all();
125 if (!talloc_reference(mem_ctx
, backends
)) {
130 struct cli_credentials
*creds
= gensec_get_credentials(gensec_security
);
131 if (gensec_security
->settings
->backends
) {
132 backends
= gensec_security
->settings
->backends
;
134 backends
= gensec_security_all();
137 if (!talloc_reference(mem_ctx
, backends
)) {
142 return gensec_use_kerberos_mechs(mem_ctx
, backends
, creds
);
146 static const struct gensec_security_ops
*gensec_security_by_authtype(struct gensec_security
*gensec_security
,
150 struct gensec_security_ops
**backends
;
151 const struct gensec_security_ops
*backend
;
152 TALLOC_CTX
*mem_ctx
= talloc_new(gensec_security
);
156 backends
= gensec_security_mechs(gensec_security
, mem_ctx
);
157 for (i
=0; backends
&& backends
[i
]; i
++) {
158 if (!gensec_security_ops_enabled(backends
[i
], gensec_security
))
160 if (backends
[i
]->auth_type
== auth_type
) {
161 backend
= backends
[i
];
162 talloc_free(mem_ctx
);
166 talloc_free(mem_ctx
);
171 _PUBLIC_
const struct gensec_security_ops
*gensec_security_by_oid(
172 struct gensec_security
*gensec_security
,
173 const char *oid_string
)
176 struct gensec_security_ops
**backends
;
177 const struct gensec_security_ops
*backend
;
178 TALLOC_CTX
*mem_ctx
= talloc_new(gensec_security
);
182 backends
= gensec_security_mechs(gensec_security
, mem_ctx
);
183 for (i
=0; backends
&& backends
[i
]; i
++) {
184 if (gensec_security
!= NULL
&&
185 !gensec_security_ops_enabled(backends
[i
],
188 if (backends
[i
]->oid
) {
189 for (j
=0; backends
[i
]->oid
[j
]; j
++) {
190 if (backends
[i
]->oid
[j
] &&
191 (strcmp(backends
[i
]->oid
[j
], oid_string
) == 0)) {
192 backend
= backends
[i
];
193 talloc_free(mem_ctx
);
199 talloc_free(mem_ctx
);
204 _PUBLIC_
const struct gensec_security_ops
*gensec_security_by_sasl_name(
205 struct gensec_security
*gensec_security
,
206 const char *sasl_name
)
209 struct gensec_security_ops
**backends
;
210 const struct gensec_security_ops
*backend
;
211 TALLOC_CTX
*mem_ctx
= talloc_new(gensec_security
);
215 backends
= gensec_security_mechs(gensec_security
, mem_ctx
);
216 for (i
=0; backends
&& backends
[i
]; i
++) {
217 if (!gensec_security_ops_enabled(backends
[i
], gensec_security
))
219 if (backends
[i
]->sasl_name
220 && (strcmp(backends
[i
]->sasl_name
, sasl_name
) == 0)) {
221 backend
= backends
[i
];
222 talloc_free(mem_ctx
);
226 talloc_free(mem_ctx
);
231 static const struct gensec_security_ops
*gensec_security_by_name(struct gensec_security
*gensec_security
,
235 struct gensec_security_ops
**backends
;
236 const struct gensec_security_ops
*backend
;
237 TALLOC_CTX
*mem_ctx
= talloc_new(gensec_security
);
241 backends
= gensec_security_mechs(gensec_security
, mem_ctx
);
242 for (i
=0; backends
&& backends
[i
]; i
++) {
243 if (gensec_security
!= NULL
&&
244 !gensec_security_ops_enabled(backends
[i
], gensec_security
))
246 if (backends
[i
]->name
247 && (strcmp(backends
[i
]->name
, name
) == 0)) {
248 backend
= backends
[i
];
249 talloc_free(mem_ctx
);
253 talloc_free(mem_ctx
);
258 * Return a unique list of security subsystems from those specified in
259 * the list of SASL names.
261 * Use the list of enabled GENSEC mechanisms from the credentials
262 * attached to the gensec_security, and return in our preferred order.
265 const struct gensec_security_ops
**gensec_security_by_sasl_list(struct gensec_security
*gensec_security
,
267 const char **sasl_names
)
269 const struct gensec_security_ops
**backends_out
;
270 struct gensec_security_ops
**backends
;
272 int num_backends_out
= 0;
278 backends
= gensec_security_mechs(gensec_security
, mem_ctx
);
280 backends_out
= talloc_array(mem_ctx
, const struct gensec_security_ops
*, 1);
284 backends_out
[0] = NULL
;
286 /* Find backends in our preferred order, by walking our list,
287 * then looking in the supplied list */
288 for (i
=0; backends
&& backends
[i
]; i
++) {
289 if (gensec_security
!= NULL
&&
290 !gensec_security_ops_enabled(backends
[i
], gensec_security
))
292 for (sasl_idx
= 0; sasl_names
[sasl_idx
]; sasl_idx
++) {
293 if (!backends
[i
]->sasl_name
||
294 !(strcmp(backends
[i
]->sasl_name
,
295 sasl_names
[sasl_idx
]) == 0)) {
299 for (k
=0; backends_out
[k
]; k
++) {
300 if (backends_out
[k
] == backends
[i
]) {
305 if (k
< num_backends_out
) {
306 /* already in there */
310 backends_out
= talloc_realloc(mem_ctx
, backends_out
,
311 const struct gensec_security_ops
*,
312 num_backends_out
+ 2);
317 backends_out
[num_backends_out
] = backends
[i
];
319 backends_out
[num_backends_out
] = NULL
;
326 * Return a unique list of security subsystems from those specified in
327 * the OID list. That is, where two OIDs refer to the same module,
328 * return that module only once.
330 * Use the list of enabled GENSEC mechanisms from the credentials
331 * attached to the gensec_security, and return in our preferred order.
334 _PUBLIC_
const struct gensec_security_ops_wrapper
*gensec_security_by_oid_list(
335 struct gensec_security
*gensec_security
,
337 const char **oid_strings
,
340 struct gensec_security_ops_wrapper
*backends_out
;
341 struct gensec_security_ops
**backends
;
342 int i
, j
, k
, oid_idx
;
343 int num_backends_out
= 0;
349 backends
= gensec_security_mechs(gensec_security
, gensec_security
);
351 backends_out
= talloc_array(mem_ctx
, struct gensec_security_ops_wrapper
, 1);
355 backends_out
[0].op
= NULL
;
356 backends_out
[0].oid
= NULL
;
358 /* Find backends in our preferred order, by walking our list,
359 * then looking in the supplied list */
360 for (i
=0; backends
&& backends
[i
]; i
++) {
361 if (gensec_security
!= NULL
&&
362 !gensec_security_ops_enabled(backends
[i
], gensec_security
))
364 if (!backends
[i
]->oid
) {
367 for (oid_idx
= 0; oid_strings
[oid_idx
]; oid_idx
++) {
368 if (strcmp(oid_strings
[oid_idx
], skip
) == 0) {
372 for (j
=0; backends
[i
]->oid
[j
]; j
++) {
373 if (!backends
[i
]->oid
[j
] ||
374 !(strcmp(backends
[i
]->oid
[j
],
375 oid_strings
[oid_idx
]) == 0)) {
379 for (k
=0; backends_out
[k
].op
; k
++) {
380 if (backends_out
[k
].op
== backends
[i
]) {
385 if (k
< num_backends_out
) {
386 /* already in there */
390 backends_out
= talloc_realloc(mem_ctx
, backends_out
,
391 struct gensec_security_ops_wrapper
,
392 num_backends_out
+ 2);
397 backends_out
[num_backends_out
].op
= backends
[i
];
398 backends_out
[num_backends_out
].oid
= backends
[i
]->oid
[j
];
400 backends_out
[num_backends_out
].op
= NULL
;
401 backends_out
[num_backends_out
].oid
= NULL
;
409 * Return OIDS from the security subsystems listed
412 const char **gensec_security_oids_from_ops(struct gensec_security
*gensec_security
,
414 struct gensec_security_ops
**ops
,
420 const char **oid_list
;
424 oid_list
= talloc_array(mem_ctx
, const char *, 1);
429 for (i
=0; ops
&& ops
[i
]; i
++) {
430 if (gensec_security
!= NULL
&&
431 !gensec_security_ops_enabled(ops
[i
], gensec_security
)) {
438 for (k
= 0; ops
[i
]->oid
[k
]; k
++) {
439 if (skip
&& strcmp(skip
, ops
[i
]->oid
[k
])==0) {
441 oid_list
= talloc_realloc(mem_ctx
, oid_list
, const char *, j
+ 2);
445 oid_list
[j
] = ops
[i
]->oid
[k
];
456 * Return OIDS from the security subsystems listed
459 _PUBLIC_
const char **gensec_security_oids_from_ops_wrapped(TALLOC_CTX
*mem_ctx
,
460 const struct gensec_security_ops_wrapper
*wops
)
465 const char **oid_list
;
469 oid_list
= talloc_array(mem_ctx
, const char *, 1);
474 for (i
=0; wops
[i
].op
; i
++) {
475 if (!wops
[i
].op
->oid
) {
479 for (k
= 0; wops
[i
].op
->oid
[k
]; k
++) {
480 oid_list
= talloc_realloc(mem_ctx
, oid_list
, const char *, j
+ 2);
484 oid_list
[j
] = wops
[i
].op
->oid
[k
];
494 * Return all the security subsystems currently enabled on a GENSEC context.
496 * This is taken from a list attached to the cli_credentials, and
497 * skips the OID in 'skip'. (Typically the SPNEGO OID)
501 _PUBLIC_
const char **gensec_security_oids(struct gensec_security
*gensec_security
,
505 struct gensec_security_ops
**ops
506 = gensec_security_mechs(gensec_security
, mem_ctx
);
507 return gensec_security_oids_from_ops(gensec_security
, mem_ctx
, ops
, skip
);
511 Start the GENSEC system, returning a context pointer.
512 @param mem_ctx The parent TALLOC memory context.
513 @param gensec_security Returned GENSEC context pointer.
514 @note The mem_ctx is only a parent and may be NULL.
515 @note, the auth context is moved to be a referenced pointer of the
516 @ gensec_security return
518 static NTSTATUS
gensec_start(TALLOC_CTX
*mem_ctx
,
519 struct gensec_settings
*settings
,
520 struct auth4_context
*auth_context
,
521 struct gensec_security
**gensec_security
)
523 (*gensec_security
) = talloc_zero(mem_ctx
, struct gensec_security
);
524 NT_STATUS_HAVE_NO_MEMORY(*gensec_security
);
526 (*gensec_security
)->max_update_size
= 0;
528 SMB_ASSERT(settings
->lp_ctx
!= NULL
);
529 (*gensec_security
)->settings
= talloc_reference(*gensec_security
, settings
);
531 /* We need to reference this, not steal, as the caller may be
532 * python, which won't like it if we steal it's object away
534 (*gensec_security
)->auth_context
= talloc_reference(*gensec_security
, auth_context
);
540 * Start a GENSEC subcontext, with a copy of the properties of the parent
541 * @param mem_ctx The parent TALLOC memory context.
542 * @param parent The parent GENSEC context
543 * @param gensec_security Returned GENSEC context pointer.
544 * @note Used by SPNEGO in particular, for the actual implementation mechanism
547 _PUBLIC_ NTSTATUS
gensec_subcontext_start(TALLOC_CTX
*mem_ctx
,
548 struct gensec_security
*parent
,
549 struct gensec_security
**gensec_security
)
551 (*gensec_security
) = talloc_zero(mem_ctx
, struct gensec_security
);
552 NT_STATUS_HAVE_NO_MEMORY(*gensec_security
);
554 (**gensec_security
) = *parent
;
555 (*gensec_security
)->ops
= NULL
;
556 (*gensec_security
)->private_data
= NULL
;
558 (*gensec_security
)->subcontext
= true;
559 (*gensec_security
)->want_features
= parent
->want_features
;
560 (*gensec_security
)->max_update_size
= parent
->max_update_size
;
561 (*gensec_security
)->dcerpc_auth_level
= parent
->dcerpc_auth_level
;
562 (*gensec_security
)->auth_context
= talloc_reference(*gensec_security
, parent
->auth_context
);
563 (*gensec_security
)->settings
= talloc_reference(*gensec_security
, parent
->settings
);
564 (*gensec_security
)->auth_context
= talloc_reference(*gensec_security
, parent
->auth_context
);
570 Start the GENSEC system, in client mode, returning a context pointer.
571 @param mem_ctx The parent TALLOC memory context.
572 @param gensec_security Returned GENSEC context pointer.
573 @note The mem_ctx is only a parent and may be NULL.
575 _PUBLIC_ NTSTATUS
gensec_client_start(TALLOC_CTX
*mem_ctx
,
576 struct gensec_security
**gensec_security
,
577 struct gensec_settings
*settings
)
581 if (settings
== NULL
) {
582 DEBUG(0,("gensec_client_start: no settings given!\n"));
583 return NT_STATUS_INTERNAL_ERROR
;
586 status
= gensec_start(mem_ctx
, settings
, NULL
, gensec_security
);
587 if (!NT_STATUS_IS_OK(status
)) {
590 (*gensec_security
)->gensec_role
= GENSEC_CLIENT
;
598 Start the GENSEC system, in server mode, returning a context pointer.
599 @param mem_ctx The parent TALLOC memory context.
600 @param gensec_security Returned GENSEC context pointer.
601 @note The mem_ctx is only a parent and may be NULL.
603 _PUBLIC_ NTSTATUS
gensec_server_start(TALLOC_CTX
*mem_ctx
,
604 struct gensec_settings
*settings
,
605 struct auth4_context
*auth_context
,
606 struct gensec_security
**gensec_security
)
611 DEBUG(0,("gensec_server_start: no settings given!\n"));
612 return NT_STATUS_INTERNAL_ERROR
;
615 status
= gensec_start(mem_ctx
, settings
, auth_context
, gensec_security
);
616 if (!NT_STATUS_IS_OK(status
)) {
619 (*gensec_security
)->gensec_role
= GENSEC_SERVER
;
624 NTSTATUS
gensec_start_mech(struct gensec_security
*gensec_security
)
627 DEBUG(5, ("Starting GENSEC %smechanism %s\n",
628 gensec_security
->subcontext
? "sub" : "",
629 gensec_security
->ops
->name
));
630 switch (gensec_security
->gensec_role
) {
632 if (gensec_security
->ops
->client_start
) {
633 status
= gensec_security
->ops
->client_start(gensec_security
);
634 if (!NT_STATUS_IS_OK(status
)) {
635 DEBUG(gensec_security
->subcontext
?4:2, ("Failed to start GENSEC client mech %s: %s\n",
636 gensec_security
->ops
->name
, nt_errstr(status
)));
642 if (gensec_security
->ops
->server_start
) {
643 status
= gensec_security
->ops
->server_start(gensec_security
);
644 if (!NT_STATUS_IS_OK(status
)) {
645 DEBUG(1, ("Failed to start GENSEC server mech %s: %s\n",
646 gensec_security
->ops
->name
, nt_errstr(status
)));
652 return NT_STATUS_INVALID_PARAMETER
;
656 * Start a GENSEC sub-mechanism with a specified mechansim structure, used in SPNEGO
660 NTSTATUS
gensec_start_mech_by_ops(struct gensec_security
*gensec_security
,
661 const struct gensec_security_ops
*ops
)
663 gensec_security
->ops
= ops
;
664 return gensec_start_mech(gensec_security
);
669 * Start a GENSEC sub-mechanism by DCERPC allocated 'auth type' number
670 * @param gensec_security GENSEC context pointer.
671 * @param auth_type DCERPC auth type
672 * @param auth_level DCERPC auth level
675 _PUBLIC_ NTSTATUS
gensec_start_mech_by_authtype(struct gensec_security
*gensec_security
,
676 uint8_t auth_type
, uint8_t auth_level
)
678 gensec_security
->ops
= gensec_security_by_authtype(gensec_security
, auth_type
);
679 if (!gensec_security
->ops
) {
680 DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type
));
681 return NT_STATUS_INVALID_PARAMETER
;
683 gensec_security
->dcerpc_auth_level
= auth_level
;
684 gensec_want_feature(gensec_security
, GENSEC_FEATURE_DCE_STYLE
);
685 gensec_want_feature(gensec_security
, GENSEC_FEATURE_ASYNC_REPLIES
);
686 if (auth_level
== DCERPC_AUTH_LEVEL_INTEGRITY
) {
687 gensec_want_feature(gensec_security
, GENSEC_FEATURE_SIGN
);
688 } else if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
689 gensec_want_feature(gensec_security
, GENSEC_FEATURE_SIGN
);
690 gensec_want_feature(gensec_security
, GENSEC_FEATURE_SEAL
);
691 } else if (auth_level
== DCERPC_AUTH_LEVEL_CONNECT
) {
692 /* Default features */
694 DEBUG(2,("auth_level %d not supported in DCE/RPC authentication\n",
696 return NT_STATUS_INVALID_PARAMETER
;
699 return gensec_start_mech(gensec_security
);
702 _PUBLIC_
const char *gensec_get_name_by_authtype(struct gensec_security
*gensec_security
, uint8_t authtype
)
704 const struct gensec_security_ops
*ops
;
705 ops
= gensec_security_by_authtype(gensec_security
, authtype
);
713 _PUBLIC_
const char *gensec_get_name_by_oid(struct gensec_security
*gensec_security
,
714 const char *oid_string
)
716 const struct gensec_security_ops
*ops
;
717 ops
= gensec_security_by_oid(gensec_security
, oid_string
);
725 * Start a GENSEC sub-mechanism by OID, used in SPNEGO
727 * @note This should also be used when you wish to just start NLTMSSP (for example), as it uses a
728 * well-known #define to hook it in.
731 _PUBLIC_ NTSTATUS
gensec_start_mech_by_oid(struct gensec_security
*gensec_security
,
732 const char *mech_oid
)
734 SMB_ASSERT(gensec_security
!= NULL
);
736 gensec_security
->ops
= gensec_security_by_oid(gensec_security
, mech_oid
);
737 if (!gensec_security
->ops
) {
738 DEBUG(3, ("Could not find GENSEC backend for oid=%s\n", mech_oid
));
739 return NT_STATUS_INVALID_PARAMETER
;
741 return gensec_start_mech(gensec_security
);
745 * Start a GENSEC sub-mechanism by a well know SASL name
749 _PUBLIC_ NTSTATUS
gensec_start_mech_by_sasl_name(struct gensec_security
*gensec_security
,
750 const char *sasl_name
)
752 gensec_security
->ops
= gensec_security_by_sasl_name(gensec_security
, sasl_name
);
753 if (!gensec_security
->ops
) {
754 DEBUG(3, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name
));
755 return NT_STATUS_INVALID_PARAMETER
;
757 return gensec_start_mech(gensec_security
);
761 * Start a GENSEC sub-mechanism with the preferred option from a SASL name list
765 _PUBLIC_ NTSTATUS
gensec_start_mech_by_sasl_list(struct gensec_security
*gensec_security
,
766 const char **sasl_names
)
768 NTSTATUS nt_status
= NT_STATUS_INVALID_PARAMETER
;
769 TALLOC_CTX
*mem_ctx
= talloc_new(gensec_security
);
770 const struct gensec_security_ops
**ops
;
773 return NT_STATUS_NO_MEMORY
;
775 ops
= gensec_security_by_sasl_list(gensec_security
, mem_ctx
, sasl_names
);
777 DEBUG(3, ("Could not find GENSEC backend for any of sasl_name = %s\n",
778 str_list_join(mem_ctx
,
780 talloc_free(mem_ctx
);
781 return NT_STATUS_INVALID_PARAMETER
;
783 for (i
=0; ops
[i
]; i
++) {
784 nt_status
= gensec_start_mech_by_ops(gensec_security
, ops
[i
]);
785 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_INVALID_PARAMETER
)) {
789 talloc_free(mem_ctx
);
794 * Start a GENSEC sub-mechanism by an internal name
798 _PUBLIC_ NTSTATUS
gensec_start_mech_by_name(struct gensec_security
*gensec_security
,
801 gensec_security
->ops
= gensec_security_by_name(gensec_security
, name
);
802 if (!gensec_security
->ops
) {
803 DEBUG(3, ("Could not find GENSEC backend for name=%s\n", name
));
804 return NT_STATUS_INVALID_PARAMETER
;
806 return gensec_start_mech(gensec_security
);
810 * Associate a credentials structure with a GENSEC context - talloc_reference()s it to the context
814 _PUBLIC_ NTSTATUS
gensec_set_credentials(struct gensec_security
*gensec_security
, struct cli_credentials
*credentials
)
816 gensec_security
->credentials
= talloc_reference(gensec_security
, credentials
);
817 NT_STATUS_HAVE_NO_MEMORY(gensec_security
->credentials
);
818 gensec_want_feature(gensec_security
, cli_credentials_get_gensec_features(gensec_security
->credentials
));
823 register a GENSEC backend.
825 The 'name' can be later used by other backends to find the operations
826 structure for this backend.
828 _PUBLIC_ NTSTATUS
gensec_register(const struct gensec_security_ops
*ops
)
830 if (gensec_security_by_name(NULL
, ops
->name
) != NULL
) {
831 /* its already registered! */
832 DEBUG(0,("GENSEC backend '%s' already registered\n",
834 return NT_STATUS_OBJECT_NAME_COLLISION
;
837 generic_security_ops
= talloc_realloc(talloc_autofree_context(),
838 generic_security_ops
,
839 struct gensec_security_ops
*,
840 gensec_num_backends
+2);
841 if (!generic_security_ops
) {
842 return NT_STATUS_NO_MEMORY
;
845 generic_security_ops
[gensec_num_backends
] = discard_const_p(struct gensec_security_ops
, ops
);
846 gensec_num_backends
++;
847 generic_security_ops
[gensec_num_backends
] = NULL
;
849 DEBUG(3,("GENSEC backend '%s' registered\n",
856 return the GENSEC interface version, and the size of some critical types
857 This can be used by backends to either detect compilation errors, or provide
858 multiple implementations for different smbd compilation options in one module
860 const struct gensec_critical_sizes
*gensec_interface_version(void)
862 static const struct gensec_critical_sizes critical_sizes
= {
863 GENSEC_INTERFACE_VERSION
,
864 sizeof(struct gensec_security_ops
),
865 sizeof(struct gensec_security
),
868 return &critical_sizes
;
871 static int sort_gensec(struct gensec_security_ops
**gs1
, struct gensec_security_ops
**gs2
) {
872 return (*gs2
)->priority
- (*gs1
)->priority
;
875 int gensec_setting_int(struct gensec_settings
*settings
, const char *mechanism
, const char *name
, int default_value
)
877 return lpcfg_parm_int(settings
->lp_ctx
, NULL
, mechanism
, name
, default_value
);
880 bool gensec_setting_bool(struct gensec_settings
*settings
, const char *mechanism
, const char *name
, bool default_value
)
882 return lpcfg_parm_bool(settings
->lp_ctx
, NULL
, mechanism
, name
, default_value
);
886 initialise the GENSEC subsystem
888 _PUBLIC_ NTSTATUS
gensec_init(void)
890 static bool initialized
= false;
891 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
892 #ifdef STATIC_gensec_MODULES
893 STATIC_gensec_MODULES_PROTO
;
894 init_module_fn static_init
[] = { STATIC_gensec_MODULES
};
896 init_module_fn
*static_init
= NULL
;
898 init_module_fn
*shared_init
;
900 if (initialized
) return NT_STATUS_OK
;
903 shared_init
= load_samba_modules(NULL
, "gensec");
905 run_init_functions(static_init
);
906 run_init_functions(shared_init
);
908 talloc_free(shared_init
);
910 TYPESAFE_QSORT(generic_security_ops
, gensec_num_backends
, sort_gensec
);