smbd/service.c

ソースコードを見る。

関数

static BOOL canonicalize_path (connection_struct *conn, pstring path)
void set_conn_connectpath (connection_struct *conn, const pstring connectpath)
BOOL set_current_service (connection_struct *conn, uint16 flags, BOOL do_chdir)
int add_home_service (const char *service, const char *username, const char *homedir)
int find_service (fstring service)
 Find a service entry.
static NTSTATUS share_sanity_checks (int snum, fstring dev)
static NTSTATUS find_forced_user (connection_struct *conn, BOOL vuser_is_guest, fstring username)
static NTSTATUS find_forced_group (BOOL force_user, int snum, const char *username, DOM_SID *pgroup_sid, gid_t *pgid)
static connection_structmake_connection_snum (int snum, user_struct *vuser, DATA_BLOB password, const char *pdev, NTSTATUS *status)
connection_structmake_connection_with_chdir (const char *service_in, DATA_BLOB password, const char *dev, uint16 vuid, NTSTATUS *status)
connection_structmake_connection (const char *service_in, DATA_BLOB password, const char *pdev, uint16 vuid, NTSTATUS *status)
void close_cnum (connection_struct *conn, uint16 vuid)

変数

userdom_struct current_user_info


関数

static BOOL canonicalize_path ( connection_struct conn,
pstring  path 
) [static]

service.c25 行で定義されています。

00026 {
00027 #ifdef REALPATH_TAKES_NULL
00028         char *resolved_name = SMB_VFS_REALPATH(conn,path,NULL);
00029         if (!resolved_name) {
00030                 return False;
00031         }
00032         pstrcpy(path, resolved_name);
00033         SAFE_FREE(resolved_name);
00034         return True;
00035 #else
00036 #ifdef PATH_MAX
00037         char resolved_name_buf[PATH_MAX+1];
00038 #else
00039         pstring resolved_name_buf;
00040 #endif
00041         char *resolved_name = SMB_VFS_REALPATH(conn,path,resolved_name_buf);
00042         if (!resolved_name) {
00043                 return False;
00044         }
00045         pstrcpy(path, resolved_name);
00046         return True;
00047 #endif /* REALPATH_TAKES_NULL */
00048 }

void set_conn_connectpath ( connection_struct conn,
const pstring  connectpath 
)

service.c56 行で定義されています。

参照先 connection_struct::connectpathnext_codepoint()string_set().

参照元 create_conn_struct()get_nt_acl_no_snum()reply_setdir().

00057 {
00058         pstring destname;
00059         char *d = destname;
00060         const char *s = connectpath;
00061         BOOL start_of_name_component = True;
00062 
00063         *d++ = '/'; /* Always start with root. */
00064 
00065         while (*s) {
00066                 if (*s == '/') {
00067                         /* Eat multiple '/' */
00068                         while (*s == '/') {
00069                                 s++;
00070                         }
00071                         if ((d > destname + 1) && (*s != '\0')) {
00072                                 *d++ = '/';
00073                         }
00074                         start_of_name_component = True;
00075                         continue;
00076                 }
00077 
00078                 if (start_of_name_component) {
00079                         if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
00080                                 /* Uh oh - "/../" or "/..\0" ! */
00081 
00082                                 /* Go past the ../ or .. */
00083                                 if (s[2] == '/') {
00084                                         s += 3;
00085                                 } else {
00086                                         s += 2; /* Go past the .. */
00087                                 }
00088 
00089                                 /* If  we just added a '/' - delete it */
00090                                 if ((d > destname) && (*(d-1) == '/')) {
00091                                         *(d-1) = '\0';
00092                                         d--;
00093                                 }
00094 
00095                                 /* Are we at the start ? Can't go back further if so. */
00096                                 if (d <= destname) {
00097                                         *d++ = '/'; /* Can't delete root */
00098                                         continue;
00099                                 }
00100                                 /* Go back one level... */
00101                                 /* Decrement d first as d points to the *next* char to write into. */
00102                                 for (d--; d > destname; d--) {
00103                                         if (*d == '/') {
00104                                                 break;
00105                                         }
00106                                 }
00107                                 /* We're still at the start of a name component, just the previous one. */
00108                                 continue;
00109                         } else if ((s[0] == '.') && ((s[1] == '\0') || s[1] == '/')) {
00110                                 /* Component of pathname can't be "." only - skip the '.' . */
00111                                 if (s[1] == '/') {
00112                                         s += 2;
00113                                 } else {
00114                                         s++;
00115                                 }
00116                                 continue;
00117                         }
00118                 }
00119 
00120                 if (!(*s & 0x80)) {
00121                         *d++ = *s++;
00122                 } else {
00123                         size_t siz;
00124                         /* Get the size of the next MB character. */
00125                         next_codepoint(s,&siz);
00126                         switch(siz) {
00127                                 case 5:
00128                                         *d++ = *s++;
00129                                         /*fall through*/
00130                                 case 4:
00131                                         *d++ = *s++;
00132                                         /*fall through*/
00133                                 case 3:
00134                                         *d++ = *s++;
00135                                         /*fall through*/
00136                                 case 2:
00137                                         *d++ = *s++;
00138                                         /*fall through*/
00139                                 case 1:
00140                                         *d++ = *s++;
00141                                         break;
00142                                 default:
00143                                         break;
00144                         }
00145                 }
00146                 start_of_name_component = False;
00147         }
00148         *d = '\0';
00149 
00150         /* And must not end in '/' */
00151         if (d > destname + 1 && (*(d-1) == '/')) {
00152                 *(d-1) = '\0';
00153         }
00154 
00155         DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
00156                 lp_servicename(SNUM(conn)), destname ));
00157 
00158         string_set(&conn->connectpath, destname);
00159 }

BOOL set_current_service ( connection_struct conn,
uint16  flags,
BOOL  do_chdir 
)

service.c165 行で定義されています。

参照先 connection_struct::case_sensitiveconnection_struct::connectpathget_remote_arch()connection_struct::lastused_countconnection_struct::origpathRA_CIFSFSRA_SAMBAra_typevfs_ChDir().

参照元 conn_close_all()process_blocking_lock_queue()reload_services()switch_message().

