You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by Ben RUBSON <be...@gmail.com> on 2016/04/15 09:14:56 UTC

[users@httpd] Get UID/GID from a username string

Hello,

I already do it with a RewriteMap Perl script, but perhaps a faster (in terms of performance) solution exists.
Let's assume an incoming request contains a username, is there a way to get the system UID of this username string (Linux/FreeBSD) ?
And from a UID string, to get the corresponding GID ?

Thank you very much,

Ben


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string

Posted by Rainer Jung <ra...@kippdata.de>.
Am 15.04.2016 um 18:59 schrieb Rainer Jung:
> Am 15.04.2016 um 18:35 schrieb Eric Covener:
>> Well, it is one option to extend mod_rewrite. What I meant
>> specifically was that any module can implement a rewritemap internal
>> function.
>
> Yes, the feature seems to be a bit too specific for general
> implementation in mod_rewrite.
>
> Ben: have a look at how mod_rewrite accesses its own
> ap_register_rewrite_mapfunc via
>
> map_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_rewrite_mapfunc);
>
> Any module can access the function using this construct. And then
> mod_rewrite registers builtin rewrite map functions e.g. like
>
> map_pfn_register("escape", rewrite_mapfunc_escape);

> Your own module can also register your own functions like myuid and mygid:
>
> map_pfn_register("escape", my_mapfunc_uid);

Oups, I meant: map_pfn_register("myuid", my_mapfunc_uid);

> Then you can configure a RewriteMap to use these functions and they will
> call directly the my_mapfunc_uid function in your module to get the uid
> without the need of an external process with locking etc.
>
> In short: the list of builtin functions for RewriteMap is extensible and
> can be extended by 3rd-arty modules using the above method.
>
> If uid and gid alone isn't powerful enough, you can code whatever logic
> you need in your map function and register it with a name that is
> reasonable for you and doesn't clash with what's already there in
> mod_rewrite.
>
> Regards,
>
> Rainer
>
>> On Fri, Apr 15, 2016 at 12:19 PM, Ben RUBSON <be...@gmail.com>
>> wrote:
>>>>> I can't think of any solution that would work out of the box, but
>>>>> you can always write your own apache module in C.
>>>>
>>>>
>>>> Which could provide nothing but a new internal rewritemap type.
>>>
>>> Rainer, Eric,
>>> Thank you very much for your feedback.
>>>
>>> Yes a new rewritemap seems to be the solution.
>>> type name : usr
>>> functions : uid, gid
>>> parameter : name or #uid
>>>
>>> For example :
>>> RewriteMap getuid usr:uid
>>> RewriteMap getgid usr:gid
>>>
>>> C functions getpwnam and getpwuid would do the job.
>>>
>>> Is a pull request here the right method to proceed ?
>>> https://github.com/apache/httpd/blob/trunk/modules/mappers/mod_rewrite.c
>>>
>>> Thank you very much,
>>>
>>> Ben

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string

Posted by Ben RUBSON <be...@gmail.com>.
>>> Ben: have a look at how mod_rewrite accesses its own ap_register_rewrite_mapfunc via
>> 
>> So Rainer, I just quickly wrote my module, it works, many thanks for your help.
>> 
>> Below is my code, I just have 2 questions regarding it :
>> 1 - do I need to "free(pw)" ?
> 
> (...)
> So you must not free the returned pointer. Two of the man pages don't guarantee thread safety so to stay on the safe side you probably better use the reentrant variants getpwnam_r() and getpwuid_r(). For those you need to allocate the storage before calling them. You can either allocate storage from the request pool (apr_palloc(r->pool, N)) or using malloc/free. Modules typically prefer pool allocation. Pool allocation doesn't need to be freed. The request pool is automatically freed at the end of each request. Even if you need the memory only shorter, if it is not many bytes it should be OK to allocate from the request pool and let it free only at the end of the request.

Thank you for the reentrant tip, I'll use them you're right, we never know.
And nice thing that pool allocations are automatically freed :)

>> 2 - is "key = apr_palloc(r->pool, 7)" the right method ? Doing this I want to avoid buffer overflow in case of uid/gid greater in length than the key parameter.
> 
> Instead of
> 
> key = apr_palloc(r->pool, 7);
> printf(key, "%d", pw->pw_uid);
> 
> you can also use
> 
> key = apr_psprintf(r->pool, "%d", pw->pw_uid);
> 
> And if you are not going to use more complex formatting tokens
> 
> key = apr_ltoa(r->pool, (long)pw->pw_uid);

