int dogetnetgr(const char **list) { char *host; char *user; char *dom; int rc = EXC_SUCCESS; if (list == NULL || *list == NULL) return (EXC_ENUM_NOT_SUPPORTED); for (; *list != NULL; list++) { printf("\n%s", *list); setnetgrent(*list); for (;;) { rc = getnetgrent(&host, &user, &dom); if (!rc) break; printf(" \\\n\t(%s,%s,%s)", (host) ? host : "", (user) ? user : "", (dom) ? dom : ""); } printf("\n"); } return (rc); }
NGR_R_RETURN getnetgrent_r(NGR_R_CONST char **machinep, NGR_R_CONST char **userp, NGR_R_CONST char **domainp, NGR_R_ARGS) { NGR_R_CONST char *mp, *up, *dp; int res = getnetgrent(&mp, &up, &dp); if (res != 1) return (res); return (copy_protoent(machinep, userp, domainp, mp, up, dp, NGR_R_COPY)); }
/* * Search for a match in a netgroup. This replaces it on broken systems. */ int innetgr(char *group,char *host,char *user,char *dom) { char *hst, *usr, *dm; setnetgrent(group); while (getnetgrent(&hst, &usr, &dm)) { if (((host == 0) || (hst == 0) || !strcmp(host, hst)) && ((user == 0) || (usr == 0) || !strcmp(user, usr)) && ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) { endnetgrent(); return (1); } } endnetgrent(); return (0); }
std::vector<NetGroupTriple> getNetGroupTriples(std::string netgroup) { std::vector<NetGroupTriple> triples; try { if (setnetgrent(netgroup.c_str()) != 1) throw NetGroupException(); char *hostname, *username, *domainname; while (getnetgrent(&hostname, &username, &domainname) == 1) { triples.push_back(NetGroupTriple(hostname, username, domainname)); } } catch (NetGroupException e) { std::cerr << e.what() << " ( for " << netgroup << " )" << std::endl; } endnetgrent(); return triples; }
/* * Load machine list from netgroup (typically NIS) * * Code contributed from Petter Reinholdtsen on 22 Dec 2001. */ linkedlist* read_machinenetgroup(linkedlist * machinelist, const char * groupname) { #ifdef HAVE_SETNETGRENT #ifdef SETNETGRENT_RETURNS_VOID #define WORKAROUND_SETNETGRENT , 1 #else #define WORKAROUND_SETNETGRENT #endif if (setnetgrent(groupname) WORKAROUND_SETNETGRENT) { char *hostp=NULL, *userp=NULL, *domainp=NULL; while (getnetgrent(&hostp, &userp, &domainp)) { if (NULL != hostp) machinelist = machinelist_lladd(machinelist, hostp); } endnetgrent(); } else { fprintf(stderr, _("%s: Unknown netgroup %s.\n"), PACKAGE, groupname); exit (1); /* it should fail on error. */ } #else /* HAVE_SETNETGRENT */ fprintf(stderr, "%s: %s\n", PACKAGE, _("This platform does not support NIS database routines")); #warning "disabled setnetgrent support" #endif return machinelist; }
/* * netgroup */ static int netgroup(int argc, char *argv[]) { char *host, *user, *domain; int first; int rv, i; assert(argc > 1); assert(argv != NULL); #define NETGROUPPRINT(s) (((s) != NULL) ? (s) : "") rv = RV_OK; if (argc == 2) { fprintf(stderr, "Enumeration not supported on netgroup\n"); rv = RV_NOENUM; } else { for (i = 2; i < argc; i++) { setnetgrent(argv[i]); first = 1; while (getnetgrent(&host, &user, &domain) != 0) { if (first) { first = 0; (void)fputs(argv[i], stdout); } (void)printf(" (%s,%s,%s)", NETGROUPPRINT(host), NETGROUPPRINT(user), NETGROUPPRINT(domain)); } if (!first) (void)putchar('\n'); endnetgrent(); } } return rv; }
static char *validate_group(char *group, DATA_BLOB password,int snum) { #ifdef HAVE_NETGROUP { char *host, *user, *domain; setnetgrent(group); while (getnetgrent(&host, &user, &domain)) { if (user) { if (user_ok(user, snum) && password_ok(user,password)) { endnetgrent(); return(user); } } } endnetgrent(); } #endif #ifdef HAVE_GETGRENT { struct group *gptr; setgrent(); while ((gptr = (struct group *)getgrent())) { if (strequal(gptr->gr_name,group)) break; } /* * As user_ok can recurse doing a getgrent(), we must * copy the member list into a pstring on the stack before * use. Bug pointed out by [email protected]. */ if (gptr) { pstring member_list; char *member; size_t copied_len = 0; int i; *member_list = '\0'; member = member_list; for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) { size_t member_len = strlen(gptr->gr_mem[i])+1; if(copied_len+member_len < sizeof(pstring)) { DEBUG(10,("validate_group: = gr_mem = " "%s\n", gptr->gr_mem[i])); safe_strcpy(member, gptr->gr_mem[i], sizeof(pstring) - copied_len - 1); copied_len += member_len; member += copied_len; } else { *member = '\0'; } } endgrent(); member = member_list; while (*member) { static fstring name; fstrcpy(name,member); if (user_ok(name,snum) && password_ok(name,password)) { endgrent(); return(&name[0]); } DEBUG(10,("validate_group = member = %s\n", member)); member += strlen(member) + 1; } } else { endgrent(); return NULL; } } #endif return(NULL); }
JNIEXPORT jobjectArray JNICALL Java_org_apache_hadoop_security_JniBasedUnixGroupsNetgroupMapping_getUsersForNetgroupJNI (JNIEnv *env, jobject jobj, jstring jgroup) { // pointers to free at the end const char *cgroup = NULL; jobjectArray jusers = NULL; // do we need to end the group lookup? int setnetgrentCalledFlag = 0; // if not NULL then THROW exception char *errorMessage = NULL; cgroup = (*env)->GetStringUTFChars(env, jgroup, NULL); if (cgroup == NULL) { goto END; } //-------------------------------------------------- // get users // see man pages for setnetgrent, getnetgrent and endnetgrent UserList *userListHead = NULL; int userListSize = 0; // set the name of the group for subsequent calls to getnetgrent // note that we want to end group lokup regardless whether setnetgrent // was successful or not (as long as it was called we need to call // endnetgrent) setnetgrentCalledFlag = 1; if(setnetgrent(cgroup) == 1) { UserList *current = NULL; // three pointers are for host, user, domain, we only care // about user now char *p[3]; while(getnetgrent(p, p + 1, p + 2)) { if(p[1]) { current = (UserList *)malloc(sizeof(UserList)); current->string = malloc(strlen(p[1]) + 1); strcpy(current->string, p[1]); current->next = userListHead; userListHead = current; userListSize++; } } } //-------------------------------------------------- // build return data (java array) jusers = (jobjectArray)(*env)->NewObjectArray(env, userListSize, (*env)->FindClass(env, "java/lang/String"), NULL); if (jusers == NULL) { errorMessage = "java/lang/OutOfMemoryError"; goto END; } UserList * current = NULL; // note that the loop iterates over list but also over array (i) int i = 0; for(current = userListHead; current != NULL; current = current->next) { jstring juser = (*env)->NewStringUTF(env, current->string); if (juser == NULL) { errorMessage = "java/lang/OutOfMemoryError"; goto END; } (*env)->SetObjectArrayElement(env, jusers, i++, juser); } END: // cleanup if(cgroup) { (*env)->ReleaseStringUTFChars(env, jgroup, cgroup); } if(setnetgrentCalledFlag) { endnetgrent(); } while(userListHead) { UserList *current = userListHead; userListHead = userListHead->next; if(current->string) { free(current->string); } free(current); } // return results or THROW if(errorMessage) { THROW(env, errorMessage, NULL); return NULL; } else { return jusers; } }
static char *validate_group(char *group, DATA_BLOB password,int snum) { #ifdef HAVE_NETGROUP { char *host, *user, *domain; setnetgrent(group); while (getnetgrent(&host, &user, &domain)) { if (user) { if (user_ok(user, snum) && password_ok(user,password)) { endnetgrent(); return(user); } } } endnetgrent(); } #endif #ifdef HAVE_GETGRENT { struct group *gptr; setgrent(); while ((gptr = (struct group *)getgrent())) { if (strequal(gptr->gr_name,group)) break; } /* * As user_ok can recurse doing a getgrent(), we must * copy the member list onto the heap before * use. Bug pointed out by [email protected]. */ if (gptr) { char *member_list = NULL; size_t list_len = 0; char *member; int i; for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) { list_len += strlen(gptr->gr_mem[i])+1; } list_len++; member_list = (char *)SMB_MALLOC(list_len); if (!member_list) { endgrent(); return NULL; } *member_list = '\0'; member = member_list; for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) { size_t member_len = strlen(gptr->gr_mem[i])+1; DEBUG(10,("validate_group: = gr_mem = " "%s\n", gptr->gr_mem[i])); safe_strcpy(member, gptr->gr_mem[i], list_len - (member-member_list)); member += member_len; } endgrent(); member = member_list; while (*member) { if (user_ok(member,snum) && password_ok(member,password)) { char *name = talloc_strdup(talloc_tos(), member); SAFE_FREE(member_list); return name; } DEBUG(10,("validate_group = member = %s\n", member)); member += strlen(member) + 1; } SAFE_FREE(member_list); } else { endgrent(); return NULL; } } #endif return(NULL); }
uid_t Str2Uid(char *uidbuff, char *usercopy, const Promise *pp) { Item *ip, *tmplist; struct passwd *pw; int offset, uid = -2, tmp = -2; char *machine, *user, *domain; if (uidbuff[0] == '+') /* NIS group - have to do this in a roundabout */ { /* way because calling getpwnam spoils getnetgrent */ offset = 1; if (uidbuff[1] == '@') { offset++; } setnetgrent(uidbuff + offset); tmplist = NULL; while (getnetgrent(&machine, &user, &domain)) { if (user != NULL) { AppendItem(&tmplist, user, NULL); } } endnetgrent(); for (ip = tmplist; ip != NULL; ip = ip->next) { if ((pw = getpwnam(ip->name)) == NULL) { Log(LOG_LEVEL_INFO, "Unknown user in promise '%s'", ip->name); if (pp != NULL) { PromiseRef(LOG_LEVEL_INFO, pp); } uid = CF_UNKNOWN_OWNER; /* signal user not found */ } else { uid = pw->pw_uid; if (usercopy != NULL) { strcpy(usercopy, ip->name); } } } DeleteItemList(tmplist); return uid; } if (isdigit((int) uidbuff[0])) { sscanf(uidbuff, "%d", &tmp); uid = (uid_t) tmp; } else { if (strcmp(uidbuff, "*") == 0) { uid = CF_SAME_OWNER; /* signals wildcard */ } else if ((pw = getpwnam(uidbuff)) == NULL) { Log(LOG_LEVEL_INFO, "Unknown user '%s' in promise", uidbuff); uid = CF_UNKNOWN_OWNER; /* signal user not found */ if (usercopy != NULL) { strcpy(usercopy, uidbuff); } } else { uid = pw->pw_uid; } } return uid; }
/* update our image of the net-group of trustworthy hosts */ void get_goodgroup(int force) { # define NG_DELAY (30*60*CLK_TCK) /* 30 minutes */ static unsigned long last_update = -NG_DELAY; unsigned long new_update; struct goodhost *ghp, **ghpp; #ifdef HAVENIS struct hosttbl *htp; char *mach, *usr, *dom; #endif /* HAVENIS */ struct tms tm; /* if no netgroup, then we are finished */ if (goodgroup == NULL || !Mflag) return; /* Do not chatter with the netgroup master too often. */ new_update = times(&tm); if (new_update < last_update + NG_DELAY && !force) return; last_update = new_update; /* forget the old temporary entries */ ghpp = &goodhosts; while ((ghp = *ghpp) != NULL) { if (!ghp->perm) { *ghpp = ghp->next; free(ghp); } else { ghpp = &ghp->next; } } #ifdef HAVENIS /* quit now if we are not one of the trusted masters */ if (!innetgr(goodgroup, &hostname[0], 0,0)) { if (trace) (void)fprintf(fd, "get_goodgroup: %s not in %s\n", &hostname[0], goodgroup); return; } if (trace) (void)fprintf(fd, "get_goodgroup: %s in %s\n", &hostname[0], goodgroup); /* mark the entire netgroup as trusted */ (void)setnetgrent(goodgroup); while (getnetgrent(&mach,&usr,&dom)) { if (mach != NULL) add_good_host(mach,0); } (void)endnetgrent(); /* update list of slaves */ for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) { htp->good = good_host_name(&htp->name[0]); } #endif /* HAVENIS */ }
int main(int argc, char *argv[]) { int msize; char buf[BUFSIZ+1]; int i; char hostname[256]; int hflag; struct rlimit rl; if (argc < 2) usage(); if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { rl.rlim_cur = (rl.rlim_max < MAX_THREADS ? rl.rlim_max : MAX_THREADS); (void) setrlimit(RLIMIT_NOFILE, &rl); (void) enable_extended_FILE_stdio(-1, -1); } (void) gethostname(hostname, sizeof (hostname)); init_who(); msize = snprintf(buf, sizeof (buf), "From %s@%s: ", who, hostname); while ((i = getchar()) != EOF) { if (msize >= (sizeof (buf) - 1)) { (void) fprintf(stderr, "Message too long\n"); exit(1); } buf[msize++] = i; } buf[msize] = '\0'; path = buf; hflag = 1; while (argc > 1) { if (argv[1][0] == '-') { switch (argv[1][1]) { case 'h': hflag = 1; break; case 'n': hflag = 0; break; case 'q': qflag = 1; break; default: usage(); break; } argc--; argv++; continue; } if (hflag) { doit(argv[1]); } else { char *machine, *user, *domain; (void) setnetgrent(argv[1]); while (getnetgrent(&machine, &user, &domain)) { if (machine) doit(machine); else doall(); } (void) endnetgrent(); } argc--; argv++; } thr_exit(NULL); return (0); }
static struct passwd * __yppwlookup(int lookup, char *name, uid_t uid, struct passwd *pw, char *buf, size_t buflen, int *flagsp) { char bf[1 + _PW_NAME_LEN], *ypcurrent = NULL, *map = NULL; int yp_pw_flags = 0, ypcurrentlen, r, s = -1, pw_keynum; static long long yppbuf[_PW_BUF_LEN / sizeof(long long)]; struct _ypexclude *ypexhead = NULL; const char *host, *user, *dom; DBT key; for (pw_keynum = 1; pw_keynum; pw_keynum++) { bf[0] = _PW_KEYBYNUM; bcopy((char *)&pw_keynum, &bf[1], sizeof(pw_keynum)); key.data = (u_char *)bf; key.size = 1 + sizeof(pw_keynum); if (__hashpw(&key, buf, buflen, pw, flagsp) == 0) break; switch (pw->pw_name[0]) { case '+': if (!__ypdomain) { if (_yp_check(&__ypdomain) == 0) continue; } __ypproto_set(pw, yppbuf, *flagsp, &yp_pw_flags); if (!map) { if (lookup == LOOKUP_BYNAME) { map = PASSWD_BYNAME; name = strdup(name); } else { map = PASSWD_BYUID; asprintf(&name, "%u", uid); } } switch (pw->pw_name[1]) { case '\0': if (ypcurrent) { free(ypcurrent); ypcurrent = NULL; } r = yp_match(__ypdomain, map, name, strlen(name), &ypcurrent, &ypcurrentlen); if (r != 0 || ypcurrentlen > buflen) { if (ypcurrent) free(ypcurrent); ypcurrent = NULL; continue; } break; case '@': pwnam_netgrp: if (ypcurrent) { free(ypcurrent); ypcurrent = NULL; } if (s == -1) /* first time */ setnetgrent(pw->pw_name + 2); s = getnetgrent(&host, &user, &dom); if (s == 0) { /* end of group */ endnetgrent(); s = -1; continue; } else { if (user && *user) { r = yp_match(__ypdomain, map, user, strlen(user), &ypcurrent, &ypcurrentlen); } else goto pwnam_netgrp; if (r != 0 || ypcurrentlen > buflen) { if (ypcurrent) free(ypcurrent); ypcurrent = NULL; /* * just because this * user is bad, doesn't * mean they all are. */ goto pwnam_netgrp; } } break; default: if (ypcurrent) { free(ypcurrent); ypcurrent = NULL; } user = pw->pw_name + 1; r = yp_match(__ypdomain, map, user, strlen(user), &ypcurrent, &ypcurrentlen); if (r != 0 || ypcurrentlen > buflen) { if (ypcurrent) free(ypcurrent); ypcurrent = NULL; continue; } break; } bcopy(ypcurrent, buf, ypcurrentlen); buf[ypcurrentlen] = '\0'; if (__ypparse(pw, buf, yp_pw_flags) || __ypexclude_is(&ypexhead, pw->pw_name)) { if (s == 1) /* inside netgrp */ goto pwnam_netgrp; continue; } break; case '-': /* attempted exclusion */ switch (pw->pw_name[1]) { case '\0': break; case '@': setnetgrent(pw->pw_name + 2); while (getnetgrent(&host, &user, &dom)) { if (user && *user) __ypexclude_add(&ypexhead, user); } endnetgrent(); break; default: __ypexclude_add(&ypexhead, pw->pw_name + 1); break; } break; } if ((lookup == LOOKUP_BYUID && pw->pw_uid == uid) || (lookup == LOOKUP_BYNAME && strcmp(pw->pw_name, name) == 0)) goto done; if (s == 1) /* inside netgrp */ goto pwnam_netgrp; continue; } pw = NULL; done: __ypexclude_free(&ypexhead); __ypproto = NULL; if (ypcurrent) free(ypcurrent); ypcurrent = NULL; if (map) free(name); return (pw); }
struct passwd * getpwent(void) { #ifdef YP static char *name = NULL; char *map; #endif char bf[1 + sizeof(_pw_keynum)]; struct passwd *pw = NULL; DBT key; _THREAD_PRIVATE_MUTEX_LOCK(pw); if (!_pw_db && !__initdb()) goto done; #ifdef YP map = PASSWD_BYNAME; if (__getpwent_has_yppw == -1) __getpwent_has_yppw = __has_yppw(); again: if (__getpwent_has_yppw && (__ypmode != YPMODE_NONE)) { const char *user, *host, *dom; int keylen, datalen, r, s; char *key, *data = NULL; if (!__ypdomain) { if (_yp_check(&__ypdomain) == 0) { __ypmode = YPMODE_NONE; goto again; } } switch (__ypmode) { case YPMODE_FULL: if (__ypcurrent) { r = yp_next(__ypdomain, map, __ypcurrent, __ypcurrentlen, &key, &keylen, &data, &datalen); free(__ypcurrent); __ypcurrent = NULL; if (r != 0) { __ypmode = YPMODE_NONE; if (data) free(data); goto again; } __ypcurrent = key; __ypcurrentlen = keylen; } else { r = yp_first(__ypdomain, map, &__ypcurrent, &__ypcurrentlen, &data, &datalen); if (r != 0 || __ypcurrentlen > sizeof(__ypline)) { __ypmode = YPMODE_NONE; if (data) free(data); goto again; } } bcopy(data, __ypline, datalen); free(data); break; case YPMODE_NETGRP: s = getnetgrent(&host, &user, &dom); if (s == 0) { /* end of group */ endnetgrent(); __ypmode = YPMODE_NONE; goto again; } if (user && *user) { r = yp_match(__ypdomain, map, user, strlen(user), &data, &datalen); } else goto again; if (r != 0 || __ypcurrentlen > sizeof(__ypline)) { /* * if the netgroup is invalid, keep looking * as there may be valid users later on. */ if (data) free(data); goto again; } bcopy(data, __ypline, datalen); free(data); break; case YPMODE_USER: if (name) { r = yp_match(__ypdomain, map, name, strlen(name), &data, &datalen); __ypmode = YPMODE_NONE; free(name); name = NULL; if (r != 0 || __ypcurrentlen > sizeof(__ypline)) { if (data) free(data); goto again; } bcopy(data, __ypline, datalen); free(data); } else { /* XXX */ __ypmode = YPMODE_NONE; goto again; } break; case YPMODE_NONE: /* NOTREACHED */ break; } __ypline[datalen] = '\0'; if (__ypparse(&_pw_passwd, __ypline, __yp_pw_flags)) goto again; pw = &_pw_passwd; goto done; } #endif ++_pw_keynum; bf[0] = _PW_KEYBYNUM; bcopy((char *)&_pw_keynum, &bf[1], sizeof(_pw_keynum)); key.data = (u_char *)bf; key.size = 1 + sizeof(_pw_keynum); if (__hashpw(&key, _pw_string, sizeof _pw_string, &_pw_passwd, &_pw_flags)) { #ifdef YP static long long __yppbuf[_PW_BUF_LEN / sizeof(long long)]; const char *user, *host, *dom; /* if we don't have YP at all, don't bother. */ if (__getpwent_has_yppw) { if (_pw_passwd.pw_name[0] == '+') { /* set the mode */ switch (_pw_passwd.pw_name[1]) { case '\0': __ypmode = YPMODE_FULL; break; case '@': __ypmode = YPMODE_NETGRP; setnetgrent(_pw_passwd.pw_name + 2); break; default: __ypmode = YPMODE_USER; name = strdup(_pw_passwd.pw_name + 1); break; } __ypproto_set(&_pw_passwd, __yppbuf, _pw_flags, &__yp_pw_flags); goto again; } else if (_pw_passwd.pw_name[0] == '-') { /* an attempted exclusion */ switch (_pw_passwd.pw_name[1]) { case '\0': break; case '@': setnetgrent(_pw_passwd.pw_name + 2); while (getnetgrent(&host, &user, &dom)) { if (user && *user) __ypexclude_add(&__ypexhead, user); } endnetgrent(); break; default: __ypexclude_add(&__ypexhead, _pw_passwd.pw_name + 1); break; } goto again; } } #endif pw = &_pw_passwd; goto done; } done: _THREAD_PRIVATE_MUTEX_UNLOCK(pw); return (pw); }
/**************************************************************************** validate a group username entry. Return the username or NULL ****************************************************************************/ static char *validate_group(char *group,char *password,int pwlen,int snum) { #ifdef NETGROUP { char *host, *user, *domain; setnetgrent(group); while (getnetgrent(&host, &user, &domain)) { if (user) { if (user_ok(user, snum) && password_ok(user,password,pwlen,NULL)) { endnetgrent(); return(user); } } } endnetgrent(); } #endif #if HAVE_GETGRNAM { struct group *gptr = (struct group *)getgrnam(group); char **member; if (gptr) { member = gptr->gr_mem; while (member && *member) { static fstring name; fstrcpy(name,*member); if (user_ok(name,snum) && password_ok(name,password,pwlen,NULL)) return(&name[0]); member++; } #ifdef GROUP_CHECK_PWENT { struct passwd *pwd; static fstring tm; setpwent (); while (pwd = getpwent ()) { if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) { /* This Entry have PASSWORD and same GID then check pwd */ if (password_ok(NULL, password, pwlen, pwd)) { fstrcpy(tm, pwd->pw_name); endpwent (); return tm; } } } endpwent (); } #endif /* GROUP_CHECK_PWENT */ } } #endif return(NULL); }