データ構造 | |
struct | DOS_ATTR_DESC |
関数 | |
smbc_dirent * | smbc_readdir_ctx (SMBCCTX *context, SMBCFILE *dir) |
smbc_dir_list * | smbc_check_dir_ent (struct smbc_dir_list *list, struct smbc_dirent *dirent) |
int | smbc_default_cache_functions (SMBCCTX *context) |
static int | DLIST_CONTAINS (SMBCFILE *list, SMBCFILE *p) |
static struct rpc_pipe_client * | find_lsa_pipe_hnd (struct cli_state *ipc_cli) |
static int | smbc_close_ctx (SMBCCTX *context, SMBCFILE *file) |
static off_t | smbc_lseek_ctx (SMBCCTX *context, SMBCFILE *file, off_t offset, int whence) |
static int | hex2int (unsigned int _char) |
int | smbc_urldecode (char *dest, char *src, size_t max_dest_len) |
Convert strings of xx to their single character equivalent. | |
int | smbc_urlencode (char *dest, char *src, int max_dest_len) |
static int | smbc_parse_path (SMBCCTX *context, const char *fname, char *workgroup, int workgroup_len, char *server, int server_len, char *share, int share_len, char *path, int path_len, char *user, int user_len, char *password, int password_len, char *options, int options_len) |
static int | smbc_check_options (char *server, char *share, char *path, char *options) |
static int | smbc_errno (SMBCCTX *context, struct cli_state *c) |
static int | smbc_check_server (SMBCCTX *context, SMBCSRV *server) |
int | smbc_remove_unused_server (SMBCCTX *context, SMBCSRV *srv) |
Remove a server from the cached server list it's unused. | |
static SMBCSRV * | find_server (SMBCCTX *context, const char *server, const char *share, fstring workgroup, fstring username, fstring password) |
static SMBCSRV * | smbc_server (SMBCCTX *context, BOOL connect_if_not_found, const char *server, const char *share, fstring workgroup, fstring username, fstring password) |
static SMBCSRV * | smbc_attr_server (SMBCCTX *context, const char *server, const char *share, fstring workgroup, fstring username, fstring password, POLICY_HND *pol) |
static SMBCFILE * | smbc_open_ctx (SMBCCTX *context, const char *fname, int flags, mode_t mode) |
static SMBCFILE * | smbc_creat_ctx (SMBCCTX *context, const char *path, mode_t mode) |
static ssize_t | smbc_read_ctx (SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) |
static ssize_t | smbc_write_ctx (SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) |
static BOOL | smbc_getatr (SMBCCTX *context, SMBCSRV *srv, char *path, uint16 *mode, SMB_OFF_T *size, struct timespec *create_time_ts, struct timespec *access_time_ts, struct timespec *write_time_ts, struct timespec *change_time_ts, SMB_INO_T *ino) |
static BOOL | smbc_setatr (SMBCCTX *context, SMBCSRV *srv, char *path, time_t create_time, time_t access_time, time_t write_time, time_t change_time, uint16 mode) |
static int | smbc_unlink_ctx (SMBCCTX *context, const char *fname) |
static int | smbc_rename_ctx (SMBCCTX *ocontext, const char *oname, SMBCCTX *ncontext, const char *nname) |
static ino_t | smbc_inode (SMBCCTX *context, const char *name) |
static int | smbc_setup_stat (SMBCCTX *context, struct stat *st, char *fname, SMB_OFF_T size, int mode) |
static int | smbc_stat_ctx (SMBCCTX *context, const char *fname, struct stat *st) |
static int | smbc_fstat_ctx (SMBCCTX *context, SMBCFILE *file, struct stat *st) |
static void | smbc_remove_dir (SMBCFILE *dir) |
static int | add_dirent (SMBCFILE *dir, const char *name, const char *comment, uint32 type) |
static void | list_unique_wg_fn (const char *name, uint32 type, const char *comment, void *state) |
static void | list_fn (const char *name, uint32 type, const char *comment, void *state) |
static void | dir_list_fn (const char *mnt, file_info *finfo, const char *mask, void *state) |
static int | net_share_enum_rpc (struct cli_state *cli, void(*fn)(const char *name, uint32 type, const char *comment, void *state), void *state) |
static SMBCFILE * | smbc_opendir_ctx (SMBCCTX *context, const char *fname) |
static int | smbc_closedir_ctx (SMBCCTX *context, SMBCFILE *dir) |
static void | smbc_readdir_internal (SMBCCTX *context, struct smbc_dirent *dest, struct smbc_dirent *src, int max_namebuf_len) |
static int | smbc_getdents_ctx (SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent *dirp, int count) |
static int | smbc_mkdir_ctx (SMBCCTX *context, const char *fname, mode_t mode) |
static void | rmdir_list_fn (const char *mnt, file_info *finfo, const char *mask, void *state) |
static int | smbc_rmdir_ctx (SMBCCTX *context, const char *fname) |
static off_t | smbc_telldir_ctx (SMBCCTX *context, SMBCFILE *dir) |
static int | smbc_lseekdir_ctx (SMBCCTX *context, SMBCFILE *dir, off_t offset) |
static int | smbc_fstatdir_ctx (SMBCCTX *context, SMBCFILE *dir, struct stat *st) |
static int | smbc_chmod_ctx (SMBCCTX *context, const char *fname, mode_t newmode) |
static int | smbc_utimes_ctx (SMBCCTX *context, const char *fname, struct timeval *tbuf) |
static int | ace_compare (SEC_ACE *ace1, SEC_ACE *ace2) |
static void | sort_acl (SEC_ACL *the_acl) |
static void | convert_sid_to_string (struct cli_state *ipc_cli, POLICY_HND *pol, fstring str, BOOL numeric, DOM_SID *sid) |
static BOOL | convert_string_to_sid (struct cli_state *ipc_cli, POLICY_HND *pol, BOOL numeric, DOM_SID *sid, const char *str) |
static BOOL | parse_ace (struct cli_state *ipc_cli, POLICY_HND *pol, SEC_ACE *ace, BOOL numeric, char *str) |
static BOOL | add_ace (SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) |
static SEC_DESC * | sec_desc_parse (TALLOC_CTX *ctx, struct cli_state *ipc_cli, POLICY_HND *pol, BOOL numeric, char *str) |
static DOS_ATTR_DESC * | dos_attr_query (SMBCCTX *context, TALLOC_CTX *ctx, const char *filename, SMBCSRV *srv) |
static void | dos_attr_parse (SMBCCTX *context, DOS_ATTR_DESC *dad, SMBCSRV *srv, char *str) |
static int | cacl_get (SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, struct cli_state *ipc_cli, POLICY_HND *pol, char *filename, char *attr_name, char *buf, int bufsize) |
static int | cacl_set (TALLOC_CTX *ctx, struct cli_state *cli, struct cli_state *ipc_cli, POLICY_HND *pol, const char *filename, const char *the_acl, int mode, int flags) |
static int | smbc_setxattr_ctx (SMBCCTX *context, const char *fname, const char *name, const void *value, size_t size, int flags) |
static int | smbc_getxattr_ctx (SMBCCTX *context, const char *fname, const char *name, const void *value, size_t size) |
static int | smbc_removexattr_ctx (SMBCCTX *context, const char *fname, const char *name) |
static int | smbc_listxattr_ctx (SMBCCTX *context, const char *fname, char *list, size_t size) |
static SMBCFILE * | smbc_open_print_job_ctx (SMBCCTX *context, const char *fname) |
static int | smbc_print_file_ctx (SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq) |
static int | smbc_list_print_jobs_ctx (SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn) |
static int | smbc_unlink_print_job_ctx (SMBCCTX *context, const char *fname, int id) |
SMBCCTX * | smbc_new_context (void) |
Create a new SBMCCTX (a context). | |
int | smbc_free_context (SMBCCTX *context, int shutdown_ctx) |
Delete a SBMCCTX (a context) acquired from smbc_new_context(). | |
void | smbc_option_set (SMBCCTX *context, char *option_name,...) |
Each time the context structure is changed, we have binary backward compatibility issues. | |
void * | smbc_option_get (SMBCCTX *context, char *option_name) |
SMBCCTX * | smbc_init_context (SMBCCTX *context) |
Initialize a SBMCCTX (a context). | |
const char * | smbc_version (void) |
Return the version of the linked Samba code, and thus the version of the libsmbclient code. | |
変数 | |
BOOL | in_client |
static int | smbc_initialized = 0 |
static const char * | smbc_prefix = "smb:" |
static int | creat_bits = O_WRONLY | O_CREAT | O_TRUNC |
static int | smbc_rmdir_dirempty = True |
struct smbc_dirent * smbc_readdir_ctx | ( | SMBCCTX * | context, | |
SMBCFILE * | dir | |||
) |
libsmbclient.c の 3059 行で定義されています。
参照先 smbc_internal_data::_dirent・smbc_internal_data::_files・smbc_internal_data::_initialized・_SMBCFILE::dir_next・smbc_dir_list::dirent・DLIST_CONTAINS()・errno・_SMBCFILE::file・_SMBCCTX::internal・smbc_dir_list::next・smbc_readdir_internal().
参照元 smbc_new_context().
03061 { 03062 int maxlen; 03063 struct smbc_dirent *dirp, *dirent; 03064 03065 /* Check that all is ok first ... */ 03066 03067 if (!context || !context->internal || 03068 !context->internal->_initialized) { 03069 03070 errno = EINVAL; 03071 DEBUG(0, ("Invalid context in smbc_readdir_ctx()\n")); 03072 return NULL; 03073 03074 } 03075 03076 if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { 03077 03078 errno = EBADF; 03079 DEBUG(0, ("Invalid dir in smbc_readdir_ctx()\n")); 03080 return NULL; 03081 03082 } 03083 03084 if (dir->file != False) { /* FIXME, should be dir, perhaps */ 03085 03086 errno = ENOTDIR; 03087 DEBUG(0, ("Found file vs directory in smbc_readdir_ctx()\n")); 03088 return NULL; 03089 03090 } 03091 03092 if (!dir->dir_next) { 03093 return NULL; 03094 } 03095 03096 dirent = dir->dir_next->dirent; 03097 if (!dirent) { 03098 03099 errno = ENOENT; 03100 return NULL; 03101 03102 } 03103 03104 dirp = (struct smbc_dirent *)context->internal->_dirent; 03105 maxlen = (sizeof(context->internal->_dirent) - 03106 sizeof(struct smbc_dirent)); 03107 03108 smbc_readdir_internal(context, dirp, dirent, maxlen); 03109 03110 dir->dir_next = dir->dir_next->next; 03111 03112 return dirp; 03113 }
struct smbc_dir_list * smbc_check_dir_ent | ( | struct smbc_dir_list * | list, | |
struct smbc_dirent * | dirent | |||
) |
libsmbclient.c の 3469 行で定義されています。
参照先 smbc_dir_list::dirent・list()・smbc_dir_list::next.
参照元 smbc_lseekdir_ctx().
03471 { 03472 03473 /* Run down the list looking for what we want */ 03474 03475 if (dirent) { 03476 03477 struct smbc_dir_list *tmp = list; 03478 03479 while (tmp) { 03480 03481 if (tmp->dirent == dirent) 03482 return tmp; 03483 03484 tmp = tmp->next; 03485 03486 } 03487 03488 } 03489 03490 return NULL; /* Not found, or an error */ 03491 03492 }
int smbc_default_cache_functions | ( | SMBCCTX * | context | ) |
libsmbclient.c の 77 行で定義されています。
参照先 list().
参照元 smbc_close_ctx()・smbc_closedir_ctx()・smbc_fstat_ctx()・smbc_getdents_ctx()・smbc_lseek_ctx()・smbc_read_ctx()・smbc_readdir_ctx()・smbc_telldir_ctx()・smbc_write_ctx().
00077 { 00078 if (!p || !list) return False; 00079 do { 00080 if (p == list) return True; 00081 list = list->next; 00082 } while (list); 00083 return False; 00084 }
static struct rpc_pipe_client* find_lsa_pipe_hnd | ( | struct cli_state * | ipc_cli | ) | [static] |
libsmbclient.c の 90 行で定義されています。
参照先 rpc_pipe_client::next・rpc_pipe_client::pipe_idx・cli_state::pipe_list.
参照元 convert_sid_to_string()・convert_string_to_sid().
00091 { 00092 struct rpc_pipe_client *pipe_hnd; 00093 00094 for (pipe_hnd = ipc_cli->pipe_list; 00095 pipe_hnd; 00096 pipe_hnd = pipe_hnd->next) { 00097 00098 if (pipe_hnd->pipe_idx == PI_LSARPC) { 00099 return pipe_hnd; 00100 } 00101 } 00102 00103 return NULL; 00104 }
libsmbclient.c の 1405 行で定義されています。
参照先 smbc_internal_data::_files・smbc_internal_data::_initialized・_SMBCCTX::callbacks・_SMBCSRV::cli・cli_close()・_SMBCFILE::cli_fd・cli_resolve_path()・_SMBCCTX::closedir・d_printf()・DLIST_CONTAINS()・errno・_SMBCFILE::file・_SMBCFILE::fname・_SMBCCTX::internal・password・_SMBCCTX::_smbc_callbacks::remove_unused_server_fn・server・share・smbc_errno()・smbc_parse_path()・_SMBCFILE::srv.
参照元 smbc_new_context()・smbc_open_ctx().
01407 { 01408 SMBCSRV *srv; 01409 fstring server, share, user, password; 01410 pstring path, targetpath; 01411 struct cli_state *targetcli; 01412 01413 if (!context || !context->internal || 01414 !context->internal->_initialized) { 01415 01416 errno = EINVAL; 01417 return -1; 01418 01419 } 01420 01421 if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { 01422 01423 errno = EBADF; 01424 return -1; 01425 01426 } 01427 01428 /* IS a dir ... */ 01429 if (!file->file) { 01430 01431 return (context->closedir)(context, file); 01432 01433 } 01434 01435 /*d_printf(">>>close: parsing %s\n", file->fname);*/ 01436 if (smbc_parse_path(context, file->fname, 01437 NULL, 0, 01438 server, sizeof(server), 01439 share, sizeof(share), 01440 path, sizeof(path), 01441 user, sizeof(user), 01442 password, sizeof(password), 01443 NULL, 0)) { 01444 errno = EINVAL; 01445 return -1; 01446 } 01447 01448 /*d_printf(">>>close: resolving %s\n", path);*/ 01449 if (!cli_resolve_path("", file->srv->cli, path, 01450 &targetcli, targetpath)) 01451 { 01452 d_printf("Could not resolve %s\n", path); 01453 return -1; 01454 } 01455 /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ 01456 01457 if (!cli_close(targetcli, file->cli_fd)) { 01458 01459 DEBUG(3, ("cli_close failed on %s. purging server.\n", 01460 file->fname)); 01461 /* Deallocate slot and remove the server 01462 * from the server cache if unused */ 01463 errno = smbc_errno(context, targetcli); 01464 srv = file->srv; 01465 DLIST_REMOVE(context->internal->_files, file); 01466 SAFE_FREE(file->fname); 01467 SAFE_FREE(file); 01468 (context->callbacks.remove_unused_server_fn)(context, srv); 01469 01470 return -1; 01471 01472 } 01473 01474 DLIST_REMOVE(context->internal->_files, file); 01475 SAFE_FREE(file->fname); 01476 SAFE_FREE(file); 01477 01478 return 0; 01479 }
static off_t smbc_lseek_ctx | ( | SMBCCTX * | context, | |
SMBCFILE * | file, | |||
off_t | offset, | |||
int | whence | |||
) | [static] |
libsmbclient.c の 1893 行で定義されています。
参照先 smbc_internal_data::_files・smbc_internal_data::_initialized・_SMBCSRV::cli・_SMBCFILE::cli_fd・cli_getattrE()・cli_qfileinfo()・cli_resolve_path()・d_printf()・DLIST_CONTAINS()・errno・_SMBCFILE::file・_SMBCFILE::fname・_SMBCCTX::internal・_SMBCFILE::offset・password・server・share・size・smbc_parse_path()・_SMBCFILE::srv.
参照元 smbc_new_context()・smbc_open_ctx().
01897 { 01898 SMB_OFF_T size; 01899 fstring server, share, user, password; 01900 pstring path, targetpath; 01901 struct cli_state *targetcli; 01902 01903 if (!context || !context->internal || 01904 !context->internal->_initialized) { 01905 01906 errno = EINVAL; 01907 return -1; 01908 01909 } 01910 01911 if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { 01912 01913 errno = EBADF; 01914 return -1; 01915 01916 } 01917 01918 if (!file->file) { 01919 01920 errno = EINVAL; 01921 return -1; /* Can't lseek a dir ... */ 01922 01923 } 01924 01925 switch (whence) { 01926 case SEEK_SET: 01927 file->offset = offset; 01928 break; 01929 01930 case SEEK_CUR: 01931 file->offset += offset; 01932 break; 01933 01934 case SEEK_END: 01935 /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ 01936 if (smbc_parse_path(context, file->fname, 01937 NULL, 0, 01938 server, sizeof(server), 01939 share, sizeof(share), 01940 path, sizeof(path), 01941 user, sizeof(user), 01942 password, sizeof(password), 01943 NULL, 0)) { 01944 01945 errno = EINVAL; 01946 return -1; 01947 } 01948 01949 /*d_printf(">>>lseek: resolving %s\n", path);*/ 01950 if (!cli_resolve_path("", file->srv->cli, path, 01951 &targetcli, targetpath)) 01952 { 01953 d_printf("Could not resolve %s\n", path); 01954 return -1; 01955 } 01956 /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ 01957 01958 if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, 01959 &size, NULL, NULL, NULL, NULL, NULL)) 01960 { 01961 SMB_OFF_T b_size = size; 01962 if (!cli_getattrE(targetcli, file->cli_fd, 01963 NULL, &b_size, NULL, NULL, NULL)) 01964 { 01965 errno = EINVAL; 01966 return -1; 01967 } else 01968 size = b_size; 01969 } 01970 file->offset = size + offset; 01971 break; 01972 01973 default: 01974 errno = EINVAL; 01975 break; 01976 01977 } 01978 01979 return file->offset; 01980 01981 }
static int hex2int | ( | unsigned int | _char | ) | [static] |
libsmbclient.c の 123 行で定義されています。
参照元 smbc_urldecode().
00124 { 00125 if ( _char >= 'A' && _char <='F') 00126 return _char - 'A' + 10; 00127 if ( _char >= 'a' && _char <='f') 00128 return _char - 'a' + 10; 00129 if ( _char >= '0' && _char <='9') 00130 return _char - '0'; 00131 return -1; 00132 }
int smbc_urlencode | ( | char * | dest, | |
char * | src, | |||
int | max_dest_len | |||
) |
libsmbclient.c の 203 行で定義されています。
00204 { 00205 char hex[] = "0123456789ABCDEF"; 00206 00207 for (; *src != '\0' && max_dest_len >= 3; src++) { 00208 00209 if ((*src < '0' && 00210 *src != '-' && 00211 *src != '.') || 00212 (*src > '9' && 00213 *src < 'A') || 00214 (*src > 'Z' && 00215 *src < 'a' && 00216 *src != '_') || 00217 (*src > 'z')) { 00218 *dest++ = '%'; 00219 *dest++ = hex[(*src >> 4) & 0x0f]; 00220 *dest++ = hex[*src & 0x0f]; 00221 max_dest_len -= 3; 00222 } else { 00223 *dest++ = *src; 00224 max_dest_len--; 00225 } 00226 } 00227 00228 *dest++ = '\0'; 00229 max_dest_len--; 00230 00231 return max_dest_len; 00232 }
static int smbc_parse_path | ( | SMBCCTX * | context, | |
const char * | fname, | |||
char * | workgroup, | |||
int | workgroup_len, | |||
char * | server, | |||
int | server_len, | |||
char * | share, | |||
int | share_len, | |||
char * | path, | |||
int | path_len, | |||
char * | user, | |||
int | user_len, | |||
char * | password, | |||
int | password_len, | |||
char * | options, | |||
int | options_len | |||
) | [static] |
libsmbclient.c の 274 行で定義されています。
参照先 all_string_sub()・rpc_pipe_client::domain・len・next_token()・next_token_no_ltrim()・smbc_prefix・smbc_urldecode()・strchr_m()・username・_SMBCCTX::workgroup.
参照元 smbc_chmod_ctx()・smbc_close_ctx()・smbc_fstat_ctx()・smbc_getxattr_ctx()・smbc_list_print_jobs_ctx()・smbc_lseek_ctx()・smbc_mkdir_ctx()・smbc_open_ctx()・smbc_open_print_job_ctx()・smbc_opendir_ctx()・smbc_read_ctx()・smbc_removexattr_ctx()・smbc_rename_ctx()・smbc_rmdir_ctx()・smbc_setxattr_ctx()・smbc_stat_ctx()・smbc_unlink_ctx()・smbc_unlink_print_job_ctx()・smbc_utimes_ctx()・smbc_write_ctx().
00283 { 00284 static pstring s; 00285 pstring userinfo; 00286 const char *p; 00287 char *q, *r; 00288 int len; 00289 00290 server[0] = share[0] = path[0] = user[0] = password[0] = (char)0; 00291 00292 /* 00293 * Assume we wont find an authentication domain to parse, so default 00294 * to the workgroup in the provided context. 00295 */ 00296 if (workgroup != NULL) { 00297 strncpy(workgroup, context->workgroup, workgroup_len - 1); 00298 workgroup[workgroup_len - 1] = '\0'; 00299 } 00300 00301 if (options != NULL && options_len > 0) { 00302 options[0] = (char)0; 00303 } 00304 pstrcpy(s, fname); 00305 00306 /* see if it has the right prefix */ 00307 len = strlen(smbc_prefix); 00308 if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) { 00309 return -1; /* What about no smb: ? */ 00310 } 00311 00312 p = s + len; 00313 00314 /* Watch the test below, we are testing to see if we should exit */ 00315 00316 if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { 00317 00318 DEBUG(1, ("Invalid path (does not begin with smb://")); 00319 return -1; 00320 00321 } 00322 00323 p += 2; /* Skip the double slash */ 00324 00325 /* See if any options were specified */ 00326 if ((q = strrchr(p, '?')) != NULL ) { 00327 /* There are options. Null terminate here and point to them */ 00328 *q++ = '\0'; 00329 00330 DEBUG(4, ("Found options '%s'", q)); 00331 00332 /* Copy the options */ 00333 if (options != NULL && options_len > 0) { 00334 safe_strcpy(options, q, options_len - 1); 00335 } 00336 } 00337 00338 if (*p == (char)0) 00339 goto decoding; 00340 00341 if (*p == '/') { 00342 int wl = strlen(context->workgroup); 00343 00344 if (wl > 16) { 00345 wl = 16; 00346 } 00347 00348 strncpy(server, context->workgroup, wl); 00349 server[wl] = '\0'; 00350 return 0; 00351 } 00352 00353 /* 00354 * ok, its for us. Now parse out the server, share etc. 00355 * 00356 * However, we want to parse out [[domain;]user[:password]@] if it 00357 * exists ... 00358 */ 00359 00360 /* check that '@' occurs before '/', if '/' exists at all */ 00361 q = strchr_m(p, '@'); 00362 r = strchr_m(p, '/'); 00363 if (q && (!r || q < r)) { 00364 pstring username, passwd, domain; 00365 const char *u = userinfo; 00366 00367 next_token_no_ltrim(&p, userinfo, "@", sizeof(fstring)); 00368 00369 username[0] = passwd[0] = domain[0] = 0; 00370 00371 if (strchr_m(u, ';')) { 00372 00373 next_token_no_ltrim(&u, domain, ";", sizeof(fstring)); 00374 00375 } 00376 00377 if (strchr_m(u, ':')) { 00378 00379 next_token_no_ltrim(&u, username, ":", sizeof(fstring)); 00380 00381 pstrcpy(passwd, u); 00382 00383 } 00384 else { 00385 00386 pstrcpy(username, u); 00387 00388 } 00389 00390 if (domain[0] && workgroup) { 00391 strncpy(workgroup, domain, workgroup_len - 1); 00392 workgroup[workgroup_len - 1] = '\0'; 00393 } 00394 00395 if (username[0]) { 00396 strncpy(user, username, user_len - 1); 00397 user[user_len - 1] = '\0'; 00398 } 00399 00400 if (passwd[0]) { 00401 strncpy(password, passwd, password_len - 1); 00402 password[password_len - 1] = '\0'; 00403 } 00404 00405 } 00406 00407 if (!next_token(&p, server, "/", sizeof(fstring))) { 00408 00409 return -1; 00410 00411 } 00412 00413 if (*p == (char)0) goto decoding; /* That's it ... */ 00414 00415 if (!next_token(&p, share, "/", sizeof(fstring))) { 00416 00417 return -1; 00418 00419 } 00420 00421 /* 00422 * Prepend a leading slash if there's a file path, as required by 00423 * NetApp filers. 00424 */ 00425 *path = '\0'; 00426 if (*p != '\0') { 00427 *path = '/'; 00428 safe_strcpy(path + 1, p, path_len - 2); 00429 } 00430 00431 all_string_sub(path, "/", "\\", 0); 00432 00433 decoding: 00434 (void) smbc_urldecode(path, path, path_len); 00435 (void) smbc_urldecode(server, server, server_len); 00436 (void) smbc_urldecode(share, share, share_len); 00437 (void) smbc_urldecode(user, user, user_len); 00438 (void) smbc_urldecode(password, password, password_len); 00439 00440 return 0; 00441 }
static int smbc_check_options | ( | char * | server, | |
char * | share, | |||
char * | path, | |||
char * | options | |||
) | [static] |
libsmbclient.c の 447 行で定義されています。
参照元 smbc_opendir_ctx().
00451 { 00452 DEBUG(4, ("smbc_check_options(): server='%s' share='%s' " 00453 "path='%s' options='%s'\n", 00454 server, share, path, options)); 00455 00456 /* No options at all is always ok */ 00457 if (! *options) return 0; 00458 00459 /* Currently, we don't support any options. */ 00460 return -1; 00461 }
libsmbclient.c の 467 行で定義されています。
参照先 c・cli_dos_error()・cli_errno()・cli_is_dos_error()・cli_nt_error()・nt_errstr()・status.
参照元 cacl_get()・dos_attr_query()・smbc_attr_server()・smbc_chmod_ctx()・smbc_close_ctx()・smbc_getxattr_ctx()・smbc_list_print_jobs_ctx()・smbc_mkdir_ctx()・smbc_open_ctx()・smbc_opendir_ctx()・smbc_read_ctx()・smbc_rename_ctx()・smbc_rmdir_ctx()・smbc_server()・smbc_setatr()・smbc_stat_ctx()・smbc_unlink_ctx()・smbc_unlink_print_job_ctx()・smbc_write_ctx().
00469 { 00470 int ret = cli_errno(c); 00471 00472 if (cli_is_dos_error(c)) { 00473 uint8 eclass; 00474 uint32 ecode; 00475 00476 cli_dos_error(c, &eclass, &ecode); 00477 00478 DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", 00479 (int)eclass, (int)ecode, (int)ecode, ret)); 00480 } else { 00481 NTSTATUS status; 00482 00483 status = cli_nt_error(c); 00484 00485 DEBUG(3,("smbc errno %s -> %d\n", 00486 nt_errstr(status), ret)); 00487 } 00488 00489 return ret; 00490 }
libsmbclient.c の 500 行で定義されています。
参照元 smbc_new_context().
00502 { 00503 socklen_t size; 00504 struct sockaddr addr; 00505 00506 size = sizeof(addr); 00507 return (getpeername(server->cli->fd, &addr, &size) == -1); 00508 }
static SMBCSRV* find_server | ( | SMBCCTX * | context, | |
const char * | server, | |||
const char * | share, | |||
fstring | workgroup, | |||
fstring | username, | |||
fstring | password | |||
) | [static] |
libsmbclient.c の 553 行で定義されています。
参照先 smbc_internal_data::_auth_fn_with_context・_SMBCCTX::_smbc_callbacks::auth_fn・_SMBCCTX::callbacks・_SMBCCTX::_smbc_callbacks::check_server_fn・_SMBCCTX::_smbc_callbacks::get_cached_srv_fn・_SMBCCTX::internal.
参照元 smbc_attr_server()・smbc_server().
00559 { 00560 SMBCSRV *srv; 00561 int auth_called = 0; 00562 00563 check_server_cache: 00564 00565 srv = (context->callbacks.get_cached_srv_fn)(context, server, share, 00566 workgroup, username); 00567 00568 if (!auth_called && !srv && (!username[0] || !password[0])) { 00569 if (context->internal->_auth_fn_with_context != NULL) { 00570 (context->internal->_auth_fn_with_context)( 00571 context, 00572 server, share, 00573 workgroup, sizeof(fstring), 00574 username, sizeof(fstring), 00575 password, sizeof(fstring)); 00576 } else { 00577 (context->callbacks.auth_fn)( 00578 server, share, 00579 workgroup, sizeof(fstring), 00580 username, sizeof(fstring), 00581 password, sizeof(fstring)); 00582 } 00583 00584 /* 00585 * However, smbc_auth_fn may have picked up info relating to 00586 * an existing connection, so try for an existing connection 00587 * again ... 00588 */ 00589 auth_called = 1; 00590 goto check_server_cache; 00591 00592 } 00593 00594 if (srv) { 00595 if ((context->callbacks.check_server_fn)(context, srv)) { 00596 /* 00597 * This server is no good anymore 00598 * Try to remove it and check for more possible 00599 * servers in the cache 00600 */ 00601 if ((context->callbacks.remove_unused_server_fn)(context, 00602 srv)) { 00603 /* 00604 * We could not remove the server completely, 00605 * remove it from the cache so we will not get 00606 * it again. It will be removed when the last 00607 * file/dir is closed. 00608 */ 00609 (context->callbacks.remove_cached_srv_fn)(context, 00610 srv); 00611 } 00612 00613 /* 00614 * Maybe there are more cached connections to this 00615 * server 00616 */ 00617 goto check_server_cache; 00618 } 00619 00620 return srv; 00621 } 00622 00623 return NULL; 00624 }
static SMBCSRV* smbc_server | ( | SMBCCTX * | context, | |
BOOL | connect_if_not_found, | |||
const char * | server, | |||
const char * | share, | |||
fstring | workgroup, | |||
fstring | username, | |||
fstring | password | |||
) | [static] |
libsmbclient.c の 638 行で定義されています。
参照先 smbc_internal_data::_auth_fn_with_context・smbc_internal_data::_servers・_SMBCCTX::_smbc_callbacks::add_cached_srv_fn・_SMBCCTX::_smbc_callbacks::auth_fn・c・_SMBCCTX::callbacks・_SMBCSRV::cli・cli_connect()・cli_initialise()・cli_negprot()・cli_send_tconX()・cli_session_request()・cli_session_setup()・cli_shutdown()・cli_state::cnum・_SMBCSRV::dev・errno・failed・cli_state::fallback_after_kerberos・find_server()・_SMBCCTX::flags・_SMBCCTX::internal・is_ipaddress()・make_nmb_name()・nmb_name::name・name_status_find()・_SMBCCTX::netbios_name・_SMBCSRV::no_nt_session・_SMBCSRV::no_pathinfo・_SMBCSRV::no_pathinfo2・_SMBCCTX::_smbc_options::one_share_per_server・_SMBCCTX::options・cli_state::port・_SMBCCTX::_smbc_callbacks::remove_cached_srv_fn・smbc_errno()・status・str_checksum()・_SMBCCTX::timeout・cli_state::timeout・cli_state::use_kerberos・zero_ip().
参照元 smbc_chmod_ctx()・smbc_getxattr_ctx()・smbc_list_print_jobs_ctx()・smbc_mkdir_ctx()・smbc_open_ctx()・smbc_opendir_ctx()・smbc_removexattr_ctx()・smbc_rename_ctx()・smbc_rmdir_ctx()・smbc_setxattr_ctx()・smbc_stat_ctx()・smbc_unlink_ctx()・smbc_unlink_print_job_ctx()・smbc_utimes_ctx().
00645 { 00646 SMBCSRV *srv=NULL; 00647 struct cli_state *c; 00648 struct nmb_name called, calling; 00649 const char *server_n = server; 00650 pstring ipenv; 00651 struct in_addr ip; 00652 int tried_reverse = 0; 00653 int port_try_first; 00654 int port_try_next; 00655 const char *username_used; 00656 NTSTATUS status; 00657 00658 zero_ip(&ip); 00659 ZERO_STRUCT(c); 00660 00661 if (server[0] == 0) { 00662 errno = EPERM; 00663 return NULL; 00664 } 00665 00666 /* Look for a cached connection */ 00667 srv = find_server(context, server, share, 00668 workgroup, username, password); 00669 00670 /* 00671 * If we found a connection and we're only allowed one share per 00672 * server... 00673 */ 00674 if (srv && *share != '\0' && context->options.one_share_per_server) { 00675 00676 /* 00677 * ... then if there's no current connection to the share, 00678 * connect to it. find_server(), or rather the function 00679 * pointed to by context->callbacks.get_cached_srv_fn which 00680 * was called by find_server(), will have issued a tree 00681 * disconnect if the requested share is not the same as the 00682 * one that was already connected. 00683 */ 00684 if (srv->cli->cnum == (uint16) -1) { 00685 /* Ensure we have accurate auth info */ 00686 if (context->internal->_auth_fn_with_context != NULL) { 00687 (context->internal->_auth_fn_with_context)( 00688 context, 00689 server, share, 00690 workgroup, sizeof(fstring), 00691 username, sizeof(fstring), 00692 password, sizeof(fstring)); 00693 } else { 00694 (context->callbacks.auth_fn)( 00695 server, share, 00696 workgroup, sizeof(fstring), 00697 username, sizeof(fstring), 00698 password, sizeof(fstring)); 00699 } 00700 00701 if (! cli_send_tconX(srv->cli, share, "?????", 00702 password, strlen(password)+1)) { 00703 00704 errno = smbc_errno(context, srv->cli); 00705 cli_shutdown(srv->cli); 00706 srv->cli = NULL; 00707 (context->callbacks.remove_cached_srv_fn)(context, 00708 srv); 00709 srv = NULL; 00710 } 00711 00712 /* 00713 * Regenerate the dev value since it's based on both 00714 * server and share 00715 */ 00716 if (srv) { 00717 srv->dev = (dev_t)(str_checksum(server) ^ 00718 str_checksum(share)); 00719 } 00720 } 00721 } 00722 00723 /* If we have a connection... */ 00724 if (srv) { 00725 00726 /* ... then we're done here. Give 'em what they came for. */ 00727 return srv; 00728 } 00729 00730 /* If we're not asked to connect when a connection doesn't exist... */ 00731 if (! connect_if_not_found) { 00732 /* ... then we're done here. */ 00733 return NULL; 00734 } 00735 00736 make_nmb_name(&calling, context->netbios_name, 0x0); 00737 make_nmb_name(&called , server, 0x20); 00738 00739 DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); 00740 00741 DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); 00742 00743 again: 00744 slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); 00745 00746 zero_ip(&ip); 00747 00748 /* have to open a new connection */ 00749 if ((c = cli_initialise()) == NULL) { 00750 errno = ENOMEM; 00751 return NULL; 00752 } 00753 00754 if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { 00755 c->use_kerberos = True; 00756 } 00757 if (context->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) { 00758 c->fallback_after_kerberos = True; 00759 } 00760 00761 c->timeout = context->timeout; 00762 00763 /* 00764 * Force use of port 139 for first try if share is $IPC, empty, or 00765 * null, so browse lists can work 00766 */ 00767 if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0) { 00768 port_try_first = 139; 00769 port_try_next = 445; 00770 } else { 00771 port_try_first = 445; 00772 port_try_next = 139; 00773 } 00774 00775 c->port = port_try_first; 00776 00777 status = cli_connect(c, server_n, &ip); 00778 if (!NT_STATUS_IS_OK(status)) { 00779 00780 /* First connection attempt failed. Try alternate port. */ 00781 c->port = port_try_next; 00782 00783 status = cli_connect(c, server_n, &ip); 00784 if (!NT_STATUS_IS_OK(status)) { 00785 cli_shutdown(c); 00786 errno = ETIMEDOUT; 00787 return NULL; 00788 } 00789 } 00790 00791 if (!cli_session_request(c, &calling, &called)) { 00792 cli_shutdown(c); 00793 if (strcmp(called.name, "*SMBSERVER")) { 00794 make_nmb_name(&called , "*SMBSERVER", 0x20); 00795 goto again; 00796 } else { /* Try one more time, but ensure we don't loop */ 00797 00798 /* Only try this if server is an IP address ... */ 00799 00800 if (is_ipaddress(server) && !tried_reverse) { 00801 fstring remote_name; 00802 struct in_addr rem_ip; 00803 00804 if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { 00805 DEBUG(4, ("Could not convert IP address " 00806 "%s to struct in_addr\n", server)); 00807 errno = ETIMEDOUT; 00808 return NULL; 00809 } 00810 00811 tried_reverse++; /* Yuck */ 00812 00813 if (name_status_find("*", 0, 0, rem_ip, remote_name)) { 00814 make_nmb_name(&called, remote_name, 0x20); 00815 goto again; 00816 } 00817 } 00818 } 00819 errno = ETIMEDOUT; 00820 return NULL; 00821 } 00822 00823 DEBUG(4,(" session request ok\n")); 00824 00825 if (!cli_negprot(c)) { 00826 cli_shutdown(c); 00827 errno = ETIMEDOUT; 00828 return NULL; 00829 } 00830 00831 username_used = username; 00832 00833 if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, 00834 password, strlen(password), 00835 password, strlen(password), 00836 workgroup))) { 00837 00838 /* Failed. Try an anonymous login, if allowed by flags. */ 00839 username_used = ""; 00840 00841 if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || 00842 !NT_STATUS_IS_OK(cli_session_setup(c, username_used, 00843 password, 1, 00844 password, 0, 00845 workgroup))) { 00846 00847 cli_shutdown(c); 00848 errno = EPERM; 00849 return NULL; 00850 } 00851 } 00852 00853 DEBUG(4,(" session setup ok\n")); 00854 00855 if (!cli_send_tconX(c, share, "?????", 00856 password, strlen(password)+1)) { 00857 errno = smbc_errno(context, c); 00858 cli_shutdown(c); 00859 return NULL; 00860 } 00861 00862 DEBUG(4,(" tconx ok\n")); 00863 00864 /* 00865 * Ok, we have got a nice connection 00866 * Let's allocate a server structure. 00867 */ 00868 00869 srv = SMB_MALLOC_P(SMBCSRV); 00870 if (!srv) { 00871 errno = ENOMEM; 00872 goto failed; 00873 } 00874 00875 ZERO_STRUCTP(srv); 00876 srv->cli = c; 00877 srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); 00878 srv->no_pathinfo = False; 00879 srv->no_pathinfo2 = False; 00880 srv->no_nt_session = False; 00881 00882 /* now add it to the cache (internal or external) */ 00883 /* Let the cache function set errno if it wants to */ 00884 errno = 0; 00885 if ((context->callbacks.add_cached_srv_fn)(context, srv, 00886 server, share, 00887 workgroup, username)) { 00888 int saved_errno = errno; 00889 DEBUG(3, (" Failed to add server to cache\n")); 00890 errno = saved_errno; 00891 if (errno == 0) { 00892 errno = ENOMEM; 00893 } 00894 goto failed; 00895 } 00896 00897 DEBUG(2, ("Server connect ok: //%s/%s: %p\n", 00898 server, share, srv)); 00899 00900 DLIST_ADD(context->internal->_servers, srv); 00901 return srv; 00902 00903 failed: 00904 cli_shutdown(c); 00905 if (!srv) { 00906 return NULL; 00907 } 00908 00909 SAFE_FREE(srv); 00910 return NULL; 00911 }
static SMBCSRV* smbc_attr_server | ( | SMBCCTX * | context, | |
const char * | server, | |||
const char * | share, | |||
fstring | workgroup, | |||
fstring | username, | |||
fstring | password, | |||
POLICY_HND * | pol | |||
) | [static] |
libsmbclient.c の 918 行で定義されています。
参照先 smbc_internal_data::_auth_fn_with_context・smbc_internal_data::_servers・_SMBCCTX::_smbc_callbacks::add_cached_srv_fn・_SMBCCTX::_smbc_callbacks::auth_fn・_SMBCCTX::callbacks・_SMBCSRV::cli・cli_full_connection()・cli_rpc_pipe_open_noauth()・cli_shutdown()・errno・find_server()・_SMBCCTX::flags・flags・global_myname・_SMBCCTX::internal・cli_state::mem_ctx・nt_errstr()・pol・rpccli_lsa_open_policy()・smbc_errno()・zero_ip().
00925 { 00926 int flags; 00927 struct in_addr ip; 00928 struct cli_state *ipc_cli; 00929 struct rpc_pipe_client *pipe_hnd; 00930 NTSTATUS nt_status; 00931 SMBCSRV *ipc_srv=NULL; 00932 00933 /* 00934 * See if we've already created this special connection. Reference 00935 * our "special" share name '*IPC$', which is an impossible real share 00936 * name due to the leading asterisk. 00937 */ 00938 ipc_srv = find_server(context, server, "*IPC$", 00939 workgroup, username, password); 00940 if (!ipc_srv) { 00941 00942 /* We didn't find a cached connection. Get the password */ 00943 if (*password == '\0') { 00944 /* ... then retrieve it now. */ 00945 if (context->internal->_auth_fn_with_context != NULL) { 00946 (context->internal->_auth_fn_with_context)( 00947 context, 00948 server, share, 00949 workgroup, sizeof(fstring), 00950 username, sizeof(fstring), 00951 password, sizeof(fstring)); 00952 } else { 00953 (context->callbacks.auth_fn)( 00954 server, share, 00955 workgroup, sizeof(fstring), 00956 username, sizeof(fstring), 00957 password, sizeof(fstring)); 00958 } 00959 } 00960 00961 flags = 0; 00962 if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { 00963 flags |= CLI_FULL_CONNECTION_USE_KERBEROS; 00964 } 00965 00966 zero_ip(&ip); 00967 nt_status = cli_full_connection(&ipc_cli, 00968 global_myname(), server, 00969 &ip, 0, "IPC$", "?????", 00970 username, workgroup, 00971 password, flags, 00972 Undefined, NULL); 00973 if (! NT_STATUS_IS_OK(nt_status)) { 00974 DEBUG(1,("cli_full_connection failed! (%s)\n", 00975 nt_errstr(nt_status))); 00976 errno = ENOTSUP; 00977 return NULL; 00978 } 00979 00980 ipc_srv = SMB_MALLOC_P(SMBCSRV); 00981 if (!ipc_srv) { 00982 errno = ENOMEM; 00983 cli_shutdown(ipc_cli); 00984 return NULL; 00985 } 00986 00987 ZERO_STRUCTP(ipc_srv); 00988 ipc_srv->cli = ipc_cli; 00989 00990 if (pol) { 00991 pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, 00992 PI_LSARPC, 00993 &nt_status); 00994 if (!pipe_hnd) { 00995 DEBUG(1, ("cli_nt_session_open fail!\n")); 00996 errno = ENOTSUP; 00997 cli_shutdown(ipc_srv->cli); 00998 free(ipc_srv); 00999 return NULL; 01000 } 01001 01002 /* 01003 * Some systems don't support 01004 * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 01005 * so we might as well do it too. 01006 */ 01007 01008 nt_status = rpccli_lsa_open_policy( 01009 pipe_hnd, 01010 ipc_srv->cli->mem_ctx, 01011 True, 01012 GENERIC_EXECUTE_ACCESS, 01013 pol); 01014 01015 if (!NT_STATUS_IS_OK(nt_status)) { 01016 errno = smbc_errno(context, ipc_srv->cli); 01017 cli_shutdown(ipc_srv->cli); 01018 return NULL; 01019 } 01020 } 01021 01022 /* now add it to the cache (internal or external) */ 01023 01024 errno = 0; /* let cache function set errno if it likes */ 01025 if ((context->callbacks.add_cached_srv_fn)(context, ipc_srv, 01026 server, 01027 "*IPC$", 01028 workgroup, 01029 username)) { 01030 DEBUG(3, (" Failed to add server to cache\n")); 01031 if (errno == 0) { 01032 errno = ENOMEM; 01033 } 01034 cli_shutdown(ipc_srv->cli); 01035 free(ipc_srv); 01036 return NULL; 01037 } 01038 01039 DLIST_ADD(context->internal->_servers, ipc_srv); 01040 } 01041 01042 return ipc_srv; 01043 }
static SMBCFILE* smbc_open_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
int | flags, | |||
mode_t | mode | |||
) | [static] |
libsmbclient.c の 1050 行で定義されています。
参照先 smbc_internal_data::_files・smbc_internal_data::_initialized・smbc_internal_data::_share_mode・_SMBCSRV::cli・_SMBCFILE::cli_fd・cli_open()・cli_resolve_path()・d_printf()・errno・fd・_SMBCFILE::file・_SMBCFILE::fname・_SMBCCTX::internal・_SMBCFILE::offset・_SMBCCTX::opendir・password・server・share・smbc_close_ctx()・smbc_errno()・smbc_lseek_ctx()・smbc_parse_path()・smbc_server()・_SMBCFILE::srv・_SMBCCTX::user・workgroup.
参照元 smbc_creat_ctx()・smbc_new_context().
01054 { 01055 fstring server, share, user, password, workgroup; 01056 pstring path; 01057 pstring targetpath; 01058 struct cli_state *targetcli; 01059 SMBCSRV *srv = NULL; 01060 SMBCFILE *file = NULL; 01061 int fd; 01062 01063 if (!context || !context->internal || 01064 !context->internal->_initialized) { 01065 01066 errno = EINVAL; /* Best I can think of ... */ 01067 return NULL; 01068 01069 } 01070 01071 if (!fname) { 01072 01073 errno = EINVAL; 01074 return NULL; 01075 01076 } 01077 01078 if (smbc_parse_path(context, fname, 01079 workgroup, sizeof(workgroup), 01080 server, sizeof(server), 01081 share, sizeof(share), 01082 path, sizeof(path), 01083 user, sizeof(user), 01084 password, sizeof(password), 01085 NULL, 0)) { 01086 errno = EINVAL; 01087 return NULL; 01088 } 01089 01090 if (user[0] == (char)0) fstrcpy(user, context->user); 01091 01092 srv = smbc_server(context, True, 01093 server, share, workgroup, user, password); 01094 01095 if (!srv) { 01096 01097 if (errno == EPERM) errno = EACCES; 01098 return NULL; /* smbc_server sets errno */ 01099 01100 } 01101 01102 /* Hmmm, the test for a directory is suspect here ... FIXME */ 01103 01104 if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { 01105 01106 fd = -1; 01107 01108 } 01109 else { 01110 01111 file = SMB_MALLOC_P(SMBCFILE); 01112 01113 if (!file) { 01114 01115 errno = ENOMEM; 01116 return NULL; 01117 01118 } 01119 01120 ZERO_STRUCTP(file); 01121 01122 /*d_printf(">>>open: resolving %s\n", path);*/ 01123 if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) 01124 { 01125 d_printf("Could not resolve %s\n", path); 01126 SAFE_FREE(file); 01127 return NULL; 01128 } 01129 /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ 01130 01131 if ((fd = cli_open(targetcli, targetpath, flags, 01132 context->internal->_share_mode)) < 0) { 01133 01134 /* Handle the error ... */ 01135 01136 SAFE_FREE(file); 01137 errno = smbc_errno(context, targetcli); 01138 return NULL; 01139 01140 } 01141 01142 /* Fill in file struct */ 01143 01144 file->cli_fd = fd; 01145 file->fname = SMB_STRDUP(fname); 01146 file->srv = srv; 01147 file->offset = 0; 01148 file->file = True; 01149 01150 DLIST_ADD(context->internal->_files, file); 01151 01152 /* 01153 * If the file was opened in O_APPEND mode, all write 01154 * operations should be appended to the file. To do that, 01155 * though, using this protocol, would require a getattrE() 01156 * call for each and every write, to determine where the end 01157 * of the file is. (There does not appear to be an append flag 01158 * in the protocol.) Rather than add all of that overhead of 01159 * retrieving the current end-of-file offset prior to each 01160 * write operation, we'll assume that most append operations 01161 * will continuously write, so we'll just set the offset to 01162 * the end of the file now and hope that's adequate. 01163 * 01164 * Note to self: If this proves inadequate, and O_APPEND 01165 * should, in some cases, be forced for each write, add a 01166 * field in the context options structure, for 01167 * "strict_append_mode" which would select between the current 01168 * behavior (if FALSE) or issuing a getattrE() prior to each 01169 * write and forcing the write to the end of the file (if 01170 * TRUE). Adding that capability will likely require adding 01171 * an "append" flag into the _SMBCFILE structure to track 01172 * whether a file was opened in O_APPEND mode. -- djl 01173 */ 01174 if (flags & O_APPEND) { 01175 if (smbc_lseek_ctx(context, file, 0, SEEK_END) < 0) { 01176 (void) smbc_close_ctx(context, file); 01177 errno = ENXIO; 01178 return NULL; 01179 } 01180 } 01181 01182 return file; 01183 01184 } 01185 01186 /* Check if opendir needed ... */ 01187 01188 if (fd == -1) { 01189 int eno = 0; 01190 01191 eno = smbc_errno(context, srv->cli); 01192 file = (context->opendir)(context, fname); 01193 if (!file) errno = eno; 01194 return file; 01195 01196 } 01197 01198 errno = EINVAL; /* FIXME, correct errno ? */ 01199 return NULL; 01200 01201 }
libsmbclient.c の 1210 行で定義されています。
参照先 smbc_internal_data::_initialized・creat_bits・errno・_SMBCCTX::internal・smbc_open_ctx().
参照元 smbc_new_context().
01213 { 01214 01215 if (!context || !context->internal || 01216 !context->internal->_initialized) { 01217 01218 errno = EINVAL; 01219 return NULL; 01220 01221 } 01222 01223 return smbc_open_ctx(context, path, creat_bits, mode); 01224 }
static ssize_t smbc_read_ctx | ( | SMBCCTX * | context, | |
SMBCFILE * | file, | |||
void * | buf, | |||
size_t | count | |||
) | [static] |
libsmbclient.c の 1231 行で定義されています。
参照先 smbc_internal_data::_files・smbc_internal_data::_initialized・_SMBCSRV::cli・_SMBCFILE::cli_fd・cli_read()・cli_resolve_path()・d_printf()・DLIST_CONTAINS()・errno・_SMBCFILE::fname・_SMBCCTX::internal・_SMBCFILE::offset・password・server・share・smbc_errno()・smbc_parse_path()・_SMBCFILE::srv.
参照元 smbc_new_context().
01235 { 01236 int ret; 01237 fstring server, share, user, password; 01238 pstring path, targetpath; 01239 struct cli_state *targetcli; 01240 01241 /* 01242 * offset: 01243 * 01244 * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) -- 01245 * appears to pass file->offset (which is type off_t) differently than 01246 * a local variable of type off_t. Using local variable "offset" in 01247 * the call to cli_read() instead of file->offset fixes a problem 01248 * retrieving data at an offset greater than 4GB. 01249 */ 01250 off_t offset; 01251 01252 if (!context || !context->internal || 01253 !context->internal->_initialized) { 01254 01255 errno = EINVAL; 01256 return -1; 01257 01258 } 01259 01260 DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); 01261 01262 if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { 01263 01264 errno = EBADF; 01265 return -1; 01266 01267 } 01268 01269 offset = file->offset; 01270 01271 /* Check that the buffer exists ... */ 01272 01273 if (buf == NULL) { 01274 01275 errno = EINVAL; 01276 return -1; 01277 01278 } 01279 01280 /*d_printf(">>>read: parsing %s\n", file->fname);*/ 01281 if (smbc_parse_path(context, file->fname, 01282 NULL, 0, 01283 server, sizeof(server), 01284 share, sizeof(share), 01285 path, sizeof(path), 01286 user, sizeof(user), 01287 password, sizeof(password), 01288 NULL, 0)) { 01289 errno = EINVAL; 01290 return -1; 01291 } 01292 01293 /*d_printf(">>>read: resolving %s\n", path);*/ 01294 if (!cli_resolve_path("", file->srv->cli, path, 01295 &targetcli, targetpath)) 01296 { 01297 d_printf("Could not resolve %s\n", path); 01298 return -1; 01299 } 01300 /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ 01301 01302 ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); 01303 01304 if (ret < 0) { 01305 01306 errno = smbc_errno(context, targetcli); 01307 return -1; 01308 01309 } 01310 01311 file->offset += ret; 01312 01313 DEBUG(4, (" --> %d\n", ret)); 01314 01315 return ret; /* Success, ret bytes of data ... */ 01316 01317 }
static ssize_t smbc_write_ctx | ( | SMBCCTX * | context, | |
SMBCFILE * | file, | |||
void * | buf, | |||
size_t | count | |||
) | [static] |
libsmbclient.c の 1324 行で定義されています。
参照先 smbc_internal_data::_files・smbc_internal_data::_initialized・_SMBCSRV::cli・_SMBCFILE::cli_fd・cli_resolve_path()・cli_write()・d_printf()・DLIST_CONTAINS()・errno・_SMBCFILE::fname・_SMBCCTX::internal・_SMBCFILE::offset・password・server・share・smbc_errno()・smbc_parse_path()・_SMBCFILE::srv.
参照元 smbc_new_context().
01328 { 01329 int ret; 01330 off_t offset; 01331 fstring server, share, user, password; 01332 pstring path, targetpath; 01333 struct cli_state *targetcli; 01334 01335 /* First check all pointers before dereferencing them */ 01336 01337 if (!context || !context->internal || 01338 !context->internal->_initialized) { 01339 01340 errno = EINVAL; 01341 return -1; 01342 01343 } 01344 01345 if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { 01346 01347 errno = EBADF; 01348 return -1; 01349 01350 } 01351 01352 /* Check that the buffer exists ... */ 01353 01354 if (buf == NULL) { 01355 01356 errno = EINVAL; 01357 return -1; 01358 01359 } 01360 01361 offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ 01362 01363 /*d_printf(">>>write: parsing %s\n", file->fname);*/ 01364 if (smbc_parse_path(context, file->fname, 01365 NULL, 0, 01366 server, sizeof(server), 01367 share, sizeof(share), 01368 path, sizeof(path), 01369 user, sizeof(user), 01370 password, sizeof(password), 01371 NULL, 0)) { 01372 errno = EINVAL; 01373 return -1; 01374 } 01375 01376 /*d_printf(">>>write: resolving %s\n", path);*/ 01377 if (!cli_resolve_path("", file->srv->cli, path, 01378 &targetcli, targetpath)) 01379 { 01380 d_printf("Could not resolve %s\n", path); 01381 return -1; 01382 } 01383 /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ 01384 01385 01386 ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); 01387 01388 if (ret <= 0) { 01389 01390 errno = smbc_errno(context, targetcli); 01391 return -1; 01392 01393 } 01394 01395 file->offset += ret; 01396 01397 return ret; /* Success, 0 bytes of data ... */ 01398 }
static BOOL smbc_getatr | ( | SMBCCTX * | context, | |
SMBCSRV * | srv, | |||
char * | path, | |||
uint16 * | mode, | |||
SMB_OFF_T * | size, | |||
struct timespec * | create_time_ts, | |||
struct timespec * | access_time_ts, | |||
struct timespec * | write_time_ts, | |||
struct timespec * | change_time_ts, | |||
SMB_INO_T * | ino | |||
) | [static] |
libsmbclient.c の 1486 行で定義されています。
参照先 smbc_internal_data::_initialized・cli_state::capabilities・_SMBCSRV::cli・cli_getatr()・cli_qpathinfo2()・cli_resolve_path()・convert_time_t_to_timespec()・d_printf()・errno・_SMBCCTX::internal・_SMBCSRV::no_pathinfo2・strequal()・trim_string().
参照元 cacl_get()・dos_attr_query()・smbc_opendir_ctx()・smbc_stat_ctx()・smbc_unlink_ctx().
01496 { 01497 pstring fixedpath; 01498 pstring targetpath; 01499 struct cli_state *targetcli; 01500 time_t write_time; 01501 01502 if (!context || !context->internal || 01503 !context->internal->_initialized) { 01504 01505 errno = EINVAL; 01506 return -1; 01507 01508 } 01509 01510 /* path fixup for . and .. */ 01511 if (strequal(path, ".") || strequal(path, "..")) 01512 pstrcpy(fixedpath, "\\"); 01513 else 01514 { 01515 pstrcpy(fixedpath, path); 01516 trim_string(fixedpath, NULL, "\\.."); 01517 trim_string(fixedpath, NULL, "\\."); 01518 } 01519 DEBUG(4,("smbc_getatr: sending qpathinfo\n")); 01520 01521 if (!cli_resolve_path( "", srv->cli, fixedpath, &targetcli, targetpath)) 01522 { 01523 d_printf("Couldn't resolve %s\n", path); 01524 return False; 01525 } 01526 01527 if (!srv->no_pathinfo2 && 01528 cli_qpathinfo2(targetcli, targetpath, 01529 create_time_ts, 01530 access_time_ts, 01531 write_time_ts, 01532 change_time_ts, 01533 size, mode, ino)) { 01534 return True; 01535 } 01536 01537 /* if this is NT then don't bother with the getatr */ 01538 if (targetcli->capabilities & CAP_NT_SMBS) { 01539 errno = EPERM; 01540 return False; 01541 } 01542 01543 if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) { 01544 01545 struct timespec w_time_ts; 01546 01547 w_time_ts = convert_time_t_to_timespec(write_time); 01548 01549 if (write_time_ts != NULL) { 01550 *write_time_ts = w_time_ts; 01551 } 01552 01553 if (create_time_ts != NULL) { 01554 *create_time_ts = w_time_ts; 01555 } 01556 01557 if (access_time_ts != NULL) { 01558 *access_time_ts = w_time_ts; 01559 } 01560 01561 if (change_time_ts != NULL) { 01562 *change_time_ts = w_time_ts; 01563 } 01564 01565 srv->no_pathinfo2 = True; 01566 return True; 01567 } 01568 01569 errno = EPERM; 01570 return False; 01571 01572 }
static BOOL smbc_setatr | ( | SMBCCTX * | context, | |
SMBCSRV * | srv, | |||
char * | path, | |||
time_t | create_time, | |||
time_t | access_time, | |||
time_t | write_time, | |||
time_t | change_time, | |||
uint16 | mode | |||
) | [static] |
libsmbclient.c の 1585 行で定義されています。
参照先 _SMBCSRV::cli・cli_close()・cli_open()・cli_setatr()・cli_setattrE()・cli_setpathinfo()・errno・fd・_SMBCSRV::no_pathinfo・smbc_errno().
参照元 smbc_setxattr_ctx()・smbc_utimes_ctx().
01591 { 01592 int fd; 01593 int ret; 01594 01595 /* 01596 * First, try setpathinfo (if qpathinfo succeeded), for it is the 01597 * modern function for "new code" to be using, and it works given a 01598 * filename rather than requiring that the file be opened to have its 01599 * attributes manipulated. 01600 */ 01601 if (srv->no_pathinfo || 01602 ! cli_setpathinfo(srv->cli, path, 01603 create_time, 01604 access_time, 01605 write_time, 01606 change_time, 01607 mode)) { 01608 01609 /* 01610 * setpathinfo is not supported; go to plan B. 01611 * 01612 * cli_setatr() does not work on win98, and it also doesn't 01613 * support setting the access time (only the modification 01614 * time), so in all cases, we open the specified file and use 01615 * cli_setattrE() which should work on all OS versions, and 01616 * supports both times. 01617 */ 01618 01619 /* Don't try {q,set}pathinfo() again, with this server */ 01620 srv->no_pathinfo = True; 01621 01622 /* Open the file */ 01623 if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { 01624 01625 errno = smbc_errno(context, srv->cli); 01626 return -1; 01627 } 01628 01629 /* Set the new attributes */ 01630 ret = cli_setattrE(srv->cli, fd, 01631 change_time, 01632 access_time, 01633 write_time); 01634 01635 /* Close the file */ 01636 cli_close(srv->cli, fd); 01637 01638 /* 01639 * Unfortunately, setattrE() doesn't have a provision for 01640 * setting the access mode (attributes). We'll have to try 01641 * cli_setatr() for that, and with only this parameter, it 01642 * seems to work on win98. 01643 */ 01644 if (ret && mode != (uint16) -1) { 01645 ret = cli_setatr(srv->cli, path, mode, 0); 01646 } 01647 01648 if (! ret) { 01649 errno = smbc_errno(context, srv->cli); 01650 return False; 01651 } 01652 } 01653 01654 return True; 01655 }
static int smbc_unlink_ctx | ( | SMBCCTX * | context, | |
const char * | fname | |||
) | [static] |
libsmbclient.c の 1662 行で定義されています。
参照先 smbc_internal_data::_initialized・_SMBCSRV::cli・cli_resolve_path()・cli_unlink()・d_printf()・errno・_SMBCCTX::internal・mode・password・server・share・size・smbc_errno()・smbc_getatr()・smbc_parse_path()・smbc_server()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
01664 { 01665 fstring server, share, user, password, workgroup; 01666 pstring path, targetpath; 01667 struct cli_state *targetcli; 01668 SMBCSRV *srv = NULL; 01669 01670 if (!context || !context->internal || 01671 !context->internal->_initialized) { 01672 01673 errno = EINVAL; /* Best I can think of ... */ 01674 return -1; 01675 01676 } 01677 01678 if (!fname) { 01679 01680 errno = EINVAL; 01681 return -1; 01682 01683 } 01684 01685 if (smbc_parse_path(context, fname, 01686 workgroup, sizeof(workgroup), 01687 server, sizeof(server), 01688 share, sizeof(share), 01689 path, sizeof(path), 01690 user, sizeof(user), 01691 password, sizeof(password), 01692 NULL, 0)) { 01693 errno = EINVAL; 01694 return -1; 01695 } 01696 01697 if (user[0] == (char)0) fstrcpy(user, context->user); 01698 01699 srv = smbc_server(context, True, 01700 server, share, workgroup, user, password); 01701 01702 if (!srv) { 01703 01704 return -1; /* smbc_server sets errno */ 01705 01706 } 01707 01708 /*d_printf(">>>unlink: resolving %s\n", path);*/ 01709 if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) 01710 { 01711 d_printf("Could not resolve %s\n", path); 01712 return -1; 01713 } 01714 /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ 01715 01716 if (!cli_unlink(targetcli, targetpath)) { 01717 01718 errno = smbc_errno(context, targetcli); 01719 01720 if (errno == EACCES) { /* Check if the file is a directory */ 01721 01722 int saverr = errno; 01723 SMB_OFF_T size = 0; 01724 uint16 mode = 0; 01725 struct timespec write_time_ts; 01726 struct timespec access_time_ts; 01727 struct timespec change_time_ts; 01728 SMB_INO_T ino = 0; 01729 01730 if (!smbc_getatr(context, srv, path, &mode, &size, 01731 NULL, 01732 &access_time_ts, 01733 &write_time_ts, 01734 &change_time_ts, 01735 &ino)) { 01736 01737 /* Hmmm, bad error ... What? */ 01738 01739 errno = smbc_errno(context, targetcli); 01740 return -1; 01741 01742 } 01743 else { 01744 01745 if (IS_DOS_DIR(mode)) 01746 errno = EISDIR; 01747 else 01748 errno = saverr; /* Restore this */ 01749 01750 } 01751 } 01752 01753 return -1; 01754 01755 } 01756 01757 return 0; /* Success ... */ 01758 01759 }
static int smbc_rename_ctx | ( | SMBCCTX * | ocontext, | |
const char * | oname, | |||
SMBCCTX * | ncontext, | |||
const char * | nname | |||
) | [static] |
libsmbclient.c の 1766 行で定義されています。
参照先 smbc_internal_data::_initialized・_SMBCSRV::cli・cli_rename()・cli_resolve_path()・cli_unlink()・d_printf()・cli_state::desthost・errno・_SMBCCTX::internal・cli_state::share・smbc_errno()・smbc_parse_path()・smbc_server()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
01770 { 01771 fstring server1; 01772 fstring share1; 01773 fstring server2; 01774 fstring share2; 01775 fstring user1; 01776 fstring user2; 01777 fstring password1; 01778 fstring password2; 01779 fstring workgroup; 01780 pstring path1; 01781 pstring path2; 01782 pstring targetpath1; 01783 pstring targetpath2; 01784 struct cli_state *targetcli1; 01785 struct cli_state *targetcli2; 01786 SMBCSRV *srv = NULL; 01787 01788 if (!ocontext || !ncontext || 01789 !ocontext->internal || !ncontext->internal || 01790 !ocontext->internal->_initialized || 01791 !ncontext->internal->_initialized) { 01792 01793 errno = EINVAL; /* Best I can think of ... */ 01794 return -1; 01795 01796 } 01797 01798 if (!oname || !nname) { 01799 01800 errno = EINVAL; 01801 return -1; 01802 01803 } 01804 01805 DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); 01806 01807 smbc_parse_path(ocontext, oname, 01808 workgroup, sizeof(workgroup), 01809 server1, sizeof(server1), 01810 share1, sizeof(share1), 01811 path1, sizeof(path1), 01812 user1, sizeof(user1), 01813 password1, sizeof(password1), 01814 NULL, 0); 01815 01816 if (user1[0] == (char)0) fstrcpy(user1, ocontext->user); 01817 01818 smbc_parse_path(ncontext, nname, 01819 NULL, 0, 01820 server2, sizeof(server2), 01821 share2, sizeof(share2), 01822 path2, sizeof(path2), 01823 user2, sizeof(user2), 01824 password2, sizeof(password2), 01825 NULL, 0); 01826 01827 if (user2[0] == (char)0) fstrcpy(user2, ncontext->user); 01828 01829 if (strcmp(server1, server2) || strcmp(share1, share2) || 01830 strcmp(user1, user2)) { 01831 01832 /* Can't rename across file systems, or users?? */ 01833 01834 errno = EXDEV; 01835 return -1; 01836 01837 } 01838 01839 srv = smbc_server(ocontext, True, 01840 server1, share1, workgroup, user1, password1); 01841 if (!srv) { 01842 01843 return -1; 01844 01845 } 01846 01847 /*d_printf(">>>rename: resolving %s\n", path1);*/ 01848 if (!cli_resolve_path( "", srv->cli, path1, &targetcli1, targetpath1)) 01849 { 01850 d_printf("Could not resolve %s\n", path1); 01851 return -1; 01852 } 01853 /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ 01854 /*d_printf(">>>rename: resolving %s\n", path2);*/ 01855 if (!cli_resolve_path( "", srv->cli, path2, &targetcli2, targetpath2)) 01856 { 01857 d_printf("Could not resolve %s\n", path2); 01858 return -1; 01859 } 01860 /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ 01861 01862 if (strcmp(targetcli1->desthost, targetcli2->desthost) || 01863 strcmp(targetcli1->share, targetcli2->share)) 01864 { 01865 /* can't rename across file systems */ 01866 01867 errno = EXDEV; 01868 return -1; 01869 } 01870 01871 if (!cli_rename(targetcli1, targetpath1, targetpath2)) { 01872 int eno = smbc_errno(ocontext, targetcli1); 01873 01874 if (eno != EEXIST || 01875 !cli_unlink(targetcli1, targetpath2) || 01876 !cli_rename(targetcli1, targetpath1, targetpath2)) { 01877 01878 errno = eno; 01879 return -1; 01880 01881 } 01882 } 01883 01884 return 0; /* Success */ 01885 01886 }
static ino_t smbc_inode | ( | SMBCCTX * | context, | |
const char * | name | |||
) | [static] |
libsmbclient.c の 1988 行で定義されています。
参照先 smbc_internal_data::_initialized・errno・_SMBCCTX::internal・str_checksum().
参照元 smbc_setup_stat().
01990 { 01991 01992 if (!context || !context->internal || 01993 !context->internal->_initialized) { 01994 01995 errno = EINVAL; 01996 return -1; 01997 01998 } 01999 02000 if (!*name) return 2; /* FIXME, why 2 ??? */ 02001 return (ino_t)str_checksum(name); 02002 02003 }
static int smbc_setup_stat | ( | SMBCCTX * | context, | |
struct stat * | st, | |||
char * | fname, | |||
SMB_OFF_T | size, | |||
int | mode | |||
) | [static] |
libsmbclient.c の 2011 行で定義されています。
参照先 smbc_inode().
参照元 smbc_fstat_ctx()・smbc_stat_ctx().
02016 { 02017 02018 st->st_mode = 0; 02019 02020 if (IS_DOS_DIR(mode)) { 02021 st->st_mode = SMBC_DIR_MODE; 02022 } else { 02023 st->st_mode = SMBC_FILE_MODE; 02024 } 02025 02026 if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; 02027 if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; 02028 if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; 02029 if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; 02030 02031 st->st_size = size; 02032 #ifdef HAVE_STAT_ST_BLKSIZE 02033 st->st_blksize = 512; 02034 #endif 02035 #ifdef HAVE_STAT_ST_BLOCKS 02036 st->st_blocks = (size+511)/512; 02037 #endif 02038 st->st_uid = getuid(); 02039 st->st_gid = getgid(); 02040 02041 if (IS_DOS_DIR(mode)) { 02042 st->st_nlink = 2; 02043 } else { 02044 st->st_nlink = 1; 02045 } 02046 02047 if (st->st_ino == 0) { 02048 st->st_ino = smbc_inode(context, fname); 02049 } 02050 02051 return True; /* FIXME: Is this needed ? */ 02052 02053 }
static int smbc_stat_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
struct stat * | st | |||
) | [static] |
libsmbclient.c の 2060 行で定義されています。
参照先 smbc_internal_data::_initialized・_SMBCSRV::cli・_SMBCSRV::dev・errno・_SMBCCTX::internal・mode・password・server・set_atimespec()・set_ctimespec()・set_mtimespec()・share・size・smbc_errno()・smbc_getatr()・smbc_parse_path()・smbc_server()・smbc_setup_stat()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
02063 { 02064 SMBCSRV *srv; 02065 fstring server; 02066 fstring share; 02067 fstring user; 02068 fstring password; 02069 fstring workgroup; 02070 pstring path; 02071 struct timespec write_time_ts; 02072 struct timespec access_time_ts; 02073 struct timespec change_time_ts; 02074 SMB_OFF_T size = 0; 02075 uint16 mode = 0; 02076 SMB_INO_T ino = 0; 02077 02078 if (!context || !context->internal || 02079 !context->internal->_initialized) { 02080 02081 errno = EINVAL; /* Best I can think of ... */ 02082 return -1; 02083 02084 } 02085 02086 if (!fname) { 02087 02088 errno = EINVAL; 02089 return -1; 02090 02091 } 02092 02093 DEBUG(4, ("smbc_stat(%s)\n", fname)); 02094 02095 if (smbc_parse_path(context, fname, 02096 workgroup, sizeof(workgroup), 02097 server, sizeof(server), 02098 share, sizeof(share), 02099 path, sizeof(path), 02100 user, sizeof(user), 02101 password, sizeof(password), 02102 NULL, 0)) { 02103 errno = EINVAL; 02104 return -1; 02105 } 02106 02107 if (user[0] == (char)0) fstrcpy(user, context->user); 02108 02109 srv = smbc_server(context, True, 02110 server, share, workgroup, user, password); 02111 02112 if (!srv) { 02113 return -1; /* errno set by smbc_server */ 02114 } 02115 02116 if (!smbc_getatr(context, srv, path, &mode, &size, 02117 NULL, 02118 &access_time_ts, 02119 &write_time_ts, 02120 &change_time_ts, 02121 &ino)) { 02122 02123 errno = smbc_errno(context, srv->cli); 02124 return -1; 02125 02126 } 02127 02128 st->st_ino = ino; 02129 02130 smbc_setup_stat(context, st, path, size, mode); 02131 02132 set_atimespec(st, access_time_ts); 02133 set_ctimespec(st, change_time_ts); 02134 set_mtimespec(st, write_time_ts); 02135 st->st_dev = srv->dev; 02136 02137 return 0; 02138 02139 }
libsmbclient.c の 2146 行で定義されています。
参照先 smbc_internal_data::_files・smbc_internal_data::_initialized・_SMBCSRV::cli・_SMBCFILE::cli_fd・cli_getattrE()・cli_qfileinfo()・cli_resolve_path()・convert_time_t_to_timespec()・d_printf()・_SMBCSRV::dev・DLIST_CONTAINS()・errno・_SMBCFILE::file・_SMBCFILE::fname・_SMBCCTX::fstatdir・_SMBCCTX::internal・mode・password・server・set_atimespec()・set_ctimespec()・set_mtimespec()・share・size・smbc_parse_path()・smbc_setup_stat()・_SMBCFILE::srv.
参照元 smbc_new_context().
02149 { 02150 struct timespec change_time_ts; 02151 struct timespec access_time_ts; 02152 struct timespec write_time_ts; 02153 SMB_OFF_T size; 02154 uint16 mode; 02155 fstring server; 02156 fstring share; 02157 fstring user; 02158 fstring password; 02159 pstring path; 02160 pstring targetpath; 02161 struct cli_state *targetcli; 02162 SMB_INO_T ino = 0; 02163 02164 if (!context || !context->internal || 02165 !context->internal->_initialized) { 02166 02167 errno = EINVAL; 02168 return -1; 02169 02170 } 02171 02172 if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { 02173 02174 errno = EBADF; 02175 return -1; 02176 02177 } 02178 02179 if (!file->file) { 02180 02181 return (context->fstatdir)(context, file, st); 02182 02183 } 02184 02185 /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ 02186 if (smbc_parse_path(context, file->fname, 02187 NULL, 0, 02188 server, sizeof(server), 02189 share, sizeof(share), 02190 path, sizeof(path), 02191 user, sizeof(user), 02192 password, sizeof(password), 02193 NULL, 0)) { 02194 errno = EINVAL; 02195 return -1; 02196 } 02197 02198 /*d_printf(">>>fstat: resolving %s\n", path);*/ 02199 if (!cli_resolve_path("", file->srv->cli, path, 02200 &targetcli, targetpath)) 02201 { 02202 d_printf("Could not resolve %s\n", path); 02203 return -1; 02204 } 02205 /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ 02206 02207 if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, 02208 NULL, 02209 &access_time_ts, 02210 &write_time_ts, 02211 &change_time_ts, 02212 &ino)) { 02213 02214 time_t change_time, access_time, write_time; 02215 02216 if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, 02217 &change_time, &access_time, &write_time)) { 02218 02219 errno = EINVAL; 02220 return -1; 02221 } 02222 02223 change_time_ts = convert_time_t_to_timespec(change_time); 02224 access_time_ts = convert_time_t_to_timespec(access_time); 02225 write_time_ts = convert_time_t_to_timespec(write_time); 02226 } 02227 02228 st->st_ino = ino; 02229 02230 smbc_setup_stat(context, st, file->fname, size, mode); 02231 02232 set_atimespec(st, access_time_ts); 02233 set_ctimespec(st, change_time_ts); 02234 set_mtimespec(st, write_time_ts); 02235 st->st_dev = file->srv->dev; 02236 02237 return 0; 02238 02239 }
static void smbc_remove_dir | ( | SMBCFILE * | dir | ) | [static] |
libsmbclient.c の 2247 行で定義されています。
参照先 _SMBCFILE::dir_end・_SMBCFILE::dir_list・_SMBCFILE::dir_next・smbc_dir_list::dirent・smbc_dir_list::next.
参照元 smbc_closedir_ctx().
02248 { 02249 struct smbc_dir_list *d,*f; 02250 02251 d = dir->dir_list; 02252 while (d) { 02253 02254 f = d; d = d->next; 02255 02256 SAFE_FREE(f->dirent); 02257 SAFE_FREE(f); 02258 02259 } 02260 02261 dir->dir_list = dir->dir_end = dir->dir_next = NULL; 02262 02263 }
static int add_dirent | ( | SMBCFILE * | dir, | |
const char * | name, | |||
const char * | comment, | |||
uint32 | type | |||
) | [static] |
libsmbclient.c の 2266 行で定義されています。
参照先 smbc_dirent::commentlen・_SMBCFILE::dir_end・_SMBCFILE::dir_error・_SMBCFILE::dir_list・_SMBCFILE::dir_next・smbc_dir_list::dirent・smbc_dirent::dirlen・smbc_dir_list::next・size・smbc_dirent::smbc_type.
参照元 dir_list_fn()・list_fn()・list_unique_wg_fn().
02270 { 02271 struct smbc_dirent *dirent; 02272 int size; 02273 int name_length = (name == NULL ? 0 : strlen(name)); 02274 int comment_len = (comment == NULL ? 0 : strlen(comment)); 02275 02276 /* 02277 * Allocate space for the dirent, which must be increased by the 02278 * size of the name and the comment and 1 each for the null terminator. 02279 */ 02280 02281 size = sizeof(struct smbc_dirent) + name_length + comment_len + 2; 02282 02283 dirent = (struct smbc_dirent *)SMB_MALLOC(size); 02284 02285 if (!dirent) { 02286 02287 dir->dir_error = ENOMEM; 02288 return -1; 02289 02290 } 02291 02292 ZERO_STRUCTP(dirent); 02293 02294 if (dir->dir_list == NULL) { 02295 02296 dir->dir_list = SMB_MALLOC_P(struct smbc_dir_list); 02297 if (!dir->dir_list) { 02298 02299 SAFE_FREE(dirent); 02300 dir->dir_error = ENOMEM; 02301 return -1; 02302 02303 } 02304 ZERO_STRUCTP(dir->dir_list); 02305 02306 dir->dir_end = dir->dir_next = dir->dir_list; 02307 } 02308 else { 02309 02310 dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list); 02311 02312 if (!dir->dir_end->next) { 02313 02314 SAFE_FREE(dirent); 02315 dir->dir_error = ENOMEM; 02316 return -1; 02317 02318 } 02319 ZERO_STRUCTP(dir->dir_end->next); 02320 02321 dir->dir_end = dir->dir_end->next; 02322 } 02323 02324 dir->dir_end->next = NULL; 02325 dir->dir_end->dirent = dirent; 02326 02327 dirent->smbc_type = type; 02328 dirent->namelen = name_length; 02329 dirent->commentlen = comment_len; 02330 dirent->dirlen = size; 02331 02332 /* 02333 * dirent->namelen + 1 includes the null (no null termination needed) 02334 * Ditto for dirent->commentlen. 02335 * The space for the two null bytes was allocated. 02336 */ 02337 strncpy(dirent->name, (name?name:""), dirent->namelen + 1); 02338 dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); 02339 strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); 02340 02341 return 0; 02342 02343 }
static void list_unique_wg_fn | ( | const char * | name, | |
uint32 | type, | |||
const char * | comment, | |||
void * | state | |||
) | [static] |
libsmbclient.c の 2346 行で定義されています。
参照先 add_dirent()・_SMBCFILE::dir_end・_SMBCFILE::dir_list・_SMBCFILE::dir_type・smbc_dir_list::dirent・smbc_dirent::name・smbc_dir_list::next.
参照元 smbc_opendir_ctx().
02350 { 02351 SMBCFILE *dir = (SMBCFILE *)state; 02352 struct smbc_dir_list *dir_list; 02353 struct smbc_dirent *dirent; 02354 int dirent_type; 02355 int do_remove = 0; 02356 02357 dirent_type = dir->dir_type; 02358 02359 if (add_dirent(dir, name, comment, dirent_type) < 0) { 02360 02361 /* An error occurred, what do we do? */ 02362 /* FIXME: Add some code here */ 02363 } 02364 02365 /* Point to the one just added */ 02366 dirent = dir->dir_end->dirent; 02367 02368 /* See if this was a duplicate */ 02369 for (dir_list = dir->dir_list; 02370 dir_list != dir->dir_end; 02371 dir_list = dir_list->next) { 02372 if (! do_remove && 02373 strcmp(dir_list->dirent->name, dirent->name) == 0) { 02374 /* Duplicate. End end of list need to be removed. */ 02375 do_remove = 1; 02376 } 02377 02378 if (do_remove && dir_list->next == dir->dir_end) { 02379 /* Found the end of the list. Remove it. */ 02380 dir->dir_end = dir_list; 02381 free(dir_list->next); 02382 free(dirent); 02383 dir_list->next = NULL; 02384 break; 02385 } 02386 } 02387 }
static void list_fn | ( | const char * | name, | |
uint32 | type, | |||
const char * | comment, | |||
void * | state | |||
) | [static] |
libsmbclient.c の 2390 行で定義されています。
参照先 add_dirent()・_SMBCFILE::dir_type.
参照元 run_dirtest()・run_dirtest1()・smbc_opendir_ctx().
02394 { 02395 SMBCFILE *dir = (SMBCFILE *)state; 02396 int dirent_type; 02397 02398 /* 02399 * We need to process the type a little ... 02400 * 02401 * Disk share = 0x00000000 02402 * Print share = 0x00000001 02403 * Comms share = 0x00000002 (obsolete?) 02404 * IPC$ share = 0x00000003 02405 * 02406 * administrative shares: 02407 * ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000 02408 */ 02409 02410 if (dir->dir_type == SMBC_FILE_SHARE) { 02411 02412 switch (type) { 02413 case 0 | 0x80000000: 02414 case 0: 02415 dirent_type = SMBC_FILE_SHARE; 02416 break; 02417 02418 case 1: 02419 dirent_type = SMBC_PRINTER_SHARE; 02420 break; 02421 02422 case 2: 02423 dirent_type = SMBC_COMMS_SHARE; 02424 break; 02425 02426 case 3 | 0x80000000: 02427 case 3: 02428 dirent_type = SMBC_IPC_SHARE; 02429 break; 02430 02431 default: 02432 dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ 02433 break; 02434 } 02435 } 02436 else { 02437 dirent_type = dir->dir_type; 02438 } 02439 02440 if (add_dirent(dir, name, comment, dirent_type) < 0) { 02441 02442 /* An error occurred, what do we do? */ 02443 /* FIXME: Add some code here */ 02444 02445 } 02446 }
static void dir_list_fn | ( | const char * | mnt, | |
file_info * | finfo, | |||
const char * | mask, | |||
void * | state | |||
) | [static] |
libsmbclient.c の 2449 行で定義されています。
参照先 add_dirent()・file_info::mode・file_info::name.
参照元 smbc_opendir_ctx().
02453 { 02454 02455 if (add_dirent((SMBCFILE *)state, finfo->name, "", 02456 (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { 02457 02458 /* Handle an error ... */ 02459 02460 /* FIXME: Add some code ... */ 02461 02462 } 02463 02464 }
static int net_share_enum_rpc | ( | struct cli_state * | cli, | |
void(*)(const char *name, uint32 type, const char *comment, void *state) | fn, | |||
void * | state | |||
) | [static] |
libsmbclient.c の 2467 行で定義されています。
参照先 cli・cli_rpc_pipe_close()・cli_rpc_pipe_open_noauth()・srv_share_info_ctr_info::info1・share_info_1_info::info_1・share_info_1_info::info_1_str・init_enum_hnd()・srv_share_info_ctr_info::num_entries・result・rpccli_srvsvc_net_share_enum()・rpcstr_pull_unistr2_fstring()・srv_share_info_ctr_info::share・talloc_init()・ptr_share_info1::type・str_share_info1::uni_netname・str_share_info1::uni_remark.
参照元 smbc_opendir_ctx().
02473 { 02474 int i; 02475 WERROR result; 02476 ENUM_HND enum_hnd; 02477 uint32 info_level = 1; 02478 uint32 preferred_len = 0xffffffff; 02479 uint32 type; 02480 SRV_SHARE_INFO_CTR ctr; 02481 fstring name = ""; 02482 fstring comment = ""; 02483 void *mem_ctx; 02484 struct rpc_pipe_client *pipe_hnd; 02485 NTSTATUS nt_status; 02486 02487 /* Open the server service pipe */ 02488 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); 02489 if (!pipe_hnd) { 02490 DEBUG(1, ("net_share_enum_rpc pipe open fail!\n")); 02491 return -1; 02492 } 02493 02494 /* Allocate a context for parsing and for the entries in "ctr" */ 02495 mem_ctx = talloc_init("libsmbclient: net_share_enum_rpc"); 02496 if (mem_ctx == NULL) { 02497 DEBUG(0, ("out of memory for net_share_enum_rpc!\n")); 02498 cli_rpc_pipe_close(pipe_hnd); 02499 return -1; 02500 } 02501 02502 /* Issue the NetShareEnum RPC call and retrieve the response */ 02503 init_enum_hnd(&enum_hnd, 0); 02504 result = rpccli_srvsvc_net_share_enum(pipe_hnd, 02505 mem_ctx, 02506 info_level, 02507 &ctr, 02508 preferred_len, 02509 &enum_hnd); 02510 02511 /* Was it successful? */ 02512 if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { 02513 /* Nope. Go clean up. */ 02514 goto done; 02515 } 02516 02517 /* For each returned entry... */ 02518 for (i = 0; i < ctr.num_entries; i++) { 02519 02520 /* pull out the share name */ 02521 rpcstr_pull_unistr2_fstring( 02522 name, &ctr.share.info1[i].info_1_str.uni_netname); 02523 02524 /* pull out the share's comment */ 02525 rpcstr_pull_unistr2_fstring( 02526 comment, &ctr.share.info1[i].info_1_str.uni_remark); 02527 02528 /* Get the type value */ 02529 type = ctr.share.info1[i].info_1.type; 02530 02531 /* Add this share to the list */ 02532 (*fn)(name, type, comment, state); 02533 } 02534 02535 done: 02536 /* Close the server service pipe */ 02537 cli_rpc_pipe_close(pipe_hnd); 02538 02539 /* Free all memory which was allocated for this request */ 02540 TALLOC_FREE(mem_ctx); 02541 02542 /* Tell 'em if it worked */ 02543 return W_ERROR_IS_OK(result) ? 0 : -1; 02544 }
libsmbclient.c の 2549 行で定義されています。
参照先 smbc_internal_data::_files・smbc_internal_data::_initialized・_SMBCCTX::_smbc_options::browse_max_lmb_count・_SMBCCTX::callbacks・_SMBCSRV::cli・cli・cli_errno()・_SMBCFILE::cli_fd・cli_is_error()・cli_list()・cli_NetServerEnum()・cli_resolve_path()・cli_RNetShareEnum()・cli_shutdown()・d_printf()・cli_state::desthost・_SMBCFILE::dir_end・_SMBCFILE::dir_list・dir_list_fn()・_SMBCFILE::dir_next・_SMBCFILE::dir_type・errno・_SMBCFILE::file・find_master_ip()・_SMBCFILE::fname・get_ipc_connect_master_ip()・_SMBCCTX::internal・ip_service::ip・is_ipaddress()・list_fn()・list_unique_wg_fn()・mode・name_resolve_bcast()・name_status_find()・net_share_enum_rpc()・_SMBCFILE::offset・_SMBCCTX::options・options・user_auth_info::password・password・resolve_name()・server・share・smbc_check_options()・smbc_errno()・smbc_getatr()・smbc_parse_path()・smbc_server()・_SMBCFILE::srv・_SMBCCTX::user・user_auth_info::username・workgroup.
参照元 smbc_new_context().
02551 { 02552 int saved_errno; 02553 fstring server, share, user, password, options; 02554 pstring workgroup; 02555 pstring path; 02556 uint16 mode; 02557 char *p; 02558 SMBCSRV *srv = NULL; 02559 SMBCFILE *dir = NULL; 02560 struct _smbc_callbacks *cb; 02561 struct in_addr rem_ip; 02562 02563 if (!context || !context->internal || 02564 !context->internal->_initialized) { 02565 DEBUG(4, ("no valid context\n")); 02566 errno = EINVAL + 8192; 02567 return NULL; 02568 02569 } 02570 02571 if (!fname) { 02572 DEBUG(4, ("no valid fname\n")); 02573 errno = EINVAL + 8193; 02574 return NULL; 02575 } 02576 02577 if (smbc_parse_path(context, fname, 02578 workgroup, sizeof(workgroup), 02579 server, sizeof(server), 02580 share, sizeof(share), 02581 path, sizeof(path), 02582 user, sizeof(user), 02583 password, sizeof(password), 02584 options, sizeof(options))) { 02585 DEBUG(4, ("no valid path\n")); 02586 errno = EINVAL + 8194; 02587 return NULL; 02588 } 02589 02590 DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' " 02591 "path='%s' options='%s'\n", 02592 fname, server, share, path, options)); 02593 02594 /* Ensure the options are valid */ 02595 if (smbc_check_options(server, share, path, options)) { 02596 DEBUG(4, ("unacceptable options (%s)\n", options)); 02597 errno = EINVAL + 8195; 02598 return NULL; 02599 } 02600 02601 if (user[0] == (char)0) fstrcpy(user, context->user); 02602 02603 dir = SMB_MALLOC_P(SMBCFILE); 02604 02605 if (!dir) { 02606 02607 errno = ENOMEM; 02608 return NULL; 02609 02610 } 02611 02612 ZERO_STRUCTP(dir); 02613 02614 dir->cli_fd = 0; 02615 dir->fname = SMB_STRDUP(fname); 02616 dir->srv = NULL; 02617 dir->offset = 0; 02618 dir->file = False; 02619 dir->dir_list = dir->dir_next = dir->dir_end = NULL; 02620 02621 if (server[0] == (char)0) { 02622 02623 int i; 02624 int count; 02625 int max_lmb_count; 02626 struct ip_service *ip_list; 02627 struct ip_service server_addr; 02628 struct user_auth_info u_info; 02629 struct cli_state *cli; 02630 02631 if (share[0] != (char)0 || path[0] != (char)0) { 02632 02633 errno = EINVAL + 8196; 02634 if (dir) { 02635 SAFE_FREE(dir->fname); 02636 SAFE_FREE(dir); 02637 } 02638 return NULL; 02639 } 02640 02641 /* Determine how many local master browsers to query */ 02642 max_lmb_count = (context->options.browse_max_lmb_count == 0 02643 ? INT_MAX 02644 : context->options.browse_max_lmb_count); 02645 02646 pstrcpy(u_info.username, user); 02647 pstrcpy(u_info.password, password); 02648 02649 /* 02650 * We have server and share and path empty but options 02651 * requesting that we scan all master browsers for their list 02652 * of workgroups/domains. This implies that we must first try 02653 * broadcast queries to find all master browsers, and if that 02654 * doesn't work, then try our other methods which return only 02655 * a single master browser. 02656 */ 02657 02658 ip_list = NULL; 02659 if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { 02660 02661 SAFE_FREE(ip_list); 02662 02663 if (!find_master_ip(workgroup, &server_addr.ip)) { 02664 02665 if (dir) { 02666 SAFE_FREE(dir->fname); 02667 SAFE_FREE(dir); 02668 } 02669 errno = ENOENT; 02670 return NULL; 02671 } 02672 02673 ip_list = &server_addr; 02674 count = 1; 02675 } 02676 02677 for (i = 0; i < count && i < max_lmb_count; i++) { 02678 DEBUG(99, ("Found master browser %d of %d: %s\n", 02679 i+1, MAX(count, max_lmb_count), 02680 inet_ntoa(ip_list[i].ip))); 02681 02682 cli = get_ipc_connect_master_ip(&ip_list[i], 02683 workgroup, &u_info); 02684 /* cli == NULL is the master browser refused to talk or 02685 could not be found */ 02686 if ( !cli ) 02687 continue; 02688 02689 fstrcpy(server, cli->desthost); 02690 cli_shutdown(cli); 02691 02692 DEBUG(4, ("using workgroup %s %s\n", 02693 workgroup, server)); 02694 02695 /* 02696 * For each returned master browser IP address, get a 02697 * connection to IPC$ on the server if we do not 02698 * already have one, and determine the 02699 * workgroups/domains that it knows about. 02700 */ 02701 02702 srv = smbc_server(context, True, server, "IPC$", 02703 workgroup, user, password); 02704 if (!srv) { 02705 continue; 02706 } 02707 02708 dir->srv = srv; 02709 dir->dir_type = SMBC_WORKGROUP; 02710 02711 /* Now, list the stuff ... */ 02712 02713 if (!cli_NetServerEnum(srv->cli, 02714 workgroup, 02715 SV_TYPE_DOMAIN_ENUM, 02716 list_unique_wg_fn, 02717 (void *)dir)) { 02718 continue; 02719 } 02720 } 02721 02722 SAFE_FREE(ip_list); 02723 } else { 02724 /* 02725 * Server not an empty string ... Check the rest and see what 02726 * gives 02727 */ 02728 if (*share == '\0') { 02729 if (*path != '\0') { 02730 02731 /* Should not have empty share with path */ 02732 errno = EINVAL + 8197; 02733 if (dir) { 02734 SAFE_FREE(dir->fname); 02735 SAFE_FREE(dir); 02736 } 02737 return NULL; 02738 02739 } 02740 02741 /* 02742 * We don't know if <server> is really a server name 02743 * or is a workgroup/domain name. If we already have 02744 * a server structure for it, we'll use it. 02745 * Otherwise, check to see if <server><1D>, 02746 * <server><1B>, or <server><20> translates. We check 02747 * to see if <server> is an IP address first. 02748 */ 02749 02750 /* 02751 * See if we have an existing server. Do not 02752 * establish a connection if one does not already 02753 * exist. 02754 */ 02755 srv = smbc_server(context, False, server, "IPC$", 02756 workgroup, user, password); 02757 02758 /* 02759 * If no existing server and not an IP addr, look for 02760 * LMB or DMB 02761 */ 02762 if (!srv && 02763 !is_ipaddress(server) && 02764 (resolve_name(server, &rem_ip, 0x1d) || /* LMB */ 02765 resolve_name(server, &rem_ip, 0x1b) )) { /* DMB */ 02766 02767 fstring buserver; 02768 02769 dir->dir_type = SMBC_SERVER; 02770 02771 /* 02772 * Get the backup list ... 02773 */ 02774 if (!name_status_find(server, 0, 0, 02775 rem_ip, buserver)) { 02776 02777 DEBUG(0, ("Could not get name of " 02778 "local/domain master browser " 02779 "for server %s\n", server)); 02780 if (dir) { 02781 SAFE_FREE(dir->fname); 02782 SAFE_FREE(dir); 02783 } 02784 errno = EPERM; 02785 return NULL; 02786 02787 } 02788 02789 /* 02790 * Get a connection to IPC$ on the server if 02791 * we do not already have one 02792 */ 02793 srv = smbc_server(context, True, 02794 buserver, "IPC$", 02795 workgroup, user, password); 02796 if (!srv) { 02797 DEBUG(0, ("got no contact to IPC$\n")); 02798 if (dir) { 02799 SAFE_FREE(dir->fname); 02800 SAFE_FREE(dir); 02801 } 02802 return NULL; 02803 02804 } 02805 02806 dir->srv = srv; 02807 02808 /* Now, list the servers ... */ 02809 if (!cli_NetServerEnum(srv->cli, server, 02810 0x0000FFFE, list_fn, 02811 (void *)dir)) { 02812 02813 if (dir) { 02814 SAFE_FREE(dir->fname); 02815 SAFE_FREE(dir); 02816 } 02817 return NULL; 02818 } 02819 } else if (srv || 02820 (resolve_name(server, &rem_ip, 0x20))) { 02821 02822 /* If we hadn't found the server, get one now */ 02823 if (!srv) { 02824 srv = smbc_server(context, True, 02825 server, "IPC$", 02826 workgroup, 02827 user, password); 02828 } 02829 02830 if (!srv) { 02831 if (dir) { 02832 SAFE_FREE(dir->fname); 02833 SAFE_FREE(dir); 02834 } 02835 return NULL; 02836 02837 } 02838 02839 dir->dir_type = SMBC_FILE_SHARE; 02840 dir->srv = srv; 02841 02842 /* List the shares ... */ 02843 02844 if (net_share_enum_rpc( 02845 srv->cli, 02846 list_fn, 02847 (void *) dir) < 0 && 02848 cli_RNetShareEnum( 02849 srv->cli, 02850 list_fn, 02851 (void *)dir) < 0) { 02852 02853 errno = cli_errno(srv->cli); 02854 if (dir) { 02855 SAFE_FREE(dir->fname); 02856 SAFE_FREE(dir); 02857 } 02858 return NULL; 02859 02860 } 02861 } else { 02862 /* Neither the workgroup nor server exists */ 02863 errno = ECONNREFUSED; 02864 if (dir) { 02865 SAFE_FREE(dir->fname); 02866 SAFE_FREE(dir); 02867 } 02868 return NULL; 02869 } 02870 02871 } 02872 else { 02873 /* 02874 * The server and share are specified ... work from 02875 * there ... 02876 */ 02877 pstring targetpath; 02878 struct cli_state *targetcli; 02879 02880 /* We connect to the server and list the directory */ 02881 dir->dir_type = SMBC_FILE_SHARE; 02882 02883 srv = smbc_server(context, True, server, share, 02884 workgroup, user, password); 02885 02886 if (!srv) { 02887 02888 if (dir) { 02889 SAFE_FREE(dir->fname); 02890 SAFE_FREE(dir); 02891 } 02892 return NULL; 02893 02894 } 02895 02896 dir->srv = srv; 02897 02898 /* Now, list the files ... */ 02899 02900 p = path + strlen(path); 02901 pstrcat(path, "\\*"); 02902 02903 if (!cli_resolve_path("", srv->cli, path, 02904 &targetcli, targetpath)) 02905 { 02906 d_printf("Could not resolve %s\n", path); 02907 if (dir) { 02908 SAFE_FREE(dir->fname); 02909 SAFE_FREE(dir); 02910 } 02911 return NULL; 02912 } 02913 02914 if (cli_list(targetcli, targetpath, 02915 aDIR | aSYSTEM | aHIDDEN, 02916 dir_list_fn, (void *)dir) < 0) { 02917 02918 if (dir) { 02919 SAFE_FREE(dir->fname); 02920 SAFE_FREE(dir); 02921 } 02922 saved_errno = smbc_errno(context, targetcli); 02923 02924 if (saved_errno == EINVAL) { 02925 /* 02926 * See if they asked to opendir something 02927 * other than a directory. If so, the 02928 * converted error value we got would have 02929 * been EINVAL rather than ENOTDIR. 02930 */ 02931 *p = '\0'; /* restore original path */ 02932 02933 if (smbc_getatr(context, srv, path, 02934 &mode, NULL, 02935 NULL, NULL, NULL, NULL, 02936 NULL) && 02937 ! IS_DOS_DIR(mode)) { 02938 02939 /* It is. Correct the error value */ 02940 saved_errno = ENOTDIR; 02941 } 02942 } 02943 02944 /* 02945 * If there was an error and the server is no 02946 * good any more... 02947 */ 02948 cb = &context->callbacks; 02949 if (cli_is_error(targetcli) && 02950 (cb->check_server_fn)(context, srv)) { 02951 02952 /* ... then remove it. */ 02953 if ((cb->remove_unused_server_fn)(context, 02954 srv)) { 02955 /* 02956 * We could not remove the 02957 * server completely, remove 02958 * it from the cache so we 02959 * will not get it again. It 02960 * will be removed when the 02961 * last file/dir is closed. 02962 */ 02963 (cb->remove_cached_srv_fn)(context, 02964 srv); 02965 } 02966 } 02967 02968 errno = saved_errno; 02969 return NULL; 02970 } 02971 } 02972 02973 } 02974 02975 DLIST_ADD(context->internal->_files, dir); 02976 return dir; 02977 02978 }
libsmbclient.c の 2985 行で定義されています。
参照先 smbc_internal_data::_files・smbc_internal_data::_initialized・DLIST_CONTAINS()・errno・_SMBCFILE::fname・_SMBCCTX::internal・smbc_remove_dir().
参照元 smbc_new_context().
02987 { 02988 02989 if (!context || !context->internal || 02990 !context->internal->_initialized) { 02991 02992 errno = EINVAL; 02993 return -1; 02994 02995 } 02996 02997 if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { 02998 02999 errno = EBADF; 03000 return -1; 03001 03002 } 03003 03004 smbc_remove_dir(dir); /* Clean it up */ 03005 03006 DLIST_REMOVE(context->internal->_files, dir); 03007 03008 if (dir) { 03009 03010 SAFE_FREE(dir->fname); 03011 SAFE_FREE(dir); /* Free the space too */ 03012 } 03013 03014 return 0; 03015 03016 }
static void smbc_readdir_internal | ( | SMBCCTX * | context, | |
struct smbc_dirent * | dest, | |||
struct smbc_dirent * | src, | |||
int | max_namebuf_len | |||
) | [static] |
libsmbclient.c の 3019 行で定義されています。
参照先 smbc_dirent::comment・smbc_dirent::commentlen・smbc_dirent::dirlen・smbc_dirent::name・smbc_dirent::namelen・_SMBCCTX::options・smbc_dirent::smbc_type・smbc_urlencode()・_SMBCCTX::_smbc_options::urlencode_readdir_entries.
参照元 smbc_getdents_ctx()・smbc_readdir_ctx().
03023 { 03024 if (context->options.urlencode_readdir_entries) { 03025 03026 /* url-encode the name. get back remaining buffer space */ 03027 max_namebuf_len = 03028 smbc_urlencode(dest->name, src->name, max_namebuf_len); 03029 03030 /* We now know the name length */ 03031 dest->namelen = strlen(dest->name); 03032 03033 /* Save the pointer to the beginning of the comment */ 03034 dest->comment = dest->name + dest->namelen + 1; 03035 03036 /* Copy the comment */ 03037 strncpy(dest->comment, src->comment, max_namebuf_len - 1); 03038 dest->comment[max_namebuf_len - 1] = '\0'; 03039 03040 /* Save other fields */ 03041 dest->smbc_type = src->smbc_type; 03042 dest->commentlen = strlen(dest->comment); 03043 dest->dirlen = ((dest->comment + dest->commentlen + 1) - 03044 (char *) dest); 03045 } else { 03046 03047 /* No encoding. Just copy the entry as is. */ 03048 memcpy(dest, src, src->dirlen); 03049 dest->comment = (char *)(&dest->name + src->namelen + 1); 03050 } 03051 03052 }
static int smbc_getdents_ctx | ( | SMBCCTX * | context, | |
SMBCFILE * | dir, | |||
struct smbc_dirent * | dirp, | |||
int | count | |||
) | [static] |
libsmbclient.c の 3120 行で定義されています。
参照先 smbc_internal_data::_dirent・smbc_internal_data::_files・smbc_internal_data::_initialized・_SMBCFILE::dir_next・smbc_dir_list::dirent・smbc_dirent::dirlen・DLIST_CONTAINS()・errno・_SMBCFILE::file・_SMBCCTX::internal・smbc_dirent::namelen・smbc_readdir_internal().
参照元 smbc_new_context().
03124 { 03125 int rem = count; 03126 int reqd; 03127 int maxlen; 03128 char *ndir = (char *)dirp; 03129 struct smbc_dir_list *dirlist; 03130 03131 /* Check that all is ok first ... */ 03132 03133 if (!context || !context->internal || 03134 !context->internal->_initialized) { 03135 03136 errno = EINVAL; 03137 return -1; 03138 03139 } 03140 03141 if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { 03142 03143 errno = EBADF; 03144 return -1; 03145 03146 } 03147 03148 if (dir->file != False) { /* FIXME, should be dir, perhaps */ 03149 03150 errno = ENOTDIR; 03151 return -1; 03152 03153 } 03154 03155 /* 03156 * Now, retrieve the number of entries that will fit in what was passed 03157 * We have to figure out if the info is in the list, or we need to 03158 * send a request to the server to get the info. 03159 */ 03160 03161 while ((dirlist = dir->dir_next)) { 03162 struct smbc_dirent *dirent; 03163 03164 if (!dirlist->dirent) { 03165 03166 errno = ENOENT; /* Bad error */ 03167 return -1; 03168 03169 } 03170 03171 /* Do urlencoding of next entry, if so selected */ 03172 dirent = (struct smbc_dirent *)context->internal->_dirent; 03173 maxlen = (sizeof(context->internal->_dirent) - 03174 sizeof(struct smbc_dirent)); 03175 smbc_readdir_internal(context, dirent, dirlist->dirent, maxlen); 03176 03177 reqd = dirent->dirlen; 03178 03179 if (rem < reqd) { 03180 03181 if (rem < count) { /* We managed to copy something */ 03182 03183 errno = 0; 03184 return count - rem; 03185 03186 } 03187 else { /* Nothing copied ... */ 03188 03189 errno = EINVAL; /* Not enough space ... */ 03190 return -1; 03191 03192 } 03193 03194 } 03195 03196 memcpy(ndir, dirent, reqd); /* Copy the data in ... */ 03197 03198 ((struct smbc_dirent *)ndir)->comment = 03199 (char *)(&((struct smbc_dirent *)ndir)->name + 03200 dirent->namelen + 03201 1); 03202 03203 ndir += reqd; 03204 03205 rem -= reqd; 03206 03207 dir->dir_next = dirlist = dirlist -> next; 03208 } 03209 03210 if (rem == count) 03211 return 0; 03212 else 03213 return count - rem; 03214 03215 }
static int smbc_mkdir_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
mode_t | mode | |||
) | [static] |
libsmbclient.c の 3222 行で定義されています。
参照先 smbc_internal_data::_initialized・_SMBCSRV::cli・cli_mkdir()・cli_resolve_path()・d_printf()・errno・_SMBCCTX::internal・password・server・share・smbc_errno()・smbc_parse_path()・smbc_server()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
03225 { 03226 SMBCSRV *srv; 03227 fstring server; 03228 fstring share; 03229 fstring user; 03230 fstring password; 03231 fstring workgroup; 03232 pstring path, targetpath; 03233 struct cli_state *targetcli; 03234 03235 if (!context || !context->internal || 03236 !context->internal->_initialized) { 03237 03238 errno = EINVAL; 03239 return -1; 03240 03241 } 03242 03243 if (!fname) { 03244 03245 errno = EINVAL; 03246 return -1; 03247 03248 } 03249 03250 DEBUG(4, ("smbc_mkdir(%s)\n", fname)); 03251 03252 if (smbc_parse_path(context, fname, 03253 workgroup, sizeof(workgroup), 03254 server, sizeof(server), 03255 share, sizeof(share), 03256 path, sizeof(path), 03257 user, sizeof(user), 03258 password, sizeof(password), 03259 NULL, 0)) { 03260 errno = EINVAL; 03261 return -1; 03262 } 03263 03264 if (user[0] == (char)0) fstrcpy(user, context->user); 03265 03266 srv = smbc_server(context, True, 03267 server, share, workgroup, user, password); 03268 03269 if (!srv) { 03270 03271 return -1; /* errno set by smbc_server */ 03272 03273 } 03274 03275 /*d_printf(">>>mkdir: resolving %s\n", path);*/ 03276 if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) 03277 { 03278 d_printf("Could not resolve %s\n", path); 03279 return -1; 03280 } 03281 /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/ 03282 03283 if (!cli_mkdir(targetcli, targetpath)) { 03284 03285 errno = smbc_errno(context, targetcli); 03286 return -1; 03287 03288 } 03289 03290 return 0; 03291 03292 }
static void rmdir_list_fn | ( | const char * | mnt, | |
file_info * | finfo, | |||
const char * | mask, | |||
void * | state | |||
) | [static] |
libsmbclient.c の 3301 行で定義されています。
参照先 file_info::name.
参照元 smbc_rmdir_ctx().
03305 { 03306 if (strncmp(finfo->name, ".", 1) != 0 && 03307 strncmp(finfo->name, "..", 2) != 0) { 03308 03309 smbc_rmdir_dirempty = False; 03310 } 03311 }
static int smbc_rmdir_ctx | ( | SMBCCTX * | context, | |
const char * | fname | |||
) | [static] |
libsmbclient.c の 3318 行で定義されています。
参照先 smbc_internal_data::_initialized・_SMBCSRV::cli・cli_list()・cli_resolve_path()・cli_rmdir()・d_printf()・errno・_SMBCCTX::internal・password・rmdir_list_fn()・server・share・smbc_errno()・smbc_parse_path()・smbc_server()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
03320 { 03321 SMBCSRV *srv; 03322 fstring server; 03323 fstring share; 03324 fstring user; 03325 fstring password; 03326 fstring workgroup; 03327 pstring path; 03328 pstring targetpath; 03329 struct cli_state *targetcli; 03330 03331 if (!context || !context->internal || 03332 !context->internal->_initialized) { 03333 03334 errno = EINVAL; 03335 return -1; 03336 03337 } 03338 03339 if (!fname) { 03340 03341 errno = EINVAL; 03342 return -1; 03343 03344 } 03345 03346 DEBUG(4, ("smbc_rmdir(%s)\n", fname)); 03347 03348 if (smbc_parse_path(context, fname, 03349 workgroup, sizeof(workgroup), 03350 server, sizeof(server), 03351 share, sizeof(share), 03352 path, sizeof(path), 03353 user, sizeof(user), 03354 password, sizeof(password), 03355 NULL, 0)) 03356 { 03357 errno = EINVAL; 03358 return -1; 03359 } 03360 03361 if (user[0] == (char)0) fstrcpy(user, context->user); 03362 03363 srv = smbc_server(context, True, 03364 server, share, workgroup, user, password); 03365 03366 if (!srv) { 03367 03368 return -1; /* errno set by smbc_server */ 03369 03370 } 03371 03372 /*d_printf(">>>rmdir: resolving %s\n", path);*/ 03373 if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) 03374 { 03375 d_printf("Could not resolve %s\n", path); 03376 return -1; 03377 } 03378 /*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/ 03379 03380 03381 if (!cli_rmdir(targetcli, targetpath)) { 03382 03383 errno = smbc_errno(context, targetcli); 03384 03385 if (errno == EACCES) { /* Check if the dir empty or not */ 03386 03387 /* Local storage to avoid buffer overflows */ 03388 pstring lpath; 03389 03390 smbc_rmdir_dirempty = True; /* Make this so ... */ 03391 03392 pstrcpy(lpath, targetpath); 03393 pstrcat(lpath, "\\*"); 03394 03395 if (cli_list(targetcli, lpath, 03396 aDIR | aSYSTEM | aHIDDEN, 03397 rmdir_list_fn, NULL) < 0) { 03398 03399 /* Fix errno to ignore latest error ... */ 03400 DEBUG(5, ("smbc_rmdir: " 03401 "cli_list returned an error: %d\n", 03402 smbc_errno(context, targetcli))); 03403 errno = EACCES; 03404 03405 } 03406 03407 if (smbc_rmdir_dirempty) 03408 errno = EACCES; 03409 else 03410 errno = ENOTEMPTY; 03411 03412 } 03413 03414 return -1; 03415 03416 } 03417 03418 return 0; 03419 03420 }
libsmbclient.c の 3427 行で定義されています。
参照先 smbc_internal_data::_files・smbc_internal_data::_initialized・_SMBCFILE::dir_next・smbc_dir_list::dirent・DLIST_CONTAINS()・errno・_SMBCFILE::file・_SMBCCTX::internal.
参照元 smbc_new_context().
03429 { 03430 if (!context || !context->internal || 03431 !context->internal->_initialized) { 03432 03433 errno = EINVAL; 03434 return -1; 03435 03436 } 03437 03438 if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { 03439 03440 errno = EBADF; 03441 return -1; 03442 03443 } 03444 03445 if (dir->file != False) { /* FIXME, should be dir, perhaps */ 03446 03447 errno = ENOTDIR; 03448 return -1; 03449 03450 } 03451 03452 /* See if we're already at the end. */ 03453 if (dir->dir_next == NULL) { 03454 /* We are. */ 03455 return -1; 03456 } 03457 03458 /* 03459 * We return the pointer here as the offset 03460 */ 03461 return (off_t)(long)dir->dir_next->dirent; 03462 }
libsmbclient.c の 3500 行で定義されています。
参照先 smbc_internal_data::_initialized・_SMBCFILE::dir_list・_SMBCFILE::dir_next・smbc_dir_list::dirent・errno・_SMBCFILE::file・_SMBCCTX::internal・smbc_check_dir_ent().
参照元 smbc_new_context().
03503 { 03504 long int l_offset = offset; /* Handle problems of size */ 03505 struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; 03506 struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; 03507 03508 if (!context || !context->internal || 03509 !context->internal->_initialized) { 03510 03511 errno = EINVAL; 03512 return -1; 03513 03514 } 03515 03516 if (dir->file != False) { /* FIXME, should be dir, perhaps */ 03517 03518 errno = ENOTDIR; 03519 return -1; 03520 03521 } 03522 03523 /* Now, check what we were passed and see if it is OK ... */ 03524 03525 if (dirent == NULL) { /* Seek to the begining of the list */ 03526 03527 dir->dir_next = dir->dir_list; 03528 return 0; 03529 03530 } 03531 03532 if (offset == -1) { /* Seek to the end of the list */ 03533 dir->dir_next = NULL; 03534 return 0; 03535 } 03536 03537 /* Now, run down the list and make sure that the entry is OK */ 03538 /* This may need to be changed if we change the format of the list */ 03539 03540 if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) { 03541 03542 errno = EINVAL; /* Bad entry */ 03543 return -1; 03544 03545 } 03546 03547 dir->dir_next = list_ent; 03548 03549 return 0; 03550 03551 }
libsmbclient.c の 3558 行で定義されています。
参照先 smbc_internal_data::_initialized・errno・_SMBCCTX::internal.
参照元 smbc_new_context().
03561 { 03562 03563 if (!context || !context->internal || 03564 !context->internal->_initialized) { 03565 03566 errno = EINVAL; 03567 return -1; 03568 03569 } 03570 03571 /* No code yet ... */ 03572 03573 return 0; 03574 03575 }
static int smbc_chmod_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
mode_t | newmode | |||
) | [static] |
libsmbclient.c の 3578 行で定義されています。
参照先 smbc_internal_data::_initialized・_SMBCSRV::cli・cli_setatr()・errno・_SMBCCTX::internal・mode・password・server・share・smbc_errno()・smbc_parse_path()・smbc_server()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
03581 { 03582 SMBCSRV *srv; 03583 fstring server; 03584 fstring share; 03585 fstring user; 03586 fstring password; 03587 fstring workgroup; 03588 pstring path; 03589 uint16 mode; 03590 03591 if (!context || !context->internal || 03592 !context->internal->_initialized) { 03593 03594 errno = EINVAL; /* Best I can think of ... */ 03595 return -1; 03596 03597 } 03598 03599 if (!fname) { 03600 03601 errno = EINVAL; 03602 return -1; 03603 03604 } 03605 03606 DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); 03607 03608 if (smbc_parse_path(context, fname, 03609 workgroup, sizeof(workgroup), 03610 server, sizeof(server), 03611 share, sizeof(share), 03612 path, sizeof(path), 03613 user, sizeof(user), 03614 password, sizeof(password), 03615 NULL, 0)) { 03616 errno = EINVAL; 03617 return -1; 03618 } 03619 03620 if (user[0] == (char)0) fstrcpy(user, context->user); 03621 03622 srv = smbc_server(context, True, 03623 server, share, workgroup, user, password); 03624 03625 if (!srv) { 03626 return -1; /* errno set by smbc_server */ 03627 } 03628 03629 mode = 0; 03630 03631 if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY; 03632 if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH; 03633 if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; 03634 if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; 03635 03636 if (!cli_setatr(srv->cli, path, mode, 0)) { 03637 errno = smbc_errno(context, srv->cli); 03638 return -1; 03639 } 03640 03641 return 0; 03642 }
static int smbc_utimes_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
struct timeval * | tbuf | |||
) | [static] |
libsmbclient.c の 3645 行で定義されています。
参照先 smbc_internal_data::_initialized・dbgtext()・errno・_SMBCCTX::internal・password・server・share・smbc_parse_path()・smbc_server()・smbc_setatr()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
03648 { 03649 SMBCSRV *srv; 03650 fstring server; 03651 fstring share; 03652 fstring user; 03653 fstring password; 03654 fstring workgroup; 03655 pstring path; 03656 time_t access_time; 03657 time_t write_time; 03658 03659 if (!context || !context->internal || 03660 !context->internal->_initialized) { 03661 03662 errno = EINVAL; /* Best I can think of ... */ 03663 return -1; 03664 03665 } 03666 03667 if (!fname) { 03668 03669 errno = EINVAL; 03670 return -1; 03671 03672 } 03673 03674 if (tbuf == NULL) { 03675 access_time = write_time = time(NULL); 03676 } else { 03677 access_time = tbuf[0].tv_sec; 03678 write_time = tbuf[1].tv_sec; 03679 } 03680 03681 if (DEBUGLVL(4)) 03682 { 03683 char *p; 03684 char atimebuf[32]; 03685 char mtimebuf[32]; 03686 03687 strncpy(atimebuf, ctime(&access_time), sizeof(atimebuf) - 1); 03688 atimebuf[sizeof(atimebuf) - 1] = '\0'; 03689 if ((p = strchr(atimebuf, '\n')) != NULL) { 03690 *p = '\0'; 03691 } 03692 03693 strncpy(mtimebuf, ctime(&write_time), sizeof(mtimebuf) - 1); 03694 mtimebuf[sizeof(mtimebuf) - 1] = '\0'; 03695 if ((p = strchr(mtimebuf, '\n')) != NULL) { 03696 *p = '\0'; 03697 } 03698 03699 dbgtext("smbc_utimes(%s, atime = %s mtime = %s)\n", 03700 fname, atimebuf, mtimebuf); 03701 } 03702 03703 if (smbc_parse_path(context, fname, 03704 workgroup, sizeof(workgroup), 03705 server, sizeof(server), 03706 share, sizeof(share), 03707 path, sizeof(path), 03708 user, sizeof(user), 03709 password, sizeof(password), 03710 NULL, 0)) { 03711 errno = EINVAL; 03712 return -1; 03713 } 03714 03715 if (user[0] == (char)0) fstrcpy(user, context->user); 03716 03717 srv = smbc_server(context, True, 03718 server, share, workgroup, user, password); 03719 03720 if (!srv) { 03721 return -1; /* errno set by smbc_server */ 03722 } 03723 03724 if (!smbc_setatr(context, srv, path, 03725 0, access_time, write_time, 0, 0)) { 03726 return -1; /* errno set by smbc_setatr */ 03727 } 03728 03729 return 0; 03730 }
libsmbclient.c の 3740 行で定義されています。
参照先 security_ace_info::access_mask・security_ace_info::flags・sec_ace_equal()・SEC_ACE_TYPE_ACCESS_ALLOWED・SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT・SEC_ACE_TYPE_ACCESS_DENIED・SEC_ACE_TYPE_ACCESS_DENIED_OBJECT・sid_compare()・security_ace_info::size・security_ace_info::trustee・security_ace_info::type.
参照元 sort_acl().
03742 { 03743 BOOL b1; 03744 BOOL b2; 03745 03746 /* If the ACEs are equal, we have nothing more to do. */ 03747 if (sec_ace_equal(ace1, ace2)) { 03748 return 0; 03749 } 03750 03751 /* Inherited follow non-inherited */ 03752 b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); 03753 b2 = ((ace2->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); 03754 if (b1 != b2) { 03755 return (b1 ? 1 : -1); 03756 } 03757 03758 /* 03759 * What shall we do with AUDITs and ALARMs? It's undefined. We'll 03760 * sort them after DENY and ALLOW. 03761 */ 03762 b1 = (ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED && 03763 ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && 03764 ace1->type != SEC_ACE_TYPE_ACCESS_DENIED && 03765 ace1->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); 03766 b2 = (ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED && 03767 ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && 03768 ace2->type != SEC_ACE_TYPE_ACCESS_DENIED && 03769 ace2->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); 03770 if (b1 != b2) { 03771 return (b1 ? 1 : -1); 03772 } 03773 03774 /* Allowed ACEs follow denied ACEs */ 03775 b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || 03776 ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); 03777 b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED || 03778 ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); 03779 if (b1 != b2) { 03780 return (b1 ? 1 : -1); 03781 } 03782 03783 /* 03784 * ACEs applying to an entity's object follow those applying to the 03785 * entity itself 03786 */ 03787 b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || 03788 ace1->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); 03789 b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || 03790 ace2->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); 03791 if (b1 != b2) { 03792 return (b1 ? 1 : -1); 03793 } 03794 03795 /* 03796 * If we get this far, the ACEs are similar as far as the 03797 * characteristics we typically care about (those defined by the 03798 * referenced MS document). We'll now sort by characteristics that 03799 * just seems reasonable. 03800 */ 03801 03802 if (ace1->type != ace2->type) { 03803 return ace2->type - ace1->type; 03804 } 03805 03806 if (sid_compare(&ace1->trustee, &ace2->trustee)) { 03807 return sid_compare(&ace1->trustee, &ace2->trustee); 03808 } 03809 03810 if (ace1->flags != ace2->flags) { 03811 return ace1->flags - ace2->flags; 03812 } 03813 03814 if (ace1->access_mask != ace2->access_mask) { 03815 return ace1->access_mask - ace2->access_mask; 03816 } 03817 03818 if (ace1->size != ace2->size) { 03819 return ace1->size - ace2->size; 03820 } 03821 03822 return memcmp(ace1, ace2, sizeof(SEC_ACE)); 03823 }
static void sort_acl | ( | SEC_ACL * | the_acl | ) | [static] |
libsmbclient.c の 3827 行で定義されています。
参照先 ace_compare()・security_acl_info::aces・security_acl_info::num_aces・sec_ace_equal().
03828 { 03829 uint32 i; 03830 if (!the_acl) return; 03831 03832 qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), 03833 QSORT_CAST ace_compare); 03834 03835 for (i=1;i<the_acl->num_aces;) { 03836 if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { 03837 int j; 03838 for (j=i; j<the_acl->num_aces-1; j++) { 03839 the_acl->aces[j] = the_acl->aces[j+1]; 03840 } 03841 the_acl->num_aces--; 03842 } else { 03843 i++; 03844 } 03845 } 03846 }
static void convert_sid_to_string | ( | struct cli_state * | ipc_cli, | |
POLICY_HND * | pol, | |||
fstring | str, | |||
BOOL | numeric, | |||
DOM_SID * | sid | |||
) | [static] |
libsmbclient.c の 3850 行で定義されています。
参照先 find_lsa_pipe_hnd()・cli_state::mem_ctx・pol・rpccli_lsa_lookup_sids()・sid_to_string().
参照元 cacl_get().
03855 { 03856 char **domains = NULL; 03857 char **names = NULL; 03858 enum lsa_SidType *types = NULL; 03859 struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); 03860 sid_to_string(str, sid); 03861 03862 if (numeric) { 03863 return; /* no lookup desired */ 03864 } 03865 03866 if (!pipe_hnd) { 03867 return; 03868 } 03869 03870 /* Ask LSA to convert the sid to a name */ 03871 03872 if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ipc_cli->mem_ctx, 03873 pol, 1, sid, &domains, 03874 &names, &types)) || 03875 !domains || !domains[0] || !names || !names[0]) { 03876 return; 03877 } 03878 03879 /* Converted OK */ 03880 03881 slprintf(str, sizeof(fstring) - 1, "%s%s%s", 03882 domains[0], lp_winbind_separator(), 03883 names[0]); 03884 }
static BOOL convert_string_to_sid | ( | struct cli_state * | ipc_cli, | |
POLICY_HND * | pol, | |||
BOOL | numeric, | |||
DOM_SID * | sid, | |||
const char * | str | |||
) | [static] |
libsmbclient.c の 3888 行で定義されています。
参照先 find_lsa_pipe_hnd()・cli_state::mem_ctx・pol・result・rpccli_lsa_lookup_names()・sid_copy()・string_to_sid().
参照元 parse_ace()・sec_desc_parse().
03893 { 03894 enum lsa_SidType *types = NULL; 03895 DOM_SID *sids = NULL; 03896 BOOL result = True; 03897 struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); 03898 03899 if (!pipe_hnd) { 03900 return False; 03901 } 03902 03903 if (numeric) { 03904 if (strncmp(str, "S-", 2) == 0) { 03905 return string_to_sid(sid, str); 03906 } 03907 03908 result = False; 03909 goto done; 03910 } 03911 03912 if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx, 03913 pol, 1, &str, NULL, &sids, 03914 &types))) { 03915 result = False; 03916 goto done; 03917 } 03918 03919 sid_copy(sid, &sids[0]); 03920 done: 03921 03922 return result; 03923 }
static BOOL parse_ace | ( | struct cli_state * | ipc_cli, | |
POLICY_HND * | pol, | |||
SEC_ACE * | ace, | |||
BOOL | numeric, | |||
char * | str | |||
) | [static] |
libsmbclient.c の 3928 行で定義されています。
参照先 convert_string_to_sid()・perm_value::mask・next_token()・perm_value::perm・pol・SEC_ACE_TYPE_ACCESS_ALLOWED・SEC_ACE_TYPE_ACCESS_DENIED・special_values・standard_values・strchr_m()・StrnCaseCmp().
参照元 parse_acl_string()・sec_desc_parse().
03933 { 03934 char *p; 03935 const char *cp; 03936 fstring tok; 03937 unsigned int atype; 03938 unsigned int aflags; 03939 unsigned int amask; 03940 DOM_SID sid; 03941 SEC_ACCESS mask; 03942 const struct perm_value *v; 03943 struct perm_value { 03944 const char *perm; 03945 uint32 mask; 03946 }; 03947 03948 /* These values discovered by inspection */ 03949 static const struct perm_value special_values[] = { 03950 { "R", 0x00120089 }, 03951 { "W", 0x00120116 }, 03952 { "X", 0x001200a0 }, 03953 { "D", 0x00010000 }, 03954 { "P", 0x00040000 }, 03955 { "O", 0x00080000 }, 03956 { NULL, 0 }, 03957 }; 03958 03959 static const struct perm_value standard_values[] = { 03960 { "READ", 0x001200a9 }, 03961 { "CHANGE", 0x001301bf }, 03962 { "FULL", 0x001f01ff }, 03963 { NULL, 0 }, 03964 }; 03965 03966 03967 ZERO_STRUCTP(ace); 03968 p = strchr_m(str,':'); 03969 if (!p) return False; 03970 *p = '\0'; 03971 p++; 03972 /* Try to parse numeric form */ 03973 03974 if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && 03975 convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { 03976 goto done; 03977 } 03978 03979 /* Try to parse text form */ 03980 03981 if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { 03982 return False; 03983 } 03984 03985 cp = p; 03986 if (!next_token(&cp, tok, "/", sizeof(fstring))) { 03987 return False; 03988 } 03989 03990 if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { 03991 atype = SEC_ACE_TYPE_ACCESS_ALLOWED; 03992 } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) { 03993 atype = SEC_ACE_TYPE_ACCESS_DENIED; 03994 } else { 03995 return False; 03996 } 03997 03998 /* Only numeric form accepted for flags at present */ 03999 04000 if (!(next_token(&cp, tok, "/", sizeof(fstring)) && 04001 sscanf(tok, "%i", &aflags))) { 04002 return False; 04003 } 04004 04005 if (!next_token(&cp, tok, "/", sizeof(fstring))) { 04006 return False; 04007 } 04008 04009 if (strncmp(tok, "0x", 2) == 0) { 04010 if (sscanf(tok, "%i", &amask) != 1) { 04011 return False; 04012 } 04013 goto done; 04014 } 04015 04016 for (v = standard_values; v->perm; v++) { 04017 if (strcmp(tok, v->perm) == 0) { 04018 amask = v->mask; 04019 goto done; 04020 } 04021 } 04022 04023 p = tok; 04024 04025 while(*p) { 04026 BOOL found = False; 04027 04028 for (v = special_values; v->perm; v++) { 04029 if (v->perm[0] == *p) { 04030 amask |= v->mask; 04031 found = True; 04032 } 04033 } 04034 04035 if (!found) return False; 04036 p++; 04037 } 04038 04039 if (*p) { 04040 return False; 04041 } 04042 04043 done: 04044 mask = amask; 04045 init_sec_ace(ace, &sid, atype, mask, aflags); 04046 return True; 04047 }
static BOOL add_ace | ( | SEC_ACL ** | the_acl, | |
SEC_ACE * | ace, | |||
TALLOC_CTX * | ctx | |||
) | [static] |
libsmbclient.c の 4051 行で定義されています。
参照先 make_sec_acl().
参照元 cacl_set()・sec_desc_parse().
04054 { 04055 SEC_ACL *newacl; 04056 SEC_ACE *aces; 04057 04058 if (! *the_acl) { 04059 (*the_acl) = make_sec_acl(ctx, 3, 1, ace); 04060 return True; 04061 } 04062 04063 if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) { 04064 return False; 04065 } 04066 memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE)); 04067 memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); 04068 newacl = make_sec_acl(ctx, (*the_acl)->revision, 04069 1+(*the_acl)->num_aces, aces); 04070 SAFE_FREE(aces); 04071 (*the_acl) = newacl; 04072 return True; 04073 }
static SEC_DESC* sec_desc_parse | ( | TALLOC_CTX * | ctx, | |
struct cli_state * | ipc_cli, | |||
POLICY_HND * | pol, | |||
BOOL | numeric, | |||
char * | str | |||
) | [static] |
libsmbclient.c の 4078 行で定義されています。
参照先 add_ace()・convert_string_to_sid()・make_sec_desc()・next_token()・parse_ace()・pol・StrnCaseCmp().
参照元 cacl_set().
04083 { 04084 const char *p = str; 04085 fstring tok; 04086 SEC_DESC *ret = NULL; 04087 size_t sd_size; 04088 DOM_SID *group_sid=NULL; 04089 DOM_SID *owner_sid=NULL; 04090 SEC_ACL *dacl=NULL; 04091 int revision=1; 04092 04093 while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) { 04094 04095 if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { 04096 revision = strtol(tok+9, NULL, 16); 04097 continue; 04098 } 04099 04100 if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { 04101 if (owner_sid) { 04102 DEBUG(5, ("OWNER specified more than once!\n")); 04103 goto done; 04104 } 04105 owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); 04106 if (!owner_sid || 04107 !convert_string_to_sid(ipc_cli, pol, 04108 numeric, 04109 owner_sid, tok+6)) { 04110 DEBUG(5, ("Failed to parse owner sid\n")); 04111 goto done; 04112 } 04113 continue; 04114 } 04115 04116 if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { 04117 if (owner_sid) { 04118 DEBUG(5, ("OWNER specified more than once!\n")); 04119 goto done; 04120 } 04121 owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); 04122 if (!owner_sid || 04123 !convert_string_to_sid(ipc_cli, pol, 04124 False, 04125 owner_sid, tok+7)) { 04126 DEBUG(5, ("Failed to parse owner sid\n")); 04127 goto done; 04128 } 04129 continue; 04130 } 04131 04132 if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { 04133 if (group_sid) { 04134 DEBUG(5, ("GROUP specified more than once!\n")); 04135 goto done; 04136 } 04137 group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); 04138 if (!group_sid || 04139 !convert_string_to_sid(ipc_cli, pol, 04140 numeric, 04141 group_sid, tok+6)) { 04142 DEBUG(5, ("Failed to parse group sid\n")); 04143 goto done; 04144 } 04145 continue; 04146 } 04147 04148 if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { 04149 if (group_sid) { 04150 DEBUG(5, ("GROUP specified more than once!\n")); 04151 goto done; 04152 } 04153 group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); 04154 if (!group_sid || 04155 !convert_string_to_sid(ipc_cli, pol, 04156 False, 04157 group_sid, tok+6)) { 04158 DEBUG(5, ("Failed to parse group sid\n")); 04159 goto done; 04160 } 04161 continue; 04162 } 04163 04164 if (StrnCaseCmp(tok,"ACL:", 4) == 0) { 04165 SEC_ACE ace; 04166 if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { 04167 DEBUG(5, ("Failed to parse ACL %s\n", tok)); 04168 goto done; 04169 } 04170 if(!add_ace(&dacl, &ace, ctx)) { 04171 DEBUG(5, ("Failed to add ACL %s\n", tok)); 04172 goto done; 04173 } 04174 continue; 04175 } 04176 04177 if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { 04178 SEC_ACE ace; 04179 if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { 04180 DEBUG(5, ("Failed to parse ACL %s\n", tok)); 04181 goto done; 04182 } 04183 if(!add_ace(&dacl, &ace, ctx)) { 04184 DEBUG(5, ("Failed to add ACL %s\n", tok)); 04185 goto done; 04186 } 04187 continue; 04188 } 04189 04190 DEBUG(5, ("Failed to parse security descriptor\n")); 04191 goto done; 04192 } 04193 04194 ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, 04195 owner_sid, group_sid, NULL, dacl, &sd_size); 04196 04197 done: 04198 SAFE_FREE(group_sid); 04199 SAFE_FREE(owner_sid); 04200 04201 return ret; 04202 }
static DOS_ATTR_DESC* dos_attr_query | ( | SMBCCTX * | context, | |
TALLOC_CTX * | ctx, | |||
const char * | filename, | |||
SMBCSRV * | srv | |||
) | [static] |
libsmbclient.c の 4207 行で定義されています。
参照先 DOS_ATTR_DESC::access_time・DOS_ATTR_DESC::change_time・_SMBCSRV::cli・convert_timespec_to_time_t()・DOS_ATTR_DESC::create_time・errno・DOS_ATTR_DESC::inode・inode・DOS_ATTR_DESC::mode・mode・DOS_ATTR_DESC::size・size・smbc_errno()・smbc_getatr()・DOS_ATTR_DESC::write_time.
参照元 smbc_setxattr_ctx().
04211 { 04212 struct timespec create_time_ts; 04213 struct timespec write_time_ts; 04214 struct timespec access_time_ts; 04215 struct timespec change_time_ts; 04216 SMB_OFF_T size = 0; 04217 uint16 mode = 0; 04218 SMB_INO_T inode = 0; 04219 DOS_ATTR_DESC *ret; 04220 04221 ret = TALLOC_P(ctx, DOS_ATTR_DESC); 04222 if (!ret) { 04223 errno = ENOMEM; 04224 return NULL; 04225 } 04226 04227 /* Obtain the DOS attributes */ 04228 if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename), 04229 &mode, &size, 04230 &create_time_ts, 04231 &access_time_ts, 04232 &write_time_ts, 04233 &change_time_ts, 04234 &inode)) { 04235 04236 errno = smbc_errno(context, srv->cli); 04237 DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); 04238 return NULL; 04239 04240 } 04241 04242 ret->mode = mode; 04243 ret->size = size; 04244 ret->create_time = convert_timespec_to_time_t(create_time_ts); 04245 ret->access_time = convert_timespec_to_time_t(access_time_ts); 04246 ret->write_time = convert_timespec_to_time_t(write_time_ts); 04247 ret->change_time = convert_timespec_to_time_t(change_time_ts); 04248 ret->inode = inode; 04249 04250 return ret; 04251 }
static void dos_attr_parse | ( | SMBCCTX * | context, | |
DOS_ATTR_DESC * | dad, | |||
SMBCSRV * | srv, | |||
char * | str | |||
) | [static] |
libsmbclient.c の 4256 行で定義されています。
参照先 smbc_internal_data::_full_time_names・DOS_ATTR_DESC::access_time・DOS_ATTR_DESC::change_time・DOS_ATTR_DESC::create_time・DOS_ATTR_DESC::inode・_SMBCCTX::internal・DOS_ATTR_DESC::mode・next_token()・DOS_ATTR_DESC::size・StrnCaseCmp()・DOS_ATTR_DESC::write_time.
参照元 smbc_setxattr_ctx().
04260 { 04261 int n; 04262 const char *p = str; 04263 fstring tok; 04264 struct { 04265 const char * create_time_attr; 04266 const char * access_time_attr; 04267 const char * write_time_attr; 04268 const char * change_time_attr; 04269 } attr_strings; 04270 04271 /* Determine whether to use old-style or new-style attribute names */ 04272 if (context->internal->_full_time_names) { 04273 /* new-style names */ 04274 attr_strings.create_time_attr = "CREATE_TIME"; 04275 attr_strings.access_time_attr = "ACCESS_TIME"; 04276 attr_strings.write_time_attr = "WRITE_TIME"; 04277 attr_strings.change_time_attr = "CHANGE_TIME"; 04278 } else { 04279 /* old-style names */ 04280 attr_strings.create_time_attr = NULL; 04281 attr_strings.access_time_attr = "A_TIME"; 04282 attr_strings.write_time_attr = "M_TIME"; 04283 attr_strings.change_time_attr = "C_TIME"; 04284 } 04285 04286 /* if this is to set the entire ACL... */ 04287 if (*str == '*') { 04288 /* ... then increment past the first colon if there is one */ 04289 if ((p = strchr(str, ':')) != NULL) { 04290 ++p; 04291 } else { 04292 p = str; 04293 } 04294 } 04295 04296 while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) { 04297 04298 if (StrnCaseCmp(tok, "MODE:", 5) == 0) { 04299 dad->mode = strtol(tok+5, NULL, 16); 04300 continue; 04301 } 04302 04303 if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { 04304 dad->size = (SMB_OFF_T)atof(tok+5); 04305 continue; 04306 } 04307 04308 n = strlen(attr_strings.access_time_attr); 04309 if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { 04310 dad->access_time = (time_t)strtol(tok+n+1, NULL, 10); 04311 continue; 04312 } 04313 04314 n = strlen(attr_strings.change_time_attr); 04315 if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { 04316 dad->change_time = (time_t)strtol(tok+n+1, NULL, 10); 04317 continue; 04318 } 04319 04320 n = strlen(attr_strings.write_time_attr); 04321 if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { 04322 dad->write_time = (time_t)strtol(tok+n+1, NULL, 10); 04323 continue; 04324 } 04325 04326 if (attr_strings.create_time_attr != NULL) { 04327 n = strlen(attr_strings.create_time_attr); 04328 if (StrnCaseCmp(tok, attr_strings.create_time_attr, 04329 n) == 0) { 04330 dad->create_time = (time_t)strtol(tok+n+1, 04331 NULL, 10); 04332 continue; 04333 } 04334 } 04335 04336 if (StrnCaseCmp(tok, "INODE:", 6) == 0) { 04337 dad->inode = (SMB_INO_T)atof(tok+6); 04338 continue; 04339 } 04340 } 04341 }
static int cacl_get | ( | SMBCCTX * | context, | |
TALLOC_CTX * | ctx, | |||
SMBCSRV * | srv, | |||
struct cli_state * | ipc_cli, | |||
POLICY_HND * | pol, | |||
char * | filename, | |||
char * | attr_name, | |||
char * | buf, | |||
int | bufsize | |||
) | [static] |
libsmbclient.c の 4348 行で定義されています。
参照先 smbc_internal_data::_full_time_names・security_acl_info::aces・_SMBCSRV::cli・cli・cli_close()・cli_errstr()・cli_nt_create()・cli_query_secdesc()・convert_sid_to_string()・convert_timespec_to_time_t()・security_descriptor_info::dacl・errno・security_descriptor_info::group_sid・_SMBCCTX::internal・mode・name・security_acl_info::num_aces・numeric・security_descriptor_info::owner_sid・pol・security_descriptor_info::revision・size・smbc_errno()・smbc_getatr()・snprintf()・StrCaseCmp()・StrnCaseCmp()・talloc_asprintf().
参照元 smbc_getxattr_ctx().
04357 { 04358 uint32 i; 04359 int n = 0; 04360 int n_used; 04361 BOOL all; 04362 BOOL all_nt; 04363 BOOL all_nt_acls; 04364 BOOL all_dos; 04365 BOOL some_nt; 04366 BOOL some_dos; 04367 BOOL exclude_nt_revision = False; 04368 BOOL exclude_nt_owner = False; 04369 BOOL exclude_nt_group = False; 04370 BOOL exclude_nt_acl = False; 04371 BOOL exclude_dos_mode = False; 04372 BOOL exclude_dos_size = False; 04373 BOOL exclude_dos_create_time = False; 04374 BOOL exclude_dos_access_time = False; 04375 BOOL exclude_dos_write_time = False; 04376 BOOL exclude_dos_change_time = False; 04377 BOOL exclude_dos_inode = False; 04378 BOOL numeric = True; 04379 BOOL determine_size = (bufsize == 0); 04380 int fnum = -1; 04381 SEC_DESC *sd; 04382 fstring sidstr; 04383 fstring name_sandbox; 04384 char *name; 04385 char *pExclude; 04386 char *p; 04387 struct timespec create_time_ts; 04388 struct timespec write_time_ts; 04389 struct timespec access_time_ts; 04390 struct timespec change_time_ts; 04391 time_t create_time = (time_t)0; 04392 time_t write_time = (time_t)0; 04393 time_t access_time = (time_t)0; 04394 time_t change_time = (time_t)0; 04395 SMB_OFF_T size = 0; 04396 uint16 mode = 0; 04397 SMB_INO_T ino = 0; 04398 struct cli_state *cli = srv->cli; 04399 struct { 04400 const char * create_time_attr; 04401 const char * access_time_attr; 04402 const char * write_time_attr; 04403 const char * change_time_attr; 04404 } attr_strings; 04405 struct { 04406 const char * create_time_attr; 04407 const char * access_time_attr; 04408 const char * write_time_attr; 04409 const char * change_time_attr; 04410 } excl_attr_strings; 04411 04412 /* Determine whether to use old-style or new-style attribute names */ 04413 if (context->internal->_full_time_names) { 04414 /* new-style names */ 04415 attr_strings.create_time_attr = "CREATE_TIME"; 04416 attr_strings.access_time_attr = "ACCESS_TIME"; 04417 attr_strings.write_time_attr = "WRITE_TIME"; 04418 attr_strings.change_time_attr = "CHANGE_TIME"; 04419 04420 excl_attr_strings.create_time_attr = "CREATE_TIME"; 04421 excl_attr_strings.access_time_attr = "ACCESS_TIME"; 04422 excl_attr_strings.write_time_attr = "WRITE_TIME"; 04423 excl_attr_strings.change_time_attr = "CHANGE_TIME"; 04424 } else { 04425 /* old-style names */ 04426 attr_strings.create_time_attr = NULL; 04427 attr_strings.access_time_attr = "A_TIME"; 04428 attr_strings.write_time_attr = "M_TIME"; 04429 attr_strings.change_time_attr = "C_TIME"; 04430 04431 excl_attr_strings.create_time_attr = NULL; 04432 excl_attr_strings.access_time_attr = "dos_attr.A_TIME"; 04433 excl_attr_strings.write_time_attr = "dos_attr.M_TIME"; 04434 excl_attr_strings.change_time_attr = "dos_attr.C_TIME"; 04435 } 04436 04437 /* Copy name so we can strip off exclusions (if any are specified) */ 04438 strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); 04439 04440 /* Ensure name is null terminated */ 04441 name_sandbox[sizeof(name_sandbox) - 1] = '\0'; 04442 04443 /* Play in the sandbox */ 04444 name = name_sandbox; 04445 04446 /* If there are any exclusions, point to them and mask them from name */ 04447 if ((pExclude = strchr(name, '!')) != NULL) 04448 { 04449 *pExclude++ = '\0'; 04450 } 04451 04452 all = (StrnCaseCmp(name, "system.*", 8) == 0); 04453 all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); 04454 all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0); 04455 all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0); 04456 some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0); 04457 some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); 04458 numeric = (* (name + strlen(name) - 1) != '+'); 04459 04460 /* Look for exclusions from "all" requests */ 04461 if (all || all_nt || all_dos) { 04462 04463 /* Exclusions are delimited by '!' */ 04464 for (; 04465 pExclude != NULL; 04466 pExclude = (p == NULL ? NULL : p + 1)) { 04467 04468 /* Find end of this exclusion name */ 04469 if ((p = strchr(pExclude, '!')) != NULL) 04470 { 04471 *p = '\0'; 04472 } 04473 04474 /* Which exclusion name is this? */ 04475 if (StrCaseCmp(pExclude, "nt_sec_desc.revision") == 0) { 04476 exclude_nt_revision = True; 04477 } 04478 else if (StrCaseCmp(pExclude, "nt_sec_desc.owner") == 0) { 04479 exclude_nt_owner = True; 04480 } 04481 else if (StrCaseCmp(pExclude, "nt_sec_desc.group") == 0) { 04482 exclude_nt_group = True; 04483 } 04484 else if (StrCaseCmp(pExclude, "nt_sec_desc.acl") == 0) { 04485 exclude_nt_acl = True; 04486 } 04487 else if (StrCaseCmp(pExclude, "dos_attr.mode") == 0) { 04488 exclude_dos_mode = True; 04489 } 04490 else if (StrCaseCmp(pExclude, "dos_attr.size") == 0) { 04491 exclude_dos_size = True; 04492 } 04493 else if (excl_attr_strings.create_time_attr != NULL && 04494 StrCaseCmp(pExclude, 04495 excl_attr_strings.change_time_attr) == 0) { 04496 exclude_dos_create_time = True; 04497 } 04498 else if (StrCaseCmp(pExclude, 04499 excl_attr_strings.access_time_attr) == 0) { 04500 exclude_dos_access_time = True; 04501 } 04502 else if (StrCaseCmp(pExclude, 04503 excl_attr_strings.write_time_attr) == 0) { 04504 exclude_dos_write_time = True; 04505 } 04506 else if (StrCaseCmp(pExclude, 04507 excl_attr_strings.change_time_attr) == 0) { 04508 exclude_dos_change_time = True; 04509 } 04510 else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) { 04511 exclude_dos_inode = True; 04512 } 04513 else { 04514 DEBUG(5, ("cacl_get received unknown exclusion: %s\n", 04515 pExclude)); 04516 errno = ENOATTR; 04517 return -1; 04518 } 04519 } 04520 } 04521 04522 n_used = 0; 04523 04524 /* 04525 * If we are (possibly) talking to an NT or new system and some NT 04526 * attributes have been requested... 04527 */ 04528 if (ipc_cli && (all || some_nt || all_nt_acls)) { 04529 /* Point to the portion after "system.nt_sec_desc." */ 04530 name += 19; /* if (all) this will be invalid but unused */ 04531 04532 /* ... then obtain any NT attributes which were requested */ 04533 fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); 04534 04535 if (fnum == -1) { 04536 DEBUG(5, ("cacl_get failed to open %s: %s\n", 04537 filename, cli_errstr(cli))); 04538 errno = 0; 04539 return -1; 04540 } 04541 04542 sd = cli_query_secdesc(cli, fnum, ctx); 04543 04544 if (!sd) { 04545 DEBUG(5, 04546 ("cacl_get Failed to query old descriptor\n")); 04547 errno = 0; 04548 return -1; 04549 } 04550 04551 cli_close(cli, fnum); 04552 04553 if (! exclude_nt_revision) { 04554 if (all || all_nt) { 04555 if (determine_size) { 04556 p = talloc_asprintf(ctx, 04557 "REVISION:%d", 04558 sd->revision); 04559 if (!p) { 04560 errno = ENOMEM; 04561 return -1; 04562 } 04563 n = strlen(p); 04564 } else { 04565 n = snprintf(buf, bufsize, 04566 "REVISION:%d", 04567 sd->revision); 04568 } 04569 } else if (StrCaseCmp(name, "revision") == 0) { 04570 if (determine_size) { 04571 p = talloc_asprintf(ctx, "%d", 04572 sd->revision); 04573 if (!p) { 04574 errno = ENOMEM; 04575 return -1; 04576 } 04577 n = strlen(p); 04578 } else { 04579 n = snprintf(buf, bufsize, "%d", 04580 sd->revision); 04581 } 04582 } 04583 04584 if (!determine_size && n > bufsize) { 04585 errno = ERANGE; 04586 return -1; 04587 } 04588 buf += n; 04589 n_used += n; 04590 bufsize -= n; 04591 n = 0; 04592 } 04593 04594 if (! exclude_nt_owner) { 04595 /* Get owner and group sid */ 04596 if (sd->owner_sid) { 04597 convert_sid_to_string(ipc_cli, pol, 04598 sidstr, 04599 numeric, 04600 sd->owner_sid); 04601 } else { 04602 fstrcpy(sidstr, ""); 04603 } 04604 04605 if (all || all_nt) { 04606 if (determine_size) { 04607 p = talloc_asprintf(ctx, ",OWNER:%s", 04608 sidstr); 04609 if (!p) { 04610 errno = ENOMEM; 04611 return -1; 04612 } 04613 n = strlen(p); 04614 } else if (sidstr[0] != '\0') { 04615 n = snprintf(buf, bufsize, 04616 ",OWNER:%s", sidstr); 04617 } 04618 } else if (StrnCaseCmp(name, "owner", 5) == 0) { 04619 if (determine_size) { 04620 p = talloc_asprintf(ctx, "%s", sidstr); 04621 if (!p) { 04622 errno = ENOMEM; 04623 return -1; 04624 } 04625 n = strlen(p); 04626 } else { 04627 n = snprintf(buf, bufsize, "%s", 04628 sidstr); 04629 } 04630 } 04631 04632 if (!determine_size && n > bufsize) { 04633 errno = ERANGE; 04634 return -1; 04635 } 04636 buf += n; 04637 n_used += n; 04638 bufsize -= n; 04639 n = 0; 04640 } 04641 04642 if (! exclude_nt_group) { 04643 if (sd->group_sid) { 04644 convert_sid_to_string(ipc_cli, pol, 04645 sidstr, numeric, 04646 sd->group_sid); 04647 } else { 04648 fstrcpy(sidstr, ""); 04649 } 04650 04651 if (all || all_nt) { 04652 if (determine_size) { 04653 p = talloc_asprintf(ctx, ",GROUP:%s", 04654 sidstr); 04655 if (!p) { 04656 errno = ENOMEM; 04657 return -1; 04658 } 04659 n = strlen(p); 04660 } else if (sidstr[0] != '\0') { 04661 n = snprintf(buf, bufsize, 04662 ",GROUP:%s", sidstr); 04663 } 04664 } else if (StrnCaseCmp(name, "group", 5) == 0) { 04665 if (determine_size) { 04666 p = talloc_asprintf(ctx, "%s", sidstr); 04667 if (!p) { 04668 errno = ENOMEM; 04669 return -1; 04670 } 04671 n = strlen(p); 04672 } else { 04673 n = snprintf(buf, bufsize, 04674 "%s", sidstr); 04675 } 04676 } 04677 04678 if (!determine_size && n > bufsize) { 04679 errno = ERANGE; 04680 return -1; 04681 } 04682 buf += n; 04683 n_used += n; 04684 bufsize -= n; 04685 n = 0; 04686 } 04687 04688 if (! exclude_nt_acl) { 04689 /* Add aces to value buffer */ 04690 for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { 04691 04692 SEC_ACE *ace = &sd->dacl->aces[i]; 04693 convert_sid_to_string(ipc_cli, pol, 04694 sidstr, numeric, 04695 &ace->trustee); 04696 04697 if (all || all_nt) { 04698 if (determine_size) { 04699 p = talloc_asprintf( 04700 ctx, 04701 ",ACL:" 04702 "%s:%d/%d/0x%08x", 04703 sidstr, 04704 ace->type, 04705 ace->flags, 04706 ace->access_mask); 04707 if (!p) { 04708 errno = ENOMEM; 04709 return -1; 04710 } 04711 n = strlen(p); 04712 } else { 04713 n = snprintf( 04714 buf, bufsize, 04715 ",ACL:%s:%d/%d/0x%08x", 04716 sidstr, 04717 ace->type, 04718 ace->flags, 04719 ace->access_mask); 04720 } 04721 } else if ((StrnCaseCmp(name, "acl", 3) == 0 && 04722 StrCaseCmp(name+3, sidstr) == 0) || 04723 (StrnCaseCmp(name, "acl+", 4) == 0 && 04724 StrCaseCmp(name+4, sidstr) == 0)) { 04725 if (determine_size) { 04726 p = talloc_asprintf( 04727 ctx, 04728 "%d/%d/0x%08x", 04729 ace->type, 04730 ace->flags, 04731 ace->access_mask); 04732 if (!p) { 04733 errno = ENOMEM; 04734 return -1; 04735 } 04736 n = strlen(p); 04737 } else { 04738 n = snprintf(buf, bufsize, 04739 "%d/%d/0x%08x", 04740 ace->type, 04741 ace->flags, 04742 ace->access_mask); 04743 } 04744 } else if (all_nt_acls) { 04745 if (determine_size) { 04746 p = talloc_asprintf( 04747 ctx, 04748 "%s%s:%d/%d/0x%08x", 04749 i ? "," : "", 04750 sidstr, 04751 ace->type, 04752 ace->flags, 04753 ace->access_mask); 04754 if (!p) { 04755 errno = ENOMEM; 04756 return -1; 04757 } 04758 n = strlen(p); 04759 } else { 04760 n = snprintf(buf, bufsize, 04761 "%s%s:%d/%d/0x%08x", 04762 i ? "," : "", 04763 sidstr, 04764 ace->type, 04765 ace->flags, 04766 ace->access_mask); 04767 } 04768 } 04769 if (!determine_size && n > bufsize) { 04770 errno = ERANGE; 04771 return -1; 04772 } 04773 buf += n; 04774 n_used += n; 04775 bufsize -= n; 04776 n = 0; 04777 } 04778 } 04779 04780 /* Restore name pointer to its original value */ 04781 name -= 19; 04782 } 04783 04784 if (all || some_dos) { 04785 /* Point to the portion after "system.dos_attr." */ 04786 name += 16; /* if (all) this will be invalid but unused */ 04787 04788 /* Obtain the DOS attributes */ 04789 if (!smbc_getatr(context, srv, filename, &mode, &size, 04790 &create_time_ts, 04791 &access_time_ts, 04792 &write_time_ts, 04793 &change_time_ts, 04794 &ino)) { 04795 04796 errno = smbc_errno(context, srv->cli); 04797 return -1; 04798 04799 } 04800 04801 create_time = convert_timespec_to_time_t(create_time_ts); 04802 access_time = convert_timespec_to_time_t(access_time_ts); 04803 write_time = convert_timespec_to_time_t(write_time_ts); 04804 change_time = convert_timespec_to_time_t(change_time_ts); 04805 04806 if (! exclude_dos_mode) { 04807 if (all || all_dos) { 04808 if (determine_size) { 04809 p = talloc_asprintf(ctx, 04810 "%sMODE:0x%x", 04811 (ipc_cli && 04812 (all || some_nt) 04813 ? "," 04814 : ""), 04815 mode); 04816 if (!p) { 04817 errno = ENOMEM; 04818 return -1; 04819 } 04820 n = strlen(p); 04821 } else { 04822 n = snprintf(buf, bufsize, 04823 "%sMODE:0x%x", 04824 (ipc_cli && 04825 (all || some_nt) 04826 ? "," 04827 : ""), 04828 mode); 04829 } 04830 } else if (StrCaseCmp(name, "mode") == 0) { 04831 if (determine_size) { 04832 p = talloc_asprintf(ctx, "0x%x", mode); 04833 if (!p) { 04834 errno = ENOMEM; 04835 return -1; 04836 } 04837 n = strlen(p); 04838 } else { 04839 n = snprintf(buf, bufsize, 04840 "0x%x", mode); 04841 } 04842 } 04843 04844 if (!determine_size && n > bufsize) { 04845 errno = ERANGE; 04846 return -1; 04847 } 04848 buf += n; 04849 n_used += n; 04850 bufsize -= n; 04851 n = 0; 04852 } 04853 04854 if (! exclude_dos_size) { 04855 if (all || all_dos) { 04856 if (determine_size) { 04857 p = talloc_asprintf( 04858 ctx, 04859 ",SIZE:%.0f", 04860 (double)size); 04861 if (!p) { 04862 errno = ENOMEM; 04863 return -1; 04864 } 04865 n = strlen(p); 04866 } else { 04867 n = snprintf(buf, bufsize, 04868 ",SIZE:%.0f", 04869 (double)size); 04870 } 04871 } else if (StrCaseCmp(name, "size") == 0) { 04872 if (determine_size) { 04873 p = talloc_asprintf( 04874 ctx, 04875 "%.0f", 04876 (double)size); 04877 if (!p) { 04878 errno = ENOMEM; 04879 return -1; 04880 } 04881 n = strlen(p); 04882 } else { 04883 n = snprintf(buf, bufsize, 04884 "%.0f", 04885 (double)size); 04886 } 04887 } 04888 04889 if (!determine_size && n > bufsize) { 04890 errno = ERANGE; 04891 return -1; 04892 } 04893 buf += n; 04894 n_used += n; 04895 bufsize -= n; 04896 n = 0; 04897 } 04898 04899 if (! exclude_dos_create_time && 04900 attr_strings.create_time_attr != NULL) { 04901 if (all || all_dos) { 04902 if (determine_size) { 04903 p = talloc_asprintf(ctx, 04904 ",%s:%lu", 04905 attr_strings.create_time_attr, 04906 create_time); 04907 if (!p) { 04908 errno = ENOMEM; 04909 return -1; 04910 } 04911 n = strlen(p); 04912 } else { 04913 n = snprintf(buf, bufsize, 04914 ",%s:%lu", 04915 attr_strings.create_time_attr, 04916 create_time); 04917 } 04918 } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) { 04919 if (determine_size) { 04920 p = talloc_asprintf(ctx, "%lu", create_time); 04921 if (!p) { 04922 errno = ENOMEM; 04923 return -1; 04924 } 04925 n = strlen(p); 04926 } else { 04927 n = snprintf(buf, bufsize, 04928 "%lu", create_time); 04929 } 04930 } 04931 04932 if (!determine_size && n > bufsize) { 04933 errno = ERANGE; 04934 return -1; 04935 } 04936 buf += n; 04937 n_used += n; 04938 bufsize -= n; 04939 n = 0; 04940 } 04941 04942 if (! exclude_dos_access_time) { 04943 if (all || all_dos) { 04944 if (determine_size) { 04945 p = talloc_asprintf(ctx, 04946 ",%s:%lu", 04947 attr_strings.access_time_attr, 04948 access_time); 04949 if (!p) { 04950 errno = ENOMEM; 04951 return -1; 04952 } 04953 n = strlen(p); 04954 } else { 04955 n = snprintf(buf, bufsize, 04956 ",%s:%lu", 04957 attr_strings.access_time_attr, 04958 access_time); 04959 } 04960 } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) { 04961 if (determine_size) { 04962 p = talloc_asprintf(ctx, "%lu", access_time); 04963 if (!p) { 04964 errno = ENOMEM; 04965 return -1; 04966 } 04967 n = strlen(p); 04968 } else { 04969 n = snprintf(buf, bufsize, 04970 "%lu", access_time); 04971 } 04972 } 04973 04974 if (!determine_size && n > bufsize) { 04975 errno = ERANGE; 04976 return -1; 04977 } 04978 buf += n; 04979 n_used += n; 04980 bufsize -= n; 04981 n = 0; 04982 } 04983 04984 if (! exclude_dos_write_time) { 04985 if (all || all_dos) { 04986 if (determine_size) { 04987 p = talloc_asprintf(ctx, 04988 ",%s:%lu", 04989 attr_strings.write_time_attr, 04990 write_time); 04991 if (!p) { 04992 errno = ENOMEM; 04993 return -1; 04994 } 04995 n = strlen(p); 04996 } else { 04997 n = snprintf(buf, bufsize, 04998 ",%s:%lu", 04999 attr_strings.write_time_attr, 05000 write_time); 05001 } 05002 } else if (StrCaseCmp(name, attr_strings.write_time_attr) == 0) { 05003 if (determine_size) { 05004 p = talloc_asprintf(ctx, "%lu", write_time); 05005 if (!p) { 05006 errno = ENOMEM; 05007 return -1; 05008 } 05009 n = strlen(p); 05010 } else { 05011 n = snprintf(buf, bufsize, 05012 "%lu", write_time); 05013 } 05014 } 05015 05016 if (!determine_size && n > bufsize) { 05017 errno = ERANGE; 05018 return -1; 05019 } 05020 buf += n; 05021 n_used += n; 05022 bufsize -= n; 05023 n = 0; 05024 } 05025 05026 if (! exclude_dos_change_time) { 05027 if (all || all_dos) { 05028 if (determine_size) { 05029 p = talloc_asprintf(ctx, 05030 ",%s:%lu", 05031 attr_strings.change_time_attr, 05032 change_time); 05033 if (!p) { 05034 errno = ENOMEM; 05035 return -1; 05036 } 05037 n = strlen(p); 05038 } else { 05039 n = snprintf(buf, bufsize, 05040 ",%s:%lu", 05041 attr_strings.change_time_attr, 05042 change_time); 05043 } 05044 } else if (StrCaseCmp(name, attr_strings.change_time_attr) == 0) { 05045 if (determine_size) { 05046 p = talloc_asprintf(ctx, "%lu", change_time); 05047 if (!p) { 05048 errno = ENOMEM; 05049 return -1; 05050 } 05051 n = strlen(p); 05052 } else { 05053 n = snprintf(buf, bufsize, 05054 "%lu", change_time); 05055 } 05056 } 05057 05058 if (!determine_size && n > bufsize) { 05059 errno = ERANGE; 05060 return -1; 05061 } 05062 buf += n; 05063 n_used += n; 05064 bufsize -= n; 05065 n = 0; 05066 } 05067 05068 if (! exclude_dos_inode) { 05069 if (all || all_dos) { 05070 if (determine_size) { 05071 p = talloc_asprintf( 05072 ctx, 05073 ",INODE:%.0f", 05074 (double)ino); 05075 if (!p) { 05076 errno = ENOMEM; 05077 return -1; 05078 } 05079 n = strlen(p); 05080 } else { 05081 n = snprintf(buf, bufsize, 05082 ",INODE:%.0f", 05083 (double) ino); 05084 } 05085 } else if (StrCaseCmp(name, "inode") == 0) { 05086 if (determine_size) { 05087 p = talloc_asprintf( 05088 ctx, 05089 "%.0f", 05090 (double) ino); 05091 if (!p) { 05092 errno = ENOMEM; 05093 return -1; 05094 } 05095 n = strlen(p); 05096 } else { 05097 n = snprintf(buf, bufsize, 05098 "%.0f", 05099 (double) ino); 05100 } 05101 } 05102 05103 if (!determine_size && n > bufsize) { 05104 errno = ERANGE; 05105 return -1; 05106 } 05107 buf += n; 05108 n_used += n; 05109 bufsize -= n; 05110 n = 0; 05111 } 05112 05113 /* Restore name pointer to its original value */ 05114 name -= 16; 05115 } 05116 05117 if (n_used == 0) { 05118 errno = ENOATTR; 05119 return -1; 05120 } 05121 05122 return n_used; 05123 }
static int cacl_set | ( | TALLOC_CTX * | ctx, | |
struct cli_state * | cli, | |||
struct cli_state * | ipc_cli, | |||
POLICY_HND * | pol, | |||
const char * | filename, | |||
const char * | the_acl, | |||
int | mode, | |||
int | flags | |||
) | [static] |
libsmbclient.c の 5130 行で定義されています。
参照先 security_acl_info::aces・add_ace()・cli・cli_close()・cli_errstr()・cli_nt_create()・cli_query_secdesc()・security_descriptor_info::dacl・err・errno・failed・security_acl_info::num_aces・numeric・pol・sec_ace_equal()・sec_desc_parse()・sid_equal()・security_ace_info::trustee.
参照元 main()・smbc_removexattr_ctx()・smbc_setxattr_ctx().
05138 { 05139 int fnum; 05140 int err = 0; 05141 SEC_DESC *sd = NULL, *old; 05142 SEC_ACL *dacl = NULL; 05143 DOM_SID *owner_sid = NULL; 05144 DOM_SID *group_sid = NULL; 05145 uint32 i, j; 05146 size_t sd_size; 05147 int ret = 0; 05148 char *p; 05149 BOOL numeric = True; 05150 05151 /* the_acl will be null for REMOVE_ALL operations */ 05152 if (the_acl) { 05153 numeric = ((p = strchr(the_acl, ':')) != NULL && 05154 p > the_acl && 05155 p[-1] != '+'); 05156 05157 /* if this is to set the entire ACL... */ 05158 if (*the_acl == '*') { 05159 /* ... then increment past the first colon */ 05160 the_acl = p + 1; 05161 } 05162 05163 sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, 05164 CONST_DISCARD(char *, the_acl)); 05165 05166 if (!sd) { 05167 errno = EINVAL; 05168 return -1; 05169 } 05170 } 05171 05172 /* SMBC_XATTR_MODE_REMOVE_ALL is the only caller 05173 that doesn't deref sd */ 05174 05175 if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) { 05176 errno = EINVAL; 05177 return -1; 05178 } 05179 05180 /* The desired access below is the only one I could find that works 05181 with NT4, W2KP and Samba */ 05182 05183 fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); 05184 05185 if (fnum == -1) { 05186 DEBUG(5, ("cacl_set failed to open %s: %s\n", 05187 filename, cli_errstr(cli))); 05188 errno = 0; 05189 return -1; 05190 } 05191 05192 old = cli_query_secdesc(cli, fnum, ctx); 05193 05194 if (!old) { 05195 DEBUG(5, ("cacl_set Failed to query old descriptor\n")); 05196 errno = 0; 05197 return -1; 05198 } 05199 05200 cli_close(cli, fnum); 05201 05202 switch (mode) { 05203 case SMBC_XATTR_MODE_REMOVE_ALL: 05204 old->dacl->num_aces = 0; 05205 dacl = old->dacl; 05206 break; 05207 05208 case SMBC_XATTR_MODE_REMOVE: 05209 for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { 05210 BOOL found = False; 05211 05212 for (j=0;old->dacl && j<old->dacl->num_aces;j++) { 05213 if (sec_ace_equal(&sd->dacl->aces[i], 05214 &old->dacl->aces[j])) { 05215 uint32 k; 05216 for (k=j; k<old->dacl->num_aces-1;k++) { 05217 old->dacl->aces[k] = 05218 old->dacl->aces[k+1]; 05219 } 05220 old->dacl->num_aces--; 05221 found = True; 05222 dacl = old->dacl; 05223 break; 05224 } 05225 } 05226 05227 if (!found) { 05228 err = ENOATTR; 05229 ret = -1; 05230 goto failed; 05231 } 05232 } 05233 break; 05234 05235 case SMBC_XATTR_MODE_ADD: 05236 for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { 05237 BOOL found = False; 05238 05239 for (j=0;old->dacl && j<old->dacl->num_aces;j++) { 05240 if (sid_equal(&sd->dacl->aces[i].trustee, 05241 &old->dacl->aces[j].trustee)) { 05242 if (!(flags & SMBC_XATTR_FLAG_CREATE)) { 05243 err = EEXIST; 05244 ret = -1; 05245 goto failed; 05246 } 05247 old->dacl->aces[j] = sd->dacl->aces[i]; 05248 ret = -1; 05249 found = True; 05250 } 05251 } 05252 05253 if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) { 05254 err = ENOATTR; 05255 ret = -1; 05256 goto failed; 05257 } 05258 05259 for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { 05260 add_ace(&old->dacl, &sd->dacl->aces[i], ctx); 05261 } 05262 } 05263 dacl = old->dacl; 05264 break; 05265 05266 case SMBC_XATTR_MODE_SET: 05267 old = sd; 05268 owner_sid = old->owner_sid; 05269 group_sid = old->group_sid; 05270 dacl = old->dacl; 05271 break; 05272 05273 case SMBC_XATTR_MODE_CHOWN: 05274 owner_sid = sd->owner_sid; 05275 break; 05276 05277 case SMBC_XATTR_MODE_CHGRP: 05278 group_sid = sd->group_sid; 05279 break; 05280 } 05281 05282 /* Denied ACE entries must come before allowed ones */ 05283 sort_acl(old->dacl); 05284 05285 /* Create new security descriptor and set it */ 05286 sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, 05287 owner_sid, group_sid, NULL, dacl, &sd_size); 05288 05289 fnum = cli_nt_create(cli, filename, 05290 WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS); 05291 05292 if (fnum == -1) { 05293 DEBUG(5, ("cacl_set failed to open %s: %s\n", 05294 filename, cli_errstr(cli))); 05295 errno = 0; 05296 return -1; 05297 } 05298 05299 if (!cli_set_secdesc(cli, fnum, sd)) { 05300 DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(cli))); 05301 ret = -1; 05302 } 05303 05304 /* Clean up */ 05305 05306 failed: 05307 cli_close(cli, fnum); 05308 05309 if (err != 0) { 05310 errno = err; 05311 } 05312 05313 return ret; 05314 }
static int smbc_setxattr_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
const char * | name, | |||
const void * | value, | |||
size_t | size, | |||
int | flags | |||
) | [static] |
libsmbclient.c の 5318 行で定義されています。
参照先 smbc_internal_data::_full_time_names・smbc_internal_data::_initialized・DOS_ATTR_DESC::access_time・cacl_set()・DOS_ATTR_DESC::change_time・_SMBCSRV::cli・DOS_ATTR_DESC::create_time・ctx・dos_attr_parse()・dos_attr_query()・errno・_SMBCCTX::internal・DOS_ATTR_DESC::mode・_SMBCSRV::no_nt_session・password・pol・server・share・smbc_attr_server()・smbc_parse_path()・smbc_server()・smbc_setatr()・StrCaseCmp()・StrnCaseCmp()・talloc_asprintf()・talloc_init()・_SMBCCTX::user・workgroup・DOS_ATTR_DESC::write_time.
参照元 smbc_new_context().
05324 { 05325 int ret; 05326 int ret2; 05327 SMBCSRV *srv; 05328 SMBCSRV *ipc_srv; 05329 fstring server; 05330 fstring share; 05331 fstring user; 05332 fstring password; 05333 fstring workgroup; 05334 pstring path; 05335 TALLOC_CTX *ctx; 05336 POLICY_HND pol; 05337 DOS_ATTR_DESC *dad; 05338 struct { 05339 const char * create_time_attr; 05340 const char * access_time_attr; 05341 const char * write_time_attr; 05342 const char * change_time_attr; 05343 } attr_strings; 05344 05345 if (!context || !context->internal || 05346 !context->internal->_initialized) { 05347 05348 errno = EINVAL; /* Best I can think of ... */ 05349 return -1; 05350 05351 } 05352 05353 if (!fname) { 05354 05355 errno = EINVAL; 05356 return -1; 05357 05358 } 05359 05360 DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", 05361 fname, name, (int) size, (const char*)value)); 05362 05363 if (smbc_parse_path(context, fname, 05364 workgroup, sizeof(workgroup), 05365 server, sizeof(server), 05366 share, sizeof(share), 05367 path, sizeof(path), 05368 user, sizeof(user), 05369 password, sizeof(password), 05370 NULL, 0)) { 05371 errno = EINVAL; 05372 return -1; 05373 } 05374 05375 if (user[0] == (char)0) fstrcpy(user, context->user); 05376 05377 srv = smbc_server(context, True, 05378 server, share, workgroup, user, password); 05379 if (!srv) { 05380 return -1; /* errno set by smbc_server */ 05381 } 05382 05383 if (! srv->no_nt_session) { 05384 ipc_srv = smbc_attr_server(context, server, share, 05385 workgroup, user, password, 05386 &pol); 05387 if (! ipc_srv) { 05388 srv->no_nt_session = True; 05389 } 05390 } else { 05391 ipc_srv = NULL; 05392 } 05393 05394 ctx = talloc_init("smbc_setxattr"); 05395 if (!ctx) { 05396 errno = ENOMEM; 05397 return -1; 05398 } 05399 05400 /* 05401 * Are they asking to set the entire set of known attributes? 05402 */ 05403 if (StrCaseCmp(name, "system.*") == 0 || 05404 StrCaseCmp(name, "system.*+") == 0) { 05405 /* Yup. */ 05406 char *namevalue = 05407 talloc_asprintf(ctx, "%s:%s", 05408 name+7, (const char *) value); 05409 if (! namevalue) { 05410 errno = ENOMEM; 05411 ret = -1; 05412 return -1; 05413 } 05414 05415 if (ipc_srv) { 05416 ret = cacl_set(ctx, srv->cli, 05417 ipc_srv->cli, &pol, path, 05418 namevalue, 05419 (*namevalue == '*' 05420 ? SMBC_XATTR_MODE_SET 05421 : SMBC_XATTR_MODE_ADD), 05422 flags); 05423 } else { 05424 ret = 0; 05425 } 05426 05427 /* get a DOS Attribute Descriptor with current attributes */ 05428 dad = dos_attr_query(context, ctx, path, srv); 05429 if (dad) { 05430 /* Overwrite old with new, using what was provided */ 05431 dos_attr_parse(context, dad, srv, namevalue); 05432 05433 /* Set the new DOS attributes */ 05434 if (! smbc_setatr(context, srv, path, 05435 dad->create_time, 05436 dad->access_time, 05437 dad->write_time, 05438 dad->change_time, 05439 dad->mode)) { 05440 05441 /* cause failure if NT failed too */ 05442 dad = NULL; 05443 } 05444 } 05445 05446 /* we only fail if both NT and DOS sets failed */ 05447 if (ret < 0 && ! dad) { 05448 ret = -1; /* in case dad was null */ 05449 } 05450 else { 05451 ret = 0; 05452 } 05453 05454 talloc_destroy(ctx); 05455 return ret; 05456 } 05457 05458 /* 05459 * Are they asking to set an access control element or to set 05460 * the entire access control list? 05461 */ 05462 if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || 05463 StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || 05464 StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || 05465 StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || 05466 StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { 05467 05468 /* Yup. */ 05469 char *namevalue = 05470 talloc_asprintf(ctx, "%s:%s", 05471 name+19, (const char *) value); 05472 05473 if (! ipc_srv) { 05474 ret = -1; /* errno set by smbc_server() */ 05475 } 05476 else if (! namevalue) { 05477 errno = ENOMEM; 05478 ret = -1; 05479 } else { 05480 ret = cacl_set(ctx, srv->cli, 05481 ipc_srv->cli, &pol, path, 05482 namevalue, 05483 (*namevalue == '*' 05484 ? SMBC_XATTR_MODE_SET 05485 : SMBC_XATTR_MODE_ADD), 05486 flags); 05487 } 05488 talloc_destroy(ctx); 05489 return ret; 05490 } 05491 05492 /* 05493 * Are they asking to set the owner? 05494 */ 05495 if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || 05496 StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { 05497 05498 /* Yup. */ 05499 char *namevalue = 05500 talloc_asprintf(ctx, "%s:%s", 05501 name+19, (const char *) value); 05502 05503 if (! ipc_srv) { 05504 05505 ret = -1; /* errno set by smbc_server() */ 05506 } 05507 else if (! namevalue) { 05508 errno = ENOMEM; 05509 ret = -1; 05510 } else { 05511 ret = cacl_set(ctx, srv->cli, 05512 ipc_srv->cli, &pol, path, 05513 namevalue, SMBC_XATTR_MODE_CHOWN, 0); 05514 } 05515 talloc_destroy(ctx); 05516 return ret; 05517 } 05518 05519 /* 05520 * Are they asking to set the group? 05521 */ 05522 if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || 05523 StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { 05524 05525 /* Yup. */ 05526 char *namevalue = 05527 talloc_asprintf(ctx, "%s:%s", 05528 name+19, (const char *) value); 05529 05530 if (! ipc_srv) { 05531 /* errno set by smbc_server() */ 05532 ret = -1; 05533 } 05534 else if (! namevalue) { 05535 errno = ENOMEM; 05536 ret = -1; 05537 } else { 05538 ret = cacl_set(ctx, srv->cli, 05539 ipc_srv->cli, &pol, path, 05540 namevalue, SMBC_XATTR_MODE_CHOWN, 0); 05541 } 05542 talloc_destroy(ctx); 05543 return ret; 05544 } 05545 05546 /* Determine whether to use old-style or new-style attribute names */ 05547 if (context->internal->_full_time_names) { 05548 /* new-style names */ 05549 attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; 05550 attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; 05551 attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; 05552 attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; 05553 } else { 05554 /* old-style names */ 05555 attr_strings.create_time_attr = NULL; 05556 attr_strings.access_time_attr = "system.dos_attr.A_TIME"; 05557 attr_strings.write_time_attr = "system.dos_attr.M_TIME"; 05558 attr_strings.change_time_attr = "system.dos_attr.C_TIME"; 05559 } 05560 05561 /* 05562 * Are they asking to set a DOS attribute? 05563 */ 05564 if (StrCaseCmp(name, "system.dos_attr.*") == 0 || 05565 StrCaseCmp(name, "system.dos_attr.mode") == 0 || 05566 (attr_strings.create_time_attr != NULL && 05567 StrCaseCmp(name, attr_strings.create_time_attr) == 0) || 05568 StrCaseCmp(name, attr_strings.access_time_attr) == 0 || 05569 StrCaseCmp(name, attr_strings.write_time_attr) == 0 || 05570 StrCaseCmp(name, attr_strings.change_time_attr) == 0) { 05571 05572 /* get a DOS Attribute Descriptor with current attributes */ 05573 dad = dos_attr_query(context, ctx, path, srv); 05574 if (dad) { 05575 char *namevalue = 05576 talloc_asprintf(ctx, "%s:%s", 05577 name+16, (const char *) value); 05578 if (! namevalue) { 05579 errno = ENOMEM; 05580 ret = -1; 05581 } else { 05582 /* Overwrite old with provided new params */ 05583 dos_attr_parse(context, dad, srv, namevalue); 05584 05585 /* Set the new DOS attributes */ 05586 ret2 = smbc_setatr(context, srv, path, 05587 dad->create_time, 05588 dad->access_time, 05589 dad->write_time, 05590 dad->change_time, 05591 dad->mode); 05592 05593 /* ret2 has True (success) / False (failure) */ 05594 if (ret2) { 05595 ret = 0; 05596 } else { 05597 ret = -1; 05598 } 05599 } 05600 } else { 05601 ret = -1; 05602 } 05603 05604 talloc_destroy(ctx); 05605 return ret; 05606 } 05607 05608 /* Unsupported attribute name */ 05609 talloc_destroy(ctx); 05610 errno = EINVAL; 05611 return -1; 05612 }
static int smbc_getxattr_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
const char * | name, | |||
const void * | value, | |||
size_t | size | |||
) | [static] |
libsmbclient.c の 5615 行で定義されています。
参照先 smbc_internal_data::_full_time_names・smbc_internal_data::_initialized・cacl_get()・_SMBCSRV::cli・ctx・errno・_SMBCCTX::internal・_SMBCSRV::no_nt_session・password・pol・server・share・smbc_attr_server()・smbc_errno()・smbc_parse_path()・smbc_server()・StrCaseCmp()・StrnCaseCmp()・talloc_init()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
05620 { 05621 int ret; 05622 SMBCSRV *srv; 05623 SMBCSRV *ipc_srv; 05624 fstring server; 05625 fstring share; 05626 fstring user; 05627 fstring password; 05628 fstring workgroup; 05629 pstring path; 05630 TALLOC_CTX *ctx; 05631 POLICY_HND pol; 05632 struct { 05633 const char * create_time_attr; 05634 const char * access_time_attr; 05635 const char * write_time_attr; 05636 const char * change_time_attr; 05637 } attr_strings; 05638 05639 05640 if (!context || !context->internal || 05641 !context->internal->_initialized) { 05642 05643 errno = EINVAL; /* Best I can think of ... */ 05644 return -1; 05645 05646 } 05647 05648 if (!fname) { 05649 05650 errno = EINVAL; 05651 return -1; 05652 05653 } 05654 05655 DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); 05656 05657 if (smbc_parse_path(context, fname, 05658 workgroup, sizeof(workgroup), 05659 server, sizeof(server), 05660 share, sizeof(share), 05661 path, sizeof(path), 05662 user, sizeof(user), 05663 password, sizeof(password), 05664 NULL, 0)) { 05665 errno = EINVAL; 05666 return -1; 05667 } 05668 05669 if (user[0] == (char)0) fstrcpy(user, context->user); 05670 05671 srv = smbc_server(context, True, 05672 server, share, workgroup, user, password); 05673 if (!srv) { 05674 return -1; /* errno set by smbc_server */ 05675 } 05676 05677 if (! srv->no_nt_session) { 05678 ipc_srv = smbc_attr_server(context, server, share, 05679 workgroup, user, password, 05680 &pol); 05681 if (! ipc_srv) { 05682 srv->no_nt_session = True; 05683 } 05684 } else { 05685 ipc_srv = NULL; 05686 } 05687 05688 ctx = talloc_init("smbc:getxattr"); 05689 if (!ctx) { 05690 errno = ENOMEM; 05691 return -1; 05692 } 05693 05694 /* Determine whether to use old-style or new-style attribute names */ 05695 if (context->internal->_full_time_names) { 05696 /* new-style names */ 05697 attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; 05698 attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; 05699 attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; 05700 attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; 05701 } else { 05702 /* old-style names */ 05703 attr_strings.create_time_attr = NULL; 05704 attr_strings.access_time_attr = "system.dos_attr.A_TIME"; 05705 attr_strings.write_time_attr = "system.dos_attr.M_TIME"; 05706 attr_strings.change_time_attr = "system.dos_attr.C_TIME"; 05707 } 05708 05709 /* Are they requesting a supported attribute? */ 05710 if (StrCaseCmp(name, "system.*") == 0 || 05711 StrnCaseCmp(name, "system.*!", 9) == 0 || 05712 StrCaseCmp(name, "system.*+") == 0 || 05713 StrnCaseCmp(name, "system.*+!", 10) == 0 || 05714 StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || 05715 StrnCaseCmp(name, "system.nt_sec_desc.*!", 21) == 0 || 05716 StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || 05717 StrnCaseCmp(name, "system.nt_sec_desc.*+!", 22) == 0 || 05718 StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || 05719 StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || 05720 StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || 05721 StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || 05722 StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || 05723 StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || 05724 StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 || 05725 StrCaseCmp(name, "system.dos_attr.*") == 0 || 05726 StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 || 05727 StrCaseCmp(name, "system.dos_attr.mode") == 0 || 05728 StrCaseCmp(name, "system.dos_attr.size") == 0 || 05729 (attr_strings.create_time_attr != NULL && 05730 StrCaseCmp(name, attr_strings.create_time_attr) == 0) || 05731 StrCaseCmp(name, attr_strings.access_time_attr) == 0 || 05732 StrCaseCmp(name, attr_strings.write_time_attr) == 0 || 05733 StrCaseCmp(name, attr_strings.change_time_attr) == 0 || 05734 StrCaseCmp(name, "system.dos_attr.inode") == 0) { 05735 05736 /* Yup. */ 05737 ret = cacl_get(context, ctx, srv, 05738 ipc_srv == NULL ? NULL : ipc_srv->cli, 05739 &pol, path, 05740 CONST_DISCARD(char *, name), 05741 CONST_DISCARD(char *, value), size); 05742 if (ret < 0 && errno == 0) { 05743 errno = smbc_errno(context, srv->cli); 05744 } 05745 talloc_destroy(ctx); 05746 return ret; 05747 } 05748 05749 /* Unsupported attribute name */ 05750 talloc_destroy(ctx); 05751 errno = EINVAL; 05752 return -1; 05753 }
static int smbc_removexattr_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
const char * | name | |||
) | [static] |
libsmbclient.c の 5757 行で定義されています。
参照先 smbc_internal_data::_initialized・cacl_set()・_SMBCSRV::cli・ctx・errno・_SMBCCTX::internal・_SMBCSRV::no_nt_session・password・pol・server・share・smbc_attr_server()・smbc_parse_path()・smbc_server()・StrCaseCmp()・StrnCaseCmp()・talloc_init()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
05760 { 05761 int ret; 05762 SMBCSRV *srv; 05763 SMBCSRV *ipc_srv; 05764 fstring server; 05765 fstring share; 05766 fstring user; 05767 fstring password; 05768 fstring workgroup; 05769 pstring path; 05770 TALLOC_CTX *ctx; 05771 POLICY_HND pol; 05772 05773 if (!context || !context->internal || 05774 !context->internal->_initialized) { 05775 05776 errno = EINVAL; /* Best I can think of ... */ 05777 return -1; 05778 05779 } 05780 05781 if (!fname) { 05782 05783 errno = EINVAL; 05784 return -1; 05785 05786 } 05787 05788 DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); 05789 05790 if (smbc_parse_path(context, fname, 05791 workgroup, sizeof(workgroup), 05792 server, sizeof(server), 05793 share, sizeof(share), 05794 path, sizeof(path), 05795 user, sizeof(user), 05796 password, sizeof(password), 05797 NULL, 0)) { 05798 errno = EINVAL; 05799 return -1; 05800 } 05801 05802 if (user[0] == (char)0) fstrcpy(user, context->user); 05803 05804 srv = smbc_server(context, True, 05805 server, share, workgroup, user, password); 05806 if (!srv) { 05807 return -1; /* errno set by smbc_server */ 05808 } 05809 05810 if (! srv->no_nt_session) { 05811 ipc_srv = smbc_attr_server(context, server, share, 05812 workgroup, user, password, 05813 &pol); 05814 if (! ipc_srv) { 05815 srv->no_nt_session = True; 05816 } 05817 } else { 05818 ipc_srv = NULL; 05819 } 05820 05821 if (! ipc_srv) { 05822 return -1; /* errno set by smbc_attr_server */ 05823 } 05824 05825 ctx = talloc_init("smbc_removexattr"); 05826 if (!ctx) { 05827 errno = ENOMEM; 05828 return -1; 05829 } 05830 05831 /* Are they asking to set the entire ACL? */ 05832 if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || 05833 StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { 05834 05835 /* Yup. */ 05836 ret = cacl_set(ctx, srv->cli, 05837 ipc_srv->cli, &pol, path, 05838 NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); 05839 talloc_destroy(ctx); 05840 return ret; 05841 } 05842 05843 /* 05844 * Are they asking to remove one or more spceific security descriptor 05845 * attributes? 05846 */ 05847 if (StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || 05848 StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || 05849 StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || 05850 StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || 05851 StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || 05852 StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || 05853 StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { 05854 05855 /* Yup. */ 05856 ret = cacl_set(ctx, srv->cli, 05857 ipc_srv->cli, &pol, path, 05858 name + 19, SMBC_XATTR_MODE_REMOVE, 0); 05859 talloc_destroy(ctx); 05860 return ret; 05861 } 05862 05863 /* Unsupported attribute name */ 05864 talloc_destroy(ctx); 05865 errno = EINVAL; 05866 return -1; 05867 }
static int smbc_listxattr_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
char * | list, | |||
size_t | size | |||
) | [static] |
libsmbclient.c の 5870 行で定義されています。
参照先 smbc_internal_data::_full_time_names・errno・_SMBCCTX::internal.
参照元 smbc_new_context().
05874 { 05875 /* 05876 * This isn't quite what listxattr() is supposed to do. This returns 05877 * the complete set of attribute names, always, rather than only those 05878 * attribute names which actually exist for a file. Hmmm... 05879 */ 05880 const char supported_old[] = 05881 "system.*\0" 05882 "system.*+\0" 05883 "system.nt_sec_desc.revision\0" 05884 "system.nt_sec_desc.owner\0" 05885 "system.nt_sec_desc.owner+\0" 05886 "system.nt_sec_desc.group\0" 05887 "system.nt_sec_desc.group+\0" 05888 "system.nt_sec_desc.acl.*\0" 05889 "system.nt_sec_desc.acl\0" 05890 "system.nt_sec_desc.acl+\0" 05891 "system.nt_sec_desc.*\0" 05892 "system.nt_sec_desc.*+\0" 05893 "system.dos_attr.*\0" 05894 "system.dos_attr.mode\0" 05895 "system.dos_attr.c_time\0" 05896 "system.dos_attr.a_time\0" 05897 "system.dos_attr.m_time\0" 05898 ; 05899 const char supported_new[] = 05900 "system.*\0" 05901 "system.*+\0" 05902 "system.nt_sec_desc.revision\0" 05903 "system.nt_sec_desc.owner\0" 05904 "system.nt_sec_desc.owner+\0" 05905 "system.nt_sec_desc.group\0" 05906 "system.nt_sec_desc.group+\0" 05907 "system.nt_sec_desc.acl.*\0" 05908 "system.nt_sec_desc.acl\0" 05909 "system.nt_sec_desc.acl+\0" 05910 "system.nt_sec_desc.*\0" 05911 "system.nt_sec_desc.*+\0" 05912 "system.dos_attr.*\0" 05913 "system.dos_attr.mode\0" 05914 "system.dos_attr.create_time\0" 05915 "system.dos_attr.access_time\0" 05916 "system.dos_attr.write_time\0" 05917 "system.dos_attr.change_time\0" 05918 ; 05919 const char * supported; 05920 05921 if (context->internal->_full_time_names) { 05922 supported = supported_new; 05923 } else { 05924 supported = supported_old; 05925 } 05926 05927 if (size == 0) { 05928 return sizeof(supported); 05929 } 05930 05931 if (sizeof(supported) > size) { 05932 errno = ERANGE; 05933 return -1; 05934 } 05935 05936 /* this can't be strcpy() because there are embedded null characters */ 05937 memcpy(list, supported, sizeof(supported)); 05938 return sizeof(supported); 05939 }
libsmbclient.c の 5947 行で定義されています。
参照先 smbc_internal_data::_initialized・errno・_SMBCCTX::internal・_SMBCCTX::open・password・server・share・smbc_parse_path().
参照元 smbc_new_context().
05949 { 05950 fstring server; 05951 fstring share; 05952 fstring user; 05953 fstring password; 05954 pstring path; 05955 05956 if (!context || !context->internal || 05957 !context->internal->_initialized) { 05958 05959 errno = EINVAL; 05960 return NULL; 05961 05962 } 05963 05964 if (!fname) { 05965 05966 errno = EINVAL; 05967 return NULL; 05968 05969 } 05970 05971 DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); 05972 05973 if (smbc_parse_path(context, fname, 05974 NULL, 0, 05975 server, sizeof(server), 05976 share, sizeof(share), 05977 path, sizeof(path), 05978 user, sizeof(user), 05979 password, sizeof(password), 05980 NULL, 0)) { 05981 errno = EINVAL; 05982 return NULL; 05983 } 05984 05985 /* What if the path is empty, or the file exists? */ 05986 05987 return (context->open)(context, fname, O_WRONLY, 666); 05988 05989 }
static int smbc_print_file_ctx | ( | SMBCCTX * | c_file, | |
const char * | fname, | |||
SMBCCTX * | c_print, | |||
const char * | printq | |||
) | [static] |
libsmbclient.c の 5999 行で定義されています。
参照先 smbc_internal_data::_initialized・buf・_SMBCCTX::close_fn・errno・_SMBCCTX::internal・_SMBCCTX::open・_SMBCCTX::open_print_job・_SMBCCTX::read・_SMBCCTX::write.
参照元 smbc_new_context().
06003 { 06004 SMBCFILE *fid1; 06005 SMBCFILE *fid2; 06006 int bytes; 06007 int saverr; 06008 int tot_bytes = 0; 06009 char buf[4096]; 06010 06011 if (!c_file || !c_file->internal->_initialized || !c_print || 06012 !c_print->internal->_initialized) { 06013 06014 errno = EINVAL; 06015 return -1; 06016 06017 } 06018 06019 if (!fname && !printq) { 06020 06021 errno = EINVAL; 06022 return -1; 06023 06024 } 06025 06026 /* Try to open the file for reading ... */ 06027 06028 if ((long)(fid1 = (c_file->open)(c_file, fname, O_RDONLY, 0666)) < 0) { 06029 06030 DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); 06031 return -1; /* smbc_open sets errno */ 06032 06033 } 06034 06035 /* Now, try to open the printer file for writing */ 06036 06037 if ((long)(fid2 = (c_print->open_print_job)(c_print, printq)) < 0) { 06038 06039 saverr = errno; /* Save errno */ 06040 (c_file->close_fn)(c_file, fid1); 06041 errno = saverr; 06042 return -1; 06043 06044 } 06045 06046 while ((bytes = (c_file->read)(c_file, fid1, buf, sizeof(buf))) > 0) { 06047 06048 tot_bytes += bytes; 06049 06050 if (((c_print->write)(c_print, fid2, buf, bytes)) < 0) { 06051 06052 saverr = errno; 06053 (c_file->close_fn)(c_file, fid1); 06054 (c_print->close_fn)(c_print, fid2); 06055 errno = saverr; 06056 06057 } 06058 06059 } 06060 06061 saverr = errno; 06062 06063 (c_file->close_fn)(c_file, fid1); /* We have to close these anyway */ 06064 (c_print->close_fn)(c_print, fid2); 06065 06066 if (bytes < 0) { 06067 06068 errno = saverr; 06069 return -1; 06070 06071 } 06072 06073 return tot_bytes; 06074 06075 }
static int smbc_list_print_jobs_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
smbc_list_print_job_fn | fn | |||
) | [static] |
libsmbclient.c の 6082 行で定義されています。
参照先 smbc_internal_data::_initialized・_SMBCSRV::cli・cli_print_queue()・errno・_SMBCCTX::internal・password・server・share・smbc_errno()・smbc_parse_path()・smbc_server()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
06085 { 06086 SMBCSRV *srv; 06087 fstring server; 06088 fstring share; 06089 fstring user; 06090 fstring password; 06091 fstring workgroup; 06092 pstring path; 06093 06094 if (!context || !context->internal || 06095 !context->internal->_initialized) { 06096 06097 errno = EINVAL; 06098 return -1; 06099 06100 } 06101 06102 if (!fname) { 06103 06104 errno = EINVAL; 06105 return -1; 06106 06107 } 06108 06109 DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); 06110 06111 if (smbc_parse_path(context, fname, 06112 workgroup, sizeof(workgroup), 06113 server, sizeof(server), 06114 share, sizeof(share), 06115 path, sizeof(path), 06116 user, sizeof(user), 06117 password, sizeof(password), 06118 NULL, 0)) { 06119 errno = EINVAL; 06120 return -1; 06121 } 06122 06123 if (user[0] == (char)0) fstrcpy(user, context->user); 06124 06125 srv = smbc_server(context, True, 06126 server, share, workgroup, user, password); 06127 06128 if (!srv) { 06129 06130 return -1; /* errno set by smbc_server */ 06131 06132 } 06133 06134 if (cli_print_queue(srv->cli, 06135 (void (*)(struct print_job_info *))fn) < 0) { 06136 06137 errno = smbc_errno(context, srv->cli); 06138 return -1; 06139 06140 } 06141 06142 return 0; 06143 06144 }
static int smbc_unlink_print_job_ctx | ( | SMBCCTX * | context, | |
const char * | fname, | |||
int | id | |||
) | [static] |
libsmbclient.c の 6151 行で定義されています。
参照先 smbc_internal_data::_initialized・_SMBCSRV::cli・cli_printjob_del()・err・errno・_SMBCCTX::internal・password・server・share・smbc_errno()・smbc_parse_path()・smbc_server()・_SMBCCTX::user・workgroup.
参照元 smbc_new_context().
06154 { 06155 SMBCSRV *srv; 06156 fstring server; 06157 fstring share; 06158 fstring user; 06159 fstring password; 06160 fstring workgroup; 06161 pstring path; 06162 int err; 06163 06164 if (!context || !context->internal || 06165 !context->internal->_initialized) { 06166 06167 errno = EINVAL; 06168 return -1; 06169 06170 } 06171 06172 if (!fname) { 06173 06174 errno = EINVAL; 06175 return -1; 06176 06177 } 06178 06179 DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); 06180 06181 if (smbc_parse_path(context, fname, 06182 workgroup, sizeof(workgroup), 06183 server, sizeof(server), 06184 share, sizeof(share), 06185 path, sizeof(path), 06186 user, sizeof(user), 06187 password, sizeof(password), 06188 NULL, 0)) { 06189 errno = EINVAL; 06190 return -1; 06191 } 06192 06193 if (user[0] == (char)0) fstrcpy(user, context->user); 06194 06195 srv = smbc_server(context, True, 06196 server, share, workgroup, user, password); 06197 06198 if (!srv) { 06199 06200 return -1; /* errno set by smbc_server */ 06201 06202 } 06203 06204 if ((err = cli_printjob_del(srv->cli, id)) != 0) { 06205 06206 if (err < 0) 06207 errno = smbc_errno(context, srv->cli); 06208 else if (err == ERRnosuchprintjob) 06209 errno = EINVAL; 06210 return -1; 06211 06212 } 06213 06214 return 0; 06215 06216 }
void* smbc_option_get | ( | SMBCCTX * | context, | |
char * | option_name | |||
) |
libsmbclient.c の 6450 行で定義されています。
参照先 smbc_internal_data::_auth_fn_with_context・smbc_internal_data::_debug_stderr・smbc_internal_data::_full_time_names・smbc_internal_data::_user_data・_SMBCCTX::internal.
06452 { 06453 if (strcmp(option_name, "debug_stderr") == 0) { 06454 /* 06455 * Log to standard error instead of standard output. 06456 */ 06457 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) 06458 return (void *) (intptr_t) context->internal->_debug_stderr; 06459 #else 06460 return (void *) context->internal->_debug_stderr; 06461 #endif 06462 } else if (strcmp(option_name, "full_time_names") == 0) { 06463 /* 06464 * Use new-style time attribute names, e.g. WRITE_TIME rather 06465 * than the old-style names such as M_TIME. This allows also 06466 * setting/getting CREATE_TIME which was previously 06467 * unimplemented. (Note that the old C_TIME was supposed to 06468 * be CHANGE_TIME but was confused and sometimes referred to 06469 * CREATE_TIME.) 06470 */ 06471 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) 06472 return (void *) (intptr_t) context->internal->_full_time_names; 06473 #else 06474 return (void *) context->internal->_full_time_names; 06475 #endif 06476 06477 } else if (strcmp(option_name, "auth_function") == 0) { 06478 /* 06479 * Use the new-style authentication function which includes 06480 * the context. 06481 */ 06482 return (void *) context->internal->_auth_fn_with_context; 06483 } else if (strcmp(option_name, "user_data") == 0) { 06484 /* 06485 * Save a user data handle which may be retrieved by the user 06486 * with smbc_option_get() 06487 */ 06488 return context->internal->_user_data; 06489 } 06490 06491 return NULL; 06492 }
loadparm.c の 56 行で定義されています。
int smbc_initialized = 0 [static] |
const char* smbc_prefix = "smb:" [static] |
int creat_bits = O_WRONLY | O_CREAT | O_TRUNC [static] |
int smbc_rmdir_dirempty = True [static] |
libsmbclient.c の 3298 行で定義されています。