1010
1111#include "shadow/gshadow/sgetsgent.h"
1212
13+ #include <errno.h>
1314#include <stddef.h>
1415#include <stdlib.h>
1516#include <string.h>
2223#include "string/strcpy/stpecpy.h"
2324#include "string/strtok/stpsep.h"
2425#include "string/strtok/strsep2arr.h"
26+ #include "typetraits.h"
2527
2628
2729#define FIELDS 4
@@ -36,9 +38,9 @@ sgetsgent(const char *s)
3638 static struct sgrp sgent_ = {};
3739 struct sgrp * sgent = & sgent_ ;
3840
39- char * fields [ 4 ] ;
40- char * p , * end ;
41- size_t n , nadm , nmem , lssize , size ;
41+ int e ;
42+ size_t n , lssize , size ;
43+ struct sgrp * dummy ;
4244
4345 n = strchrcnt (s , ',' ) + 4 ;
4446 lssize = n * sizeof (char * ); // For 'sgent->sg_adm' and 'sgent->sg_mem'
@@ -49,33 +51,66 @@ sgetsgent(const char *s)
4951 if (buf == NULL )
5052 return NULL ;
5153
54+ e = sgetsgent_r (s , sgent , buf , size , & dummy );
55+ if (e != 0 ) {
56+ errno = e ;
57+ return NULL ;
58+ }
59+
60+ return sgent ;
61+ }
62+
63+
64+ // from-string get shadow group entry re-entrant
65+ int
66+ sgetsgent_r (size_t size ;
67+ const char * s , struct sgrp * sgent , char buf [size ], size_t size ,
68+ struct sgrp * * dummy )
69+ {
70+ char * fields [4 ];
71+ char * p , * end ;
72+ size_t n , nadm , nmem , lssize ;
73+
74+ // 'dummy' exists only for historic reasons.
75+ if (dummy != NULL )
76+ * dummy = sgent ;
77+
78+ // The first 'lssize' bytes of 'buf' are used for 'sg_adm' and 'sg_mem'.
79+ n = strchrcnt (s , ',' ) + 4 ;
80+ lssize = n * sizeof (char * );
81+ if (lssize >= size )
82+ return E2BIG ;
83+
84+ // The remaining bytes of 'buf' are used for a copy of 's'.
5285 end = buf + size ;
5386 p = buf + lssize ;
5487 if (stpecpy (p , end , s ) == NULL )
55- return NULL ;
88+ return errno ;
5689
5790 stpsep (p , "\n" );
5891
5992 if (STRSEP2ARR (p , ":" , fields ) == -1 )
60- return NULL ;
93+ return EINVAL ;
6194
6295 sgent -> sg_namp = fields [0 ];
6396 sgent -> sg_passwd = fields [1 ];
6497
98+ if (!is_aligned (buf , char * ))
99+ return EINVAL ;
65100 sgent -> sg_adm = (char * * ) buf ;
66101 nadm = strchrcnt (fields [2 ], ',' ) + 2 ;
67102 if (nadm > n )
68- return NULL ;
103+ return E2BIG ;
69104 if (csv2ls (fields [2 ], nadm , sgent -> sg_adm ) == -1 )
70- return NULL ;
105+ return errno ;
71106
72107 sgent -> sg_mem = sgent -> sg_adm + nadm ;
73108 nmem = strchrcnt (fields [3 ], ',' ) + 2 ;
74109 if (nmem + nadm > n )
75- return NULL ;
110+ return E2BIG ;
76111 if (csv2ls (fields [3 ], nmem , sgent -> sg_mem ) == -1 )
77- return NULL ;
112+ return errno ;
78113
79- return sgent ;
114+ return 0 ;
80115}
81116#endif
0 commit comments