関数 | |
static ADS_STRUCT * | ads_cached_connection (struct winbindd_domain *domain) |
static NTSTATUS | query_user_list (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32 *num_entries, WINBIND_USERINFO **info) |
static NTSTATUS | enum_dom_groups (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32 *num_entries, struct acct_info **info) |
static NTSTATUS | enum_local_groups (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32 *num_entries, struct acct_info **info) |
static BOOL | dn_lookup (ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *dn, char **name, uint32 *name_type, DOM_SID *sid) |
static NTSTATUS | query_user (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const DOM_SID *sid, WINBIND_USERINFO *info) |
static NTSTATUS | lookup_usergroups_member (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const char *user_dn, DOM_SID *primary_group, size_t *p_num_groups, DOM_SID **user_sids) |
static NTSTATUS | lookup_usergroups_memberof (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const char *user_dn, DOM_SID *primary_group, size_t *p_num_groups, DOM_SID **user_sids) |
static NTSTATUS | lookup_usergroups (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const DOM_SID *sid, uint32 *p_num_groups, DOM_SID **user_sids) |
static NTSTATUS | lookup_groupmem (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const DOM_SID *group_sid, uint32 *num_names, DOM_SID **sid_mem, char ***names, uint32 **name_types) |
static NTSTATUS | sequence_number (struct winbindd_domain *domain, uint32 *seq) |
static NTSTATUS | trusted_domains (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32 *num_domains, char ***names, char ***alt_names, DOM_SID **dom_sids) |
変数 | |
winbindd_methods | reconnect_methods |
winbindd_methods | ads_methods |
static ADS_STRUCT* ads_cached_connection | ( | struct winbindd_domain * | domain | ) | [static] |
winbindd_ads.c の 39 行で定義されています。
参照先 ads_connect()・ads_destroy()・ads_errstr()・ads_init()・ads_kdestroy()・winbindd_domain::alt_name・ADS_STRUCT::auth・winbindd_domain::backend・ADS_STRUCT::config・ENUM_ADS_ERROR_SYSTEM・find_our_domain()・get_dc_name()・ADS_STRUCT::is_mine・lp_workgroup()・winbindd_domain::name・ADS_STRUCT::password・winbindd_domain::primary・winbindd_domain::private_data・ADS_STRUCT::realm・reconnect_methods・ADS_STRUCT::renewable・secrets_fetch_machine_password()・secrets_fetch_trusted_domain_password()・ADS_STRUCT::server・setenv()・status・strupper_m()・ADS_STRUCT::tgs_expire・ADS_STRUCT::tgt_expire・ADS_STRUCT::workgroup.
参照元 enum_dom_groups()・lookup_groupmem()・lookup_usergroups()・lookup_usergroups_member()・lookup_usergroups_memberof()・query_user()・query_user_list()・sequence_number().
00040 { 00041 ADS_STRUCT *ads; 00042 ADS_STATUS status; 00043 fstring dc_name; 00044 struct in_addr dc_ip; 00045 00046 DEBUG(10,("ads_cached_connection\n")); 00047 00048 if (domain->private_data) { 00049 00050 time_t expire; 00051 time_t now = time(NULL); 00052 00053 /* check for a valid structure */ 00054 ads = (ADS_STRUCT *)domain->private_data; 00055 00056 expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire); 00057 00058 DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n", 00059 (uint32)expire-(uint32)now, (uint32) expire, (uint32) now)); 00060 00061 if ( ads->config.realm && (expire > now)) { 00062 return ads; 00063 } else { 00064 /* we own this ADS_STRUCT so make sure it goes away */ 00065 DEBUG(7,("Deleting expired krb5 credential cache\n")); 00066 ads->is_mine = True; 00067 ads_destroy( &ads ); 00068 ads_kdestroy("MEMORY:winbind_ccache"); 00069 domain->private_data = NULL; 00070 } 00071 } 00072 00073 /* we don't want this to affect the users ccache */ 00074 setenv("KRB5CCNAME", "MEMORY:winbind_ccache", 1); 00075 00076 ads = ads_init(domain->alt_name, domain->name, NULL); 00077 if (!ads) { 00078 DEBUG(1,("ads_init for domain %s failed\n", domain->name)); 00079 return NULL; 00080 } 00081 00082 /* the machine acct password might have change - fetch it every time */ 00083 00084 SAFE_FREE(ads->auth.password); 00085 SAFE_FREE(ads->auth.realm); 00086 00087 if ( IS_DC ) { 00088 DOM_SID sid; 00089 time_t last_set_time; 00090 00091 if ( !secrets_fetch_trusted_domain_password( domain->name, &ads->auth.password, &sid, &last_set_time ) ) { 00092 ads_destroy( &ads ); 00093 return NULL; 00094 } 00095 ads->auth.realm = SMB_STRDUP( ads->server.realm ); 00096 strupper_m( ads->auth.realm ); 00097 } 00098 else { 00099 struct winbindd_domain *our_domain = domain; 00100 00101 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); 00102 00103 /* always give preference to the alt_name in our 00104 primary domain if possible */ 00105 00106 if ( !domain->primary ) 00107 our_domain = find_our_domain(); 00108 00109 if ( our_domain->alt_name[0] != '\0' ) { 00110 ads->auth.realm = SMB_STRDUP( our_domain->alt_name ); 00111 strupper_m( ads->auth.realm ); 00112 } 00113 else 00114 ads->auth.realm = SMB_STRDUP( lp_realm() ); 00115 } 00116 00117 ads->auth.renewable = WINBINDD_PAM_AUTH_KRB5_RENEW_TIME; 00118 00119 /* Setup the server affinity cache. We don't reaally care 00120 about the name. Just setup affinity and the KRB5_CONFIG 00121 file. */ 00122 00123 get_dc_name( ads->server.workgroup, ads->server.realm, dc_name, &dc_ip ); 00124 00125 status = ads_connect(ads); 00126 if (!ADS_ERR_OK(status) || !ads->config.realm) { 00127 DEBUG(1,("ads_connect for domain %s failed: %s\n", 00128 domain->name, ads_errstr(status))); 00129 ads_destroy(&ads); 00130 00131 /* if we get ECONNREFUSED then it might be a NT4 00132 server, fall back to MSRPC */ 00133 if (status.error_type == ENUM_ADS_ERROR_SYSTEM && 00134 status.err.rc == ECONNREFUSED) { 00135 /* 'reconnect_methods' is the MS-RPC backend. */ 00136 DEBUG(1,("Trying MSRPC methods\n")); 00137 domain->backend = &reconnect_methods; 00138 } 00139 return NULL; 00140 } 00141 00142 /* set the flag that says we don't own the memory even 00143 though we do so that ads_destroy() won't destroy the 00144 structure we pass back by reference */ 00145 00146 ads->is_mine = False; 00147 00148 domain->private_data = (void *)ads; 00149 return ads; 00150 }
static NTSTATUS query_user_list | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
uint32 * | num_entries, | |||
WINBIND_USERINFO ** | info | |||
) | [static] |
winbindd_ads.c の 154 行で定義されています。
参照先 ads_atype_map()・ads_cached_connection()・ads_count_replies()・ads_errstr()・ads_first_entry()・ads_msgfree()・ads_next_entry()・ads_pull_sid()・ads_pull_string()・ads_pull_uint32()・ads_pull_username()・ads_search_retry()・winbindd_domain::last_status・winbindd_domain::name・name・nss_get_info()・winbindd_domain::sid・sid_compose()・SID_NAME_USER・status.
00158 { 00159 ADS_STRUCT *ads = NULL; 00160 const char *attrs[] = { "*", NULL }; 00161 int i, count; 00162 ADS_STATUS rc; 00163 LDAPMessage *res = NULL; 00164 LDAPMessage *msg = NULL; 00165 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 00166 00167 *num_entries = 0; 00168 00169 DEBUG(3,("ads: query_user_list\n")); 00170 00171 ads = ads_cached_connection(domain); 00172 00173 if (!ads) { 00174 domain->last_status = NT_STATUS_SERVER_DISABLED; 00175 goto done; 00176 } 00177 00178 rc = ads_search_retry(ads, &res, "(objectCategory=user)", attrs); 00179 if (!ADS_ERR_OK(rc) || !res) { 00180 DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc))); 00181 goto done; 00182 } 00183 00184 count = ads_count_replies(ads, res); 00185 if (count == 0) { 00186 DEBUG(1,("query_user_list: No users found\n")); 00187 goto done; 00188 } 00189 00190 (*info) = TALLOC_ZERO_ARRAY(mem_ctx, WINBIND_USERINFO, count); 00191 if (!*info) { 00192 status = NT_STATUS_NO_MEMORY; 00193 goto done; 00194 } 00195 00196 i = 0; 00197 00198 for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { 00199 char *name, *gecos = NULL; 00200 char *homedir = NULL; 00201 char *shell = NULL; 00202 uint32 group; 00203 uint32 atype; 00204 DOM_SID user_sid; 00205 gid_t primary_gid = (gid_t)-1; 00206 00207 if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) || 00208 ads_atype_map(atype) != SID_NAME_USER) { 00209 DEBUG(1,("Not a user account? atype=0x%x\n", atype)); 00210 continue; 00211 } 00212 00213 name = ads_pull_username(ads, mem_ctx, msg); 00214 00215 if ( ads_pull_sid( ads, msg, "objectSid", &user_sid ) ) { 00216 status = nss_get_info( domain->name, &user_sid, mem_ctx, 00217 ads, msg, &homedir, &shell, &gecos, 00218 &primary_gid ); 00219 } 00220 00221 if (gecos == NULL) { 00222 gecos = ads_pull_string(ads, mem_ctx, msg, "name"); 00223 } 00224 00225 if (!ads_pull_sid(ads, msg, "objectSid", 00226 &(*info)[i].user_sid)) { 00227 DEBUG(1,("No sid for %s !?\n", name)); 00228 continue; 00229 } 00230 if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group)) { 00231 DEBUG(1,("No primary group for %s !?\n", name)); 00232 continue; 00233 } 00234 00235 (*info)[i].acct_name = name; 00236 (*info)[i].full_name = gecos; 00237 (*info)[i].homedir = homedir; 00238 (*info)[i].shell = shell; 00239 (*info)[i].primary_gid = primary_gid; 00240 sid_compose(&(*info)[i].group_sid, &domain->sid, group); 00241 i++; 00242 } 00243 00244 (*num_entries) = i; 00245 status = NT_STATUS_OK; 00246 00247 DEBUG(3,("ads query_user_list gave %d entries\n", (*num_entries))); 00248 00249 done: 00250 if (res) 00251 ads_msgfree(ads, res); 00252 00253 return status; 00254 }
static NTSTATUS enum_dom_groups | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
uint32 * | num_entries, | |||
struct acct_info ** | info | |||
) | [static] |
winbindd_ads.c の 257 行で定義されています。
参照先 ads_cached_connection()・ads_count_replies()・ads_errstr()・ads_first_entry()・ads_msgfree()・ads_next_entry()・ads_pull_sid()・ads_pull_string()・ads_pull_username()・ads_search_retry()・winbindd_domain::alt_name・winbindd_domain::last_status・name・winbindd_domain::native_mode・winbindd_domain::sid・sid_peek_check_rid()・status・strequal()・talloc_asprintf().
00261 { 00262 ADS_STRUCT *ads = NULL; 00263 const char *attrs[] = {"userPrincipalName", "sAMAccountName", 00264 "name", "objectSid", NULL}; 00265 int i, count; 00266 ADS_STATUS rc; 00267 LDAPMessage *res = NULL; 00268 LDAPMessage *msg = NULL; 00269 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 00270 const char *filter; 00271 BOOL enum_dom_local_groups = False; 00272 00273 *num_entries = 0; 00274 00275 DEBUG(3,("ads: enum_dom_groups\n")); 00276 00277 /* only grab domain local groups for our domain */ 00278 if ( domain->native_mode && strequal(lp_realm(), domain->alt_name) ) { 00279 enum_dom_local_groups = True; 00280 } 00281 00282 /* Workaround ADS LDAP bug present in MS W2K3 SP0 and W2K SP4 w/o 00283 * rollup-fixes: 00284 * 00285 * According to Section 5.1(4) of RFC 2251 if a value of a type is it's 00286 * default value, it MUST be absent. In case of extensible matching the 00287 * "dnattr" boolean defaults to FALSE and so it must be only be present 00288 * when set to TRUE. 00289 * 00290 * When it is set to FALSE and the OpenLDAP lib (correctly) encodes a 00291 * filter using bitwise matching rule then the buggy AD fails to decode 00292 * the extensible match. As a workaround set it to TRUE and thereby add 00293 * the dnAttributes "dn" field to cope with those older AD versions. 00294 * It should not harm and won't put any additional load on the AD since 00295 * none of the dn components have a bitmask-attribute. 00296 * 00297 * Thanks to Ralf Haferkamp for input and testing - Guenther */ 00298 00299 filter = talloc_asprintf(mem_ctx, "(&(objectCategory=group)(&(groupType:dn:%s:=%d)(!(groupType:dn:%s:=%d))))", 00300 ADS_LDAP_MATCHING_RULE_BIT_AND, GROUP_TYPE_SECURITY_ENABLED, 00301 ADS_LDAP_MATCHING_RULE_BIT_AND, 00302 enum_dom_local_groups ? GROUP_TYPE_BUILTIN_LOCAL_GROUP : GROUP_TYPE_RESOURCE_GROUP); 00303 00304 if (filter == NULL) { 00305 status = NT_STATUS_NO_MEMORY; 00306 goto done; 00307 } 00308 00309 ads = ads_cached_connection(domain); 00310 00311 if (!ads) { 00312 domain->last_status = NT_STATUS_SERVER_DISABLED; 00313 goto done; 00314 } 00315 00316 rc = ads_search_retry(ads, &res, filter, attrs); 00317 if (!ADS_ERR_OK(rc) || !res) { 00318 DEBUG(1,("enum_dom_groups ads_search: %s\n", ads_errstr(rc))); 00319 goto done; 00320 } 00321 00322 count = ads_count_replies(ads, res); 00323 if (count == 0) { 00324 DEBUG(1,("enum_dom_groups: No groups found\n")); 00325 goto done; 00326 } 00327 00328 (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct acct_info, count); 00329 if (!*info) { 00330 status = NT_STATUS_NO_MEMORY; 00331 goto done; 00332 } 00333 00334 i = 0; 00335 00336 for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { 00337 char *name, *gecos; 00338 DOM_SID sid; 00339 uint32 rid; 00340 00341 name = ads_pull_username(ads, mem_ctx, msg); 00342 gecos = ads_pull_string(ads, mem_ctx, msg, "name"); 00343 if (!ads_pull_sid(ads, msg, "objectSid", &sid)) { 00344 DEBUG(1,("No sid for %s !?\n", name)); 00345 continue; 00346 } 00347 00348 if (!sid_peek_check_rid(&domain->sid, &sid, &rid)) { 00349 DEBUG(1,("No rid for %s !?\n", name)); 00350 continue; 00351 } 00352 00353 fstrcpy((*info)[i].acct_name, name); 00354 fstrcpy((*info)[i].acct_desc, gecos); 00355 (*info)[i].rid = rid; 00356 i++; 00357 } 00358 00359 (*num_entries) = i; 00360 00361 status = NT_STATUS_OK; 00362 00363 DEBUG(3,("ads enum_dom_groups gave %d entries\n", (*num_entries))); 00364 00365 done: 00366 if (res) 00367 ads_msgfree(ads, res); 00368 00369 return status; 00370 }
static NTSTATUS enum_local_groups | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
uint32 * | num_entries, | |||
struct acct_info ** | info | |||
) | [static] |
winbindd_ads.c の 373 行で定義されています。
00377 { 00378 /* 00379 * This is a stub function only as we returned the domain 00380 * local groups in enum_dom_groups() if the domain->native field 00381 * was true. This is a simple performance optimization when 00382 * using LDAP. 00383 * 00384 * if we ever need to enumerate domain local groups separately, 00385 * then this the optimization in enum_dom_groups() will need 00386 * to be split out 00387 */ 00388 *num_entries = 0; 00389 00390 return NT_STATUS_OK; 00391 }
static BOOL dn_lookup | ( | ADS_STRUCT * | ads, | |
TALLOC_CTX * | mem_ctx, | |||
const char * | dn, | |||
char ** | name, | |||
uint32 * | name_type, | |||
DOM_SID * | sid | |||
) | [static] |
winbindd_ads.c の 397 行で定義されています。
参照先 ads_atype_map()・ads_msgfree()・ads_pull_sid()・ads_pull_uint32()・ads_pull_username()・ads_search_retry_dn()・failed・winbindd_domain::sid.
参照元 lookup_groupmem().
00400 { 00401 LDAPMessage *res = NULL; 00402 const char *attrs[] = {"userPrincipalName", "sAMAccountName", 00403 "objectSid", "sAMAccountType", NULL}; 00404 ADS_STATUS rc; 00405 uint32 atype; 00406 DEBUG(3,("ads: dn_lookup\n")); 00407 00408 rc = ads_search_retry_dn(ads, &res, dn, attrs); 00409 00410 if (!ADS_ERR_OK(rc) || !res) { 00411 goto failed; 00412 } 00413 00414 (*name) = ads_pull_username(ads, mem_ctx, res); 00415 00416 if (!ads_pull_uint32(ads, res, "sAMAccountType", &atype)) { 00417 goto failed; 00418 } 00419 (*name_type) = ads_atype_map(atype); 00420 00421 if (!ads_pull_sid(ads, res, "objectSid", sid)) { 00422 goto failed; 00423 } 00424 00425 if (res) 00426 ads_msgfree(ads, res); 00427 00428 return True; 00429 00430 failed: 00431 if (res) 00432 ads_msgfree(ads, res); 00433 00434 return False; 00435 }
static NTSTATUS query_user | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
const DOM_SID * | sid, | |||
WINBIND_USERINFO * | info | |||
) | [static] |
winbindd_ads.c の 438 行で定義されています。
参照先 WINBIND_USERINFO::acct_name・ads_cached_connection()・ads_count_replies()・ads_errstr()・ads_msgfree()・ads_pull_string()・ads_pull_uint32()・ads_pull_username()・ads_search_retry()・asprintf()・WINBIND_USERINFO::full_name・WINBIND_USERINFO::group_sid・WINBIND_USERINFO::homedir・winbindd_domain::last_status・winbindd_domain::name・nss_get_info()・WINBIND_USERINFO::primary_gid・WINBIND_USERINFO::shell・winbindd_domain::sid・sid_binstring()・sid_compose()・sid_copy()・sid_string_static()・status・WINBIND_USERINFO::user_sid.
00442 { 00443 ADS_STRUCT *ads = NULL; 00444 const char *attrs[] = { "*", NULL }; 00445 ADS_STATUS rc; 00446 int count; 00447 LDAPMessage *msg = NULL; 00448 char *ldap_exp; 00449 char *sidstr; 00450 uint32 group_rid; 00451 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 00452 00453 DEBUG(3,("ads: query_user\n")); 00454 00455 if ( (ads = ads_cached_connection(domain)) == NULL ) { 00456 domain->last_status = NT_STATUS_SERVER_DISABLED; 00457 goto done; 00458 } 00459 00460 sidstr = sid_binstring(sid); 00461 asprintf(&ldap_exp, "(objectSid=%s)", sidstr); 00462 rc = ads_search_retry(ads, &msg, ldap_exp, attrs); 00463 free(ldap_exp); 00464 free(sidstr); 00465 if (!ADS_ERR_OK(rc) || !msg) { 00466 DEBUG(1,("query_user(sid=%s) ads_search: %s\n", 00467 sid_string_static(sid), ads_errstr(rc))); 00468 goto done; 00469 } 00470 00471 count = ads_count_replies(ads, msg); 00472 if (count != 1) { 00473 DEBUG(1,("query_user(sid=%s): Not found\n", 00474 sid_string_static(sid))); 00475 goto done; 00476 } 00477 00478 info->acct_name = ads_pull_username(ads, mem_ctx, msg); 00479 00480 info->primary_gid = (gid_t)-1; 00481 nss_get_info( domain->name, sid, mem_ctx, ads, msg, 00482 &info->homedir, &info->shell, &info->full_name, &info->primary_gid ); 00483 00484 if (info->full_name == NULL) { 00485 info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); 00486 } 00487 00488 if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) { 00489 DEBUG(1,("No primary group for %s !?\n", 00490 sid_string_static(sid))); 00491 goto done; 00492 } 00493 00494 sid_copy(&info->user_sid, sid); 00495 sid_compose(&info->group_sid, &domain->sid, group_rid); 00496 00497 status = NT_STATUS_OK; 00498 00499 DEBUG(3,("ads query_user gave %s\n", info->acct_name)); 00500 done: 00501 if (msg) 00502 ads_msgfree(ads, msg); 00503 00504 return status; 00505 }
static NTSTATUS lookup_usergroups_member | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
const char * | user_dn, | |||
DOM_SID * | primary_group, | |||
size_t * | p_num_groups, | |||
DOM_SID ** | user_sids | |||
) | [static] |
winbindd_ads.c の 509 行で定義されています。
参照先 add_sid_to_array()・ads_cached_connection()・ads_count_replies()・ads_errstr()・ads_first_entry()・ads_msgfree()・ads_next_entry()・ads_ntstatus()・ads_pull_sid()・ads_search_retry()・escape_ldap_string_alloc()・winbindd_domain::last_status・sid_check_is_in_builtin()・status・talloc_asprintf().
参照元 lookup_usergroups().
00514 { 00515 ADS_STATUS rc; 00516 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 00517 int count; 00518 LDAPMessage *res = NULL; 00519 LDAPMessage *msg = NULL; 00520 char *ldap_exp; 00521 ADS_STRUCT *ads; 00522 const char *group_attrs[] = {"objectSid", NULL}; 00523 char *escaped_dn; 00524 size_t num_groups = 0; 00525 00526 DEBUG(3,("ads: lookup_usergroups_member\n")); 00527 00528 ads = ads_cached_connection(domain); 00529 00530 if (!ads) { 00531 domain->last_status = NT_STATUS_SERVER_DISABLED; 00532 goto done; 00533 } 00534 00535 if (!(escaped_dn = escape_ldap_string_alloc(user_dn))) { 00536 status = NT_STATUS_NO_MEMORY; 00537 goto done; 00538 } 00539 00540 if (!(ldap_exp = talloc_asprintf(mem_ctx, "(&(member=%s)(objectCategory=group))", escaped_dn))) { 00541 DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn)); 00542 SAFE_FREE(escaped_dn); 00543 status = NT_STATUS_NO_MEMORY; 00544 goto done; 00545 } 00546 00547 SAFE_FREE(escaped_dn); 00548 00549 rc = ads_search_retry(ads, &res, ldap_exp, group_attrs); 00550 00551 if (!ADS_ERR_OK(rc) || !res) { 00552 DEBUG(1,("lookup_usergroups ads_search member=%s: %s\n", user_dn, ads_errstr(rc))); 00553 return ads_ntstatus(rc); 00554 } 00555 00556 count = ads_count_replies(ads, res); 00557 00558 *user_sids = NULL; 00559 num_groups = 0; 00560 00561 /* always add the primary group to the sid array */ 00562 if (!add_sid_to_array(mem_ctx, primary_group, user_sids, &num_groups)) { 00563 status = NT_STATUS_NO_MEMORY; 00564 goto done; 00565 } 00566 00567 if (count > 0) { 00568 for (msg = ads_first_entry(ads, res); msg; 00569 msg = ads_next_entry(ads, msg)) { 00570 DOM_SID group_sid; 00571 00572 if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) { 00573 DEBUG(1,("No sid for this group ?!?\n")); 00574 continue; 00575 } 00576 00577 /* ignore Builtin groups from ADS - Guenther */ 00578 if (sid_check_is_in_builtin(&group_sid)) { 00579 continue; 00580 } 00581 00582 if (!add_sid_to_array(mem_ctx, &group_sid, user_sids, 00583 &num_groups)) { 00584 status = NT_STATUS_NO_MEMORY; 00585 goto done; 00586 } 00587 } 00588 00589 } 00590 00591 *p_num_groups = num_groups; 00592 status = (user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; 00593 00594 DEBUG(3,("ads lookup_usergroups (member) succeeded for dn=%s\n", user_dn)); 00595 done: 00596 if (res) 00597 ads_msgfree(ads, res); 00598 00599 return status; 00600 }
static NTSTATUS lookup_usergroups_memberof | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
const char * | user_dn, | |||
DOM_SID * | primary_group, | |||
size_t * | p_num_groups, | |||
DOM_SID ** | user_sids | |||
) | [static] |
winbindd_ads.c の 604 行で定義されています。
参照先 add_sid_to_array()・ads_cached_connection()・ads_count_replies()・ads_errstr()・ADS_EXTENDED_DN_HEX_STRING・ads_msgfree()・ads_ntstatus()・ads_pull_sids_from_extendeddn()・ads_search_retry_extended_dn()・winbindd_domain::last_status・sid_check_is_in_builtin()・status.
参照元 lookup_usergroups().
00609 { 00610 ADS_STATUS rc; 00611 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 00612 int count; 00613 LDAPMessage *res = NULL; 00614 ADS_STRUCT *ads; 00615 const char *attrs[] = {"memberOf", NULL}; 00616 size_t num_groups = 0; 00617 DOM_SID *group_sids = NULL; 00618 int i; 00619 00620 DEBUG(3,("ads: lookup_usergroups_memberof\n")); 00621 00622 ads = ads_cached_connection(domain); 00623 00624 if (!ads) { 00625 domain->last_status = NT_STATUS_SERVER_DISABLED; 00626 goto done; 00627 } 00628 00629 rc = ads_search_retry_extended_dn(ads, &res, user_dn, attrs, 00630 ADS_EXTENDED_DN_HEX_STRING); 00631 00632 if (!ADS_ERR_OK(rc) || !res) { 00633 DEBUG(1,("lookup_usergroups_memberof ads_search member=%s: %s\n", 00634 user_dn, ads_errstr(rc))); 00635 return ads_ntstatus(rc); 00636 } 00637 00638 count = ads_count_replies(ads, res); 00639 00640 if (count == 0) { 00641 status = NT_STATUS_NO_SUCH_USER; 00642 goto done; 00643 } 00644 00645 *user_sids = NULL; 00646 num_groups = 0; 00647 00648 /* always add the primary group to the sid array */ 00649 if (!add_sid_to_array(mem_ctx, primary_group, user_sids, &num_groups)) { 00650 status = NT_STATUS_NO_MEMORY; 00651 goto done; 00652 } 00653 00654 count = ads_pull_sids_from_extendeddn(ads, mem_ctx, res, "memberOf", 00655 ADS_EXTENDED_DN_HEX_STRING, 00656 &group_sids); 00657 if (count == 0) { 00658 DEBUG(1,("No memberOf for this user?!?\n")); 00659 status = NT_STATUS_NO_MEMORY; 00660 goto done; 00661 } 00662 00663 for (i=0; i<count; i++) { 00664 00665 /* ignore Builtin groups from ADS - Guenther */ 00666 if (sid_check_is_in_builtin(&group_sids[i])) { 00667 continue; 00668 } 00669 00670 if (!add_sid_to_array(mem_ctx, &group_sids[i], user_sids, 00671 &num_groups)) { 00672 status = NT_STATUS_NO_MEMORY; 00673 goto done; 00674 } 00675 00676 } 00677 00678 *p_num_groups = num_groups; 00679 status = (*user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; 00680 00681 DEBUG(3,("ads lookup_usergroups (memberof) succeeded for dn=%s\n", user_dn)); 00682 done: 00683 TALLOC_FREE(group_sids); 00684 if (res) 00685 ads_msgfree(ads, res); 00686 00687 return status; 00688 }
static NTSTATUS lookup_usergroups | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
const DOM_SID * | sid, | |||
uint32 * | p_num_groups, | |||
DOM_SID ** | user_sids | |||
) | [static] |
winbindd_ads.c の 692 行で定義されています。
参照先 add_sid_to_array()・add_sid_to_array_unique()・ads_cached_connection()・ads_count_replies()・ads_errstr()・ads_get_dn()・ads_memfree()・ads_msgfree()・ads_ntstatus()・ads_pull_sids()・ads_pull_uint32()・ads_search_retry_sid()・winbindd_domain::last_status・lookup_usergroups_cached()・lookup_usergroups_member()・lookup_usergroups_memberof()・winbindd_domain::name・winbindd_domain::sid・sid_append_rid()・sid_check_is_in_builtin()・sid_copy()・sid_to_string()・status.
00696 { 00697 ADS_STRUCT *ads = NULL; 00698 const char *attrs[] = {"tokenGroups", "primaryGroupID", NULL}; 00699 ADS_STATUS rc; 00700 int count; 00701 LDAPMessage *msg = NULL; 00702 char *user_dn = NULL; 00703 DOM_SID *sids; 00704 int i; 00705 DOM_SID primary_group; 00706 uint32 primary_group_rid; 00707 fstring sid_string; 00708 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 00709 size_t num_groups = 0; 00710 00711 DEBUG(3,("ads: lookup_usergroups\n")); 00712 *p_num_groups = 0; 00713 00714 status = lookup_usergroups_cached(domain, mem_ctx, sid, 00715 p_num_groups, user_sids); 00716 if (NT_STATUS_IS_OK(status)) { 00717 return NT_STATUS_OK; 00718 } 00719 00720 ads = ads_cached_connection(domain); 00721 00722 if (!ads) { 00723 domain->last_status = NT_STATUS_SERVER_DISABLED; 00724 status = NT_STATUS_SERVER_DISABLED; 00725 goto done; 00726 } 00727 00728 rc = ads_search_retry_sid(ads, &msg, sid, attrs); 00729 00730 if (!ADS_ERR_OK(rc)) { 00731 status = ads_ntstatus(rc); 00732 DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: %s\n", 00733 sid_to_string(sid_string, sid), ads_errstr(rc))); 00734 goto done; 00735 } 00736 00737 count = ads_count_replies(ads, msg); 00738 if (count != 1) { 00739 status = NT_STATUS_UNSUCCESSFUL; 00740 DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: " 00741 "invalid number of results (count=%d)\n", 00742 sid_to_string(sid_string, sid), count)); 00743 goto done; 00744 } 00745 00746 if (!msg) { 00747 DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n", 00748 sid_to_string(sid_string, sid))); 00749 status = NT_STATUS_UNSUCCESSFUL; 00750 goto done; 00751 } 00752 00753 user_dn = ads_get_dn(ads, msg); 00754 if (user_dn == NULL) { 00755 status = NT_STATUS_NO_MEMORY; 00756 goto done; 00757 } 00758 00759 if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group_rid)) { 00760 DEBUG(1,("%s: No primary group for sid=%s !?\n", 00761 domain->name, sid_to_string(sid_string, sid))); 00762 goto done; 00763 } 00764 00765 sid_copy(&primary_group, &domain->sid); 00766 sid_append_rid(&primary_group, primary_group_rid); 00767 00768 count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids); 00769 00770 /* there must always be at least one group in the token, 00771 unless we are talking to a buggy Win2k server */ 00772 00773 /* actually this only happens when the machine account has no read 00774 * permissions on the tokenGroup attribute - gd */ 00775 00776 if (count == 0) { 00777 00778 /* no tokenGroups */ 00779 00780 /* lookup what groups this user is a member of by DN search on 00781 * "memberOf" */ 00782 00783 status = lookup_usergroups_memberof(domain, mem_ctx, user_dn, 00784 &primary_group, 00785 &num_groups, user_sids); 00786 *p_num_groups = (uint32)num_groups; 00787 if (NT_STATUS_IS_OK(status)) { 00788 goto done; 00789 } 00790 00791 /* lookup what groups this user is a member of by DN search on 00792 * "member" */ 00793 00794 status = lookup_usergroups_member(domain, mem_ctx, user_dn, 00795 &primary_group, 00796 &num_groups, user_sids); 00797 *p_num_groups = (uint32)num_groups; 00798 goto done; 00799 } 00800 00801 *user_sids = NULL; 00802 num_groups = 0; 00803 00804 if (!add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups)) { 00805 status = NT_STATUS_NO_MEMORY; 00806 goto done; 00807 } 00808 00809 for (i=0;i<count;i++) { 00810 00811 /* ignore Builtin groups from ADS - Guenther */ 00812 if (sid_check_is_in_builtin(&sids[i])) { 00813 continue; 00814 } 00815 00816 if (!add_sid_to_array_unique(mem_ctx, &sids[i], 00817 user_sids, &num_groups)) { 00818 status = NT_STATUS_NO_MEMORY; 00819 goto done; 00820 } 00821 } 00822 00823 *p_num_groups = (uint32)num_groups; 00824 status = (*user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; 00825 00826 DEBUG(3,("ads lookup_usergroups (tokenGroups) succeeded for sid=%s\n", 00827 sid_to_string(sid_string, sid))); 00828 done: 00829 ads_memfree(ads, user_dn); 00830 ads_msgfree(ads, msg); 00831 return status; 00832 }
static NTSTATUS lookup_groupmem | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
const DOM_SID * | group_sid, | |||
uint32 * | num_names, | |||
DOM_SID ** | sid_mem, | |||
char *** | names, | |||
uint32 ** | name_types | |||
) | [static] |
winbindd_ads.c の 837 行で定義されています。
参照先 ads_cached_connection()・ads_count_replies()・ads_errstr()・ads_msgfree()・ads_ntstatus()・ads_pull_strings_range()・ads_pull_uint32()・ads_search_retry()・dn_lookup()・winbindd_domain::last_status・name・winbindd_domain::name・name_type・winbindd_domain::sid・sid_binstring()・sid_copy()・sid_string_static()・sid_to_string()・status・talloc_asprintf()・talloc_strdup().
00842 { 00843 ADS_STATUS rc; 00844 int count; 00845 LDAPMessage *res=NULL; 00846 ADS_STRUCT *ads = NULL; 00847 char *ldap_exp; 00848 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 00849 char *sidstr; 00850 char **members; 00851 int i; 00852 size_t num_members; 00853 fstring sid_string; 00854 BOOL more_values; 00855 const char **attrs; 00856 uint32 first_usn; 00857 uint32 current_usn; 00858 int num_retries = 0; 00859 00860 DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, 00861 sid_string_static(group_sid))); 00862 00863 *num_names = 0; 00864 00865 ads = ads_cached_connection(domain); 00866 00867 if (!ads) { 00868 domain->last_status = NT_STATUS_SERVER_DISABLED; 00869 goto done; 00870 } 00871 00872 if ((sidstr = sid_binstring(group_sid)) == NULL) { 00873 status = NT_STATUS_NO_MEMORY; 00874 goto done; 00875 } 00876 00877 /* search for all members of the group */ 00878 if (!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)",sidstr))) { 00879 SAFE_FREE(sidstr); 00880 DEBUG(1, ("ads: lookup_groupmem: tallloc_asprintf for ldap_exp failed!\n")); 00881 status = NT_STATUS_NO_MEMORY; 00882 goto done; 00883 } 00884 SAFE_FREE(sidstr); 00885 00886 members = NULL; 00887 num_members = 0; 00888 00889 if ((attrs = TALLOC_ARRAY(mem_ctx, const char *, 3)) == NULL) { 00890 status = NT_STATUS_NO_MEMORY; 00891 goto done; 00892 } 00893 00894 attrs[1] = talloc_strdup(mem_ctx, "usnChanged"); 00895 attrs[2] = NULL; 00896 00897 do { 00898 if (num_members == 0) 00899 attrs[0] = talloc_strdup(mem_ctx, "member"); 00900 00901 DEBUG(10, ("Searching for attrs[0] = %s, attrs[1] = %s\n", attrs[0], attrs[1])); 00902 00903 rc = ads_search_retry(ads, &res, ldap_exp, attrs); 00904 00905 if (!ADS_ERR_OK(rc) || !res) { 00906 DEBUG(1,("ads: lookup_groupmem ads_search: %s\n", 00907 ads_errstr(rc))); 00908 status = ads_ntstatus(rc); 00909 goto done; 00910 } 00911 00912 count = ads_count_replies(ads, res); 00913 if (count == 0) 00914 break; 00915 00916 if (num_members == 0) { 00917 if (!ads_pull_uint32(ads, res, "usnChanged", &first_usn)) { 00918 DEBUG(1, ("ads: lookup_groupmem could not pull usnChanged!\n")); 00919 goto done; 00920 } 00921 } 00922 00923 if (!ads_pull_uint32(ads, res, "usnChanged", ¤t_usn)) { 00924 DEBUG(1, ("ads: lookup_groupmem could not pull usnChanged!\n")); 00925 goto done; 00926 } 00927 00928 if (first_usn != current_usn) { 00929 DEBUG(5, ("ads: lookup_groupmem USN on this record changed" 00930 " - restarting search\n")); 00931 if (num_retries < 5) { 00932 num_retries++; 00933 num_members = 0; 00934 ads_msgfree(ads, res); 00935 res = NULL; 00936 continue; 00937 } else { 00938 DEBUG(5, ("ads: lookup_groupmem USN on this record changed" 00939 " - restarted search too many times, aborting!\n")); 00940 status = NT_STATUS_UNSUCCESSFUL; 00941 goto done; 00942 } 00943 } 00944 00945 members = ads_pull_strings_range(ads, mem_ctx, res, 00946 "member", 00947 members, 00948 &attrs[0], 00949 &num_members, 00950 &more_values); 00951 00952 ads_msgfree(ads, res); 00953 res = NULL; 00954 00955 if ((members == NULL) || (num_members == 0)) 00956 break; 00957 00958 } while (more_values); 00959 00960 /* now we need to turn a list of members into rids, names and name types 00961 the problem is that the members are in the form of distinguised names 00962 */ 00963 00964 if (num_members) { 00965 (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members); 00966 (*name_types) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_members); 00967 (*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members); 00968 00969 if ((members == NULL) || (*sid_mem == NULL) || 00970 (*name_types == NULL) || (*names == NULL)) { 00971 DEBUG(1, ("talloc failed\n")); 00972 status = NT_STATUS_NO_MEMORY; 00973 goto done; 00974 } 00975 } else { 00976 (*sid_mem) = NULL; 00977 (*name_types) = NULL; 00978 (*names) = NULL; 00979 } 00980 00981 for (i=0;i<num_members;i++) { 00982 uint32 name_type; 00983 char *name; 00984 DOM_SID sid; 00985 00986 if (dn_lookup(ads, mem_ctx, members[i], &name, &name_type, &sid)) { 00987 (*names)[*num_names] = name; 00988 (*name_types)[*num_names] = name_type; 00989 sid_copy(&(*sid_mem)[*num_names], &sid); 00990 (*num_names)++; 00991 } 00992 } 00993 00994 status = NT_STATUS_OK; 00995 DEBUG(3,("ads lookup_groupmem for sid=%s\n", sid_to_string(sid_string, group_sid))); 00996 done: 00997 00998 if (res) 00999 ads_msgfree(ads, res); 01000 01001 return status; 01002 }
static NTSTATUS sequence_number | ( | struct winbindd_domain * | domain, | |
uint32 * | seq | |||
) | [static] |
winbindd_ads.c の 1005 行で定義されています。
参照先 ads_cached_connection()・ads_destroy()・ads_kdestroy()・ads_ntstatus()・ads_USN()・ADS_STRUCT::is_mine・winbindd_domain::last_status・winbindd_domain::name・winbindd_domain::private_data.
01006 { 01007 ADS_STRUCT *ads = NULL; 01008 ADS_STATUS rc; 01009 01010 DEBUG(3,("ads: fetch sequence_number for %s\n", domain->name)); 01011 01012 *seq = DOM_SEQUENCE_NONE; 01013 01014 ads = ads_cached_connection(domain); 01015 01016 if (!ads) { 01017 domain->last_status = NT_STATUS_SERVER_DISABLED; 01018 return NT_STATUS_UNSUCCESSFUL; 01019 } 01020 01021 rc = ads_USN(ads, seq); 01022 01023 if (!ADS_ERR_OK(rc)) { 01024 01025 /* its a dead connection, destroy it */ 01026 01027 if (domain->private_data) { 01028 ads = (ADS_STRUCT *)domain->private_data; 01029 ads->is_mine = True; 01030 ads_destroy(&ads); 01031 ads_kdestroy("MEMORY:winbind_ccache"); 01032 domain->private_data = NULL; 01033 } 01034 } 01035 return ads_ntstatus(rc); 01036 }
static NTSTATUS trusted_domains | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
uint32 * | num_domains, | |||
char *** | names, | |||
char *** | alt_names, | |||
DOM_SID ** | dom_sids | |||
) | [static] |
winbindd_ads.c の 1039 行で定義されています。
参照先 cli・cm_connect_netlogon()・cli_state::desthost・ds_domain_trust::dns_domain・rpc_pipe_client::domain・flags・nt_errstr()・result・rpccli_ds_enum_domain_trusts()・sid_copy().
01045 { 01046 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 01047 struct ds_domain_trust *domains = NULL; 01048 int count = 0; 01049 int i; 01050 uint32 flags = DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND; 01051 struct rpc_pipe_client *cli; 01052 01053 DEBUG(3,("ads: trusted_domains\n")); 01054 01055 *num_domains = 0; 01056 *alt_names = NULL; 01057 *names = NULL; 01058 *dom_sids = NULL; 01059 01060 result = cm_connect_netlogon(domain, &cli); 01061 01062 if (!NT_STATUS_IS_OK(result)) { 01063 DEBUG(5, ("trusted_domains: Could not open a connection to %s " 01064 "for PIPE_NETLOGON (%s)\n", 01065 domain->name, nt_errstr(result))); 01066 return NT_STATUS_UNSUCCESSFUL; 01067 } 01068 01069 if ( NT_STATUS_IS_OK(result) ) { 01070 result = rpccli_ds_enum_domain_trusts(cli, mem_ctx, 01071 cli->cli->desthost, 01072 flags, &domains, 01073 (unsigned int *)&count); 01074 } 01075 01076 if ( NT_STATUS_IS_OK(result) && count) { 01077 01078 /* Allocate memory for trusted domain names and sids */ 01079 01080 if ( !(*names = TALLOC_ARRAY(mem_ctx, char *, count)) ) { 01081 DEBUG(0, ("trusted_domains: out of memory\n")); 01082 return NT_STATUS_NO_MEMORY; 01083 } 01084 01085 if ( !(*alt_names = TALLOC_ARRAY(mem_ctx, char *, count)) ) { 01086 DEBUG(0, ("trusted_domains: out of memory\n")); 01087 return NT_STATUS_NO_MEMORY; 01088 } 01089 01090 if ( !(*dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, count)) ) { 01091 DEBUG(0, ("trusted_domains: out of memory\n")); 01092 return NT_STATUS_NO_MEMORY; 01093 } 01094 01095 /* Copy across names and sids */ 01096 01097 for (i = 0; i < count; i++) { 01098 (*names)[i] = domains[i].netbios_domain; 01099 (*alt_names)[i] = domains[i].dns_domain; 01100 01101 sid_copy(&(*dom_sids)[i], &domains[i].sid); 01102 } 01103 01104 *num_domains = count; 01105 } 01106 01107 return result; 01108 }
struct winbindd_methods ads_methods |
初期値:
{ True, query_user_list, enum_dom_groups, enum_local_groups, msrpc_name_to_sid, msrpc_sid_to_name, msrpc_rids_to_names, query_user, lookup_usergroups, msrpc_lookup_useraliases, lookup_groupmem, sequence_number, msrpc_lockout_policy, msrpc_password_policy, trusted_domains, }
winbindd_ads.c の 1111 行で定義されています。
参照元 get_cache().