/* Update the mtab by removing any DIR entries and replace it with INSTEAD. */ void update_mtab (const char *dir, struct mntent *instead) { struct mntent *mnt; struct mntent *next; int added = 0; open_mtab ("r"); if ((F_temp = setmntent (MOUNTED_TEMP, "w")) == NULL) die (2, "can't open %s: %s", MOUNTED_TEMP, strerror (errno)); while ((mnt = getmntent (F_mtab))) { next = streq (mnt->mnt_dir, dir) ? (added++, instead) : mnt; if (next && addmntent(F_temp, next) == 1) die (1, "error writing %s: %s", MOUNTED_TEMP, strerror (errno)); } if (instead && !added) addmntent(F_temp, instead); endmntent (F_mtab); if (fchmod (fileno (F_temp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) die (1, "error changing mode of %s: %s", MOUNTED_TEMP, strerror (errno)); endmntent (F_temp); if (rename (MOUNTED_TEMP, MOUNTED) < 0) die (1, "can't rename %s to %s: %s", MOUNTED_TEMP, MOUNTED, strerror(errno)); }
static void append_mtab(FILE *fp, FILE *ofp, struct mntent *ent) { int err; struct mntent *p; while ((p = getmntent(ofp))) { err = addmntent(fp, p); if (err) AuFin("addmntent"); } err = addmntent(fp, ent); if (err) AuFin("addmntent"); }
int commandtool::automnt_part(const blockdevice *block, QString mount_point) { struct mntent *mnt; FILE *fp; fp = setmntent(FSTAB_FILE, "r"); if (fp == NULL) { util::log(QString("automount %1 error %2").arg(block->device).arg(errno)); return -1; } while ((mnt = getmntent(fp))) { QString fsname = QString(mnt->mnt_fsname); foreach(const QString& symlink, block->symlinks) { if (fsname == symlink) { endmntent(fp); return 0; //already exist; } } } endmntent(fp); //add mmntent QString device_path = QString("%1%2").arg(DEVICE_PATH_PREFIX).arg(block->id); bool found = false; foreach(const QString& symlink, block->symlinks) { if (symlink == device_path) { found = true; break; } } if (!found){ util::log(QString("automount %1 at can not found in %2 symbol links").arg(device_path).arg(block->device)); } struct mntent *m = (mntent*)calloc(1,sizeof(mntent)); m->mnt_fsname = strdup(device_path.toAscii().data()); m->mnt_dir = strdup(mount_point.toAscii().data()); m->mnt_type = strdup("ext4"); m->mnt_opts = strdup("defaults,nofail,user"); m->mnt_passno = 2; m->mnt_freq = 0; util::log(QString("mnt=%1 fsname=%2").arg(mount_point).arg(device_path)); fp = setmntent(FSTAB_FILE,"a+"); //open file for describing the mounted filesystems addmntent(fp,m); endmntent(fp); free(m->mnt_dir); free(m->mnt_fsname); free(m->mnt_type); free(m->mnt_opts); free(m); return 0; }
static int update_mtab_entry(char *spec, char *mtpt, char *type, char *opts, int flags, int freq, int pass) { FILE *fp; struct mntent mnt; int rc = 0; mnt.mnt_fsname = spec; mnt.mnt_dir = mtpt; mnt.mnt_type = type; mnt.mnt_opts = opts ? opts : ""; mnt.mnt_freq = freq; mnt.mnt_passno = pass; fp = setmntent(MOUNTED, "a+"); if (fp == NULL) { fprintf(stderr, "%s: setmntent(%s): %s:", progname, MOUNTED, strerror (errno)); rc = 16; } else { if ((addmntent(fp, &mnt)) == 1) { fprintf(stderr, "%s: addmntent: %s:", progname, strerror (errno)); rc = 16; } endmntent(fp); } return rc; }
/* * Append a mntent structure to the * current mount table. */ void write_mntent(mntent_t *mp, const char *mnttabname) { int retries = 0; FILE *mfp; if (!mtab_is_writable()) { return; } enfile: mfp = open_locked_mtab(mnttabname, "a", mp->mnt_dir); if (mfp) { mtab_stripnl(mp->mnt_opts); if (addmntent(mfp, mp)) plog(XLOG_ERROR, "Couldn't write %s: %m", mnttabname); if (fflush(mfp)) plog(XLOG_ERROR, "Couldn't flush %s: %m", mnttabname); (void) endmntent(mfp); } else { if (errno == ENFILE && retries < NFILE_RETRIES) { sleep(1); goto enfile; } plog(XLOG_ERROR, "setmntent(\"%s\", \"a\"): %m", mnttabname); } unlock_mntlist(); }
static int add_mount(const char *fsname, const char *mnt, const char *type, const char *opts) { int res; const char *mtab = _PATH_MOUNTED; struct mntent ent; FILE *fp; if (check_name(fsname) == -1 || check_name(mnt) == -1 || check_name(type) == -1 || check_name(opts) == -1) return -1; fp = setmntent(mtab, "a"); if (fp == NULL) { fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab, strerror(errno)); return -1; } ent.mnt_fsname = (char *) fsname; ent.mnt_dir = (char *) mnt; ent.mnt_type = (char *) type; ent.mnt_opts = (char *) opts; ent.mnt_freq = 0; ent.mnt_passno = 0; res = addmntent(fp, &ent); if (res != 0) { fprintf(stderr, "%s: failed to add entry to %s: %s\n", progname, mtab, strerror(errno)); return -1; } endmntent(fp); return 0; }
static int mount_it_now(struct mntent *mp, int vfsflags, char *filteropts) { int rc; if (fakeIt) { return 0; } // Mount, with fallback to read-only if necessary. for(;;) { rc = mount(mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, vfsflags, filteropts); if(!rc || (vfsflags&MS_RDONLY) || (errno!=EACCES && errno!=EROFS)) break; bb_error_msg("%s is write-protected, mounting read-only", mp->mnt_fsname); vfsflags |= MS_RDONLY; } // Abort entirely if permission denied. if (rc && errno == EPERM) bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); /* If the mount was successful, and we're maintaining an old-style * mtab file by hand, add the new entry to it now. */ if(ENABLE_FEATURE_MTAB_SUPPORT && useMtab && !rc) { FILE *mountTable = setmntent(bb_path_mtab_file, "a+"); int i; if(!mountTable) bb_error_msg("No %s\n",bb_path_mtab_file); // Add vfs string flags for(i=0; mount_options[i].flags != MS_REMOUNT; i++) if (mount_options[i].flags > 0) append_mount_options(&(mp->mnt_opts), // Shut up about the darn const. It's not important. I don't care. (char *)mount_options[i].name); // Remove trailing / (if any) from directory we mounted on i = strlen(mp->mnt_dir); if(i>1 && mp->mnt_dir[i-1] == '/') mp->mnt_dir[i-1] = 0; // Write and close. if(!mp->mnt_type || !*mp->mnt_type) mp->mnt_type="--bind"; addmntent(mountTable, mp); endmntent(mountTable); if (ENABLE_FEATURE_CLEAN_UP) if(strcmp(mp->mnt_type,"--bind")) mp->mnt_type = 0; } return rc; }
int addMountEntry (FILE *table, MountEntry *entry) { #ifdef HAVE_ADDMNTENT if (addmntent(table, entry)) { logMessage(LOG_ERR, "mounts table entry add error: %s[%s] -> %s: %s", entry->mnt_type, entry->mnt_fsname, entry->mnt_dir, strerror(errno)); return 0; } #endif /* HAVE_ADDMNTENT */ return 1; }
/* todo: there are some cases which options are not changed */ static void update_mtab(FILE *fp, char *mntpnt, int do_remount, int do_verbose) { int err; long pos; FILE *ofp; struct mntent ent, *p; /* prohibit updating mount options for this mntpnt */ au_plink_maint(mntpnt); err = au_proc_getmntent(mntpnt, &ent); if (err) AuFin("no such mount point"); ofp = setmntent(MTab, "r"); if (!ofp) AuFin(MTab); if (do_remount) { /* find the last one */ pos = -1; while ((p = getmntent(ofp))) { if (!strcmp(p->mnt_dir, mntpnt)) pos = ftell(ofp); } rewind(ofp); if (pos > 0) { while ((p = getmntent(ofp))) { if (ftell(ofp) == pos) { /* replace the line */ p = &ent; pos = -1; } err = addmntent(fp, p); if (err) AuFin("addmntent"); } if (pos > 0) AuFin("internal error"); } else append_mtab(fp, ofp, &ent); } else append_mtab(fp, ofp, &ent); endmntent(ofp); /* ignore */ au_plink_maint(NULL); if (do_verbose) au_print_ent(&ent); }
int zuluCrypRemoveEntryFromMtab( const char * m_point ) { #if USE_NEW_LIBMOUNT_API struct libmnt_lock * lock ; #else mnt_lock * lock ; #endif struct mntent * mt ; FILE * f ; FILE * g ; size_t dir_len = strlen( m_point ) ; int h ; lock = mnt_new_lock( "/etc/mtab~",getpid() ) ; f = setmntent( "/etc/mtab","r" ) ; if( mnt_lock_file( lock ) != 0 ){ h = 4 ; }else{ g = setmntent( "/etc/mtab-zuluCrypt","w" ) ; while( ( mt = getmntent( f ) ) != NULL ){ if( StringPrefixMatch( mt->mnt_dir,m_point,dir_len ) ){ /* * an entry we want to delete,skip it */ ; }else{ addmntent( g,mt ) ; } } endmntent( g ) ; rename( "/etc/mtab-zuluCrypt","/etc/mtab" ) ; chown( "/etc/mtab",0,0 ) ; chmod( "/etc/mtab",S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH ) ; mnt_unlock_file( lock ) ; h = 0 ; } endmntent( f ) ; mnt_free_lock( lock ) ; return h ; }
static int add_mount(const char *dev, const char *mnt, const char *type) { int res; const char *mtab = _PATH_MOUNTED; struct mntent ent; FILE *fp; char *opts; fp = setmntent(mtab, "a"); if(fp == NULL) { fprintf(stderr, "%s failed to open %s: %s\n", progname, mtab, strerror(errno)); return -1; } if(getuid() != 0) { const char *user = get_user_name(); if(user == NULL) return -1; opts = malloc(strlen(user) + 128); if(opts != NULL) sprintf(opts, "rw,nosuid,nodev,user=%s", user); } else opts = strdup("rw,nosuid,nodev"); if(opts == NULL) return -1; ent.mnt_fsname = (char *) dev; ent.mnt_dir = (char *) mnt; ent.mnt_type = (char *) type; ent.mnt_opts = opts; ent.mnt_freq = 0; ent.mnt_passno = 0; res = addmntent(fp, &ent); if(res != 0) { fprintf(stderr, "%s: failed to add entry to %s: %s\n", progname, mtab, strerror(errno)); return -1; } endmntent(fp); return 0; }
/* Create mtab with a root entry. */ static void create_mtab (void) { struct mntent *fstab; if ((F_mtab = setmntent (MOUNTED, "a+")) == NULL) die (1, "mount: can't open %s for writing: %s", MOUNTED, strerror (errno)); /* Find the root entry by looking it up in fstab, which might be wrong. We could statfs "/" followed by a slew of stats on /dev/ but then we'd have to unparse the mount options as well.... */ if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) { if (addmntent (F_mtab, fstab) == 1) die (1, "mount: error writing %s: %s", MOUNTED, strerror (errno)); } endmntent (F_mtab); }
void write_mtab(char *blockDevice, char *directory, char *filesystemType, long flags, char *string_flags) { FILE *mountTable = setmntent(mtab_file, "a+"); struct mntent m; if (mountTable == 0) { perror_msg("%s", mtab_file); return; } if (mountTable) { int length = strlen(directory); if (length > 1 && directory[length - 1] == '/') directory[length - 1] = '\0'; if (filesystemType == 0) { struct mntent *p = find_mount_point(blockDevice, "/proc/mounts"); if (p && p->mnt_type) filesystemType = p->mnt_type; } m.mnt_fsname = blockDevice; m.mnt_dir = directory; m.mnt_type = filesystemType ? filesystemType : "default"; if (*string_flags) { m.mnt_opts = string_flags; } else { if ((flags | MS_RDONLY) == flags) m.mnt_opts = "ro"; else m.mnt_opts = "rw"; } m.mnt_freq = 0; m.mnt_passno = 0; addmntent(mountTable, &m); endmntent(mountTable); } }
void erase_mtab(const char *name) { struct mntent entries[20]; int count = 0; FILE *mountTable = setmntent(mtab_file, "r"); struct mntent *m; /* Check if reading the mtab file failed */ if (mountTable == 0 /* Bummer. fall back on trying the /proc filesystem */ && (mountTable = setmntent("/proc/mounts", "r")) == 0) { perror_msg("%s", mtab_file); return; } while ((m = getmntent(mountTable)) != 0) { entries[count].mnt_fsname = strdup(m->mnt_fsname); entries[count].mnt_dir = strdup(m->mnt_dir); entries[count].mnt_type = strdup(m->mnt_type); entries[count].mnt_opts = strdup(m->mnt_opts); entries[count].mnt_freq = m->mnt_freq; entries[count].mnt_passno = m->mnt_passno; count++; } endmntent(mountTable); if ((mountTable = setmntent(mtab_file, "w"))) { int i; for (i = 0; i < count; i++) { int result = (strcmp(entries[i].mnt_fsname, name) == 0 || strcmp(entries[i].mnt_dir, name) == 0); if (result) continue; else addmntent(mountTable, &entries[i]); } endmntent(mountTable); } else if (errno != EROFS) perror_msg("%s", mtab_file); }
void FAST_FUNC erase_mtab(const char *name) { struct mntent *entries; int i, count; FILE *mountTable; struct mntent *m; mountTable = setmntent(bb_path_mtab_file, "r"); /* Bummer. Fall back on trying the /proc filesystem */ if (!mountTable) mountTable = setmntent("/proc/mounts", "r"); if (!mountTable) { bb_perror_msg(bb_path_mtab_file); return; } entries = NULL; count = 0; while ((m = getmntent(mountTable)) != 0) { entries = xrealloc_vector(entries, 3, count); entries[count].mnt_fsname = xstrdup(m->mnt_fsname); entries[count].mnt_dir = xstrdup(m->mnt_dir); entries[count].mnt_type = xstrdup(m->mnt_type); entries[count].mnt_opts = xstrdup(m->mnt_opts); entries[count].mnt_freq = m->mnt_freq; entries[count].mnt_passno = m->mnt_passno; count++; } endmntent(mountTable); //TODO: make update atomic mountTable = setmntent(bb_path_mtab_file, "w"); if (mountTable) { for (i = 0; i < count; i++) { if (strcmp(entries[i].mnt_fsname, name) != 0 && strcmp(entries[i].mnt_dir, name) != 0) addmntent(mountTable, &entries[i]); } endmntent(mountTable); } else if (errno != EROFS) bb_perror_msg(bb_path_mtab_file); }
static int _update_mtab (char *options, char *spec, char *dir) { uid_t saved_euid = geteuid (); FILE *f; int ret = 0; struct mntent mnt; mnt.mnt_fsname = spec; mnt.mnt_dir = dir; mnt.mnt_type = "diod"; mnt.mnt_opts = options; mnt.mnt_freq = 0; mnt.mnt_passno = 0; if (seteuid (0) < 0) { err ("failed to set effective uid to root"); goto done; } if (!(f = setmntent (_PATH_MOUNTED, "a"))) { err (_PATH_MOUNTED); goto done; } if (addmntent (f, &mnt) != 0) { msg ("failed to add entry to %s", _PATH_MOUNTED); endmntent (f); goto done; } endmntent (f); if (seteuid (saved_euid) < 0) { err ("failed to restore effective uid to %d", saved_euid); goto done; } ret = 1; done: return ret; }
int commandtool::deautomnt_part(const blockdevice *block) { const char *fstab_tmp = "/etc/fstab~"; struct mntent *m1 = NULL; FILE *f1= NULL,*f2 = NULL; f1 = setmntent(FSTAB_FILE, "r"); f2 = setmntent(fstab_tmp, "w+"); if (f1 == NULL || f2 == NULL) { util::log(QString("deautomount %1 error %2").arg(block->device).arg(errno)); return -1; } while ((m1 = getmntent(f1))) { QString fsname = QString(m1->mnt_fsname); bool has = false; foreach(const QString& symlink, block->symlinks) { if (fsname == symlink) { has = true; qDebug() <<symlink; break; } } if (!has) { addmntent(f2,m1); } } endmntent(f1); endmntent(f2); rename(fstab_tmp, FSTAB_FILE); return 0; }
static void UpdateMtab(HgfsMountInfo *mountInfo, // IN: Info to write into mtab int flags) // IN: Flags (read-only, etc.) { struct mntent mountEnt; FILE *mountFile; struct passwd *password; char *userName = NULL; ASSERT(mountInfo); mountFile = setmntent(MOUNTED, "a+"); if (mountFile == NULL) { printf("Could not open mtab for appending, continuing sans mtab\n"); return; } /* We only care about the mounting user if it isn't root. */ if (getuid() != 0) { password = getpwuid(getuid()); if (password == NULL) { printf("Could not get user for mounting uid, skipping user entry\n"); } else { userName = password->pw_name; } } /* * Create the mtab entry to be written. We'll go ahead and try to write * even if we fail to allocate the mount options. */ mountEnt.mnt_fsname = shareName; mountEnt.mnt_dir = mountPoint; mountEnt.mnt_type = HGFS_NAME; mountEnt.mnt_freq = 0; mountEnt.mnt_passno = 0; mountEnt.mnt_opts = malloc(MOUNT_OPTS_BUFFER_SIZE); if (mountEnt.mnt_opts) { char *ttlString; memset(mountEnt.mnt_opts, 0, MOUNT_OPTS_BUFFER_SIZE); /* * These are typically the displayed options in /etc/mtab (note that not * all options are typically displayed, just those the user may find * interesting). */ if (flags & MS_RDONLY) { Str_Strcat(mountEnt.mnt_opts, "ro", MOUNT_OPTS_BUFFER_SIZE); } else { Str_Strcat(mountEnt.mnt_opts, "rw", MOUNT_OPTS_BUFFER_SIZE); } if (flags & MS_NOSUID) { Str_Strcat(mountEnt.mnt_opts, ",nosuid", MOUNT_OPTS_BUFFER_SIZE); } #ifdef MS_NODEV if (flags & MS_NODEV) { Str_Strcat(mountEnt.mnt_opts, ",nodev", MOUNT_OPTS_BUFFER_SIZE); } #endif if (flags & MS_NOEXEC) { Str_Strcat(mountEnt.mnt_opts, ",noexec", MOUNT_OPTS_BUFFER_SIZE); } if (flags & MS_SYNCHRONOUS) { Str_Strcat(mountEnt.mnt_opts, ",sync", MOUNT_OPTS_BUFFER_SIZE); } if (flags & MS_MANDLOCK) { Str_Strcat(mountEnt.mnt_opts, ",mand", MOUNT_OPTS_BUFFER_SIZE); } if (flags & MS_NOATIME) { Str_Strcat(mountEnt.mnt_opts, ",noatime", MOUNT_OPTS_BUFFER_SIZE); } if (flags & MS_NODIRATIME) { Str_Strcat(mountEnt.mnt_opts, ",nodiratime", MOUNT_OPTS_BUFFER_SIZE); } if (userName != NULL) { Str_Strcat(mountEnt.mnt_opts, ",user="******"%u", mountInfo->ttl); if (ttlString != NULL) { Str_Strcat(mountEnt.mnt_opts, ",ttl=", MOUNT_OPTS_BUFFER_SIZE); Str_Strcat(mountEnt.mnt_opts, ttlString, MOUNT_OPTS_BUFFER_SIZE); free(ttlString); } else { printf("Could not allocate memory for ttl entry in mtab, " "continuing\n"); } } /* Add the entry and close. */ if (addmntent(mountFile, &mountEnt)) { printf("Could not add entry to mtab, continuing\n"); } endmntent(mountFile); if (mountEnt.mnt_opts) { free(mountEnt.mnt_opts); } }
static int HandleMTab(char *cacheMountDir) { #if (defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)) FILE *tfilep; #if defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV) struct mntent tmntent; char *dir; int i; tfilep = setmntent("/etc/mtab", "a+"); if (!tfilep) { printf("Can't open /etc/mtab for writing (errno %d); not adding " "an entry for AFS\n", errno); return 1; } dir = strdup(cacheMountDir); /* trim trailing slashes; don't look at dir[0] in case we are somehow * just "/" */ for (i = strlen(dir)-1; i > 0; i--) { if (dir[i] == '/') { dir[i] = '\0'; } else { break; } } tmntent.mnt_fsname = "AFS"; tmntent.mnt_dir = dir; tmntent.mnt_type = "afs"; tmntent.mnt_opts = "rw"; tmntent.mnt_freq = 1; tmntent.mnt_passno = 3; addmntent(tfilep, &tmntent); endmntent(tfilep); free(dir); dir = NULL; #else struct mntent tmntent; memset(&tmntent, '\0', sizeof(struct mntent)); tfilep = setmntent(MOUNTED_TABLE, "a+"); if (!tfilep) { printf("Can't open %s for write; Not adding afs entry to it\n", MOUNTED_TABLE); return 1; } tmntent.mnt_fsname = "AFS"; tmntent.mnt_dir = cacheMountDir; tmntent.mnt_type = "xx"; tmntent.mnt_opts = "rw"; tmntent.mnt_freq = 1; tmntent.mnt_passno = 3; #ifdef AFS_HPUX_ENV tmntent.mnt_type = "afs"; tmntent.mnt_time = time(0); tmntent.mnt_cnode = 0; #endif addmntent(tfilep, &tmntent); endmntent(tfilep); #endif /* AFS_SGI_ENV */ #endif /* unreasonable systems */ #ifdef AFS_DARWIN_ENV #ifndef AFS_DARWIN100_ENV mach_port_t diskarb_port; kern_return_t status; status = DiskArbStart(&diskarb_port); if (status == KERN_SUCCESS) { status = DiskArbDiskAppearedWithMountpointPing_auto("AFS", DISK_ARB_NETWORK_DISK_FLAG, cacheMountDir); } return status; #endif #endif /* AFS_DARWIN_ENV */ return 0; }
static int remove_from_mtab(char * mountpoint) { int rc; int num_matches; FILE * org_fd; FILE * new_fd; struct mntent * mount_entry; /* Do we need to check if it is a symlink to e.g. /proc/mounts in which case we probably do not want to update it? */ /* Do we first need to check if it is writable? */ atexit(unlock_mtab); if (lock_mtab()) { printf("Mount table locked\n"); return -EACCES; } if(verboseflg) printf("attempting to remove from mtab\n"); org_fd = setmntent(MOUNTED, "r"); if(org_fd == NULL) { printf("Can not open %s\n",MOUNTED); unlock_mtab(); return -EIO; } new_fd = setmntent(MOUNTED_TEMP,"w"); if(new_fd == NULL) { printf("Can not open temp file %s", MOUNTED_TEMP); endmntent(org_fd); unlock_mtab(); return -EIO; } /* BB fix so we only remove the last entry that matches BB */ num_matches = 0; while((mount_entry = getmntent(org_fd)) != NULL) { if(strcmp(mount_entry->mnt_dir, mountpoint) == 0) { num_matches++; } } if(verboseflg) printf("%d matching entries in mount table\n", num_matches); /* Is there a better way to seek back to the first entry in mtab? */ endmntent(org_fd); org_fd = setmntent(MOUNTED, "r"); if(org_fd == NULL) { printf("Can not open %s\n",MOUNTED); unlock_mtab(); return -EIO; } while((mount_entry = getmntent(org_fd)) != NULL) { if(strcmp(mount_entry->mnt_dir, mountpoint) != 0) { addmntent(new_fd, mount_entry); } else { if(num_matches != 1) { addmntent(new_fd, mount_entry); num_matches--; } else if(verboseflg) printf("entry not copied (ie entry is removed)\n"); } } if(verboseflg) printf("done updating tmp file\n"); rc = fchmod (fileno (new_fd), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if(rc < 0) { printf("error %s changing mode of %s\n", strerror(errno), MOUNTED_TEMP); } endmntent(new_fd); rc = rename(MOUNTED_TEMP, MOUNTED); if(rc < 0) { printf("failure %s renaming %s to %s\n",strerror(errno), MOUNTED_TEMP, MOUNTED); unlock_mtab(); return -EIO; } unlock_mtab(); return rc; }
// Perform actual mount of specific filesystem at specific location. // NB: mp->xxx fields may be trashed on exit static int mount_it_now(struct mntent *mp, int vfsflags, char *filteropts) { int rc = 0; if (fakeIt) goto mtab; // Mount, with fallback to read-only if necessary. for (;;) { rc = mount(mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, vfsflags, filteropts); if (!rc || (vfsflags&MS_RDONLY) || (errno!=EACCES && errno!=EROFS)) break; bb_error_msg("%s is write-protected, mounting read-only", mp->mnt_fsname); vfsflags |= MS_RDONLY; } // Abort entirely if permission denied. if (rc && errno == EPERM) bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); /* If the mount was successful, and we're maintaining an old-style * mtab file by hand, add the new entry to it now. */ mtab: if (ENABLE_FEATURE_MTAB_SUPPORT && useMtab && !rc && !(vfsflags & MS_REMOUNT)) { char *fsname; FILE *mountTable = setmntent(bb_path_mtab_file, "a+"); int i; if (!mountTable) { bb_error_msg("no %s",bb_path_mtab_file); goto ret; } // Add vfs string flags for (i=0; mount_options[i].flags != MS_REMOUNT; i++) if (mount_options[i].flags > 0 && (mount_options[i].flags & vfsflags)) append_mount_options(&(mp->mnt_opts), mount_options[i].name); // Remove trailing / (if any) from directory we mounted on i = strlen(mp->mnt_dir) - 1; if (i > 0 && mp->mnt_dir[i] == '/') mp->mnt_dir[i] = 0; // Convert to canonical pathnames as needed mp->mnt_dir = bb_simplify_path(mp->mnt_dir); fsname = 0; if (!mp->mnt_type || !*mp->mnt_type) { /* bind mount */ mp->mnt_fsname = fsname = bb_simplify_path(mp->mnt_fsname); mp->mnt_type = (char*)"bind"; } mp->mnt_freq = mp->mnt_passno = 0; // Write and close. addmntent(mountTable, mp); endmntent(mountTable); if (ENABLE_FEATURE_CLEAN_UP) { free(mp->mnt_dir); free(fsname); } } ret: return rc; }
/* Add entry in the /etc/mtab */ int zfs_linux_add_entry(char *mountpoint, char *zfs_name, const char *mtab_file, char *mountopt) { struct mntent mnt; FILE *mtab = NULL; int lock_fd; bzero(&mnt, sizeof(struct mntent)); mnt.mnt_dir = mountpoint; mnt.mnt_type = "zfs"; mnt.mnt_fsname = zfs_name; if (!system("selinuxenabled > /dev/null 2>&1")) { mnt.mnt_opts = (strcmp(mountopt, MNTOPT_RW) == 0) ? "rw,context=\"system_u:object_r:file_t:s0\"" : "ro,context=\"system_u:object_r:file_t:s0\""; } else { mnt.mnt_opts = mountopt; } mnt.mnt_freq = 0; mnt.mnt_passno = 0; if ((lock_fd = open(FLOCK_PATH, O_RDONLY)) < 0) { fprintf(stderr, "%s(%d): open: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); return -1; } if (flock(lock_fd, LOCK_EX) < 0) { fprintf(stderr, "%s(%d): flock: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); close(lock_fd); return -1; } if (NULL == (mtab = setmntent(mtab_file, "a+"))) { flock(lock_fd, LOCK_UN); close(lock_fd); return -1; } if (addmntent(mtab, &mnt) != 0) { fprintf(stderr, "%s(%d): addmntent: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); endmntent(mtab); flock(lock_fd, LOCK_UN); close(lock_fd); return -1; } endmntent(mtab); if (flock(lock_fd, LOCK_UN) < 0) { fprintf(stderr, "%s(%d): flock: %s.\n", __FUNCTION__, __LINE__, strerror(errno)); close(lock_fd); return -1; } close(lock_fd); return 0; }
/* * Write out a mount list */ void rewrite_mtab(mntlist *mp, const char *mnttabname) { FILE *mfp; int error = 0; char tmpname[64]; int retries; int tmpfd; char *cp; char mcp[128]; if (!mtab_is_writable()) { return; } /* * Concoct a temporary name in the same directory as the target mount * table so that rename() will work. */ xstrlcpy(mcp, mnttabname, sizeof(mcp)); cp = strrchr(mcp, '/'); if (cp) { memmove(tmpname, mcp, cp - mcp); tmpname[cp - mcp] = '\0'; } else { plog(XLOG_WARNING, "No '/' in mtab (%s), using \".\" as tmp directory", mnttabname); tmpname[0] = '.'; tmpname[1] = '\0'; } xstrlcat(tmpname, "/mtabXXXXXX", sizeof(tmpname)); retries = 0; enfile1: #ifdef HAVE_MKSTEMP tmpfd = mkstemp(tmpname); fchmod(tmpfd, 0644); #else /* not HAVE_MKSTEMP */ mktemp(tmpname); tmpfd = open(tmpname, O_RDWR | O_CREAT | O_TRUNC, 0644); #endif /* not HAVE_MKSTEMP */ if (tmpfd < 0) { if (errno == ENFILE && retries++ < NFILE_RETRIES) { sleep(1); goto enfile1; } plog(XLOG_ERROR, "%s: open: %m", tmpname); return; } if (close(tmpfd) < 0) plog(XLOG_ERROR, "Couldn't close tmp file descriptor: %m"); retries = 0; enfile2: mfp = setmntent(tmpname, "w"); if (!mfp) { if (errno == ENFILE && retries++ < NFILE_RETRIES) { sleep(1); goto enfile2; } plog(XLOG_ERROR, "setmntent(\"%s\", \"w\"): %m", tmpname); error = 1; goto out; } while (mp) { if (mp->mnt) { if (addmntent(mfp, mp->mnt)) { plog(XLOG_ERROR, "Can't write entry to %s", tmpname); error = 1; goto out; } } mp = mp->mnext; } /* * SunOS 4.1 manuals say that the return code from entmntent() * is always 1 and to treat as a void. That means we need to * call fflush() to make sure the new mtab file got written. */ if (fflush(mfp)) { plog(XLOG_ERROR, "flush new mtab file: %m"); error = 1; goto out; } (void) endmntent(mfp); /* * Rename temporary mtab to real mtab */ if (rename(tmpname, mnttabname) < 0) { plog(XLOG_ERROR, "rename %s to %s: %m", tmpname, mnttabname); error = 1; goto out; } out: if (error) (void) unlink(tmpname); }
int mount_dir(char *path, char *options, mode_t mode, uid_t uid, gid_t gid) { struct passwd *pwd; struct group *grp; struct mntent entry; FILE *mounts; char dummy; int useMtab; struct mount_list *list, *previous; list = collect_active_mounts(NULL); if (list && check_if_already_mounted(list, path)) { WARNING("Directory %s is already mounted.\n", path); while (list) { previous = list; list = list->next; free(previous); } return 0; } while (list) { previous = list; list = list->next; free(previous); } if (opt_dry_run) { pwd = getpwuid(uid); grp = getgrgid(gid); printf("mount -t %s none %s -o %s\n", FS_NAME, path, options); printf("chown %s:%s %s\n", pwd->pw_name, grp->gr_name, path); printf("chmod %o %s\n", mode, path); } else { if (mount("none", path, FS_NAME, 0, options)) { ERROR("Unable to mount %s, error: %s\n", path, strerror(errno)); return 1; } /* Check if mtab is a symlink */ useMtab = (readlink(MOUNTED, &dummy, 1) < 0); if (useMtab) { mounts = setmntent(MOUNTED, "a+"); if (mounts) { entry.mnt_fsname = FS_NAME; entry.mnt_dir = path; entry.mnt_type = FS_NAME; entry.mnt_opts = options; entry.mnt_freq = 0; entry.mnt_passno = 0; if (addmntent(mounts, &entry)) WARNING("Unable to add entry %s to %s, error: %s\n", path, MOUNTED, strerror(errno)); endmntent(mounts); } else { WARNING("Unable to open %s, error: %s\n", MOUNTED, strerror(errno)); } } if (chown(path, uid, gid)) { ERROR("Unable to change ownership of %s, error: %s\n", path, strerror(errno)); return 1; } if (chmod(path, mode)) { ERROR("Unable to set permissions on %s, error: %s\n", path, strerror(errno)); return 1; } } return 0; }
int main (int argc, char **argv) { char *dir; char *host; char *ports; int port; struct hostent *h; int fstype; FILE *mtabf; struct mntent mnt = { 0, 0, NSD_FSTYPE, "soft,timeo=100,retrans=2", 0, 0, }; if (argc != 4) usage (); dir = argv[1]; host = argv[2]; port = atoi ((ports = argv[3])); /* Prepare for host lookup. */ memset ((void *) &sin, 0, sizeof (sin)); sin.sin_family = 2; sin.sin_port = port; /* Look up the host. */ if (inet_aton (host, &sin.sin_addr)) ; else if ((h = gethostbyname (host))) { unsigned long *l = (unsigned long *) *(h->h_addr_list); sin.sin_addr.s_addr = l[0]; } else { fprintf (stderr, "Cannot resolve host %s.\n", host); return 1; } /* Get filesystem type index for nsd filesystem type. */ if ((fstype = sysfs (GETFSIND, NSD_FSTYPE)) < 0) { perror ("sysfs (" NSD_FSTYPE ")"); return 1; } fprintf (stderr, "Mounting nsd " NSD_FSTYPE " fs from %s(%s):%d onto %s\n", host, inet_ntoa (sin.sin_addr), port, dir); /* These flags are documented in /usr/include/sys/mount.h. MS_DOXATTR means "tell server to trust us with attributes" and MS_DATA means "6-argument mount". MS_DOXATTR is a mount option in IRIX 6.4 and up. The attack doesn't seem to work without this option. So even though this program will compile on IRIX 6.2, you need to use an IRIX 6.4 or higher OS to attack nsd. */ if (mount (dir, dir, MS_DOXATTR|MS_DATA, (char *) fstype, &nx, sizeof (nx)) != 0) { perror ("mount"); return 1; } /* Record mount point in /etc/mtab. */ mnt.mnt_fsname = malloc (strlen (host) + sizeof (":nsd@") + strlen (ports) + 1); sprintf (mnt.mnt_fsname, "%s:nsd@%s", host, ports); mnt.mnt_dir = dir; if (!(mtabf = setmntent (MTAB_FILE, "r+"))) { perror ("setmntent"); return 1; } if (addmntent (mtabf, &mnt) < 0) { perror ("addmntent"); return 1; } if (endmntent (mtabf) < 0) { perror ("endmntent"); return 1; } return 0; }
int main(int argc, char ** argv) { int c; int flags = MS_MANDLOCK; /* no need to set legacy MS_MGC_VAL */ char * orgoptions = NULL; char * share_name = NULL; char * ipaddr = NULL; char * uuid = NULL; char * mountpoint = NULL; char * options; char * resolved_path; char * temp; int rc; int rsize = 0; int wsize = 0; int nomtab = 0; int uid = 0; int gid = 0; int optlen = 0; int orgoptlen = 0; int retry = 0; /* set when we have to retry mount with uppercase */ struct stat statbuf; struct utsname sysinfo; struct mntent mountent; FILE * pmntfile; /* setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); */ if(argc && argv) { thisprogram = argv[0]; } else { mount_cifs_usage(); exit(1); } if(thisprogram == NULL) thisprogram = "mount.cifs"; uname(&sysinfo); /* BB add workstation name and domain and pass down */ /* #ifdef _GNU_SOURCE printf(" node: %s machine: %s sysname %s domain %s\n", sysinfo.nodename,sysinfo.machine,sysinfo.sysname,sysinfo.domainname); #endif */ if(argc > 2) { share_name = argv[1]; mountpoint = argv[2]; } /* add sharename in opts string as unc= parm */ while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsSU:vVwt:", longopts, NULL)) != -1) { switch (c) { /* No code to do the following options yet */ /* case 'l': list_with_volumelabel = 1; break; case 'L': volumelabel = optarg; break; */ /* case 'a': ++mount_all; break; */ case '?': case 'h': /* help */ mount_cifs_usage (); exit(1); case 'n': ++nomtab; break; case 'b': flags |= MS_BIND; break; case 'm': flags |= MS_MOVE; break; case 'o': orgoptions = strdup(optarg); break; case 'r': /* mount readonly */ flags |= MS_RDONLY; break; case 'U': uuid = optarg; break; case 'v': ++verboseflag; break; case 'V': printf ("mount.cifs version: %s.%s%s\n", MOUNT_CIFS_VERSION_MAJOR, MOUNT_CIFS_VERSION_MINOR, MOUNT_CIFS_VENDOR_SUFFIX); if(mountpassword) { memset(mountpassword,0,64); } exit (0); case 'w': flags &= ~MS_RDONLY; break; case 'R': rsize = atoi(optarg) ; break; case 'W': wsize = atoi(optarg); break; case '1': if (isdigit(*optarg)) { char *ep; uid = strtoul(optarg, &ep, 10); if (*ep) { printf("bad uid value \"%s\"\n", optarg); exit(1); } } else { struct passwd *pw; if (!(pw = getpwnam(optarg))) { printf("bad user name \"%s\"\n", optarg); exit(1); } uid = pw->pw_uid; endpwent(); } break; case '2': if (isdigit(*optarg)) { char *ep; gid = strtoul(optarg, &ep, 10); if (*ep) { printf("bad gid value \"%s\"\n", optarg); exit(1); } } else { struct group *gr; if (!(gr = getgrnam(optarg))) { printf("bad user name \"%s\"\n", optarg); exit(1); } gid = gr->gr_gid; endpwent(); } break; case 'u': got_user = 1; user_name = optarg; break; case 'd': domain_name = optarg; /* BB fix this - currently ignored */ got_domain = 1; break; case 'p': if(mountpassword == NULL) mountpassword = calloc(65,1); if(mountpassword) { got_password = 1; strncpy(mountpassword,optarg,64); } break; case 'S': get_password_from_file(0 /* stdin */,NULL); break; case 't': break; default: printf("unknown mount option %c\n",c); mount_cifs_usage(); exit(1); } } if((argc < 3) || (share_name == NULL) || (mountpoint == NULL)) { mount_cifs_usage(); exit(1); } if (getenv("PASSWD")) { if(mountpassword == NULL) mountpassword = calloc(65,1); if(mountpassword) { strncpy(mountpassword,getenv("PASSWD"),64); got_password = 1; } } else if (getenv("PASSWD_FD")) { get_password_from_file(atoi(getenv("PASSWD_FD")),NULL); } else if (getenv("PASSWD_FILE")) { get_password_from_file(0, getenv("PASSWD_FILE")); } if (orgoptions && parse_options(&orgoptions, &flags)) return -1; ipaddr = parse_server(&share_name); if((ipaddr == NULL) && (got_ip == 0)) { printf("No ip address specified and hostname not found\n"); return -1; } /* BB save off path and pop after mount returns? */ resolved_path = malloc(PATH_MAX+1); if(resolved_path) { /* Note that if we can not canonicalize the name, we get another chance to see if it is valid when we chdir to it */ if (realpath(mountpoint, resolved_path)) { mountpoint = resolved_path; } } if(chdir(mountpoint)) { printf("mount error: can not change directory into mount target %s\n",mountpoint); return -1; } if(stat (".", &statbuf)) { printf("mount error: mount point %s does not exist\n",mountpoint); return -1; } if (S_ISDIR(statbuf.st_mode) == 0) { printf("mount error: mount point %s is not a directory\n",mountpoint); return -1; } if((getuid() != 0) && (geteuid() == 0)) { if((statbuf.st_uid == getuid()) && (S_IRWXU == (statbuf.st_mode & S_IRWXU))) { #ifndef CIFS_ALLOW_USR_SUID /* Do not allow user mounts to control suid flag for mount unless explicitly built that way */ flags |= MS_NOSUID | MS_NODEV; #endif } else { printf("mount error: permission denied or not superuser and mount.cifs not installed SUID\n"); return -1; } } if(got_user == 0) { user_name = getusername(); got_user = 1; } if(got_password == 0) { mountpassword = getpass("Password: "******"No server share name specified\n"); printf("\nMounting the DFS root for server not implemented yet\n"); exit(1); } if(user_name) optlen += strlen(user_name) + 6; if(ipaddr) optlen += strlen(ipaddr) + 4; if(mountpassword) optlen += strlen(mountpassword) + 6; options = malloc(optlen + 10 + 64 /* space for commas in password */ + 8 /* space for domain= , domain name itself was counted as part of the length username string above */); if(options == NULL) { printf("Could not allocate memory for mount options\n"); return -1; } options[0] = 0; strncat(options,"unc=",4); strcat(options,share_name); /* scan backwards and reverse direction of slash */ temp = strrchr(options, '/'); if(temp > options + 6) *temp = '\\'; if(ipaddr) { strncat(options,",ip=",4); strcat(options,ipaddr); } if(user_name) { /* check for syntax like user=domain\user */ if(got_domain == 0) domain_name = check_for_domain(&user_name); strncat(options,",user="******",domain=",8); strcat(options,domain_name); } } if(mountpassword) { /* Commas have to be doubled, or else they will look like the parameter separator */ /* if(sep is not set)*/ if(retry == 0) check_for_comma(&mountpassword); strncat(options,",pass="******",ver=",5); strcat(options,MOUNT_CIFS_VERSION_MAJOR); if(orgoptions) { strcat(options,","); strcat(options,orgoptions); } if(verboseflag) printf("\nmount.cifs kernel mount options %s \n",options); if(mount(share_name, mountpoint, "cifs", flags, options)) { /* remember to kill daemon on error */ char * tmp; switch (errno) { case 0: printf("mount failed but no error number set\n"); break; case ENODEV: printf("mount error: cifs filesystem not supported by the system\n"); break; case ENXIO: if(retry == 0) { retry = 1; tmp = share_name; while (*tmp && !(((unsigned char)tmp[0]) & 0x80)) { *tmp = toupper((unsigned char)*tmp); tmp++; } if(!*tmp) { printf("retrying with upper case share name\n"); goto mount_retry; } } default: printf("mount error %d = %s\n",errno,strerror(errno)); } printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n"); if(mountpassword) { memset(mountpassword,0,64); } return -1; } else { pmntfile = setmntent(MOUNTED, "a+"); if(pmntfile) { mountent.mnt_fsname = share_name; mountent.mnt_dir = mountpoint; mountent.mnt_type = CONST_DISCARD(char *,"cifs"); mountent.mnt_opts = malloc(220); if(mountent.mnt_opts) { char * mount_user = getusername(); memset(mountent.mnt_opts,0,200); if(flags & MS_RDONLY) strcat(mountent.mnt_opts,"ro"); else strcat(mountent.mnt_opts,"rw"); if(flags & MS_MANDLOCK) strcat(mountent.mnt_opts,",mand"); if(flags & MS_NOEXEC) strcat(mountent.mnt_opts,",noexec"); if(flags & MS_NOSUID) strcat(mountent.mnt_opts,",nosuid"); if(flags & MS_NODEV) strcat(mountent.mnt_opts,",nodev"); if(flags & MS_SYNCHRONOUS) strcat(mountent.mnt_opts,",synch"); if(mount_user) { if(getuid() != 0) { strcat(mountent.mnt_opts,",user="******"could not update mount table\n"); } }
int main(int argc, char ** argv) { int c; int flags = MS_MANDLOCK; /* no need to set legacy MS_MGC_VAL */ char * orgoptions = NULL; char * share_name = NULL; const char * ipaddr = NULL; char * uuid = NULL; char * mountpoint = NULL; char * options = NULL; char * optionstail; char * resolved_path = NULL; char * temp; char * dev_name; int rc = 0; int rsize = 0; int wsize = 0; int nomtab = 0; int uid = 0; int gid = 0; int optlen = 0; int orgoptlen = 0; size_t options_size = 0; size_t current_len; int retry = 0; /* set when we have to retry mount with uppercase */ struct addrinfo *addrhead = NULL, *addr; struct stat statbuf; struct utsname sysinfo; struct mntent mountent; struct sockaddr_in *addr4; struct sockaddr_in6 *addr6; FILE * pmntfile; /* setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); */ if(argc && argv) { thisprogram = argv[0]; } else { mount_cifs_usage(); exit(EX_USAGE); } if(thisprogram == NULL) thisprogram = "mount.cifs"; uname(&sysinfo); /* BB add workstation name and domain and pass down */ /* #ifdef _GNU_SOURCE printf(" node: %s machine: %s sysname %s domain %s\n", sysinfo.nodename,sysinfo.machine,sysinfo.sysname,sysinfo.domainname); #endif */ if(argc > 2) { dev_name = argv[1]; share_name = strndup(argv[1], MAX_UNC_LEN); if (share_name == NULL) { fprintf(stderr, "%s: %s", argv[0], strerror(ENOMEM)); exit(EX_SYSERR); } mountpoint = argv[2]; } else if (argc == 2) { if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) { print_cifs_mount_version(); exit(0); } if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "--help") == 0)) { mount_cifs_usage(); exit(0); } mount_cifs_usage(); exit(EX_USAGE); } else { mount_cifs_usage(); exit(EX_USAGE); } /* add sharename in opts string as unc= parm */ while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsSU:vVwt:", longopts, NULL)) != -1) { switch (c) { /* No code to do the following options yet */ /* case 'l': list_with_volumelabel = 1; break; case 'L': volumelabel = optarg; break; */ /* case 'a': ++mount_all; break; */ case '?': case 'h': /* help */ mount_cifs_usage (); exit(EX_USAGE); case 'n': ++nomtab; break; case 'b': #ifdef MS_BIND flags |= MS_BIND; #else fprintf(stderr, "option 'b' (MS_BIND) not supported\n"); #endif break; case 'm': #ifdef MS_MOVE flags |= MS_MOVE; #else fprintf(stderr, "option 'm' (MS_MOVE) not supported\n"); #endif break; case 'o': orgoptions = strdup(optarg); break; case 'r': /* mount readonly */ flags |= MS_RDONLY; break; case 'U': uuid = optarg; break; case 'v': ++verboseflag; break; case 'V': print_cifs_mount_version(); exit (0); case 'w': flags &= ~MS_RDONLY; break; case 'R': rsize = atoi(optarg) ; break; case 'W': wsize = atoi(optarg); break; case '1': if (isdigit(*optarg)) { char *ep; uid = strtoul(optarg, &ep, 10); if (*ep) { printf("bad uid value \"%s\"\n", optarg); exit(EX_USAGE); } } else { struct passwd *pw; if (!(pw = getpwnam(optarg))) { printf("bad user name \"%s\"\n", optarg); exit(EX_USAGE); } uid = pw->pw_uid; endpwent(); } break; case '2': if (isdigit(*optarg)) { char *ep; gid = strtoul(optarg, &ep, 10); if (*ep) { printf("bad gid value \"%s\"\n", optarg); exit(EX_USAGE); } } else { struct group *gr; if (!(gr = getgrnam(optarg))) { printf("bad user name \"%s\"\n", optarg); exit(EX_USAGE); } gid = gr->gr_gid; endpwent(); } break; case 'u': got_user = 1; user_name = optarg; break; case 'd': domain_name = optarg; /* BB fix this - currently ignored */ got_domain = 1; break; case 'p': if(mountpassword == NULL) mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); if(mountpassword) { got_password = 1; strlcpy(mountpassword,optarg,MOUNT_PASSWD_SIZE+1); } break; case 'S': get_password_from_file(0 /* stdin */,NULL); break; case 't': break; case 'f': ++fakemnt; break; default: printf("unknown mount option %c\n",c); mount_cifs_usage(); exit(EX_USAGE); } } if((argc < 3) || (dev_name == NULL) || (mountpoint == NULL)) { mount_cifs_usage(); exit(EX_USAGE); } if (getenv("PASSWD")) { if(mountpassword == NULL) mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); if(mountpassword) { strlcpy(mountpassword,getenv("PASSWD"),MOUNT_PASSWD_SIZE+1); got_password = 1; } } else if (getenv("PASSWD_FD")) { get_password_from_file(atoi(getenv("PASSWD_FD")),NULL); } else if (getenv("PASSWD_FILE")) { get_password_from_file(0, getenv("PASSWD_FILE")); } if (orgoptions && parse_options(&orgoptions, &flags)) { rc = EX_USAGE; goto mount_exit; } addrhead = addr = parse_server(&share_name); if((addrhead == NULL) && (got_ip == 0)) { printf("No ip address specified and hostname not found\n"); rc = EX_USAGE; goto mount_exit; } /* BB save off path and pop after mount returns? */ resolved_path = (char *)malloc(PATH_MAX+1); if(resolved_path) { /* Note that if we can not canonicalize the name, we get another chance to see if it is valid when we chdir to it */ if (realpath(mountpoint, resolved_path)) { mountpoint = resolved_path; } } if(chdir(mountpoint)) { printf("mount error: can not change directory into mount target %s\n",mountpoint); rc = EX_USAGE; goto mount_exit; } if(stat (".", &statbuf)) { printf("mount error: mount point %s does not exist\n",mountpoint); rc = EX_USAGE; goto mount_exit; } if (S_ISDIR(statbuf.st_mode) == 0) { printf("mount error: mount point %s is not a directory\n",mountpoint); rc = EX_USAGE; goto mount_exit; } if((getuid() != 0) && (geteuid() == 0)) { if((statbuf.st_uid == getuid()) && (S_IRWXU == (statbuf.st_mode & S_IRWXU))) { #ifndef CIFS_ALLOW_USR_SUID /* Do not allow user mounts to control suid flag for mount unless explicitly built that way */ flags |= MS_NOSUID | MS_NODEV; #endif } else { printf("mount error: permission denied or not superuser and mount.cifs not installed SUID\n"); exit(EX_USAGE); } } if(got_user == 0) { /* Note that the password will not be retrieved from the USER env variable (ie user%password form) as there is already a PASSWD environment varaible */ if (getenv("USER")) user_name = strdup(getenv("USER")); if (user_name == NULL) user_name = getusername(); got_user = 1; } if(got_password == 0) { char *tmp_pass = getpass("Password: "******"Password not entered, exiting\n"); exit(EX_USAGE); } strlcpy(mountpassword, tmp_pass, MOUNT_PASSWD_SIZE+1); got_password = 1; } /* FIXME launch daemon (handles dfs name resolution and credential change) remember to clear parms and overwrite password field before launching */ if(orgoptions) { optlen = strlen(orgoptions); orgoptlen = optlen; } else optlen = 0; if(share_name) optlen += strlen(share_name) + 4; else { printf("No server share name specified\n"); printf("\nMounting the DFS root for server not implemented yet\n"); exit(EX_USAGE); } if(user_name) optlen += strlen(user_name) + 6; optlen += MAX_ADDRESS_LEN + 4; if(mountpassword) optlen += strlen(mountpassword) + 6; mount_retry: SAFE_FREE(options); options_size = optlen + 10 + DOMAIN_SIZE; options = (char *)malloc(options_size /* space for commas in password */ + 8 /* space for domain= , domain name itself was counted as part of the length username string above */); if(options == NULL) { printf("Could not allocate memory for mount options\n"); exit(EX_SYSERR); } strlcpy(options, "unc=", options_size); strlcat(options,share_name,options_size); /* scan backwards and reverse direction of slash */ temp = strrchr(options, '/'); if(temp > options + 6) *temp = '\\'; if(user_name) { /* check for syntax like user=domain\user */ if(got_domain == 0) domain_name = check_for_domain(&user_name); strlcat(options,",user="******",domain=",options_size); strlcat(options,domain_name,options_size); } } strlcat(options,",ver=",options_size); strlcat(options,MOUNT_CIFS_VERSION_MAJOR,options_size); if(orgoptions) { strlcat(options,",",options_size); strlcat(options,orgoptions,options_size); } if(prefixpath) { strlcat(options,",prefixpath=",options_size); strlcat(options,prefixpath,options_size); /* no need to cat the / */ } /* convert all '\\' to '/' in share portion so that /proc/mounts looks pretty */ replace_char(dev_name, '\\', '/', strlen(share_name)); if (!got_ip && addr) { strlcat(options, ",ip=", options_size); current_len = strnlen(options, options_size); optionstail = options + current_len; switch (addr->ai_addr->sa_family) { case AF_INET6: addr6 = (struct sockaddr_in6 *) addr->ai_addr; ipaddr = inet_ntop(AF_INET6, &addr6->sin6_addr, optionstail, options_size - current_len); break; case AF_INET: addr4 = (struct sockaddr_in *) addr->ai_addr; ipaddr = inet_ntop(AF_INET, &addr4->sin_addr, optionstail, options_size - current_len); break; } /* if the address looks bogus, try the next one */ if (!ipaddr) { addr = addr->ai_next; if (addr) goto mount_retry; rc = EX_SYSERR; goto mount_exit; } } if(verboseflag) fprintf(stderr, "\nmount.cifs kernel mount options: %s", options); if (mountpassword) { /* * Commas have to be doubled, or else they will * look like the parameter separator */ if(retry == 0) check_for_comma(&mountpassword); strlcat(options,",pass="******",pass=********"); } if (verboseflag) fprintf(stderr, "\n"); if (!fakemnt && mount(dev_name, mountpoint, "cifs", flags, options)) { switch (errno) { case ECONNREFUSED: case EHOSTUNREACH: if (addr) { addr = addr->ai_next; if (addr) goto mount_retry; } break; case ENODEV: printf("mount error: cifs filesystem not supported by the system\n"); break; case ENXIO: if(retry == 0) { retry = 1; if (uppercase_string(dev_name) && uppercase_string(share_name) && uppercase_string(prefixpath)) { printf("retrying with upper case share name\n"); goto mount_retry; } } } printf("mount error(%d): %s\n", errno, strerror(errno)); printf("Refer to the mount.cifs(8) manual page (e.g. man " "mount.cifs)\n"); rc = EX_FAIL; goto mount_exit; } if (nomtab) goto mount_exit; atexit(unlock_mtab); rc = lock_mtab(); if (rc) { printf("cannot lock mtab"); goto mount_exit; } pmntfile = setmntent(MOUNTED, "a+"); if (!pmntfile) { printf("could not update mount table\n"); unlock_mtab(); rc = EX_FILEIO; goto mount_exit; } mountent.mnt_fsname = dev_name; mountent.mnt_dir = mountpoint; mountent.mnt_type = CONST_DISCARD(char *,"cifs"); mountent.mnt_opts = (char *)malloc(220); if(mountent.mnt_opts) { char * mount_user = getusername(); memset(mountent.mnt_opts,0,200); if(flags & MS_RDONLY) strlcat(mountent.mnt_opts,"ro",220); else strlcat(mountent.mnt_opts,"rw",220); if(flags & MS_MANDLOCK) strlcat(mountent.mnt_opts,",mand",220); if(flags & MS_NOEXEC) strlcat(mountent.mnt_opts,",noexec",220); if(flags & MS_NOSUID) strlcat(mountent.mnt_opts,",nosuid",220); if(flags & MS_NODEV) strlcat(mountent.mnt_opts,",nodev",220); if(flags & MS_SYNCHRONOUS) strlcat(mountent.mnt_opts,",sync",220); if(mount_user) { if(getuid() != 0) { strlcat(mountent.mnt_opts, ",user=", 220); strlcat(mountent.mnt_opts, mount_user, 220); } } } mountent.mnt_freq = 0; mountent.mnt_passno = 0; rc = addmntent(pmntfile,&mountent); endmntent(pmntfile); unlock_mtab(); SAFE_FREE(mountent.mnt_opts); if (rc) rc = EX_FILEIO; mount_exit: if(mountpassword) { int len = strlen(mountpassword); memset(mountpassword,0,len); SAFE_FREE(mountpassword); } if (addrhead) freeaddrinfo(addrhead); SAFE_FREE(options); SAFE_FREE(orgoptions); SAFE_FREE(resolved_path); SAFE_FREE(share_name); exit(rc); }
int main (int argc, char *argv[]) { int result = 0; struct mntent mef; struct mntent *mnt = &mef; FILE *fp; mef.mnt_fsname = strdupa ("/dev/hda1"); mef.mnt_dir = strdupa ("/some dir"); mef.mnt_type = strdupa ("ext2"); mef.mnt_opts = strdupa ("defaults"); mef.mnt_freq = 1; mef.mnt_passno = 2; if (hasmntopt (mnt, "defaults")) printf ("Found!\n"); else { printf ("Didn't find it\n"); result = 1; } fp = tmpfile (); if (fp == NULL) { printf ("Cannot open temporary file: %m\n"); result = 1; } else { char buf[1024]; /* Write the name entry. */ addmntent (fp, &mef); /* Prepare for reading. */ rewind (fp); /* First, read it raw. */ if (fgets (buf, sizeof (buf), fp) == NULL) { printf ("Cannot read temporary file: %m"); result = 1; } else if (strcmp (buf, "/dev/hda1 /some\\040dir ext2 defaults 1 2\n") != 0) { puts ("Raw file data not correct"); result = 1; } /* Prepare for reading, part II. */ rewind (fp); /* Now read it cooked. */ mnt = getmntent (fp); if (strcmp (mnt->mnt_fsname, "/dev/hda1") != 0 || strcmp (mnt->mnt_dir, "/some dir") != 0 || strcmp (mnt->mnt_type, "ext2") != 0 || strcmp (mnt->mnt_opts, "defaults") != 0 || mnt->mnt_freq != 1 || mnt->mnt_passno != 2) { puts ("Error while reading written entry back in"); result = 1; } } return result; }
int main(int argc, char *argv[]) { int fd; char* mount_point; struct mntent *mnt; FILE* mtab; FILE* new_mtab; if (argc != 2) { usage(); exit(1); } if (geteuid() != 0) { fprintf(stderr, "smbumount must be installed suid root\n"); exit(1); } mount_point = canonicalize(argv[1]); if (mount_point == NULL) { exit(1); } if (umount_ok(mount_point) != 0) { exit(1); } if (umount(mount_point) != 0) { fprintf(stderr, "Could not umount %s: %s\n", mount_point, strerror(errno)); exit(1); } if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) { fprintf(stderr, "Can't get "MOUNTED"~ lock file"); return 1; } close(fd); if ((mtab = setmntent(MOUNTED, "r")) == NULL) { fprintf(stderr, "Can't open " MOUNTED ": %s\n", strerror(errno)); return 1; } #define MOUNTED_TMP MOUNTED".tmp" if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n", strerror(errno)); endmntent(mtab); return 1; } while ((mnt = getmntent(mtab)) != NULL) { if (strcmp(mnt->mnt_dir, mount_point) != 0) { addmntent(new_mtab, mnt); } } endmntent(mtab); if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { fprintf(stderr, "Error changing mode of %s: %s\n", MOUNTED_TMP, strerror(errno)); exit(1); } endmntent(new_mtab); if (rename(MOUNTED_TMP, MOUNTED) < 0) { fprintf(stderr, "Cannot rename %s to %s: %s\n", MOUNTED, MOUNTED_TMP, strerror(errno)); exit(1); } if (unlink(MOUNTED"~") == -1) { fprintf(stderr, "Can't remove "MOUNTED"~"); return 1; } return 0; }
/** @todo Use defines for return values! */ int vbsfmount_complete(const char *host_name, const char *mount_point, unsigned long flags, struct vbsf_mount_opts *opts) { FILE *f, *m; char *buf; size_t size; struct mntent e; int rc = 0; m = open_memstream(&buf, &size); if (!m) return 1; /* Could not update mount table (failed to create memstream). */ if (opts->uid) fprintf(m, "uid=%d,", opts->uid); if (opts->gid) fprintf(m, "gid=%d,", opts->gid); if (opts->ttl) fprintf(m, "ttl=%d,", opts->ttl); if (*opts->nls_name) fprintf(m, "iocharset=%s,", opts->nls_name); if (flags & MS_NOSUID) fprintf(m, "%s,", MNTOPT_NOSUID); if (flags & MS_RDONLY) fprintf(m, "%s,", MNTOPT_RO); else fprintf(m, "%s,", MNTOPT_RW); fclose(m); if (size > 0) buf[size - 1] = 0; else buf = "defaults"; f = setmntent(MOUNTED, "a+"); if (!f) { rc = 2; /* Could not open mount table for update. */ } else { e.mnt_fsname = (char*)host_name; e.mnt_dir = (char*)mount_point; e.mnt_type = "vboxsf"; e.mnt_opts = buf; e.mnt_freq = 0; e.mnt_passno = 0; if (addmntent(f, &e)) rc = 3; /* Could not add an entry to the mount table. */ endmntent(f); } if (size > 0) { memset(buf, 0, size); free(buf); } return rc; }