smbd/uid.c

ソースコードを見る。

データ構造

struct  conn_ctx

関数

gid_t get_current_user_gid_first (int *piterator)
gid_t get_current_user_gid_next (int *piterator)
BOOL change_to_guest (void)
static BOOL check_user_ok (connection_struct *conn, user_struct *vuser, int snum)
BOOL change_to_user (connection_struct *conn, uint16 vuid)
BOOL change_to_root_user (void)
BOOL become_authenticated_pipe_user (pipes_struct *p)
BOOL unbecome_authenticated_pipe_user (void)
static void push_conn_ctx (void)
static void pop_conn_ctx (void)
void become_root (void)
void unbecome_root (void)
BOOL become_user (connection_struct *conn, uint16 vuid)
BOOL unbecome_user (void)

変数

current_user current_user
static struct conn_ctx conn_ctx_stack [MAX_SEC_CTX_DEPTH]
static int conn_ctx_stack_ndx


関数

gid_t get_current_user_gid_first ( int *  piterator  ) 

uid.c30 行で定義されています。

参照先 current_user_unix_token::gidcurrent_user::ut.

00031 {
00032         *piterator = 0;
00033         return current_user.ut.gid;
00034 }

gid_t get_current_user_gid_next ( int *  piterator  ) 

uid.c36 行で定義されています。

参照先 current_user_unix_token::groups_unix_token::ngroupscurrent_user::ut.

00037 {
00038         gid_t ret;
00039 
00040         if (!current_user.ut.groups || *piterator >= current_user.ut.ngroups) {
00041                 return (gid_t)-1;
00042         }
00043 
00044         ret = current_user.ut.groups[*piterator];
00045         (*piterator) += 1;
00046         return ret;
00047 }

BOOL change_to_guest ( void   ) 

uid.c53 行で定義されています。

参照先 current_user::conncurrent_usergetpwnam_alloc()set_sec_ctx()current_user::vuid.

参照元 switch_message().

00054 {
00055         static struct passwd *pass=NULL;
00056 
00057         if (!pass) {
00058                 /* Don't need to free() this as its stored in a static */
00059                 pass = getpwnam_alloc(NULL, lp_guestaccount());
00060                 if (!pass)
00061                         return(False);
00062         }
00063         
00064 #ifdef AIX
00065         /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before 
00066            setting IDs */
00067         initgroups(pass->pw_name, pass->pw_gid);
00068 #endif
00069         
00070         set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL);
00071         
00072         current_user.conn = NULL;
00073         current_user.vuid = UID_FIELD_INVALID;
00074 
00075         TALLOC_FREE(pass);
00076         pass = NULL;
00077         
00078         return True;
00079 }

static BOOL check_user_ok ( connection_struct conn,
user_struct vuser,
int  snum 
) [static]

uid.c85 行で定義されています。

参照先 vuid_cache_entry::admin_userconnection_struct::admin_uservuid_cache::arrayvuid_cache::entriesvuid_cache_entry::read_onlyconnection_struct::read_onlyuser_struct::vuidvuid_cache_entry::vuidconnection_struct::vuid_cache.

参照元 change_to_user().

00086 {
00087         unsigned int i;
00088         struct vuid_cache_entry *ent = NULL;
00089         BOOL readonly_share;
00090         NT_USER_TOKEN *token;
00091 
00092         for (i=0;i<conn->vuid_cache.entries && i< VUID_CACHE_SIZE;i++) {
00093                 if (conn->vuid_cache.array[i].vuid == vuser->vuid) {
00094                         ent = &conn->vuid_cache.array[i];
00095                         conn->read_only = ent->read_only;
00096                         conn->admin_user = ent->admin_user;
00097                         return(True);
00098                 }
00099         }
00100 
00101         if (!user_ok_token(vuser->user.unix_name, vuser->nt_user_token, snum))
00102                 return(False);
00103 
00104         readonly_share = is_share_read_only_for_token(vuser->user.unix_name,
00105                                                       vuser->nt_user_token,
00106                                                       SNUM(conn));
00107 
00108         token = conn->nt_user_token ?
00109                 conn->nt_user_token : vuser->nt_user_token;
00110 
00111         if (!readonly_share &&
00112             !share_access_check(token, lp_servicename(snum),
00113                                 FILE_WRITE_DATA)) {
00114                 /* smb.conf allows r/w, but the security descriptor denies
00115                  * write. Fall back to looking at readonly. */
00116                 readonly_share = True;
00117                 DEBUG(5,("falling back to read-only access-evaluation due to "
00118                          "security descriptor\n"));
00119         }
00120 
00121         if (!share_access_check(token, lp_servicename(snum),
00122                                 readonly_share ?
00123                                 FILE_READ_DATA : FILE_WRITE_DATA)) {
00124                 return False;
00125         }
00126 
00127         i = conn->vuid_cache.entries % VUID_CACHE_SIZE;
00128         if (conn->vuid_cache.entries < VUID_CACHE_SIZE)
00129                 conn->vuid_cache.entries++;
00130 
00131         ent = &conn->vuid_cache.array[i];
00132         ent->vuid = vuser->vuid;
00133         ent->read_only = readonly_share;
00134 
00135         ent->admin_user = token_contains_name_in_list(
00136                 vuser->user.unix_name, NULL, vuser->nt_user_token,
00137                 lp_admin_users(SNUM(conn)));
00138 
00139         conn->read_only = ent->read_only;
00140         conn->admin_user = ent->admin_user;
00141 
00142         return(True);
00143 }