00166 {
00167         static connection_struct *last_conn;
00168         static uint16 last_flags;
00169         int snum;
00170 
00171         if (!conn)  {
00172                 last_conn = NULL;
00173                 return(False);
00174         }
00175 
00176         conn->lastused_count++;
00177 
00178         snum = SNUM(conn);
00179   
00180         if (do_chdir &&
00181             vfs_ChDir(conn,conn->connectpath) != 0 &&
00182             vfs_ChDir(conn,conn->origpath) != 0) {
00183                 DEBUG(0,("chdir (%s) failed\n",
00184                          conn->connectpath));
00185                 return(False);
00186         }
00187 
00188         if ((conn == last_conn) && (last_flags == flags)) {
00189                 return(True);
00190         }
00191 
00192         last_conn = conn;
00193         last_flags = flags;
00194         
00195         /* Obey the client case sensitivity requests - only for clients that support it. */
00196         switch (lp_casesensitive(snum)) {
00197                 case Auto:
00198                         {
00199                                 /* We need this uglyness due to DOS/Win9x clients that lie about case insensitivity. */
00200                                 enum remote_arch_types ra_type = get_remote_arch();
00201                                 if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
00202                                         /* Client can't support per-packet case sensitive pathnames. */
00203                                         conn->case_sensitive = False;
00204                                 } else {
00205                                         conn->case_sensitive = !(flags & FLAG_CASELESS_PATHNAMES);
00206                                 }
00207                         }
00208                         break;
00209                 case True:
00210                         conn->case_sensitive = True;
00211                         break;
00212                 default:
00213                         conn->case_sensitive = False;
00214                         break;
00215         }
00216         return(True);
00217 }

int add_home_service ( const char *  service,
const char *  username,
const char *  homedir 
)

service.c223 行で定義されています。

参照先 lp_add_home().

参照元 find_service()register_vuid().

00224 {
00225         int iHomeService;
00226 
00227         if (!service || !homedir)
00228                 return -1;
00229 
00230         if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0)
00231                 return -1;
00232 
00233         /*
00234          * If this is a winbindd provided username, remove
00235          * the domain component before adding the service.
00236          * Log a warning if the "path=" parameter does not
00237          * include any macros.
00238          */
00239 
00240         {
00241                 const char *p = strchr(service,*lp_winbind_separator());
00242 
00243                 /* We only want the 'user' part of the string */
00244                 if (p) {
00245                         service = p + 1;
00246                 }
00247         }
00248 
00249         if (!lp_add_home(service, iHomeService, username, homedir)) {
00250                 return -1;
00251         }
00252         
00253         return lp_servicenumber(service);
00254 
00255 }

int find_service ( fstring  service  ) 

Find a service entry.

引数:
service is modified (to canonical form??)

service.c264 行で定義されています。

参照先 add_home_service()all_string_sub()find_service()get_user_home_dir()load_usershare_service()lp_add_printer()lp_add_service()map_username()pcap_printername_ok()strequal()strlower_m()strstr_m().

00265 {
00266         int iService;
00267 
00268         all_string_sub(service,"\\","/",0);
00269 
00270         iService = lp_servicenumber(service);
00271 
00272         /* now handle the special case of a home directory */
00273         if (iService < 0) {
00274                 char *phome_dir = get_user_home_dir(service);
00275 
00276                 if(!phome_dir) {
00277                         /*
00278                          * Try mapping the servicename, it may
00279                          * be a Windows to unix mapped user name.
00280                          */
00281                         if(map_username(service))
00282                                 phome_dir = get_user_home_dir(service);
00283                 }
00284 
00285                 DEBUG(3,("checking for home directory %s gave %s\n",service,
00286                         phome_dir?phome_dir:"(NULL)"));
00287 
00288                 iService = add_home_service(service,service /* 'username' */, phome_dir);
00289         }
00290 
00291         /* If we still don't have a service, attempt to add it as a printer. */
00292         if (iService < 0) {
00293                 int iPrinterService;
00294 
00295                 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
00296                         DEBUG(3,("checking whether %s is a valid printer name...\n", service));
00297                         if (pcap_printername_ok(service)) {
00298                                 DEBUG(3,("%s is a valid printer name\n", service));
00299                                 DEBUG(3,("adding %s as a printer service\n", service));
00300                                 lp_add_printer(service, iPrinterService);
00301                                 iService = lp_servicenumber(service);
00302                                 if (iService < 0) {
00303                                         DEBUG(0,("failed to add %s as a printer service!\n", service));
00304                                 }
00305                         } else {
00306                                 DEBUG(3,("%s is not a valid printer name\n", service));
00307                         }
00308                 }
00309         }
00310 
00311         /* Check for default vfs service?  Unsure whether to implement this */
00312         if (iService < 0) {
00313         }
00314 
00315         /* Is it a usershare service ? */
00316         if (iService < 0 && *lp_usershare_path()) {
00317                 /* Ensure the name is canonicalized. */
00318                 strlower_m(service);
00319                 iService = load_usershare_service(service);
00320         }
00321 
00322         /* just possibly it's a default service? */
00323         if (iService < 0) {
00324                 char *pdefservice = lp_defaultservice();
00325                 if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr_m(service,"..")) {
00326                         /*
00327                          * We need to do a local copy here as lp_defaultservice() 
00328                          * returns one of the rotating lp_string buffers that
00329                          * could get overwritten by the recursive find_service() call
00330                          * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
00331                          */
00332                         pstring defservice;
00333                         pstrcpy(defservice, pdefservice);
00334 
00335                         /* Disallow anything except explicit share names. */
00336                         if (strequal(defservice,HOMES_NAME) ||
00337                                         strequal(defservice, PRINTERS_NAME) ||
00338                                         strequal(defservice, "IPC$")) {
00339                                 goto fail;
00340                         }
00341 
00342                         iService = find_service(defservice);
00343                         if (iService >= 0) {
00344                                 all_string_sub(service, "_","/",0);
00345                                 iService = lp_add_service(service, iService);
00346                         }
00347                 }
00348         }
00349 
00350         if (iService >= 0) {
00351                 if (!VALID_SNUM(iService)) {
00352                         DEBUG(0,("Invalid snum %d for %s\n",iService, service));
00353                         iService = -1;
00354                 }
00355         }
00356 
00357   fail:
00358 
00359         if (iService < 0)
00360                 DEBUG(3,("find_service() failed to find service %s\n", service));
00361 
00362         return (iService);
00363 }

