diff options
author | Gerald W. Carter <jerry@samba.org> | 2008-09-15 12:38:36 -0500 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2008-09-15 17:18:23 -0500 |
commit | 62791bbd030f7db272ca68260a4f7586de6576d0 (patch) | |
tree | ec3431562911a9c4eeda73cd07234e8347b3cd8f /source3/winbindd | |
parent | 458101b5776057549b35181a75b745604ae47d48 (diff) | |
download | samba-62791bbd030f7db272ca68260a4f7586de6576d0.tar.gz samba-62791bbd030f7db272ca68260a4f7586de6576d0.tar.bz2 samba-62791bbd030f7db272ca68260a4f7586de6576d0.zip |
idmap_ad: Fix a segfault when calling nss_get_info() with a NULL ads structure.
Diffstat (limited to 'source3/winbindd')
-rw-r--r-- | source3/winbindd/idmap_ad.c | 81 |
1 files changed, 69 insertions, 12 deletions
diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c index 9fefb1bba7..d7c87497a9 100644 --- a/source3/winbindd/idmap_ad.c +++ b/source3/winbindd/idmap_ad.c @@ -732,6 +732,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,22 +753,69 @@ 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; } /************************************************************************ |