static void fileaction_setowngrp(char *filename, int fileref) { int uid, gid; uid = xuname2uid(rpm_getstr(TAG_FILEUSERNAME, fileref)); gid = xgroup2gid(rpm_getstr(TAG_FILEGROUPNAME, fileref)); chown(filename, uid, gid); }
int adduser_main(int argc UNUSED_PARAM, char **argv) { struct passwd pw; const char *usegroup = NULL; char *p; unsigned opts; #if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS applet_long_options = adduser_longopts; #endif /* got root? */ if (geteuid()) { bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); } pw.pw_gecos = (char *)"Linux User,,,"; /* We assume that newly created users "inherit" root's shell setting */ pw.pw_shell = (char *)get_shell_name(); pw.pw_dir = NULL; /* at most two non-option args */ /* disable interactive passwd for system accounts */ opt_complementary = "?2:SD:u+"; if (sizeof(pw.pw_uid) == sizeof(int)) { opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &pw.pw_uid); } else { unsigned uid; opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &uid); if (opts & OPT_UID) { pw.pw_uid = uid; } } argv += optind; pw.pw_name = argv[0]; if (!opts && argv[1]) { /* if called with two non-option arguments, adduser * will add an existing user to an existing group. */ return addgroup_wrapper(&pw, argv[1]); } /* fill in the passwd struct */ die_if_bad_username(pw.pw_name); if (!pw.pw_dir) { /* create string for $HOME if not specified already */ pw.pw_dir = xasprintf("/home/%s", argv[0]); } pw.pw_passwd = (char *)"x"; if (opts & OPT_SYSTEM_ACCOUNT) { if (!usegroup) { usegroup = "nogroup"; } if (!(opts & OPT_SHELL)) { pw.pw_shell = (char *) "/bin/false"; } } pw.pw_gid = usegroup ? xgroup2gid(usegroup) : -1; /* exits on failure */ /* make sure everything is kosher and setup uid && maybe gid */ passwd_study(&pw); p = xasprintf("x:%u:%u:%s:%s:%s", (unsigned) pw.pw_uid, (unsigned) pw.pw_gid, pw.pw_gecos, pw.pw_dir, pw.pw_shell); if (update_passwd(bb_path_passwd_file, pw.pw_name, p, NULL) < 0) { return EXIT_FAILURE; } if (ENABLE_FEATURE_CLEAN_UP) free(p); #if ENABLE_FEATURE_SHADOWPASSWDS /* /etc/shadow fields: * 1. username * 2. encrypted password * 3. last password change (unix date (unix time/24*60*60)) * 4. minimum days required between password changes * 5. maximum days password is valid * 6. days before password is to expire that user is warned * 7. days after password expires that account is disabled * 8. unix date when login expires (i.e. when it may no longer be used) */ /* fields: 2 3 4 5 6 78 */ p = xasprintf("!:%u:0:99999:7:::", (unsigned)(time(NULL)) / (24*60*60)); /* ignore errors: if file is missing we suppose admin doesn't want it */ update_passwd(bb_path_shadow_file, pw.pw_name, p, NULL); if (ENABLE_FEATURE_CLEAN_UP) free(p); #endif /* add to group */ addgroup_wrapper(&pw, usegroup); /* clear the umask for this process so it doesn't * screw up the permissions on the mkdir and chown. */ umask(0); if (!(opts & OPT_DONT_MAKE_HOME)) { /* set the owner and group so it is owned by the new user, * then fix up the permissions to 2755. Can't do it before * since chown will clear the setgid bit */ int mkdir_err = mkdir(pw.pw_dir, 0755); if (mkdir_err == 0) { /* New home. Copy /etc/skel to it */ const char *args[] = { "chown", "-R", xasprintf("%u:%u", (int)pw.pw_uid, (int)pw.pw_gid), pw.pw_dir, NULL }; /* Be silent on any errors (like: no /etc/skel) */ logmode = LOGMODE_NONE; copy_file("/etc/skel", pw.pw_dir, FILEUTILS_RECUR); logmode = LOGMODE_STDIO; chown_main(4, (char**)args); } if ((mkdir_err != 0 && errno != EEXIST) || chown(pw.pw_dir, pw.pw_uid, pw.pw_gid) != 0 || chmod(pw.pw_dir, 02755) != 0 /* set setgid bit on homedir */ ) { bb_simple_perror_msg(pw.pw_dir); } } if (!(opts & OPT_DONT_SET_PASS)) { /* interactively set passwd */ passwd_wrapper(pw.pw_name); } return EXIT_SUCCESS; }
int tunctl_main(int argc UNUSED_PARAM, char **argv) { struct ifreq ifr; int fd; const char *opt_name = "tap%d"; const char *opt_device = "/dev/net/tun"; #if ENABLE_FEATURE_TUNCTL_UG const char *opt_user, *opt_group; long user = -1, group = -1; #endif unsigned opts; enum { OPT_f = 1 << 0, // control device name (/dev/net/tun) OPT_t = 1 << 1, // create named interface OPT_d = 1 << 2, // delete named interface #if ENABLE_FEATURE_TUNCTL_UG OPT_u = 1 << 3, // set new interface owner OPT_g = 1 << 4, // set new interface group OPT_b = 1 << 5, // brief output #endif }; opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d opts = getopt32(argv, "f:t:d:" IF_FEATURE_TUNCTL_UG("u:g:b"), &opt_device, &opt_name, &opt_name IF_FEATURE_TUNCTL_UG(, &opt_user, &opt_group)); // select device memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy_IFNAMSIZ(ifr.ifr_name, opt_name); // open device fd = xopen(opt_device, O_RDWR); IOCTL(fd, TUNSETIFF, (void *)&ifr); // delete? if (opts & OPT_d) { IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)0); printf("Set '%s' nonpersistent\n", ifr.ifr_name); return EXIT_SUCCESS; } // create #if ENABLE_FEATURE_TUNCTL_UG if (opts & OPT_g) { group = xgroup2gid(opt_group); IOCTL(fd, TUNSETGROUP, (void *)(uintptr_t)group); } else user = geteuid(); if (opts & OPT_u) user = xuname2uid(opt_user); IOCTL(fd, TUNSETOWNER, (void *)(uintptr_t)user); #endif IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)1); // show info #if ENABLE_FEATURE_TUNCTL_UG if (opts & OPT_b) { puts(ifr.ifr_name); } else { printf("Set '%s' %spersistent", ifr.ifr_name, ""); printf(" and owned by uid %ld", user); if (group != -1) printf(" gid %ld", group); bb_putchar('\n'); } #else puts(ifr.ifr_name); #endif return EXIT_SUCCESS; }
int adduser_main(int argc UNUSED_PARAM, char **argv) { struct passwd pw; const char *usegroup = NULL; FILE *file; #if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS applet_long_options = adduser_longopts; #endif /* got root? */ if (geteuid()) { bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); } pw.pw_gecos = (char *)"Linux User,,,"; pw.pw_shell = (char *)DEFAULT_SHELL; pw.pw_dir = NULL; /* exactly one non-option arg */ opt_complementary = "=1"; getopt32(argv, "h:g:s:G:DSH", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup); argv += optind; /* fill in the passwd struct */ pw.pw_name = argv[0]; die_if_bad_username(pw.pw_name); if (!pw.pw_dir) { /* create string for $HOME if not specified already */ pw.pw_dir = xasprintf("/home/%s", argv[0]); } pw.pw_passwd = (char *)"x"; pw.pw_gid = usegroup ? xgroup2gid(usegroup) : 0; /* exits on failure */ /* make sure everything is kosher and setup uid && maybe gid */ passwd_study(&pw); /* add to passwd */ file = xfopen(bb_path_passwd_file, "a"); //fseek(file, 0, SEEK_END); /* paranoia, "a" should ensure that anyway */ if (putpwent(&pw, file) != 0) { bb_perror_nomsg_and_die(); } /* do fclose even if !ENABLE_FEATURE_CLEAN_UP. * We will exec passwd, files must be flushed & closed before that! */ fclose(file); #if ENABLE_FEATURE_SHADOWPASSWDS /* add to shadow if necessary */ file = fopen_or_warn(bb_path_shadow_file, "a"); if (file) { //fseek(file, 0, SEEK_END); fprintf(file, "%s:!:%u:0:99999:7:::\n", pw.pw_name, /* username */ (unsigned)(time(NULL) / 86400) /* sp->sp_lstchg */ /*0,*/ /* sp->sp_min */ /*99999,*/ /* sp->sp_max */ /*7*/ /* sp->sp_warn */ ); fclose(file); } #endif /* add to group */ /* addgroup should be responsible for dealing w/ gshadow */ /* if using a pre-existing group, don't create one */ if (!usegroup) addgroup_wrapper(&pw); /* Clear the umask for this process so it doesn't * screw up the permissions on the mkdir and chown. */ umask(0); if (!(option_mask32 & OPT_DONT_MAKE_HOME)) { /* Set the owner and group so it is owned by the new user, then fix up the permissions to 2755. Can't do it before since chown will clear the setgid bit */ if (mkdir(pw.pw_dir, 0755) || chown(pw.pw_dir, pw.pw_uid, pw.pw_gid) || chmod(pw.pw_dir, 02755) /* set setgid bit on homedir */ ) { bb_simple_perror_msg(pw.pw_dir); } } if (!(option_mask32 & OPT_DONT_SET_PASS)) { /* interactively set passwd */ passwd_wrapper(pw.pw_name); } return 0; }