fss: add generic UNC parser
authorDavid Disseldorp <ddiss@samba.org>
Sun, 28 Apr 2013 13:20:28 +0000 (15:20 +0200)
committerDavid Disseldorp <ddiss@samba.org>
Wed, 8 May 2013 10:21:37 +0000 (12:21 +0200)
diskshadow.exe sends UNC paths with a trailing '\'.

source3/rpc_server/fss/srv_fss_agent.c

index 6f3038b5eff62e9aeccb44a1772af05626a904cb..78628f9bb9ca50614f25b3d5f1f3bd8d62fbf801 100644 (file)
@@ -69,6 +69,54 @@ static uint32_t fss_ntstatus_map(NTSTATUS status)
        return E_OUTOFMEMORY;   /* FIXME */
 }
 
+static NTSTATUS fss_unc_parse(TALLOC_CTX *mem_ctx,
+                             const char *unc,
+                             char **_server,
+                             char **_share)
+{
+       char *s;
+       char *server;
+       char *share;
+
+       if (unc == NULL) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       s = strstr(unc, "\\\\");
+       if (s == NULL) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       server = talloc_strdup(mem_ctx, s + 2);
+       if (server == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       s = strchr(server, '\\');
+       if ((s == NULL) || (s == server)) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+       *s = '\0';
+       share = s + 1;
+
+       s = strchr(share, '\\');
+       if (s != NULL) {
+               /* diskshadow.exe adds a trailing '\' to the share-name */
+               *s = '\0';
+       }
+       if (strlen(share) == 0) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (_server != NULL) {
+               *_server = server;
+       }
+       if (_share != NULL) {
+               *_share = share;
+       }
+
+       return NT_STATUS_OK;
+}
+
 static NTSTATUS fss_vfs_conn_create(TALLOC_CTX *mem_ctx,
                                    struct tevent_context *ev,
                                    struct messaging_context *msg_ctx,
@@ -432,10 +480,10 @@ uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
                return E_INVALIDARG;
        }
 
-       share = strrchr(r->in.ShareName, '\\');
-       if (share++ == NULL) {
+       status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
+       if (!NT_STATUS_IS_OK(status)) {
                talloc_free(tmp_ctx);
-               return E_INVALIDARG;
+               return fss_ntstatus_map(status);
        }
 
        snum = find_service(tmp_ctx, share, &service);
@@ -1110,10 +1158,10 @@ uint32_t _fss_IsPathSupported(struct pipes_struct *p,
                return E_ACCESSDENIED;
        }
 
-       share = strrchr(r->in.ShareName, '\\');
-       if (share++ == NULL) {
+       status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
+       if (!NT_STATUS_IS_OK(status)) {
                talloc_free(tmp_ctx);
-               return E_INVALIDARG;
+               return fss_ntstatus_map(status);
        }
 
        snum = find_service(tmp_ctx, share, &service);