The eternal uid issue

classic Classic list List threaded Threaded
28 messages Options
12
Reply | Threaded
Open this post in threaded view
|

The eternal uid issue

Daniel
Hi Cygwin lovers,

After some weeks of serious compiling, researching, understanding, fixing, testing
and compiling again, I managed to get the Sendmail source code compiled and working.

But I had to compromise in some critical areas. One of them is the uid issue.

* sendmail, procmail, mail.local assume that the id of the privileged user is '0'.

Within the current Cygwin DLL, this is '18'. So the maintainer of, let's say, the
procmail code has to change a constant, named ROOT_uid to be 18 if compiled in
cygwin. I had to do the same in Sendmails' own Mail Delivery Agent, 'mail.local'.

But that's no real fix. That's a work-around. Cygwin is supposed to emulate Linux,
so why not change the 'getuid' function to return '0' if the uid is '18'? This is
exactly what all Linux source code expects, so we would never have to worry about it
again.

Instead, maintainers constantly have to "correct" this "bug" in every new version of
their source code.

The general idea behind this is "never to break user space", where the programs are
seen as the users. Actually, it's Linus Torwalds's first rule of kernel programming
and one can read here how serious he is about this:

https://lkml.org/lkml/2012/12/23/75

Isn't it about time to make this our First Directive also?

Daniel


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

L A Walsh
D. Boland wrote:
> But I had to compromise in some critical areas. One of them is the uid issue.
>
> * sendmail, procmail, mail.local assume that the id of the privileged user is '0'.
>
> Isn't it about time to make this our First Directive also?
>
>  
I thought sendmail used capabilities?

Isn't it about time none of them used a fixed 'uid', but used capabilities?

I thought hard coding a Uid was going out with the dodo bird?




--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Daniel
Linda Walsh wrote:

>
> D. Boland wrote:
> > But I had to compromise in some critical areas. One of them is the uid issue.
> >
> > * sendmail, procmail, mail.local assume that the id of the privileged user is '0'.
> >
> > Isn't it about time to make this our First Directive also?
> >
> >
> I thought sendmail used capabilities?
>
> Isn't it about time none of them used a fixed 'uid', but used capabilities?
>
> I thought hard coding a Uid was going out with the dodo bird?

You didn't get the point. We create a kernel on which Linux software runs. We don't
dictate how software should be written.

Regards,
Daniel


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Corinna Vinschen-2
In reply to this post by Daniel
On Jul 23 10:06, D. Boland wrote:

> Hi Cygwin lovers,
>
> After some weeks of serious compiling, researching, understanding, fixing, testing
> and compiling again, I managed to get the Sendmail source code compiled and working.
>
> But I had to compromise in some critical areas. One of them is the uid issue.
>
> * sendmail, procmail, mail.local assume that the id of the privileged user is '0'.
>
> Within the current Cygwin DLL, this is '18'. So the maintainer of, let's say, the
> procmail code has to change a constant, named ROOT_uid to be 18 if compiled in
> cygwin. I had to do the same in Sendmails' own Mail Delivery Agent, 'mail.local'.
The port of procmail is old (2004), and not changed ever since.
This patch is old and wrong.

> But that's no real fix. That's a work-around. Cygwin is supposed to emulate Linux,
> so why not change the 'getuid' function to return '0' if the uid is '18'? This is
> exactly what all Linux source code expects, so we would never have to worry about it
> again.
>
> Instead, maintainers constantly have to "correct" this "bug" in every new version of
> their source code.
>
> The general idea behind this is "never to break user space", where the programs are
> seen as the users. Actually, it's Linus Torwalds's first rule of kernel programming
> and one can read here how serious he is about this:
>
> https://lkml.org/lkml/2012/12/23/75
Doesn't work well with systemd...

> Isn't it about time to make this our First Directive also?

Not in relation to the uid.  In contrast to Linux we don't have the one
single root user.  We have potentially endless numbers of them, and one
of them, not necessarily SYSTEM, is used to run the service.  Keep in
mind that there may also be company policy in place which disallows
installing services under specific accounts unless absolutely necessary.

Therefore, while we mostly strive to make Cygwin accommodate user
space, we're not able to do it related to the root uid.

The right thing to do is to add Cygwin-required tweaks in the most
unobtrusive way you can come up with and send them upstream.  Cygwin is
by far not the only platform which requires upstream patches.  Most
portable projects have platform-specifc code.  Think of using pam for
authentication, socket options only available on some platforms and
more.  There is nothing inherently bad or wrong with that and upstream
maintainers striving for portability will take platform-specific changes
if they are nicely written and the maintainer can be convinced of the
necessity.

As for the root checks, if you *must* check for an administrative user
account, check if the group 544 is in the user token (getgroups(3),
getgrouplist(3)).

Other than that, there's often code checking file ownership, along
the lines of

  if (stat.st_uid != 0)
    ...

For Cygwin, convert these checks to something along the lines of

  if (stat.st_uid != getuid ())
    ...

Because it's basically the same thing, while allowing to run the
service under any account.

Even better, try to convince the upstream maintainer to change these
tests into a platform-specific function call, for instance:

  if (is_admin (stat.st_uid != 0))
    ...

int
is_admin (uid_t uid)
{
#ifdef __CYGWIN__
  return [getgrouplist(uid, ...) contains group 544];
#else [other platform]
  return [different test];
#else
  return uid == 0;
#endif
}


Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

