summaryrefslogtreecommitdiff
path: root/source3/libads
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2005-06-29 14:03:53 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:58:07 -0500
commit2e7f22e833fbb549f698460f9ed4d81af68b86e9 (patch)
tree58f04a4311fa6cb4b2acdb33222b8b340675badb /source3/libads
parent3922667cbe6cd56c6d29c88692b7e7d3342c1f1f (diff)
downloadsamba-2e7f22e833fbb549f698460f9ed4d81af68b86e9.tar.gz
samba-2e7f22e833fbb549f698460f9ed4d81af68b86e9.tar.bz2
samba-2e7f22e833fbb549f698460f9ed4d81af68b86e9.zip
r7994: This adds support in Winbindd's "security = ads"-mode to retrieve the POSIX
homedirectory and the loginshell from Active Directory's "Services for Unix". Enable it with: winbind sfu support = yes User-Accounts without SFU-Unix-Attributes will be assigned template-based Shells and Homedirs as before. Note that it doesn't matter which version of Services for Unix you use (2.0, 2.2, 3.0 or 3.5). Samba should detect the correct attributes (msSFULoginShell, msSFU30LoginShell, etc.) automatically. If you also want to share the same uid/gid-space as SFU then also use PADL's ad-idmap-Plugin: idmap backend = ad When using the idmap-plugin only those accounts will appear in Name Service Switch that have those UNIX-attributes which avoids potential uid/gid-space clashes between SFU-ids and automatically assigned idmap-ids. Guenther (This used to be commit 28b59699425b1c954d191fc0e3bd357e4a4e4cd8)
Diffstat (limited to 'source3/libads')
-rw-r--r--source3/libads/ads_struct.c5
-rw-r--r--source3/libads/ldap.c96
2 files changed, 100 insertions, 1 deletions
diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c
index e8546f86f5..d8676d050d 100644
--- a/source3/libads/ads_struct.c
+++ b/source3/libads/ads_struct.c
@@ -132,8 +132,13 @@ void ads_destroy(ADS_STRUCT **ads)
SAFE_FREE((*ads)->config.realm);
SAFE_FREE((*ads)->config.bind_path);
+ SAFE_FREE((*ads)->config.schema_path);
SAFE_FREE((*ads)->config.ldap_server_name);
+ SAFE_FREE((*ads)->schema.sfu_uidnumber_attr);
+ SAFE_FREE((*ads)->schema.sfu_gidnumber_attr);
+ SAFE_FREE((*ads)->schema.sfu_shell_attr);
+ SAFE_FREE((*ads)->schema.sfu_homedir_attr);
ZERO_STRUCTP(*ads);
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 04754f4e9e..1289015464 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -2388,6 +2388,43 @@ static time_t ads_parse_time(const char *str)
}
+const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * oid)
+{
+ ADS_STATUS rc;
+ int count = 0;
+ void *res = NULL;
+ char *expr = NULL;
+ const char *attrs[] = { "lDAPDisplayName", NULL };
+
+ if (ads == NULL || mem_ctx == NULL || oid == NULL) {
+ goto done;
+ }
+
+ expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", oid);
+ if (expr == NULL) {
+ goto done;
+ }
+
+ rc = ads_do_search_retry(ads, ads->config.schema_path,
+ LDAP_SCOPE_SUBTREE, expr, attrs, &res);
+ if (!ADS_ERR_OK(rc)) {
+ goto done;
+ }
+
+ count = ads_count_replies(ads, res);
+ if (count == 0 || !res) {
+ goto done;
+ }
+
+ return ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName");
+
+done:
+ DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n",
+ oid));
+
+ return NULL;
+}
+
/**
* Find the servers name and realm - this can be done before authentication
* The ldapServiceName field on w2k looks like this:
@@ -2397,12 +2434,15 @@ static time_t ads_parse_time(const char *str)
**/
ADS_STATUS ads_server_info(ADS_STRUCT *ads)
{
- const char *attrs[] = {"ldapServiceName", "currentTime", NULL};
+ const char *attrs[] = {"ldapServiceName",
+ "currentTime",
+ "schemaNamingContext", NULL};
ADS_STATUS status;
void *res;
char *value;
char *p;
char *timestr;
+ char *schema_path;
TALLOC_CTX *ctx;
if (!(ctx = talloc_init("ads_server_info"))) {
@@ -2429,6 +2469,16 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
}
+ schema_path = ads_pull_string(ads, ctx, res, "schemaNamingContext");
+ if (!schema_path) {
+ ads_msgfree(ads, res);
+ talloc_destroy(ctx);
+ return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
+ }
+
+ SAFE_FREE(ads->config.schema_path);
+ ads->config.schema_path = SMB_STRDUP(schema_path);
+
ads_msgfree(ads, res);
p = strchr(value, ':');
@@ -2476,6 +2526,50 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
}
/**
+ * Check for "Services for Unix"-Schema and load some attributes into the ADS_STRUCT
+ * @param ads connection to ads server
+ * @return BOOL status of search (False if one or more attributes couldn't be
+ * found in Active Directory)
+ **/
+BOOL ads_check_sfu_mapping(ADS_STRUCT *ads)
+{
+ BOOL ret = False;
+ TALLOC_CTX *ctx = NULL;
+ const char *gidnumber, *uidnumber, *homedir, *shell;
+
+ ctx = talloc_init("ads_check_sfu_mapping");
+ if (ctx == NULL)
+ goto done;
+
+ gidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GIDNUMBER_OID);
+ if (gidnumber == NULL)
+ goto done;
+ ads->schema.sfu_gidnumber_attr = SMB_STRDUP(gidnumber);
+
+ uidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_UIDNUMBER_OID);
+ if (uidnumber == NULL)
+ goto done;
+ ads->schema.sfu_uidnumber_attr = SMB_STRDUP(uidnumber);
+
+ homedir = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_HOMEDIR_OID);
+ if (homedir == NULL)
+ goto done;
+ ads->schema.sfu_homedir_attr = SMB_STRDUP(homedir);
+
+ shell = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_SHELL_OID);
+ if (shell == NULL)
+ goto done;
+ ads->schema.sfu_shell_attr = SMB_STRDUP(shell);
+
+ ret = True;
+done:
+ if (ctx)
+ talloc_destroy(ctx);
+
+ return ret;
+}
+
+/**
* find the domain sid for our domain
* @param ads connection to ads server
* @param sid Pointer to domain sid