[PATCH 0/4] idmap_ad: Add username aliasing support.

jerry at samba.org jerry at samba.org
Tue Sep 16 16:20:29 GMT 2008


From: Gerald (Jerry) Carter <jerry at samba.org>

* 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 at 192.168.56.91
  Password:

  coffeedude at 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(-)

diff --git a/source3/include/ads.h b/source3/include/ads.h
index 97faf0b..b290fb0 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 ff41ccc..b5d2d35 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 9fefb1b..d7f7622 100644
--- a/source3/winbindd/idmap_ad.c
+++ b/source3/winbindd/idmap_ad.c
@@ -761,6 +761,159 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
 	return NT_STATUS_OK;
 }
 
+/**********************************************************************
+ *********************************************************************/
+
+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 +939,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
 };
 
 
-- 
1.5.4.3



More information about the samba-technical mailing list