nsswitch/winbindd_user.c

ソースコードを見る。

データ構造

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.c31 行で定義されています。

参照先 SEC_ADSstrequal()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.c71 行で定義されています。

参照先 fill_domain_username()fillup_pw_field()idmap_sid_to_gid()idmap_sid_to_uid()winbindd_pw::pw_dirwinbindd_pw::pw_gecoswinbindd_pw::pw_gidwinbindd_pw::pw_namewinbindd_pw::pw_passwdwinbindd_pw::pw_shellwinbindd_pw::pw_uidsid_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.c130 行で定義されています。

参照先 WINBIND_USERINFO::acct_namewinbindd_response::datawinbindd_request::dataWINBIND_USERINFO::full_nameWINBIND_USERINFO::group_sidWINBIND_USERINFO::homedirwinbindd_cli_state::mem_ctxwinbindd_domain::methodswinbindd_cli_state::pidWINBIND_USERINFO::primary_gidwinbindd_methods::query_userwinbindd_cli_state::requestwinbindd_cli_state::responseWINBIND_USERINFO::shellwinbindd_domain::sidwinbindd_request::sidsid_peek_check_rid()sid_string_static()statusstring_to_sid()winbindd_response::user_infoWINBINDD_ERRORWINBINDD_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.c223 行で定義されています。

参照先 getpwsid_state::domaingetpwsid_state::fullnamegetpwsid_sid2uid_recv()getpwsid_state::gidgetpwsid_state::group_sidgetpwsid_state::homedirwinbindd_cli_state::mem_ctxwinbindd_domain::namerequest_error()getpwsid_state::shellwinbindd_domain::sidsid_append_rid()sid_copy()sid_string_static()getpwsid_state::statestrlower_m()talloc_strdup()getpwsid_state::user_sidgetpwsid_state::usernameusernamewinbindd_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.c259 行で定義されています。

参照先 getpwsid_state::domaingetpwsid_sid2gid_recv()getpwsid_state::group_sidwinbindd_cli_state::mem_ctxwinbindd_domain::namerequest_error()getpwsid_state::stategetpwsid_state::uidgetpwsid_state::usernamewinbindd_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.c276 行で定義されています。

参照先 winbindd_response::datagetpwsid_state::domainfailedfill_domain_username()fillup_pw_field()getpwsid_state::fullnamegetpwsid_state::gidgetpwsid_state::homedirwinbindd_domain::namewinbindd_response::pwwinbindd_pw::pw_dirwinbindd_pw::pw_gecoswinbindd_pw::pw_gidwinbindd_pw::pw_namewinbindd_pw::pw_passwdwinbindd_pw::pw_shellwinbindd_pw::pw_uidrequest_error()request_ok()winbindd_cli_state::responsegetpwsid_state::shellgetpwsid_state::stategetpwsid_state::uidgetpwsid_state::username.

参照元 getpwsid_sid2uid_recv().

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.c194 行で定義されています。

参照先 getpwsid_state::domainerrorfind_domain_from_sid_noinit()getpwsid_queryuser_recv()winbindd_cli_state::mem_ctxquery_user_async()request_error()sid_copy()sid_string_static()getpwsid_state::stategetpwsid_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.c382 行で定義されています。

参照先 winbindd_request::datawinbindd_cli_state::requestrequest_error()SID_NAME_COMPUTERSID_NAME_USERwinbindd_request::usernamewinbindd_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.c337 行で定義されています。

参照先 winbindd_request::datafind_domain_from_name()getpwnam_name2sid_recv()lp_workgroup()winbindd_cli_state::mem_ctxparse_domain_user()winbindd_cli_state::pidwinbindd_cli_state::requestrequest_error()strequal()winbindd_request::usernameusernamewinbindd_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.c404 行で定義されています。

参照先 winbindd_request::datawinbindd_cli_state::requestrequest_error()string_to_sid()winbindd_request::uidwinbindd_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.c425 行で定義されています。

参照先 winbindd_request::datagetpwuid_recv()winbindd_cli_state::mem_ctxwinbindd_cli_state::pidwinbindd_cli_state::requestwinbindd_request::uidwinbindd_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.c441 行で定義されています。

参照先 domain_list()free_getent_state()winbindd_cli_state::getpwent_initializedwinbindd_cli_state::getpwent_statelp_workgroup()winbindd_domain::namewinbindd_domain::nextwinbindd_cli_state::pidstrequal().

参照元 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.c508 行で定義されています。

参照先 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.c519 行で定義されています。

参照先 free_getent_state()winbindd_cli_state::getpwent_initializedwinbindd_cli_state::getpwent_statewinbindd_cli_state::pidrequest_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.c534 行で定義されています。

参照先 WINBIND_USERINFO::acct_namegetent_state::domain_namefind_domain_from_name()WINBIND_USERINFO::full_nameWINBIND_USERINFO::group_sidWINBIND_USERINFO::homedirwinbindd_domain::methodsmethodsnt_errstr()getent_state::num_sam_entriesgetent_state::sam_entriesgetent_state::sam_entry_indexWINBIND_USERINFO::shellsid_copy()statusWINBIND_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.c630 行で定義されています。

参照先 winbindd_response::datawinbindd_request::datawinbindd_response::extra_dataget_sam_user_entries()winbindd_cli_state::getpwent_initializedwinbindd_cli_state::getpwent_statewinbindd_cli_state::mem_ctxgetent_state::nextwinbindd_request::num_entriesgetent_state::num_sam_entrieswinbindd_cli_state::pidwinbindd_cli_state::requestrequest_error()winbindd_cli_state::responseresultgetent_state::sam_entriesgetent_state::sam_entry_indexwinbindd_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.c744 行で定義されています。

参照先 winbindd_response::datadomain_list()winbindd_request::domain_namewinbindd_response::extra_datafill_domain_username()winbindd_response::lengthwinbindd_cli_state::mem_ctxwinbindd_domain::methodsmethodsnamewinbindd_domain::namewinbindd_domain::nextwinbindd_cli_state::pidwinbindd_cli_state::requestrequest_error()request_ok()winbindd_cli_state::responsestatusstrequal()WINBINDD_ERRORWINBINDD_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 }


Sambaに対してSat Aug 29 21:23:58 2009に生成されました。  doxygen 1.4.7