BOOL change_to_user ( connection_struct conn,
uint16  vuid 
)

uid.c150 行で定義されています。

参照先 connection_struct::admin_usercheck_user_ok()current_user::conncurrent_userdup_nt_token()connection_struct::force_userget_valid_user_struct()user_struct::gidconnection_struct::gidgid_to_sid()user_struct::groupsconnection_struct::groupsuser_struct::n_groupsconnection_struct::ngroupsuser_struct::nt_user_tokenconnection_struct::nt_user_tokenSEC_SHAREuserdom_struct::smb_nameuser_struct::uidconnection_struct::uid_unix_token::uiduserdom_struct::unix_nameuser_struct::usernt_user_token::user_sidscurrent_user::utcurrent_user::vuid.

参照元 become_user()close_cnum()process_blocking_lock_queue()switch_message().

00151 {
00152         user_struct *vuser = get_valid_user_struct(vuid);
00153         int snum;
00154         gid_t gid;
00155         uid_t uid;
00156         char group_c;
00157         BOOL must_free_token = False;
00158         NT_USER_TOKEN *token = NULL;
00159         int num_groups = 0;
00160         gid_t *group_list = NULL;
00161         
00162         if (!conn) {
00163                 DEBUG(2,("change_to_user: Connection not open\n"));
00164                 return(False);
00165         }
00166 
00167         /*
00168          * We need a separate check in security=share mode due to vuid
00169          * always being UID_FIELD_INVALID. If we don't do this then
00170          * in share mode security we are *always* changing uid's between
00171          * SMB's - this hurts performance - Badly.
00172          */
00173 
00174         if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
00175            (current_user.ut.uid == conn->uid)) {
00176                 DEBUG(4,("change_to_user: Skipping user change - already "
00177                          "user\n"));
00178                 return(True);
00179         } else if ((current_user.conn == conn) && 
00180                    (vuser != 0) && (current_user.vuid == vuid) && 
00181                    (current_user.ut.uid == vuser->uid)) {
00182                 DEBUG(4,("change_to_user: Skipping user change - already "
00183                          "user\n"));
00184                 return(True);
00185         }
00186 
00187         snum = SNUM(conn);
00188 
00189         if ((vuser) && !check_user_ok(conn, vuser, snum)) {
00190                 DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) "
00191                          "not permitted access to share %s.\n",
00192                          vuser->user.smb_name, vuser->user.unix_name, vuid,
00193                          lp_servicename(snum)));
00194                 return False;
00195         }
00196 
00197         if (conn->force_user) /* security = share sets this too */ {
00198                 uid = conn->uid;
00199                 gid = conn->gid;
00200                 group_list = conn->groups;
00201                 num_groups = conn->ngroups;
00202                 token = conn->nt_user_token;
00203         } else if (vuser) {
00204                 uid = conn->admin_user ? 0 : vuser->uid;
00205                 gid = vuser->gid;
00206                 num_groups = vuser->n_groups;
00207                 group_list  = vuser->groups;
00208                 token = vuser->nt_user_token;
00209         } else {
00210                 DEBUG(2,("change_to_user: Invalid vuid used %d in accessing "
00211                          "share %s.\n",vuid, lp_servicename(snum) ));
00212                 return False;
00213         }
00214 
00215         /*
00216          * See if we should force group for this service.
00217          * If so this overrides any group set in the force
00218          * user code.
00219          */
00220 
00221         if((group_c = *lp_force_group(snum))) {
00222 
00223                 token = dup_nt_token(NULL, token);
00224                 if (token == NULL) {
00225                         DEBUG(0, ("dup_nt_token failed\n"));
00226                         return False;
00227                 }
00228                 must_free_token = True;
00229 
00230                 if(group_c == '+') {
00231 
00232                         /*
00233                          * Only force group if the user is a member of
00234                          * the service group. Check the group memberships for
00235                          * this user (we already have this) to
00236                          * see if we should force the group.
00237                          */
00238 
00239                         int i;
00240                         for (i = 0; i < num_groups; i++) {
00241                                 if (group_list[i] == conn->gid) {
00242                                         gid = conn->gid;
00243                                         gid_to_sid(&token->user_sids[1], gid);
00244                                         break;
00245                                 }
00246                         }
00247                 } else {
00248                         gid = conn->gid;
00249                         gid_to_sid(&token->user_sids[1], gid);
00250                 }
00251         }
00252         
00253         /* Now set current_user since we will immediately also call
00254            set_sec_ctx() */
00255 
00256         current_user.ut.ngroups = num_groups;
00257         current_user.ut.groups  = group_list;   
00258 
00259         set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups,
00260                     token);
00261 
00262         /*
00263          * Free the new token (as set_sec_ctx copies it).
00264          */
00265 
00266         if (must_free_token)
00267                 TALLOC_FREE(token);
00268 
00269         current_user.conn = conn;
00270         current_user.vuid = vuid;
00271 
00272         DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n",
00273                  (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
00274   
00275         return(True);
00276 }

