summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald (Jerry) Carter <jerry@samba.org>2008-09-16 10:35:21 -0700
committerJeremy Allison <jra@samba.org>2008-09-16 10:35:21 -0700
commit28d2683903677d396c77c437fabd7ea807ff0de6 (patch)
tree1a8d2b115d6bb001aa62d3b0b1bae49fa54ef65c
parent63554b4078e3039bfeda46d8bc77d6ad7ab189ad (diff)
downloadsamba-28d2683903677d396c77c437fabd7ea807ff0de6.tar.gz
samba-28d2683903677d396c77c437fabd7ea807ff0de6.tar.bz2
samba-28d2683903677d396c77c437fabd7ea807ff0de6.zip
* 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
-rw-r--r--source3/include/ads.h5
-rw-r--r--source3/libads/ldap_schema.c15
-rw-r--r--source3/winbindd/idmap_ad.c177
3 files changed, 185 insertions, 12 deletions
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
};