データ構造 | |
struct | getpwsid_state |
関数 | |
static BOOL | fillup_pw_field (const char *lp_template, const char *username, const char *domname, uid_t uid, gid_t gid, const char *in, fstring out) |
static BOOL | winbindd_fill_pwent (char *dom_name, char *user_name, DOM_SID *user_sid, DOM_SID *group_sid, char *full_name, char *homedir, char *shell, struct winbindd_pw *pw) |
enum winbindd_result | winbindd_dual_userinfo (struct winbindd_domain *domain, struct winbindd_cli_state *state) |
static void | getpwsid_queryuser_recv (void *private_data, BOOL success, const char *acct_name, const char *full_name, const char *homedir, const char *shell, uint32 gid, uint32 group_rid) |
static void | getpwsid_sid2uid_recv (void *private_data, BOOL success, uid_t uid) |
static void | getpwsid_sid2gid_recv (void *private_data, BOOL success, gid_t gid) |
static void | winbindd_getpwsid (struct winbindd_cli_state *state, const DOM_SID *sid) |
static void | getpwnam_name2sid_recv (void *private_data, BOOL success, const DOM_SID *sid, enum lsa_SidType type) |
void | winbindd_getpwnam (struct winbindd_cli_state *state) |
static void | getpwuid_recv (void *private_data, BOOL success, const char *sid) |
void | winbindd_getpwuid (struct winbindd_cli_state *state) |
static BOOL | winbindd_setpwent_internal (struct winbindd_cli_state *state) |
void | winbindd_setpwent (struct winbindd_cli_state *state) |
void | winbindd_endpwent (struct winbindd_cli_state *state) |
static BOOL | get_sam_user_entries (struct getent_state *ent, TALLOC_CTX *mem_ctx) |
void | winbindd_getpwent (struct winbindd_cli_state *state) |
void | winbindd_list_users (struct winbindd_cli_state *state) |
static BOOL fillup_pw_field | ( | const char * | lp_template, | |
const char * | username, | |||
const char * | domname, | |||
uid_t | uid, | |||
gid_t | gid, | |||
const char * | in, | |||
fstring | out | |||
) | [static] |
winbindd_user.c の 31 行で定義されています。
参照先 SEC_ADS・strequal()・talloc_sub_specified().
参照元 getpwsid_sid2gid_recv()・winbindd_fill_pwent().
00038 { 00039 char *templ; 00040 00041 if (out == NULL) 00042 return False; 00043 00044 /* The substitution of %U and %D in the 'template 00045 homedir' is done by talloc_sub_specified() below. 00046 If we have an in string (which means the value has already 00047 been set in the nss_info backend), then use that. 00048 Otherwise use the template value passed in. */ 00049 00050 if ( in && !strequal(in,"") && lp_security() == SEC_ADS ) { 00051 templ = talloc_sub_specified(NULL, in, 00052 username, domname, 00053 uid, gid); 00054 } else { 00055 templ = talloc_sub_specified(NULL, lp_template, 00056 username, domname, 00057 uid, gid); 00058 } 00059 00060 if (!templ) 00061 return False; 00062 00063 safe_strcpy(out, templ, sizeof(fstring) - 1); 00064 TALLOC_FREE(templ); 00065 00066 return True; 00067 00068 }
static BOOL winbindd_fill_pwent | ( | char * | dom_name, | |
char * | user_name, | |||
DOM_SID * | user_sid, | |||
DOM_SID * | group_sid, | |||
char * | full_name, | |||
char * | homedir, | |||
char * | shell, | |||
struct winbindd_pw * | pw | |||
) | [static] |
winbindd_user.c の 71 行で定義されています。
参照先 fill_domain_username()・fillup_pw_field()・idmap_sid_to_gid()・idmap_sid_to_uid()・winbindd_pw::pw_dir・winbindd_pw::pw_gecos・winbindd_pw::pw_gid・winbindd_pw::pw_name・winbindd_pw::pw_passwd・winbindd_pw::pw_shell・winbindd_pw::pw_uid・sid_to_string()・strlower_m().
00075 { 00076 fstring output_username; 00077 fstring sid_string; 00078 00079 if (!pw || !dom_name || !user_name) 00080 return False; 00081 00082 /* Resolve the uid number */ 00083 00084 if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &pw->pw_uid))) { 00085 DEBUG(1, ("error getting user id for sid %s\n", sid_to_string(sid_string, user_sid))); 00086 return False; 00087 } 00088 00089 /* Resolve the gid number */ 00090 00091 if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &pw->pw_gid))) { 00092 DEBUG(1, ("error getting group id for sid %s\n", sid_to_string(sid_string, group_sid))); 00093 return False; 00094 } 00095 00096 strlower_m(user_name); 00097 00098 /* Username */ 00099 00100 fill_domain_username(output_username, dom_name, user_name, True); 00101 00102 safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1); 00103 00104 /* Full name (gecos) */ 00105 00106 safe_strcpy(pw->pw_gecos, full_name, sizeof(pw->pw_gecos) - 1); 00107 00108 /* Home directory and shell - use template config parameters. The 00109 defaults are /tmp for the home directory and /bin/false for 00110 shell. */ 00111 00112 if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name, 00113 pw->pw_uid, pw->pw_gid, homedir, pw->pw_dir)) 00114 return False; 00115 00116 if (!fillup_pw_field(lp_template_shell(), user_name, dom_name, 00117 pw->pw_uid, pw->pw_gid, shell, pw->pw_shell)) 00118 return False; 00119 00120 /* Password - set to "*" as we can't generate anything useful here. 00121 Authentication can be done using the pam_winbind module. */ 00122 00123 safe_strcpy(pw->pw_passwd, "*", sizeof(pw->pw_passwd) - 1); 00124 00125 return True; 00126 }
enum winbindd_result winbindd_dual_userinfo | ( | struct winbindd_domain * | domain, | |
struct winbindd_cli_state * | state | |||
) |
winbindd_user.c の 130 行で定義されています。
参照先 WINBIND_USERINFO::acct_name・winbindd_response::data・winbindd_request::data・WINBIND_USERINFO::full_name・WINBIND_USERINFO::group_sid・WINBIND_USERINFO::homedir・winbindd_cli_state::mem_ctx・winbindd_domain::methods・winbindd_cli_state::pid・WINBIND_USERINFO::primary_gid・winbindd_methods::query_user・winbindd_cli_state::request・winbindd_cli_state::response・WINBIND_USERINFO::shell・winbindd_domain::sid・winbindd_request::sid・sid_peek_check_rid()・sid_string_static()・status・string_to_sid()・winbindd_response::user_info・WINBINDD_ERROR・WINBINDD_OK.
00132 { 00133 DOM_SID sid; 00134 WINBIND_USERINFO user_info; 00135 NTSTATUS status; 00136 00137 /* Ensure null termination */ 00138 state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; 00139 00140 DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, 00141 state->request.data.sid)); 00142 00143 if (!string_to_sid(&sid, state->request.data.sid)) { 00144 DEBUG(5, ("%s not a SID\n", state->request.data.sid)); 00145 return WINBINDD_ERROR; 00146 } 00147 00148 status = domain->methods->query_user(domain, state->mem_ctx, 00149 &sid, &user_info); 00150 if (!NT_STATUS_IS_OK(status)) { 00151 DEBUG(1, ("error getting user info for sid %s\n", 00152 sid_string_static(&sid))); 00153 return WINBINDD_ERROR; 00154 } 00155 00156 fstrcpy(state->response.data.user_info.acct_name, user_info.acct_name); 00157 fstrcpy(state->response.data.user_info.full_name, user_info.full_name); 00158 fstrcpy(state->response.data.user_info.homedir, user_info.homedir); 00159 fstrcpy(state->response.data.user_info.shell, user_info.shell); 00160 state->response.data.user_info.primary_gid = user_info.primary_gid; 00161 if (!sid_peek_check_rid(&domain->sid, &user_info.group_sid, 00162 &state->response.data.user_info.group_rid)) { 00163 DEBUG(1, ("Could not extract group rid out of %s\n", 00164 sid_string_static(&sid))); 00165 return WINBINDD_ERROR; 00166 } 00167 00168 return WINBINDD_OK; 00169 }
static void getpwsid_queryuser_recv | ( | void * | private_data, | |
BOOL | success, | |||
const char * | acct_name, | |||
const char * | full_name, | |||
const char * | homedir, | |||
const char * | shell, | |||
uint32 | gid, | |||
uint32 | group_rid | |||
) | [static] |
winbindd_user.c の 223 行で定義されています。
参照先 getpwsid_state::domain・getpwsid_state::fullname・getpwsid_sid2uid_recv()・getpwsid_state::gid・getpwsid_state::group_sid・getpwsid_state::homedir・winbindd_cli_state::mem_ctx・winbindd_domain::name・request_error()・getpwsid_state::shell・winbindd_domain::sid・sid_append_rid()・sid_copy()・sid_string_static()・getpwsid_state::state・strlower_m()・talloc_strdup()・getpwsid_state::user_sid・getpwsid_state::username・username・winbindd_sid2uid_async()・ws_name_replace().
参照元 winbindd_getpwsid().
00230 { 00231 fstring username; 00232 struct getpwsid_state *s = 00233 talloc_get_type_abort(private_data, struct getpwsid_state); 00234 00235 if (!success) { 00236 DEBUG(5, ("Could not query domain %s SID %s\n", s->domain->name, 00237 sid_string_static(&s->user_sid))); 00238 request_error(s->state); 00239 return; 00240 } 00241 00242 fstrcpy( username, acct_name ); 00243 strlower_m( username ); 00244 s->username = talloc_strdup(s->state->mem_ctx, username); 00245 00246 ws_name_replace( s->username, WB_REPLACE_CHAR ); 00247 00248 s->fullname = talloc_strdup(s->state->mem_ctx, full_name); 00249 s->homedir = talloc_strdup(s->state->mem_ctx, homedir); 00250 s->shell = talloc_strdup(s->state->mem_ctx, shell); 00251 s->gid = gid; 00252 sid_copy(&s->group_sid, &s->domain->sid); 00253 sid_append_rid(&s->group_sid, group_rid); 00254 00255 winbindd_sid2uid_async(s->state->mem_ctx, &s->user_sid, 00256 getpwsid_sid2uid_recv, s); 00257 }
static void getpwsid_sid2uid_recv | ( | void * | private_data, | |
BOOL | success, | |||
uid_t | uid | |||
) | [static] |
winbindd_user.c の 259 行で定義されています。
参照先 getpwsid_state::domain・getpwsid_sid2gid_recv()・getpwsid_state::group_sid・winbindd_cli_state::mem_ctx・winbindd_domain::name・request_error()・getpwsid_state::state・getpwsid_state::uid・getpwsid_state::username・winbindd_sid2gid_async().
参照元 getpwsid_queryuser_recv().
00260 { 00261 struct getpwsid_state *s = 00262 talloc_get_type_abort(private_data, struct getpwsid_state); 00263 00264 if (!success) { 00265 DEBUG(5, ("Could not query uid for user %s\\%s\n", 00266 s->domain->name, s->username)); 00267 request_error(s->state); 00268 return; 00269 } 00270 00271 s->uid = uid; 00272 winbindd_sid2gid_async(s->state->mem_ctx, &s->group_sid, 00273 getpwsid_sid2gid_recv, s); 00274 }
static void getpwsid_sid2gid_recv | ( | void * | private_data, | |
BOOL | success, | |||
gid_t | gid | |||
) | [static] |
winbindd_user.c の 276 行で定義されています。
参照先 winbindd_response::data・getpwsid_state::domain・failed・fill_domain_username()・fillup_pw_field()・getpwsid_state::fullname・getpwsid_state::gid・getpwsid_state::homedir・winbindd_domain::name・winbindd_response::pw・winbindd_pw::pw_dir・winbindd_pw::pw_gecos・winbindd_pw::pw_gid・winbindd_pw::pw_name・winbindd_pw::pw_passwd・winbindd_pw::pw_shell・winbindd_pw::pw_uid・request_error()・request_ok()・winbindd_cli_state::response・getpwsid_state::shell・getpwsid_state::state・getpwsid_state::uid・getpwsid_state::username.
00277 { 00278 struct getpwsid_state *s = 00279 talloc_get_type_abort(private_data, struct getpwsid_state); 00280 struct winbindd_pw *pw; 00281 fstring output_username; 00282 00283 /* allow the nss backend to override the primary group ID. 00284 If the gid has already been set, then keep it. 00285 This makes me feel dirty. If the nss backend already 00286 gave us a gid, we don't really care whether the sid2gid() 00287 call worked or not. --jerry */ 00288 00289 if ( s->gid == (gid_t)-1 ) { 00290 00291 if (!success) { 00292 DEBUG(5, ("Could not query gid for user %s\\%s\n", 00293 s->domain->name, s->username)); 00294 goto failed; 00295 } 00296 00297 /* take what the sid2gid() call gave us */ 00298 s->gid = gid; 00299 } 00300 00301 pw = &s->state->response.data.pw; 00302 pw->pw_uid = s->uid; 00303 pw->pw_gid = s->gid; 00304 fill_domain_username(output_username, s->domain->name, s->username, True); 00305 safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1); 00306 safe_strcpy(pw->pw_gecos, s->fullname, sizeof(pw->pw_gecos) - 1); 00307 00308 if (!fillup_pw_field(lp_template_homedir(), s->username, s->domain->name, 00309 pw->pw_uid, pw->pw_gid, s->homedir, pw->pw_dir)) { 00310 DEBUG(5, ("Could not compose homedir\n")); 00311 goto failed; 00312 } 00313 00314 if (!fillup_pw_field(lp_template_shell(), s->username, s->domain->name, 00315 pw->pw_uid, pw->pw_gid, s->shell, pw->pw_shell)) { 00316 DEBUG(5, ("Could not compose shell\n")); 00317 goto failed; 00318 } 00319 00320 /* Password - set to "*" as we can't generate anything useful here. 00321 Authentication can be done using the pam_winbind module. */ 00322 00323 safe_strcpy(pw->pw_passwd, "*", sizeof(pw->pw_passwd) - 1); 00324 00325 request_ok(s->state); 00326 return; 00327 00328 failed: 00329 request_error(s->state); 00330 }
static void winbindd_getpwsid | ( | struct winbindd_cli_state * | state, | |
const DOM_SID * | sid | |||
) | [static] |
winbindd_user.c の 194 行で定義されています。
参照先 getpwsid_state::domain・error・find_domain_from_sid_noinit()・getpwsid_queryuser_recv()・winbindd_cli_state::mem_ctx・query_user_async()・request_error()・sid_copy()・sid_string_static()・getpwsid_state::state・getpwsid_state::user_sid.
参照元 getpwnam_name2sid_recv()・getpwuid_recv().
00196 { 00197 struct getpwsid_state *s; 00198 00199 s = TALLOC_ZERO_P(state->mem_ctx, struct getpwsid_state); 00200 if (s == NULL) { 00201 DEBUG(0, ("talloc failed\n")); 00202 goto error; 00203 } 00204 00205 s->state = state; 00206 s->domain = find_domain_from_sid_noinit(sid); 00207 if (s->domain == NULL) { 00208 DEBUG(3, ("Could not find domain for sid %s\n", 00209 sid_string_static(sid))); 00210 goto error; 00211 } 00212 00213 sid_copy(&s->user_sid, sid); 00214 00215 query_user_async(s->state->mem_ctx, s->domain, sid, 00216 getpwsid_queryuser_recv, s); 00217 return; 00218 00219 error: 00220 request_error(state); 00221 }
static void getpwnam_name2sid_recv | ( | void * | private_data, | |
BOOL | success, | |||
const DOM_SID * | sid, | |||
enum lsa_SidType | type | |||
) | [static] |
winbindd_user.c の 382 行で定義されています。
参照先 winbindd_request::data・winbindd_cli_state::request・request_error()・SID_NAME_COMPUTER・SID_NAME_USER・winbindd_request::username・winbindd_getpwsid().
参照元 winbindd_getpwnam().
00384 { 00385 struct winbindd_cli_state *state = 00386 (struct winbindd_cli_state *)private_data; 00387 00388 if (!success) { 00389 DEBUG(5, ("Could not lookup name for user %s\n", 00390 state->request.data.username)); 00391 request_error(state); 00392 return; 00393 } 00394 00395 if ((type != SID_NAME_USER) && (type != SID_NAME_COMPUTER)) { 00396 DEBUG(5, ("%s is not a user\n", state->request.data.username)); 00397 request_error(state); 00398 return; 00399 } 00400 00401 winbindd_getpwsid(state, sid); 00402 }
void winbindd_getpwnam | ( | struct winbindd_cli_state * | state | ) |
winbindd_user.c の 337 行で定義されています。
参照先 winbindd_request::data・find_domain_from_name()・getpwnam_name2sid_recv()・lp_workgroup()・winbindd_cli_state::mem_ctx・parse_domain_user()・winbindd_cli_state::pid・winbindd_cli_state::request・request_error()・strequal()・winbindd_request::username・username・winbindd_lookupname_async()・ws_name_return().
00338 { 00339 struct winbindd_domain *domain; 00340 fstring domname, username; 00341 00342 /* Ensure null termination */ 00343 state->request.data.username[sizeof(state->request.data.username)-1]='\0'; 00344 00345 DEBUG(3, ("[%5lu]: getpwnam %s\n", (unsigned long)state->pid, 00346 state->request.data.username)); 00347 00348 ws_name_return( state->request.data.username, WB_REPLACE_CHAR ); 00349 00350 if (!parse_domain_user(state->request.data.username, domname, 00351 username)) { 00352 DEBUG(5, ("Could not parse domain user: %s\n", 00353 state->request.data.username)); 00354 request_error(state); 00355 return; 00356 } 00357 00358 /* Get info for the domain */ 00359 00360 domain = find_domain_from_name(domname); 00361 00362 if (domain == NULL) { 00363 DEBUG(7, ("could not find domain entry for domain %s\n", 00364 domname)); 00365 request_error(state); 00366 return; 00367 } 00368 00369 if ( strequal(domname, lp_workgroup()) && lp_winbind_trusted_domains_only() ) { 00370 DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n", 00371 domname, username)); 00372 request_error(state); 00373 return; 00374 } 00375 00376 /* Get rid and name type from name. The following costs 1 packet */ 00377 00378 winbindd_lookupname_async(state->mem_ctx, domname, username, 00379 getpwnam_name2sid_recv, state); 00380 }
static void getpwuid_recv | ( | void * | private_data, | |
BOOL | success, | |||
const char * | sid | |||
) | [static] |
winbindd_user.c の 404 行で定義されています。
参照先 winbindd_request::data・winbindd_cli_state::request・request_error()・string_to_sid()・winbindd_request::uid・winbindd_getpwsid().
参照元 winbindd_getpwuid().
00405 { 00406 struct winbindd_cli_state *state = 00407 (struct winbindd_cli_state *)private_data; 00408 DOM_SID user_sid; 00409 00410 if (!success) { 00411 DEBUG(10,("uid2sid_recv: uid [%lu] to sid mapping failed\n.", 00412 (unsigned long)(state->request.data.uid))); 00413 request_error(state); 00414 return; 00415 } 00416 00417 DEBUG(10,("uid2sid_recv: uid %lu has sid %s\n", 00418 (unsigned long)(state->request.data.uid), sid)); 00419 00420 string_to_sid(&user_sid, sid); 00421 winbindd_getpwsid(state, &user_sid); 00422 }
void winbindd_getpwuid | ( | struct winbindd_cli_state * | state | ) |
winbindd_user.c の 425 行で定義されています。
参照先 winbindd_request::data・getpwuid_recv()・winbindd_cli_state::mem_ctx・winbindd_cli_state::pid・winbindd_cli_state::request・winbindd_request::uid・winbindd_uid2sid_async().
00426 { 00427 DEBUG(3, ("[%5lu]: getpwuid %lu\n", (unsigned long)state->pid, 00428 (unsigned long)state->request.data.uid)); 00429 00430 /* always query idmap via the async interface */ 00431 /* if this turns to be too slow we will add here a direct query to the cache */ 00432 winbindd_uid2sid_async(state->mem_ctx, state->request.data.uid, getpwuid_recv, state); 00433 }
static BOOL winbindd_setpwent_internal | ( | struct winbindd_cli_state * | state | ) | [static] |
winbindd_user.c の 441 行で定義されています。
参照先 domain_list()・free_getent_state()・winbindd_cli_state::getpwent_initialized・winbindd_cli_state::getpwent_state・lp_workgroup()・winbindd_domain::name・winbindd_domain::next・winbindd_cli_state::pid・strequal().
参照元 winbindd_getpwent()・winbindd_setpwent().
00442 { 00443 struct winbindd_domain *domain; 00444 00445 DEBUG(3, ("[%5lu]: setpwent\n", (unsigned long)state->pid)); 00446 00447 /* Check user has enabled this */ 00448 00449 if (!lp_winbind_enum_users()) { 00450 return False; 00451 } 00452 00453 /* Free old static data if it exists */ 00454 00455 if (state->getpwent_state != NULL) { 00456 free_getent_state(state->getpwent_state); 00457 state->getpwent_state = NULL; 00458 } 00459 00460 #if 0 /* JERRY */ 00461 /* add any local users we have */ 00462 00463 if ( (domain_state = (struct getent_state *)malloc(sizeof(struct getent_state))) == NULL ) 00464 return False; 00465 00466 ZERO_STRUCTP(domain_state); 00467 00468 /* Add to list of open domains */ 00469 00470 DLIST_ADD(state->getpwent_state, domain_state); 00471 #endif 00472 00473 /* Create sam pipes for each domain we know about */ 00474 00475 for(domain = domain_list(); domain != NULL; domain = domain->next) { 00476 struct getent_state *domain_state; 00477 00478 00479 /* don't add our domaina if we are a PDC or if we 00480 are a member of a Samba domain */ 00481 00482 if ( (IS_DC || lp_winbind_trusted_domains_only()) 00483 && strequal(domain->name, lp_workgroup()) ) 00484 { 00485 continue; 00486 } 00487 00488 /* Create a state record for this domain */ 00489 00490 if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) { 00491 DEBUG(0, ("malloc failed\n")); 00492 return False; 00493 } 00494 00495 ZERO_STRUCTP(domain_state); 00496 00497 fstrcpy(domain_state->domain_name, domain->name); 00498 00499 /* Add to list of open domains */ 00500 00501 DLIST_ADD(state->getpwent_state, domain_state); 00502 } 00503 00504 state->getpwent_initialized = True; 00505 return True; 00506 }
void winbindd_setpwent | ( | struct winbindd_cli_state * | state | ) |
winbindd_user.c の 508 行で定義されています。
参照先 request_error()・request_ok()・winbindd_setpwent_internal().
00509 { 00510 if (winbindd_setpwent_internal(state)) { 00511 request_ok(state); 00512 } else { 00513 request_error(state); 00514 } 00515 }
void winbindd_endpwent | ( | struct winbindd_cli_state * | state | ) |
winbindd_user.c の 519 行で定義されています。
参照先 free_getent_state()・winbindd_cli_state::getpwent_initialized・winbindd_cli_state::getpwent_state・winbindd_cli_state::pid・request_ok().
00520 { 00521 DEBUG(3, ("[%5lu]: endpwent\n", (unsigned long)state->pid)); 00522 00523 free_getent_state(state->getpwent_state); 00524 state->getpwent_initialized = False; 00525 state->getpwent_state = NULL; 00526 request_ok(state); 00527 }
static BOOL get_sam_user_entries | ( | struct getent_state * | ent, | |
TALLOC_CTX * | mem_ctx | |||
) | [static] |
winbindd_user.c の 534 行で定義されています。
参照先 WINBIND_USERINFO::acct_name・getent_state::domain_name・find_domain_from_name()・WINBIND_USERINFO::full_name・WINBIND_USERINFO::group_sid・WINBIND_USERINFO::homedir・winbindd_domain::methods・methods・nt_errstr()・getent_state::num_sam_entries・getent_state::sam_entries・getent_state::sam_entry_index・WINBIND_USERINFO::shell・sid_copy()・status・WINBIND_USERINFO::user_sid.
参照元 winbindd_getpwent().
00535 { 00536 NTSTATUS status; 00537 uint32 num_entries; 00538 WINBIND_USERINFO *info; 00539 struct getpwent_user *name_list = NULL; 00540 struct winbindd_domain *domain; 00541 struct winbindd_methods *methods; 00542 unsigned int i; 00543 00544 if (ent->num_sam_entries) 00545 return False; 00546 00547 if (!(domain = find_domain_from_name(ent->domain_name))) { 00548 DEBUG(3, ("no such domain %s in get_sam_user_entries\n", 00549 ent->domain_name)); 00550 return False; 00551 } 00552 00553 methods = domain->methods; 00554 00555 /* Free any existing user info */ 00556 00557 SAFE_FREE(ent->sam_entries); 00558 ent->num_sam_entries = 0; 00559 00560 /* Call query_user_list to get a list of usernames and user rids */ 00561 00562 num_entries = 0; 00563 00564 status = methods->query_user_list(domain, mem_ctx, &num_entries, 00565 &info); 00566 00567 if (!NT_STATUS_IS_OK(status)) { 00568 DEBUG(10,("get_sam_user_entries: query_user_list failed with %s\n", 00569 nt_errstr(status) )); 00570 return False; 00571 } 00572 00573 if (num_entries) { 00574 name_list = SMB_REALLOC_ARRAY(name_list, struct getpwent_user, ent->num_sam_entries + num_entries); 00575 00576 if (!name_list) { 00577 DEBUG(0,("get_sam_user_entries realloc failed.\n")); 00578 return False; 00579 } 00580 } 00581 00582 for (i = 0; i < num_entries; i++) { 00583 /* Store account name and gecos */ 00584 if (!info[i].acct_name) { 00585 fstrcpy(name_list[ent->num_sam_entries + i].name, ""); 00586 } else { 00587 fstrcpy(name_list[ent->num_sam_entries + i].name, 00588 info[i].acct_name); 00589 } 00590 if (!info[i].full_name) { 00591 fstrcpy(name_list[ent->num_sam_entries + i].gecos, ""); 00592 } else { 00593 fstrcpy(name_list[ent->num_sam_entries + i].gecos, 00594 info[i].full_name); 00595 } 00596 if (!info[i].homedir) { 00597 fstrcpy(name_list[ent->num_sam_entries + i].homedir, ""); 00598 } else { 00599 fstrcpy(name_list[ent->num_sam_entries + i].homedir, 00600 info[i].homedir); 00601 } 00602 if (!info[i].shell) { 00603 fstrcpy(name_list[ent->num_sam_entries + i].shell, ""); 00604 } else { 00605 fstrcpy(name_list[ent->num_sam_entries + i].shell, 00606 info[i].shell); 00607 } 00608 00609 00610 /* User and group ids */ 00611 sid_copy(&name_list[ent->num_sam_entries+i].user_sid, 00612 &info[i].user_sid); 00613 sid_copy(&name_list[ent->num_sam_entries+i].group_sid, 00614 &info[i].group_sid); 00615 } 00616 00617 ent->num_sam_entries += num_entries; 00618 00619 /* Fill in remaining fields */ 00620 00621 ent->sam_entries = name_list; 00622 ent->sam_entry_index = 0; 00623 return ent->num_sam_entries > 0; 00624 }
void winbindd_getpwent | ( | struct winbindd_cli_state * | state | ) |
winbindd_user.c の 630 行で定義されています。
参照先 winbindd_response::data・winbindd_request::data・winbindd_response::extra_data・get_sam_user_entries()・winbindd_cli_state::getpwent_initialized・winbindd_cli_state::getpwent_state・winbindd_cli_state::mem_ctx・getent_state::next・winbindd_request::num_entries・getent_state::num_sam_entries・winbindd_cli_state::pid・winbindd_cli_state::request・request_error()・winbindd_cli_state::response・result・getent_state::sam_entries・getent_state::sam_entry_index・winbindd_setpwent_internal().
00631 { 00632 struct getent_state *ent; 00633 struct winbindd_pw *user_list; 00634 int num_users, user_list_ndx; 00635 00636 DEBUG(3, ("[%5lu]: getpwent\n", (unsigned long)state->pid)); 00637 00638 /* Check user has enabled this */ 00639 00640 if (!lp_winbind_enum_users()) { 00641 request_error(state); 00642 return; 00643 } 00644 00645 /* Allocate space for returning a chunk of users */ 00646 00647 num_users = MIN(MAX_GETPWENT_USERS, state->request.data.num_entries); 00648 00649 if (num_users == 0) { 00650 request_error(state); 00651 return; 00652 } 00653 00654 if ((state->response.extra_data.data = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users)) == NULL) { 00655 request_error(state); 00656 return; 00657 } 00658 00659 memset(state->response.extra_data.data, 0, num_users * 00660 sizeof(struct winbindd_pw)); 00661 00662 user_list = (struct winbindd_pw *)state->response.extra_data.data; 00663 00664 if (!state->getpwent_initialized) 00665 winbindd_setpwent_internal(state); 00666 00667 if (!(ent = state->getpwent_state)) { 00668 request_error(state); 00669 return; 00670 } 00671 00672 /* Start sending back users */ 00673 00674 for (user_list_ndx = 0; user_list_ndx < num_users; ) { 00675 struct getpwent_user *name_list = NULL; 00676 uint32 result; 00677 00678 /* Do we need to fetch another chunk of users? */ 00679 00680 if (ent->num_sam_entries == ent->sam_entry_index) { 00681 00682 while(ent && 00683 !get_sam_user_entries(ent, state->mem_ctx)) { 00684 struct getent_state *next_ent; 00685 00686 /* Free state information for this domain */ 00687 00688 SAFE_FREE(ent->sam_entries); 00689 00690 next_ent = ent->next; 00691 DLIST_REMOVE(state->getpwent_state, ent); 00692 00693 SAFE_FREE(ent); 00694 ent = next_ent; 00695 } 00696 00697 /* No more domains */ 00698 00699 if (!ent) 00700 break; 00701 } 00702 00703 name_list = (struct getpwent_user *)ent->sam_entries; 00704 00705 /* Lookup user info */ 00706 00707 result = winbindd_fill_pwent( 00708 ent->domain_name, 00709 name_list[ent->sam_entry_index].name, 00710 &name_list[ent->sam_entry_index].user_sid, 00711 &name_list[ent->sam_entry_index].group_sid, 00712 name_list[ent->sam_entry_index].gecos, 00713 name_list[ent->sam_entry_index].homedir, 00714 name_list[ent->sam_entry_index].shell, 00715 &user_list[user_list_ndx]); 00716 00717 /* Add user to return list */ 00718 00719 if (result) { 00720 00721 user_list_ndx++; 00722 state->response.data.num_entries++; 00723 state->response.length += 00724 sizeof(struct winbindd_pw); 00725 00726 } else 00727 DEBUG(1, ("could not lookup domain user %s\n", 00728 name_list[ent->sam_entry_index].name)); 00729 00730 ent->sam_entry_index++; 00731 00732 } 00733 00734 /* Out of domains */ 00735 00736 if (user_list_ndx > 0) 00737 request_ok(state); 00738 else 00739 request_error(state); 00740 }
void winbindd_list_users | ( | struct winbindd_cli_state * | state | ) |
winbindd_user.c の 744 行で定義されています。
参照先 winbindd_response::data・domain_list()・winbindd_request::domain_name・winbindd_response::extra_data・fill_domain_username()・winbindd_response::length・winbindd_cli_state::mem_ctx・winbindd_domain::methods・methods・name・winbindd_domain::name・winbindd_domain::next・winbindd_cli_state::pid・winbindd_cli_state::request・request_error()・request_ok()・winbindd_cli_state::response・status・strequal()・WINBINDD_ERROR・WINBINDD_OK.
00745 { 00746 struct winbindd_domain *domain; 00747 WINBIND_USERINFO *info; 00748 const char *which_domain; 00749 uint32 num_entries = 0, total_entries = 0; 00750 char *extra_data = NULL; 00751 int extra_data_len = 0; 00752 enum winbindd_result rv = WINBINDD_ERROR; 00753 00754 DEBUG(3, ("[%5lu]: list users\n", (unsigned long)state->pid)); 00755 00756 /* Ensure null termination */ 00757 state->request.domain_name[sizeof(state->request.domain_name)-1]='\0'; 00758 which_domain = state->request.domain_name; 00759 00760 /* Enumerate over trusted domains */ 00761 00762 for (domain = domain_list(); domain; domain = domain->next) { 00763 NTSTATUS status; 00764 struct winbindd_methods *methods; 00765 unsigned int i; 00766 00767 /* if we have a domain name restricting the request and this 00768 one in the list doesn't match, then just bypass the remainder 00769 of the loop */ 00770 00771 if ( *which_domain && !strequal(which_domain, domain->name) ) 00772 continue; 00773 00774 methods = domain->methods; 00775 00776 /* Query display info */ 00777 status = methods->query_user_list(domain, state->mem_ctx, 00778 &num_entries, &info); 00779 00780 if (!NT_STATUS_IS_OK(status)) { 00781 continue; 00782 } 00783 00784 if (num_entries == 0) 00785 continue; 00786 00787 /* Allocate some memory for extra data */ 00788 total_entries += num_entries; 00789 00790 extra_data = (char *)SMB_REALLOC( 00791 extra_data, sizeof(fstring) * total_entries); 00792 00793 if (!extra_data) { 00794 DEBUG(0,("failed to enlarge buffer!\n")); 00795 goto done; 00796 } 00797 00798 /* Pack user list into extra data fields */ 00799 00800 for (i = 0; i < num_entries; i++) { 00801 fstring acct_name, name; 00802 00803 if (!info[i].acct_name) { 00804 fstrcpy(acct_name, ""); 00805 } else { 00806 fstrcpy(acct_name, info[i].acct_name); 00807 } 00808 00809 fill_domain_username(name, domain->name, acct_name, True); 00810 00811 /* Append to extra data */ 00812 memcpy(&extra_data[extra_data_len], name, 00813 strlen(name)); 00814 extra_data_len += strlen(name); 00815 extra_data[extra_data_len++] = ','; 00816 } 00817 } 00818 00819 /* Assign extra_data fields in response structure */ 00820 00821 if (extra_data) { 00822 extra_data[extra_data_len - 1] = '\0'; 00823 state->response.extra_data.data = extra_data; 00824 state->response.length += extra_data_len; 00825 } 00826 00827 /* No domains responded but that's still OK so don't return an 00828 error. */ 00829 00830 rv = WINBINDD_OK; 00831 00832 done: 00833 00834 if (rv == WINBINDD_OK) 00835 request_ok(state); 00836 else 00837 request_error(state); 00838 }