2 * CAP VFS module for Samba 3.x Version 0.3
4 * Copyright (C) Tim Potter, 1999-2000
5 * Copyright (C) Alexander Bokovoy, 2002-2003
6 * Copyright (C) Stefan (metze) Metzmacher, 2003
7 * Copyright (C) TAKAHASHI Motonobu (monyo), 2003
8 * Copyright (C) Jeremy Allison, 2007
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 #include "smbd/smbd.h"
29 static char *capencode(TALLOC_CTX
*ctx
, const char *from
);
30 static char *capdecode(TALLOC_CTX
*ctx
, const char *from
);
32 static uint64_t cap_disk_free(vfs_handle_struct
*handle
,
33 const struct smb_filename
*smb_fname
,
38 char *capname
= capencode(talloc_tos(), smb_fname
->base_name
);
39 struct smb_filename
*cap_smb_fname
= NULL
;
45 cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
51 if (cap_smb_fname
== NULL
) {
56 return SMB_VFS_NEXT_DISK_FREE(handle
, cap_smb_fname
,
60 static int cap_get_quota(vfs_handle_struct
*handle
,
61 const struct smb_filename
*smb_fname
,
62 enum SMB_QUOTA_TYPE qtype
,
66 char *cappath
= capencode(talloc_tos(), smb_fname
->base_name
);
67 struct smb_filename
*cap_smb_fname
= NULL
;
73 cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
79 if (cap_smb_fname
== NULL
) {
84 return SMB_VFS_NEXT_GET_QUOTA(handle
, cap_smb_fname
, qtype
, id
, dq
);
87 static struct dirent
*cap_readdir(vfs_handle_struct
*handle
,
88 struct files_struct
*dirfsp
,
90 SMB_STRUCT_STAT
*sbuf
)
92 struct dirent
*result
;
93 struct dirent
*newdirent
;
96 DEBUG(3,("cap: cap_readdir\n"));
98 result
= SMB_VFS_NEXT_READDIR(handle
, dirfsp
, dirp
, NULL
);
103 newname
= capdecode(talloc_tos(), result
->d_name
);
107 DEBUG(3,("cap: cap_readdir: %s\n", newname
));
108 newnamelen
= strlen(newname
)+1;
109 newdirent
= talloc_size(
110 talloc_tos(), sizeof(struct dirent
) + newnamelen
);
114 talloc_set_name_const(newdirent
, "struct dirent");
115 memcpy(newdirent
, result
, sizeof(struct dirent
));
116 memcpy(&newdirent
->d_name
, newname
, newnamelen
);
120 static int cap_mkdirat(vfs_handle_struct
*handle
,
121 struct files_struct
*dirfsp
,
122 const struct smb_filename
*smb_fname
,
125 char *cappath
= capencode(talloc_tos(), smb_fname
->base_name
);
126 struct smb_filename
*cap_smb_fname
= NULL
;
133 cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
139 if (cap_smb_fname
== NULL
) {
140 TALLOC_FREE(cappath
);
145 return SMB_VFS_NEXT_MKDIRAT(handle
,
151 static int cap_openat(vfs_handle_struct
*handle
,
152 const struct files_struct
*dirfsp
,
153 const struct smb_filename
*smb_fname_in
,
158 char *cappath
= NULL
;
159 struct smb_filename
*smb_fname
= NULL
;
163 cappath
= capencode(talloc_tos(), smb_fname_in
->base_name
);
164 if (cappath
== NULL
) {
169 smb_fname
= cp_smb_filename(talloc_tos(), smb_fname_in
);
170 if (smb_fname
== NULL
) {
171 TALLOC_FREE(cappath
);
175 smb_fname
->base_name
= cappath
;
177 DBG_DEBUG("cap_open for %s\n", smb_fname_str_dbg(smb_fname
));
178 ret
= SMB_VFS_NEXT_OPENAT(handle
,
188 TALLOC_FREE(cappath
);
189 TALLOC_FREE(smb_fname
);
190 if (saved_errno
!= 0) {
196 static int cap_renameat(vfs_handle_struct
*handle
,
197 files_struct
*srcfsp
,
198 const struct smb_filename
*smb_fname_src
,
199 files_struct
*dstfsp
,
200 const struct smb_filename
*smb_fname_dst
)
204 struct smb_filename
*smb_fname_src_tmp
= NULL
;
205 struct smb_filename
*smb_fname_dst_tmp
= NULL
;
206 struct smb_filename
*full_fname_src
= NULL
;
207 struct smb_filename
*full_fname_dst
= NULL
;
211 full_fname_src
= full_path_from_dirfsp_atname(talloc_tos(),
214 if (full_fname_src
== NULL
) {
219 full_fname_dst
= full_path_from_dirfsp_atname(talloc_tos(),
222 if (full_fname_dst
== NULL
) {
227 capold
= capencode(talloc_tos(), full_fname_src
->base_name
);
228 capnew
= capencode(talloc_tos(), full_fname_dst
->base_name
);
229 if (!capold
|| !capnew
) {
234 /* Setup temporary smb_filename structs. */
235 smb_fname_src_tmp
= cp_smb_filename(talloc_tos(), full_fname_src
);
236 if (smb_fname_src_tmp
== NULL
) {
240 smb_fname_dst_tmp
= cp_smb_filename(talloc_tos(), full_fname_dst
);
241 if (smb_fname_dst_tmp
== NULL
) {
246 smb_fname_src_tmp
->base_name
= capold
;
247 smb_fname_dst_tmp
->base_name
= capnew
;
249 ret
= SMB_VFS_NEXT_RENAMEAT(handle
,
250 srcfsp
->conn
->cwd_fsp
,
252 dstfsp
->conn
->cwd_fsp
,
261 TALLOC_FREE(full_fname_src
);
262 TALLOC_FREE(full_fname_dst
);
265 TALLOC_FREE(smb_fname_src_tmp
);
266 TALLOC_FREE(smb_fname_dst_tmp
);
275 static int cap_stat(vfs_handle_struct
*handle
, struct smb_filename
*smb_fname
)
278 char *tmp_base_name
= NULL
;
281 cappath
= capencode(talloc_tos(), smb_fname
->base_name
);
288 tmp_base_name
= smb_fname
->base_name
;
289 smb_fname
->base_name
= cappath
;
291 ret
= SMB_VFS_NEXT_STAT(handle
, smb_fname
);
293 smb_fname
->base_name
= tmp_base_name
;
294 TALLOC_FREE(cappath
);
299 static int cap_lstat(vfs_handle_struct
*handle
, struct smb_filename
*smb_fname
)
302 char *tmp_base_name
= NULL
;
305 cappath
= capencode(talloc_tos(), smb_fname
->base_name
);
312 tmp_base_name
= smb_fname
->base_name
;
313 smb_fname
->base_name
= cappath
;
315 ret
= SMB_VFS_NEXT_LSTAT(handle
, smb_fname
);
317 smb_fname
->base_name
= tmp_base_name
;
318 TALLOC_FREE(cappath
);
323 static int cap_unlinkat(vfs_handle_struct
*handle
,
324 struct files_struct
*dirfsp
,
325 const struct smb_filename
*smb_fname
,
328 struct smb_filename
*full_fname
= NULL
;
329 struct smb_filename
*smb_fname_tmp
= NULL
;
330 char *cappath
= NULL
;
333 full_fname
= full_path_from_dirfsp_atname(talloc_tos(),
336 if (full_fname
== NULL
) {
340 cappath
= capencode(talloc_tos(), full_fname
->base_name
);
342 TALLOC_FREE(full_fname
);
347 /* Setup temporary smb_filename structs. */
348 smb_fname_tmp
= cp_smb_filename(talloc_tos(), full_fname
);
349 TALLOC_FREE(full_fname
);
350 if (smb_fname_tmp
== NULL
) {
355 smb_fname_tmp
->base_name
= cappath
;
357 ret
= SMB_VFS_NEXT_UNLINKAT(handle
,
358 dirfsp
->conn
->cwd_fsp
,
362 TALLOC_FREE(smb_fname_tmp
);
366 static int cap_lchown(vfs_handle_struct
*handle
,
367 const struct smb_filename
*smb_fname
,
371 struct smb_filename
*cap_smb_fname
= NULL
;
372 char *cappath
= capencode(talloc_tos(), smb_fname
->base_name
);
381 cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
387 if (cap_smb_fname
== NULL
) {
388 TALLOC_FREE(cappath
);
393 ret
= SMB_VFS_NEXT_LCHOWN(handle
, cap_smb_fname
, uid
, gid
);
395 TALLOC_FREE(cappath
);
396 TALLOC_FREE(cap_smb_fname
);
401 static int cap_chdir(vfs_handle_struct
*handle
,
402 const struct smb_filename
*smb_fname
)
404 struct smb_filename
*cap_smb_fname
= NULL
;
405 char *cappath
= capencode(talloc_tos(), smb_fname
->base_name
);
413 DEBUG(3,("cap: cap_chdir for %s\n", smb_fname
->base_name
));
415 cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
421 if (cap_smb_fname
== NULL
) {
422 TALLOC_FREE(cappath
);
426 ret
= SMB_VFS_NEXT_CHDIR(handle
, cap_smb_fname
);
430 TALLOC_FREE(cappath
);
431 TALLOC_FREE(cap_smb_fname
);
432 if (saved_errno
!= 0) {
438 static int cap_symlinkat(vfs_handle_struct
*handle
,
439 const struct smb_filename
*link_contents
,
440 struct files_struct
*dirfsp
,
441 const struct smb_filename
*new_smb_fname
)
443 struct smb_filename
*full_fname
= NULL
;
444 char *capold
= capencode(talloc_tos(), link_contents
->base_name
);
446 struct smb_filename
*new_link_target
= NULL
;
447 struct smb_filename
*new_cap_smb_fname
= NULL
;
451 if (!capold
|| !capnew
) {
456 full_fname
= full_path_from_dirfsp_atname(talloc_tos(),
459 if (full_fname
== NULL
) {
463 capnew
= capencode(talloc_tos(), full_fname
->base_name
);
465 TALLOC_FREE(full_fname
);
470 new_link_target
= synthetic_smb_fname(talloc_tos(),
475 new_smb_fname
->flags
);
476 if (new_link_target
== NULL
) {
477 TALLOC_FREE(full_fname
);
484 new_cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
489 new_smb_fname
->flags
);
490 if (new_cap_smb_fname
== NULL
) {
491 TALLOC_FREE(full_fname
);
494 TALLOC_FREE(new_link_target
);
498 ret
= SMB_VFS_NEXT_SYMLINKAT(handle
,
500 handle
->conn
->cwd_fsp
,
505 TALLOC_FREE(full_fname
);
508 TALLOC_FREE(new_link_target
);
509 TALLOC_FREE(new_cap_smb_fname
);
510 if (saved_errno
!= 0) {
516 static int cap_readlinkat(vfs_handle_struct
*handle
,
517 const struct files_struct
*dirfsp
,
518 const struct smb_filename
*smb_fname
,
522 struct smb_filename
*full_fname
= NULL
;
523 struct smb_filename
*cap_smb_fname
= NULL
;
524 char *cappath
= NULL
;
528 full_fname
= full_path_from_dirfsp_atname(talloc_tos(),
531 if (full_fname
== NULL
) {
535 cappath
= capencode(talloc_tos(), full_fname
->base_name
);
536 if (cappath
== NULL
) {
537 TALLOC_FREE(full_fname
);
541 cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
547 if (cap_smb_fname
== NULL
) {
548 TALLOC_FREE(full_fname
);
549 TALLOC_FREE(cappath
);
553 ret
= SMB_VFS_NEXT_READLINKAT(handle
,
554 handle
->conn
->cwd_fsp
,
561 TALLOC_FREE(full_fname
);
562 TALLOC_FREE(cappath
);
563 TALLOC_FREE(cap_smb_fname
);
564 if (saved_errno
!= 0) {
570 static int cap_linkat(vfs_handle_struct
*handle
,
571 files_struct
*srcfsp
,
572 const struct smb_filename
*old_smb_fname
,
573 files_struct
*dstfsp
,
574 const struct smb_filename
*new_smb_fname
,
577 struct smb_filename
*old_full_fname
= NULL
;
578 struct smb_filename
*new_full_fname
= NULL
;
581 struct smb_filename
*old_cap_smb_fname
= NULL
;
582 struct smb_filename
*new_cap_smb_fname
= NULL
;
586 /* Process 'old' name. */
587 old_full_fname
= full_path_from_dirfsp_atname(talloc_tos(),
590 if (old_full_fname
== NULL
) {
593 capold
= capencode(talloc_tos(), old_full_fname
->base_name
);
594 if (capold
== NULL
) {
597 TALLOC_FREE(old_full_fname
);
598 old_cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
603 old_smb_fname
->flags
);
604 if (old_cap_smb_fname
== NULL
) {
608 /* Process 'new' name. */
609 new_full_fname
= full_path_from_dirfsp_atname(talloc_tos(),
612 if (new_full_fname
== NULL
) {
615 capnew
= capencode(talloc_tos(), new_full_fname
->base_name
);
616 if (capnew
== NULL
) {
619 TALLOC_FREE(new_full_fname
);
620 new_cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
625 new_smb_fname
->flags
);
626 if (new_cap_smb_fname
== NULL
) {
630 ret
= SMB_VFS_NEXT_LINKAT(handle
,
631 handle
->conn
->cwd_fsp
,
633 handle
->conn
->cwd_fsp
,
639 TALLOC_FREE(old_full_fname
);
640 TALLOC_FREE(old_full_fname
);
643 TALLOC_FREE(old_cap_smb_fname
);
644 TALLOC_FREE(new_cap_smb_fname
);
645 if (saved_errno
!= 0) {
652 TALLOC_FREE(old_full_fname
);
653 TALLOC_FREE(old_full_fname
);
656 TALLOC_FREE(old_cap_smb_fname
);
657 TALLOC_FREE(new_cap_smb_fname
);
662 static int cap_mknodat(vfs_handle_struct
*handle
,
663 files_struct
*dirfsp
,
664 const struct smb_filename
*smb_fname
,
668 struct smb_filename
*full_fname
= NULL
;
669 struct smb_filename
*cap_smb_fname
= NULL
;
670 char *cappath
= NULL
;
674 full_fname
= full_path_from_dirfsp_atname(talloc_tos(),
677 if (full_fname
== NULL
) {
681 cappath
= capencode(talloc_tos(), full_fname
->base_name
);
683 TALLOC_FREE(full_fname
);
687 cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
693 if (cap_smb_fname
== NULL
) {
694 TALLOC_FREE(full_fname
);
695 TALLOC_FREE(cappath
);
699 ret
= SMB_VFS_NEXT_MKNODAT(handle
,
700 handle
->conn
->cwd_fsp
,
707 TALLOC_FREE(full_fname
);
708 TALLOC_FREE(cappath
);
709 TALLOC_FREE(cap_smb_fname
);
710 if (saved_errno
!= 0) {
716 static struct smb_filename
*cap_realpath(vfs_handle_struct
*handle
,
718 const struct smb_filename
*smb_fname
)
720 /* monyo need capencode'ed and capdecode'ed? */
721 struct smb_filename
*cap_smb_fname
= NULL
;
722 struct smb_filename
*return_fname
= NULL
;
723 char *cappath
= capencode(talloc_tos(), smb_fname
->base_name
);
730 cap_smb_fname
= synthetic_smb_fname(ctx
,
736 if (cap_smb_fname
== NULL
) {
737 TALLOC_FREE(cappath
);
741 return_fname
= SMB_VFS_NEXT_REALPATH(handle
, ctx
, cap_smb_fname
);
742 if (return_fname
== NULL
) {
745 TALLOC_FREE(cappath
);
746 TALLOC_FREE(cap_smb_fname
);
747 if (saved_errno
!= 0) {
753 static ssize_t
cap_fgetxattr(vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *path
, void *value
, size_t size
)
755 char *cappath
= capencode(talloc_tos(), path
);
761 return SMB_VFS_NEXT_FGETXATTR(handle
, fsp
, cappath
, value
, size
);
764 static int cap_fremovexattr(vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *path
)
766 char *cappath
= capencode(talloc_tos(), path
);
772 return SMB_VFS_NEXT_FREMOVEXATTR(handle
, fsp
, cappath
);
775 static int cap_fsetxattr(vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *path
, const void *value
, size_t size
, int flags
)
777 char *cappath
= capencode(talloc_tos(), path
);
783 return SMB_VFS_NEXT_FSETXATTR(handle
, fsp
, cappath
, value
, size
, flags
);
786 static NTSTATUS
cap_create_dfs_pathat(vfs_handle_struct
*handle
,
787 files_struct
*dirfsp
,
788 const struct smb_filename
*smb_fname
,
789 const struct referral
*reflist
,
790 size_t referral_count
)
792 char *cappath
= capencode(talloc_tos(), smb_fname
->base_name
);
793 struct smb_filename
*cap_smb_fname
= NULL
;
796 if (cappath
== NULL
) {
797 return NT_STATUS_NO_MEMORY
;
799 cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
805 if (cap_smb_fname
== NULL
) {
806 TALLOC_FREE(cappath
);
807 return NT_STATUS_NO_MEMORY
;
809 status
= SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle
,
814 TALLOC_FREE(cappath
);
815 TALLOC_FREE(cap_smb_fname
);
819 static NTSTATUS
cap_read_dfs_pathat(struct vfs_handle_struct
*handle
,
821 struct files_struct
*dirfsp
,
822 struct smb_filename
*smb_fname
,
823 struct referral
**ppreflist
,
824 size_t *preferral_count
)
826 struct smb_filename
*full_fname
= NULL
;
827 struct smb_filename
*cap_smb_fname
= NULL
;
828 char *cappath
= NULL
;
831 full_fname
= full_path_from_dirfsp_atname(talloc_tos(),
834 if (full_fname
== NULL
) {
835 return NT_STATUS_NO_MEMORY
;
837 cappath
= capencode(talloc_tos(), full_fname
->base_name
);
838 if (cappath
== NULL
) {
839 TALLOC_FREE(full_fname
);
840 return NT_STATUS_NO_MEMORY
;
842 cap_smb_fname
= synthetic_smb_fname(talloc_tos(),
848 if (cap_smb_fname
== NULL
) {
849 TALLOC_FREE(full_fname
);
850 TALLOC_FREE(cappath
);
851 return NT_STATUS_NO_MEMORY
;
854 status
= SMB_VFS_NEXT_READ_DFS_PATHAT(handle
,
856 handle
->conn
->cwd_fsp
,
861 if (NT_STATUS_IS_OK(status
)) {
862 /* Return any stat(2) info. */
863 smb_fname
->st
= cap_smb_fname
->st
;
866 TALLOC_FREE(full_fname
);
867 TALLOC_FREE(cappath
);
868 TALLOC_FREE(cap_smb_fname
);
872 static struct vfs_fn_pointers vfs_cap_fns
= {
873 .disk_free_fn
= cap_disk_free
,
874 .get_quota_fn
= cap_get_quota
,
875 .readdir_fn
= cap_readdir
,
876 .mkdirat_fn
= cap_mkdirat
,
877 .openat_fn
= cap_openat
,
878 .renameat_fn
= cap_renameat
,
880 .lstat_fn
= cap_lstat
,
881 .unlinkat_fn
= cap_unlinkat
,
882 .lchown_fn
= cap_lchown
,
883 .chdir_fn
= cap_chdir
,
884 .symlinkat_fn
= cap_symlinkat
,
885 .readlinkat_fn
= cap_readlinkat
,
886 .linkat_fn
= cap_linkat
,
887 .mknodat_fn
= cap_mknodat
,
888 .realpath_fn
= cap_realpath
,
889 .getxattrat_send_fn
= vfs_not_implemented_getxattrat_send
,
890 .getxattrat_recv_fn
= vfs_not_implemented_getxattrat_recv
,
891 .fgetxattr_fn
= cap_fgetxattr
,
892 .fremovexattr_fn
= cap_fremovexattr
,
893 .fsetxattr_fn
= cap_fsetxattr
,
894 .create_dfs_pathat_fn
= cap_create_dfs_pathat
,
895 .read_dfs_pathat_fn
= cap_read_dfs_pathat
899 NTSTATUS
vfs_cap_init(TALLOC_CTX
*ctx
)
901 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION
, "cap",
905 /* For CAP functions */
907 #define hex2bin(c) hex2bin_table[(unsigned char)(c)]
908 #define bin2hex(c) bin2hex_table[(unsigned char)(c)]
909 #define is_hex(s) ((s)[0] == hex_tag)
911 static unsigned char hex2bin_table
[256] = {
912 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
913 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
914 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
915 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
916 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x40 */
917 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
918 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
919 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x60 */
920 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
921 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */
922 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
923 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
924 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
925 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
926 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
927 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
928 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 */
929 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 */
931 static unsigned char bin2hex_table
[256] = "0123456789abcdef";
933 /*******************************************************************
934 original code -> ":xx" - CAP format
935 ********************************************************************/
937 static char *capencode(TALLOC_CTX
*ctx
, const char *from
)
944 for (p1
= from
; *p1
; p1
++) {
945 if ((unsigned char)*p1
>= 0x80) {
953 to
= talloc_array(ctx
, char, len
);
958 for (out
= to
; *from
;) {
959 /* buffer husoku error */
960 if ((unsigned char)*from
>= 0x80) {
962 *out
++ = bin2hex (((*from
)>>4)&0x0f);
963 *out
++ = bin2hex ((*from
)&0x0f);
973 /*******************************************************************
975 ********************************************************************/
976 /* ":xx" -> a byte */
978 static char *capdecode(TALLOC_CTX
*ctx
, const char *from
)
985 for (p1
= from
; *p1
; len
++) {
994 to
= talloc_array(ctx
, char, len
);
999 for (out
= to
; *from
;) {
1001 *out
++ = (hex2bin(from
[1])<<4) | (hex2bin(from
[2]));