r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need
[vlendec/samba-autobuild/.git] / source3 / smbd / service.c
index 5c4974329c79291c4349ebc9394622506360dc51..9dcb8a354f416625c2c290fe2dd43d822bc9b4c1 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "includes.h"
 
-extern struct timeval smb_last_time;
 extern userdom_struct current_user_info;
 
 /****************************************************************************
@@ -140,7 +139,7 @@ BOOL set_current_service(connection_struct *conn, uint16 flags, BOOL do_chdir)
                return(False);
        }
 
-       conn->lastused = smb_last_time.tv_sec;
+       conn->lastused_count++;
 
        snum = SNUM(conn);
   
@@ -372,35 +371,38 @@ static NTSTATUS find_forced_user(int snum, BOOL vuser_is_guest,
 {
        TALLOC_CTX *mem_ctx;
        char *fuser, *found_username;
+       struct nt_user_token *tmp_token;
        NTSTATUS result;
 
-       mem_ctx = talloc_new(NULL);
-       if (mem_ctx == NULL) {
+       if (!(mem_ctx = talloc_new(NULL))) {
                DEBUG(0, ("talloc_new failed\n"));
                return NT_STATUS_NO_MEMORY;
        }
 
-       fuser = talloc_string_sub(mem_ctx, lp_force_user(snum), "%S",
-                                 lp_servicename(snum));
-       if (fuser == NULL) {
-               result = NT_STATUS_NO_MEMORY;
-               goto done;
+       if (!(fuser = talloc_string_sub(mem_ctx, lp_force_user(snum), "%S",
+                                       lp_servicename(snum)))) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
+               
        }
 
        result = create_token_from_username(mem_ctx, fuser, vuser_is_guest,
                                            uid, gid, &found_username,
-                                           token);
+                                           &tmp_token);
        if (!NT_STATUS_IS_OK(result)) {
-               goto done;
+               TALLOC_FREE(mem_ctx);
+               return result;
+       }
+
+       if (!(*token = dup_nt_token(NULL, tmp_token))) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
        }
 
-       talloc_steal(NULL, *token);
        fstrcpy(username, found_username);
 
-       result = NT_STATUS_OK;
- done:
        TALLOC_FREE(mem_ctx);
-       return result;
+       return NT_STATUS_OK;
 }
 
 /*
@@ -524,8 +526,12 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
                return NULL;
        }
 
+       conn->nt_user_token = NULL;
+
        if (lp_guest_only(snum)) {
                const char *guestname = lp_guestaccount();
+               NTSTATUS status2;
+               char *found_username;
                guest = True;
                pass = getpwnam_alloc(NULL, guestname);
                if (!pass) {
@@ -535,11 +541,18 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
                        *status = NT_STATUS_NO_SUCH_USER;
                        return NULL;
                }
-               fstrcpy(user,pass->pw_name);
+               status2 = create_token_from_username(NULL, pass->pw_name, True,
+                                                    &conn->uid, &conn->gid,
+                                                    &found_username,
+                                                    &conn->nt_user_token);
+               if (!NT_STATUS_IS_OK(status2)) {
+                       conn_free(conn);
+                       *status = status2;
+                       return NULL;
+               }
+               fstrcpy(user, found_username);
+               string_set(&conn->user,user);
                conn->force_user = True;
-               conn->uid = pass->pw_uid;
-               conn->gid = pass->pw_gid;
-               string_set(&conn->user,pass->pw_name);
                TALLOC_FREE(pass);
                DEBUG(3,("Guest only user %s\n",user));
        } else if (vuser) {
@@ -571,6 +584,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
                fstrcpy(user,vuser->user.unix_name);
                guest = vuser->guest; 
        } else if (lp_security() == SEC_SHARE) {
+               NTSTATUS status2;
+               char *found_username;
                /* add it as a possible user name if we 
                   are in share mode security */
                add_session_user(lp_servicename(snum));
@@ -583,12 +598,18 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
                        return NULL;
                }
                pass = Get_Pwnam(user);
+               status2 = create_token_from_username(NULL, pass->pw_name, True,
+                                                    &conn->uid, &conn->gid,
+                                                    &found_username,
+                                                    &conn->nt_user_token);
+               if (!NT_STATUS_IS_OK(status2)) {
+                       conn_free(conn);
+                       *status = status2;
+                       return NULL;
+               }
+               fstrcpy(user, found_username);
+               string_set(&conn->user,user);
                conn->force_user = True;