attachment0 (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Daniel
Hi Corinna,

Corinna Vinschen wrote:

>
> > Isn't it about time to make this our First Directive also?
>
> Not in relation to the uid.  In contrast to Linux we don't have the one
> single root user.  We have potentially endless numbers of them, and one
> of them, not necessarily SYSTEM, is used to run the service.  Keep in
> mind that there may also be company policy in place which disallows
> installing services under specific accounts unless absolutely necessary.
>
> Therefore, while we mostly strive to make Cygwin accommodate user
> space, we're not able to do it related to the root uid.
>

Thanks for your lengthly and detailed answer. I appreciate that. But don't you think
upstream maintainers will raise at least one eyebrow if we propose code that makes
any user who starts the program the root/admin user?
You suggest only those who are in the admin group. But that will soon be any service
that starts up.

It actually is my solution to running Sendmail: create the Sendmail user, called
'smmsp' and make it an Administrator, so it can impersonate users on my system.
But I don't like my solution, because this would mean I have to create an admin-user
for any Linux service that I install. So now my Cygwin setup would be crowded with
highly
privileged daemons, listening, waiting to get hacked.

The more elegant solution would be to create only one secondary privileged user,
let's call it 'root' ;-). Now Sendmail can start as root, switch to the totally
*unprivileged* 'smmsp' user and receive mail.
Of course the real bonus is that these unprivileged users wouldn't need passwords,
since they are impersonated, not logged on. These would consequently be
*super-secure* users, because it is impossible to login with an empty password.

Why is this related to the uid issue? I already tested the second solution. I found
out that if I assign my 'root' user the '0' id in /etc/passwd, it actually works. I
was delighted, because I could roll-back all these weird changes I put in the
Sendmail/procmail/mail.local source to fix the getuid != 0 problem.

If we go with this MS-imposed idea of "putting services in admin-context", Cygwin
security will be done for in the long run. Why not make the leap and show MS
admins/developers how it should be done?

Sincerely,
Daniel


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Larry Hall (Cygwin)
On 07/23/2014 07:35 AM, D. Boland wrote:

<snip>

> It actually is my solution to running Sendmail: create the Sendmail user, called
> 'smmsp' and make it an Administrator, so it can impersonate users on my system.
> But I don't like my solution, because this would mean I have to create an admin-user
> for any Linux service that I install. So now my Cygwin setup would be crowded with
> highly
> privileged daemons, listening, waiting to get hacked.
>
> The more elegant solution would be to create only one secondary privileged user,
> let's call it 'root' ;-).

I believe what you're referring to here is 'cyg-server' which Cygwin already
has.  Corinna referenced this here:

<https://cygwin.com/ml/cygwin/2014-07/msg00196.html>

--
Larry

_____________________________________________________________________

A: Yes.
 > Q: Are you sure?
 >> A: Because it reverses the logical flow of conversation.
 >>> Q: Why is top posting annoying in email?

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Corinna Vinschen-2
In reply to this post by Daniel
On Jul 23 13:35, D. Boland wrote:

> Corinna Vinschen wrote:
> > Not in relation to the uid.  In contrast to Linux we don't have the one
> > single root user.  We have potentially endless numbers of them, and one
> > of them, not necessarily SYSTEM, is used to run the service.  Keep in
> > mind that there may also be company policy in place which disallows
> > installing services under specific accounts unless absolutely necessary.
> >
> > Therefore, while we mostly strive to make Cygwin accommodate user
> > space, we're not able to do it related to the root uid.
>
> Thanks for your lengthly and detailed answer. I appreciate that. But
> don't you think upstream maintainers will raise at least one eyebrow
> if we propose code that makes any user who starts the program the
> root/admin user?  You suggest only those who are in the admin group.
> But that will soon be any service that starts up.
You're getting this wrong.  Cygwin is not the OS.  We do not make
every user an admin since we're in no position to do that.  We can't
give the user any more rights the OS is already giving the user.

The idea of such a test is to make the test independent of the actual
uid.  There are two cases.  One is to check if the user has admin
rights to perform certain actions, the other is to check if a file
ownership is safe.  A safe ownership is one where the file belongs
to the user running the service.  On Linux or BSD systems that's
usually the root user, in our case it's some arbitrary user account.
The check is basically the same.

> It actually is my solution to running Sendmail: create the Sendmail
> user, called 'smmsp' and make it an Administrator, so it can
> impersonate users on my system.  But I don't like my solution, because
> this would mean I have to create an admin-user for any Linux service
> that I install. So now my Cygwin setup would be crowded with highly
> privileged daemons, listening, waiting to get hacked.

That's what the cyg_server account is meant for.  It's the one account
which has the right to change the user context even when using method 1
from the setuid overview of the User's Guide.

Other services don't need this permissions, they just have to have
the right to create certain objects.  Cygserver is such a service,
for instance.  It's perfectly fine for cygserver to run under SYSTEM
or, FWIW, any other account with local administrative privileges.

> The more elegant solution would be to create only one secondary
> privileged user, let's call it 'root' ;-). Now Sendmail can start as
> root, switch to the totally *unprivileged* 'smmsp' user and receive
> mail.  Of course the real bonus is that these unprivileged users
> wouldn't need passwords, since they are impersonated, not logged on.
> These would consequently be *super-secure* users, because it is
> impossible to login with an empty password.

Same thing with cyg_server.

> Why is this related to the uid issue? I already tested the second
> solution. I found out that if I assign my 'root' user the '0' id in
> /etc/passwd, it actually works. I was delighted, because I could
> roll-back all these weird changes I put in the
> Sendmail/procmail/mail.local source to fix the getuid != 0 problem.

Yes, you can do that and it was always possible, but it requires
unnecessary user changes.  Also, passwd and group files are going
to become entirely superfluous at one point, and there's not a
single account which is translated to uid 0 on the fly.  There
simply isn't one.


Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

attachment0 (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Andrey Repin
In reply to this post by Daniel
Greetings, D. Boland!

> Hi Corinna,

> Corinna Vinschen wrote:
>>
>> > Isn't it about time to make this our First Directive also?
>>
>> Not in relation to the uid.  In contrast to Linux we don't have the one
>> single root user.  We have potentially endless numbers of them, and one
>> of them, not necessarily SYSTEM, is used to run the service.  Keep in
>> mind that there may also be company policy in place which disallows
>> installing services under specific accounts unless absolutely necessary.
>>
>> Therefore, while we mostly strive to make Cygwin accommodate user
>> space, we're not able to do it related to the root uid.
>>

> Thanks for your lengthly and detailed answer. I appreciate that. But don't you think
> upstream maintainers will raise at least one eyebrow if we propose code that makes
> any user who starts the program the root/admin user?

You obviously did not understand Corinna's reply.
And removed the part of reply that directly answer all your questions.

> You suggest only those who are in the admin group. But that will soon be any service
> that starts up.

That's essentially the same as starting services as root on *NIX system.
I fail to see the difference.

> It actually is my solution to running Sendmail: create the Sendmail user, called
> 'smmsp' and make it an Administrator, so it can impersonate users on my system.
> But I don't like my solution, because this would mean I have to create an admin-user
> for any Linux service that I install. So now my Cygwin setup would be crowded with
> highly privileged daemons, listening, waiting to get hacked.

Windows privilege model allow you to alleviate such concerns.

> The more elegant solution would be to create only one secondary privileged user,
> let's call it 'root' ;-). Now Sendmail can start as root, switch to the totally
> *unprivileged* 'smmsp' user and receive mail.

This is essentially what Cygwin is doing right now.

> Of course the real bonus is that these unprivileged users wouldn't need passwords,
> since they are impersonated, not logged on. These would consequently be
> *super-secure* users, because it is impossible to login with an empty password.

You'd be surprised.

> Why is this related to the uid issue?

Because there's no fixed UID. This is a core system difference, that you have
to live with.

> I already tested the second solution. I found out that if I assign my 'root'
> user the '0' id in /etc/passwd, it actually works. I was delighted, because
> I could roll-back all these weird changes I put in the
> Sendmail/procmail/mail.local source to fix the getuid != 0 problem.

/etc/passwd will soon be gone.

> If we go with this MS-imposed idea of "putting services in admin-context",

There's no such idea. You just imagined it.

> Cygwin security will be done for in the long run. Why not make the leap and
> show MS admins/developers how it should be done?

You really think they are all idiots?... Like, really?


--
WBR,
Andrey Repin ([hidden email]) 23.07.2014, <20:01>

Sorry for my terrible english...


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Christopher Faylor-8
On Wed, Jul 23, 2014 at 08:08:07PM +0400, Andrey Repin wrote:
>Greetings, D. Boland!
>> Cygwin security will be done for in the long run. Why not make the leap and
>> show MS admins/developers how it should be done?
>
>You really think they are all idiots?... Like, really?

Sure, why not.  MS admins/developers are all idiots who are apparently
supposed to be taught by Cygwin developers who have been getting it
wrong for many years until being correct by the OP.

To the OP: If you want to start a dialog, do research and ask questions.
Don't just assume that you understand everything and can provide insight
that no one else has thought of.

cgf

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Daniel
In reply to this post by Corinna Vinschen-2
Hi Corinna,

Thanks for the reply.

Corinna Vinschen wrote:

>
> On Jul 23 13:35, D. Boland wrote:
> > Corinna Vinschen wrote:
> > > Not in relation to the uid.  In contrast to Linux we don't have the one
> > > single root user.  We have potentially endless numbers of them, and one
> > > of them, not necessarily SYSTEM, is used to run the service.  Keep in
> > > mind that there may also be company policy in place which disallows
> > > installing services under specific accounts unless absolutely necessary.
> > >
> > > Therefore, while we mostly strive to make Cygwin accommodate user
> > > space, we're not able to do it related to the root uid.
> >
> > Thanks for your lengthly and detailed answer. I appreciate that. But
> > don't you think upstream maintainers will raise at least one eyebrow
> > if we propose code that makes any user who starts the program the
> > root/admin user?  You suggest only those who are in the admin group.
> > But that will soon be any service that starts up.
>
> You're getting this wrong.  Cygwin is not the OS.  We do not make
> every user an admin since we're in no position to do that.  We can't
> give the user any more rights the OS is already giving the user.

Yes, Cygwin is not the OS. But to the user-software, it re-presents the OS as if it
were Linux. That's what an emulator does.

>
> The idea of such a test is to make the test independent of the actual
> uid.  There are two cases.  One is to check if the user has admin
> rights to perform certain actions, the other is to check if a file
> ownership is safe.  A safe ownership is one where the file belongs
> to the user running the service.  On Linux or BSD systems that's
> usually the root user, in our case it's some arbitrary user account.
> The check is basically the same.
>
> > It actually is my solution to running Sendmail: create the Sendmail
> > user, called 'smmsp' and make it an Administrator, so it can
> > impersonate users on my system.  But I don't like my solution, because
> > this would mean I have to create an admin-user for any Linux service
> > that I install. So now my Cygwin setup would be crowded with highly
> > privileged daemons, listening, waiting to get hacked.
>
> That's what the cyg_server account is meant for.  It's the one account
> which has the right to change the user context even when using method 1
> from the setuid overview of the User's Guide.
>
> Other services don't need this permissions, they just have to have
> the right to create certain objects.  Cygserver is such a service,
> for instance.  It's perfectly fine for cygserver to run under SYSTEM
> or, FWIW, any other account with local administrative privileges.
>
> > The more elegant solution would be to create only one secondary
> > privileged user, let's call it 'root' ;-). Now Sendmail can start as
> > root, switch to the totally *unprivileged* 'smmsp' user and receive
> > mail.  Of course the real bonus is that these unprivileged users
> > wouldn't need passwords, since they are impersonated, not logged on.
> > These would consequently be *super-secure* users, because it is
> > impossible to login with an empty password.
>
> Same thing with cyg_server.
>
> > Why is this related to the uid issue? I already tested the second
> > solution. I found out that if I assign my 'root' user the '0' id in
> > /etc/passwd, it actually works. I was delighted, because I could
> > roll-back all these weird changes I put in the
> > Sendmail/procmail/mail.local source to fix the getuid != 0 problem.
>
> Yes, you can do that and it was always possible, but it requires
> unnecessary user changes.  Also, passwd and group files are going
> to become entirely superfluous at one point, and there's not a
> single account which is translated to uid 0 on the fly.  There
> simply isn't one.

That's my point. All Linux software expects one. So Cygwin has to provide one.
Otherwise, the emulation breaks.

Sendmail, for instance, is filled to the brim with uid checks, all assuming that
there is a '0' account. Its whole idea of security is based around it. Below a
sample:

$ grep -r getuid *
sendmail/deliver.c:                             if (RealUid != 0 && RealUid !=
getuid())
sendmail/deliver.c:                                        (int) getuid(), (int)
geteuid(),
sendmail/deliver.c:                     ret = safefile(m->m_mailer, getuid(),
getgid(),
sendmail/deliver.c:                             (int) getuid(), (int) geteuid(),
sendmail/main.c:        RealUid = getuid();
sendmail/main.c:                      (geteuid() != getuid() || getegid() !=
getgid()));
sendmail/main.c:                           (int) geteuid(), (int) getuid(),
sendmail/main.c:                                   (int) geteuid(), (int) getuid());
sendmail/main.c:                                   (int) geteuid(), (int) getuid());
sendmail/main.c:                if (dp == EX_OK && UseMSP && (geteuid() == 0 ||
getuid() == 0))
sendmail/main.c:                           (int) getuid(), (int) getgid(),
sendmail/main.c:                    (getuid() != RunAsUid &&
sendmail/main.c:                     (to_real_uid || geteuid() == 0 || getuid() ==
0)))
sendmail/main.c:            getuid() != 0 && geteuid() != 0)
sendmail/main.c:                           (int) geteuid(), (int) getuid(),


