diff -ruN samba-3.0.20-save/source/include/ads.h samba-3.0.20/source/include/ads.h --- samba-3.0.20-save/source/include/ads.h 2005-07-28 14:19:50.000000000 +0100 +++ samba-3.0.20/source/include/ads.h 2005-12-17 19:08:25.000000000 +0000 @@ -43,6 +43,12 @@ /* info derived from the servers schema */ struct { + /* RFC2307 Attributes if they exist */ + char *homedir_attr; + char *shell_attr; + char *uidnumber_attr; + char *gidnumber_attr; + /* SFU Attributes if they exist */ char *sfu_homedir_attr; char *sfu_shell_attr; char *sfu_uidnumber_attr; @@ -92,6 +98,13 @@ #define ADS_SERVER_SORT_OID "1.2.840.113556.1.4.473" #define ADS_PERMIT_MODIFY_OID "1.2.840.113556.1.4.1413" +/* ldap attribute oids (RFC2307) */ +#define ATTR_UIDNUMBER_OID "1.3.6.1.1.1.1.0" +#define ATTR_GIDNUMBER_OID "1.3.6.1.1.1.1.1" +#define ATTR_GECOS_OID "1.3.6.1.1.1.1.2" +#define ATTR_HOMEDIR_OID "1.3.6.1.1.1.1.3" +#define ATTR_SHELL_OID "1.3.6.1.1.1.1.4" + /* ldap attribute oids (Services for Unix) */ #define ADS_ATTR_SFU_UIDNUMBER_OID "1.2.840.113556.1.6.18.1.310" #define ADS_ATTR_SFU_GIDNUMBER_OID "1.2.840.113556.1.6.18.1.311" diff -ruN samba-3.0.20-save/source/libads/ads_struct.c samba-3.0.20/source/libads/ads_struct.c --- samba-3.0.20-save/source/libads/ads_struct.c 2005-07-28 14:19:50.000000000 +0100 +++ samba-3.0.20/source/libads/ads_struct.c 2005-12-17 19:08:25.000000000 +0000 @@ -134,6 +134,11 @@ SAFE_FREE((*ads)->config.bind_path); SAFE_FREE((*ads)->config.schema_path); SAFE_FREE((*ads)->config.ldap_server_name); + + SAFE_FREE((*ads)->schema.uidnumber_attr); + SAFE_FREE((*ads)->schema.gidnumber_attr); + SAFE_FREE((*ads)->schema.shell_attr); + SAFE_FREE((*ads)->schema.homedir_attr); SAFE_FREE((*ads)->schema.sfu_uidnumber_attr); SAFE_FREE((*ads)->schema.sfu_gidnumber_attr); diff -ruN samba-3.0.20-save/source/libads/ldap.c samba-3.0.20/source/libads/ldap.c --- samba-3.0.20-save/source/libads/ldap.c 2005-07-28 14:19:50.000000000 +0100 +++ samba-3.0.20/source/libads/ldap.c 2005-12-17 19:08:25.000000000 +0000 @@ -2526,45 +2526,75 @@ } /** - * Check for "Services for Unix"-Schema and load some attributes into the ADS_STRUCT + * Check for "Services for Unix/RFC2307"-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 ads_check_mapping(ADS_STRUCT *ads) { BOOL ret = False; TALLOC_CTX *ctx = NULL; const char *gidnumber, *uidnumber, *homedir, *shell; - ctx = talloc_init("ads_check_sfu_mapping"); + ctx = talloc_init("ads_check_mapping"); if (ctx == NULL) goto done; + /* RFC2307 mapping */ + gidnumber = ads_get_attrname_by_oid(ads, ctx, ATTR_GIDNUMBER_OID); + if (gidnumber == NULL) + goto rfc2307done; + + uidnumber = ads_get_attrname_by_oid(ads, ctx, ATTR_UIDNUMBER_OID); + if (uidnumber == NULL) + goto rfc2307done; + + homedir = ads_get_attrname_by_oid(ads, ctx, ATTR_HOMEDIR_OID); + if (homedir == NULL) + goto rfc2307done; + + shell = ads_get_attrname_by_oid(ads, ctx, ATTR_SHELL_OID); + if (shell == NULL) + goto rfc2307done; + + + ads->schema.gidnumber_attr = SMB_STRDUP(gidnumber); + ads->schema.uidnumber_attr = SMB_STRDUP(uidnumber); + ads->schema.homedir_attr = SMB_STRDUP(homedir); + ads->schema.shell_attr = SMB_STRDUP(shell); + + ret = True; + +rfc2307done: + + /* SFU mapping */ 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); + goto sfudone; 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); + goto sfudone; 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); + goto sfudone; shell = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_SHELL_OID); if (shell == NULL) - goto done; + goto sfudone; + + ads->schema.sfu_gidnumber_attr = SMB_STRDUP(gidnumber); + ads->schema.sfu_uidnumber_attr = SMB_STRDUP(uidnumber); + ads->schema.sfu_homedir_attr = SMB_STRDUP(homedir); ads->schema.sfu_shell_attr = SMB_STRDUP(shell); ret = True; -done: - if (ctx) - talloc_destroy(ctx); + sfudone: + talloc_destroy(ctx); + + done: return ret; } diff -ruN samba-3.0.20-save/source/nsswitch/winbindd_ads.c samba-3.0.20/source/nsswitch/winbindd_ads.c --- samba-3.0.20-save/source/nsswitch/winbindd_ads.c 2005-08-19 18:16:27.000000000 +0100 +++ samba-3.0.20/source/nsswitch/winbindd_ads.c 2005-12-17 19:17:36.000000000 +0000 @@ -95,7 +95,7 @@ return NULL; } - if (use_nss_info("sfu") && (!ads_check_sfu_mapping(ads))) { + if (use_nss_info("sfu") && (!ads_check_mapping(ads))) { DEBUG(0,("ads_cached_connection: failed to check sfu attributes\n")); return NULL; } @@ -122,6 +122,8 @@ "sAMAccountName", "name", "objectSid", "primaryGroupID", "sAMAccountType", + ATTR_HOMEDIR_OID, + ATTR_SHELL_OID, ADS_ATTR_SFU_HOMEDIR_OID, ADS_ATTR_SFU_SHELL_OID, NULL}; @@ -130,6 +132,7 @@ void *res = NULL; void *msg = NULL; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + char *homedir_attr, *shell_attr; *num_entries = 0; @@ -148,12 +151,16 @@ goto done; } + DEBUG(5,("ads: query_user_list - ads_search_retry returned\n")); + count = ads_count_replies(ads, res); if (count == 0) { DEBUG(1,("query_user_list: No users found\n")); goto done; } + DEBUG(5,("ads: query_user_list - ads_count_replies returned\n")); + (*info) = TALLOC_ZERO_ARRAY(mem_ctx, WINBIND_USERINFO, count); if (!*info) { status = NT_STATUS_NO_MEMORY; @@ -162,6 +169,28 @@ i = 0; + if (use_nss_info("rfc2307")) { + if (!ads_check_mapping(ads)) { + DEBUG(0,("query_user_list: failed to check for RFC2307 schema\n")); + homedir_attr = "unixHomeDirectory"; + shell_attr = "loginShell"; + } else { + homedir_attr = ads->schema.homedir_attr; + shell_attr = ads->schema.shell_attr; + } + } else if (use_nss_info("sfu")) { + if (!ads_check_mapping(ads)) { + DEBUG(0,("query_user_list: failed to check for SFU schema\n")); + homedir_attr = "unixHomeDirectory"; + shell_attr = "loginShell"; + } else { + homedir_attr = ads->schema.sfu_homedir_attr; + shell_attr = ads->schema.sfu_shell_attr; + } + } else { + homedir_attr = "unixHomeDirectory"; + shell_attr = "loginShell"; + } for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { char *name, *gecos; char *homedir = NULL; @@ -169,6 +198,8 @@ uint32 group; uint32 atype; + DEBUG(5,("ads: query_user_list processing msg\n")); + if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) || ads_atype_map(atype) != SID_NAME_USER) { DEBUG(1,("Not a user account? atype=0x%x\n", atype)); @@ -177,11 +208,12 @@ name = ads_pull_username(ads, mem_ctx, msg); gecos = ads_pull_string(ads, mem_ctx, msg, "name"); - if (use_nss_info("sfu")) { - homedir = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_homedir_attr); - shell = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_shell_attr); - } + homedir = ads_pull_string(ads, mem_ctx, msg, homedir_attr); + shell = ads_pull_string(ads, mem_ctx, msg, shell_attr); + DEBUG(5,("ads: query_user_list - homedir=%s, shell=%s\n", + (homedir)?homedir:"NULL", (shell)?shell:"NULL")); + if (!ads_pull_sid(ads, msg, "objectSid", &(*info)[i].user_sid)) { DEBUG(1,("No sid for %s !?\n", name)); @@ -382,6 +414,8 @@ "sAMAccountName", "name", "primaryGroupID", + ATTR_HOMEDIR_OID, + ATTR_SHELL_OID, ADS_ATTR_SFU_HOMEDIR_OID, ADS_ATTR_SFU_SHELL_OID, NULL}; @@ -392,6 +426,7 @@ char *sidstr; uint32 group_rid; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + char *homedir_attr, *shell_attr; DEBUG(3,("ads: query_user\n")); @@ -423,11 +458,30 @@ info->acct_name = ads_pull_username(ads, mem_ctx, msg); info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); - if (use_nss_info("sfu")) { - info->homedir = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_homedir_attr); - info->shell = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_shell_attr); + if (use_nss_info("rfc2307")) { + if (!ads_check_mapping(ads)) { + DEBUG(0,("query_user_list: failed to check for RFC2307 schema\n")); + homedir_attr = "unixHomeDirectory"; + shell_attr = "loginShell"; + } else { + homedir_attr = ads->schema.homedir_attr; + shell_attr = ads->schema.shell_attr; + } + } else if (use_nss_info("sfu")) { + if (!ads_check_mapping(ads)) { + DEBUG(0,("query_user_list: failed to check for SFU schema\n")); + homedir_attr = "unixHomeDirectory"; + shell_attr = "loginShell"; + } else { + homedir_attr = ads->schema.sfu_homedir_attr; + shell_attr = ads->schema.sfu_shell_attr; + } + } else { + homedir_attr = "unixHomeDirectory"; + shell_attr = "loginShell"; } - + info->homedir = ads_pull_string(ads, mem_ctx, msg, homedir_attr); + info->shell = ads_pull_string(ads, mem_ctx, msg, shell_attr); if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) { DEBUG(1,("No primary group for %s !?\n", sid_string_static(sid))); diff -ruN samba-3.0.20-save/source/nsswitch/winbindd_user.c samba-3.0.20/source/nsswitch/winbindd_user.c --- samba-3.0.20-save/source/nsswitch/winbindd_user.c 2005-07-28 14:19:44.000000000 +0100 +++ samba-3.0.20/source/nsswitch/winbindd_user.c 2005-12-17 19:08:25.000000000 +0000 @@ -43,7 +43,8 @@ if (out == NULL) return False; - if (in && !strequal(in,"") && lp_security() == SEC_ADS && use_nss_info("sfu")) { + if (in && !strequal(in,"") && lp_security() == SEC_ADS + && (use_nss_info("rfc2307") || use_nss_info("sfu"))) { safe_strcpy(out, in, sizeof(fstring) - 1); return True; } diff -ruN samba-3.0.20-save/source/sam/idmap_ad.c samba-3.0.20/source/sam/idmap_ad.c --- samba-3.0.20-save/source/sam/idmap_ad.c 2005-07-28 14:19:49.000000000 +0100 +++ samba-3.0.20/source/sam/idmap_ad.c 2005-12-17 19:08:25.000000000 +0000 @@ -30,14 +30,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_IDMAP -#ifndef ATTR_UIDNUMBER -#define ATTR_UIDNUMBER ADS_ATTR_SFU_UIDNUMBER_OID -#endif - -#ifndef ATTR_GIDNUMBER -#define ATTR_GIDNUMBER ADS_ATTR_SFU_GIDNUMBER_OID -#endif - #define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache" NTSTATUS init_module(void); @@ -54,9 +46,19 @@ return True; } - if (use_nss_info("sfu")) { - - if (!ads_check_sfu_mapping(ads)) { + if (use_nss_info("rfc2307")) { + + if (!ads_check_mapping(ads)) { + DEBUG(0,("ad_idmap_check_attr_mapping: failed to check for RFC2307 schema\n")); + return False; + } + + attr_uidnumber = SMB_STRDUP(ads->schema.uidnumber_attr); + attr_gidnumber = SMB_STRDUP(ads->schema.gidnumber_attr); + + } else if (use_nss_info("sfu")) { + + if (!ads_check_mapping(ads)) { DEBUG(0,("ad_idmap_check_attr_mapping: failed to check for SFU schema\n")); return False; } @@ -192,16 +194,16 @@ switch (id_type & ID_TYPEMASK) { case ID_USERID: - if (asprintf(&expr, "(&(|(sAMAccountType=%d)(sAMAccountType=%d)(sAMAccountType=%d))(%s=%d))", + if (asprintf(&expr, "(&(|(sAMAccountType=%d)(sAMAccountType=%d)(sAMAccountType=%d))(%s=%s))", ATYPE_NORMAL_ACCOUNT, ATYPE_WORKSTATION_TRUST, ATYPE_INTERDOMAIN_TRUST, - ATTR_UIDNUMBER, (int)unid.uid) == -1) { + attr_uidnumber, (int)unid.uid) == -1) { return NT_STATUS_NO_MEMORY; } break; case ID_GROUPID: - if (asprintf(&expr, "(&(|(sAMAccountType=%d)(sAMAccountType=%d))(%s=%d))", + if (asprintf(&expr, "(&(|(sAMAccountType=%d)(sAMAccountType=%d))(%s=%s))", ATYPE_SECURITY_GLOBAL_GROUP, ATYPE_SECURITY_LOCAL_GROUP, - ATTR_GIDNUMBER, (int)unid.gid) == -1) { + attr_gidnumber, (int)unid.gid) == -1) { return NT_STATUS_NO_MEMORY; } break; @@ -254,7 +256,7 @@ { ADS_STATUS rc; NTSTATUS status = NT_STATUS_NONE_MAPPED; - const char *attrs[] = { "sAMAccountType", ATTR_UIDNUMBER, ATTR_GIDNUMBER, NULL }; + const char *attrs[] = { "sAMAccountType", attr_uidnumber, attr_gidnumber, NULL }; void *res = NULL; void *msg = NULL; char *expr = NULL;