diff -ruN samba-3.0.21c-save/source/include/ads.h samba-3.0.21c/source/include/ads.h --- samba-3.0.21c-save/source/include/ads.h 2006-02-23 16:29:34.000000000 +0000 +++ samba-3.0.21c/source/include/ads.h 2006-03-22 08:53:02.000000000 +0000 @@ -43,6 +43,13 @@ /* info derived from the servers schema */ struct { + /* RFC2307 Attributes if they exist */ + char *homedir_attr; + char *shell_attr; + char *uidnumber_attr; + char *gidnumber_attr; + char *gecos_attr; + /* SFU Attributes if they exist */ char *sfu_homedir_attr; char *sfu_shell_attr; char *sfu_uidnumber_attr; @@ -93,6 +100,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.21c-save/source/libads/ads_struct.c samba-3.0.21c/source/libads/ads_struct.c --- samba-3.0.21c-save/source/libads/ads_struct.c 2006-02-23 16:29:34.000000000 +0000 +++ samba-3.0.21c/source/libads/ads_struct.c 2006-03-22 08:53:02.000000000 +0000 @@ -134,6 +134,12 @@ 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.gecos_attr); SAFE_FREE((*ads)->schema.sfu_uidnumber_attr); SAFE_FREE((*ads)->schema.sfu_gidnumber_attr); diff -ruN samba-3.0.21c-save/source/libads/ldap.c samba-3.0.21c/source/libads/ldap.c --- samba-3.0.21c-save/source/libads/ldap.c 2006-02-23 16:29:34.000000000 +0000 +++ samba-3.0.21c/source/libads/ldap.c 2006-03-22 08:53:02.000000000 +0000 @@ -2559,46 +2559,77 @@ * @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, *gecos; - 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; + + gecos = ads_get_attrname_by_oid(ads, ctx, ATTR_GECOS_OID); + if (gecos == 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); + ads->schema.gecos_attr = SMB_STRDUP(gecos); + + 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; - ads->schema.sfu_shell_attr = SMB_STRDUP(shell); + goto sfudone; gecos = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GECOS_OID); if (gecos == 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); ads->schema.sfu_gecos_attr = SMB_STRDUP(gecos); ret = True; -done: - if (ctx) - talloc_destroy(ctx); - + sfudone: + talloc_destroy(ctx); + done: return ret; } diff -ruN samba-3.0.21c-save/source/nsswitch/winbindd_ads.c samba-3.0.21c/source/nsswitch/winbindd_ads.c --- samba-3.0.21c-save/source/nsswitch/winbindd_ads.c 2006-02-24 05:32:14.000000000 +0000 +++ samba-3.0.21c/source/nsswitch/winbindd_ads.c 2006-03-22 08:53:02.000000000 +0000 @@ -123,8 +123,8 @@ return NULL; } - if (use_nss_info("sfu") && (!ads_check_sfu_mapping(ads))) { - DEBUG(0,("ads_cached_connection: failed to check sfu attributes\n")); + if ((use_nss_info("rfc2307") || use_nss_info("sfu")) && (!ads_check_mapping(ads))) { + DEBUG(0,("ads_cached_connection: failed to check rfc2307/sfu attributes\n")); return NULL; } @@ -138,6 +138,39 @@ return ads; } +static void map_attributes(ADS_STRUCT *ads, + char **homedir_attr, + char **shell_attr, + char **gecos_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"; + *gecos_attr = "gecos"; + } else { + *homedir_attr = ads->schema.homedir_attr; + *shell_attr = ads->schema.shell_attr; + *gecos_attr = ads->schema.gecos_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"; + *gecos_attr = "gecos"; + } else { + *homedir_attr = ads->schema.sfu_homedir_attr; + *shell_attr = ads->schema.sfu_shell_attr; + *gecos_attr = ads->schema.sfu_gecos_attr; + } + } else { + *homedir_attr = "unixHomeDirectory"; + *shell_attr = "loginShell"; + *gecos_attr = "gecos"; + } +} /* Query display info for a realm. This is the basic user list fn */ static NTSTATUS query_user_list(struct winbindd_domain *domain, @@ -150,6 +183,9 @@ "sAMAccountName", "name", "objectSid", "primaryGroupID", "sAMAccountType", + ATTR_HOMEDIR_OID, + ATTR_SHELL_OID, + ATTR_GECOS_OID, ADS_ATTR_SFU_HOMEDIR_OID, ADS_ATTR_SFU_SHELL_OID, ADS_ATTR_SFU_GECOS_OID, @@ -159,6 +195,7 @@ void *res = NULL; void *msg = NULL; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + char *homedir_attr, *shell_attr, *gecos_attr; *num_entries = 0; @@ -177,12 +214,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; @@ -191,6 +232,8 @@ i = 0; + map_attributes(ads, &homedir_attr, &shell_attr, &gecos_attr); + for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { char *name, *gecos = NULL; char *homedir = NULL; @@ -198,6 +241,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)); @@ -206,14 +251,9 @@ name = ads_pull_username(ads, mem_ctx, msg); - 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); - gecos = ads_pull_string(ads, mem_ctx, msg, - ads->schema.sfu_gecos_attr); - } + homedir = ads_pull_string(ads, mem_ctx, msg, homedir_attr); + shell = ads_pull_string(ads, mem_ctx, msg, shell_attr); + gecos = ads_pull_string(ads, mem_ctx, msg, gecos_attr); if (gecos == NULL) { gecos = ads_pull_string(ads, mem_ctx, msg, "name"); @@ -265,6 +305,7 @@ NTSTATUS status = NT_STATUS_UNSUCCESSFUL; const char *filter; BOOL enum_dom_local_groups = False; + char *homedir_attr, *shell_attr, *gecos_attr; *num_entries = 0; @@ -328,14 +369,22 @@ } i = 0; + + map_attributes(ads, &homedir_attr, &shell_attr, &gecos_attr); for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - char *name, *gecos; + char *name, *gecos, *homedir, *shell; DOM_SID sid; uint32 rid; name = ads_pull_username(ads, mem_ctx, msg); gecos = ads_pull_string(ads, mem_ctx, msg, "name"); + 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", &sid)) { DEBUG(1,("No sid for %s !?\n", name)); continue; @@ -441,6 +490,8 @@ "sAMAccountName", "name", "primaryGroupID", + ATTR_HOMEDIR_OID, + ATTR_SHELL_OID, ADS_ATTR_SFU_HOMEDIR_OID, ADS_ATTR_SFU_SHELL_OID, ADS_ATTR_SFU_GECOS_OID, @@ -452,6 +503,7 @@ char *sidstr; uint32 group_rid; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + char *homedir_attr, *shell_attr, *gecos_attr; DEBUG(3,("ads: query_user\n")); @@ -482,14 +534,11 @@ info->acct_name = ads_pull_username(ads, mem_ctx, msg); - 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); - info->full_name = ads_pull_string(ads, mem_ctx, msg, - ads->schema.sfu_gecos_attr); - } + map_attributes(ads, &homedir_attr, &shell_attr, &gecos_attr); + + info->homedir = ads_pull_string(ads, mem_ctx, msg, homedir_attr); + info->shell = ads_pull_string(ads, mem_ctx, msg, shell_attr); + info->full_name = ads_pull_string(ads, mem_ctx, msg, gecos_attr); if (info->full_name == NULL) { info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); diff -ruN samba-3.0.21c-save/source/nsswitch/winbindd_user.c samba-3.0.21c/source/nsswitch/winbindd_user.c --- samba-3.0.21c-save/source/nsswitch/winbindd_user.c 2005-09-29 22:52:42.000000000 +0100 +++ samba-3.0.21c/source/nsswitch/winbindd_user.c 2006-03-22 08:53:02.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.21c-save/source/sam/idmap_ad.c samba-3.0.21c/source/sam/idmap_ad.c --- samba-3.0.21c-save/source/sam/idmap_ad.c 2005-07-28 14:19:49.000000000 +0100 +++ samba-3.0.21c/source/sam/idmap_ad.c 2006-03-22 08:56:26.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); @@ -47,6 +39,7 @@ static char *attr_uidnumber = NULL; static char *attr_gidnumber = NULL; +static char **account_attrs = NULL; static BOOL ad_idmap_check_attr_mapping(ADS_STRUCT *ads) { @@ -54,9 +47,20 @@ return True; } - if (use_nss_info("sfu")) { - - if (!ads_check_sfu_mapping(ads)) { + DEBUG(10,("ad_idmap_check_attr_mapping: checking for rfc2307, sfu\n")); + if (use_nss_info("rfc2307")) { + DEBUG(10,("ad_idmap_check_attr_mapping: rfc2307 selected\n")); + 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")) { + DEBUG(10,("ad_idmap_check_attr_mapping: sfu selected\n")); + if (!ads_check_mapping(ads)) { DEBUG(0,("ad_idmap_check_attr_mapping: failed to check for SFU schema\n")); return False; } @@ -65,10 +69,23 @@ attr_gidnumber = SMB_STRDUP(ads->schema.sfu_gidnumber_attr); } else { + DEBUG(10,("ad_idmap_check_attr_mapping: nothing selected\n")); attr_uidnumber = SMB_STRDUP("uidNumber"); attr_gidnumber = SMB_STRDUP("gidNumber"); } + DEBUG(10,("ad_idmap_check_attr_mapping: returning uidnumber = %s, gidnumber = %s\n", + attr_uidnumber, attr_gidnumber)); + + if (account_attrs != NULL) { + free((void*)account_attrs); + } + account_attrs = (char**)malloc(sizeof(char*)*4); + account_attrs[0] = "sAMAccountType"; + account_attrs[1] = attr_uidnumber; + account_attrs[2] = attr_gidnumber; + account_attrs[3] = NULL; + return True; } @@ -192,16 +209,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 +271,6 @@ { ADS_STATUS rc; NTSTATUS status = NT_STATUS_NONE_MAPPED; - const char *attrs[] = { "sAMAccountType", ATTR_UIDNUMBER, ATTR_GIDNUMBER, NULL }; void *res = NULL; void *msg = NULL; char *expr = NULL; @@ -280,7 +296,9 @@ return NT_STATUS_NO_MEMORY; } - rc = ads_search_retry(ads, &res, expr, attrs); + DEBUG(10,("ad_idmap_get_id_from_sid: fetching %s, %s, %s\n", + account_attrs[0], account_attrs[1], account_attrs[2])); + rc = ads_search_retry(ads, &res, expr, (const char **)account_attrs); free(sidstr); free(expr); if (!ADS_ERR_OK(rc)) {