mirror of
https://github.com/samba-team/samba.git
synced 2025-01-14 19:24:43 +03:00
Add the beginings of sam_ads to the tree.
This module, primarilly the work of "Stefan (metze) Metzmacher" <metze@metzemix.de>, uses the Active Directory schema to store the user/group/other information. I've been testing it against a real AD server, and it is intended to work with OpenLDAP as well. I've moved a few functions around in our other libads code, which has made it easier to tap into that existing code. Also, I've made some changes to the SAM interface, I hope there are not too many objections... To ensure we don't get silly bugs in the skel module, it is now in the default compile. This way you should not forget to update it :-) Andrew Bartlett
This commit is contained in:
parent
df906c156a
commit
24fb0cde2f
source
@ -221,7 +221,7 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
|
||||
passdb/pdb_unix.o passdb/util_sam_sid.o \
|
||||
passdb/pdb_compat.o passdb/pdb_nisplus.o
|
||||
|
||||
SAM_STATIC_MODULES = sam/sam_plugin.o
|
||||
SAM_STATIC_MODULES = sam/sam_plugin.o sam/sam_skel.o sam/sam_ads.o
|
||||
|
||||
SAM_OBJ = sam/account.o sam/get_set_account.o sam/get_set_group.o \
|
||||
sam/get_set_domain.o sam/interface.o sam/api.o $(SAM_STATIC_MODULES)
|
||||
|
@ -15,6 +15,7 @@ typedef struct {
|
||||
char *realm;
|
||||
char *workgroup;
|
||||
char *ldap_server;
|
||||
char *ldap_uri;
|
||||
int foreign; /* set to 1 if connecting to a foreign realm */
|
||||
} server;
|
||||
|
||||
@ -255,5 +256,7 @@ typedef void **ADS_MODLIST;
|
||||
|
||||
|
||||
/* ads auth control flags */
|
||||
#define ADS_AUTH_DISABLE_KERBEROS 1
|
||||
#define ADS_AUTH_NO_BIND 2
|
||||
#define ADS_AUTH_DISABLE_KERBEROS 0x01
|
||||
#define ADS_AUTH_NO_BIND 0x02
|
||||
#define ADS_AUTH_ANON_BIND 0x04
|
||||
#define ADS_AUTH_SIMPLE_BIND 0x08
|
||||
|
@ -167,8 +167,8 @@ typedef struct sam_context
|
||||
NTSTATUS (*sam_get_sec_desc) (const struct sam_context *, const NT_USER_TOKEN *access_token, const DOM_SID *sid, SEC_DESC **sd);
|
||||
NTSTATUS (*sam_set_sec_desc) (const struct sam_context *, const NT_USER_TOKEN *access_token, const DOM_SID *sid, const SEC_DESC *sd);
|
||||
|
||||
NTSTATUS (*sam_lookup_sid) (const struct sam_context *, const NT_USER_TOKEN *access_token, const DOM_SID *sid, char **name, uint32 *type);
|
||||
NTSTATUS (*sam_lookup_name) (const struct sam_context *, const NT_USER_TOKEN *access_token, const char *domain, const char *name, DOM_SID **sid, uint32 *type);
|
||||
NTSTATUS (*sam_lookup_sid) (const struct sam_context *, const NT_USER_TOKEN *access_token, TALLOC_CTX *ctx, const DOM_SID *sid, char **name, uint32 *type);
|
||||
NTSTATUS (*sam_lookup_name) (const struct sam_context *, const NT_USER_TOKEN *access_token, const char *domain, const char *name, DOM_SID *sid, uint32 *type);
|
||||
|
||||
|
||||
/* Domain API */
|
||||
@ -183,7 +183,7 @@ typedef struct sam_context
|
||||
|
||||
/* Account API */
|
||||
|
||||
NTSTATUS (*sam_create_account) (const struct sam_context *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *domainsid, const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account);
|
||||
NTSTATUS (*sam_create_account) (const struct sam_context *context, const NT_USER_TOKEN *access_token, uint32 access_desired, TALLOC_CTX *mem_ctx, const DOM_SID *domainsid, const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account);
|
||||
NTSTATUS (*sam_add_account) (const struct sam_context *, const DOM_SID *domainsid, const SAM_ACCOUNT_HANDLE *account);
|
||||
NTSTATUS (*sam_update_account) (const struct sam_context *, const SAM_ACCOUNT_HANDLE *account);
|
||||
NTSTATUS (*sam_delete_account) (const struct sam_context *, const SAM_ACCOUNT_HANDLE *account);
|
||||
@ -225,8 +225,8 @@ typedef struct sam_methods
|
||||
NTSTATUS (*sam_get_sec_desc) (const struct sam_methods *, const NT_USER_TOKEN *access_token, const DOM_SID *sid, SEC_DESC **sd);
|
||||
NTSTATUS (*sam_set_sec_desc) (const struct sam_methods *, const NT_USER_TOKEN *access_token, const DOM_SID *sid, const SEC_DESC *sd);
|
||||
|
||||
NTSTATUS (*sam_lookup_sid) (const struct sam_methods *, const NT_USER_TOKEN *access_token, const DOM_SID *sid, char **name, uint32 *type);
|
||||
NTSTATUS (*sam_lookup_name) (const struct sam_methods *, const NT_USER_TOKEN *access_token, const char *name, DOM_SID **sid, uint32 *type);
|
||||
NTSTATUS (*sam_lookup_sid) (const struct sam_methods *, const NT_USER_TOKEN *access_token, TALLOC_CTX *mem_ctx, const DOM_SID *sid, char **name, uint32 *type);
|
||||
NTSTATUS (*sam_lookup_name) (const struct sam_methods *, const NT_USER_TOKEN *access_token, const char *name, DOM_SID *sid, uint32 *type);
|
||||
|
||||
/* Domain API */
|
||||
|
||||
@ -235,7 +235,7 @@ typedef struct sam_methods
|
||||
|
||||
/* Account API */
|
||||
|
||||
NTSTATUS (*sam_create_account) (const struct sam_methods *, const NT_USER_TOKEN *access_token, uint32 access_desired, const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account);
|
||||
NTSTATUS (*sam_create_account) (const struct sam_methods *, const NT_USER_TOKEN *access_token, uint32 access_desired, TALLOC_CTX *mem_ctx, const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account);
|
||||
NTSTATUS (*sam_add_account) (const struct sam_methods *, const SAM_ACCOUNT_HANDLE *account);
|
||||
NTSTATUS (*sam_update_account) (const struct sam_methods *, const SAM_ACCOUNT_HANDLE *account);
|
||||
NTSTATUS (*sam_delete_account) (const struct sam_methods *, const SAM_ACCOUNT_HANDLE *account);
|
||||
|
@ -83,7 +83,7 @@ done:
|
||||
/* convert a sid to a user or group name */
|
||||
NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
DOM_SID *sid,
|
||||
const DOM_SID *sid,
|
||||
char **name,
|
||||
enum SID_NAME_USE *type)
|
||||
{
|
||||
|
@ -122,6 +122,7 @@ void ads_destroy(ADS_STRUCT **ads)
|
||||
SAFE_FREE((*ads)->server.realm);
|
||||
SAFE_FREE((*ads)->server.workgroup);
|
||||
SAFE_FREE((*ads)->server.ldap_server);
|
||||
SAFE_FREE((*ads)->server.ldap_uri);
|
||||
|
||||
SAFE_FREE((*ads)->auth.realm);
|
||||
SAFE_FREE((*ads)->auth.password);
|
||||
|
@ -67,6 +67,29 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
try a connection to a given ldap server, based on URL, returning True if successful
|
||||
*/
|
||||
static BOOL ads_try_connect_uri(ADS_STRUCT *ads)
|
||||
{
|
||||
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
|
||||
DEBUG(5,("ads_try_connect: trying ldap server at URI '%s'\n",
|
||||
ads->server.ldap_uri));
|
||||
|
||||
|
||||
if (ldap_initialize((LDAP**)&(ads->ld), ads->server.ldap_uri) == LDAP_SUCCESS) {
|
||||
return True;
|
||||
}
|
||||
DEBUG(0, ("ldap_initialize: %s\n", strerror(errno)));
|
||||
|
||||
#else
|
||||
|
||||
DEBUG(1, ("no URL support in LDAP libs!\n"));
|
||||
#endif
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/* used by the IP comparison function */
|
||||
struct ldap_ip {
|
||||
struct in_addr ip;
|
||||
@ -210,6 +233,13 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
|
||||
ads->last_attempt = time(NULL);
|
||||
ads->ld = NULL;
|
||||
|
||||
/* try with a URL based server */
|
||||
|
||||
if (ads->server.ldap_uri &&
|
||||
ads_try_connect_uri(ads)) {
|
||||
goto got_connection;
|
||||
}
|
||||
|
||||
/* try with a user specified server */
|
||||
if (ads->server.ldap_server &&
|
||||
ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) {
|
||||
@ -278,6 +308,14 @@ got_connection:
|
||||
return ADS_SUCCESS;
|
||||
}
|
||||
|
||||
if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
|
||||
return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL));
|
||||
}
|
||||
|
||||
if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) {
|
||||
return ADS_ERROR(ldap_simple_bind_s( ads->ld, ads->auth.user_name, ads->auth.password));
|
||||
}
|
||||
|
||||
return ads_sasl_bind(ads);
|
||||
}
|
||||
|
||||
@ -1771,8 +1809,9 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
|
||||
ads->config.realm = strdup(p+2);
|
||||
ads->config.bind_path = ads_build_dn(ads->config.realm);
|
||||
|
||||
DEBUG(3,("got ldap server name %s@%s\n",
|
||||
ads->config.ldap_server_name, ads->config.realm));
|
||||
DEBUG(3,("got ldap server name %s@%s, using bind path: %s\n",
|
||||
ads->config.ldap_server_name, ads->config.realm,
|
||||
ads->config.bind_path));
|
||||
|
||||
ads->config.current_time = ads_parse_time(timestr);
|
||||
|
||||
|
@ -42,6 +42,9 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope
|
||||
|
||||
bp = strdup(bind_path);
|
||||
|
||||
if (!bp)
|
||||
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
|
||||
while (count--) {
|
||||
status = ads_do_search_all(ads, bp, scope, exp, attrs, res);
|
||||
if (ADS_ERR_OK(status)) {
|
||||
|
@ -50,7 +50,7 @@ NTSTATUS sam_set_sec_desc(const NT_USER_TOKEN *access_token, const DOM_SID *sid,
|
||||
return sam_context->sam_set_sec_desc(sam_context, access_token, sid, sd);
|
||||
}
|
||||
|
||||
NTSTATUS sam_lookup_sid(const NT_USER_TOKEN *access_token, const DOM_SID *sid, char **name, uint32 *type)
|
||||
NTSTATUS sam_lookup_sid(const NT_USER_TOKEN *access_token, TALLOC_CTX *mem_ctx, const DOM_SID *sid, char **name, uint32 *type)
|
||||
{
|
||||
SAM_CONTEXT *sam_context = sam_get_static_context(False);
|
||||
|
||||
@ -58,10 +58,10 @@ NTSTATUS sam_lookup_sid(const NT_USER_TOKEN *access_token, const DOM_SID *sid, c
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return sam_context->sam_lookup_sid(sam_context, access_token, sid, name, type);
|
||||
return sam_context->sam_lookup_sid(sam_context, access_token, mem_ctx, sid, name, type);
|
||||
}
|
||||
|
||||
NTSTATUS sam_lookup_name(const NT_USER_TOKEN *access_token, const char *domain, const char *name, DOM_SID **sid, uint32 *type)
|
||||
NTSTATUS sam_lookup_name(const NT_USER_TOKEN *access_token, const char *domain, const char *name, DOM_SID *sid, uint32 *type)
|
||||
{
|
||||
SAM_CONTEXT *sam_context = sam_get_static_context(False);
|
||||
|
||||
@ -69,7 +69,7 @@ NTSTATUS sam_lookup_name(const NT_USER_TOKEN *access_token, const char *domain,
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return sam_context->sam_lookup_name(sam_context, access_token, domain, name, sid, type);
|
||||
return sam_context->sam_lookup_name(sam_context, access_token,domain, name, sid, type);
|
||||
}
|
||||
|
||||
/* Domain API */
|
||||
@ -120,7 +120,7 @@ NTSTATUS sam_get_domain_by_sid(const NT_USER_TOKEN *access_token, const uint32 a
|
||||
|
||||
/* Account API */
|
||||
|
||||
NTSTATUS sam_create_account(const NT_USER_TOKEN *access_token, const uint32 access_desired, const DOM_SID *domainsid, const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account)
|
||||
NTSTATUS sam_create_account(const NT_USER_TOKEN *access_token, const uint32 access_desired, TALLOC_CTX *mem_ctx, const DOM_SID *domainsid, const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account)
|
||||
{
|
||||
SAM_CONTEXT *sam_context = sam_get_static_context(False);
|
||||
|
||||
@ -128,7 +128,7 @@ NTSTATUS sam_create_account(const NT_USER_TOKEN *access_token, const uint32 acce
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return sam_context->sam_create_account(sam_context, access_token, access_desired, domainsid, account_name, acct_ctrl, account);
|
||||
return sam_context->sam_create_account(sam_context, access_token, access_desired, mem_ctx, domainsid, account_name, acct_ctrl, account);
|
||||
}
|
||||
|
||||
NTSTATUS sam_add_account(const DOM_SID *domainsid, const SAM_ACCOUNT_HANDLE *account)
|
||||
|
@ -32,6 +32,8 @@ extern DOM_SID global_sid_Builtin;
|
||||
|
||||
const struct sam_init_function_entry builtin_sam_init_functions[] = {
|
||||
{ "plugin", sam_init_plugin },
|
||||
{ "ads", sam_init_ads },
|
||||
{ "skel", sam_init_skel },
|
||||
{ NULL, NULL}
|
||||
};
|
||||
|
||||
@ -79,7 +81,7 @@ NTSTATUS sam_get_methods_by_name(const SAM_CONTEXT *context, SAM_METHODS **sam_m
|
||||
tmp_methods = context->methods;
|
||||
|
||||
while (tmp_methods) {
|
||||
if (!strcmp(domainname, tmp_methods->domain_name))
|
||||
if (strequal(domainname, tmp_methods->domain_name))
|
||||
{
|
||||
(*sam_method) = tmp_methods;
|
||||
return NT_STATUS_OK;
|
||||
@ -143,7 +145,7 @@ NTSTATUS context_sam_set_sec_desc(const SAM_CONTEXT *context, const NT_USER_TOKE
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS context_sam_lookup_name(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const char *domain, const char *name, DOM_SID **sid, uint32 *type)
|
||||
NTSTATUS context_sam_lookup_name(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const char *domain, const char *name, DOM_SID *sid, uint32 *type)
|
||||
{
|
||||
SAM_METHODS *tmp_methods;
|
||||
NTSTATUS nt_status;
|
||||
@ -169,7 +171,7 @@ NTSTATUS context_sam_lookup_name(const SAM_CONTEXT *context, const NT_USER_TOKEN
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS context_sam_lookup_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, const DOM_SID *sid, char **name, uint32 *type)
|
||||
NTSTATUS context_sam_lookup_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, TALLOC_CTX *mem_ctx, const DOM_SID *sid, char **name, uint32 *type)
|
||||
{
|
||||
SAM_METHODS *tmp_methods;
|
||||
uint32 rid;
|
||||
@ -194,7 +196,7 @@ NTSTATUS context_sam_lookup_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_lookup_sid(tmp_methods, access_token, sid, name, type))) {
|
||||
if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_lookup_sid(tmp_methods, access_token, mem_ctx, sid, name, type))) {
|
||||
DEBUG(4,("sam_lookup_name for %s in backend %s failed\n",
|
||||
sid_string_static(sid), tmp_methods->backendname));
|
||||
return nt_status;
|
||||
@ -354,7 +356,7 @@ NTSTATUS context_sam_get_domain_by_sid(const SAM_CONTEXT *context, const NT_USER
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS context_sam_create_account(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID *domainsid, const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account)
|
||||
NTSTATUS context_sam_create_account(const SAM_CONTEXT *context, const NT_USER_TOKEN *access_token, uint32 access_desired, TALLOC_CTX *mem_ctx, const DOM_SID *domainsid, const char *account_name, uint16 acct_ctrl, SAM_ACCOUNT_HANDLE **account)
|
||||
{
|
||||
SAM_METHODS *tmp_methods;
|
||||
NTSTATUS nt_status;
|
||||
@ -371,7 +373,7 @@ NTSTATUS context_sam_create_account(const SAM_CONTEXT *context, const NT_USER_TO
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_create_account(tmp_methods, access_token, access_desired, account_name, acct_ctrl, account))) {
|
||||
if (!NT_STATUS_IS_OK(nt_status = tmp_methods->sam_create_account(tmp_methods, access_token, access_desired, mem_ctx, account_name, acct_ctrl, account))) {
|
||||
DEBUG(4,("sam_create_account in backend %s failed\n",
|
||||
tmp_methods->backendname));
|
||||
return nt_status;
|
||||
@ -924,21 +926,21 @@ static NTSTATUS make_backend_entry(SAM_BACKEND_ENTRY *backend_entry, char *sam_b
|
||||
if ((tmp = strchr(tmp_string, '|')) != NULL) {
|
||||
DEBUGADD(20,("a domain name has been specified\n"));
|
||||
*tmp = 0;
|
||||
backend_entry->domain_name = tmp + 1;
|
||||
backend_entry->domain_name = smb_xstrdup(tmp + 1);
|
||||
tmp_string = tmp + 1;
|
||||
}
|
||||
|
||||
if ((tmp = strchr(tmp_string, ':')) != NULL) {
|
||||
DEBUG(20,("options for the backend have been specified\n"));
|
||||
*tmp = 0;
|
||||
backend_entry->module_params = tmp + 1;
|
||||
backend_entry->module_params = smb_xstrdup(tmp + 1);
|
||||
tmp_string = tmp + 1;
|
||||
}
|
||||
|
||||
if (backend_entry->domain_name == NULL) {
|
||||
DEBUG(10,("make_backend_entry: no domain was specified for sam module %s. Useing default domain %s\n",
|
||||
backend_entry->module_name, lp_workgroup()));
|
||||
backend_entry->domain_name = lp_workgroup();
|
||||
backend_entry->domain_name = smb_xstrdup(lp_workgroup());
|
||||
}
|
||||
|
||||
if ((backend_entry->domain_sid = (DOM_SID *)malloc(sizeof(DOM_SID))) == NULL) {
|
||||
@ -1109,11 +1111,12 @@ NTSTATUS make_sam_context_list(SAM_CONTEXT **context, char **sam_backends_param)
|
||||
|
||||
DEBUG(6,("There are %d domains listed with there backends\n", nBackends));
|
||||
|
||||
if ((backends = (SAM_BACKEND_ENTRY *)malloc(sizeof(SAM_BACKEND_ENTRY)*nBackends)) == NULL) {
|
||||
if ((backends = (SAM_BACKEND_ENTRY *)malloc(sizeof(*backends)*nBackends)) == NULL) {
|
||||
DEBUG(0,("make_sam_context_list: failed to allocate backends\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
ZERO_STRUCTP(backends);
|
||||
|
||||
memset(backends, '\0', sizeof(*backends)*nBackends);
|
||||
|
||||
for (i = 0; i < nBackends; i++) {
|
||||
DEBUG(8,("processing %s\n",sam_backends_param[i]));
|
||||
|
1080
source/sam/sam_ads.c
Executable file
1080
source/sam/sam_ads.c
Executable file
File diff suppressed because it is too large
Load Diff
@ -99,7 +99,7 @@ static NTSTATUS cmd_lookup_sid(struct samtest_state *st, TALLOC_CTX *mem_ctx, in
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status = context_sam_lookup_sid(st->context, st->token, &sid, &name, &type))) {
|
||||
if (!NT_STATUS_IS_OK(status = context_sam_lookup_sid(st->context, st->token, mem_ctx, &sid, &name, &type))) {
|
||||
printf("context_sam_lookup_sid failed!\n");
|
||||
return status;
|
||||
}
|
||||
@ -112,7 +112,7 @@ static NTSTATUS cmd_lookup_sid(struct samtest_state *st, TALLOC_CTX *mem_ctx, in
|
||||
|
||||
static NTSTATUS cmd_lookup_name(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
|
||||
{
|
||||
DOM_SID *sid;
|
||||
DOM_SID sid;
|
||||
uint32 type;
|
||||
NTSTATUS status;
|
||||
if (argc != 3) {
|
||||
@ -125,7 +125,7 @@ static NTSTATUS cmd_lookup_name(struct samtest_state *st, TALLOC_CTX *mem_ctx, i
|
||||
return status;
|
||||
}
|
||||
|
||||
printf("SID: %s\n", sid_string_static(sid));
|
||||
printf("SID: %s\n", sid_string_static(&sid));
|
||||
printf("Type: %d\n", type);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
|
Loading…
x
Reference in New Issue
Block a user