Very elegant !

>> Thank you very much,
> 
> You're welcome. Nice seeing you picking up that ball so quickly. Welcome to the world of module development :) Your example was a nice one, because you don't need much clutter to realize that module.

Very happy too to, it's totally worth it !
Will be much more performant than a rewritemap program.

I'm already thinking about my next module :)

Ben


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string

Posted by Rainer Jung <ra...@kippdata.de>.
Am 16.04.2016 um 12:09 schrieb Ben RUBSON:
>> Ben: have a look at how mod_rewrite accesses its own ap_register_rewrite_mapfunc via
>
> So Rainer, I just quickly wrote my module, it works, many thanks for your help.
>
> Below is my code, I just have 2 questions regarding it :
> 1 - do I need to "free(pw)" ?

Good question. My (Solaris) man page for getpwnam() says:

   Reentrant Interfaces
      The  getpwnam(),  getpwuid(),  getpwent(),  and  fgetpwent()
      functions use thread-specific data storage that is reused in
      each call to one of these functions by the same thread, mak-
      ing  them  safe  to use but not recommeded for multithreaded
      applications.

The Linux man page says:

        The return value may point to a static area, and may be 
overwritten by subsequent calls to getpwent(3), getpwnam(), or 
getpwuid().   (Do  not  pass  the
        returned pointer to free(3).)

And the latest standards man page of the OpenGroup says:

The getpwnam() function need not be thread-safe.
...
The application shall not modify the structure to which the return value 
points, nor any storage areas pointed to by pointers within the 
structure. The returned pointer, and pointers within the structure, 
might be invalidated or the structure or the storage areas might be 
overwritten by a subsequent call to getpwent(), getpwnam(), or getpwuid().

So you must not free the returned pointer. Two of the man pages don't 
guarantee thread safety so to stay on the safe side you probably better 
use the reentrant variants getpwnam_r() and getpwuid_r(). For those you 
need to allocate the storage before calling them. You can either 
allocate storage from the request pool (apr_palloc(r->pool, N)) or using 
malloc/free. Modules typically prefer pool allocation. Pool allocation 
doesn't need to be freed. The request pool is automatically freed at the 
end of each request. Even if you need the memory only shorter, if it is 
not many bytes it should be OK to allocate from the request pool and let 
it free only at the end of the request.

> 2 - is "key = apr_palloc(r->pool, 7)" the right method ? Doing this I want to avoid buffer overflow in case of uid/gid greater in length than the key parameter.

Instead of

  key = apr_palloc(r->pool, 7);
  printf(key, "%d", pw->pw_uid);

you can also use

  key = apr_psprintf(r->pool, "%d", pw->pw_uid);

And if you are not going to use more complex formatting tokens

  key = apr_ltoa(r->pool, (long)pw->pw_uid);

There's also an apr_itoa() but we might not be sure, that uid_t fits 
into an int.

Finally as a matter of style, I wouldn't reuse the incoming variable 
"key" for outgoing tasks. Instead I would declare it "const char*" as a 
param, and where you set

  *key = '\0';

you could also

   return "";

and then later

  return apr_ltoa(r->pool, (long)pw->pw_uid);

Everything untested ...

But as always there are many solutions that will work.

> Thank you very much,

You're welcome. Nice seeing you picking up that ball so quickly. Welcome 
to the world of module development :) Your example was a nice one, 
because you don't need much clutter to realize that module.

Regards,

Rainer

> #include "http_core.h"
> #include "mod_rewrite.h"
> #include <pwd.h>
>
> static char *uid(request_rec *r, char *key)
> {
> 	struct passwd *pw;
> 	if((pw = getpwnam(key)) == NULL)
> 	{
> 		*key = '\0';
> 	}
> 	else
> 	{
> 		key = apr_palloc(r->pool, 7);
> 		sprintf(key, "%d", pw->pw_uid);
> 	}
> 	return key;
> }
>
> static char *gid(request_rec *r, char *key)
> {
> 	int uid=atoi(key);
> 	struct passwd *pw;
> 	if((pw = getpwuid(uid)) == NULL)
> 	{
> 		*key = '\0';
> 	}
> 	else
> 	{
> 		key = apr_palloc(r->pool, 7);
> 		sprintf(key, "%d", pw->pw_gid);
> 		return key;
> 	}
> 	return key;
> }
>
> static void register_hooks(apr_pool_t *pool)
> {
> 	APR_OPTIONAL_FN_TYPE(ap_register_rewrite_mapfunc) *map_pfn_register;
> 	map_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_rewrite_mapfunc);
> 	map_pfn_register("uid", uid);
> 	map_pfn_register("gid", gid);
> }
>
> AP_DECLARE_MODULE(test) = {
> 	STANDARD20_MODULE_STUFF,NULL,NULL,NULL,NULL,NULL,register_hooks
> };

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string

