Index: yp.c
===================================================================
RCS file: /cvs/src/usr.sbin/ypldap/yp.c,v
retrieving revision 1.14
diff -u -p -r1.14 yp.c
--- yp.c        11 Feb 2015 01:26:00 -0000      1.14
+++ yp.c        12 Feb 2015 02:21:09 -0000
@@ -51,6 +51,7 @@ int   yp_check(struct svc_req *);
 int    yp_valid_domain(char *, struct ypresp_val *);
 void   yp_make_val(struct ypresp_val *, char *, int);
 void   yp_make_keyval(struct ypresp_key_val *, char *, char *);
+bool_t ypdb_xdr_get_all(XDR *xdrs, ypreq_nokey *req);
 
 static struct env      *env;
 
@@ -218,6 +219,8 @@ yp_dispatch(struct svc_req *req, SVCXPRT
                return;
        case YPPROC_ALL:
                log_debug("ypproc_all");
+               xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
+               xdr_result = (xdrproc_t) ypdb_xdr_get_all;
                if (yp_check(req) == -1)
                        return;
                cb = (void *)ypproc_all_2_svc;
@@ -548,13 +551,175 @@ ypproc_next_2_svc(ypreq_key *arg, struct
 ypresp_all *
 ypproc_all_2_svc(ypreq_nokey *arg, struct svc_req *req)
 {
-       static struct ypresp_all        res;
+       struct ypresp_val fake;
 
-       if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1)
-               return (&res);
+       if (yp_valid_domain(arg->domain, &fake) == -1)
+               return (NULL);
+       if (strcmp(arg->map, "passwd.byname") &&
+           strcmp(arg->map, "passwd.byuid") &&
+           strcmp(arg->map, "group.byname") &&
+           strcmp(arg->map, "group.bygid") &&
+           strcmp(arg->map, "netid.byname")) {
+               return (NULL);
+       }
+       return ((void *) arg);
+}
 
-       svcerr_auth(req->rq_xprt, AUTH_FAILED);
-       return (NULL);
+static bool_t
+ypdb_xdr_get_all_passwd(XDR *xdrs, struct ypresp_all *resp, int byname)
+{
+       static char key[YPMAXRECORD + 1];
+       struct userent *ue;
+
+       RB_FOREACH(ue, user_name_tree, env->sc_user_names) {
+               size_t len, keylen = strlen(ue->ue_line);
+
+               resp->more = TRUE;
+               resp->ypresp_all_u.val.stat = TRUE;
+
+               if (byname) {
+                       strlcpy(key, ue->ue_line, sizeof key);
+                       resp->ypresp_all_u.val.key.keydat_val = key;
+                       resp->ypresp_all_u.val.key.keydat_len = keylen;
+               }
+               else {
+                       int kl = snprintf(key, sizeof key, "%u", ue->ue_uid);
+
+                       if (kl < 0) {
+                               log_warnx("%s: key too long", __func__);
+                               return FALSE;
+                       }
+                       resp->ypresp_all_u.val.key.keydat_val = key;
+                       resp->ypresp_all_u.val.key.keydat_len = kl;
+               }
+
+               ue->ue_line[keylen] = ':';
+               len = strnlen(ue->ue_line, YPMAXRECORD);
+               resp->ypresp_all_u.val.val.valdat_val = ue->ue_line;
+               resp->ypresp_all_u.val.val.valdat_len = len;
+
+               if (!xdr_ypresp_all(xdrs, resp)) {
+                       log_warn("%s: %s (%zu bytes)", __func__, key, len);
+                       return FALSE;
+               }
+
+               ue->ue_line[keylen] = '\0';
+       }
+       return TRUE;
+}
+
+static bool_t
+ypdb_xdr_get_all_group(XDR *xdrs, struct ypresp_all *resp, int byname)
+{
+       static char key[YPMAXRECORD + 1];
+       struct groupent *ge;
+
+       RB_FOREACH(ge, group_name_tree, env->sc_group_names) {
+               size_t len, keylen = strlen(ge->ge_line);
+
+               resp->more = TRUE;
+               resp->ypresp_all_u.val.stat = TRUE;
+               if (byname) {
+                       strlcpy(key, ge->ge_line, sizeof key);
+                       resp->ypresp_all_u.val.key.keydat_val = key;
+                       resp->ypresp_all_u.val.key.keydat_len = keylen;
+               }
+               else {
+                       int kl = snprintf(key, sizeof key, "%u", ge->ge_gid);
+
+                       if (kl < 0) {
+                               log_warnx("%s: key too long", __func__);
+                               return FALSE;
+                       }
+                       resp->ypresp_all_u.val.key.keydat_val = key;
+                       resp->ypresp_all_u.val.key.keydat_len = kl;
+               }
+
+               ge->ge_line[keylen] = ':';
+               len = strnlen(ge->ge_line, YPMAXRECORD);
+               resp->ypresp_all_u.val.val.valdat_val = ge->ge_line;
+               resp->ypresp_all_u.val.val.valdat_len = len;
+
+               if (!xdr_ypresp_all(xdrs, resp)) {
+                       log_warn("%s: %s (%zu bytes)", __func__, key, len);
+                       return FALSE;
+               }
+
+               ge->ge_line[keylen] = '\0';
+       }
+       return TRUE;
+}
+
+static bool_t
+ypdb_xdr_get_all_netid_byname(XDR *xdrs, struct ypresp_all *resp)
+{
+       static char key[YPMAXRECORD + 1];
+       struct userent *ue;
+
+       RB_FOREACH(ue, user_name_tree, env->sc_user_names) {
+               size_t len = strlen(ue->ue_netid_line);
+               int keylen;
+
+               keylen = snprintf(key, sizeof key, "unix.%u@%s", ue->ue_uid,
+                   env->sc_domainname);
+               if (keylen < 0) {
+                       log_warnx("%s: key too long", __func__);
+                       return FALSE;
+               }
+
+               resp->more = TRUE;
+               resp->ypresp_all_u.val.stat = TRUE;
+               resp->ypresp_all_u.val.key.keydat_val = key;
+               resp->ypresp_all_u.val.key.keydat_len = keylen;
+
+               resp->ypresp_all_u.val.val.valdat_val = ue->ue_netid_line;
+               resp->ypresp_all_u.val.val.valdat_len = len;
+
+               if (!xdr_ypresp_all(xdrs, resp)) {
+                       log_warn("%s: %s (%zu bytes)", __func__, key, len);
+                       return FALSE;
+               }
+       }
+       return TRUE;
+}
+
+bool_t
+ypdb_xdr_get_all(XDR *xdrs, ypreq_nokey *req)
+{
+       static struct ypresp_all resp;
+
+       if (strcmp(req->map, "passwd.byname") == 0) {
+               if (ypdb_xdr_get_all_passwd(xdrs, &resp, TRUE) == FALSE)
+                       return FALSE;
+       }
+       else if (strcmp(req->map, "passwd.byuid") == 0) {
+               if (ypdb_xdr_get_all_passwd(xdrs, &resp, FALSE) == FALSE)
+                       return FALSE;
+       }
+       else if (strcmp(req->map, "group.byname") == 0) {
+               if (ypdb_xdr_get_all_group(xdrs, &resp, TRUE) == FALSE)
+                       return FALSE;
+       }
+       else if (strcmp(req->map, "group.byuid") == 0) {
+               if (ypdb_xdr_get_all_group(xdrs, &resp, FALSE) == FALSE)
+                       return FALSE;
+       }
+       else if (strcmp(req->map, "netid.byname") == 0) {
+               if (ypdb_xdr_get_all_netid_byname(xdrs, &resp) == FALSE)
+                       return FALSE;
+       }
+       else
+               return FALSE;
+
+       memset(&resp, 0, sizeof resp);
+       resp.more = FALSE;
+       resp.ypresp_all_u.val.stat = YP_NOKEY;
+
+       if (!xdr_ypresp_all(xdrs, &resp)) {
+               log_warn("xdr_ypresp_all: the last entry");
+               return FALSE;
+       }
+       return TRUE;
 }
 
 ypresp_master *

Reply via email to