- got client code cleartext passwords working again in cli_session_setup.
[samba.git] / source / smbwrapper / smbw.c
index 2dcf4cc588d97331ad174c80fe3eb11b76a13e75..dfe99a7ed1afa7cd75e80ba05535cebe8af66d9b 100644 (file)
@@ -38,6 +38,7 @@ int smbw_busy=0;
 /* needs to be here because of dumb include files on some systems */
 int creat_bits = O_WRONLY|O_CREAT|O_TRUNC;
 
+
 /***************************************************** 
 initialise structures
 *******************************************************/
@@ -49,6 +50,7 @@ void smbw_init(void)
        extern FILE *dbf;
        char *p;
        int eno;
+       pstring line;
 
        if (initialised) return;
        initialised = 1;
@@ -58,12 +60,12 @@ void smbw_init(void)
        smbw_busy++;
 
        DEBUGLEVEL = 0;
-       setup_logging("smbw",True);
+       setup_logging("smbsh",True);
 
        dbf = stderr;
 
-       if ((p=getenv("SMBW_LOGFILE"))) {
-               dbf = fopen(p, "a");
+       if ((p=smbw_getshared("LOGFILE"))) {
+               dbf = sys_fopen(p, "a");
        }
 
        smbw_file_bmap = bitmap_allocate(SMBW_MAX_OPEN);
@@ -81,26 +83,34 @@ void smbw_init(void)
 
        get_myname(global_myname,NULL);
 
-       if ((p=getenv("SMBW_DEBUG"))) {
+       if ((p=smbw_getshared("DEBUG"))) {
                DEBUGLEVEL = atoi(p);
        }
 
-       if ((p=getenv("SMBW_PREFIX"))) {
+       if ((p=smbw_getshared("RESOLVE_ORDER"))) {
+               lp_set_name_resolve_order(p);
+       }
+
+       if ((p=smbw_getshared("PREFIX"))) {
                slprintf(smbw_prefix,sizeof(fstring)-1, "/%s/", p);
                string_sub(smbw_prefix,"//", "/");
                DEBUG(2,("SMBW_PREFIX is %s\n", smbw_prefix));
        }
 
-       if ((p=getenv(SMBW_PWD_ENV))) {
-               pstrcpy(smbw_cwd, p);
-               DEBUG(4,("Initial cwd from smbw_cwd is %s\n", smbw_cwd));
-       } else {
+       slprintf(line,sizeof(line)-1,"PWD_%d", getpid());
+       
+       p = smbw_getshared(line);
+       if (!p) {
                sys_getwd(smbw_cwd);
-               DEBUG(4,("Initial cwd from getwd is %s\n", smbw_cwd));
        }
+       pstrcpy(smbw_cwd, p);
+       DEBUG(4,("Initial cwd is %s\n", smbw_cwd));
+
        smbw_busy--;
 
-       set_maxfiles();
+       set_maxfiles(SMBW_MAX_OPEN);
+
+       BlockSignals(True,SIGPIPE);
 
        errno = eno;
 }
@@ -114,11 +124,31 @@ int smbw_fd(int fd)
        return smbw_file_bmap && bitmap_query(smbw_file_bmap, fd);
 }
 
+/***************************************************** 
+determine if a file descriptor is an internal smbw fd
+*******************************************************/
+int smbw_local_fd(int fd)
+{
+       struct smbw_server *srv;
+       
+       smbw_init();
+
+       if (smbw_busy) return 0;
+       if (smbw_shared_fd(fd)) return 1;
+
+       for (srv=smbw_srvs;srv;srv=srv->next) {
+               if (srv->cli.fd == fd) return 1;
+       }
+
+       return 0;
+}
+
 /***************************************************** 
 a crude inode number generator
 *******************************************************/
 ino_t smbw_inode(const char *name)
 {
+       if (!*name) return 2;
        return (ino_t)str_checksum(name);
 }
 
@@ -259,7 +289,7 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
        p = p2;
        if (!p) {
                if (len == 0) {
-                       char *workgroup = getenv("SMBW_WORKGROUP");
+                       char *workgroup = smbw_getshared("WORKGROUP");
                        if (!workgroup) workgroup = lp_workgroup();
                        slprintf(server,sizeof(fstring)-1, "%s#1D", workgroup);
                }
@@ -293,7 +323,7 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
        string_sub(path, "/", "\\");
 
  ok:
-       DEBUG(5,("parsed path name=%s cwd=%s [%s] [%s] [%s]\n", 
+       DEBUG(4,("parsed path name=%s cwd=%s [%s] [%s] [%s]\n", 
                 fname, smbw_cwd,
                 server, share, path));
 
@@ -311,6 +341,12 @@ int smbw_path(const char *path)
        char *cwd;
        int len;
 
+       /* this is needed to prevent recursion with the BSD malloc which
+          opens /etc/malloc.conf on the first call */
+       if (strncmp(path,"/etc/", 5) == 0) {
+               return 0;
+       }
+
        smbw_init();
 
        len = strlen(smbw_prefix)-1;
@@ -364,17 +400,22 @@ struct smbw_server *smbw_server(char *server, char *share)
        struct nmb_name called, calling;
        char *p, *server_n = server;
        fstring group;
+       pstring ipenv;
+       struct in_addr ip;
+       extern struct in_addr ipzero;
+       char lm_24[24], nt_24[24];
 
+       ip = ipzero;
        ZERO_STRUCT(c);
 
-       username = getenv("SMBW_USER");
+       username = smbw_getshared("USER");
        if (!username) username = getenv("USER");
        if (!username) username = "guest";
 
-       workgroup = getenv("SMBW_WORKGROUP");
+       workgroup = smbw_getshared("WORKGROUP");
        if (!workgroup) workgroup = lp_workgroup();
 
-       password = getenv("SMBW_PASSWORD");
+       password = smbw_getshared("PASSWORD");
        if (!password) password = "";
 
        /* try to use an existing connection */
@@ -391,26 +432,41 @@ struct smbw_server *smbw_server(char *server, char *share)
        make_nmb_name(&calling, global_myname, 0x0, "");
        make_nmb_name(&called , server, 0x20, "");
 
-       DEBUG(5,("server_n=[%s] server=[%s]\n", server_n, server));
+       DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server));
 
        if ((p=strchr(server_n,'#')) && strcmp(p+1,"1D")==0) {
-               struct in_addr ip;
+               struct in_addr sip;
+               pstring s;
+
                fstrcpy(group, server_n);
                p = strchr(group,'#');
                *p = 0;
-               if (!find_master(group, &ip)) {
-                       errno = ENOENT;
-                       return NULL;
+               
+               /* cache the workgroup master lookup */
+               slprintf(s,sizeof(s)-1,"MASTER_%s", group);
+               if (!(server_n = smbw_getshared(s))) {
+                       if (!find_master_ip(group, &sip)) {
+                               errno = ENOENT;
+                               return NULL;
+                       }
+                       fstrcpy(group, inet_ntoa(sip));
+                       server_n = group;
+                       smbw_setshared(s,server_n);
                }
-               fstrcpy(group, inet_ntoa(ip));
-               server_n = group;
        }
 
-       DEBUG(5,(" -> server_n=[%s] server=[%s]\n", server_n, server));
+       DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
 
  again:
+       slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
+
+       ip = ipzero;
+       if ((p=smbw_getshared(ipenv))) {
+               ip = *(interpret_addr2(p));
+       }
+
        /* have to open a new connection */
-       if (!cli_initialise(&c) || !cli_connect(&c, server_n, NULL)) {
+       if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) {
                errno = ENOENT;
                return NULL;
        }
@@ -425,6 +481,7 @@ struct smbw_server *smbw_server(char *server, char *share)
                return NULL;
        }
 
+       DEBUG(4,(" session request ok\n"));
 
        if (!cli_negprot(&c)) {
                cli_shutdown(&c);
@@ -432,9 +489,12 @@ struct smbw_server *smbw_server(char *server, char *share)
                return NULL;
        }
 
+       SMBencrypt  ((uchar *)password,(uchar *)c.cryptkey,(uchar *)lm_24);
+       SMBNTencrypt((uchar *)password,(uchar *)c.cryptkey,(uchar *)nt_24);
+
        if (!cli_session_setup(&c, username, 
-                              password, strlen(password),
-                              password, strlen(password),
+                              lm_24, 24,
+                              nt_24, 24,
                               workgroup) &&
            /* try an anonymous login if it failed */
            !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) {
@@ -443,6 +503,8 @@ struct smbw_server *smbw_server(char *server, char *share)
                return NULL;
        }
 
+       DEBUG(4,(" session setup ok\n"));
+
        if (!cli_send_tconX(&c, share, "?????",
                            password, strlen(password)+1)) {
                errno = smbw_errno(&c);
@@ -450,6 +512,10 @@ struct smbw_server *smbw_server(char *server, char *share)
                return NULL;
        }
 
+       smbw_setshared(ipenv,inet_ntoa(ip));
+       
+       DEBUG(4,(" tconx ok\n"));
+
        srv = (struct smbw_server *)malloc(sizeof(*srv));
        if (!srv) {
                errno = ENOMEM;
@@ -699,13 +765,12 @@ ssize_t smbw_write(int fd, void *buf, size_t count)
 
        file = smbw_file(fd);
        if (!file) {
-               DEBUG(3,("bad fd in read\n"));
                errno = EBADF;
                smbw_busy--;
                return -1;
        }
        
-       ret = cli_write(&file->srv->cli, file->f->cli_fd, buf, file->f->offset, count);
+       ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, file->f->offset, count);
 
        if (ret == -1) {
                errno = smbw_errno(&file->srv->cli);
@@ -731,13 +796,12 @@ ssize_t smbw_pwrite(int fd, void *buf, size_t count, off_t ofs)
 
        file = smbw_file(fd);
        if (!file) {
-               DEBUG(3,("bad fd in read\n"));
                errno = EBADF;
                smbw_busy--;
                return -1;
        }
        
-       ret = cli_write(&file->srv->cli, file->f->cli_fd, buf, ofs, count);
+       ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, ofs, count);
 
        if (ret == -1) {
                errno = smbw_errno(&file->srv->cli);
@@ -960,7 +1024,7 @@ static int smbw_settime(const char *fname, time_t t)
        struct smbw_server *srv;
        fstring server, share;
        pstring path;
-       uint32 mode;
+       uint16 mode;
 
        if (!fname) {
                errno = EINVAL;
@@ -1029,7 +1093,7 @@ int smbw_chown(const char *fname, uid_t owner, gid_t group)
        struct smbw_server *srv;
        fstring server, share;
        pstring path;
-       uint32 mode;
+       uint16 mode;
 
        if (!fname) {
                errno = EINVAL;
@@ -1140,7 +1204,8 @@ off_t smbw_lseek(int fd, off_t offset, int whence)
                break;
        case SEEK_END:
                if (!cli_qfileinfo(&file->srv->cli, file->f->cli_fd, 
-                                  NULL, &size, NULL, NULL, NULL) &&
+                                  NULL, &size, NULL, NULL, NULL, 
+                                  NULL, NULL) &&
                    !cli_getattrE(&file->srv->cli, file->f->cli_fd, 
                                  NULL, &size, NULL, NULL, NULL)) {
                        errno = EINVAL;
@@ -1292,6 +1357,7 @@ int smbw_fork(void)
        pid_t child;
        int p[2];
        char c=0;
+       pstring line;
 
        struct smbw_file *file, *next_file;
        struct smbw_server *srv, *next_srv;
@@ -1323,6 +1389,9 @@ int smbw_fork(void)
                smbw_srv_close(srv);
        }
 
+       slprintf(line,sizeof(line)-1,"PWD_%d", getpid());
+       smbw_setshared(line,smbw_cwd);
+
        /* unblock the parent */
        write(p[1], &c, 1);
        close(p[1]);
@@ -1335,7 +1404,7 @@ int smbw_fork(void)
 /***************************************************** 
 say no to acls
 *******************************************************/
-int smbw_acl(const char *pathp, int cmd, int nentries, aclent_t *aclbufp)
+ int smbw_acl(const char *pathp, int cmd, int nentries, aclent_t *aclbufp)
 {
        if (cmd == GETACL || cmd == GETACLCNT) return 0;
        errno = ENOSYS;
@@ -1347,7 +1416,7 @@ int smbw_acl(const char *pathp, int cmd, int nentries, aclent_t *aclbufp)
 /***************************************************** 
 say no to acls
 *******************************************************/
-int smbw_facl(int fd, int cmd, int nentries, aclent_t *aclbufp)
+ int smbw_facl(int fd, int cmd, int nentries, aclent_t *aclbufp)
 {
        if (cmd == GETACL || cmd == GETACLCNT) return 0;
        errno = ENOSYS;
@@ -1358,7 +1427,7 @@ int smbw_facl(int fd, int cmd, int nentries, aclent_t *aclbufp)
 
 #ifdef HAVE_STAT64
 /* this can't be in wrapped.c because of include conflicts */
-void stat64_convert(struct stat *st, struct stat64 *st64)
+ void stat64_convert(struct stat *st, struct stat64 *st64)
 {
        st64->st_size = st->st_size;
        st64->st_mode = st->st_mode;
@@ -1377,7 +1446,7 @@ void stat64_convert(struct stat *st, struct stat64 *st64)
 #endif
 
 #ifdef HAVE_READDIR64
-void dirent64_convert(struct dirent *d, struct dirent64 *d64)
+ void dirent64_convert(struct dirent *d, struct dirent64 *d64)
 {
        d64->d_ino = d->d_ino;
        d64->d_off = d->d_off;
@@ -1412,12 +1481,18 @@ struct kernel_stat {
        unsigned long int __unused5;
 };
 
-void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf)
+/*
+ * Prototype for gcc in 'fussy' mode.
+ */
+ void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf);
+ void xstat_convert(int vers, struct stat *st, struct kernel_stat *kbuf)
 {
+#ifdef _STAT_VER_LINUX_OLD
        if (vers == _STAT_VER_LINUX_OLD) {
                memcpy(st, kbuf, sizeof(*st));
                return;
        }
+#endif
 
        ZERO_STRUCTP(st);