Posted by Ben RUBSON <be...@gmail.com>.
> Ben: have a look at how mod_rewrite accesses its own ap_register_rewrite_mapfunc via

So Rainer, I just quickly wrote my module, it works, many thanks for your help.

Below is my code, I just have 2 questions regarding it :
1 - do I need to "free(pw)" ?
2 - is "key = apr_palloc(r->pool, 7)" the right method ? Doing this I want to avoid buffer overflow in case of uid/gid greater in length than the key parameter.

Thank you very much,

Cheers,

Ben



#include "http_core.h"
#include "mod_rewrite.h"
#include <pwd.h>

static char *uid(request_rec *r, char *key)
{
	struct passwd *pw;
	if((pw = getpwnam(key)) == NULL)
	{
		*key = '\0';
	}
	else
	{
		key = apr_palloc(r->pool, 7);
		sprintf(key, "%d", pw->pw_uid);
	}
	return key;
}

static char *gid(request_rec *r, char *key)
{
	int uid=atoi(key);
	struct passwd *pw;
	if((pw = getpwuid(uid)) == NULL)
	{
		*key = '\0';
	}
	else
	{
		key = apr_palloc(r->pool, 7);
		sprintf(key, "%d", pw->pw_gid);
		return key;
	}
	return key;
}

static void register_hooks(apr_pool_t *pool)
{
	APR_OPTIONAL_FN_TYPE(ap_register_rewrite_mapfunc) *map_pfn_register;
	map_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_rewrite_mapfunc);
	map_pfn_register("uid", uid);
	map_pfn_register("gid", gid);
}

AP_DECLARE_MODULE(test) = {
	STANDARD20_MODULE_STUFF,NULL,NULL,NULL,NULL,NULL,register_hooks
};



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string

Posted by Ben RUBSON <be...@gmail.com>.
>> Well, it is one option to extend mod_rewrite. What I meant
>> specifically was that any module can implement a rewritemap internal
>> function.
> 
> Yes, the feature seems to be a bit too specific for general implementation in mod_rewrite.

I was thinking about mod_rewrite because these functions would have then been easily available to everyone.
And quite easy to develop, as it only requires to extend the existing functions catalog :)
But quite specific I agree.

> Ben: have a look at how mod_rewrite accesses its own ap_register_rewrite_mapfunc via
> 
> map_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_rewrite_mapfunc);
> 
> Any module can access the function using this construct. And then mod_rewrite registers builtin rewrite map functions e.g. like
> 
> map_pfn_register("escape", rewrite_mapfunc_escape);
> 
> Your own module can also register your own functions like myuid and mygid:
> 
> map_pfn_register("myuid", my_mapfunc_uid);
> 
> Then you can configure a RewriteMap to use these functions and they will call directly the my_mapfunc_uid function in your module to get the uid without the need of an external process with locking etc.

Many thanks Rainer for this howto !
I have never written a module from scratch, but I found the documentation :
https://httpd.apache.org/docs/2.4/developer/modguide.html
Does not seems so difficult to just register some new rewritemap functions.

> In short: the list of builtin functions for RewriteMap is extensible and can be extended by 3rd-arty modules using the above method.
> 
> If uid and gid alone isn't powerful enough, you can code whatever logic you need in your map function and register it with a name that is reasonable for you and doesn't clash with what's already there in mod_rewrite.

Sounds perfect, again, many thanks Rainar !

