summaryrefslogtreecommitdiff
path: root/source3/winbindd/idmap_ad.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/winbindd/idmap_ad.c')
-rw-r--r--source3/winbindd/idmap_ad.c260
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
};