static NTSTATUS share_sanity_checks ( int  snum,
fstring  dev 
) [static]

service.c371 行で定義されています。

参照先 check_access()lp_snum_ok()smbd_server_fd()strequal()strupper_m().

参照元 make_connection_snum().

00372 {
00373         
00374         if (!lp_snum_ok(snum) || 
00375             !check_access(smbd_server_fd(), 
00376                           lp_hostsallow(snum), lp_hostsdeny(snum))) {    
00377                 return NT_STATUS_ACCESS_DENIED;
00378         }
00379 
00380         if (dev[0] == '?' || !dev[0]) {
00381                 if (lp_print_ok(snum)) {
00382                         fstrcpy(dev,"LPT1:");
00383                 } else if (strequal(lp_fstype(snum), "IPC")) {
00384                         fstrcpy(dev, "IPC");
00385                 } else {
00386                         fstrcpy(dev,"A:");
00387                 }
00388         }
00389 
00390         strupper_m(dev);
00391 
00392         if (lp_print_ok(snum)) {
00393                 if (!strequal(dev, "LPT1:")) {
00394                         return NT_STATUS_BAD_DEVICE_TYPE;
00395                 }
00396         } else if (strequal(lp_fstype(snum), "IPC")) {
00397                 if (!strequal(dev, "IPC")) {
00398                         return NT_STATUS_BAD_DEVICE_TYPE;
00399                 }
00400         } else if (!strequal(dev, "A:")) {
00401                 return NT_STATUS_BAD_DEVICE_TYPE;
00402         }
00403 
00404         /* Behave as a printer if we are supposed to */
00405         if (lp_print_ok(snum) && (strcmp(dev, "A:") == 0)) {
00406                 fstrcpy(dev, "LPT1:");
00407         }
00408 
00409         return NT_STATUS_OK;
00410 }

static NTSTATUS find_forced_user ( connection_struct conn,
BOOL  vuser_is_guest,
fstring  username 
) [static]

service.c412 行で定義されています。

参照先 create_token_from_username()connection_struct::gidconnection_struct::mem_ctxconnection_struct::nt_user_tokenconnection_struct::paramsresultshare_params::servicetalloc_string_sub()connection_struct::uid.

参照元 make_connection_snum().

00413 {
00414         int snum = conn->params->service;
00415         char *fuser, *found_username;
00416         NTSTATUS result;
00417 
00418         if (!(fuser = talloc_string_sub(conn->mem_ctx, lp_force_user(snum), "%S",
00419                                         lp_servicename(snum)))) {
00420                 return NT_STATUS_NO_MEMORY;
00421         }
00422 
00423         result = create_token_from_username(conn->mem_ctx, fuser, vuser_is_guest,
00424                                             &conn->uid, &conn->gid, &found_username,
00425                                             &conn->nt_user_token);
00426         if (!NT_STATUS_IS_OK(result)) {
00427                 return result;
00428         }
00429 
00430         fstrcpy(username, found_username);
00431 
00432         TALLOC_FREE(fuser);
00433         TALLOC_FREE(found_username);
00434         return NT_STATUS_OK;
00435 }

static NTSTATUS find_forced_group ( BOOL  force_user,
int  snum,
const char *  username,
DOM_SID pgroup_sid,
gid_t *  pgid 
) [static]

service.c444 行で定義されています。

参照先 lookup_name_smbconf()resultsid_copy()SID_NAME_ALIASSID_NAME_DOM_GRPSID_NAME_WKN_GRPsid_string_static()sid_to_gid()sid_type_lookup()talloc_strdup()talloc_string_sub()typeuser_in_group_sid().

参照元 make_connection_snum().

00448 {
00449         NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
00450         TALLOC_CTX *mem_ctx;
00451         DOM_SID group_sid;
00452         enum lsa_SidType type;
00453         char *groupname;
00454         BOOL user_must_be_member = False;
00455         gid_t gid;
00456 
00457         ZERO_STRUCTP(pgroup_sid);
00458         *pgid = (gid_t)-1;
00459 
00460         mem_ctx = talloc_new(NULL);
00461         if (mem_ctx == NULL) {
00462                 DEBUG(0, ("talloc_new failed\n"));
00463                 return NT_STATUS_NO_MEMORY;
00464         }
00465 
00466         groupname = talloc_strdup(mem_ctx, lp_force_group(snum));
00467         if (groupname == NULL) {
00468                 DEBUG(1, ("talloc_strdup failed\n"));
00469                 result = NT_STATUS_NO_MEMORY;
00470                 goto done;
00471         }
00472 
00473         if (groupname[0] == '+') {
00474                 user_must_be_member = True;
00475                 groupname += 1;
00476         }
00477 
00478         groupname = talloc_string_sub(mem_ctx, groupname,
00479                                       "%S", lp_servicename(snum));
00480 
00481         if (!lookup_name_smbconf(mem_ctx, groupname,
00482                          LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP,
00483                          NULL, NULL, &group_sid, &type)) {
00484                 DEBUG(10, ("lookup_name_smbconf(%s) failed\n",
00485                            groupname));
00486                 goto done;
00487         }
00488 
00489         if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
00490             (type != SID_NAME_WKN_GRP)) {
00491                 DEBUG(10, ("%s is a %s, not a group\n", groupname,
00492                            sid_type_lookup(type)));
00493                 goto done;
00494         }
00495 
00496         if (!sid_to_gid(&group_sid, &gid)) {
00497                 DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
00498                            sid_string_static(&group_sid), groupname));
00499                 goto done;
00500         }
00501 
00502         /*
00503          * If the user has been forced and the forced group starts with a '+',
00504          * then we only set the group to be the forced group if the forced
00505          * user is a member of that group.  Otherwise, the meaning of the '+'
00506          * would be ignored.
00507          */
00508 
00509         if (force_user && user_must_be_member) {
00510                 if (user_in_group_sid(username, &group_sid)) {
00511                         sid_copy(pgroup_sid, &group_sid);
00512                         *pgid = gid;
00513                         DEBUG(3,("Forced group %s for member %s\n",
00514                                  groupname, username));
00515                 } else {
00516                         DEBUG(0,("find_forced_group: forced user %s is not a member "
00517                                 "of forced group %s. Disallowing access.\n",
00518                                 username, groupname ));
00519                         result = NT_STATUS_MEMBER_NOT_IN_GROUP;
00520                         goto done;
00521                 }
00522         } else {
00523                 sid_copy(pgroup_sid, &group_sid);
00524                 *pgid = gid;
00525                 DEBUG(3,("Forced group %s\n", groupname));
00526         }
00527 
00528         result = NT_STATUS_OK;
00529  done:
00530         TALLOC_FREE(mem_ctx);
00531         return result;
00532 }