>> On Fri, Apr 15, 2016 at 12:19 PM, Ben RUBSON <be...@gmail.com> wrote:
>>>>> I can't think of any solution that would work out of the box, but
>>>>> you can always write your own apache module in C.
>>>> 
>>>> 
>>>> Which could provide nothing but a new internal rewritemap type.
>>> 
>>> Rainer, Eric,
>>> Thank you very much for your feedback.
>>> 
>>> Yes a new rewritemap seems to be the solution.
>>> type name : usr
>>> functions : uid, gid
>>> parameter : name or #uid
>>> 
>>> For example :
>>> RewriteMap getuid usr:uid
>>> RewriteMap getgid usr:gid
>>> 
>>> C functions getpwnam and getpwuid would do the job.
>>> 
>>> Is a pull request here the right method to proceed ?
>>> https://github.com/apache/httpd/blob/trunk/modules/mappers/mod_rewrite.c
>>> 
>>> Thank you very much,
>>> 
>>> Ben


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string

Posted by Rainer Jung <ra...@kippdata.de>.
Am 15.04.2016 um 18:35 schrieb Eric Covener:
> Well, it is one option to extend mod_rewrite. What I meant
> specifically was that any module can implement a rewritemap internal
> function.

Yes, the feature seems to be a bit too specific for general 
implementation in mod_rewrite.

Ben: have a look at how mod_rewrite accesses its own 
ap_register_rewrite_mapfunc via

map_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_rewrite_mapfunc);

Any module can access the function using this construct. And then 
mod_rewrite registers builtin rewrite map functions e.g. like

map_pfn_register("escape", rewrite_mapfunc_escape);

Your own module can also register your own functions like myuid and mygid:

map_pfn_register("escape", my_mapfunc_uid);

Then you can configure a RewriteMap to use these functions and they will 
call directly the my_mapfunc_uid function in your module to get the uid 
without the need of an external process with locking etc.

In short: the list of builtin functions for RewriteMap is extensible and 
can be extended by 3rd-arty modules using the above method.

If uid and gid alone isn't powerful enough, you can code whatever logic 
you need in your map function and register it with a name that is 
reasonable for you and doesn't clash with what's already there in 
mod_rewrite.

Regards,

Rainer

> On Fri, Apr 15, 2016 at 12:19 PM, Ben RUBSON <be...@gmail.com> wrote:
>>>> I can't think of any solution that would work out of the box, but
>>>> you can always write your own apache module in C.
>>>
>>>
>>> Which could provide nothing but a new internal rewritemap type.
>>
>> Rainer, Eric,
>> Thank you very much for your feedback.
>>
>> Yes a new rewritemap seems to be the solution.
>> type name : usr
>> functions : uid, gid
>> parameter : name or #uid
>>
>> For example :
>> RewriteMap getuid usr:uid
>> RewriteMap getgid usr:gid
>>
>> C functions getpwnam and getpwuid would do the job.
>>
>> Is a pull request here the right method to proceed ?
>> https://github.com/apache/httpd/blob/trunk/modules/mappers/mod_rewrite.c
>>
>> Thank you very much,
>>
>> Ben

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string

Posted by Eric Covener <co...@gmail.com>.
Well, it is one option to extend mod_rewrite. What I meant
specifically was that any module can implement a rewritemap internal
function.

On Fri, Apr 15, 2016 at 12:19 PM, Ben RUBSON <be...@gmail.com> wrote:
>>> I can't think of any solution that would work out of the box, but
>>> you can always write your own apache module in C.
>>
>>
>> Which could provide nothing but a new internal rewritemap type.
>
> Rainer, Eric,
> Thank you very much for your feedback.
>
> Yes a new rewritemap seems to be the solution.
> type name : usr
> functions : uid, gid
> parameter : name or #uid
>
> For example :
> RewriteMap getuid usr:uid
> RewriteMap getgid usr:gid
>
> C functions getpwnam and getpwuid would do the job.
>
> Is a pull request here the right method to proceed ?
> https://github.com/apache/httpd/blob/trunk/modules/mappers/mod_rewrite.c
>
> Thank you very much,
>
> Ben
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
> For additional commands, e-mail: users-help@httpd.apache.org
>



-- 
Eric Covener
covener@gmail.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string

Posted by Ben RUBSON <be...@gmail.com>.
>> I can't think of any solution that would work out of the box, but
>> you can always write your own apache module in C.
> 
> 
> Which could provide nothing but a new internal rewritemap type.

Rainer, Eric,
Thank you very much for your feedback.

Yes a new rewritemap seems to be the solution.
type name : usr
functions : uid, gid
parameter : name or #uid

For example :
RewriteMap getuid usr:uid
RewriteMap getgid usr:gid

C functions getpwnam and getpwuid would do the job.

