From 28d2683903677d396c77c437fabd7ea807ff0de6 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Tue, 16 Sep 2008 10:35:21 -0700 Subject: * Allow an admin to define the "uid" attribute for a RFC2307 user object in AD to be the username alias. For example: $ net ads search "(uid=coffeedude)" distinguishedName: CN=Gerald W. Carter,CN=Users,DC=pink,DC=plainjoe,DC=org sAMAccountName: gcarter memberOf: CN=UnixUsers,CN=Users,DC=pink,DC=plainjoe,DC=org memberOf: CN=Domain Admins,CN=Users,DC=pink,DC=plainjoe,DC=org memberOf: CN=Enterprise Admins,CN=Users,DC=pink,DC=plainjoe,DC=org memberOf: CN=Schema Admins,CN=Users,DC=pink,DC=plainjoe,DC=org uid: coffeedude uidNumber: 10000 gidNumber: 10000 unixHomeDirectory: /home/gcarter loginShell: /bin/bash $ ssh coffeedude@192.168.56.91 Password: coffeedude@orville:~$ id uid=10000(coffeedude) gid=10000(PINK\unixusers) groups=10000(PINK\unixusers) $ getent passwd PINK\\gcarter coffeedude:*:10000:10000::/home/gcarter:/bin/bash $ getent passwd coffeedude coffeedude:*:10000:10000::/home/gcarter:/bin/bash $ getent group PINK\\Unixusers PINK\unixusers:x:10000:coffeedude --- source3/include/ads.h | 5 ++ source3/libads/ldap_schema.c | 15 +++- source3/winbindd/idmap_ad.c | 177 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 185 insertions(+), 12 deletions(-) (limited to 'source3') diff --git a/source3/include/ads.h b/source3/include/ads.h index 97faf0b6eb..b72d250940 100644 --- a/source3/include/ads.h +++ b/source3/include/ads.h @@ -133,6 +133,7 @@ struct posix_schema { char *posix_uidnumber_attr; char *posix_gidnumber_attr; char *posix_gecos_attr; + char *posix_uid_attr; }; @@ -179,6 +180,7 @@ typedef void **ADS_MODLIST; #define ADS_ATTR_SFU_HOMEDIR_OID "1.2.840.113556.1.6.18.1.344" #define ADS_ATTR_SFU_SHELL_OID "1.2.840.113556.1.6.18.1.312" #define ADS_ATTR_SFU_GECOS_OID "1.2.840.113556.1.6.18.1.337" +#define ADS_ATTR_SFU_UID_OID "1.2.840.113556.1.6.18.1.309" /* ldap attribute oids (Services for Unix 2.0) */ #define ADS_ATTR_SFU20_UIDNUMBER_OID "1.2.840.113556.1.4.7000.187.70" @@ -186,6 +188,8 @@ typedef void **ADS_MODLIST; #define ADS_ATTR_SFU20_HOMEDIR_OID "1.2.840.113556.1.4.7000.187.106" #define ADS_ATTR_SFU20_SHELL_OID "1.2.840.113556.1.4.7000.187.72" #define ADS_ATTR_SFU20_GECOS_OID "1.2.840.113556.1.4.7000.187.97" +#define ADS_ATTR_SFU20_UID_OID "1.2.840.113556.1.4.7000.187.102" + /* ldap attribute oids (RFC2307) */ #define ADS_ATTR_RFC2307_UIDNUMBER_OID "1.3.6.1.1.1.1.0" @@ -193,6 +197,7 @@ typedef void **ADS_MODLIST; #define ADS_ATTR_RFC2307_HOMEDIR_OID "1.3.6.1.1.1.1.3" #define ADS_ATTR_RFC2307_SHELL_OID "1.3.6.1.1.1.1.4" #define ADS_ATTR_RFC2307_GECOS_OID "1.3.6.1.1.1.1.2" +#define ADS_ATTR_RFC2307_UID_OID "0.9.2342.19200300.100.1.1" /* ldap bitwise searches */ #define ADS_LDAP_MATCHING_RULE_BIT_AND "1.2.840.113556.1.4.803" diff --git a/source3/libads/ldap_schema.c b/source3/libads/ldap_schema.c index ff41ccc861..b5d2d35889 100644 --- a/source3/libads/ldap_schema.c +++ b/source3/libads/ldap_schema.c @@ -246,19 +246,22 @@ ADS_STATUS ads_check_posix_schema_mapping(TALLOC_CTX *mem_ctx, ADS_ATTR_SFU_GIDNUMBER_OID, ADS_ATTR_SFU_HOMEDIR_OID, ADS_ATTR_SFU_SHELL_OID, - ADS_ATTR_SFU_GECOS_OID}; + ADS_ATTR_SFU_GECOS_OID, + ADS_ATTR_SFU_UID_OID }; const char *oids_sfu20[] = { ADS_ATTR_SFU20_UIDNUMBER_OID, ADS_ATTR_SFU20_GIDNUMBER_OID, ADS_ATTR_SFU20_HOMEDIR_OID, ADS_ATTR_SFU20_SHELL_OID, - ADS_ATTR_SFU20_GECOS_OID}; + ADS_ATTR_SFU20_GECOS_OID, + ADS_ATTR_SFU20_UID_OID }; const char *oids_rfc2307[] = { ADS_ATTR_RFC2307_UIDNUMBER_OID, ADS_ATTR_RFC2307_GIDNUMBER_OID, ADS_ATTR_RFC2307_HOMEDIR_OID, ADS_ATTR_RFC2307_SHELL_OID, - ADS_ATTR_RFC2307_GECOS_OID }; + ADS_ATTR_RFC2307_GECOS_OID, + ADS_ATTR_RFC2307_UID_OID }; DEBUG(10,("ads_check_posix_schema_mapping for schema mode: %d\n", map_type)); @@ -359,6 +362,12 @@ ADS_STATUS ads_check_posix_schema_mapping(TALLOC_CTX *mem_ctx, strequal(ADS_ATTR_SFU20_GECOS_OID, oids_out[i])) { schema->posix_gecos_attr = talloc_strdup(schema, names_out[i]); } + + if (strequal(ADS_ATTR_RFC2307_UID_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU_UID_OID, oids_out[i]) || + strequal(ADS_ATTR_SFU20_UID_OID, oids_out[i])) { + schema->posix_uid_attr = talloc_strdup(schema, names_out[i]); + } } if (!schema->posix_uidnumber_attr || diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c index d7c87497a9..8144d876d4 100644 --- a/source3/winbindd/idmap_ad.c +++ b/source3/winbindd/idmap_ad.c @@ -818,6 +818,159 @@ done: 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; +} + + /************************************************************************ ***********************************************************************/ @@ -843,21 +996,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 }; -- cgit