static connection_struct* make_connection_snum ( int  snum,
user_struct vuser,
DATA_BLOB  password,
const char *  pdev,
NTSTATUS status 
) [static]

service.c539 行で定義されています。

参照先 add_gid_to_array_unique()add_session_user()connection_struct::admin_userconnection_struct::aio_write_behind_listauthorise_login()connection_struct::case_preserveconnection_struct::case_sensitiveclient_addr()connection_struct::client_addressconn_free()conn_new()create_token_from_username()devconnection_struct::dirpathconnection_struct::dirptrdup_nt_token()find_forced_group()find_forced_user()connection_struct::force_groupconnection_struct::force_userGet_Pwnam()getpwnam_alloc()user_struct::gidconnection_struct::gidconnection_struct::groupsuser_struct::guestconnection_struct::hide_listconnection_struct::ipcconnection_struct::lastusedconnection_struct::lastused_countconnection_struct::mem_ctxconnection_struct::ngroupsuser_struct::nt_user_tokenconnection_struct::nt_user_tokenconnection_struct::num_files_opennt_user_token::num_sidsconnection_struct::paramspasswordconnection_struct::printerconnection_struct::read_onlySEC_SHAREshare_params::serviceshare_sanity_checks()connection_struct::short_case_preservesid_copy()sid_string_static()sid_to_gid()statusstrequal()string_set()user_struct::uidconnection_struct::uiduserdom_struct::unix_nameconnection_struct::useduser_struct::userconnection_struct::useruser_ok_token()nt_user_token::user_sidsconnection_struct::veto_listconnection_struct::veto_oplock_listuser_struct::vuidconnection_struct::vuid.

参照元 make_connection().

