smbd/password.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Password and authentication handling
00004    Copyright (C) Andrew Tridgell 1992-1998
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 #include "includes.h"
00022 
00023 /* users from session setup */
00024 static char *session_userlist = NULL;
00025 static int len_session_userlist = 0;
00026 /* workgroup from session setup. */
00027 static char *session_workgroup = NULL;
00028 
00029 /* this holds info on user ids that are already validated for this VC */
00030 static user_struct *validated_users;
00031 static int next_vuid = VUID_OFFSET;
00032 static int num_validated_vuids;
00033 
00034 /****************************************************************************
00035  Check if a uid has been validated, and return an pointer to the user_struct
00036  if it has. NULL if not. vuid is biased by an offset. This allows us to
00037  tell random client vuid's (normally zero) from valid vuids.
00038 ****************************************************************************/
00039 
00040 user_struct *get_valid_user_struct(uint16 vuid)
00041 {
00042         user_struct *usp;
00043         int count=0;
00044 
00045         if (vuid == UID_FIELD_INVALID)
00046                 return NULL;
00047 
00048         for (usp=validated_users;usp;usp=usp->next,count++) {
00049                 if (vuid == usp->vuid && usp->server_info) {
00050                         if (count > 10) {
00051                                 DLIST_PROMOTE(validated_users, usp);
00052                         }
00053                         return usp;
00054                 }
00055         }
00056 
00057         return NULL;
00058 }
00059 
00060 /****************************************************************************
00061  Get the user struct of a partial NTLMSSP login
00062 ****************************************************************************/
00063 
00064 user_struct *get_partial_auth_user_struct(uint16 vuid)
00065 {
00066         user_struct *usp;
00067         int count=0;
00068 
00069         if (vuid == UID_FIELD_INVALID)
00070                 return NULL;
00071 
00072         for (usp=validated_users;usp;usp=usp->next,count++) {
00073                 if (vuid == usp->vuid && !usp->server_info) {
00074                         if (count > 10) {
00075                                 DLIST_PROMOTE(validated_users, usp);
00076                         }
00077                         return usp;
00078                 }
00079         }
00080 
00081         return NULL;
00082 }
00083 
00084 /****************************************************************************
00085  Invalidate a uid.
00086 ****************************************************************************/
00087 
00088 void invalidate_vuid(uint16 vuid)
00089 {
00090         user_struct *vuser = get_valid_user_struct(vuid);
00091 
00092         if (vuser == NULL)
00093                 return;
00094 
00095         SAFE_FREE(vuser->homedir);
00096         SAFE_FREE(vuser->unix_homedir);
00097         SAFE_FREE(vuser->logon_script);
00098 
00099         if (vuser->auth_ntlmssp_state) {
00100                 auth_ntlmssp_end(&vuser->auth_ntlmssp_state);
00101         }
00102 
00103         session_yield(vuser);
00104         SAFE_FREE(vuser->session_keystr);
00105 
00106         TALLOC_FREE(vuser->server_info);
00107 
00108         data_blob_free(&vuser->session_key);
00109 
00110         DLIST_REMOVE(validated_users, vuser);
00111 
00112         /* clear the vuid from the 'cache' on each connection, and
00113            from the vuid 'owner' of connections */
00114         conn_clear_vuid_cache(vuid);
00115 
00116         SAFE_FREE(vuser->groups);
00117         TALLOC_FREE(vuser->nt_user_token);
00118 
00119         SAFE_FREE(vuser);
00120         num_validated_vuids--;
00121 }
00122 
00123 void invalidate_intermediate_vuid(uint16 vuid)
00124 {
00125         user_struct *vuser = get_partial_auth_user_struct(vuid);
00126 
00127         if (vuser == NULL)
00128                 return;
00129 
00130         if (vuser->auth_ntlmssp_state) {
00131                 auth_ntlmssp_end(&vuser->auth_ntlmssp_state);
00132         }
00133 
00134         DLIST_REMOVE(validated_users, vuser);
00135 
00136         SAFE_FREE(vuser);
00137         num_validated_vuids--;
00138 }
00139 
00140 /****************************************************************************
00141  Invalidate all vuid entries for this process.
00142 ****************************************************************************/
00143 
00144 void invalidate_all_vuids(void)
00145 {
00146         user_struct *usp, *next=NULL;
00147 
00148         for (usp=validated_users;usp;usp=next) {
00149                 next = usp->next;
00150                 
00151                 invalidate_vuid(usp->vuid);
00152         }
00153 }
00154 
00155 /**
00156  *  register that a valid login has been performed, establish 'session'.
00157  *  @param server_info The token returned from the authentication process. 
00158  *   (now 'owned' by register_vuid)
00159  *
00160  *  @param session_key The User session key for the login session (now also
00161  *  'owned' by register_vuid)
00162  *
00163  *  @param respose_blob The NT challenge-response, if available.  (May be
00164  *  freed after this call)
00165  *
00166  *  @param smb_name The untranslated name of the user
00167  *
00168  *  @return Newly allocated vuid, biased by an offset. (This allows us to
00169  *   tell random client vuid's (normally zero) from valid vuids.)
00170  *
00171  */
00172 
00173 int register_vuid(auth_serversupplied_info *server_info,
00174                   DATA_BLOB session_key, DATA_BLOB response_blob,
00175                   const char *smb_name)
00176 {
00177         user_struct *vuser = NULL;
00178 
00179         /* Paranoia check. */
00180         if(lp_security() == SEC_SHARE) {
00181                 smb_panic("Tried to register uid in security=share\n");
00182         }
00183 
00184         /* Limit allowed vuids to 16bits - VUID_OFFSET. */
00185         if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) {
00186                 data_blob_free(&session_key);
00187                 TALLOC_FREE(server_info);
00188                 return UID_FIELD_INVALID;
00189         }
00190 
00191         if((vuser = SMB_MALLOC_P(user_struct)) == NULL) {
00192                 DEBUG(0,("Failed to malloc users struct!\n"));
00193                 data_blob_free(&session_key);
00194                 TALLOC_FREE(server_info);
00195                 return UID_FIELD_INVALID;
00196         }
00197 
00198         ZERO_STRUCTP(vuser);
00199 
00200         /* Allocate a free vuid. Yes this is a linear search... :-) */
00201         while( (get_valid_user_struct(next_vuid) != NULL)
00202                || (get_partial_auth_user_struct(next_vuid) != NULL) ) {
00203                 next_vuid++;
00204                 /* Check for vuid wrap. */
00205                 if (next_vuid == UID_FIELD_INVALID)
00206                         next_vuid = VUID_OFFSET;
00207         }
00208 
00209         DEBUG(10,("register_vuid: allocated vuid = %u\n",
00210                   (unsigned int)next_vuid ));
00211 
00212         vuser->vuid = next_vuid;
00213 
00214         if (!server_info) {
00215                 /*
00216                  * This happens in an unfinished NTLMSSP session setup. We
00217                  * need to allocate a vuid between the first and second calls
00218                  * to NTLMSSP.
00219                  */
00220                 next_vuid++;
00221                 num_validated_vuids++;
00222                 
00223                 vuser->server_info = NULL;
00224                 
00225                 DLIST_ADD(validated_users, vuser);
00226                 
00227                 return vuser->vuid;
00228         }
00229 
00230         /* the next functions should be done by a SID mapping system (SMS) as
00231          * the new real sam db won't have reference to unix uids or gids
00232          */
00233         
00234         vuser->uid = server_info->uid;
00235         vuser->gid = server_info->gid;
00236         
00237         vuser->n_groups = server_info->n_groups;
00238         if (vuser->n_groups) {
00239                 if (!(vuser->groups = (gid_t *)memdup(server_info->groups,
00240                                                       sizeof(gid_t) *
00241                                                       vuser->n_groups))) {
00242                         DEBUG(0,("register_vuid: failed to memdup "
00243                                  "vuser->groups\n"));
00244                         data_blob_free(&session_key);
00245                         free(vuser);
00246                         TALLOC_FREE(server_info);
00247                         return UID_FIELD_INVALID;
00248                 }
00249         }
00250 
00251         vuser->guest = server_info->guest;
00252         fstrcpy(vuser->user.unix_name, server_info->unix_name); 
00253 
00254         /* This is a potentially untrusted username */
00255         alpha_strcpy(vuser->user.smb_name, smb_name, ". _-$",
00256                      sizeof(vuser->user.smb_name));
00257 
00258         fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account));
00259         fstrcpy(vuser->user.full_name,
00260                 pdb_get_fullname(server_info->sam_account));
00261 
00262         {
00263                 /* Keep the homedir handy */
00264                 const char *homedir =
00265                         pdb_get_homedir(server_info->sam_account);
00266                 const char *logon_script =
00267                         pdb_get_logon_script(server_info->sam_account);
00268 
00269                 if (!IS_SAM_DEFAULT(server_info->sam_account,
00270                                     PDB_UNIXHOMEDIR)) {
00271                         const char *unix_homedir =
00272                                 pdb_get_unix_homedir(server_info->sam_account);
00273                         if (unix_homedir) {
00274                                 vuser->unix_homedir =
00275                                         smb_xstrdup(unix_homedir);
00276                         }
00277                 } else {
00278                         struct passwd *passwd =
00279                                 getpwnam_alloc(NULL, vuser->user.unix_name);
00280                         if (passwd) {
00281                                 vuser->unix_homedir =
00282                                         smb_xstrdup(passwd->pw_dir);
00283                                 TALLOC_FREE(passwd);
00284                         }
00285                 }
00286                 
00287                 if (homedir) {
00288                         vuser->homedir = smb_xstrdup(homedir);
00289                 }
00290                 if (logon_script) {
00291                         vuser->logon_script = smb_xstrdup(logon_script);
00292                 }
00293         }
00294 
00295         vuser->session_key = session_key;
00296 
00297         DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", 
00298                   (unsigned int)vuser->uid, 
00299                   (unsigned int)vuser->gid,
00300                   vuser->user.unix_name, vuser->user.smb_name,
00301                   vuser->user.domain, vuser->guest ));
00302 
00303         DEBUG(3, ("User name: %s\tReal name: %s\n", vuser->user.unix_name,
00304                   vuser->user.full_name));      
00305 
00306         if (server_info->ptok) {
00307                 vuser->nt_user_token = dup_nt_token(NULL, server_info->ptok);
00308         } else {
00309                 DEBUG(1, ("server_info does not contain a user_token - "
00310                           "cannot continue\n"));
00311                 TALLOC_FREE(server_info);
00312                 data_blob_free(&session_key);
00313                 SAFE_FREE(vuser->homedir);
00314                 SAFE_FREE(vuser->unix_homedir);
00315                 SAFE_FREE(vuser->logon_script);
00316 
00317                 SAFE_FREE(vuser);
00318                 return UID_FIELD_INVALID;
00319         }
00320 
00321         /* use this to keep tabs on all our info from the authentication */
00322         vuser->server_info = server_info;
00323 
00324         DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",
00325                  (int)vuser->uid,vuser->user.unix_name, vuser->vuid));
00326 
00327         next_vuid++;
00328         num_validated_vuids++;
00329 
00330         DLIST_ADD(validated_users, vuser);
00331 
00332         if (!session_claim(vuser)) {
00333                 DEBUG(1, ("Failed to claim session for vuid=%d\n",
00334                           vuser->vuid));
00335                 invalidate_vuid(vuser->vuid);
00336                 return UID_FIELD_INVALID;
00337         }
00338 
00339         /* Register a home dir service for this user iff
00340         
00341            (a) This is not a guest connection,
00342            (b) we have a home directory defined 
00343            (c) there s not an existing static share by that name
00344            
00345            If a share exists by this name (autoloaded or not) reuse it . */
00346 
00347         vuser->homes_snum = -1;
00348 
00349         if ( (!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) 
00350         {
00351                 int servicenumber = lp_servicenumber(vuser->user.unix_name);
00352 
00353                 if ( servicenumber == -1 ) {
00354                         DEBUG(3, ("Adding homes service for user '%s' using "
00355                                   "home directory: '%s'\n", 
00356                                 vuser->user.unix_name, vuser->unix_homedir));
00357                         vuser->homes_snum =
00358                                 add_home_service(vuser->user.unix_name, 
00359                                                  vuser->user.unix_name,
00360                                                  vuser->unix_homedir);
00361                 } else {
00362                         DEBUG(3, ("Using static (or previously created) "
00363                                   "service for user '%s'; path = '%s'\n", 
00364                                   vuser->user.unix_name,
00365                                   lp_pathname(servicenumber) ));
00366                         vuser->homes_snum = servicenumber;
00367                 }
00368         } 
00369         
00370         if (srv_is_signing_negotiated() && !vuser->guest &&
00371             !srv_signing_started()) {
00372                 /* Try and turn on server signing on the first non-guest
00373                  * sessionsetup. */
00374                 srv_set_signing(vuser->session_key, response_blob);
00375         }
00376         
00377         /* fill in the current_user_info struct */
00378         set_current_user_info( &vuser->user );
00379 
00380 
00381         return vuser->vuid;
00382 }
00383 
00384 /****************************************************************************
00385  Add a name to the session users list.
00386 ****************************************************************************/
00387 
00388 void add_session_user(const char *user)
00389 {
00390         fstring suser;
00391         struct passwd *passwd;
00392 
00393         if (!(passwd = Get_Pwnam(user)))
00394                 return;
00395 
00396         fstrcpy(suser,passwd->pw_name);
00397 
00398         if(!*suser)
00399                 return;
00400 
00401         if( session_userlist && in_list(suser,session_userlist,False) )
00402                 return;
00403 
00404         if( !session_userlist ||
00405             (strlen(suser) + strlen(session_userlist) + 2 >=
00406              len_session_userlist) ) {
00407                 char *newlist;
00408 
00409                 if (len_session_userlist > 128 * PSTRING_LEN) {
00410                         DEBUG(3,("add_session_user: session userlist already "
00411                                  "too large.\n"));
00412                         return;
00413                 }
00414                 newlist = (char *)SMB_REALLOC_KEEP_OLD_ON_ERROR(
00415                         session_userlist,
00416                         len_session_userlist + PSTRING_LEN );
00417                 if( newlist == NULL ) {
00418                         DEBUG(1,("Unable to resize session_userlist\n"));
00419                         return;
00420                 }
00421                 if (!session_userlist) {
00422                         *newlist = '\0';
00423                 }
00424                 session_userlist = newlist;
00425                 len_session_userlist += PSTRING_LEN;
00426         }
00427 
00428         safe_strcat(session_userlist," ",len_session_userlist-1);
00429         safe_strcat(session_userlist,suser,len_session_userlist-1);
00430 }
00431 
00432 /****************************************************************************
00433  In security=share mode we need to store the client workgroup, as that's
00434   what Vista uses for the NTLMv2 calculation.
00435 ****************************************************************************/
00436 
00437 void add_session_workgroup(const char *workgroup)
00438 {
00439         if (session_workgroup) {
00440                 SAFE_FREE(session_workgroup);
00441         }
00442         session_workgroup = smb_xstrdup(workgroup);
00443 }
00444 
00445 /****************************************************************************
00446  In security=share mode we need to return the client workgroup, as that's
00447   what Vista uses for the NTLMv2 calculation.
00448 ****************************************************************************/
00449 
00450 const char *get_session_workgroup(void)
00451 {
00452         return session_workgroup;
00453 }
00454 
00455 /****************************************************************************
00456  Check if a user is in a netgroup user list. If at first we don't succeed,
00457  try lower case.
00458 ****************************************************************************/
00459 
00460 BOOL user_in_netgroup(const char *user, const char *ngname)
00461 {
00462 #ifdef HAVE_NETGROUP
00463         static char *mydomain = NULL;
00464         fstring lowercase_user;
00465 
00466         if (mydomain == NULL)
00467                 yp_get_default_domain(&mydomain);
00468 
00469         if(mydomain == NULL) {
00470                 DEBUG(5,("Unable to get default yp domain, let's try without specifying it\n"));
00471         }
00472 
00473         DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
00474                 user, mydomain?mydomain:"(ANY)", ngname));
00475 
00476         if (innetgr(ngname, NULL, user, mydomain)) {
00477                 DEBUG(5,("user_in_netgroup: Found\n"));
00478                 return (True);
00479         } else {
00480 
00481                 /*
00482                  * Ok, innetgr is case sensitive. Try once more with lowercase
00483                  * just in case. Attempt to fix #703. JRA.
00484                  */
00485 
00486                 fstrcpy(lowercase_user, user);
00487                 strlower_m(lowercase_user);
00488         
00489                 DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
00490                         lowercase_user, mydomain?mydomain:"(ANY)", ngname));
00491 
00492                 if (innetgr(ngname, NULL, lowercase_user, mydomain)) {
00493                         DEBUG(5,("user_in_netgroup: Found\n"));
00494                         return (True);
00495                 }
00496         }
00497 #endif /* HAVE_NETGROUP */
00498         return False;
00499 }
00500 
00501 /****************************************************************************
00502  Check if a user is in a user list - can check combinations of UNIX
00503  and netgroup lists.
00504 ****************************************************************************/
00505 
00506 BOOL user_in_list(const char *user,const char **list)
00507 {
00508         if (!list || !*list)
00509                 return False;
00510 
00511         DEBUG(10,("user_in_list: checking user %s in list\n", user));
00512 
00513         while (*list) {
00514 
00515                 DEBUG(10,("user_in_list: checking user |%s| against |%s|\n",
00516                           user, *list));
00517 
00518                 /*
00519                  * Check raw username.
00520                  */
00521                 if (strequal(user, *list))
00522                         return(True);
00523 
00524                 /*
00525                  * Now check to see if any combination
00526                  * of UNIX and netgroups has been specified.
00527                  */
00528 
00529                 if(**list == '@') {
00530                         /*
00531                          * Old behaviour. Check netgroup list
00532                          * followed by UNIX list.
00533                          */
00534                         if(user_in_netgroup(user, *list +1))
00535                                 return True;
00536                         if(user_in_group(user, *list +1))
00537                                 return True;
00538                 } else if (**list == '+') {
00539 
00540                         if((*(*list +1)) == '&') {
00541                                 /*
00542                                  * Search UNIX list followed by netgroup.
00543                                  */
00544                                 if(user_in_group(user, *list +2))
00545                                         return True;
00546                                 if(user_in_netgroup(user, *list +2))
00547                                         return True;
00548 
00549                         } else {
00550 
00551                                 /*
00552                                  * Just search UNIX list.
00553                                  */
00554 
00555                                 if(user_in_group(user, *list +1))
00556                                         return True;
00557                         }
00558 
00559                 } else if (**list == '&') {
00560 
00561                         if(*(*list +1) == '+') {
00562                                 /*
00563                                  * Search netgroup list followed by UNIX list.
00564                                  */
00565                                 if(user_in_netgroup(user, *list +2))
00566                                         return True;
00567                                 if(user_in_group(user, *list +2))
00568                                         return True;
00569                         } else {
00570                                 /*
00571                                  * Just search netgroup list.
00572                                  */
00573                                 if(user_in_netgroup(user, *list +1))
00574                                         return True;
00575                         }
00576                 }
00577     
00578                 list++;
00579         }
00580         return(False);
00581 }
00582 
00583 /****************************************************************************
00584  Check if a username is valid.
00585 ****************************************************************************/
00586 
00587 static BOOL user_ok(const char *user, int snum)
00588 {
00589         char **valid, **invalid;
00590         BOOL ret;
00591 
00592         valid = invalid = NULL;
00593         ret = True;
00594 
00595         if (lp_invalid_users(snum)) {
00596                 str_list_copy(&invalid, lp_invalid_users(snum));
00597                 if (invalid &&
00598                     str_list_substitute(invalid, "%S", lp_servicename(snum))) {
00599 
00600                         /* This is used in sec=share only, so no current user
00601                          * around to pass to str_list_sub_basic() */
00602 
00603                         if ( invalid && str_list_sub_basic(invalid, "", "") ) {
00604                                 ret = !user_in_list(user,
00605                                                     (const char **)invalid);
00606                         }
00607                 }
00608         }
00609         if (invalid)
00610                 str_list_free (&invalid);
00611 
00612         if (ret && lp_valid_users(snum)) {
00613                 str_list_copy(&valid, lp_valid_users(snum));
00614                 if ( valid &&
00615                      str_list_substitute(valid, "%S", lp_servicename(snum)) ) {
00616 
00617                         /* This is used in sec=share only, so no current user
00618                          * around to pass to str_list_sub_basic() */
00619 
00620                         if ( valid && str_list_sub_basic(valid, "", "") ) {
00621                                 ret = user_in_list(user, (const char **)valid);
00622                         }
00623                 }
00624         }
00625         if (valid)
00626                 str_list_free (&valid);
00627 
00628         if (ret && lp_onlyuser(snum)) {
00629                 char **user_list = str_list_make (lp_username(snum), NULL);
00630                 if (user_list &&
00631                     str_list_substitute(user_list, "%S",
00632                                         lp_servicename(snum))) {
00633                         ret = user_in_list(user, (const char **)user_list);
00634                 }
00635                 if (user_list) str_list_free (&user_list);
00636         }
00637 
00638         return(ret);
00639 }
00640 
00641 /****************************************************************************
00642  Validate a group username entry. Return the username or NULL.
00643 ****************************************************************************/
00644 
00645 static char *validate_group(char *group, DATA_BLOB password,int snum)
00646 {
00647 #ifdef HAVE_NETGROUP
00648         {
00649                 char *host, *user, *domain;
00650                 setnetgrent(group);
00651                 while (getnetgrent(&host, &user, &domain)) {
00652                         if (user) {
00653                                 if (user_ok(user, snum) && 
00654                                     password_ok(user,password)) {
00655                                         endnetgrent();
00656                                         return(user);
00657                                 }
00658                         }
00659                 }
00660                 endnetgrent();
00661         }
00662 #endif
00663   
00664 #ifdef HAVE_GETGRENT
00665         {
00666                 struct group *gptr;
00667                 setgrent();
00668                 while ((gptr = (struct group *)getgrent())) {
00669                         if (strequal(gptr->gr_name,group))
00670                                 break;
00671                 }
00672 
00673                 /*
00674                  * As user_ok can recurse doing a getgrent(), we must
00675                  * copy the member list into a pstring on the stack before
00676                  * use. Bug pointed out by leon@eatworms.swmed.edu.
00677                  */
00678 
00679                 if (gptr) {
00680                         pstring member_list;
00681                         char *member;
00682                         size_t copied_len = 0;
00683                         int i;
00684 
00685                         *member_list = '\0';
00686                         member = member_list;
00687 
00688                         for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) {
00689                                 size_t member_len = strlen(gptr->gr_mem[i])+1;
00690                                 if(copied_len+member_len < sizeof(pstring)) { 
00691 
00692                                         DEBUG(10,("validate_group: = gr_mem = "
00693                                                   "%s\n", gptr->gr_mem[i]));
00694 
00695                                         safe_strcpy(member, gptr->gr_mem[i],
00696                                                     sizeof(pstring) -
00697                                                     copied_len - 1);
00698                                         copied_len += member_len;
00699                                         member += copied_len;
00700                                 } else {
00701                                         *member = '\0';
00702                                 }
00703                         }
00704 
00705                         endgrent();
00706 
00707                         member = member_list;
00708                         while (*member) {
00709                                 static fstring name;
00710                                 fstrcpy(name,member);
00711                                 if (user_ok(name,snum) &&
00712                                     password_ok(name,password)) {
00713                                         endgrent();
00714                                         return(&name[0]);
00715                                 }
00716 
00717                                 DEBUG(10,("validate_group = member = %s\n",
00718                                           member));
00719 
00720                                 member += strlen(member) + 1;
00721                         }
00722                 } else {
00723                         endgrent();
00724                         return NULL;
00725                 }
00726         }
00727 #endif
00728         return(NULL);
00729 }
00730 
00731 /****************************************************************************
00732  Check for authority to login to a service with a given username/password.
00733  Note this is *NOT* used when logging on using sessionsetup_and_X.
00734 ****************************************************************************/
00735 
00736 BOOL authorise_login(int snum, fstring user, DATA_BLOB password, 
00737                      BOOL *guest)
00738 {
00739         BOOL ok = False;
00740         
00741 #ifdef DEBUG_PASSWORD
00742         DEBUG(100,("authorise_login: checking authorisation on "
00743                    "user=%s pass=%s\n", user,password.data));
00744 #endif
00745 
00746         *guest = False;
00747   
00748         /* there are several possibilities:
00749                 1) login as the given user with given password
00750                 2) login as a previously registered username with the given 
00751                    password
00752                 3) login as a session list username with the given password
00753                 4) login as a previously validated user/password pair
00754                 5) login as the "user =" user with given password
00755                 6) login as the "user =" user with no password 
00756                    (guest connection)
00757                 7) login as guest user with no password
00758 
00759                 if the service is guest_only then steps 1 to 5 are skipped
00760         */
00761 
00762         /* now check the list of session users */
00763         if (!ok) {
00764                 char *auser;
00765                 char *user_list = NULL;
00766 
00767                 if ( session_userlist )
00768                         user_list = SMB_STRDUP(session_userlist);
00769                 else
00770                         user_list = SMB_STRDUP("");
00771 
00772                 if (!user_list)
00773                         return(False);
00774                 
00775                 for (auser=strtok(user_list,LIST_SEP); !ok && auser;
00776                      auser = strtok(NULL,LIST_SEP)) {
00777                         fstring user2;
00778                         fstrcpy(user2,auser);
00779                         if (!user_ok(user2,snum))
00780                                 continue;
00781                         
00782                         if (password_ok(user2,password)) {
00783                                 ok = True;
00784                                 fstrcpy(user,user2);
00785                                 DEBUG(3,("authorise_login: ACCEPTED: session "
00786                                          "list username (%s) and given "
00787                                          "password ok\n", user));
00788                         }
00789                 }
00790 
00791                 SAFE_FREE(user_list);
00792         }
00793         
00794         /* check the user= fields and the given password */
00795         if (!ok && lp_username(snum)) {
00796                 char *auser;
00797                 pstring user_list;
00798                 pstrcpy(user_list,lp_username(snum));
00799                 
00800                 pstring_sub(user_list,"%S",lp_servicename(snum));
00801                 
00802                 for (auser=strtok(user_list,LIST_SEP); auser && !ok;
00803                      auser = strtok(NULL,LIST_SEP)) {
00804                         if (*auser == '@') {
00805                                 auser = validate_group(auser+1,password,snum);
00806                                 if (auser) {
00807                                         ok = True;
00808                                         fstrcpy(user,auser);
00809                                         DEBUG(3,("authorise_login: ACCEPTED: "
00810                                                  "group username and given "
00811                                                  "password ok (%s)\n", user));
00812                                 }
00813                         } else {
00814                                 fstring user2;
00815                                 fstrcpy(user2,auser);
00816                                 if (user_ok(user2,snum) &&
00817                                     password_ok(user2,password)) {
00818                                         ok = True;
00819                                         fstrcpy(user,user2);
00820                                         DEBUG(3,("authorise_login: ACCEPTED: "
00821                                                  "user list username and "
00822                                                  "given password ok (%s)\n",
00823                                                  user));
00824                                 }
00825                         }
00826                 }
00827         }
00828 
00829         /* check for a normal guest connection */
00830         if (!ok && GUEST_OK(snum)) {
00831                 fstring guestname;
00832                 fstrcpy(guestname,lp_guestaccount());
00833                 if (Get_Pwnam(guestname)) {
00834                         fstrcpy(user,guestname);
00835                         ok = True;
00836                         DEBUG(3,("authorise_login: ACCEPTED: guest account "
00837                                  "and guest ok (%s)\n", user));
00838                 } else {
00839                         DEBUG(0,("authorise_login: Invalid guest account "
00840                                  "%s??\n",guestname));
00841                 }
00842                 *guest = True;
00843         }
00844 
00845         if (ok && !user_ok(user, snum)) {
00846                 DEBUG(0,("authorise_login: rejected invalid user %s\n",user));
00847                 ok = False;
00848         }
00849 
00850         return(ok);
00851 }

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