BOOL change_to_root_user ( void   ) 

uid.c283 行で定義されています。

参照先 current_user::conncurrent_userset_root_sec_ctx()current_user::vuid.

参照元 async_processing()close_cnum()exit_server_common()open_sockets_smbd()process_blocking_lock_queue()smbd_process()start_background_queue()switch_message()timeout_processing().

00284 {
00285         set_root_sec_ctx();
00286 
00287         DEBUG(5,("change_to_root_user: now uid=(%d,%d) gid=(%d,%d)\n",
00288                 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
00289 
00290         current_user.conn = NULL;
00291         current_user.vuid = UID_FIELD_INVALID;
00292 
00293         return(True);
00294 }

BOOL become_authenticated_pipe_user ( pipes_struct p  ) 

uid.c302 行で定義されています。

参照先 _unix_token::gid_unix_token::groups_unix_token::ngroupscurrent_user::nt_user_tokenpipes_struct::pipe_userpush_sec_ctx()set_sec_ctx()_unix_token::uidcurrent_user::ut.

参照元 api_pipe_request().

00303 {
00304         if (!push_sec_ctx())
00305                 return False;
00306 
00307         set_sec_ctx(p->pipe_user.ut.uid, p->pipe_user.ut.gid, 
00308                     p->pipe_user.ut.ngroups, p->pipe_user.ut.groups,
00309                     p->pipe_user.nt_user_token);
00310 
00311         return True;
00312 }

BOOL unbecome_authenticated_pipe_user ( void   ) 

uid.c321 行で定義されています。

参照先 pop_sec_ctx().

参照元 api_pipe_request().

00322 {
00323         return pop_sec_ctx();
00324 }

static void push_conn_ctx ( void   )  [static]

uid.c340 行で定義されています。

参照先 current_user::connconn_ctx::connconn_ctx_stackcurrent_usersmb_panic()current_user::vuidconn_ctx::vuid.

参照元 become_root()become_user().

00341 {
00342         struct conn_ctx *ctx_p;
00343  
00344         /* Check we don't overflow our stack */
00345  
00346         if (conn_ctx_stack_ndx == MAX_SEC_CTX_DEPTH) {
00347                 DEBUG(0, ("Connection context stack overflow!\n"));
00348                 smb_panic("Connection context stack overflow!\n");
00349         }
00350  
00351         /* Store previous user context */
00352         ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
00353  
00354         ctx_p->conn = current_user.conn;
00355         ctx_p->vuid = current_user.vuid;
00356  
00357         DEBUG(3, ("push_conn_ctx(%u) : conn_ctx_stack_ndx = %d\n",
00358                 (unsigned int)ctx_p->vuid, conn_ctx_stack_ndx ));
00359 
00360         conn_ctx_stack_ndx++;
00361 }

static void pop_conn_ctx ( void   )  [static]

uid.c363 行で定義されています。

参照先 conn_ctx::conncurrent_user::connconn_ctx_stackcurrent_usersmb_panic()conn_ctx::vuidcurrent_user::vuid.

参照元 become_user()unbecome_root()unbecome_user().

00364 {
00365         struct conn_ctx *ctx_p;
00366  
00367         /* Check for stack underflow. */
00368 
00369         if (conn_ctx_stack_ndx == 0) {
00370                 DEBUG(0, ("Connection context stack underflow!\n"));
00371                 smb_panic("Connection context stack underflow!\n");
00372         }
00373 
00374         conn_ctx_stack_ndx--;
00375         ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
00376 
00377         current_user.conn = ctx_p->conn;
00378         current_user.vuid = ctx_p->vuid;
00379 
00380         ctx_p->conn = NULL;
00381         ctx_p->vuid = UID_FIELD_INVALID;
00382 }

void become_root ( void   ) 

uid.c389 行で定義されています。

参照先 push_conn_ctx()push_sec_ctx()set_root_sec_ctx().

00390 {
00391         push_sec_ctx();
00392         push_conn_ctx();
00393         set_root_sec_ctx();
00394 }

void unbecome_root ( void   ) 

uid.c398 行で定義されています。

参照先 pop_conn_ctx()pop_sec_ctx().

00399 {
00400         pop_sec_ctx();
00401         pop_conn_ctx();
00402 }

BOOL become_user ( connection_struct conn,
uint16  vuid 
)

uid.c409 行で定義されています。

参照先 change_to_user()conn_ctx::connpop_conn_ctx()pop_sec_ctx()push_conn_ctx()push_sec_ctx().

参照元 _srv_net_file_query_secdesc()_srv_net_file_set_secdesc()close_directory()close_remove_share_mode()delete_driver_files()get_correct_cversion()move_driver_to_download_area().

00410 {
00411         if (!push_sec_ctx())
00412                 return False;
00413 
00414         push_conn_ctx();
00415 
00416         if (!change_to_user(conn, vuid)) {
00417                 pop_sec_ctx();
00418                 pop_conn_ctx();
00419                 return False;
00420         }
00421 
00422         return True;
00423 }

BOOL unbecome_user ( void   ) 

uid.c425 行で定義されています。

参照先 pop_conn_ctx()pop_sec_ctx().

参照元 _srv_net_file_query_secdesc()_srv_net_file_set_secdesc()close_directory()close_remove_share_mode()delete_driver_files()get_correct_cversion().

00426 {
00427         pop_sec_ctx();
00428         pop_conn_ctx();
00429         return True;
00430 }


変数

struct current_user current_user

smbrun.c24 行で定義されています。

参照元 afs_login()api_RDosPrintJobDel()api_WPrintQueueCtrl()call_nt_transact_get_user_quota()call_nt_transact_set_user_quota()call_trans2qfsinfo()call_trans2setfsinfo()can_access_file()can_access_file_acl()can_delete_file_in_directory()change_to_guest()change_to_root_user()change_to_user()close_directory()close_remove_share_mode()current_user_in_group()fake_perms_fstat()fake_perms_stat()fcb_or_dos_open()get_current_user()get_current_user_gid_first()get_current_user_gid_next()init_sec_ctx()open_directory()open_fake_file()open_file()open_file_ntcreate()open_file_stat()pop_conn_ctx()pop_sec_ctx()print_access_check()print_fsp_open()print_queue_update()print_run_command()push_conn_ctx()reply_close()set_sec_ctx()smb_set_file_disposition_info()smb_set_nt_acl_nfs4()smbrun_internal()smbrunsecret()try_chown()uid_entry_in_group()unpack_nt_owners()user_can_read_file()user_can_write_file().

struct conn_ctx conn_ctx_stack[MAX_SEC_CTX_DEPTH] [static]

uid.c337 行で定義されています。

参照元 pop_conn_ctx()push_conn_ctx().

int conn_ctx_stack_ndx [static]

uid.c338 行で定義されています。


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