Is a pull request here the right method to proceed ?
https://github.com/apache/httpd/blob/trunk/modules/mappers/mod_rewrite.c

Thank you very much,

Ben

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string

Posted by Eric Covener <co...@gmail.com>.
On Fri, Apr 15, 2016 at 9:38 AM, Rainer Canavan
<ra...@sevenval.com> wrote:
> I can't think of any solution that would work out of the box, but
> you can always write your own apache module in C.


Which could provide nothing but a new internal rewritemap type.

-- 
Eric Covener
covener@gmail.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string

Posted by Rainer Canavan <ra...@sevenval.com>.
On Fri, Apr 15, 2016 at 9:14 AM, Ben RUBSON <be...@gmail.com> wrote:
> Hello,
>
> I already do it with a RewriteMap Perl script, but perhaps a faster (in terms of performance) solution exists.
> Let's assume an incoming request contains a username, is there a way to get the system UID of this username string (Linux/FreeBSD) ?
> And from a UID string, to get the corresponding GID ?

I can't think of any solution that would work out of the box, but
you can always write your own apache module in C.

rainer

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] Get UID/GID from a username string [wd-vc]

Posted by Ben RUBSON <be...@gmail.com>.
Well I would like to be able to do it on the fly when a request is proceeded by Apache.
Through mod_rewrite for example.
I already do it with a RewriteMap which returns me UID/GID, but perhaps there is a less time consuming solution.

Ben



> In case your system uses /etc/passwd, this will get you both values separated by a colon:
> 
> grep username /etc/passwd|cut -f3,4 -d:
> 
> HTH
> Kurt Bremser
> AMOS Austria
> 
> Newton was wrong. There is no gravity. The Earth sucks.
> ________________________________________
> Von: Ben RUBSON [ben.rubson@gmail.com]
> Gesendet: Freitag, 15. April 2016 09:14
> An: users@httpd.apache.org
> Betreff: [users@httpd] Get UID/GID from a username string [wd-vc]
> 
> Hello,
> 
> I already do it with a RewriteMap Perl script, but perhaps a faster (in terms of performance) solution exists.
> Let's assume an incoming request contains a username, is there a way to get the system UID of this username string (Linux/FreeBSD) ?
> And from a UID string, to get the corresponding GID ?
> 
> Thank you very much,
> 
> Ben

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


AW: [users@httpd] Get UID/GID from a username string [wd-vc]

Posted by "Bremser, Kurt (AMOS Austria GmbH)" <Ku...@allianz.at>.
In case your system uses /etc/passwd, this will get you both values separated by a colon:

grep username /etc/passwd|cut -f3,4 -d:

HTH
Kurt Bremser
AMOS Austria

Newton was wrong. There is no gravity. The Earth sucks.
________________________________________
Von: Ben RUBSON [ben.rubson@gmail.com]
Gesendet: Freitag, 15. April 2016 09:14
An: users@httpd.apache.org
Betreff: [users@httpd] Get UID/GID from a username string [wd-vc]

Hello,

I already do it with a RewriteMap Perl script, but perhaps a faster (in terms of performance) solution exists.
Let's assume an incoming request contains a username, is there a way to get the system UID of this username string (Linux/FreeBSD) ?
And from a UID string, to get the corresponding GID ?

Thank you very much,

Ben


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org



AMOS Austria GmbH 
1130 Wien, Hietzinger Kai 101-105 
FN 365014k, Handelsgericht Wien 
UID: ATU 66614737 

http://www.allianz.at 

******************************************************** 
Dieses E-Mail und allfaellig daran angeschlossene Anhaenge 
enthalten Informationen, die vertraulich und 
ausschliesslich fuer den (die) bezeichneten Adressaten 
bestimmt sind. 
Wenn Sie nicht der genannte Adressat sind, darf dieses 
E-Mail samt allfaelliger Anhaenge von Ihnen weder anderen 
Personen zugaenglich gemacht noch in anderer Weise 
verwertet werden.
Wenn Sie nicht der beabsichtigte Empfaenger sind, bitten
wir Sie, dieses E-Mail und saemtliche angeschlossene
Anhaenge zu loeschen. 

Please note: This email and any files transmitted with it is 
intended only for the named recipients and may contain 
confidential and/or privileged information. If you are not the 
intended recipient, please do not read, copy, use or disclose 
the contents of this communication to others and notify the 
sender immediately. Then please delete the email and any 
copies of it. Thank you.
********************************************************

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org