r23779: Change from v2 or later to v3 or later.
[nivanova/samba-autobuild/.git] / source3 / nsswitch / winbindd_sid.c
index 13b2cd05550133fb7a162fdef6e7f3157df428e8..84a7e76e78fe8077f98ef5690bff4eb1092fbad8 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -103,7 +103,8 @@ void winbindd_lookupname(struct winbindd_cli_state *state)
                  name_domain, lp_winbind_separator(), name_user));
 
        winbindd_lookupname_async(state->mem_ctx, name_domain, name_user,
                  name_domain, lp_winbind_separator(), name_user));
 
        winbindd_lookupname_async(state->mem_ctx, name_domain, name_user,
-                                 lookupname_recv, state);
+                                 lookupname_recv, WINBINDD_LOOKUPNAME, 
+                                 state);
 }
 
 static void lookupname_recv(void *private_data, BOOL success,
 }
 
 static void lookupname_recv(void *private_data, BOOL success,
@@ -183,6 +184,40 @@ static void sid2uid_recv(void *private_data, BOOL success, uid_t uid)
        request_ok(state);
 }
 
        request_ok(state);
 }
 
+static void sid2uid_lookupsid_recv( void *private_data, BOOL success, 
+                                   const char *domain_name, 
+                                   const char *name, 
+                                   enum lsa_SidType type)
+{
+       struct winbindd_cli_state *state =
+               talloc_get_type_abort(private_data, struct winbindd_cli_state);
+       DOM_SID sid;
+
+       if (!success) {
+               DEBUG(5, ("sid2uid_lookupsid_recv Could not convert get sid type for %s\n",
+                         state->request.data.sid));
+               request_error(state);
+               return;
+       }
+
+       if ( (type!=SID_NAME_USER) && (type!=SID_NAME_COMPUTER) ) {
+               DEBUG(5,("sid2uid_lookupsid_recv: Sid %s is not a user or a computer.\n", 
+                        state->request.data.sid));
+               request_error(state);
+               return;         
+       }
+
+       if (!string_to_sid(&sid, state->request.data.sid)) {
+               DEBUG(1, ("sid2uid_lookupsid_recv: Could not get convert sid %s from string\n",
+                         state->request.data.sid));
+               request_error(state);
+               return;
+       }
+       
+       /* always use the async interface (may block) */
+       winbindd_sid2uid_async(state->mem_ctx, &sid, sid2uid_recv, state);
+}
+
 void winbindd_sid_to_uid(struct winbindd_cli_state *state)
 {
        DOM_SID sid;
 void winbindd_sid_to_uid(struct winbindd_cli_state *state)
 {
        DOM_SID sid;
@@ -200,8 +235,11 @@ void winbindd_sid_to_uid(struct winbindd_cli_state *state)
                return;
        }
 
                return;
        }
 
-       /* always use the async interface (may block) */
-       winbindd_sid2uid_async(state->mem_ctx, &sid, sid2uid_recv, state);
+       /* Validate the SID as a user.  Hopefully this will hit cache.
+          Needed to prevent DoS by exhausting the uid allocation
+          range from random SIDs. */
+
+       winbindd_lookupsid_async( state->mem_ctx, &sid, sid2uid_lookupsid_recv, state );
 }
 
 /* Convert a sid to a gid.  We assume we only have one rid attached to the
 }
 
 /* Convert a sid to a gid.  We assume we only have one rid attached to the
@@ -223,6 +261,43 @@ static void sid2gid_recv(void *private_data, BOOL success, gid_t gid)
        request_ok(state);
 }
 
        request_ok(state);
 }
 
+static void sid2gid_lookupsid_recv( void *private_data, BOOL success, 
+                                   const char *domain_name, 
+                                   const char *name, 
+                                   enum lsa_SidType type)
+{
+       struct winbindd_cli_state *state =
+               talloc_get_type_abort(private_data, struct winbindd_cli_state);
+       DOM_SID sid;
+
+       if (!success) {
+               DEBUG(5, ("sid2gid_lookupsid_recv: Could not get sid type for %s\n",
+                         state->request.data.sid));
+               request_error(state);
+               return;
+       }
+
+       if ( (type!=SID_NAME_DOM_GRP) &&
+            (type!=SID_NAME_ALIAS) && 
+            (type!=SID_NAME_WKN_GRP) ) 
+       {
+               DEBUG(5,("sid2gid_lookupsid_recv: Sid %s is not a group.\n", 
+                        state->request.data.sid));
+               request_error(state);
+               return;         
+       }
+
+       if (!string_to_sid(&sid, state->request.data.sid)) {
+               DEBUG(1, ("sid2gid_lookupsid_recv: Could not get convert sid %s from string\n",
+                         state->request.data.sid));
+               request_error(state);
+               return;
+       }
+       
+       /* always use the async interface (may block) */
+       winbindd_sid2gid_async(state->mem_ctx, &sid, sid2gid_recv, state);
+}
+
 void winbindd_sid_to_gid(struct winbindd_cli_state *state)
 {
        DOM_SID sid;
 void winbindd_sid_to_gid(struct winbindd_cli_state *state)
 {
        DOM_SID sid;
@@ -240,8 +315,11 @@ void winbindd_sid_to_gid(struct winbindd_cli_state *state)
                return;
        }
 
                return;
        }
 
-       /* always use the async interface (may block) */
-       winbindd_sid2gid_async(state->mem_ctx, &sid, sid2gid_recv, state);
+       /* Validate the SID as a group.  Hopefully this will hit cache.
+          Needed to prevent DoS by exhausting the uid allocation
+          range from random SIDs. */
+
+       winbindd_lookupsid_async( state->mem_ctx, &sid, sid2gid_lookupsid_recv, state );        
 }
 
 static void sids2xids_recv(void *private_data, BOOL success, void *data, int len)
 }
 
 static void sids2xids_recv(void *private_data, BOOL success, void *data, int len)