diff options
Diffstat (limited to 'source3/winbindd/idmap_ad.c')
-rw-r--r-- | source3/winbindd/idmap_ad.c | 260 |
1 files changed, 239 insertions, 21 deletions
diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c index 9fefb1bba7..60a2d8642a 100644 --- a/source3/winbindd/idmap_ad.c +++ b/source3/winbindd/idmap_ad.c @@ -517,6 +517,8 @@ again: bidx = idx; for (i = 0; (i < IDMAP_AD_MAX_IDS) && ids[idx]; i++, idx++) { + ids[idx]->status = ID_UNKNOWN; + sidstr = sid_binstring(ids[idx]->sid); filter = talloc_asprintf_append_buffer(filter, "(objectSid=%s)", sidstr); @@ -732,6 +734,16 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e, uint32 *gid ) { ADS_STRUCT *ads_internal = NULL; + const char *attrs[] = {NULL, /* attr_homedir */ + NULL, /* attr_shell */ + NULL, /* attr_gecos */ + NULL, /* attr_gidnumber */ + NULL }; + char *filter = NULL; + LDAPMessage *msg_internal = NULL; + ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + char *sidstr = NULL; /* Only do query if we are online */ if (idmap_is_offline()) { @@ -743,24 +755,224 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e, ads_internal = ad_idmap_cached_connection(); - if ( !ads_internal || !ad_schema ) + if ( !ads_internal || !ad_schema ) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; - - if ( !homedir || !shell || !gecos ) + } + + if (!sid || !homedir || !shell || !gecos) { return NT_STATUS_INVALID_PARAMETER; + } + + /* See if we can use the ADS connection struct swe were given */ - *homedir = ads_pull_string( ads, ctx, msg, ad_schema->posix_homedir_attr ); - *shell = ads_pull_string( ads, ctx, msg, ad_schema->posix_shell_attr ); - *gecos = ads_pull_string( ads, ctx, msg, ad_schema->posix_gecos_attr ); - - if ( gid ) { - if ( !ads_pull_uint32(ads, msg, ad_schema->posix_gidnumber_attr, gid ) ) - *gid = (uint32)-1; + if (ads) { + *homedir = ads_pull_string( ads, ctx, msg, ad_schema->posix_homedir_attr ); + *shell = ads_pull_string( ads, ctx, msg, ad_schema->posix_shell_attr ); + *gecos = ads_pull_string( ads, ctx, msg, ad_schema->posix_gecos_attr ); + + if (gid) { + if ( !ads_pull_uint32(ads, msg, ad_schema->posix_gidnumber_attr, gid ) ) + *gid = (uint32)-1; + } + + nt_status = NT_STATUS_OK; + goto done; } - - return NT_STATUS_OK; + + /* Have to do our own query */ + + attrs[0] = ad_schema->posix_homedir_attr; + attrs[1] = ad_schema->posix_shell_attr; + attrs[2] = ad_schema->posix_gecos_attr; + attrs[3] = ad_schema->posix_gidnumber_attr; + + sidstr = sid_binstring(sid); + filter = talloc_asprintf(ctx, "(objectSid=%s)", sidstr); + SAFE_FREE(sidstr); + + if (!filter) { + nt_status = NT_STATUS_NO_MEMORY; + goto done; + } + + ads_status = ads_search_retry(ads_internal, &msg_internal, filter, attrs); + if (!ADS_ERR_OK(ads_status)) { + nt_status = ads_ntstatus(ads_status); + goto done; + } + + *homedir = ads_pull_string(ads_internal, ctx, msg_internal, ad_schema->posix_homedir_attr); + *shell = ads_pull_string(ads_internal, ctx, msg_internal, ad_schema->posix_shell_attr); + *gecos = ads_pull_string(ads_internal, ctx, msg_internal, ad_schema->posix_gecos_attr); + + if (gid) { + if (!ads_pull_uint32(ads_internal, msg_internal, ad_schema->posix_gidnumber_attr, gid)) + *gid = (uint32)-1; + } + + nt_status = NT_STATUS_OK; + +done: + if (msg_internal) { + ads_msgfree(ads_internal, msg_internal); + } + + return nt_status; } +/********************************************************************** + *********************************************************************/ + +static NTSTATUS nss_ad_map_to_alias(TALLOC_CTX *mem_ctx, + const char *domain, + const char *name, + char **alias) +{ + ADS_STRUCT *ads_internal = NULL; + const char *attrs[] = {NULL, /* attr_uid */ + NULL }; + char *filter = NULL; + LDAPMessage *msg = NULL; + ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + + /* Check incoming parameters */ + + if ( !domain || !name || !*alias) { + nt_status = NT_STATUS_INVALID_PARAMETER; + goto done; + } + + /* Only do query if we are online */ + + if (idmap_is_offline()) { + nt_status = NT_STATUS_FILE_IS_OFFLINE; + goto done; + } + + ads_internal = ad_idmap_cached_connection(); + + if (!ads_internal || !ad_schema) { + nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND; + goto done; + } + + attrs[0] = ad_schema->posix_uid_attr; + + filter = talloc_asprintf(mem_ctx, + "(sAMAccountName=%s)", + name); + if (!filter) { + nt_status = NT_STATUS_NO_MEMORY; + goto done; + } + + ads_status = ads_search_retry(ads_internal, &msg, filter, attrs); + if (!ADS_ERR_OK(ads_status)) { + nt_status = ads_ntstatus(ads_status); + goto done; + } + + *alias = ads_pull_string(ads_internal, mem_ctx, msg, ad_schema->posix_uid_attr ); + + if (!*alias) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + nt_status = NT_STATUS_OK; + +done: + if (filter) { + talloc_destroy(filter); + } + if (msg) { + ads_msgfree(ads_internal, msg); + } + + return nt_status; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS nss_ad_map_from_alias( TALLOC_CTX *mem_ctx, + const char *domain, + const char *alias, + char **name ) +{ + ADS_STRUCT *ads_internal = NULL; + const char *attrs[] = {"sAMAccountName", + NULL }; + char *filter = NULL; + LDAPMessage *msg = NULL; + ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + char *username; + + /* Check incoming parameters */ + + if ( !alias || !name) { + nt_status = NT_STATUS_INVALID_PARAMETER; + goto done; + } + + /* Only do query if we are online */ + + if (idmap_is_offline()) { + nt_status = NT_STATUS_FILE_IS_OFFLINE; + goto done; + } + + ads_internal = ad_idmap_cached_connection(); + + if (!ads_internal || !ad_schema) { + nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND; + goto done; + } + + filter = talloc_asprintf(mem_ctx, + "(%s=%s)", + ad_schema->posix_uid_attr, + alias); + if (!filter) { + nt_status = NT_STATUS_NO_MEMORY; + goto done; + } + + ads_status = ads_search_retry(ads_internal, &msg, filter, attrs); + if (!ADS_ERR_OK(ads_status)) { + nt_status = ads_ntstatus(ads_status); + goto done; + } + + username = ads_pull_string(ads_internal, mem_ctx, msg, + "sAMAccountName"); + if (!username) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + *name = talloc_asprintf(mem_ctx, "%s\\%s", + lp_workgroup(), + username); + if (!*name) { + nt_status = NT_STATUS_NO_MEMORY; + goto done; + } + + nt_status = NT_STATUS_OK; + +done: + if (filter) { + talloc_destroy(filter); + } + if (msg) { + ads_msgfree(ads_internal, msg); + } + + return nt_status; +} + + /************************************************************************ ***********************************************************************/ @@ -786,21 +998,27 @@ static struct idmap_methods ad_methods = { function which sets the intended schema model to use */ static struct nss_info_methods nss_rfc2307_methods = { - .init = nss_rfc2307_init, - .get_nss_info = nss_ad_get_info, - .close_fn = nss_ad_close + .init = nss_rfc2307_init, + .get_nss_info = nss_ad_get_info, + .map_to_alias = nss_ad_map_to_alias, + .map_from_alias = nss_ad_map_from_alias, + .close_fn = nss_ad_close }; static struct nss_info_methods nss_sfu_methods = { - .init = nss_sfu_init, - .get_nss_info = nss_ad_get_info, - .close_fn = nss_ad_close + .init = nss_sfu_init, + .get_nss_info = nss_ad_get_info, + .map_to_alias = nss_ad_map_to_alias, + .map_from_alias = nss_ad_map_from_alias, + .close_fn = nss_ad_close }; static struct nss_info_methods nss_sfu20_methods = { - .init = nss_sfu20_init, - .get_nss_info = nss_ad_get_info, - .close_fn = nss_ad_close + .init = nss_sfu20_init, + .get_nss_info = nss_ad_get_info, + .map_to_alias = nss_ad_map_to_alias, + .map_from_alias = nss_ad_map_from_alias, + .close_fn = nss_ad_close }; |