00543 {
00544         struct passwd *pass = NULL;
00545         BOOL guest = False;
00546         connection_struct *conn;
00547         SMB_STRUCT_STAT st;
00548         fstring user;
00549         fstring dev;
00550         int ret;
00551 
00552         *user = 0;
00553         fstrcpy(dev, pdev);
00554         SET_STAT_INVALID(st);
00555 
00556         if (NT_STATUS_IS_ERR(*status = share_sanity_checks(snum, dev))) {
00557                 return NULL;
00558         }       
00559 
00560         conn = conn_new();
00561         if (!conn) {
00562                 DEBUG(0,("Couldn't find free connection.\n"));
00563                 *status = NT_STATUS_INSUFFICIENT_RESOURCES;
00564                 return NULL;
00565         }
00566 
00567         conn->params->service = snum;
00568         conn->nt_user_token = NULL;
00569 
00570         if (lp_guest_only(snum)) {
00571                 const char *guestname = lp_guestaccount();
00572                 NTSTATUS status2;
00573                 char *found_username = NULL;
00574 
00575                 guest = True;
00576                 pass = getpwnam_alloc(NULL, guestname);
00577                 if (!pass) {
00578                         DEBUG(0,("make_connection_snum: Invalid guest "
00579                                  "account %s??\n",guestname));
00580                         conn_free(conn);
00581                         *status = NT_STATUS_NO_SUCH_USER;
00582                         return NULL;
00583                 }
00584                 status2 = create_token_from_username(conn->mem_ctx, pass->pw_name, True,
00585                                                      &conn->uid, &conn->gid,
00586                                                      &found_username,
00587                                                      &conn->nt_user_token);
00588                 if (!NT_STATUS_IS_OK(status2)) {
00589                         TALLOC_FREE(pass);
00590                         conn_free(conn);
00591                         *status = status2;
00592                         return NULL;
00593                 }
00594                 fstrcpy(user, found_username);
00595                 string_set(&conn->user,user);
00596                 conn->force_user = True;
00597                 TALLOC_FREE(found_username);
00598                 TALLOC_FREE(pass);
00599                 DEBUG(3,("Guest only user %s\n",user));
00600         } else if (vuser) {
00601                 if (vuser->guest) {
00602                         if (!lp_guest_ok(snum)) {
00603                                 DEBUG(2, ("guest user (from session setup) "
00604                                           "not permitted to access this share "
00605                                           "(%s)\n", lp_servicename(snum)));
00606                                       conn_free(conn);
00607                                       *status = NT_STATUS_ACCESS_DENIED;
00608                                       return NULL;
00609                         }
00610                 } else {
00611                         if (!user_ok_token(vuser->user.unix_name,
00612                                            vuser->nt_user_token, snum)) {
00613                                 DEBUG(2, ("user '%s' (from session setup) not "
00614                                           "permitted to access this share "
00615                                           "(%s)\n", vuser->user.unix_name,
00616                                           lp_servicename(snum)));
00617                                 conn_free(conn);
00618                                 *status = NT_STATUS_ACCESS_DENIED;
00619                                 return NULL;
00620                         }
00621                 }
00622                 conn->vuid = vuser->vuid;
00623                 conn->uid = vuser->uid;
00624                 conn->gid = vuser->gid;
00625                 string_set(&conn->user,vuser->user.unix_name);
00626                 fstrcpy(user,vuser->user.unix_name);
00627                 guest = vuser->guest; 
00628         } else if (lp_security() == SEC_SHARE) {
00629                 NTSTATUS status2;
00630                 char *found_username = NULL;
00631 
00632                 /* add it as a possible user name if we 
00633                    are in share mode security */
00634                 add_session_user(lp_servicename(snum));
00635                 /* shall we let them in? */
00636                 if (!authorise_login(snum,user,password,&guest)) {
00637                         DEBUG( 2, ( "Invalid username/password for [%s]\n", 
00638                                     lp_servicename(snum)) );
00639                         conn_free(conn);
00640                         *status = NT_STATUS_WRONG_PASSWORD;
00641                         return NULL;
00642                 }
00643                 pass = Get_Pwnam(user);
00644                 status2 = create_token_from_username(conn->mem_ctx, pass->pw_name, True,
00645                                                      &conn->uid, &conn->gid,
00646                                                      &found_username,
00647                                                      &conn->nt_user_token);
00648                 if (!NT_STATUS_IS_OK(status2)) {
00649                         conn_free(conn);
00650                         *status = status2;
00651                         return NULL;
00652                 }
00653                 fstrcpy(user, found_username);
00654                 string_set(&conn->user,user);
00655                 TALLOC_FREE(found_username);
00656                 conn->force_user = True;
00657         } else {
00658                 DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
00659                 conn_free(conn);
00660                 *status = NT_STATUS_ACCESS_DENIED;
00661                 return NULL;
00662         }
00663 
00664         add_session_user(user);
00665 
00666         safe_strcpy(conn->client_address, client_addr(), 
00667                     sizeof(conn->client_address)-1);
00668         conn->num_files_open = 0;
00669         conn->lastused = conn->lastused_count = time(NULL);
00670         conn->used = True;
00671         conn->printer = (strncmp(dev,"LPT",3) == 0);
00672         conn->ipc = ( (strncmp(dev,"IPC",3) == 0) ||
00673                       ( lp_enable_asu_support() && strequal(dev,"ADMIN$")) );
00674         conn->dirptr = NULL;
00675 
00676         /* Case options for the share. */
00677         if (lp_casesensitive(snum) == Auto) {
00678                 /* We will be setting this per packet. Set to be case
00679                  * insensitive for now. */
00680                 conn->case_sensitive = False;
00681         } else {
00682                 conn->case_sensitive = (BOOL)lp_casesensitive(snum);
00683         }
00684 
00685         conn->case_preserve = lp_preservecase(snum);
00686         conn->short_case_preserve = lp_shortpreservecase(snum);
00687 
00688         conn->veto_list = NULL;
00689         conn->hide_list = NULL;
00690         conn->veto_oplock_list = NULL;
00691         conn->aio_write_behind_list = NULL;
00692         string_set(&conn->dirpath,"");
00693         string_set(&conn->user,user);
00694 
00695         conn->read_only = lp_readonly(SNUM(conn));
00696         conn->admin_user = False;
00697 
00698         /*
00699          * If force user is true, then store the given userid and the gid of
00700          * the user we're forcing.
00701          * For auxiliary groups see below.
00702          */
00703         
00704         if (*lp_force_user(snum)) {
00705                 NTSTATUS status2;
00706 
00707                 status2 = find_forced_user(conn,
00708                                 (vuser != NULL) && vuser->guest,
00709                                 user);
00710                 if (!NT_STATUS_IS_OK(status2)) {
00711                         conn_free(conn);
00712                         *status = status2;
00713                         return NULL;
00714                 }
00715                 string_set(&conn->user,user);
00716                 conn->force_user = True;
00717                 DEBUG(3,("Forced user %s\n",user));       
00718         }
00719 
00720         /*
00721          * If force group is true, then override
00722          * any groupid stored for the connecting user.
00723          */
00724         
00725         if (*lp_force_group(snum)) {
00726                 NTSTATUS status2;
00727                 DOM_SID group_sid;
00728 
00729                 status2 = find_forced_group(conn->force_user,
00730                                             snum, user,
00731                                             &group_sid, &conn->gid);
00732                 if (!NT_STATUS_IS_OK(status2)) {
00733                         conn_free(conn);
00734                         *status = status2;
00735                         return NULL;
00736                 }
00737 
00738                 if ((conn->nt_user_token == NULL) && (vuser != NULL)) {
00739 
00740                         /* Not force user and not security=share, but force
00741                          * group. vuser has a token to copy */
00742                         
00743                         conn->nt_user_token = dup_nt_token(
00744                                 NULL, vuser->nt_user_token);
00745                         if (conn->nt_user_token == NULL) {
00746                                 DEBUG(0, ("dup_nt_token failed\n"));
00747                                 conn_free(conn);
00748                                 *status = NT_STATUS_NO_MEMORY;
00749                                 return NULL;
00750                         }
00751                 }
00752 
00753                 /* If conn->nt_user_token is still NULL, we have
00754                  * security=share. This means ignore the SID, as we had no
00755                  * vuser to copy from */
00756 
00757                 if (conn->nt_user_token != NULL) {
00758                         /* Overwrite the primary group sid */
00759                         sid_copy(&conn->nt_user_token->user_sids[1],
00760                                  &group_sid);
00761 
00762                 }
00763                 conn->force_group = True;
00764         }
00765 
00766         if (conn->nt_user_token != NULL) {
00767                 size_t i;
00768 
00769                 /* We have a share-specific token from force [user|group].
00770                  * This means we have to create the list of unix groups from
00771                  * the list of sids. */
00772 
00773                 conn->ngroups = 0;
00774                 conn->groups = NULL;
00775 
00776                 for (i=0; i<conn->nt_user_token->num_sids; i++) {
00777                         gid_t gid;
00778                         DOM_SID *sid = &conn->nt_user_token->user_sids[i];
00779 
00780                         if (!sid_to_gid(sid, &gid)) {
00781                                 DEBUG(10, ("Could not convert SID %s to gid, "
00782                                            "ignoring it\n",
00783                                            sid_string_static(sid)));
00784                                 continue;
00785                         }
00786                         if (!add_gid_to_array_unique(conn->mem_ctx, gid, &conn->groups,
00787                                                 &conn->ngroups)) {
00788                                 DEBUG(0, ("add_gid_to_array_unique failed\n"));
00789                                 conn_free(conn);
00790                                 *status = NT_STATUS_NO_MEMORY;
00791                                 return NULL;
00792                         }
00793                 }
00794         }
00795 
00796         {
00797                 pstring s;
00798                 pstrcpy(s,lp_pathname(snum));
00799                 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
00800                                       conn->connectpath, conn->gid,
00801                                       get_current_username(),
00802                                       current_user_info.domain,
00803                                       s, sizeof(s));
00804                 set_conn_connectpath(conn,s);
00805                 DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
00806                          lp_servicename(snum)));
00807         }
00808 
00809         /*
00810          * New code to check if there's a share security descripter
00811          * added from NT server manager. This is done after the
00812          * smb.conf checks are done as we need a uid and token. JRA.
00813          *
00814          */
00815 
00816         {
00817                 BOOL can_write = False;
00818                 NT_USER_TOKEN *token = conn->nt_user_token ?
00819                         conn->nt_user_token :
00820                         (vuser ? vuser->nt_user_token : NULL);
00821 
00822                 /*
00823                  * I don't believe this can happen. But the
00824                  * logic above is convoluted enough to confuse
00825                  * automated checkers, so be sure. JRA.
00826                  */
00827 
00828                 if (token == NULL) {
00829                         DEBUG(0,("make_connection: connection to %s "
00830                                  "denied due to missing "
00831                                  "NT token.\n",
00832                                   lp_servicename(snum)));
00833                         conn_free(conn);
00834                         *status = NT_STATUS_ACCESS_DENIED;
00835                         return NULL;
00836                 }
00837 
00838                 can_write = share_access_check(token,
00839                                                     lp_servicename(snum),
00840                                                     FILE_WRITE_DATA);
00841 
00842                 if (!can_write) {
00843                         if (!share_access_check(token,
00844                                                 lp_servicename(snum),
00845                                                 FILE_READ_DATA)) {
00846                                 /* No access, read or write. */
00847                                 DEBUG(0,("make_connection: connection to %s "
00848                                          "denied due to security "
00849                                          "descriptor.\n",
00850                                           lp_servicename(snum)));
00851                                 conn_free(conn);
00852                                 *status = NT_STATUS_ACCESS_DENIED;
00853                                 return NULL;
00854                         } else {
00855                                 conn->read_only = True;
00856                         }
00857                 }
00858         }
00859         /* Initialise VFS function pointers */
00860 
00861         if (!smbd_vfs_init(conn)) {
00862                 DEBUG(0, ("vfs_init failed for service %s\n",
00863                           lp_servicename(snum)));
00864                 conn_free(conn);
00865                 *status = NT_STATUS_BAD_NETWORK_NAME;
00866                 return NULL;
00867         }
00868 
00869         /*
00870          * If widelinks are disallowed we need to canonicalise the connect
00871          * path here to ensure we don't have any symlinks in the
00872          * connectpath. We will be checking all paths on this connection are
00873          * below this directory. We must do this after the VFS init as we
00874          * depend on the realpath() pointer in the vfs table. JRA.
00875          */
00876         if (!lp_widelinks(snum)) {
00877                 pstring s;
00878                 pstrcpy(s,conn->connectpath);
00879                 canonicalize_path(conn, s);
00880                 set_conn_connectpath(conn,s);
00881         }
00882 
00883         if ((!conn->printer) && (!conn->ipc)) {
00884                 conn->notify_ctx = notify_init(conn->mem_ctx, server_id_self(),
00885                                                smbd_messaging_context(),
00886                                                smbd_event_context(),
00887                                                conn);
00888         }
00889 
00890 /* ROOT Activities: */  
00891         /* check number of connections */
00892         if (!claim_connection(conn,
00893                               lp_servicename(snum),
00894                               lp_max_connections(snum),
00895                               False,0)) {
00896                 DEBUG(1,("too many connections - rejected\n"));
00897                 conn_free(conn);
00898                 *status = NT_STATUS_INSUFFICIENT_RESOURCES;
00899                 return NULL;
00900         }  
00901 
00902         /* Preexecs are done here as they might make the dir we are to ChDir
00903          * to below */
00904         /* execute any "root preexec = " line */
00905         if (*lp_rootpreexec(snum)) {
00906                 pstring cmd;
00907                 pstrcpy(cmd,lp_rootpreexec(snum));
00908                 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
00909                                       conn->connectpath, conn->gid,
00910                                       get_current_username(),
00911                                       current_user_info.domain,
00912                                       cmd, sizeof(cmd));
00913                 DEBUG(5,("cmd=%s\n",cmd));
00914                 ret = smbrun(cmd,NULL);
00915                 if (ret != 0 && lp_rootpreexec_close(snum)) {
00916                         DEBUG(1,("root preexec gave %d - failing "
00917                                  "connection\n", ret));
00918                         yield_connection(conn, lp_servicename(snum));
00919                         conn_free(conn);
00920                         *status = NT_STATUS_ACCESS_DENIED;
00921                         return NULL;
00922                 }
00923         }
00924 
00925 /* USER Activites: */
00926         if (!change_to_user(conn, conn->vuid)) {
00927                 /* No point continuing if they fail the basic checks */
00928                 DEBUG(0,("Can't become connected user!\n"));
00929                 yield_connection(conn, lp_servicename(snum));
00930                 conn_free(conn);
00931                 *status = NT_STATUS_LOGON_FAILURE;
00932                 return NULL;
00933         }
00934 
00935         /* Remember that a different vuid can connect later without these
00936          * checks... */
00937         
00938         /* Preexecs are done here as they might make the dir we are to ChDir
00939          * to below */
00940 
00941         /* execute any "preexec = " line */
00942         if (*lp_preexec(snum)) {
00943                 pstring cmd;
00944                 pstrcpy(cmd,lp_preexec(snum));
00945                 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
00946                                       conn->connectpath, conn->gid,
00947                                       get_current_username(),
00948                                       current_user_info.domain,
00949                                       cmd, sizeof(cmd));
00950                 ret = smbrun(cmd,NULL);
00951                 if (ret != 0 && lp_preexec_close(snum)) {
00952                         DEBUG(1,("preexec gave %d - failing connection\n",
00953                                  ret));
00954                         change_to_root_user();
00955                         yield_connection(conn, lp_servicename(snum));
00956                         conn_free(conn);
00957                         *status = NT_STATUS_ACCESS_DENIED;
00958                         return NULL;
00959                 }
00960         }
00961 
00962 #ifdef WITH_FAKE_KASERVER
00963         if (lp_afs_share(snum)) {
00964                 afs_login(conn);
00965         }
00966 #endif
00967         
00968         /* Add veto/hide lists */
00969         if (!IS_IPC(conn) && !IS_PRINT(conn)) {
00970                 set_namearray( &conn->veto_list, lp_veto_files(snum));
00971                 set_namearray( &conn->hide_list, lp_hide_files(snum));
00972                 set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(snum));
00973         }
00974         
00975         /* Invoke VFS make connection hook - do this before the VFS_STAT call
00976            to allow any filesystems needing user credentials to initialize
00977            themselves. */
00978 
00979         if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) {
00980                 DEBUG(0,("make_connection: VFS make connection failed!\n"));
00981                 change_to_root_user();
00982                 yield_connection(conn, lp_servicename(snum));
00983                 conn_free(conn);
00984                 *status = NT_STATUS_UNSUCCESSFUL;
00985                 return NULL;
00986         }
00987 
00988         /* win2000 does not check the permissions on the directory
00989            during the tree connect, instead relying on permission
00990            check during individual operations. To match this behaviour
00991            I have disabled this chdir check (tridge) */
00992         /* the alternative is just to check the directory exists */
00993         if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 ||
00994             !S_ISDIR(st.st_mode)) {
00995                 if (ret == 0 && !S_ISDIR(st.st_mode)) {
00996                         DEBUG(0,("'%s' is not a directory, when connecting to "
00997                                  "[%s]\n", conn->connectpath,
00998                                  lp_servicename(snum)));
00999                 } else {
01000                         DEBUG(0,("'%s' does not exist or permission denied "
01001                                  "when connecting to [%s] Error was %s\n",
01002                                  conn->connectpath, lp_servicename(snum),
01003                                  strerror(errno) ));
01004                 }
01005                 change_to_root_user();
01006                 /* Call VFS disconnect hook */    
01007                 SMB_VFS_DISCONNECT(conn);
01008                 yield_connection(conn, lp_servicename(snum));
01009                 conn_free(conn);
01010                 *status = NT_STATUS_BAD_NETWORK_NAME;
01011                 return NULL;
01012         }
01013         
01014         string_set(&conn->origpath,conn->connectpath);
01015         
01016 #if SOFTLINK_OPTIMISATION
01017         /* resolve any soft links early if possible */
01018         if (vfs_ChDir(conn,conn->connectpath) == 0) {
01019                 pstring s;
01020                 pstrcpy(s,conn->connectpath);
01021                 vfs_GetWd(conn,s);
01022                 set_conn_connectpath(conn,s);
01023                 vfs_ChDir(conn,conn->connectpath);
01024         }
01025 #endif
01026         
01027         /*
01028          * Print out the 'connected as' stuff here as we need
01029          * to know the effective uid and gid we will be using
01030          * (at least initially).
01031          */
01032 
01033         if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
01034                 dbgtext( "%s (%s) ", get_remote_machine_name(),
01035                          conn->client_address );
01036                 dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
01037                 dbgtext( "connect to service %s ", lp_servicename(snum) );
01038                 dbgtext( "initially as user %s ", user );
01039                 dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
01040                 dbgtext( "(pid %d)\n", (int)sys_getpid() );
01041         }
01042         
01043         /* we've finished with the user stuff - go back to root */
01044         change_to_root_user();
01045         return(conn);
01046 }