-               conn->uid = pass->pw_uid;
-               conn->gid = pass->pw_gid;
-               string_set(&conn->user, pass->pw_name);
-               fstrcpy(user, pass->pw_name);
-
        } else {
                DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
                conn_free(conn);
@@ -601,8 +622,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
        safe_strcpy(conn->client_address, client_addr(), 
                    sizeof(conn->client_address)-1);
        conn->num_files_open = 0;
-       conn->lastused = time(NULL);
-       conn->service = snum;
+       conn->lastused = conn->lastused_count = time(NULL);
+       conn->params->service = snum;
        conn->used = True;
        conn->printer = (strncmp(dev,"LPT",3) == 0);
        conn->ipc = ( (strncmp(dev,"IPC",3) == 0) ||
@@ -627,9 +648,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
        conn->aio_write_behind_list = NULL;
        string_set(&conn->dirpath,"");
        string_set(&conn->user,user);
-       conn->nt_user_token = NULL;
 
-       conn->read_only = lp_readonly(conn->service);
+       conn->read_only = lp_readonly(SNUM(conn));
        conn->admin_user = False;
 
        /*
@@ -729,7 +749,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
        {
                pstring s;
                pstrcpy(s,lp_pathname(snum));
-               standard_sub_conn(conn,s,sizeof(s));
+               standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+                                     conn->connectpath, conn->gid,
+                                     get_current_username(),
+                                     current_user_info.domain,
+                                     s, sizeof(s));
                set_conn_connectpath(conn,s);
                DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
                         lp_servicename(snum)));
@@ -804,7 +828,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
        if (*lp_rootpreexec(snum)) {
                pstring cmd;
                pstrcpy(cmd,lp_rootpreexec(snum));
-               standard_sub_conn(conn,cmd,sizeof(cmd));
+               standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+                                     conn->connectpath, conn->gid,
+                                     get_current_username(),
+                                     current_user_info.domain,
+                                     cmd, sizeof(cmd));
                DEBUG(5,("cmd=%s\n",cmd));
                ret = smbrun(cmd,NULL);
                if (ret != 0 && lp_rootpreexec_close(snum)) {
@@ -837,7 +865,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
        if (*lp_preexec(snum)) {
                pstring cmd;
                pstrcpy(cmd,lp_preexec(snum));
-               standard_sub_conn(conn,cmd,sizeof(cmd));
+               standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+                                     conn->connectpath, conn->gid,
+                                     get_current_username(),
+                                     current_user_info.domain,
+                                     cmd, sizeof(cmd));
                ret = smbrun(cmd,NULL);
                if (ret != 0 && lp_preexec_close(snum)) {
                        DEBUG(1,("preexec gave %d - failing connection\n",
@@ -931,6 +963,9 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
                dbgtext( "(pid %d)\n", (int)sys_getpid() );
        }
        
+       /* Setup the minimum value for a change notify wait time (seconds). */
+       set_change_notify_timeout(lp_change_notify_timeout(snum));
+
        /* we've finished with the user stuff - go back to root */
        change_to_root_user();
        return(conn);
@@ -1128,7 +1163,11 @@ void close_cnum(connection_struct *conn, uint16 vuid)
            change_to_user(conn, vuid))  {
                pstring cmd;
                pstrcpy(cmd,lp_postexec(SNUM(conn)));
-               standard_sub_conn(conn,cmd,sizeof(cmd));
+               standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+                                     conn->connectpath, conn->gid,
+                                     get_current_username(),
+                                     current_user_info.domain,
+                                     cmd, sizeof(cmd));
                smbrun(cmd,NULL);
                change_to_root_user();
        }
@@ -1138,7 +1177,11 @@ void close_cnum(connection_struct *conn, uint16 vuid)
        if (*lp_rootpostexec(SNUM(conn)))  {
                pstring cmd;
                pstrcpy(cmd,lp_rootpostexec(SNUM(conn)));
-               standard_sub_conn(conn,cmd,sizeof(cmd));
+               standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+                                     conn->connectpath, conn->gid,
+                                     get_current_username(),
+                                     current_user_info.domain,
+                                     cmd, sizeof(cmd));
                smbrun(cmd,NULL);
        }