static VALUE group_gr_put(VALUE self, VALUE io) { struct group grp; VALUE path; #ifdef HAVE_FGETGRENT struct group *tmp_grp; long i = 0; #endif Check_EU_Type(self, rb_cGroup); Check_Writes(io, FMODE_WRITABLE); path = RFILE_PATH(io); rewind(RFILE_FPTR(io)); grp.gr_name = RSTRING_PTR(rb_ivar_get(self, id_name)); #ifdef HAVE_FGETGRENT while ( (tmp_grp = fgetgrent(RFILE_FPTR(io))) ) if ( !strcmp(tmp_grp->gr_name, grp.gr_name) ) rb_raise(rb_eArgError, "%s is already mentioned in %s:%ld", tmp_grp->gr_name, StringValuePtr(path), ++i ); #endif grp.gr_passwd = RSTRING_PTR(rb_ivar_get(self, id_passwd)); grp.gr_gid = NUM2GIDT( rb_ivar_get(self, id_gid) ); grp.gr_mem = setup_char_members( rb_iv_get(self, "@members") ); if ( putgrent(&grp,RFILE_FPTR(io)) ) eu_errno(RFILE_PATH(io)); free_char_members(grp.gr_mem, (int)RARRAY_LEN( rb_iv_get(self, "@members") )); return Qtrue; }
int dogetgr(const char **list) { struct group *grp; int rc = EXC_SUCCESS; char *ptr; gid_t gid; if (list == NULL || *list == NULL) { while ((grp = getgrent()) != NULL) (void) putgrent(grp, stdout); } else { for (; *list != NULL; list++) { errno = 0; /* * Here we assume that the argument passed is * a gid, if it can be completely transformed * to a long integer. So we check for gid in * the database and if we fail then we check * for the group name. * If the argument passed is not numeric, then * we take it as the group name and proceed. */ gid = strtoul(*list, &ptr, 10); if (!(*ptr == '\0' && errno == 0) || ((grp = getgrgid(gid)) == NULL)) { grp = getgrnam(*list); } if (grp == NULL) rc = EXC_NAME_NOT_FOUND; else (void) putgrent(grp, stdout); } } return (rc); }
static int group_put (const void *ent, FILE * file) { const struct group *gr = (const struct group *) ent; return (putgrent (gr, file) == -1) ? -1 : 0; }
int main(int argc, char **argv) { char * tmpdir = getenv("_FAKEUSER_DIR_"); char *passwd_file, *group_file; name = argv[0]; int opt, ret = 0; int action = 0, uid = 0, gid = 0; char *name = NULL, *passwd = NULL, *members = NULL, *shell = NULL, *gecos = NULL, *dir = NULL; extern char *optarg; while ((opt = getopt(argc, argv, "UGu:g:n:p:m:s:c:d:h")) != -1) { switch (opt) { case 'U': action = 'U'; break; case 'G': action = 'G'; break; case 'u': uid = atoi(optarg); break; case 'g': gid = atoi(optarg); break; case 'n': name = optarg; break; case 'p': passwd = optarg; break; case 'm': members = optarg; break; case 's': shell = optarg; break; case 'c': gecos = optarg; break; case 'd': dir = optarg; break; case 'h': help(); exit(EXIT_SUCCESS); default: /* '?' */ usage_fd(stderr); exit(EXIT_FAILURE); } } if (action == 0 || name == NULL) { usage(); exit(EXIT_FAILURE); } // only continue when environment variable with directory found. if (!tmpdir) { fputs("Error! Not in fakeuser environment\n", stderr); exit(EXIT_FAILURE); } // init file paths passwd_file = (char*)malloc(strlen(tmpdir)+10); strcpy(passwd_file, tmpdir); strcat(passwd_file, "/passwd"); group_file = (char*)malloc(strlen(tmpdir)+10); strcpy(group_file, tmpdir); strcat(group_file, "/group"); // Create directory structure mkdir_r(tmpdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); if (action == 'U') { // create and append passwd entry struct passwd pw; pw.pw_name = name; pw.pw_passwd = passwd ? passwd : ""; pw.pw_gecos = gecos ? gecos : ""; pw.pw_dir = dir ? dir : ""; pw.pw_shell = shell ? shell : ""; pw.pw_uid = uid; pw.pw_gid = gid; // append to file with error handling. FILE * pwf = fopen(passwd_file, "a"); if (pwf) { if(putpwent(&pw, pwf)) ret = EIO; if (fclose(pwf)) ret = EIO; } else ret = EIO; } else if (action == 'G') { // create and append group entry struct group gr; gr.gr_name = name; gr.gr_passwd = passwd ? passwd : ""; gr.gr_gid = gid; char *strings; gr.gr_mem = members ? string_to_array(members, " ,;", &strings) : (char *[]) { NULL }; // append to file with error handling. FILE * pwf = fopen(group_file, "a"); if (pwf) { if(putgrent(&gr, pwf)) ret = EIO; if (fclose(pwf)) ret = EIO; } else ret = EIO; } // return 0 on success or the error value return ret; }