/* * SMB_Mount */ int32_t SMBNetFsMount(SMBHANDLE inConnection, CFURLRef url, CFStringRef mPoint, CFDictionaryRef mOptions, CFDictionaryRef *mInfo, void (*callout)(void *, void *), void *args) { int error = 0; struct smb_ctx *hContext = NULL; SMBServerContext(inConnection, (void **)&hContext); /* Now deal with the URL, need a better way of handling this in the future */ if (hContext->ct_url) { CFRelease(hContext->ct_url); } hContext->ct_url = CFURLCopyAbsoluteURL(url); if (hContext->ct_url) { error = ParseSMBURL(hContext); } else { error = ENOMEM; } if (error) { return error; } return smb_mount(hContext, mPoint, mOptions, mInfo, callout, args); }
void *smb_getdir(void *value) { int err, dh1, dsize, dirc, i, count; char dirbuf[2048] = {0}; struct smbc_dirent *dirp; char url[MAX_NAME_LEN] = {0}; char buf[MAX_NAME_LEN] = {0}; char tmpdirname[MAX_NAME_LEN] = {0}; char dir_path[MAX_NAME_LEN] = {0}; int ret, mount_ok_num, mount_fail_num; char *p = NULL; struct smbserverinfo_t *psmbserverinfo = NULL; struct smbEventProxyCmd *pevent = NULL; if(value == NULL) return NULL; psmbserverinfo = (struct smbserverinfo_t *)value; printf("%s[%d], name = [%s], ip = [%s], user = [%s], passwd = [%s], cmd_id = [%d]\n", __FILE__, __LINE__, psmbserverinfo->name, psmbserverinfo->ip, psmbserverinfo->user, psmbserverinfo->passwd, psmbserverinfo->cmd_id); memset(smb_username, 0, sizeof(smb_username)); memset(smb_passwd, 0, sizeof(smb_passwd)); if(psmbserverinfo->user != NULL) { strncpy(smb_username, psmbserverinfo->user, strlen(psmbserverinfo->user)); smb_username[strlen(psmbserverinfo->user)] = '\0'; } if(psmbserverinfo->passwd != NULL) { strncpy(smb_passwd, psmbserverinfo->passwd, strlen(psmbserverinfo->passwd)); smb_passwd[strlen(psmbserverinfo->passwd)] = '\0'; } printf("%s[%d], smb_username = [%s], smb_passwd = [%s]\n", __FILE__, __LINE__, smb_username, smb_passwd); snprintf(url, sizeof(url), "smb://%s:%s@%s", smb_username, smb_passwd, psmbserverinfo->name); err = smbc_init(get_static_auth_data_fn, 0); /* Initialize things */ if (err < 0) { printf("%s[%d], Initializing the smbclient library ...: %s\n", __FILE__, __LINE__, strerror(errno)); SMBTREE_send_event_to_OSD(SMB_CMD_BROWSE_RESPONSE, SMB_MOUNT_FAILED, psmbserverinfo->cmd_id, NULL); SMBTREE_free_smbserverinfo(psmbserverinfo); return NULL; } if ((dh1 = smbc_opendir(url))<1) { printf("%s[%d], Could not open directory: %s: %s\n", __FILE__, __LINE__, url, strerror(errno)); SMBTREE_send_event_to_OSD(SMB_CMD_BROWSE_RESPONSE, SMB_MOUNT_FAILED, psmbserverinfo->cmd_id, NULL); SMBTREE_free_smbserverinfo(psmbserverinfo); return NULL; } snprintf(dir_path, sizeof(dir_path), "%s/%s", CONF_SAMBA_MOUNT_POINT, psmbserverinfo->name); smb_umount(dir_path); /* Now, list those directories, but in funny ways ... */ /* keep call smbc_getdents() until there is no share folder to fix Device only can browse less than 8 root folder.*/ while(0 != (dirc = smbc_getdents(dh1, (struct smbc_dirent *)dirbuf, sizeof(dirbuf)))) { if(dirc < 0) { fprintf(stderr, "Problems getting directory entries: %s\n", strerror(errno)); smbc_closedir(dh1); SMBTREE_send_event_to_OSD(SMB_CMD_BROWSE_RESPONSE, SMB_MOUNT_FAILED, psmbserverinfo->cmd_id, NULL); SMBTREE_free_smbserverinfo(psmbserverinfo); return NULL; } /* Now, process the list of names ... */ fprintf(stdout, "Directory listing, size = %u\n", dirc); dirp = (struct smbc_dirent *)dirbuf; count = 0; mount_ok_num = 0; mount_fail_num = 0; while (dirc > 0) { dsize = dirp->dirlen; switch (dirp->smbc_type) { case SMBC_DIR: case SMBC_FILE: case SMBC_FILE_SHARE: snprintf(buf, sizeof(buf), "%s\\%s\\%s", psmbserverinfo->name, psmbserverinfo->ip, dirp->name); fprintf(stdout, "Shared Dir Type: %u, Name: %s\n", dirp->smbc_type, dirp->name); /*if share-folder-name is end of $, system doesn't mount it*/ if((p=strrchr(buf, '$')) != NULL && strlen(p) == 1) { printf("%s[%d], ##### %s not match ####\n", __FILE__, __LINE__, buf); break; } memset(tmpdirname, '\0', sizeof(tmpdirname)); smb_replace_special_char(dirp->name, tmpdirname); ret = smb_mount(psmbserverinfo->user, psmbserverinfo->passwd, psmbserverinfo->name, psmbserverinfo->ip, tmpdirname); if (ret == 0) { #ifdef ENABLE_PTHREAD pevent = malloc(sizeof(struct smbEventProxyCmd)); pevent->cmd = SMB_CMD_BROWSE_RESPONSE; pevent->status = SMB_MOUNTING; pevent->id = psmbserverinfo->cmd_id; pevent->datalen = strlen(buf) + 1; strcpy((char *)pevent->data, buf); XLinkedList_Lock(sharefolderlist); XLinkedList_AddTail(sharefolderlist, (void *)pevent); XLinkedList_UnLock(sharefolderlist); #else SMBTREE_send_event_to_OSD(SMB_CMD_BROWSE_RESPONSE, SMB_MOUNTING, psmbserverinfo->cmd_id, buf); #endif mount_ok_num++; } else { mount_fail_num++; } break; default: break; } i = dsize % 4 == 0 ? 0 : (4 - dsize % 4); dsize += i; count += dsize; dirp = (struct smbc_dirent *)(dirbuf + count); dirc -= dsize; } memset(dirbuf, 0, sizeof(dirbuf)); } smbc_closedir(dh1); if(mount_fail_num > 0 && mount_ok_num == 0) { SMBTREE_send_event_to_OSD(SMB_CMD_BROWSE_RESPONSE, SMB_MOUNT_FAILED, psmbserverinfo->cmd_id, NULL); } else { SMBTREE_send_event_to_OSD(SMB_CMD_BROWSE_RESPONSE, SMB_MOUNT_OK, psmbserverinfo->cmd_id, NULL); } SMBTREE_free_smbserverinfo(psmbserverinfo); return NULL; }
/** * Try one mount request * * @param source NUL-terminated C string containing name of "special device" * @param target NUL-terminated C string containing local mounted-on directory * @param text_options NUL-terminated C string containing user's mount options * @return an exit status code * * Parse the pathname in "source." It contains the file system protocol * and FedFS domain name. Then pass these arguments to the appropriate * mount helper subcommand. */ static int try_mount(const char *source, const char *target, const char *text_options) { char *global_name, *topdir, *domainname, *remaining; int result; remaining = NULL; result = EX_FAIL; global_name = strdup(source); if (global_name == NULL) { fprintf(stderr, _("%s: Unable to parse globally useful name\n"), progname); goto out; } topdir = strtok(global_name, "/"); if (topdir == NULL) { fprintf(stderr, _("%s: Invalid globally useful name: %s\n"), progname, source); goto out; } if (verbose) printf(_("%s: Top-level directory: %s\n"), progname, topdir); domainname = strtok(NULL, "/"); if (domainname == NULL) { fprintf(stderr, _("%s: Missing domain name in globally " "useful name: %s\n"), progname, source); goto out; } if (verbose) printf(_("%s: Domain name: %s\n"), progname, domainname); remaining = strtok(NULL, "/"); if (remaining == NULL) { remaining = strdup("/"); if (remaining == NULL) { fprintf(stderr, _("%s: No memory\n"), progname); goto out; } } else { char *tmp; tmp = malloc(strlen(remaining) + 1); if (tmp == NULL) { fprintf(stderr, _("%s: No memory\n"), progname); remaining = NULL; goto out; } strcpy(tmp, "/"); strcat(tmp, remaining); remaining = tmp; } if (verbose) printf(_("%s: Export path: %s\n"), progname, remaining); if (strcmp(topdir, FEDFS_NFS4_TLDIR) == 0) result = nfs4_mount(domainname, remaining, target, text_options); #if 0 /* example: SMB support plugs in here */ else if (strcmp(topdir, FEDFS_SMB_TLDIR) == 0) result = smb_mount(domainname, remaining, target, text_options); #endif else fprintf(stderr, _("%s: Unrecognized file system protocol\n"), progname); out: free(global_name); free(remaining); return result; }
NTSTATUS SMBMountShareEx( SMBHANDLE inConnection, const char *targetShare, const char *mountPoint, unsigned mountFlags, uint64_t mountOptions, mode_t fileMode, mode_t dirMode, void (*callout)(void *, void *), void *args) { NTSTATUS status = STATUS_SUCCESS; int err = 0; void * hContext = NULL; CFStringRef mountPtRef = NULL; CFMutableDictionaryRef mOptions = NULL; CFNumberRef numRef = NULL; status = SMBServerContext(inConnection, &hContext); if (!NT_SUCCESS(status)) { /* Couldn't get the context? */ goto done; } mOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (mOptions == NULL) { /* Couldn't create the mount option dictionary, error out */ errno = ENOMEM; status = STATUS_NO_MEMORY; goto done; } numRef = CFNumberCreate (NULL, kCFNumberSInt32Type, &mountFlags); if (numRef) { /* Put the mount flags into the dictionary */ CFDictionarySetValue (mOptions, kNetFSMountFlagsKey, numRef); CFRelease(numRef); } if (mountOptions & kSMBMntOptionNoStreams) { /* Don't use NTFS Streams even if they are supported by the server. */ CFDictionarySetValue (mOptions, kStreamstMountKey, kCFBooleanFalse); } if (mountOptions & kSMBMntOptionNoNotifcations) { /* Don't use Remote Notifications even if they are supported by the server. */ CFDictionarySetValue (mOptions, kNotifyOffMountKey, kCFBooleanTrue); } if (mountOptions & kSMBMntOptionSoftMount) { /* Mount the volume soft, return time out error durring reconnect. */ CFDictionarySetValue (mOptions, kNetFSSoftMountKey, kCFBooleanTrue); } if (mountOptions & kSMBReservedTMMount) { /* Mount the volume as a Time Machine mount. */ CFDictionarySetValue (mOptions, kTimeMachineMountKey, kCFBooleanTrue); } /* * Specify permissions that should be assigned to files and directories. The * value must be specified as an octal numbers. A value of zero means use the * default values. Not setting these in the dictionary will force the default * values to be used. */ if (fileMode || dirMode) { if (fileMode) { numRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &fileMode); if (numRef) { CFDictionarySetValue (mOptions, kfileModeKey, numRef); CFRelease(numRef); } } if (dirMode) { numRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &dirMode); if (numRef) { CFDictionarySetValue (mOptions, kdirModeKey, numRef); CFRelease(numRef); } } } /* Get the mount point */ if (mountPoint) { mountPtRef = CFStringCreateWithCString(kCFAllocatorDefault, mountPoint, kCFStringEncodingUTF8); } if (mountPtRef == NULL) { /* No mount point */ errno = ENOMEM; status = STATUS_NO_MEMORY; goto done; } /* Set the share if they gave us one */ if (targetShare) { err = smb_ctx_setshare(hContext, targetShare); } if (err == 0) { err = smb_mount(hContext, mountPtRef, mOptions, NULL, callout, args); } if (err) { errno = err; status = STATUS_UNSUCCESSFUL; goto done; } done: if (mOptions) { CFRelease(mOptions); } if (mountPtRef) { CFRelease(mountPtRef); } return status; }