s3/lib: add parent_smb_fname()
[vlendec/samba-autobuild/.git] / source3 / libsmb / libsmb_xattr.c
index f8dd7fdefb962dc18db7afd26383af2ef22ad04a..059233b4f091c9d7c917d83bf91fb457a30a3bb6 100644 (file)
@@ -23,6 +23,7 @@
 */
 
 #include "includes.h"
+#include "libsmb/libsmb.h"
 #include "libsmbclient.h"
 #include "libsmb_internal.h"
 #include "../librpc/gen_ndr/ndr_lsa.h"
@@ -63,7 +64,7 @@ ace_compare(struct security_ace *ace1,
         bool b2;
 
         /* If the ACEs are equal, we have nothing more to do. */
-        if (sec_ace_equal(ace1, ace2)) {
+        if (security_ace_equal(ace1, ace2)) {
                return 0;
         }
 
@@ -145,17 +146,16 @@ ace_compare(struct security_ace *ace1,
 static void
 sort_acl(struct security_acl *the_acl)
 {
-       uint32 i;
+       uint32_t i;
        if (!the_acl) return;
 
        TYPESAFE_QSORT(the_acl->aces, the_acl->num_aces, ace_compare);
 
        for (i=1;i<the_acl->num_aces;) {
-               if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) {
-                       int j;
-                       for (j=i; j<the_acl->num_aces-1; j++) {
-                               the_acl->aces[j] = the_acl->aces[j+1];
-                       }
+               if (security_ace_equal(&the_acl->aces[i-1],
+                                      &the_acl->aces[i])) {
+                       ARRAY_DEL_ELEMENT(
+                               the_acl->aces, i, the_acl->num_aces);
                        the_acl->num_aces--;
                } else {
                        i++;
@@ -201,9 +201,8 @@ convert_sid_to_string(struct cli_state *ipc_cli,
 
        /* Converted OK */
 
-       slprintf(str, sizeof(fstring) - 1, "%s%s%s",
-                domains[0], lp_winbind_separator(),
-                names[0]);
+       fstr_sprintf(str, "%s%s%s",
+                    domains[0], lp_winbind_separator(), names[0]);
 
        TALLOC_FREE(ctx);
 }
@@ -270,7 +269,7 @@ parse_ace(struct cli_state *ipc_cli,
        const struct perm_value *v;
         struct perm_value {
                 const char perm[7];
-                uint32 mask;
+                uint32_t mask;
         };
        TALLOC_CTX *frame = talloc_stackframe();
 
@@ -302,7 +301,7 @@ parse_ace(struct cli_state *ipc_cli,
        p++;
        /* Try to parse numeric form */
 
-       if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&
+       if (sscanf(p, "%u/%u/%u", &atype, &aflags, &amask) == 3 &&
            convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) {
                goto done;
        }
@@ -320,9 +319,9 @@ parse_ace(struct cli_state *ipc_cli,
                return false;
        }
 
-       if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
+       if (strncasecmp_m(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
                atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
-       } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) {
+       } else if (strncasecmp_m(tok, "DENIED", strlen("DENIED")) == 0) {
                atype = SEC_ACE_TYPE_ACCESS_DENIED;
        } else {
                TALLOC_FREE(frame);
@@ -332,7 +331,7 @@ parse_ace(struct cli_state *ipc_cli,
        /* Only numeric form accepted for flags at present */
 
        if (!(next_token_talloc(frame, &cp, &tok, "/") &&
-             sscanf(tok, "%i", &aflags))) {
+             sscanf(tok, "%u", &aflags))) {
                TALLOC_FREE(frame);
                return false;
        }
@@ -343,14 +342,14 @@ parse_ace(struct cli_state *ipc_cli,
        }
 
        if (strncmp(tok, "0x", 2) == 0) {
-               if (sscanf(tok, "%i", &amask) != 1) {
+               if (sscanf(tok, "%u", &amask) != 1) {
                        TALLOC_FREE(frame);
                        return false;
                }
                goto done;
        }
 
-       for (v = standard_values; v->perm; v++) {
+       for (v = standard_values; v != NULL; v++) {
                if (strcmp(tok, v->perm) == 0) {
                        amask = v->mask;
                        goto done;
@@ -362,7 +361,7 @@ parse_ace(struct cli_state *ipc_cli,
        while(*p) {
                bool found = False;
 
-               for (v = special_values; v->perm; v++) {
+               for (v = special_values; v != NULL; v++) {
                        if (v->perm[0] == *p) {
                                amask |= v->mask;
                                found = True;
@@ -435,12 +434,12 @@ sec_desc_parse(TALLOC_CTX *ctx,
 
        while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) {
 
-               if (StrnCaseCmp(tok,"REVISION:", 9) == 0) {
+               if (strncasecmp_m(tok,"REVISION:", 9) == 0) {
                        revision = strtol(tok+9, NULL, 16);
                        continue;
                }
 
-               if (StrnCaseCmp(tok,"OWNER:", 6) == 0) {
+               if (strncasecmp_m(tok,"OWNER:", 6) == 0) {
                        if (owner_sid) {
                                DEBUG(5,("OWNER specified more than once!\n"));
                                goto done;
@@ -456,7 +455,7 @@ sec_desc_parse(TALLOC_CTX *ctx,
                        continue;
                }
 
-               if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) {
+               if (strncasecmp_m(tok,"OWNER+:", 7) == 0) {
                        if (owner_sid) {
                                DEBUG(5,("OWNER specified more than once!\n"));
                                goto done;
@@ -472,7 +471,7 @@ sec_desc_parse(TALLOC_CTX *ctx,
                        continue;
                }
 
-               if (StrnCaseCmp(tok,"GROUP:", 6) == 0) {
+               if (strncasecmp_m(tok,"GROUP:", 6) == 0) {
                        if (group_sid) {
                                DEBUG(5,("GROUP specified more than once!\n"));
                                goto done;
@@ -488,7 +487,7 @@ sec_desc_parse(TALLOC_CTX *ctx,
                        continue;
                }
 
-               if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) {
+               if (strncasecmp_m(tok,"GROUP+:", 7) == 0) {
                        if (group_sid) {
                                DEBUG(5,("GROUP specified more than once!\n"));
                                goto done;
@@ -504,7 +503,7 @@ sec_desc_parse(TALLOC_CTX *ctx,
                        continue;
                }
 
-               if (StrnCaseCmp(tok,"ACL:", 4) == 0) {
+               if (strncasecmp_m(tok,"ACL:", 4) == 0) {
                        struct security_ace ace;
                        if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) {
                                DEBUG(5, ("Failed to parse ACL %s\n", tok));
@@ -517,7 +516,7 @@ sec_desc_parse(TALLOC_CTX *ctx,
                        continue;
                }
 
-               if (StrnCaseCmp(tok,"ACL+:", 5) == 0) {
+               if (strncasecmp_m(tok,"ACL+:", 5) == 0) {
                        struct security_ace ace;
                        if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) {
                                DEBUG(5, ("Failed to parse ACL %s\n", tok));
@@ -545,47 +544,36 @@ done:
 
 
 /* Obtain the current dos attributes */
-static DOS_ATTR_DESC *
+static struct DOS_ATTR_DESC *
 dos_attr_query(SMBCCTX *context,
                TALLOC_CTX *ctx,
                const char *filename,
                SMBCSRV *srv)
 {
-        struct timespec create_time_ts;
-        struct timespec write_time_ts;
-        struct timespec access_time_ts;
-        struct timespec change_time_ts;
-        SMB_OFF_T size = 0;
-        uint16 mode = 0;
-       SMB_INO_T inode = 0;
-        DOS_ATTR_DESC *ret;
-
-        ret = TALLOC_P(ctx, DOS_ATTR_DESC);
+       struct stat sb = {0};
+        struct DOS_ATTR_DESC *ret = NULL;
+
+        ret = talloc(ctx, struct DOS_ATTR_DESC);
         if (!ret) {
                 errno = ENOMEM;
                 return NULL;
         }
 
         /* Obtain the DOS attributes */
-        if (!SMBC_getatr(context, srv, filename,
-                         &mode, &size,
-                         &create_time_ts,
-                         &access_time_ts,
-                         &write_time_ts,
-                         &change_time_ts,
-                         &inode)) {
+        if (!SMBC_getatr(context, srv, filename, &sb)) {
                 errno = SMBC_errno(context, srv->cli);
                 DEBUG(5, ("dos_attr_query Failed to query old attributes\n"));
+               TALLOC_FREE(ret);
                 return NULL;
         }
 
-        ret->mode = mode;
-        ret->size = size;
-        ret->create_time = convert_timespec_to_time_t(create_time_ts);
-        ret->access_time = convert_timespec_to_time_t(access_time_ts);
-        ret->write_time = convert_timespec_to_time_t(write_time_ts);
-        ret->change_time = convert_timespec_to_time_t(change_time_ts);
-        ret->inode = inode;
+        ret->mode = sb.st_mode;
+        ret->size = sb.st_size;
+        ret->create_time = sb.st_ctime;
+        ret->access_time = sb.st_atime;
+        ret->write_time = sb.st_mtime;
+        ret->change_time = sb.st_mtime;
+        ret->inode = sb.st_ino;
 
         return ret;
 }
@@ -594,7 +582,7 @@ dos_attr_query(SMBCCTX *context,
 /* parse a ascii version of a security descriptor */
 static void
 dos_attr_parse(SMBCCTX *context,
-               DOS_ATTR_DESC *dad,
+               struct DOS_ATTR_DESC *dad,
                SMBCSRV *srv,
                char *str)
 {
@@ -636,7 +624,7 @@ dos_attr_parse(SMBCCTX *context,
 
        frame = talloc_stackframe();
        while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) {
-               if (StrnCaseCmp(tok, "MODE:", 5) == 0) {
+               if (strncasecmp_m(tok, "MODE:", 5) == 0) {
                         long request = strtol(tok+5, NULL, 16);
                         if (request == 0) {
                                 dad->mode = (request |
@@ -649,32 +637,32 @@ dos_attr_parse(SMBCCTX *context,
                        continue;
                }
 
-               if (StrnCaseCmp(tok, "SIZE:", 5) == 0) {
-                        dad->size = (SMB_OFF_T)atof(tok+5);
+               if (strncasecmp_m(tok, "SIZE:", 5) == 0) {
+                        dad->size = (off_t)atof(tok+5);
                        continue;
                }
 
                 n = strlen(attr_strings.access_time_attr);
-                if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) {
+                if (strncasecmp_m(tok, attr_strings.access_time_attr, n) == 0) {
                         dad->access_time = (time_t)strtol(tok+n+1, NULL, 10);
                        continue;
                }
 
                 n = strlen(attr_strings.change_time_attr);
-                if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) {
+                if (strncasecmp_m(tok, attr_strings.change_time_attr, n) == 0) {
                         dad->change_time = (time_t)strtol(tok+n+1, NULL, 10);
                        continue;
                }
 
                 n = strlen(attr_strings.write_time_attr);
-                if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) {
+                if (strncasecmp_m(tok, attr_strings.write_time_attr, n) == 0) {
                         dad->write_time = (time_t)strtol(tok+n+1, NULL, 10);
                        continue;
                }
 
                if (attr_strings.create_time_attr != NULL) {
                        n = strlen(attr_strings.create_time_attr);
-                       if (StrnCaseCmp(tok, attr_strings.create_time_attr,
+                       if (strncasecmp_m(tok, attr_strings.create_time_attr,
                                        n) == 0) {
                                dad->create_time = (time_t)strtol(tok+n+1,
                                                                  NULL, 10);
@@ -682,7 +670,7 @@ dos_attr_parse(SMBCCTX *context,
                        }
                }
 
-               if (StrnCaseCmp(tok, "INODE:", 6) == 0) {
+               if (strncasecmp_m(tok, "INODE:", 6) == 0) {
                         dad->inode = (SMB_INO_T)atof(tok+6);
                        continue;
                }
@@ -705,7 +693,7 @@ cacl_get(SMBCCTX *context,
          char *buf,
          int bufsize)
 {
-       uint32 i;
+       uint32_t i;
         int n = 0;
         int n_used;
         bool all;
@@ -734,17 +722,6 @@ cacl_get(SMBCCTX *context,
         char *name;
         char *pExclude;
         char *p;
-        struct timespec create_time_ts;
-       struct timespec write_time_ts;
-        struct timespec access_time_ts;
-        struct timespec change_time_ts;
-       time_t create_time = (time_t)0;
-       time_t write_time = (time_t)0;
-        time_t access_time = (time_t)0;
-        time_t change_time = (time_t)0;
-       SMB_OFF_T size = 0;
-       uint16 mode = 0;
-       SMB_INO_T ino = 0;
        struct cli_state *cli = srv->cli;
         struct {
                 const char * create_time_attr;
@@ -799,12 +776,12 @@ cacl_get(SMBCCTX *context,
                 *pExclude++ = '\0';
         }
 
-        all = (StrnCaseCmp(name, "system.*", 8) == 0);
-        all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0);
-        all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0);
-        all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0);
-        some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0);
-        some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0);
+        all = (strncasecmp_m(name, "system.*", 8) == 0);
+        all_nt = (strncasecmp_m(name, "system.nt_sec_desc.*", 20) == 0);
+        all_nt_acls = (strncasecmp_m(name, "system.nt_sec_desc.acl.*", 24) == 0);
+        all_dos = (strncasecmp_m(name, "system.dos_attr.*", 17) == 0);
+        some_nt = (strncasecmp_m(name, "system.nt_sec_desc.", 19) == 0);
+        some_dos = (strncasecmp_m(name, "system.dos_attr.", 16) == 0);
         numeric = (* (name + strlen(name) - 1) != '+');
 
         /* Look for exclusions from "all" requests */
@@ -821,48 +798,48 @@ cacl_get(SMBCCTX *context,
                         }
 
                         /* Which exclusion name is this? */
-                        if (StrCaseCmp(pExclude,
+                        if (strcasecmp_m(pExclude,
                                        "nt_sec_desc.revision") == 0) {
                                 exclude_nt_revision = True;
                         }
-                        else if (StrCaseCmp(pExclude,
+                        else if (strcasecmp_m(pExclude,
                                             "nt_sec_desc.owner") == 0) {
                                 exclude_nt_owner = True;
                         }
-                        else if (StrCaseCmp(pExclude,
+                        else if (strcasecmp_m(pExclude,
                                             "nt_sec_desc.group") == 0) {
                                 exclude_nt_group = True;
                         }
-                        else if (StrCaseCmp(pExclude,
+                        else if (strcasecmp_m(pExclude,
                                             "nt_sec_desc.acl") == 0) {
                                 exclude_nt_acl = True;
                         }
-                        else if (StrCaseCmp(pExclude,
+                        else if (strcasecmp_m(pExclude,
                                             "dos_attr.mode") == 0) {
                                 exclude_dos_mode = True;
                         }
-                        else if (StrCaseCmp(pExclude,
+                        else if (strcasecmp_m(pExclude,
                                             "dos_attr.size") == 0) {
                                 exclude_dos_size = True;
                         }
                         else if (excl_attr_strings.create_time_attr != NULL &&
-                                 StrCaseCmp(pExclude,
+                                 strcasecmp_m(pExclude,
                                             excl_attr_strings.change_time_attr) == 0) {
                                 exclude_dos_create_time = True;
                         }
-                        else if (StrCaseCmp(pExclude,
+                        else if (strcasecmp_m(pExclude,
                                             excl_attr_strings.access_time_attr) == 0) {
                                 exclude_dos_access_time = True;
                         }
-                        else if (StrCaseCmp(pExclude,
+                        else if (strcasecmp_m(pExclude,
                                             excl_attr_strings.write_time_attr) == 0) {
                                 exclude_dos_write_time = True;
                         }
-                        else if (StrCaseCmp(pExclude,
+                        else if (strcasecmp_m(pExclude,
                                             excl_attr_strings.change_time_attr) == 0) {
                                 exclude_dos_change_time = True;
                         }
-                        else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) {
+                        else if (strcasecmp_m(pExclude, "dos_attr.inode") == 0) {
                                 exclude_dos_inode = True;
                         }
                         else {
@@ -883,13 +860,15 @@ cacl_get(SMBCCTX *context,
         if (ipc_cli && (all || some_nt || all_nt_acls)) {
                char *targetpath = NULL;
                struct cli_state *targetcli = NULL;
+               NTSTATUS status;
 
                 /* Point to the portion after "system.nt_sec_desc." */
                 name += 19;     /* if (all) this will be invalid but unused */
 
-               if (!cli_resolve_path(ctx, "", context->internal->auth_info,
-                               cli, filename,
-                               &targetcli, &targetpath)) {
+               status = cli_resolve_path(
+                       ctx, "", context->internal->auth_info,
+                       cli, filename, &targetcli, &targetpath);
+               if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(5, ("cacl_get Could not resolve %s\n",
                                filename));
                         errno = ENOENT;
@@ -897,22 +876,25 @@ cacl_get(SMBCCTX *context,
                }
 
                 /* ... then obtain any NT attributes which were requested */
-                if (!NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetpath, 0, CREATE_ACCESS_READ, 0,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
+               status = cli_ntcreate(targetcli, targetpath, 0,
+                                     CREATE_ACCESS_READ, 0,
+                                     FILE_SHARE_READ|FILE_SHARE_WRITE,
+                                     FILE_OPEN, 0x0, 0x0, &fnum, NULL);
+               if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(5, ("cacl_get failed to open %s: %s\n",
-                               targetpath, cli_errstr(targetcli)));
+                                 targetpath, nt_errstr(status)));
                        errno = 0;
                        return -1;
                }
 
-               sd = cli_query_secdesc(targetcli, fnum, ctx);
-
-                if (!sd) {
-                        DEBUG(5,
-                              ("cacl_get Failed to query old descriptor\n"));
-                        errno = 0;
-                        return -1;
-                }
+               status = cli_query_secdesc(targetcli, fnum, ctx, &sd);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(5,("cacl_get Failed to query old descriptor "
+                                "of %s: %s\n",
+                                 targetpath, nt_errstr(status)));
+                       errno = 0;
+                       return -1;
+               }
 
                 cli_close(targetcli, fnum);
 
@@ -932,7 +914,7 @@ cacl_get(SMBCCTX *context,
                                                      "REVISION:%d",
                                                      sd->revision);
                                 }
-                        } else if (StrCaseCmp(name, "revision") == 0) {
+                        } else if (strcasecmp_m(name, "revision") == 0) {
                                 if (determine_size) {
                                         p = talloc_asprintf(ctx, "%d",
                                                             sd->revision);
@@ -981,7 +963,7 @@ cacl_get(SMBCCTX *context,
                                         n = snprintf(buf, bufsize,
                                                      ",OWNER:%s", sidstr);
                                 }
-                        } else if (StrnCaseCmp(name, "owner", 5) == 0) {
+                        } else if (strncasecmp_m(name, "owner", 5) == 0) {
                                 if (determine_size) {
                                         p = talloc_asprintf(ctx, "%s", sidstr);
                                         if (!p) {
@@ -1027,7 +1009,7 @@ cacl_get(SMBCCTX *context,
                                         n = snprintf(buf, bufsize,
                                                      ",GROUP:%s", sidstr);
                                 }
-                        } else if (StrnCaseCmp(name, "group", 5) == 0) {
+                        } else if (strncasecmp_m(name, "group", 5) == 0) {
                                 if (determine_size) {
                                         p = talloc_asprintf(ctx, "%s", sidstr);
                                         if (!p) {
@@ -1084,10 +1066,10 @@ cacl_get(SMBCCTX *context,
                                                         ace->flags,
                                                         ace->access_mask);
                                         }
-                                } else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
-                                            StrCaseCmp(name+3, sidstr) == 0) ||
-                                           (StrnCaseCmp(name, "acl+", 4) == 0 &&
-                                            StrCaseCmp(name+4, sidstr) == 0)) {
+                                } else if ((strncasecmp_m(name, "acl", 3) == 0 &&
+                                            strcasecmp_m(name+3, sidstr) == 0) ||
+                                           (strncasecmp_m(name, "acl+", 4) == 0 &&
+                                            strcasecmp_m(name+4, sidstr) == 0)) {
                                         if (determine_size) {
                                                 p = talloc_asprintf(
                                                         ctx, 
@@ -1148,25 +1130,31 @@ cacl_get(SMBCCTX *context,
         }
 
         if (all || some_dos) {
+               struct stat sb = {0};
+               time_t create_time = (time_t)0;
+               time_t write_time = (time_t)0;
+               time_t access_time = (time_t)0;
+               time_t change_time = (time_t)0;
+               off_t size = 0;
+               uint16_t mode = 0;
+               SMB_INO_T ino = 0;
+
                 /* Point to the portion after "system.dos_attr." */
                 name += 16;     /* if (all) this will be invalid but unused */
 
                 /* Obtain the DOS attributes */
-                if (!SMBC_getatr(context, srv, filename, &mode, &size, 
-                                 &create_time_ts,
-                                 &access_time_ts,
-                                 &write_time_ts,
-                                 &change_time_ts,
-                                 &ino)) {
-
+                if (!SMBC_getatr(context, srv, filename, &sb)) {
                         errno = SMBC_errno(context, srv->cli);
                         return -1;
                 }
 
-                create_time = convert_timespec_to_time_t(create_time_ts);
-                access_time = convert_timespec_to_time_t(access_time_ts);
-                write_time = convert_timespec_to_time_t(write_time_ts);
-                change_time = convert_timespec_to_time_t(change_time_ts);
+               create_time = sb.st_ctime;
+               access_time = sb.st_atime;
+               write_time  = sb.st_mtime;
+               change_time = sb.st_mtime;
+               size        = sb.st_size;
+               mode        = sb.st_mode;
+               ino         = sb.st_ino;
 
                 if (! exclude_dos_mode) {
                         if (all || all_dos) {
@@ -1192,7 +1180,7 @@ cacl_get(SMBCCTX *context,
                                                       : ""),
                                                      mode);
                                 }
-                        } else if (StrCaseCmp(name, "mode") == 0) {
+                        } else if (strcasecmp_m(name, "mode") == 0) {
                                 if (determine_size) {
                                         p = talloc_asprintf(ctx, "0x%x", mode);
                                         if (!p) {
@@ -1233,7 +1221,7 @@ cacl_get(SMBCCTX *context,
                                                      ",SIZE:%.0f",
                                                      (double)size);
                                 }
-                        } else if (StrCaseCmp(name, "size") == 0) {
+                        } else if (strcasecmp_m(name, "size") == 0) {
                                 if (determine_size) {
                                         p = talloc_asprintf(
                                                 ctx,
@@ -1280,7 +1268,7 @@ cacl_get(SMBCCTX *context,
                                                      attr_strings.create_time_attr,
                                                      (unsigned long) create_time);
                                 }
-                        } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) {
+                        } else if (strcasecmp_m(name, attr_strings.create_time_attr) == 0) {
                                 if (determine_size) {
                                         p = talloc_asprintf(ctx, "%lu", (unsigned long) create_time);
                                         if (!p) {
@@ -1322,7 +1310,7 @@ cacl_get(SMBCCTX *context,
                                                      attr_strings.access_time_attr,
                                                      (unsigned long) access_time);
                                 }
-                        } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) {
+                        } else if (strcasecmp_m(name, attr_strings.access_time_attr) == 0) {
                                 if (determine_size) {
                                         p = talloc_asprintf(ctx, "%lu", (unsigned long) access_time);
                                         if (!p) {
@@ -1364,7 +1352,7 @@ cacl_get(SMBCCTX *context,
                                                      attr_strings.write_time_attr,
                                                      (unsigned long) write_time);
                                 }
-                        } else if (StrCaseCmp(name, attr_strings.write_time_attr) == 0) {
+                        } else if (strcasecmp_m(name, attr_strings.write_time_attr) == 0) {
                                 if (determine_size) {
                                         p = talloc_asprintf(ctx, "%lu", (unsigned long) write_time);
                                         if (!p) {
@@ -1406,7 +1394,7 @@ cacl_get(SMBCCTX *context,
                                                      attr_strings.change_time_attr,
                                                      (unsigned long) change_time);
                                 }
-                        } else if (StrCaseCmp(name, attr_strings.change_time_attr) == 0) {
+                        } else if (strcasecmp_m(name, attr_strings.change_time_attr) == 0) {
                                 if (determine_size) {
                                         p = talloc_asprintf(ctx, "%lu", (unsigned long) change_time);
                                         if (!p) {
@@ -1447,7 +1435,7 @@ cacl_get(SMBCCTX *context,
                                                      ",INODE:%.0f",
                                                      (double) ino);
                                 }
-                        } else if (StrCaseCmp(name, "inode") == 0) {
+                        } else if (strcasecmp_m(name, "inode") == 0) {
                                 if (determine_size) {
                                         p = talloc_asprintf(
                                                 ctx,
@@ -1507,7 +1495,7 @@ cacl_set(SMBCCTX *context,
         struct security_acl *dacl = NULL;
        struct dom_sid *owner_sid = NULL;
        struct dom_sid *group_sid = NULL;
-       uint32 i, j;
+       uint32_t i, j;
        size_t sd_size;
        int ret = 0;
         char *p;
@@ -1543,9 +1531,9 @@ cacl_set(SMBCCTX *context,
                return -1;
        }
 
-       if (!cli_resolve_path(ctx, "", context->internal->auth_info,
-                       cli, filename,
-                       &targetcli, &targetpath)) {
+       status = cli_resolve_path(ctx, "", context->internal->auth_info,
+                                 cli, filename, &targetcli, &targetpath);
+       if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("cacl_set: Could not resolve %s\n", filename));
                errno = ENOENT;
                return -1;
@@ -1554,19 +1542,21 @@ cacl_set(SMBCCTX *context,
        /* The desired access below is the only one I could find that works
           with NT4, W2KP and Samba */
 
-       if (!NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetpath, 0, CREATE_ACCESS_READ, 0,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
+       status = cli_ntcreate(targetcli, targetpath, 0, CREATE_ACCESS_READ, 0,
+                             FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN,
+                             0x0, 0x0, &fnum, NULL);
+       if (!NT_STATUS_IS_OK(status)) {
                 DEBUG(5, ("cacl_set failed to open %s: %s\n",
-                          targetpath, cli_errstr(targetcli)));
+                          targetpath, nt_errstr(status)));
                 errno = 0;
                return -1;
        }
 
-       old = cli_query_secdesc(targetcli, fnum, ctx);
-
-       if (!old) {
-                DEBUG(5, ("cacl_set Failed to query old descriptor\n"));
-                errno = 0;
+       status = cli_query_secdesc(targetcli, fnum, ctx, &old);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(5,("cacl_set Failed to query old descriptor of %s: %s\n",
+                        targetpath, nt_errstr(status)));
+               errno = 0;
                return -1;
        }
 
@@ -1583,9 +1573,9 @@ cacl_set(SMBCCTX *context,
                        bool found = False;
 
                        for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
-                                if (sec_ace_equal(&sd->dacl->aces[i],
-                                                  &old->dacl->aces[j])) {
-                                       uint32 k;
+                                if (security_ace_equal(&sd->dacl->aces[i],
+                                                      &old->dacl->aces[j])) {
+                                       uint32_t k;
                                        for (k=j; k<old->dacl->num_aces-1;k++) {
                                                old->dacl->aces[k] =
                                                         old->dacl->aces[k+1];
@@ -1659,11 +1649,13 @@ cacl_set(SMBCCTX *context,
        sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE,
                           owner_sid, group_sid, NULL, dacl, &sd_size);
 
-       if (!NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetpath, 0,
-                             WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS, 0,
-                            FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
+       status = cli_ntcreate(targetcli, targetpath, 0,
+                             WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS, 0,
+                             FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN,
+                             0x0, 0x0, &fnum, NULL);
+       if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5, ("cacl_set failed to open %s: %s\n",
-                          targetpath, cli_errstr(targetcli)));
+                          targetpath, nt_errstr(status)));
                 errno = 0;
                return -1;
        }
@@ -1706,13 +1698,14 @@ SMBC_setxattr_ctx(SMBCCTX *context,
        char *password = NULL;
        char *workgroup = NULL;
        char *path = NULL;
-        DOS_ATTR_DESC *dad = NULL;
+        struct DOS_ATTR_DESC *dad = NULL;
         struct {
                 const char * create_time_attr;
                 const char * access_time_attr;
                 const char * write_time_attr;
                 const char * change_time_attr;
         } attr_strings;
+       uint16_t port = 0;
         TALLOC_CTX *frame = talloc_stackframe();
 
        if (!context || !context->internal->initialized) {
@@ -1735,6 +1728,7 @@ SMBC_setxattr_ctx(SMBCCTX *context,
                             fname,
                             &workgroup,
                             &server,
+                            &port,
                             &share,
                             &path,
                             &user,
@@ -1755,14 +1749,14 @@ SMBC_setxattr_ctx(SMBCCTX *context,
        }
 
        srv = SMBC_server(frame, context, True,
-                          server, share, &workgroup, &user, &password);
+                          server, port, share, &workgroup, &user, &password);
        if (!srv) {
                TALLOC_FREE(frame);
                return -1;  /* errno set by SMBC_server */
        }
 
         if (! srv->no_nt_session) {
-                ipc_srv = SMBC_attr_server(frame, context, server, share,
+                ipc_srv = SMBC_attr_server(frame, context, server, port, share,
                                            &workgroup, &user, &password);
                 if (! ipc_srv) {
                         srv->no_nt_session = True;
@@ -1774,8 +1768,8 @@ SMBC_setxattr_ctx(SMBCCTX *context,
         /*
          * Are they asking to set the entire set of known attributes?
          */
-        if (StrCaseCmp(name, "system.*") == 0 ||
-            StrCaseCmp(name, "system.*+") == 0) {
+        if (strcasecmp_m(name, "system.*") == 0 ||
+            strcasecmp_m(name, "system.*+") == 0) {
                 /* Yup. */
                 char *namevalue =
                         talloc_asprintf(talloc_tos(), "%s:%s",
@@ -1802,17 +1796,26 @@ SMBC_setxattr_ctx(SMBCCTX *context,
                 /* get a DOS Attribute Descriptor with current attributes */
                 dad = dos_attr_query(context, talloc_tos(), path, srv);
                 if (dad) {
+                       bool ok;
+
                         /* Overwrite old with new, using what was provided */
                         dos_attr_parse(context, dad, srv, namevalue);
 
                         /* Set the new DOS attributes */
-                        if (! SMBC_setatr(context, srv, path,
-                                          dad->create_time,
-                                          dad->access_time,
-                                          dad->write_time,
-                                          dad->change_time,
-                                          dad->mode)) {
-
+                       ok = SMBC_setatr(
+                               context,
+                               srv,
+                               path,
+                               (struct timespec) {
+                                       .tv_sec = dad->create_time },
+                               (struct timespec) {
+                                       .tv_sec = dad->access_time },
+                               (struct timespec) {
+                                       .tv_sec = dad->write_time },
+                               (struct timespec) {
+                                       .tv_sec = dad->change_time },
+                               dad->mode);
+                       if (!ok) {
                                 /* cause failure if NT failed too */
                                 dad = NULL; 
                         }
@@ -1834,11 +1837,11 @@ SMBC_setxattr_ctx(SMBCCTX *context,
          * Are they asking to set an access control element or to set
          * the entire access control list?
          */
-        if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
-            StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
-            StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
+        if (strcasecmp_m(name, "system.nt_sec_desc.*") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.*+") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.revision") == 0 ||
+            strncasecmp_m(name, "system.nt_sec_desc.acl", 22) == 0 ||
+            strncasecmp_m(name, "system.nt_sec_desc.acl+", 23) == 0) {
 
                 /* Yup. */
                 char *namevalue =
@@ -1867,8 +1870,8 @@ SMBC_setxattr_ctx(SMBCCTX *context,
         /*
          * Are they asking to set the owner?
          */
-        if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) {
+        if (strcasecmp_m(name, "system.nt_sec_desc.owner") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.owner+") == 0) {
 
                 /* Yup. */
                 char *namevalue =
@@ -1893,8 +1896,8 @@ SMBC_setxattr_ctx(SMBCCTX *context,
         /*
          * Are they asking to set the group?
          */
-        if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) {
+        if (strcasecmp_m(name, "system.nt_sec_desc.group") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.group+") == 0) {
 
                 /* Yup. */
                 char *namevalue =
@@ -1935,13 +1938,13 @@ SMBC_setxattr_ctx(SMBCCTX *context,
         /*
          * Are they asking to set a DOS attribute?
          */
-        if (StrCaseCmp(name, "system.dos_attr.*") == 0 ||
-            StrCaseCmp(name, "system.dos_attr.mode") == 0 ||
+        if (strcasecmp_m(name, "system.dos_attr.*") == 0 ||
+            strcasecmp_m(name, "system.dos_attr.mode") == 0 ||
             (attr_strings.create_time_attr != NULL &&
-             StrCaseCmp(name, attr_strings.create_time_attr) == 0) ||
-            StrCaseCmp(name, attr_strings.access_time_attr) == 0 ||
-            StrCaseCmp(name, attr_strings.write_time_attr) == 0 ||
-            StrCaseCmp(name, attr_strings.change_time_attr) == 0) {
+             strcasecmp_m(name, attr_strings.create_time_attr) == 0) ||
+            strcasecmp_m(name, attr_strings.access_time_attr) == 0 ||
+            strcasecmp_m(name, attr_strings.write_time_attr) == 0 ||
+            strcasecmp_m(name, attr_strings.change_time_attr) == 0) {
 
                 /* get a DOS Attribute Descriptor with current attributes */
                 dad = dos_attr_query(context, talloc_tos(), path, srv);
@@ -1957,12 +1960,19 @@ SMBC_setxattr_ctx(SMBCCTX *context,
                                 dos_attr_parse(context, dad, srv, namevalue);
 
                                 /* Set the new DOS attributes */
-                                ret2 = SMBC_setatr(context, srv, path,
-                                                   dad->create_time,
-                                                   dad->access_time,
-                                                   dad->write_time,
-                                                   dad->change_time,
-                                                   dad->mode);
+                               ret2 = SMBC_setatr(
+                                       context,
+                                       srv,
+                                       path,
+                                       (struct timespec) {
+                                               .tv_sec = dad->create_time },
+                                       (struct timespec) {
+                                               .tv_sec = dad->access_time },
+                                       (struct timespec) {
+                                               .tv_sec = dad->write_time },
+                                       (struct timespec) {
+                                               .tv_sec = dad->change_time },
+                                       dad->mode);
 
                                 /* ret2 has True (success) / False (failure) */
                                 if (ret2) {
@@ -2007,6 +2017,7 @@ SMBC_getxattr_ctx(SMBCCTX *context,
                 const char * write_time_attr;
                 const char * change_time_attr;
         } attr_strings;
+       uint16_t port = 0;
        TALLOC_CTX *frame = talloc_stackframe();
 
        if (!context || !context->internal->initialized) {
@@ -2028,6 +2039,7 @@ SMBC_getxattr_ctx(SMBCCTX *context,
                             fname,
                             &workgroup,
                             &server,
+                            &port,
                             &share,
                             &path,
                             &user,
@@ -2048,15 +2060,34 @@ SMBC_getxattr_ctx(SMBCCTX *context,
        }
 
         srv = SMBC_server(frame, context, True,
-                          server, share, &workgroup, &user, &password);
+                          server, port, share, &workgroup, &user, &password);
         if (!srv) {
                TALLOC_FREE(frame);
                 return -1;  /* errno set by SMBC_server */
         }
 
         if (! srv->no_nt_session) {
-                ipc_srv = SMBC_attr_server(frame, context, server, share,
+                ipc_srv = SMBC_attr_server(frame, context, server, port, share,
                                            &workgroup, &user, &password);
+               /*
+                * SMBC_attr_server() can cause the original
+                * server to be removed from the cache.
+                * If so we must error out here as the srv
+                * pointer has been freed.
+                */
+               if (smbc_getFunctionGetCachedServer(context)(context,
+                               server,
+                               share,
+                               workgroup,
+                               user) != srv) {
+#if defined(ECONNRESET)
+                       errno = ECONNRESET;
+#else
+                       errno = ETIMEDOUT;
+#endif
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
                 if (! ipc_srv) {
                         srv->no_nt_session = True;
                 }
@@ -2080,31 +2111,31 @@ SMBC_getxattr_ctx(SMBCCTX *context,
         }
 
         /* Are they requesting a supported attribute? */
-        if (StrCaseCmp(name, "system.*") == 0 ||
-            StrnCaseCmp(name, "system.*!", 9) == 0 ||
-            StrCaseCmp(name, "system.*+") == 0 ||
-            StrnCaseCmp(name, "system.*+!", 10) == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
-            StrnCaseCmp(name, "system.nt_sec_desc.*!", 21) == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 ||
-            StrnCaseCmp(name, "system.nt_sec_desc.*+!", 22) == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 ||
-            StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
-            StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 ||
-            StrCaseCmp(name, "system.dos_attr.*") == 0 ||
-            StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 ||
-            StrCaseCmp(name, "system.dos_attr.mode") == 0 ||
-            StrCaseCmp(name, "system.dos_attr.size") == 0 ||
+        if (strcasecmp_m(name, "system.*") == 0 ||
+            strncasecmp_m(name, "system.*!", 9) == 0 ||
+            strcasecmp_m(name, "system.*+") == 0 ||
+            strncasecmp_m(name, "system.*+!", 10) == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.*") == 0 ||
+            strncasecmp_m(name, "system.nt_sec_desc.*!", 21) == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.*+") == 0 ||
+            strncasecmp_m(name, "system.nt_sec_desc.*+!", 22) == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.revision") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.owner") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.owner+") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.group") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.group+") == 0 ||
+            strncasecmp_m(name, "system.nt_sec_desc.acl", 22) == 0 ||
+            strncasecmp_m(name, "system.nt_sec_desc.acl+", 23) == 0 ||
+            strcasecmp_m(name, "system.dos_attr.*") == 0 ||
+            strncasecmp_m(name, "system.dos_attr.*!", 18) == 0 ||
+            strcasecmp_m(name, "system.dos_attr.mode") == 0 ||
+            strcasecmp_m(name, "system.dos_attr.size") == 0 ||
             (attr_strings.create_time_attr != NULL &&
-             StrCaseCmp(name, attr_strings.create_time_attr) == 0) ||
-            StrCaseCmp(name, attr_strings.access_time_attr) == 0 ||
-            StrCaseCmp(name, attr_strings.write_time_attr) == 0 ||
-            StrCaseCmp(name, attr_strings.change_time_attr) == 0 ||
-            StrCaseCmp(name, "system.dos_attr.inode") == 0) {
+             strcasecmp_m(name, attr_strings.create_time_attr) == 0) ||
+            strcasecmp_m(name, attr_strings.access_time_attr) == 0 ||
+            strcasecmp_m(name, attr_strings.write_time_attr) == 0 ||
+            strcasecmp_m(name, attr_strings.change_time_attr) == 0 ||
+            strcasecmp_m(name, "system.dos_attr.inode") == 0) {
 
                 /* Yup. */
                 const char *filename = name;
@@ -2142,6 +2173,7 @@ SMBC_removexattr_ctx(SMBCCTX *context,
        char *password = NULL;
        char *workgroup = NULL;
        char *path = NULL;
+       uint16_t port = 0;
        TALLOC_CTX *frame = talloc_stackframe();
 
        if (!context || !context->internal->initialized) {
@@ -2163,6 +2195,7 @@ SMBC_removexattr_ctx(SMBCCTX *context,
                             fname,
                             &workgroup,
                             &server,
+                            &port,
                             &share,
                             &path,
                             &user,
@@ -2183,16 +2216,38 @@ SMBC_removexattr_ctx(SMBCCTX *context,
        }
 
         srv = SMBC_server(frame, context, True,
-                          server, share, &workgroup, &user, &password);
+                          server, port, share, &workgroup, &user, &password);
         if (!srv) {
                TALLOC_FREE(frame);
                 return -1;  /* errno set by SMBC_server */
         }
 
         if (! srv->no_nt_session) {
-                ipc_srv = SMBC_attr_server(frame, context, server, share,
+               int saved_errno;
+                ipc_srv = SMBC_attr_server(frame, context, server, port, share,
                                            &workgroup, &user, &password);
+               saved_errno = errno;
+               /*
+                * SMBC_attr_server() can cause the original
+                * server to be removed from the cache.
+                * If so we must error out here as the srv
+                * pointer has been freed.
+                */
+               if (smbc_getFunctionGetCachedServer(context)(context,
+                               server,
+                               share,
+                               workgroup,
+                               user) != srv) {
+#if defined(ECONNRESET)
+                       errno = ECONNRESET;
+#else
+                       errno = ETIMEDOUT;
+#endif
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
                 if (! ipc_srv) {
+                       errno = saved_errno;
                         srv->no_nt_session = True;
                 }
         } else {
@@ -2205,8 +2260,8 @@ SMBC_removexattr_ctx(SMBCCTX *context,
         }
 
         /* Are they asking to set the entire ACL? */
-        if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) {
+        if (strcasecmp_m(name, "system.nt_sec_desc.*") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.*+") == 0) {
 
                 /* Yup. */
                 ret = cacl_set(context, talloc_tos(), srv->cli,
@@ -2220,13 +2275,13 @@ SMBC_removexattr_ctx(SMBCCTX *context,
          * Are they asking to remove one or more spceific security descriptor
          * attributes?
          */
-        if (StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
-            StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 ||
-            StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
-            StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
+        if (strcasecmp_m(name, "system.nt_sec_desc.revision") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.owner") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.owner+") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.group") == 0 ||
+            strcasecmp_m(name, "system.nt_sec_desc.group+") == 0 ||
+            strncasecmp_m(name, "system.nt_sec_desc.acl", 22) == 0 ||
+            strncasecmp_m(name, "system.nt_sec_desc.acl+", 23) == 0) {
 
                 /* Yup. */
                 ret = cacl_set(context, talloc_tos(), srv->cli,