connection_struct* make_connection_with_chdir ( const char *  service_in,
DATA_BLOB  password,
const char *  dev,
uint16  vuid,
NTSTATUS status 
)

service.c1053 行で定義されています。

参照先 conn_free()connection_struct::connectpatherrnomake_connection()passwordstatusstrerror()vfs_ChDir()yield_connection().

参照元 delete_driver_files()get_correct_cversion()move_driver_to_download_area().

01057 {
01058         connection_struct *conn = NULL;
01059         
01060         conn = make_connection(service_in, password, dev, vuid, status);
01061         
01062         /*
01063          * make_connection() does not change the directory for us any more
01064          * so we have to do it as a separate step  --jerry
01065          */
01066          
01067         if ( conn && vfs_ChDir(conn,conn->connectpath) != 0 ) {
01068                 DEBUG(0,("move_driver_to_download_area: Can't change "
01069                          "directory to %s for [print$] (%s)\n",
01070                          conn->connectpath,strerror(errno)));
01071                 yield_connection(conn, lp_servicename(SNUM(conn)));
01072                 conn_free(conn);
01073                 *status = NT_STATUS_UNSUCCESSFUL;
01074                 return NULL;
01075         }
01076         
01077         return conn;
01078 }

connection_struct* make_connection ( const char *  service_in,
DATA_BLOB  password,
const char *  pdev,
uint16  vuid,
NTSTATUS status 
)