$ grep -r setuid *
sendmail/deliver.c:                             if (new_euid != geteuid() &&
setuid(new_euid) < 0 && suidwarn)
sendmail/deliver.c:                                     syserr("openmailer:
setuid(%ld) failed",
sendmail/deliver.c:                             if (setuid(new_ruid) < 0 &&
suidwarn)
sendmail/deliver.c:                                     syserr("openmailer:
setuid(%ld) failed",
sendmail/deliver.c:             /* we have to open the data file BEFORE setuid() */
sendmail/deliver.c:             if (setuid(RealUid) < 0 && suidwarn)
sendmail/deliver.c:                     syserr("mailfile: setuid(%ld) failed",
(long) RealUid);
sendmail/deliver.c:             (void) setuid(RealUid);
sendmail/main.c:                if (setuid(new_uid) < 0)
sendmail/main.c:                        syserr("main: setuid(%d) failed", (int)
new_uid);
sendmail/main.c:        (void) setuid(RealUid);
sendmail/main.c:                                        syserr("drop_privileges:
second setuid(%d) attempt failed",
sendmail/main.c:                                syserr("drop_privileges: setuid(%d)
failed",
sendmail/main.c:                if (RunAsUid != 0 && setuid(0) == 0)
sendmail/main.c:                        **  allows a non-root process to override
setuid()
sendmail/main.c:                        syserr("drop_privileges: setuid(0) succeeded
(when it should not)");
sendmail/main.c:                else if (RunAsUid != euid && setuid(euid) == 0)
sendmail/main.c:                        **  if a non-root effective-uid calls
setuid(real-uid)
sendmail/readcf.c:      bool can_setuid = RunAsUid == 0;
sendmail/readcf.c:                      if (can_setuid)
sendmail/readcf.c:                      else if (can_setuid)
sendmail/readcf.c:                              if (can_setuid || EffGid ==
runasgid)
sendmail/readcf.c:                              else if (can_setuid || EffGid ==
gr->gr_gid)

These greps are only a small sample. Changing all these lines of code would be
insane. I would instantly introduce bugs, which will haunt me until I finally decide
to rewrite the whole thing. This is *not* how emulating works.

In your previous mail, you propose the following function to check for 'root'
privileges, which an upstream maintainer could put in his code:

int
is_admin (uid_t uid)
{
#ifdef __CYGWIN__
  return [getgrouplist(uid, ...) contains group 544];
#else [other platform]
  return [different test];
#else
  return uid == 0;
#endif
}

But this only introduces a new function which she has to put into multiple locations
of the original code. So again, why not just modify the 'getuid' function in
cygwin1.dll to return '0' if the current user is actually SYSTEM or one of the
administrators?

Then you have rock-solid emulation. I would not have to modify a single line of
code.

Sincerely,
Daniel


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Daniel
In reply to this post by Christopher Faylor-8
Hi Christopher,

Thanks for your reply.

Christopher Faylor wrote:

>
> On Wed, Jul 23, 2014 at 08:08:07PM +0400, Andrey Repin wrote:
> >Greetings, D. Boland!
> >> Cygwin security will be done for in the long run. Why not make the leap and
> >> show MS admins/developers how it should be done?
> >
> >You really think they are all idiots?... Like, really?
>
> Sure, why not.  MS admins/developers are all idiots who are apparently
> supposed to be taught by Cygwin developers who have been getting it
> wrong for many years until being correct by the OP.
>
> To the OP: If you want to start a dialog, do research and ask questions.
> Don't just assume that you understand everything and can provide insight
> that no one else has thought of.
>
> cgf

I didn't say 'idiots', but I did LOL at Andrey's suggestion. Andrey, I'm beginning
to like you. By the way, your english really isn't that bad.

What I meant was that MS dicided to take away impersonation privileges from the
SYSTEM user, without educating admins/developers about the new model or alternatives
for SYSTEM.

I searched the web extensively for an explanation on the newly imposed restriction.
I didn't find one yet. Only vague advice to not start services using the local
System account:

"Minimize the use of the Local System account on the site servers and site systems
by not installing other services that use the Local System account. This ensures
that other processes cannot take advantage of the enhanced privileges of the
system’s computer account, accessing Configuration Manager 2007 files and data
through those other systems."
--
source: http://technet.microsoft.com/en-us/library/bb680595.aspx

So I have to assume that it was to enhance Windows security. That is not
far-fetched, since the SYSTEM "user" is totally unrestricted and not suited to be
exposed directly to users from the outside.
I also have to assume that what they mean by "not installing other services that use
the Local System account" is to create a new user and running a service on behalf of
it.

Here's how they explain how to configure MS SQL Server (which uses impersonation),
but without explaining the underlying security model for services:

http://msdn.microsoft.com/en-us/library/ms143504.aspx

The only reference I can find about the service security model are the terms
"minimum rights" and "minimum privileges".

In Linux, the daemon security model is well-known and can be implemented by running
as an 'unprivileged user'. Sendmail uses this idea extensively.

Again, the only option I have at this moment is to run the Sendmail user (smmsp) as
an Administrator, so it can do impersonation. But this does *not* constitute
'minimum privileges', nor does this make the Sendmail user run as an 'unprivileged
user'.

The preferred solution is to only *start* Sendmail with a privileged user, let's say
'cyg_server'. Now Sendmail can switch to the 'smmsp' user and be running totally
unprivileged, only having access to its mail queue directory.

But after configuring Sendmail this way, it starts to complain about not having
access permissions, because it detects it was not started with the root user (getuid
!= 0).

So, my original question was: can the Cygwin function 'getuid' be made to return '0'
if the program is running as the SYSTEM user? But because SYSTEM cannot be used
anymore, Corinna suggests to use 'cyg_server' instead and put checks for
administrator rights in the Sendmail source.

In my reply to her in this thread, I rephrased my question: can the Cygwin function
'getuid' be made to return '0' if the program is running as the SYSTEM user or is
running with administrator rights?

Cincerely,
Daniel


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Andrey Repin
Greetings, D. Boland!

> What I meant was that MS dicided to take away impersonation privileges from the
> SYSTEM user, without educating admins/developers about the new model or alternatives
> for SYSTEM.

There's no "model", there's "rights" or "capabilities", or "privileges".

> I searched the web extensively for an explanation on the newly imposed restriction.
> I didn't find one yet.

Because there's none.

> Only vague advice to not start services using the local System account:

> "Minimize the use of the Local System account on the site servers and site systems
> by not installing other services that use the Local System account. This ensures
> that other processes cannot take advantage of the enhanced privileges of the
> system’s computer account, accessing Configuration Manager 2007 files and data
> through those other systems."

Exactly that. What is unclear?

> So I have to assume that it was to enhance Windows security.

It's to enhance operating security of default installations. "Windows
security" as a "model" isn't changed in even slightest way.

> That is not far-fetched, since the SYSTEM "user" is totally unrestricted and
> not suited to be exposed directly to users from the outside.
> I also have to assume that what they mean by "not installing other services that use
> the Local System account" is to create a new user and running a service on behalf of
> it.

> Here's how they explain how to configure MS SQL Server (which uses impersonation),
> but without explaining the underlying security model for services:

> http://msdn.microsoft.com/en-us/library/ms143504.aspx

> The only reference I can find about the service security model are the terms
> "minimum rights" and "minimum privileges".

It's not "model" again. It's privilege separation.

> In Linux, the daemon security model is well-known and can be implemented by running
> as an 'unprivileged user'. Sendmail uses this idea extensively.

That's no different here. The point you miss is that in Windows you don't have
single "privileged user", which is just a long synonym for "root" in Linux
world. You have exactly "privileged users", as in "users that have privileges
above and beyond".

> Again, the only option I have at this moment is to run the Sendmail user (smmsp) as
> an Administrator, so it can do impersonation.

You contradicting yourself. Mere lines above you said your Linux user is
unprivileged, now you want to do impersonation. Which is only possible for
privileged user.

> But this does *not* constitute 'minimum privileges', nor does this make the
> Sendmail user run as an 'unprivileged user'.

That because... see above.

> The preferred solution is to only *start* Sendmail with a privileged user, let's say
> 'cyg_server'. Now Sendmail can switch to the 'smmsp' user and be running totally
> unprivileged, only having access to its mail queue directory.

Right.

> But after configuring Sendmail this way, it starts to complain about not having
> access permissions, because it detects it was not started with the root user (getuid
> != 0).

Look, here you have a problem, that you don't want to understand it seems.
Checking for 'privileged user' is not the same as checking for 'uid == 0'.

> So, my original question was: can the Cygwin function 'getuid' be made to return '0'

No. A blatant and angry one. There's more systems, than Linux, and not all of
them employ same security model, nor their model can be closely approximated
to the one in Linux.

> if the program is running as the SYSTEM user? But because SYSTEM cannot be used
> anymore, Corinna suggests to use 'cyg_server' instead and put checks for
> administrator rights in the Sendmail source.

> In my reply to her in this thread, I rephrased my question: can the Cygwin function
> 'getuid' be made to return '0'

"Can", "will" and "want" (or in our case "should") are three completely
different terms. The fact their areas intersect sometimes is a complete
coincidence.

> if the program is running as the SYSTEM user or is
> running with administrator rights?

No. If you want to do the right thing, do it right.


--
WBR,
Andrey Repin ([hidden email]) 24.07.2014, <16:05>

Sorry for my terrible english...
Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Corinna Vinschen-2
In reply to this post by Daniel
On Jul 24 08:52, D. Boland wrote:

> In your previous mail, you propose the following function to check for 'root'
> privileges, which an upstream maintainer could put in his code:
>
> int
> is_admin (uid_t uid)
> {
> #ifdef __CYGWIN__
>   return [getgrouplist(uid, ...) contains group 544];
> #else [other platform]
>   return [different test];
> #else
>   return uid == 0;
> #endif
> }
>
> But this only introduces a new function which she has to put into multiple locations
> of the original code. So again, why not just modify the 'getuid' function in
> cygwin1.dll to return '0' if the current user is actually SYSTEM or one of the
> administrators?
>
> Then you have rock-solid emulation. I would not have to modify a single line of
> code.
You're kidding, right?  What about code like this:

  struct stat st;
  stat("foo", &st);
  if (st.st_uid != getuid ())
    /*error*/
  else
    /*do something*/

I'm not saying that this is overly elegant coding, but just as you
expect that getuid() returns 0 for any admin, other applications will
expect that getuid() reflects reality.

Why don't you just override getuid in your application to serve the
applications needs?

  #ifdef __CYGWIN__
  #define getuid() CYG_getuid()
  #endif

  [...]

  #ifdef __CYGWIN__
  #undef getuid
  uid_t
  CYG_getuid ()
  {
    /* Return 0 for any admin user. */
    if (/*getgroups() contains group 544*/)
      return 0;
    return getuid ();
  }

But be careful.  Just because there are multiple users with admin
permissions, that doesn't mean they all want their mail in the same
mailbox for user 0...


Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

attachment0 (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Daniel
Hi Corinna,

Corinna Vinschen wrote:
> > But this only introduces a new function which she has to put into multiple locations
> > of the original code. So again, why not just modify the 'getuid' function in
> > cygwin1.dll to return '0' if the current user is actually SYSTEM or one of the
> > administrators?
> >
> > Then you have rock-solid emulation. I would not have to modify a single line of
> > code.
>
> You're kidding, right?  

Haha. I must admit that I was not kidding. I got stuck with the idea that "there can
only be one".

> What about code like this:
>
>   struct stat st;
>   stat("foo", &st);
>   if (st.st_uid != getuid ())
>     /*error*/
>   else
>     /*do something*/
>
> I'm not saying that this is overly elegant coding, but just as you
> expect that getuid() returns 0 for any admin, other applications will
> expect that getuid() reflects reality.
>
> Why don't you just override getuid in your application to serve the
> applications needs?
>
>   #ifdef __CYGWIN__
>   #define getuid()      CYG_getuid()
>   #endif
>
>   [...]
>
>   #ifdef __CYGWIN__
>   #undef getuid
>   uid_t
>   CYG_getuid ()
>   {
>     /* Return 0 for any admin user. */
>     if (/*getgroups() contains group 544*/)
>       return 0;
>     return getuid ();
>   }
>
> But be careful.  Just because there are multiple users with admin
> permissions, that doesn't mean they all want their mail in the same
> mailbox for user 0...

Thanks for the overloading code. I already tested it. Now I can leave the Sendmail
code (almost) unchanged. Thanks also for the time you put into this. I hope the
RedHat people pay you well.

I have Sendmail ready to be released, but only the 'crude' version (running as an
admin user). I'd like to go for the preferred solution (starting as admin, switching
to unprivileged). The uid issue is sorted. But to get it there, I have one final
problem to solve.

Sendmail checks if the user's home directories are group- or world writable. It does
this with 'stat'. If Sendmail is running in 'crude' mode (main program and children
running as the Sendmail 'smmsp' user, made admin), stat returns the right file mode
for my home directory (rwxr-xr-x). The email is delivered.

If I have Sendmail running in preferred mode (main program as cyg_server, children
running as 'smmsp', removed from admin group), stat returns the wrong mode
(rwxrwxrwx). As a consequence, Sendmail refuses to deliver email.

Can I do anything about this?

Cincerely,
Daniel


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Jeffrey Altman-2
On 7/24/2014 5:42 PM, D. Boland wrote:
> Hi Corinna,
>
> Corinna Vinschen wrote:
>> But be careful.  Just because there are multiple users with admin
>> permissions, that doesn't mean they all want their mail in the same
>> mailbox for user 0...

Things are actually worse than Corinna and others have described.  The
SYSTEM account is a built-in local machine account that by default is
granted certain permissions but those permissions are configurable.

There is a built-in Administrator account which everyone is taught to
never use

There are two default groups "Administrators" and "Domain
Administrators" whose members are considered to be administrators but
whose logon sessions run in a restricted mode which is tighter in many
regards than standard users UNLESS the process running as that user is
granted "elevated" access.

Simply working off the user's SID or GIDs to make decisions are often
going to result in failures that appear to your users as unpredictable.

> Thanks for the overloading code. I already tested it. Now I can leave the Sendmail
> code (almost) unchanged. Thanks also for the time you put into this. I hope the
> RedHat people pay you well.
>
> I have Sendmail ready to be released, but only the 'crude' version (running as an
> admin user). I'd like to go for the preferred solution (starting as admin, switching
> to unprivileged). The uid issue is sorted. But to get it there, I have one final
> problem to solve.

On all modern versions of Windows the accounts that are members of the
Administrators and Domain Administrators accounts are going to run
unprivileged.

In the Windows world background daemons (aka services) should be
assigned their own service account that is granted the minimum set of
privileges required.   Windows permissions are much more fine grained
than POSIX and this gives you a great deal of control.

Shedding privileges can be done by a privileged process by replacing its
process (or thread access tokens) with a more restricted version.

> Sendmail checks if the user's home directories are group- or world writable. It does
> this with 'stat'. If Sendmail is running in 'crude' mode (main program and children
> running as the Sendmail 'smmsp' user, made admin), stat returns the right file mode
> for my home directory (rwxr-xr-x). The email is delivered.

On Windows file systems (as with many UNIX network file systems, think
AFS as one example) the UNIX mode is not going to have much value.
What matters are the entries in the access control list and that is what
should be checked and manipulated.   Cygwin can't turn a non-POSIX file
system into a POSIX file system no matter how hard it tries.

> If I have Sendmail running in preferred mode (main program as cyg_server, children
> running as 'smmsp', removed from admin group), stat returns the wrong mode
> (rwxrwxrwx). As a consequence, Sendmail refuses to deliver email.

The UNIX mode cannot describe the fine grained permissions of the access
control language for the file system.

> Can I do anything about this?

Other members of this group might have some additional suggestions on
how to remove checks but if you really want secure delivery of e-mail on
a Windows file system you will need to write code that is capable of
understanding the capabilities of the file system.  Just as you would on
UNIX if the home directory was in a network file system that relied upon
GSS/Kerberos network credentials and Access Control Lists instead of
UNIX mode for access control.

Jeffrey Altman



smime.p7s (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Corinna Vinschen-2
In reply to this post by Daniel
On Jul 24 23:42, D. Boland wrote:

> [...]
> Sendmail checks if the user's home directories are group- or world
> writable. It does this with 'stat'. If Sendmail is running in 'crude'
> mode (main program and children running as the Sendmail 'smmsp' user,
> made admin), stat returns the right file mode for my home directory
> (rwxr-xr-x). The email is delivered.
>
> If I have Sendmail running in preferred mode (main program as
> cyg_server, children running as 'smmsp', removed from admin group),
> stat returns the wrong mode (rwxrwxrwx). As a consequence, Sendmail
> refuses to deliver email.
>
> Can I do anything about this?
That shouldn't happen.  Unless your home dir is on FAT or FAT32
and you're using the wrong umask.  For a start, can you try this:

Login as user smmsp twice, once with admin privs, once without.
Each time, run the following command:

  $ strace -o stat.trace stat <your home dir>

And send the output of stat, as well as the two generated trace files
here.  This might give us a clue.


Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

attachment0 (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Corinna Vinschen-2
On Jul 25 14:42, Corinna Vinschen wrote:

> On Jul 24 23:42, D. Boland wrote:
> > [...]
> > Sendmail checks if the user's home directories are group- or world
> > writable. It does this with 'stat'. If Sendmail is running in 'crude'
> > mode (main program and children running as the Sendmail 'smmsp' user,
> > made admin), stat returns the right file mode for my home directory
> > (rwxr-xr-x). The email is delivered.
> >
> > If I have Sendmail running in preferred mode (main program as
> > cyg_server, children running as 'smmsp', removed from admin group),
> > stat returns the wrong mode (rwxrwxrwx). As a consequence, Sendmail
> > refuses to deliver email.
> >
> > Can I do anything about this?
>
> That shouldn't happen.  Unless your home dir is on FAT or FAT32
> and you're using the wrong umask.  For a start, can you try this:
>
> Login as user smmsp twice, once with admin privs, once without.
> Each time, run the following command:
>
>   $ strace -o stat.trace stat <your home dir>
>
> And send the output of stat, as well as the two generated trace files
> here.  This might give us a clue.
Oh, hang on.  Is this using the default setuid method 1 and is your
home dir on a remote share, by any chance?


Corinna

--
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

attachment0 (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: The eternal uid issue

Daniel
Corinna Vinschen wrote:
> Oh, hang on.  Is this using the default setuid method 1 and is your
> home dir on a remote share, by any chance?

No. All file locations are local (C:\). I'll send you the output later on.


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The deprecated uid issue: use caps

L A Walsh
In reply to this post by Daniel
D. Boland wrote:

> Linda Walsh wrote:
>> D. Boland wrote:
>>> But I had to compromise in some critical areas. One of them is the uid issue.
>>>
>>> * sendmail, procmail, mail.local assume that the id of the privileged user is '0'.
>>>
>>> Isn't it about time to make this our First Directive also?
>>>
>>>
>> I thought sendmail used capabilities?
>>
>> Isn't it about time none of them used a fixed 'uid', but used capabilities?
>>
>> I thought hard coding a Uid was going out with the dodo bird?
>
> You didn't get the point. We create a kernel on which Linux software runs. We don't
> dictate how software should be written.
You are missing the point.

MS privilege model is the MS version of the linux capability model.

MS didn't get it wrong, linux has been slow to adopt, but MS had linux
capabilities 10 years before linux did.

Several other people have tried to explain that the way to go is to use
the "minimum priviledge model".

For example, almost ALL user have the "unreadable directory traversal"
priv/capability.

To enforce it cost alot in execution time on Windows (as it would under
cygwin).

Another priviledge is to "impersonate" another user; sendmail would
likely need such a privilege.  Another is to ignore file-permissions.
It would be questionable whether or not sendmail needed that.

Sendmail was using capabilities back in 2000 when I brought a basic
"non-reciprocal action"  bug in the capability code to the attention
of Ted Tso, he told me and others that I didn't know what I was talking
about and they were following POSIX and my "find" was irrelevant under
POSIX.
About 10 days later there was a day-zero exploit involving the bug
in the defective code using sendmail's capability usage as the vector.
The result was kernel caps being disabled for the next few years until
the cap-code could be reviewed by more eyes and knew what to look for.

So I'm pretty sure sendmail has had code to extensively run solely off
of capabilities and has had it for some time.  I'd be surprised if it
was removed.

Linux software that uses the capability model is likely to not have
these problems.  But saying that any random linux software with security
bugs
from the past should work on cygwin, seems like a ridiculous stance to
take.

You can set capabilities on files processes and network sockets. Linux file
systems with "extended attributes" or "alternate data forks" (2 names
for the
same thing), can and do support "SETCAP" on linux files that works just
like SETUID, but for capabilities.

MS only supports the capability model and uses it to implement their
Admin or privileged user model.  They don't support the less secure setuid
model that linux is moving away from.

Does this help clarify the issue ?






--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply | Threaded
Open this post in threaded view
|

Re: The deprecated uid issue: use caps

Daniel
Hi Linda,

Linda Walsh wrote:

>
> D. Boland wrote:
> > Linda Walsh wrote:
> >> D. Boland wrote:
> >>> But I had to compromise in some critical areas. One of them is the uid issue.
> >>>
> >>> * sendmail, procmail, mail.local assume that the id of the privileged user is '0'.
> >>>
> >>> Isn't it about time to make this our First Directive also?
> >>>
> >>>
> >> I thought sendmail used capabilities?
> >>
> >> Isn't it about time none of them used a fixed 'uid', but used capabilities?
> >>
> >> I thought hard coding a Uid was going out with the dodo bird?
> >
> > You didn't get the point. We create a kernel on which Linux software runs. We don't
> > dictate how software should be written.
> You are missing the point.
>
> MS privilege model is the MS version of the linux capability model.
>
> MS didn't get it wrong, linux has been slow to adopt, but MS had linux
> capabilities 10 years before linux did.
>
> Several other people have tried to explain that the way to go is to use
> the "minimum priviledge model".
>
> For example, almost ALL user have the "unreadable directory traversal"
> priv/capability.
>
> To enforce it cost alot in execution time on Windows (as it would under
> cygwin).
>
> Another priviledge is to "impersonate" another user; sendmail would
> likely need such a privilege.  Another is to ignore file-permissions.
> It would be questionable whether or not sendmail needed that.
>
> Sendmail was using capabilities back in 2000 when I brought a basic
> "non-reciprocal action"  bug in the capability code to the attention
> of Ted Tso, he told me and others that I didn't know what I was talking
> about and they were following POSIX and my "find" was irrelevant under
> POSIX.
> About 10 days later there was a day-zero exploit involving the bug
> in the defective code using sendmail's capability usage as the vector.
> The result was kernel caps being disabled for the next few years until
> the cap-code could be reviewed by more eyes and knew what to look for.
>
> So I'm pretty sure sendmail has had code to extensively run solely off
> of capabilities and has had it for some time.  I'd be surprised if it
> was removed.
>
> Linux software that uses the capability model is likely to not have
> these problems.  But saying that any random linux software with security
> bugs
> from the past should work on cygwin, seems like a ridiculous stance to
> take.
>
> You can set capabilities on files processes and network sockets. Linux file
> systems with "extended attributes" or "alternate data forks" (2 names
> for the
> same thing), can and do support "SETCAP" on linux files that works just
> like SETUID, but for capabilities.
>
> MS only supports the capability model and uses it to implement their
> Admin or privileged user model.  They don't support the less secure setuid
> model that linux is moving away from.
>
> Does this help clarify the issue ?

Thanks for disagreeing. You are completely right. Sendmail seems to demand a much
more restrictive impersonation policy than Windows offers. That's why I can't get
the thing to work. It constantly tests if certain actions are allowed and if so, it
just refuses to deliver e-mail.

I'll look into this capabilities thing, but I do not intend to change anything
significant  in the Sendmail code. Maybe the folks at Proofpoint will switch to it
one day.

Daniel


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

12