* Allow an admin to define the "uid" attribute for a RFC2307
authorGerald (Jerry) Carter <jerry@samba.org>
Tue, 16 Sep 2008 17:35:21 +0000 (10:35 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 16 Sep 2008 17:35:21 +0000 (10:35 -0700)
  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
source3/libads/ldap_schema.c
source3/winbindd/idmap_ad.c

index 97faf0b6eb4515b9bc02e73284fe8531d456f09a..b72d25094025156108c6815f62c44c8a0b141867 100644 (file)
@@ -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"
index ff41ccc8614a7319d237219baf95aa3244e42df8..b5d2d35889e17d5c4402bdcee995c7c90de8ad14 100644 (file)
@@ -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 ||
index d7c87497a925827ee0b88e1ef8ab714dd4a0f7e2..8144d876d4061a4083ad96693e33877f0176c730 100644 (file)
@@ -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
 };