service.c1086 行で定義されています。

参照先 client_addr()conn_num_open()current_user_infodata_blob()devfind_service()get_remote_machine_name()get_valid_user_struct()user_struct::homes_snummake_connection_snum()map_username()non_root_mode()passwordSEC_SHAREuserdom_struct::smb_namesmb_panic()statusstrequal()strlower_m().

参照元 _srv_net_file_query_secdesc()_srv_net_file_set_secdesc()make_connection_with_chdir()reply_tcon()reply_tcon_and_X().

01089 {
01090         uid_t euid;
01091         user_struct *vuser = NULL;
01092         fstring service;
01093         fstring dev;
01094         int snum = -1;
01095 
01096         fstrcpy(dev, pdev);
01097 
01098         /* This must ONLY BE CALLED AS ROOT. As it exits this function as
01099          * root. */
01100         if (!non_root_mode() && (euid = geteuid()) != 0) {
01101                 DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
01102                          "(%u)\n", (unsigned int)euid ));
01103                 smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
01104         }
01105 
01106         if (conn_num_open() > 2047) {
01107                 *status = NT_STATUS_INSUFF_SERVER_RESOURCES;
01108                 return NULL;
01109         }
01110 
01111         if(lp_security() != SEC_SHARE) {
01112                 vuser = get_valid_user_struct(vuid);
01113                 if (!vuser) {
01114                         DEBUG(1,("make_connection: refusing to connect with "
01115                                  "no session setup\n"));
01116                         *status = NT_STATUS_ACCESS_DENIED;
01117                         return NULL;
01118                 }
01119         }
01120 
01121         /* Logic to try and connect to the correct [homes] share, preferably
01122            without too many getpwnam() lookups.  This is particulary nasty for
01123            winbind usernames, where the share name isn't the same as unix
01124            username.
01125 
01126            The snum of the homes share is stored on the vuser at session setup
01127            time.
01128         */
01129 
01130         if (strequal(service_in,HOMES_NAME)) {
01131                 if(lp_security() != SEC_SHARE) {
01132                         DATA_BLOB no_pw = data_blob(NULL, 0);
01133                         if (vuser->homes_snum == -1) {
01134                                 DEBUG(2, ("[homes] share not available for "
01135                                           "this user because it was not found "
01136                                           "or created at session setup "
01137                                           "time\n"));
01138                                 *status = NT_STATUS_BAD_NETWORK_NAME;
01139                                 return NULL;
01140                         }
01141                         DEBUG(5, ("making a connection to [homes] service "
01142                                   "created at session setup time\n"));
01143                         return make_connection_snum(vuser->homes_snum,
01144                                                     vuser, no_pw, 
01145                                                     dev, status);
01146                 } else {
01147                         /* Security = share. Try with
01148                          * current_user_info.smb_name as the username.  */
01149                         if (*current_user_info.smb_name) {
01150                                 fstring unix_username;
01151                                 fstrcpy(unix_username,
01152                                         current_user_info.smb_name);
01153                                 map_username(unix_username);
01154                                 snum = find_service(unix_username);
01155                         } 
01156                         if (snum != -1) {
01157                                 DEBUG(5, ("making a connection to 'homes' "
01158                                           "service %s based on "
01159                                           "security=share\n", service_in));
01160                                 return make_connection_snum(snum, NULL,
01161                                                             password,
01162                                                             dev, status);
01163                         }
01164                 }
01165         } else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1)
01166                    && strequal(service_in,
01167                                lp_servicename(vuser->homes_snum))) {
01168                 DATA_BLOB no_pw = data_blob(NULL, 0);
01169                 DEBUG(5, ("making a connection to 'homes' service [%s] "
01170                           "created at session setup time\n", service_in));
01171                 return make_connection_snum(vuser->homes_snum,
01172                                             vuser, no_pw, 
01173                                             dev, status);
01174         }
01175         
01176         fstrcpy(service, service_in);
01177 
01178         strlower_m(service);
01179 
01180         snum = find_service(service);
01181 
01182         if (snum < 0) {
01183                 if (strequal(service,"IPC$") ||
01184                     (lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
01185                         DEBUG(3,("refusing IPC connection to %s\n", service));
01186                         *status = NT_STATUS_ACCESS_DENIED;
01187                         return NULL;
01188                 }
01189 
01190                 DEBUG(0,("%s (%s) couldn't find service %s\n",
01191                          get_remote_machine_name(), client_addr(), service));
01192                 *status = NT_STATUS_BAD_NETWORK_NAME;
01193                 return NULL;
01194         }
01195 
01196         /* Handle non-Dfs clients attempting connections to msdfs proxy */
01197         if (lp_host_msdfs() && (*lp_msdfs_proxy(snum) != '\0'))  {
01198                 DEBUG(3, ("refusing connection to dfs proxy share '%s' "
01199                           "(pointing to %s)\n", 
01200                         service, lp_msdfs_proxy(snum)));
01201                 *status = NT_STATUS_BAD_NETWORK_NAME;
01202                 return NULL;
01203         }
01204 
01205         DEBUG(5, ("making a connection to 'normal' service %s\n", service));
01206 
01207         return make_connection_snum(snum, vuser,
01208                                     password,
01209                                     dev, status);
01210 }

void close_cnum ( connection_struct conn,
uint16  vuid 
)

service.c1216 行で定義されています。

参照先 change_to_root_user()change_to_user()connection_struct::client_addressconn_free()connection_struct::connectpathcurrent_user_infouserdom_struct::domaindptr_closecnum()file_close_conn()get_current_username()get_remote_machine_name()connection_struct::gidpipe_close_conn()smbrun()standard_sub_advanced()connection_struct::uservfs_ChDir()yield_connection().

参照元 _srv_net_file_query_secdesc()_srv_net_file_set_secdesc()conn_close_all()get_correct_cversion()handle_trans()msg_force_tdis()reply_tcon_and_X()reply_tdis().

01217 {
01218         if (IS_IPC(conn)) {
01219                 pipe_close_conn(conn);
01220         } else {
01221                 file_close_conn(conn);
01222                 dptr_closecnum(conn);
01223         }
01224 
01225         change_to_root_user();
01226 
01227         DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
01228                                  get_remote_machine_name(),
01229                                  conn->client_address,
01230                                  lp_servicename(SNUM(conn))));
01231 
01232         /* Call VFS disconnect hook */    
01233         SMB_VFS_DISCONNECT(conn);
01234 
01235         yield_connection(conn, lp_servicename(SNUM(conn)));
01236 
01237         /* make sure we leave the directory available for unmount */
01238         vfs_ChDir(conn, "/");
01239 
01240         /* execute any "postexec = " line */
01241         if (*lp_postexec(SNUM(conn)) && 
01242             change_to_user(conn, vuid))  {
01243                 pstring cmd;
01244                 pstrcpy(cmd,lp_postexec(SNUM(conn)));
01245                 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
01246                                       conn->connectpath, conn->gid,
01247                                       get_current_username(),
01248                                       current_user_info.domain,
01249                                       cmd, sizeof(cmd));
01250                 smbrun(cmd,NULL);
01251                 change_to_root_user();
01252         }
01253 
01254         change_to_root_user();
01255         /* execute any "root postexec = " line */
01256         if (*lp_rootpostexec(SNUM(conn)))  {
01257                 pstring cmd;
01258                 pstrcpy(cmd,lp_rootpostexec(SNUM(conn)));
01259                 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
01260                                       conn->connectpath, conn->gid,
01261                                       get_current_username(),
01262                                       current_user_info.domain,
01263                                       cmd, sizeof(cmd));
01264                 smbrun(cmd,NULL);
01265         }
01266 
01267         conn_free(conn);
01268 }


変数

userdom_struct current_user_info

substitute.c29 行で定義されています。


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